changeset 3:32d17f6062cb

adding javascript code -- working on Display and Visualizer and srcHolder
author Sean Halle <seanhalle@yahoo.com>
date Sun, 06 Jul 2014 12:02:12 -0700
parents 5c0400b5ae59
children ef3143bbd516
files 1__Development/0__Code_Dev/Javascript_approach/9__misc/multi_reference_bug.js 1__Development/0__Code_Dev/Javascript_approach/9__misc/terminal.js 1__Development/0__Code_Dev/Javascript_approach/DESIGN_NOTES__14_Jn_22.txt 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.html 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/CalcCombosOfWord.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/POPDisplay.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/epocratesPuzzle.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/renderPOPSyntaxGraph.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/displayLoadPage.html 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/index.html 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/jquery.min.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/require.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation_SVG_in_parts.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_syntax_graph.js 1__Development/0__Code_Dev/Javascript_approach/Display - Copy/startUpApp.js 1__Development/0__Code_Dev/Javascript_approach/Display/POPDisplay.html 1__Development/0__Code_Dev/Javascript_approach/Display/app/GabePatternSrcHolder.js 1__Development/0__Code_Dev/Javascript_approach/Display/app/POPApp.js 1__Development/0__Code_Dev/Javascript_approach/Display/app/POPDisplay.js 1__Development/0__Code_Dev/Javascript_approach/Display/app/POPSyntaxGraphVisualizer.js 1__Development/0__Code_Dev/Javascript_approach/Display/app/buildGabePatternSyntaxGraph.js 1__Development/0__Code_Dev/Javascript_approach/Display/app/renderPOPSyntaxGraph.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/classList.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.css 1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous_styles.css 1__Development/0__Code_Dev/Javascript_approach/Display/lib/functionPrototypeBind.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/jquery.min.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/requestAnimationFrame.js 1__Development/0__Code_Dev/Javascript_approach/Display/lib/require.js 1__Development/0__Code_Dev/Javascript_approach/Display/startUpApp.js 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.odg 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.pdf 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.odg 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.pdf 1__Development/0__Code_Dev/Javascript_approach/GabePattern/GabePattern_data_structs.js 1__Development/0__Code_Dev/Javascript_approach/GabePattern/loadGabePattern.html 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/A.svg 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/B.svg 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/cubic.svg.xml 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.html 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.js 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles-svg.css 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles.css 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/box.svg 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/inkscape_sigma.svg 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/plus.svg 1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/sigma.svg 1__Development/0__Code_Dev/Javascript_approach/ToDos__14_Jy_02.txt 1__Development/0__Code_Dev/Javascript_approach/learning_scripts/copy_of_famous_univ_example_code.js 1__Development/0__Code_Dev/Javascript_approach/learning_scripts/famous_learning.js 1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning.js 1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learningLoadPage.html 1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning_text_bounding_box.js 1__Development/0__Code_Dev/Javascript_approach/lib/classList.js 1__Development/0__Code_Dev/Javascript_approach/lib/famous.css 1__Development/0__Code_Dev/Javascript_approach/lib/famous.js 1__Development/0__Code_Dev/Javascript_approach/lib/famous_styles.css 1__Development/0__Code_Dev/Javascript_approach/lib/functionPrototypeBind.js 1__Development/0__Code_Dev/Javascript_approach/lib/requestAnimationFrame.js 1__Development/0__Code_Dev/Javascript_approach/lib/require.js 1__Development/9__Design_documents/0__figures__on_which_work_out_fundamentals_of_EQNLang/09_My_26___HamiltonianPath_and_Taylor_series.pdf
diffstat 64 files changed, 44677 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/9__misc/multi_reference_bug.js	Sun Jul 06 12:02:12 2014 -0700
     1.3 @@ -0,0 +1,90 @@
     1.4 +
     1.5 +
     1.6 +define(function(require, exports, module) {
     1.7 +    var Engine           = require("famous/core/Engine");
     1.8 +    var Surface          = require("famous/core/Surface");
     1.9 +    var Modifier         = require("famous/core/Modifier");
    1.10 +    var Transform = require('famous/core/Transform');
    1.11 +    var StateModifier = require('famous/modifiers/StateModifier');
    1.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
    1.13 +    var Scrollview       = require("famous/views/Scrollview");
    1.14 +
    1.15 +    var mainContext = Engine.createContext();
    1.16 +	var mySurface1 = new Surface({
    1.17 +	  size: [100, 100],
    1.18 +      content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
    1.19 +      properties: {
    1.20 +        color: 'white',
    1.21 +        lineHeight: '200%',
    1.22 +        textAlign: 'center',
    1.23 +        fontSize: '36px',
    1.24 +        cursor: 'pointer'
    1.25 +     }
    1.26 +	});
    1.27 +
    1.28 +	var mySurface2 = new Surface({
    1.29 +	  size: [100, 100],
    1.30 +      content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:blue;stroke-width:3;opacity:0.5">',
    1.31 +      properties: {
    1.32 +        color: 'white',
    1.33 +        lineHeight: '200%',
    1.34 +        textAlign: 'center',
    1.35 +        fontSize: '36px',
    1.36 +        cursor: 'pointer'
    1.37 +     }
    1.38 +	});
    1.39 +	var mySurface3 = new Surface({
    1.40 +	  size: [100, 100],
    1.41 +      content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:green;stroke-width:3;opacity:0.5">',
    1.42 +      properties: {
    1.43 +        color: 'white',
    1.44 +        lineHeight: '200%',
    1.45 +        textAlign: 'center',
    1.46 +        fontSize: '36px',
    1.47 +        cursor: 'pointer'
    1.48 +     }
    1.49 +	});
    1.50 +	var mySurface4 = new Surface({
    1.51 +	  size: [100, 100],
    1.52 +      content: '<svg width="100" height="100"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
    1.53 +      properties: {
    1.54 +        color: 'white',
    1.55 +        lineHeight: '200%',
    1.56 +        textAlign: 'center',
    1.57 +        fontSize: '36px',
    1.58 +        cursor: 'pointer'
    1.59 +     }
    1.60 +	});
    1.61 +
    1.62 +	var moveModifier1 = new StateModifier({
    1.63 +        transform: Transform.translate(50, 50, 0)
    1.64 +    });
    1.65 +	var moveModifier2 = new StateModifier({
    1.66 +        transform: Transform.translate(100, 100, 0)
    1.67 +    });
    1.68 +	var moveModifier3 = new StateModifier({
    1.69 +        transform: Transform.translate(150, 150, 0)
    1.70 +    });
    1.71 +	var moveModifier4 = new StateModifier({
    1.72 +        transform: Transform.translate(100, 100, 0)
    1.73 +    });
    1.74 +	var moveModifier5 = new StateModifier({
    1.75 +        transform: Transform.translate(100, 100, 0)
    1.76 +    });
    1.77 +//A given surface object will only render once!  Have to
    1.78 +// clone it if want multiple versions to be drawn.
    1.79 +//Same goes for modifiers -- cannot put same modifier object at multiple 
    1.80 +// places within tree -- it will only render children of ONE of those places!
    1.81 +   mainContext.add(moveModifier1).add(mySurface1);
    1.82 +   mainContext.add(moveModifier2).add(mySurface2);
    1.83 +//uncomment this line to see the first disappear
    1.84 +//   mainContext.add(moveModifier3).add(mySurface1);
    1.85 +
    1.86 +   //this shows ganged modifiers working correctly
    1.87 +   mainContext.add(moveModifier4).add(moveModifier5).add(mySurface3);
    1.88 +
    1.89 +   //this shows that repeating modifier2 makes the second fail to render!
    1.90 +// uncomment this line to see the second disappear!
    1.91 +//   mainContext.add(moveModifier2).add(moveModifier3).add(mySurface4);
    1.92 +   
    1.93 +});
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/9__misc/terminal.js	Sun Jul 06 12:02:12 2014 -0700
     2.3 @@ -0,0 +1,1 @@
     2.4 +!function a(b,c,e){function f(d,j){if(!c[d]){if(!b[d]){var i=typeof require=='function'&&require;if(!j&&i)return i(d,!0);if(g)return g(d,!0);throw new Error("Cannot find module '"+d+"'")}var h=c[d]={exports:{}};b[d][0].call(h.exports,function(c){var a=b[d][1][c];return f(a?a:c)},h,h.exports,a,b,c,e)}return c[d].exports}var g=typeof require=='function'&&require;for(var d=0;d<e.length;d++)f(e[d]);return f}({1:[function(a,D,C){function b(a){window.parent&&window.parent.postMessage&&window.parent.postMessage(a,'*')}function r(){document.body.className='focused'}function t(){document.body.className=''}function v(c){document.hasFocus&&document.hasFocus()&&r(),f=c||f;var a=f.split('/')[2];a!=='log'&&b('stream:'+a),l()}function l(){c=k(f);var a=new m(u);c.pipe(a).pipe(c),c.on('end',g),c.on('connect',j)}function B(){console.log('DIS'),b('term:dis'),c.removeListener('end',g),c.end()}function g(){if(console.log('RE'),window.term)try{document.body.removeChild(window.term.element)}catch(a){}e=!0,w(),setTimeout(l,5e3)}function u(a){e&&(e=!1,j()),a.meta==='terminal'&&y(a),a.meta==='clientEvents'&&A(a),a.meta==='terminalLog'&&x(a)}function j(){document.getElementById('loader').style.display='none',b('hide:loader')}function w(){document.getElementById('loader').style.display='block',b('show:loader')}function x(a){a.on('data',function(a){b('term:data'+a)})}function y(c){window.pty=c;var a=window.term=new s({cols:80,rows:24,useStyle:!0,screenKeys:!0});c.on('data',function(a){/\[1;32mExecuting Build Command: /.test(a)&&(console.log('BUILD'),b('stream:build')),/\[1;32mExecuting Run Command: /.test(a)&&(console.log('RUN'),b('stream:run')),/Process exited with code: /.test(a)&&(console.log('ERROR'),b('stream:error'))}),a.on('data',c.write.bind(c)),a.once('data',function(a){d.emit('enableLog')}),a.open(),c.pipe(a),a.end=a.destroy;var e=z.bind(null,a);e(),setTimeout(e,1e3),window.onresize=e}function z(a){var b=document.body.clientWidth/a.element.offsetWidth,c=document.body.clientHeight/a.element.offsetHeight;b=b*a.cols|0,c=c*a.rows|0,a.resize(b,c),typeof i==='function'&&i(b,c)}function A(g){var c=a('querystring').parse(window.location.search.slice(1)),b=c.options?JSON.parse(c.options):null,e=b&&b.args?b.args:[],f=b&&b.env?b.env:{};n.toStream(d).pipe(o.stringify()).pipe(g),i=function(a,b){d.emit('resize',a,b)},d.emit('startTerminal',e,f),setInterval(function a(){d.emit('ping',!0)},1e3)}a('es5-shimify');var s=a('term.js'),k=a('shoe'),i,m=a('mux-demux'),n=a('emit-stream'),o=a('JSONStream'),p=a('events').EventEmitter,q=a('away'),f,e=!0,c,d=new p,h=q(6e5);h.on('idle',B),h.on('active',g),window.onfocus=r,window.onblur=t,window.start=v},{JSONStream:2,away:5,'emit-stream':15,'es5-shimify':17,events:7,'mux-demux':18,querystring:9,shoe:24,'term.js':26}],2:[function(a,i,c){function d(a,b){return'string'===typeof a?b==a:a&&'function'===typeof a.exec?a.exec(b):'boolean'===typeof a?a:'function'===typeof a?a(b):!1}var e=a('__browserify_process'),f=a('__browserify_Buffer').Buffer,g=a('jsonparse'),h=a('stream').Stream,b=a('through');c.parse=function(c){var h=new g,a=b(function(a){if('string'===typeof a)if(e.browser){var c=new Array(a.length);for(var b=0;b<a.length;b++)c[b]=a.charCodeAt(b);a=new Int32Array(c)}else a=new f(a);h.write(a)},function(b){b&&a.write(b),a.queue(null)});'string'===typeof c&&(c=c.split('.').map(function(a){return a==='*'?!0:a===''?{recurse:!0}:a}));var i=0;return c&&c.length||(c=null),h.onValue=function(){if(!this.root&&this.stack.length==1&&(a.root=this.value),!c)return;var e=0,b=0;while(e<c.length){var g=c[e],f;if(b++,g&&!g.recurse){if(f=b===this.stack.length?this:this.stack[b],!f)return;if(!d(g,f.key))return;e++}else{e++;var h=c[e];if(!h)return;while(!0){if(f=b===this.stack.length?this:this.stack[b],!f)return;if(d(h,f.key)){e++;break}b++}}}if(b!==this.stack.length)return;i++,a.queue(this.value[this.key]),delete this.value[this.key]},h._onToken=h.onToken,h.onToken=function(b,d){h._onToken(b,d),this.stack.length===0&&a.root&&(c||a.queue(a.root),a.emit('root',a.root,i),i=0,a.root=null)},h.onError=function(b){a.emit('error',b)},a},c.stringify=function(c,d,e){c===!1?(c='',d='\n',e=''):c==null&&(c='[\n',d='\n,\n',e='\n]\n');var a,f=!0,g=!1;return a=b(function(e){g=!0;var b=JSON.stringify(e);f?(f=!1,a.queue(c+b)):a.queue(d+b)},function(b){g||a.queue(c),a.queue(e),a.queue(null)}),a},c.stringifyObject=function(c,d,e){c===!1?(c='',d='\n',e=''):c==null&&(c='{\n',d='\n,\n',e='\n}\n');var a=new h,f=!0,g=!1;return a=b(function(e){g=!0;var b=JSON.stringify(e[0])+':'+JSON.stringify(e[1]);f?(f=!1,a.queue(c+b)):a.queue(d+b)},function(b){g||a.queue(c),a.queue(e),a.queue(null)}),a}},{__browserify_Buffer:13,__browserify_process:14,jsonparse:3,stream:10,through:4}],3:[function(T,U,V){function y(c){var d=Object.keys(a);for(var b=0,f=d.length;b<f;b++){var e=d[b];if(a[e]===c)return e}return c&&'0x'+c.toString(16)}function S(){this.tState=d,this.value=undefined,this.string=undefined,this.unicode=undefined,this.negative=undefined,this.magnatude=undefined,this.position=undefined,this.exponent=undefined,this.negativeExponent=undefined,this.key=undefined,this.mode=undefined,this.stack=[],this.state=e,this.bytes_remaining=0,this.bytes_in_sequence=0,this.temp_buffs={2:new l(2),3:new l(3),4:new l(4)}}var l=T('__browserify_Buffer').Buffer,a={},M=a.LEFT_BRACE=1,h=a.RIGHT_BRACE=2,J=a.LEFT_BRACKET=3,n=a.RIGHT_BRACKET=4,i=a.COLON=5,j=a.COMMA=6,F=a.TRUE=7,G=a.FALSE=8,H=a.NULL=9,t=a.STRING=10,f=a.NUMBER=11,d=a.START=17,u=a.TRUE1=33,v=a.TRUE2=34,w=a.TRUE3=35,x=a.FALSE1=49,L=a.FALSE2=50,z=a.FALSE3=51,A=a.FALSE4=52,B=a.NULL1=65,C=a.NULL3=66,D=a.NULL2=67,E=a.NUMBER1=81,o=a.NUMBER2=82,p=a.NUMBER3=83,q=a.NUMBER4=84,I=a.NUMBER5=85,m=a.NUMBER6=86,K=a.NUMBER7=87,s=a.NUMBER8=88,c=a.STRING1=97,N=a.STRING2=98,O=a.STRING3=99,R=a.STRING4=100,Q=a.STRING5=101,P=a.STRING6=102,e=a.VALUE=113,r=a.KEY=114,g=a.OBJECT=129,k=a.ARRAY=130,b=S.prototype;b.charError=function(b,a){this.onError(new Error('Unexpected '+JSON.stringify(String.fromCharCode(b[a]))+' at position '+a+' in state '+y(this.tState)))},b.onError=function(a){throw a},b.write=function(e){typeof e==='string'&&(e=new l(e));var a;for(var b=0,r=e.length;b<r;b++)if(this.tState===d)a=e[b],a===123?this.onToken(M,'{'):a===125?this.onToken(h,'}'):a===91?this.onToken(J,'['):a===93?this.onToken(n,']'):a===58?this.onToken(i,':'):a===44?this.onToken(j,','):a===116?this.tState=u:a===102?this.tState=x:a===110?this.tState=B:a===34?(this.string='',this.tState=c):a===45?(this.negative=!0,this.tState=E):a===48?(this.magnatude=0,this.tState=o):a>48&&a<64?(this.magnatude=a-48,this.tState=p):a===32||a===9||a===10||a===13||this.charError(e,b);else if(this.tState===c)if(a=e[b],this.bytes_remaining>0){for(var g=0;g<this.bytes_remaining;g++)this.temp_buffs[this.bytes_in_sequence][this.bytes_in_sequence-this.bytes_remaining+g]=e[g];this.string+=this.temp_buffs[this.bytes_in_sequence].toString(),this.bytes_in_sequence=this.bytes_remaining=0,b=b+g-1}else if(this.bytes_remaining===0&&a>=128)if(a>=194&&a<=223&&(this.bytes_in_sequence=2),a>=224&&a<=239&&(this.bytes_in_sequence=3),a>=240&&a<=244&&(this.bytes_in_sequence=4),this.bytes_in_sequence+b>e.length){for(var k=0;k<=e.length-1-b;k++)this.temp_buffs[this.bytes_in_sequence][k]=e[b+k];this.bytes_remaining=b+this.bytes_in_sequence-e.length,b=e.length-1}else this.string+=e.slice(b,b+this.bytes_in_sequence).toString(),b=b+this.bytes_in_sequence-1;else a===34?(this.tState=d,this.onToken(t,this.string),this.string=undefined):a===92?this.tState=N:a>=32?this.string+=String.fromCharCode(a):this.charError(e,b);else this.tState===N?(a=e[b],a===34?(this.string+='"',this.tState=c):a===92?(this.string+='\\',this.tState=c):a===47?(this.string+='/',this.tState=c):a===98?(this.string+='',this.tState=c):a===102?(this.string+='',this.tState=c):a===110?(this.string+='\n',this.tState=c):a===114?(this.string+='\r',this.tState=c):a===116?(this.string+='	',this.tState=c):a===117?(this.unicode='',this.tState=O):this.charError(e,b)):this.tState===O||this.tState===R||this.tState===Q||this.tState===P?(a=e[b],a>=48&&a<64||a>64&&a<=70||a>96&&a<=102?(this.unicode+=String.fromCharCode(a),this.tState++===P&&(this.string+=String.fromCharCode(parseInt(this.unicode,16)),this.unicode=undefined,this.tState=c)):this.charError(e,b)):this.tState===E?(a=e[b],a===48?(this.magnatude=0,this.tState=o):a>48&&a<64?(this.magnatude=a-48,this.tState=p):this.charError(e,b)):this.tState===o?(a=e[b],a===46?(this.position=.1,this.tState=q):a===101||a===69?(this.exponent=0,this.tState=m):(this.tState=d,this.onToken(f,0),this.magnatude=undefined,this.negative=undefined,b--)):this.tState===p?(a=e[b],a===46?(this.position=.1,this.tState=q):a===101||a===69?(this.exponent=0,this.tState=m):a>=48&&a<64?this.magnatude=this.magnatude*10+a-48:(this.tState=d,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.onToken(f,this.magnatude),this.magnatude=undefined,b--)):this.tState===q?(a=e[b],a>=48&&a<64?(this.magnatude+=this.position*(a-48),this.position/=10,this.tState=I):this.charError(e,b)):this.tState===I?(a=e[b],a>=48&&a<64?(this.magnatude+=this.position*(a-48),this.position/=10):a===101||a===69?(this.exponent=0,this.tState=m):(this.tState=d,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.onToken(f,this.negative?-this.magnatude:this.magnatude),this.magnatude=undefined,this.position=undefined,b--)):this.tState===m?(a=e[b],a===43||a===45?(a===45&&(this.negativeExponent=!0),this.tState=K):a>=48&&a<64?(this.exponent=this.exponent*10+(a-48),this.tState=s):this.charError(e,b)):this.tState===K?(a=e[b],a>=48&&a<64?(this.exponent=this.exponent*10+(a-48),this.tState=s):this.charError(e,b)):this.tState===s?(a=e[b],a>=48&&a<64?this.exponent=this.exponent*10+(a-48):(this.negativeExponent&&(this.exponent=-this.exponent,this.negativeExponent=undefined),this.magnatude*=Math.pow(10,this.exponent),this.exponent=undefined,this.negative&&(this.magnatude=-this.magnatude,this.negative=undefined),this.tState=d,this.onToken(f,this.magnatude),this.magnatude=undefined,b--)):this.tState===u?e[b]===114?this.tState=v:this.charError(e,b):this.tState===v?e[b]===117?this.tState=w:this.charError(e,b):this.tState===w?e[b]===101?(this.tState=d,this.onToken(F,!0)):this.charError(e,b):this.tState===x?e[b]===97?this.tState=L:this.charError(e,b):this.tState===L?e[b]===108?this.tState=z:this.charError(e,b):this.tState===z?e[b]===115?this.tState=A:this.charError(e,b):this.tState===A?e[b]===101?(this.tState=d,this.onToken(G,!1)):this.charError(e,b):this.tState===B?e[b]===117?this.tState=C:this.charError(e,b):this.tState===C?e[b]===108?this.tState=D:this.charError(e,b):this.tState===D&&(e[b]===108?(this.tState=d,this.onToken(H,null)):this.charError(e,b))},b.onToken=function(a,b){},b.parseError=function(b,a){this.onError(new Error('Unexpected '+y(b)+(a?'('+JSON.stringify(a)+')':'')+' in state '+y(this.state)))},b.onError=function(a){throw a},b.push=function(){this.stack.push({value:this.value,key:this.key,mode:this.mode})},b.pop=function(){var b=this.value,a=this.stack.pop();this.value=a.value,this.key=a.key,this.mode=a.mode,this.emit(b),this.mode||(this.state=e)},b.emit=function(a){this.mode&&(this.state=j),this.onValue(a)},b.onValue=function(a){},b.onToken=function(a,b){this.state===e?a===t||a===f||a===F||a===G||a===H?(this.value&&(this.value[this.key]=b),this.emit(b)):a===M?(this.push(),this.value?this.value=this.value[this.key]={}:this.value={},this.key=undefined,this.state=r,this.mode=g):a===J?(this.push(),this.value?this.value=this.value[this.key]=[]:this.value=[],this.key=0,this.mode=k,this.state=e):a===h?this.mode===g?this.pop():this.parseError(a,b):a===n?this.mode===k?this.pop():this.parseError(a,b):this.parseError(a,b):this.state===r?a===t?(this.key=b,this.state=i):a===h?this.pop():this.parseError(a,b):this.state===i?a===i?this.state=e:this.parseError(a,b):this.state===j?a===j?this.mode===k?(this.key++,this.state=e):this.mode===g&&(this.state=r):a===n&&this.mode===k||a===h&&this.mode===g?this.pop():this.parseError(a,b):this.parseError(a,b)},U.exports=S},{__browserify_Buffer:13}],4:[function(b,e,f){function a(f,g){function i(){while(b.length&&!a.paused){var c=b.shift();if(null===c)return a.emit('end');a.emit('data',c)}}function j(){a.writable=!1,g.call(a),a.readable||a.destroy()}f=f||function(a){this.queue(a)},g=g||function(){this.queue(null)};var e=!1,h=!1,b=[],a=new d;return a.readable=a.writable=!0,a.paused=!1,a.write=function(b){return f.call(this,b),!a.paused},a.queue=a.push=function(c){return b.push(c),i(),a},a.on('end',function(){a.readable=!1,a.writable||c.nextTick(function(){a.destroy()})}),a.end=function(b){return e?void 0:(e=!0,arguments.length&&a.write(b),j(),a)},a.destroy=function(){return h?void 0:(h=!0,e=!0,b.length=0,a.writable=a.readable=!1,a.emit('close'),a)},a.pause=function(){return a.paused?void 0:(a.paused=!0,a.emit('pause'),a)},a.resume=function(){return a.paused&&(a.paused=!1),i(),a.paused||a.emit('drain'),a},a}var c=b('__browserify_process'),d=b('stream');f=e.exports=a,a.through=a},{__browserify_process:14,stream:10}],5:[function(h,i,j){function e(a){a.idle=!a.idle;var d=+new Date-a.olddate;if(a.olddate=+new Date,a.idle&&d<a.timeout){a.idle=!1,clearTimeout(a.timer_id),a.enabled&&(a.timer_id=setTimeout(a.state_fn,a.timeout));return}var e=a.idle?'idle':'active',c=e==='idle'?a.idle_fn:a.active_fn;for(var b=0;b<c.length;++b)c[b]()}var c=h('xtend');i.exports=function(a){return new b({timeout:a})};var g={start:!0,enabled:!0,timeout:3e4,element:document,events:'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove'},b=function(b){var a=this;a.opt=c(g,b),a.element=a.opt.element,a.state={idle:a.opt.idle,timeout:a.opt.timeout,enabled:a.opt.enabled,idle_fn:[],active_fn:[]},a.state.state_fn=function(){e(a.state)},a.opt.start&&a.start()},a=b.prototype;a.start=function(){function g(b){if(clearTimeout(a.timer_id),!a.enabled)return;a.idle&&e(a),a.timer_id=setTimeout(a.state_fn,a.timeout)}var b=this,a=b.state,h=b.element;a.handler=g;var d=this.opt.events.split(' ');for(var c=0;c<d.length;++c){var i=d[c];f(h,i,g)}a.timer_id=setTimeout(b.state.state_fn,a.timeout)},a.on=function(d,b){var c=this,a=c.state;d==='idle'?a.idle_fn.push(b):a.active_fn.push(b)},a.getElapsed=function(){return+new Date-this.state.olddate},a.stop=function(){var e=this,a=this.state,f=e.element;a.enabled=!1,clearTimeout(a.timer_id);var c=this.opt.events.split(' ');for(var b=0;b<c.length;++b){var g=c[b];d(f,g,a.handler)}};var f=function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent('on'+b,c)},d=function(a,b,c){a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent('on'+b,c)}},{xtend:6}],6:[function(f,b,g){function c(){var f={};for(var b=0;b<arguments.length;b++){var c=arguments[b];if(!e(c))continue;var g=a(c);for(var d=0;d<g.length;d++){var h=g[d];f[h]=c[h]}}return f}function d(c){var a=[];for(var b in c)a.push(b);return a}function e(a){return a!==null&&typeof a==='object'}var a=Object.keys||d;b.exports=c},{}],7:[function(e,h,f){function g(b,c){if(b.indexOf)return b.indexOf(c);for(var a=0;a<b.length;a++)if(c===b[a])return a;return-1}var c=e('__browserify_process');c.EventEmitter||(c.EventEmitter=function(){});var a=f.EventEmitter=c.EventEmitter,b=typeof Array.isArray==='function'?Array.isArray:function(a){return Object.prototype.toString.call(a)==='[object Array]'},d=10;a.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},a.prototype.emit=function(f){if(f==='error'&&(!(this._events&&this._events.error)||b(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var a=this._events[f];if(!a)return!1;if(!(typeof a=='function'))if(b(a)){var c=Array.prototype.slice.call(arguments,1),e=a.slice();for(var d=0,g=e.length;d<g;d++)e[d].apply(this,c);return!0}else return!1;switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:var c=Array.prototype.slice.call(arguments,1);a.apply(this,c)}return!0},a.prototype.addListener=function(a,c){if('function'!==typeof c)throw new Error('addListener only takes instances of Function');if(this._events||(this._events={}),this.emit('newListener',a,c),!this._events[a])this._events[a]=c;else if(b(this._events[a])){if(!this._events[a].warned){var e;this._events.maxListeners!==undefined?e=this._events.maxListeners:e=d,e&&e>0&&this._events[a].length>e&&(this._events[a].warned=!0,console.error('(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.',this._events[a].length),console.trace())}this._events[a].push(c)}else this._events[a]=[this._events[a],c];return this},a.prototype.on=a.prototype.addListener,a.prototype.once=function(b,c){var a=this;return a.on(b,function d(){a.removeListener(b,d),c.apply(this,arguments)}),this},a.prototype.removeListener=function(a,d){if('function'!==typeof d)throw new Error('removeListener only takes instances of Function');if(!(this._events&&this._events[a]))return this;var c=this._events[a];if(b(c)){var e=g(c,d);if(e<0)return this;c.splice(e,1),c.length==0&&delete this._events[a]}else this._events[a]===d&&delete this._events[a];return this},a.prototype.removeAllListeners=function(a){return arguments.length===0?(this._events={},this):(a&&this._events&&this._events[a]&&(this._events[a]=null),this)},a.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),b(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]},a.listenerCount=function(a,c){var b;return a._events&&a._events[c]?typeof a._events[c]==='function'?b=1:b=a._events[c].length:b=0,b}},{__browserify_process:14}],8:[function(a,b,c){},{}],9:[function(u,v,l){function i(a,b){if(a[b].length==0)return a[b]={};var c={};for(var d in a[b])c[d]=a[b][d];return a[b]=c,c}function f(l,e,g,k){var j=l.shift();if(!j)a(e[g])?e[g].push(k):'object'==typeof e[g]?e[g]=k:void 0===e[g]?e[g]=k:e[g]=[e[g],k];else{var h=e[g]=e[g]||[];']'==j?a(h)?''!=k&&h.push(k):'object'==typeof h?h[d(h).length]=k:h=e[g]=[e[g],k]:~b(j,']')?(j=j.substr(0,j.length-1),!c.test(j)&&a(h)&&(h=i(e,g)),f(l,h,j,k)):(!c.test(j)&&a(h)&&(h=i(e,g)),f(l,h,j,k))}}function k(d,e,j){if(~b(e,']')){var g=e.split('['),k=g.length,l=k-1;f(g,d,'base',j)}else{if(!c.test(e)&&a(d.base)){var h={};for(var i in d.base)h[i]=d.base[i];d.base=h}t(d.base,e,j)}return d}function o(b){var a={base:{}};return j(d(b),function(c){k(a,c,b[c])}),a.base}function p(a){return m(String(a).split('&'),function(g,c){var e=b(c,'='),f=n(c),d=c.substr(0,f||e),a=c.substr(f||e,c.length),a=a.substr(b(a,'=')+1,a.length);return''==d&&(d=c,a=''),''==d?g:k(g,h(d),h(a))},{base:{}}).base}function q(b,a){if(!a)throw new TypeError('stringify expects an object');return a+'='+encodeURIComponent(b)}function r(c,d){var b=[];if(!d)throw new TypeError('stringify expects an object');for(var a=0;a<c.length;a++)b.push(e(c[a],d+'['+a+']'));return b.join('&')}function s(f,h){var b=[],g=d(f),a;for(var c=0,i=g.length;c<i;++c)a=g[c],null==f[a]?b.push(encodeURIComponent(a)+'='):b.push(e(f[a],h?h+'['+encodeURIComponent(a)+']':encodeURIComponent(a)));return b.join('&')}function t(c,d,e){var b=c[d];undefined===b?c[d]=e:a(b)?b.push(e):c[d]=[b,e]}function n(d){var e=d.length,c,b;for(var a=0;a<e;++a)if(b=d[a],']'==b&&(c=!1),'['==b&&(c=!0),'='==b&&!c)return a}function h(a){try{return decodeURIComponent(a.replace(/\+/g,' '))}catch(b){return a}}var g=Object.prototype.toString,b=typeof Array.prototype.indexOf==='function'?function(a,b){return a.indexOf(b)}:function(b,c){for(var a=0;a<b.length;a++)if(b[a]===c)return a;return-1},a=Array.isArray||function(a){return g.call(a)=='[object Array]'},d=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},j=typeof Array.prototype.forEach==='function'?function(a,b){return a.forEach(b)}:function(b,c){for(var a=0;a<b.length;a++)c(b[a])},m=function(a,d,e){if(typeof a.reduce==='function')return a.reduce(d,e);var b=e;for(var c=0;c<a.length;c++)b=d(b,a[c]);return b},c=/^[0-9]+$/;l.parse=function(a){return null==a||''==a?{}:'object'==typeof a?o(a):p(a)};var e=l.stringify=function(b,c){return a(b)?r(b,c):'[object Object]'==g.call(b)?s(b,c):'string'==typeof b?q(b,c):c+'='+encodeURIComponent(String(b))}},{}],10:[function(c,e,f){function a(){b.EventEmitter.call(this)}var b=c('events'),d=c('util');d.inherits(a,b.EventEmitter),e.exports=a,a.Stream=a,a.prototype.pipe=function(a,h){function i(c){a.writable&&!1===a.write(c)&&b.pause&&b.pause()}function j(){b.readable&&b.resume&&b.resume()}function f(){if(d)return;if(d=!0,a._pipeCount--,c(),a._pipeCount>0)return;a.end()}function g(){if(d)return;if(d=!0,a._pipeCount--,c(),a._pipeCount>0)return;a.destroy()}function e(a){if(c(),this.listeners('error').length===0)throw a}function c(){b.removeListener('data',i),a.removeListener('drain',j),b.removeListener('end',f),b.removeListener('close',g),b.removeListener('error',e),a.removeListener('error',e),b.removeListener('end',c),b.removeListener('close',c),a.removeListener('end',c),a.removeListener('close',c)}var b=this;b.on('data',i),a.on('drain',j),!a._isStdio&&(!h||h.end!==!1)&&(a._pipeCount=a._pipeCount||0,a._pipeCount++,b.on('end',f),b.on('close',g));var d=!1;return b.on('error',e),a.on('error',e),b.on('end',c),b.on('close',c),a.on('end',c),a.on('close',c),a.emit('pipe',b),a}},{events:7,util:12}],11:[function(v,y,g){function b(b,d){for(var a=0,c=b.length;a<c;a++)if(b[a]==d)return a;return-1}function h(x,X,Y){if(x&&typeof x==='object'&&x.href)return x;if(typeof x!=='string')throw new TypeError("Parameter 'url' must be a string, not "+typeof x);var g={},o=x;for(var h=0,p=o.length;h<p;h++)if(b(d,o.charAt(h))===-1)break;h!==0&&(o=o.substr(h));var s=u.exec(o);if(s){s=s[0];var M=s.toLowerCase();g.protocol=M,o=o.substr(s.length)}if(Y||s||o.match(/^\/\/[^@\/]+@[^@\/]+/)){var Q=o.substr(0,2)==='//';Q&&!(s&&f[s])&&(o=o.substr(2),g.slashes=!0)}if(!f[s]&&(Q||s&&!c[s])){var A=b(o,'@');if(A!==-1){var U=!0;for(var h=0,p=e.length;h<p;h++){var v=b(o,e[h]);if(v!==-1&&v<A){U=!1;break}}U&&(g.auth=o.substr(0,A),o=o.substr(A+1))}var y=-1;for(var h=0,p=k.length;h<p;h++){var v=b(o,k[h]);v!==-1&&(y<0||v<y)&&(y=v)}y!==-1?(g.host=o.substr(0,y),o=o.substr(y)):(g.host=o,o='');var N=w(g.host),P=j(N);for(var h=0,p=P.length;h<p;h++){var V=P[h];g[V]=N[V]}if(g.hostname=g.hostname||'',g.hostname.length>t)g.hostname='';else{var C=g.hostname.split(/\./);for(var h=0,p=C.length;h<p;h++){var z=C[h];if(!z)continue;if(!z.match(m)){var F='';for(var E=0,W=z.length;E<W;E++)z.charCodeAt(E)>127?F+='x':F+=z[E];if(!F.match(m)){var O=C.slice(0,h),H=C.slice(h+1),I=z.match(n);I&&(O.push(I[1]),H.unshift(I[2])),H.length&&(o='/'+H.join('.')+o),g.hostname=O.join('.');break}}}}g.hostname=g.hostname.toLowerCase();var R=g.hostname.split('.'),S=[];for(var h=0;h<R.length;++h){var J=R[h];S.push(J.match(/[^A-Za-z0-9_-]/)?'xn--'+r.encode(J):J)}g.hostname=S.join('.'),g.host=(g.hostname||'')+(g.port?':'+g.port:''),g.href+=g.host}if(!q[M]){for(var h=0,p=i.length;h<p;h++){var B=i[h],L=encodeURIComponent(B);L===B&&(L=escape(B)),o=o.split(B).join(L)}var G=o.length;for(var h=0,p=d.length;h<p;h++){var T=b(o,d[h]);T!==-1&&(G=Math.min(T,G))}o=o.substr(0,G)}var K=b(o,'#');K!==-1&&(g.hash=o.substr(K),o=o.slice(0,K));var D=b(o,'?');return D!==-1?(g.search=o.substr(D),g.query=o.substr(D+1),X&&(g.query=l.parse(g.query)),o=o.slice(0,D)):X&&(g.search='',g.query={}),o&&(g.pathname=o),c[s]&&g.hostname&&!g.pathname&&(g.pathname='/'),(g.pathname||g.search)&&(g.path=(g.pathname?g.pathname:'')+(g.search?g.search:'')),g.href=a(g),g}function a(a){typeof a==='string'&&(a=h(a));var b=a.auth||'';if(b){b=b.split('@').join('%40');for(var m=0,p=e.length;m<p;m++){var n=e[m];b=b.split(n).join(encodeURIComponent(n))}b+='@'}var d=a.protocol||'',f=a.host!==undefined?b+a.host:a.hostname!==undefined?b+a.hostname+(a.port?':'+a.port:''):!1,g=a.pathname||'',o=a.query&&(typeof a.query==='object'&&j(a.query).length?l.stringify(a.query):'')||'',k=a.search||o&&'?'+o||'',i=a.hash||'';return d&&d.substr(-1)!==':'&&(d+=':'),a.slashes||(!d||c[d])&&f!==!1?(f='//'+(f||''),g&&g.charAt(0)!=='/'&&(g='/'+g)):f||(f=''),i&&i.charAt(0)!=='#'&&(i='#'+i),k&&k.charAt(0)!=='?'&&(k='?'+k),d+f+g+k+i}function x(b,c){return a(o(b,c))}function o(d,e){if(!d)return e;if(d=h(a(d),!1,!0),e=h(a(e),!1,!0),d.hash=e.hash,e.href==='')return d.href=a(d),d;if(e.slashes&&!e.protocol)return e.protocol=d.protocol,c[e.protocol]&&e.hostname&&!e.pathname&&(e.path=e.pathname='/'),e.href=a(e),e;if(e.protocol&&e.protocol!==d.protocol){if(!c[e.protocol])return e.href=a(e),e;if(d.protocol=e.protocol,!(e.host||f[e.protocol])){var i=(e.pathname||'').split('/');while(i.length&&!(e.host=i.shift()));e.host||(e.host=''),e.hostname||(e.hostname=''),i[0]!==''&&i.unshift(''),i.length<2&&i.unshift(''),e.pathname=i.join('/')}return d.pathname=e.pathname,d.search=e.search,d.query=e.query,d.host=e.host||'',d.auth=e.auth,d.hostname=e.hostname||e.host,d.port=e.port,(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.slashes=d.slashes||e.slashes,d.href=a(d),d}var t=d.pathname&&d.pathname.charAt(0)==='/',q=e.host!==undefined||e.pathname&&e.pathname.charAt(0)==='/',j=q||t||d.host&&e.pathname,s=j,g=d.pathname&&d.pathname.split('/')||[],i=e.pathname&&e.pathname.split('/')||[],o=d.protocol&&!c[d.protocol];if(o&&(delete d.hostname,delete d.port,d.host&&(g[0]===''?g[0]=d.host:g.unshift(d.host)),delete d.host,e.protocol&&(delete e.hostname,delete e.port,e.host&&(i[0]===''?i[0]=e.host:i.unshift(e.host)),delete e.host),j=j&&(i[0]===''||g[0]==='')),q)d.host=e.host||e.host===''?e.host:d.host,d.hostname=e.hostname||e.hostname===''?e.hostname:d.hostname,d.search=e.search,d.query=e.query,g=i;else if(i.length)g||(g=[]),g.pop(),g=g.concat(i),d.search=e.search,d.query=e.query;else if('search'in e){if(o){d.hostname=d.host=g.shift();var k=d.host&&b(d.host,'@')>0?d.host.split('@'):!1;k&&(d.auth=k.shift(),d.host=d.hostname=k.shift())}return d.search=e.search,d.query=e.query,(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.href=a(d),d}if(!g.length)return delete d.pathname,d.search?delete d.path:d.path='/'+d.search,d.href=a(d),d;var m=g.slice(-1)[0],r=(d.host||e.host)&&(m==='.'||m==='..')||m==='',n=0;for(var l=g.length;l>=0;l--)m=g[l],m=='.'?g.splice(l,1):m==='..'?(g.splice(l,1),n++):n&&(g.splice(l,1),n--);if(!(j||s))for(;n--;n)g.unshift('..');j&&g[0]!==''&&(!g[0]||g[0].charAt(0)!=='/')&&g.unshift(''),r&&g.join('/').substr(-1)!=='/'&&g.push('');var p=g[0]===''||g[0]&&g[0].charAt(0)==='/';if(o){d.hostname=d.host=p?'':g.length?g.shift():'';var k=d.host&&b(d.host,'@')>0?d.host.split('@'):!1;k&&(d.auth=k.shift(),d.host=d.hostname=k.shift())}return j=j||d.host&&g.length,j&&!p&&g.unshift(''),d.pathname=g.join('/'),(d.pathname!==undefined||d.search!==undefined)&&(d.path=(d.pathname?d.pathname:'')+(d.search?d.search:'')),d.auth=e.auth||d.auth,d.slashes=d.slashes||e.slashes,d.href=a(d),d}function w(a){var c={},b=s.exec(a);return b&&(b=b[0],c.port=b.substr(1),a=a.substr(0,a.length-b.length)),a&&(c.hostname=a),c}var r={encode:function(a){return a}};g.parse=h,g.resolve=x,g.resolveObject=o,g.format=a;var j=Object.keys||function a(a){if(a!==Object(a))throw new TypeError('Invalid object');var b=[];for(var c in a)a.hasOwnProperty(c)&&(b[b.length]=c);return b},u=/^([a-z0-9.+-]+:)/i,s=/:[0-9]+$/,d=['<','>','"','`',' ','\r','\n','	'],p=['{','}','|','\\','^','~','[',']','`'].concat(d),i=["'"],k=['%','/','?',';','#'].concat(p).concat(i),e=['/','@','?','#'].concat(d),t=255,m=/^[a-zA-Z0-9][a-z0-9A-Z_-]{0,62}$/,n=/^([a-zA-Z0-9][a-z0-9A-Z_-]{0,62})(.*)$/,q={javascript:!0,'javascript:':!0},f={javascript:!0,'javascript:':!0},c={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,'http:':!0,'https:':!0,'ftp:':!0,'gopher:':!0,'file:':!0},l=v('querystring')},{querystring:9}],12:[function(j,k,a){function b(a){return Array.isArray(a)||typeof a==='object'&&Object.prototype.toString.call(a)==='[object Array]'}function c(a){typeof a==='object'&&Object.prototype.toString.call(a)==='[object RegExp]'}function d(a){return typeof a==='object'&&Object.prototype.toString.call(a)==='[object Date]'}var i=j('events');a.isArray=b,a.isDate=function(a){return Object.prototype.toString.call(a)==='[object Date]'},a.isRegExp=function(a){return Object.prototype.toString.call(a)==='[object RegExp]'},a.print=function(){},a.puts=function(){},a.debug=function(){},a.inspect=function(k,l,j,m){function i(j,p){if(j&&typeof j.inspect==='function'&&j!==a&&!(j.constructor&&j.constructor.prototype===j))return j.inspect(p);switch(typeof j){case'undefined':return e('undefined','undefined');case'string':var w="'"+JSON.stringify(j).replace(/^"|"$/g,'').replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e(w,'string');case'number':return e(''+j,'number');case'boolean':return e(''+j,'boolean')}if(j===null)return e('null','null');var q=h(j),o=l?g(j):q;if(typeof j==='function'&&o.length===0)if(c(j))return e(''+j,'regexp');else{var t=j.name?': '+j.name:'';return e('[Function'+t+']','special')}if(d(j)&&o.length===0)return e(j.toUTCString(),'date');var m,r,k;if(b(j)?(r='Array',k=['[',']']):(r='Object',k=['{','}']),typeof j==='function'){var u=j.name?': '+j.name:'';m=c(j)?' '+j:' [Function'+u+']'}else m='';if(d(j)&&(m=' '+j.toUTCString()),o.length===0)return k[0]+m+k[1];if(p<0)return c(j)?e(''+j,'regexp'):e('[Object]','special');f.push(j);var n=o.map(function(d){var a,c;if(j.__lookupGetter__&&(j.__lookupGetter__(d)?j.__lookupSetter__(d)?c=e('[Getter/Setter]','special'):c=e('[Getter]','special'):j.__lookupSetter__(d)&&(c=e('[Setter]','special'))),q.indexOf(d)<0&&(a='['+d+']'),c||(f.indexOf(j[d])<0?(p===null?c=i(j[d]):c=i(j[d],p-1),c.indexOf('\n')>-1&&(b(j)?c=c.split('\n').map(function(a){return'  '+a}).join('\n').substr(2):c='\n'+c.split('\n').map(function(a){return'   '+a}).join('\n'))):c=e('[Circular]','special')),a===void 0){if(r==='Array'&&d.match(/^\d+$/))return c;a=JSON.stringify(''+d),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e(a,'name')):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e(a,'string'))}return a+': '+c});f.pop();var s=0,v=n.reduce(function(b,a){return s++,a.indexOf('\n')>=0&&s++,b+a.length+1},0);return v>50?n=k[0]+(m===''?'':m+'\n ')+' '+n.join(',\n  ')+' '+k[1]:n=k[0]+m+' '+n.join(', ')+' '+k[1],n}var f=[],e=function(c,d){var b={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a={special:'cyan',number:'blue',boolean:'yellow',undefined:'grey',null:'bold',string:'green',date:'magenta',regexp:'red'}[d];return a?'['+b[a][0]+'m'+c+'['+b[a][1]+'m':c};return m||(e=function(a,b){return a}),i(k,j===void 0?2:j)},a.log=function(a){},a.pump=null;var h=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},g=Object.getOwnPropertyNames||function(c){var a=[];for(var b in c)Object.hasOwnProperty.call(c,b)&&a.push(b);return a},e=Object.create||function(a,d){var b;if(a===null)b={__proto__:null};else{if(typeof a!=='object')throw new TypeError('typeof prototype['+typeof a+"] != 'object'");var c=function(){};c.prototype=a,b=new c,b.__proto__=a}return d!==void 0&&Object.defineProperties&&Object.defineProperties(b,d),b};a.inherits=function(a,b){a.super_=b,a.prototype=e(b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}})};var f=/%[sdj%]/g;a.format=function(i){if(typeof i!=='string'){var g=[];for(var b=0;b<arguments.length;b++)g.push(a.inspect(arguments[b]));return g.join(' ')}var b=1,c=arguments,h=c.length,e=String(i).replace(f,function(a){if(a==='%%')return'%';if(b>=h)return a;switch(a){case'%s':return String(c[b++]);case'%d':return Number(c[b++]);case'%j':return JSON.stringify(c[b++]);default:return a}});for(var d=c[b];b<h;d=c[++b])d===null||typeof d!=='object'?e+=' '+d:e+=' '+a.inspect(d);return e}},{events:7}],13:[function(a,b,c){a=function(e,b,c,f,a){function d(a){if(!c[a]){if(!b[a]){if(e)return e(a);throw new Error("Cannot find module '"+a+"'")}var f=c[a]={exports:{}};b[a][0](function(e){var c=b[a][1][e];return d(c?c:e)},f,f.exports)}return c[a].exports}for(a=0;a<f.length;a++)d(f[a]);return d}(a!==void 0&&a,{1:[function(j,q,r){function h(a){if(Object.keys)return Object.keys(a);var b=[];for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b}function l(b,a){return a===undefined?''+a:typeof a==='number'&&(isNaN(a)||!isFinite(a))?a.toString():typeof a==='function'||a instanceof RegExp?a.toString():a}function g(a,b){return typeof a=='string'?a.length<b?a:a.slice(0,b):a}function b(b,c,d,e,f){throw new a.AssertionError({message:d,actual:b,expected:c,operator:e,stackStartFunction:f})}function i(c,d){c||b(c,!0,d,'==',a.ok)}function d(a,b){if(a===b)return!0;else if(e.isBuffer(a)&&e.isBuffer(b)){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0}else return a instanceof Date&&b instanceof Date?a.getTime()===b.getTime():typeof a!='object'&&typeof b!='object'?a==b:p(a,b)}function k(a){return a===null||a===undefined}function f(a){return Object.prototype.toString.call(a)=='[object Arguments]'}function p(b,e){if(k(b)||k(e))return!1;if(b.prototype!==e.prototype)return!1;if(f(b))return f(e)?(b=c.call(b),e=c.call(e),d(b,e)):!1;try{var g=h(b),i=h(e),j,a}catch(a){return!1}if(g.length!=i.length)return!1;for(g.sort(),i.sort(),a=g.length-1;a>=0;a--)if(g[a]!=i[a])return!1;for(a=g.length-1;a>=0;a--)if(j=g[a],!d(b[j],e[j]))return!1;return!0}function n(b,a){return b&&a?a instanceof RegExp?a.test(b):b instanceof a?!0:a.call({},b)===!0?!0:!1:!1}function o(e,f,a,d){var c;typeof a==='string'&&(d=a,a=null);try{f()}catch(a){c=a}if(d=(a&&a.name?' ('+a.name+').':'.')+(d?' '+d:'.'),e&&!c&&b('Missing expected exception'+d),!e&&n(c,a)&&b('Got unwanted exception'+d),e&&c&&a&&!n(c,a)||!e&&c)throw c}var m=j('util'),e=j('buffer').Buffer,c=Array.prototype.slice,a=q.exports=i;a.AssertionError=function a(a){this.name='AssertionError',this.message=a.message,this.actual=a.actual,this.expected=a.expected,this.operator=a.operator;var c=a.stackStartFunction||b;Error.captureStackTrace&&Error.captureStackTrace(this,c)},m.inherits(a.AssertionError,Error),a.AssertionError.prototype.toString=function(){return this.message?[this.name+':',this.message].join(' '):[this.name+':',g(JSON.stringify(this.actual,l),128),this.operator,g(JSON.stringify(this.expected,l),128)].join(' ')},a.AssertionError.__proto__=Error.prototype,a.fail=b,a.ok=i,a.equal=function c(c,d,e){c!=d&&b(c,d,e,'==',a.equal)},a.notEqual=function c(c,d,e){c==d&&b(c,d,e,'!=',a.notEqual)},a.deepEqual=function c(c,e,f){d(c,e)||b(c,e,f,'deepEqual',a.deepEqual)},a.notDeepEqual=function c(c,e,f){d(c,e)&&b(c,e,f,'notDeepEqual',a.notDeepEqual)},a.strictEqual=function c(c,d,e){c!==d&&b(c,d,e,'===',a.strictEqual)},a.notStrictEqual=function c(c,d,e){c===d&&b(c,d,e,'!==',a.notStrictEqual)},a.throws=function(a,b,d){o.apply(this,[!0].concat(c.call(arguments)))},a.doesNotThrow=function(a,b,d){o.apply(this,[!1].concat(c.call(arguments)))},a.ifError=function(a){if(a)throw a}},{util:2,buffer:3}],2:[function(j,k,a){function b(a){return a instanceof Array||Array.isArray(a)||a&&a!==Object.prototype&&b(a.__proto__)}function d(a){return a instanceof RegExp||typeof a==='object'&&Object.prototype.toString.call(a)==='[object RegExp]'}function e(a){if(a instanceof Date)return!0;if(typeof a!=='object')return!1;var b=Date.prototype&&c(Date.prototype),d=a.__proto__&&c(a.__proto__);return JSON.stringify(d)===JSON.stringify(b)}var i=j('events');a.isArray=b,a.isDate=function(a){return Object.prototype.toString.call(a)==='[object Date]'},a.isRegExp=function(a){return Object.prototype.toString.call(a)==='[object RegExp]'},a.print=function(){},a.puts=function(){},a.debug=function(){},a.inspect=function(k,l,j,m){function i(j,p){if(j&&typeof j.inspect==='function'&&j!==a&&!(j.constructor&&j.constructor.prototype===j))return j.inspect(p);switch(typeof j){case'undefined':return f('undefined','undefined');case'string':var w="'"+JSON.stringify(j).replace(/^"|"$/g,'').replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return f(w,'string');case'number':return f(''+j,'number');case'boolean':return f(''+j,'boolean')}if(j===null)return f('null','null');var q=h(j),o=l?c(j):q;if(typeof j==='function'&&o.length===0)if(d(j))return f(''+j,'regexp');else{var t=j.name?': '+j.name:'';return f('[Function'+t+']','special')}if(e(j)&&o.length===0)return f(j.toUTCString(),'date');var m,r,k;if(b(j)?(r='Array',k=['[',']']):(r='Object',k=['{','}']),typeof j==='function'){var u=j.name?': '+j.name:'';m=d(j)?' '+j:' [Function'+u+']'}else m='';if(e(j)&&(m=' '+j.toUTCString()),o.length===0)return k[0]+m+k[1];if(p<0)return d(j)?f(''+j,'regexp'):f('[Object]','special');g.push(j);var n=o.map(function(d){var a,c;if(j.__lookupGetter__&&(j.__lookupGetter__(d)?j.__lookupSetter__(d)?c=f('[Getter/Setter]','special'):c=f('[Getter]','special'):j.__lookupSetter__(d)&&(c=f('[Setter]','special'))),q.indexOf(d)<0&&(a='['+d+']'),c||(g.indexOf(j[d])<0?(p===null?c=i(j[d]):c=i(j[d],p-1),c.indexOf('\n')>-1&&(b(j)?c=c.split('\n').map(function(a){return'  '+a}).join('\n').substr(2):c='\n'+c.split('\n').map(function(a){return'   '+a}).join('\n'))):c=f('[Circular]','special')),a===void 0){if(r==='Array'&&d.match(/^\d+$/))return c;a=JSON.stringify(''+d),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=f(a,'name')):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=f(a,'string'))}return a+': '+c});g.pop();var s=0,v=n.reduce(function(b,a){return s++,a.indexOf('\n')>=0&&s++,b+a.length+1},0);return v>50?n=k[0]+(m===''?'':m+'\n ')+' '+n.join(',\n  ')+' '+k[1]:n=k[0]+m+' '+n.join(', ')+' '+k[1],n}var g=[],f=function(c,d){var b={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},a={special:'cyan',number:'blue',boolean:'yellow',undefined:'grey',null:'bold',string:'green',date:'magenta',regexp:'red'}[d];return a?'['+b[a][0]+'m'+c+'['+b[a][1]+'m':c};return m||(f=function(a,b){return a}),i(k,j===void 0?2:j)},a.log=function(a){},a.pump=null;var h=Object.keys||function(c){var a=[];for(var b in c)a.push(b);return a},c=Object.getOwnPropertyNames||function(c){var a=[];for(var b in c)Object.hasOwnProperty.call(c,b)&&a.push(b);return a},g=Object.create||function(a,d){var b;if(a===null)b={__proto__:null};else{if(typeof a!=='object')throw new TypeError('typeof prototype['+typeof a+"] != 'object'");var c=function(){};c.prototype=a,b=new c,b.__proto__=a}return d!==void 0&&Object.defineProperties&&Object.defineProperties(b,d),b};a.inherits=function(a,b){a.super_=b,a.prototype=g(b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}})};var f=/%[sdj%]/g;a.format=function(i){if(typeof i!=='string'){var g=[];for(var b=0;b<arguments.length;b++)g.push(a.inspect(arguments[b]));return g.join(' ')}var b=1,c=arguments,h=c.length,e=String(i).replace(f,function(a){if(a==='%%')return'%';if(b>=h)return a;switch(a){case'%s':return String(c[b++]);case'%d':return Number(c[b++]);case'%j':return JSON.stringify(c[b++]);default:return a}});for(var d=c[b];b<h;d=c[++b])d===null||typeof d!=='object'?e+=' '+d:e+=' '+a.inspect(d);return e}},{events:4}],5:[function(b,c,a){a.readIEEE754=function(h,l,n,f,m){var b,d,i=m*8-f-1,j=(1<<i)-1,k=j>>1,a=-7,c=n?0:m-1,g=n?1:-1,e=h[l+c];for(c+=g,b=e&(1<<-a)-1,e>>=-a,a+=i;a>0;b=b*256+h[l+c],c+=g,a-=8);for(d=b&(1<<-a)-1,b>>=-a,a+=f;a>0;d=d*256+h[l+c],c+=g,a-=8);if(b===0)b=1-k;else if(b===j)return d?NaN:(e?-1:1)*Infinity;else d+=Math.pow(2,f),b-=k;return(e?-1:1)*d*Math.pow(2,b-f)},a.writeIEEE754=function(k,b,m,n,c,p){var a,d,f,h=p*8-c-1,i=(1<<h)-1,e=i>>1,l=c===23?Math.pow(2,-24)-Math.pow(2,-77):0,g=n?p-1:0,j=n?-1:1,o=b<0||b===0&&1/b<0?1:0;for(b=Math.abs(b),isNaN(b)||b===Infinity?(d=isNaN(b)?1:0,a=i):(a=Math.floor(Math.log(b)/Math.LN2),b*(f=Math.pow(2,-a))<1&&(a--,f*=2),a+e>=1?b+=l/f:b+=l*Math.pow(2,1-e),b*f>=2&&(a++,f/=2),a+e>=i?(d=0,a=i):a+e>=1?(d=(b*f-1)*Math.pow(2,c),a+=e):(d=b*Math.pow(2,e-1)*Math.pow(2,c),a=0));c>=8;k[m+g]=d&255,g+=j,d/=256,c-=8);for(a=a<<c|d,h+=c;h>0;k[m+g]=a&255,g+=j,a/=256,h-=8);k[m+g-j]|=o*128}},{}],6:[function(c,b,d){var a=b.exports={};a.nextTick=function(b,c,a){return b=typeof window!=='undefined'&&window.setImmediate,c=typeof window!=='undefined'&&window.postMessage&&window.addEventListener,b?function(a){return window.setImmediate(a)}:c?(a=[],window.addEventListener('message',function(b){if(b.source===window&&b.data==='process-tick'&&(b.stopPropagation(),a.length>0)){var c=a.shift();c()}},!0),function b(b){a.push(b),window.postMessage('process-tick','*')}):function a(a){setTimeout(a,0)}}(),a.title='browser',a.browser=!0,a.env={},a.argv=[],a.binding=function(a){throw new Error('process.binding is not supported')},a.cwd=function(){return'/'},a.chdir=function(a){throw new Error('process.chdir is not supported')}},{}],4:[function(a,c,b){!function(d,a,c,e){function f(b,c){if(b.indexOf)return b.indexOf(c);for(var a=0;a<b.length;a++)if(c===b[a])return a;return-1}d.EventEmitter||(d.EventEmitter=function(){}),a=b.EventEmitter=d.EventEmitter,c=typeof Array.isArray==='function'?Array.isArray:function(a){return Object.prototype.toString.call(a)==='[object Array]'},e=10,a.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},a.prototype.emit=function(f){if(f==='error'&&(!(this._events&&this._events.error)||c(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var a=this._events[f];if(!a)return!1;if(!(typeof a=='function'))if(c(a)){var b=Array.prototype.slice.call(arguments,1),e=a.slice();for(var d=0,g=e.length;d<g;d++)e[d].apply(this,b);return!0}else return!1;switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:var b=Array.prototype.slice.call(arguments,1);a.apply(this,b)}return!0},a.prototype.addListener=function(a,b){if('function'!==typeof b)throw new Error('addListener only takes instances of Function');if(this._events||(this._events={}),this.emit('newListener',a,b),!this._events[a])this._events[a]=b;else if(c(this._events[a])){if(!this._events[a].warned){var d;this._events.maxListeners!==undefined?d=this._events.maxListeners:d=e,d&&d>0&&this._events[a].length>d&&(this._events[a].warned=!0,console.error('(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.',this._events[a].length),console.trace())}this._events[a].push(b)}else this._events[a]=[this._events[a],b];return this},a.prototype.on=a.prototype.addListener,a.prototype.once=function(b,c){var a=this;return a.on(b,function d(){a.removeListener(b,d),c.apply(this,arguments)}),this},a.prototype.removeListener=function(a,d){if('function'!==typeof d)throw new Error('removeListener only takes instances of Function');if(!(this._events&&this._events[a]))return this;var b=this._events[a];if(c(b)){var e=f(b,d);if(e<0)return this;b.splice(e,1),b.length==0&&delete this._events[a]}else this._events[a]===d&&delete this._events[a];return this},a.prototype.removeAllListeners=function(a){return arguments.length===0?(this._events={},this):(a&&this._events&&this._events[a]&&(this._events[a]=null),this)},a.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),c(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]}}(a('__browserify_process'))},{__browserify_process:6}],'buffer-browserify':[function(a,b,c){b.exports=a('q9TxCC')},{}],q9TxCC:[function(e,E,f){function c(a){this.length=a}function i(a){return a<16?'0'+a.toString(16):a.toString(16)}function w(b){var c=[];for(var a=0;a<b.length;a++)if(b.charCodeAt(a)<=127)c.push(b.charCodeAt(a));else{var e=encodeURIComponent(b.charAt(a)).substr(1).split('%');for(var d=0;d<e.length;d++)c.push(parseInt(e[d],16))}return c}function B(c){var b=[];for(var a=0;a<c.length;a++)b.push(c.charCodeAt(a)&255);return b}function p(a){return e('base64-js').toByteArray(a)}function j(b,c,d,e){var a=0;while(a<e){if(a+d>=c.length||a>=b.length)break;c[a+d]=b[a],a++}return a}function u(a){try{return decodeURIComponent(a)}catch(a){return String.fromCharCode(65533)}}function l(a){return a=~~Math.ceil(+a),a<0?0:a}function a(b,f,g){if(!(this instanceof a))return new a(b,f,g);var h;if(typeof g==='number')this.length=l(f),this.parent=b,this.offset=g;else{switch(h=typeof b){case'number':this.length=l(b);break;case'string':this.length=a.byteLength(b,f);break;case'object':this.length=l(b.length);break;default:throw new Error('First argument needs to be a number, array or string.')}if(this.length>a.poolSize?(this.parent=new c(this.length),this.offset=0):((!d||d.length-d.used<this.length)&&C(),this.parent=d,this.offset=d.used,d.used+=this.length),D(b))for(var e=0;e<this.length;e++)b instanceof a?this.parent[e+this.offset]=b.readUInt8(e):this.parent[e+this.offset]=b[e];else h=='string'&&(this.length=this.write(b,0,f))}}function D(b){return Array.isArray(b)||a.isBuffer(b)||b&&typeof b==='object'&&typeof b.length==='number'}function C(){d=new c(a.poolSize),d.used=0}function o(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<a.length,'Trying to read beyond buffer length')),c>=a.length?0:(e?(d=a.parent[a.offset+c]<<8,c+1<a.length&&(d|=a.parent[a.offset+c+1])):(d=a.parent[a.offset+c],c+1<a.length&&(d|=a.parent[a.offset+c+1]<<8)),d)}function n(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),c>=a.length?0:(e?(c+1<a.length&&(d=a.parent[a.offset+c+1]<<16),c+2<a.length&&(d|=a.parent[a.offset+c+2]<<8),c+3<a.length&&(d|=a.parent[a.offset+c+3]),d+=a.parent[a.offset+c]<<24>>>0):(c+2<a.length&&(d=a.parent[a.offset+c+2]<<16),c+1<a.length&&(d|=a.parent[a.offset+c+1]<<8),d|=a.parent[a.offset+c],c+3<a.length&&(d+=a.parent[a.offset+c+3]<<24>>>0)),d)}function v(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+1<d.length,'Trying to read beyond buffer length')),c=o(d,a,e,f),g=c&32768,g?(65535-c+1)*-1:c}function r(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+3<d.length,'Trying to read beyond buffer length')),c=n(d,a,e,f),g=c&2147483648,g?(4294967295-c+1)*-1:c}function s(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,23,4)}function t(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+7<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,52,8)}function k(a,c){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a>=0,'specified a negative value for writing an unsigned value'),b.ok(a<=c,'value is larger than maximum value for type'),b.ok(Math.floor(a)===a,'value has a fractional component')}function h(d,e,c,f,g){g||(b.ok(e!==undefined&&e!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'trying to write beyond buffer length'),k(e,65535));for(var a=0;a<Math.min(d.length-c,2);a++)d.parent[d.offset+c+a]=(e&255<<8*(f?1-a:a))>>>(f?1-a:a)*8}function g(d,e,c,f,g){g||(b.ok(e!==undefined&&e!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'trying to write beyond buffer length'),k(e,4294967295));for(var a=0;a<Math.min(d.length-c,4);a++)d.parent[d.offset+c+a]=e>>>(f?3-a:a)*8&255}function m(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value'),b.ok(Math.floor(a)===a,'value has a fractional component')}function x(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value')}function y(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'Trying to write beyond buffer length'),m(a,32767,-32768)),a>=0?h(d,a,c,e,f):h(d,65535+a+1,c,e,f)}function z(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),m(a,2147483647,-2147483648)),a>=0?g(d,a,c,e,f):g(d,4294967295+a+1,c,e,f)}function A(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),x(a,3.4028234663852886e38,-3.4028234663852886e38)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,23,4)}function q(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+7<d.length,'Trying to write beyond buffer length'),x(a,1.7976931348623157e308,-1.7976931348623157e308)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,52,8)}var b=e('assert');f.INSPECT_MAX_BYTES=50,c.byteLength=function(a,b){switch(b||'utf8'){case'hex':return a.length/2;case'utf8':case'utf-8':return w(a).length;case'ascii':case'binary':return a.length;case'base64':return p(a).length;default:throw new Error('Unknown encoding')}},c.prototype.utf8Write=function(a,b,d){return c._charsWritten=j(w(a),this,b,d)},c.prototype.asciiWrite=function(a,b,d){return c._charsWritten=j(B(a),this,b,d)},c.prototype.binaryWrite=c.prototype.asciiWrite,c.prototype.base64Write=function(a,b,d){return c._charsWritten=j(p(a),this,b,d)},c.prototype.base64Slice=function(b,c){var a=Array.prototype.slice.apply(this,arguments);return e('base64-js').fromByteArray(a)},c.prototype.utf8Slice=function(){var b=Array.prototype.slice.apply(this,arguments),d='',c='',a=0;while(a<b.length)b[a]<=127?(d+=u(c)+String.fromCharCode(b[a]),c=''):c+='%'+b[a].toString(16),a++;return d+u(c)},c.prototype.asciiSlice=function(){var b=Array.prototype.slice.apply(this,arguments),c='';for(var a=0;a<b.length;a++)c+=String.fromCharCode(b[a]);return c},c.prototype.binarySlice=c.prototype.asciiSlice,c.prototype.inspect=function(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this[a]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<SlowBuffer '+b.join(' ')+'>'},c.prototype.hexSlice=function(b,a){var d=this.length;(!b||b<0)&&(b=0),(!a||a<0||a>d)&&(a=d);var e='';for(var c=b;c<a;c++)e+=i(this[c]);return e},c.prototype.toString=function(c,a,b){if(c=String(c||'utf8').toLowerCase(),a=+a||0,b===void 0&&(b=this.length),+b==a)return'';switch(c){case'hex':return this.hexSlice(a,b);case'utf8':case'utf-8':return this.utf8Slice(a,b);case'ascii':return this.asciiSlice(a,b);case'binary':return this.binarySlice(a,b);case'base64':return this.base64Slice(a,b);case'ucs2':case'ucs-2':return this.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},c.prototype.hexWrite=function(h,d,a){d=+d||0;var e=this.length-d;a?(a=+a,a>e&&(a=e)):a=e;var f=h.length;if(f%2)throw new Error('Invalid hex string');a>f/2&&(a=f/2);for(var b=0;b<a;b++){var g=parseInt(h.substr(b*2,2),16);if(isNaN(g))throw new Error('Invalid hex string');this[d+b]=g}return c._charsWritten=b*2,b},c.prototype.write=function(c,b,a,d){if(isFinite(b))isFinite(a)||(d=a,a=undefined);else{var f=d;d=b,b=a,a=f}b=+b||0;var e=this.length-b;a?(a=+a,a>e&&(a=e)):a=e,d=String(d||'utf8').toLowerCase();switch(d){case'hex':return this.hexWrite(c,b,a);case'utf8':case'utf-8':return this.utf8Write(c,b,a);case'ascii':return this.asciiWrite(c,b,a);case'binary':return this.binaryWrite(c,b,a);case'base64':return this.base64Write(c,b,a);case'ucs2':case'ucs-2':return this.ucs2Write(c,b,a);default:throw new Error('Unknown encoding')}},c.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this,b-c,+c)},c.prototype.copy=function(e,d,f,g){var c=[];for(var a=f;a<g;a++)b.ok(this[a]!==void 0,'copying undefined buffer bytes!'),c.push(this[a]);for(var a=d;a<d+c.length;a++)e[a]=c[a-d]},c.prototype.fill=function(d,c,b){if(b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');for(var a=c;a<b;a++)this[a]=d},f.SlowBuffer=c,f.Buffer=a,a.poolSize=8192;var d;a.isBuffer=function b(b){return b instanceof a||b instanceof c},a.concat=function(c,e){if(!Array.isArray(c))throw new Error('Usage: Buffer.concat(list, [totalLength])\n       list should be an Array.');if(c.length===0)return new a(0);if(c.length===1)return c[0];if(typeof e!=='number'){e=0;for(var b=0;b<c.length;b++){var d=c[b];e+=d.length}}var f=new a(e),g=0;for(var b=0;b<c.length;b++){var d=c[b];d.copy(f,g),g+=d.length}return f},a.prototype.inspect=function a(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this.parent[a+this.offset]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<Buffer '+b.join(' ')+'>'},a.prototype.get=function a(a){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]},a.prototype.set=function a(a,b){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]=b},a.prototype.write=function(f,d,b,g){if(isFinite(d))isFinite(b)||(g=b,b=undefined);else{var i=g;g=d,d=b,b=i}d=+d||0;var h=this.length-d;b?(b=+b,b>h&&(b=h)):b=h,g=String(g||'utf8').toLowerCase();var e;switch(g){case'hex':e=this.parent.hexWrite(f,this.offset+d,b);break;case'utf8':case'utf-8':e=this.parent.utf8Write(f,this.offset+d,b);break;case'ascii':e=this.parent.asciiWrite(f,this.offset+d,b);break;case'binary':e=this.parent.binaryWrite(f,this.offset+d,b);break;case'base64':e=this.parent.base64Write(f,this.offset+d,b);break;case'ucs2':case'ucs-2':e=this.parent.ucs2Write(f,this.offset+d,b);break;default:throw new Error('Unknown encoding')}return a._charsWritten=c._charsWritten,e},a.prototype.toString=function(c,a,b){c=String(c||'utf8').toLowerCase(),a===void 0||a<0?a=0:a>this.length&&(a=this.length),b===void 0||b>this.length?b=this.length:b<0&&(b=0),a+=this.offset,b+=this.offset;switch(c){case'hex':return this.parent.hexSlice(a,b);case'utf8':case'utf-8':return this.parent.utf8Slice(a,b);case'ascii':return this.parent.asciiSlice(a,b);case'binary':return this.parent.binarySlice(a,b);case'base64':return this.parent.base64Slice(a,b);case'ucs2':case'ucs-2':return this.parent.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},a.byteLength=c.byteLength,a.prototype.fill=function a(a,b,c){if(a||(a=0),b||(b=0),c||(c=this.length),typeof a==='string'&&(a=a.charCodeAt(0)),!(typeof a==='number')||isNaN(a))throw new Error('value is not a number');if(c<b)throw new Error('end < start');if(c===b)return 0;if(this.length==0)return 0;if(b<0||b>=this.length)throw new Error('start out of bounds');if(c<0||c>this.length)throw new Error('end out of bounds');return this.parent.fill(a,b+this.offset,c+this.offset)},a.prototype.copy=function(d,c,b,a){var e=this;if(b||(b=0),a||(a=this.length),c||(c=0),a<b)throw new Error('sourceEnd < sourceStart');if(a===b)return 0;if(d.length==0||e.length==0)return 0;if(c<0||c>=d.length)throw new Error('targetStart out of bounds');if(b<0||b>=e.length)throw new Error('sourceStart out of bounds');if(a<0||a>e.length)throw new Error('sourceEnd out of bounds');return a>this.length&&(a=this.length),d.length-c<a-b&&(a=d.length-c+b),this.parent.copy(d.parent,c+d.offset,b+this.offset,a+this.offset)},a.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this.parent,b-c,+c+this.offset)},a.prototype.utf8Slice=function(a,b){return this.toString('utf8',a,b)},a.prototype.binarySlice=function(a,b){return this.toString('binary',a,b)},a.prototype.asciiSlice=function(a,b){return this.toString('ascii',a,b)},a.prototype.utf8Write=function(a,b){return this.write(a,b,'utf8')},a.prototype.binaryWrite=function(a,b){return this.write(a,b,'binary')},a.prototype.asciiWrite=function(a,b){return this.write(a,b,'ascii')},a.prototype.readUInt8=function(a,d){var c=this;return d||(b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'Trying to read beyond buffer length')),a>=c.length?void 0:c.parent[c.offset+a]},a.prototype.readUInt16LE=function(a,b){return o(this,a,!1,b)},a.prototype.readUInt16BE=function(a,b){return o(this,a,!0,b)},a.prototype.readUInt32LE=function(a,b){return n(this,a,!1,b)},a.prototype.readUInt32BE=function(a,b){return n(this,a,!0,b)},a.prototype.readInt8=function(c,e){var a=this,d;return e||(b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<a.length,'Trying to read beyond buffer length')),c>=a.length?void 0:(d=a.parent[a.offset+c]&128,d?(255-a.parent[a.offset+c]+1)*-1:a.parent[a.offset+c])},a.prototype.readInt16LE=function(a,b){return v(this,a,!1,b)},a.prototype.readInt16BE=function(a,b){return v(this,a,!0,b)},a.prototype.readInt32LE=function(a,b){return r(this,a,!1,b)},a.prototype.readInt32BE=function(a,b){return r(this,a,!0,b)},a.prototype.readFloatLE=function(a,b){return s(this,a,!1,b)},a.prototype.readFloatBE=function(a,b){return s(this,a,!0,b)},a.prototype.readDoubleLE=function(a,b){return t(this,a,!1,b)},a.prototype.readDoubleBE=function(a,b){return t(this,a,!0,b)},a.prototype.writeUInt8=function(d,a,e){var c=this;e||(b.ok(d!==undefined&&d!==null,'missing value'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'trying to write beyond buffer length'),k(d,255)),a<c.length&&(c.parent[c.offset+a]=d)},a.prototype.writeUInt16LE=function(a,b,c){h(this,a,b,!1,c)},a.prototype.writeUInt16BE=function(a,b,c){h(this,a,b,!0,c)},a.prototype.writeUInt32LE=function(a,b,c){g(this,a,b,!1,c)},a.prototype.writeUInt32BE=function(a,b,c){g(this,a,b,!0,c)},a.prototype.writeInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'Trying to write beyond buffer length'),m(a,127,-128)),a>=0?d.writeUInt8(a,c,e):d.writeUInt8(255+a+1,c,e)},a.prototype.writeInt16LE=function(a,b,c){y(this,a,b,!1,c)},a.prototype.writeInt16BE=function(a,b,c){y(this,a,b,!0,c)},a.prototype.writeInt32LE=function(a,b,c){z(this,a,b,!1,c)},a.prototype.writeInt32BE=function(a,b,c){z(this,a,b,!0,c)},a.prototype.writeFloatLE=function(a,b,c){A(this,a,b,!1,c)},a.prototype.writeFloatBE=function(a,b,c){A(this,a,b,!0,c)},a.prototype.writeDoubleLE=function(a,b,c){q(this,a,b,!1,c)},a.prototype.writeDoubleBE=function(a,b,c){q(this,a,b,!0,c)},c.prototype.readUInt8=a.prototype.readUInt8,c.prototype.readUInt16LE=a.prototype.readUInt16LE,c.prototype.readUInt16BE=a.prototype.readUInt16BE,c.prototype.readUInt32LE=a.prototype.readUInt32LE,c.prototype.readUInt32BE=a.prototype.readUInt32BE,c.prototype.readInt8=a.prototype.readInt8,c.prototype.readInt16LE=a.prototype.readInt16LE,c.prototype.readInt16BE=a.prototype.readInt16BE,c.prototype.readInt32LE=a.prototype.readInt32LE,c.prototype.readInt32BE=a.prototype.readInt32BE,c.prototype.readFloatLE=a.prototype.readFloatLE,c.prototype.readFloatBE=a.prototype.readFloatBE,c.prototype.readDoubleLE=a.prototype.readDoubleLE,c.prototype.readDoubleBE=a.prototype.readDoubleBE,c.prototype.writeUInt8=a.prototype.writeUInt8,c.prototype.writeUInt16LE=a.prototype.writeUInt16LE,c.prototype.writeUInt16BE=a.prototype.writeUInt16BE,c.prototype.writeUInt32LE=a.prototype.writeUInt32LE,c.prototype.writeUInt32BE=a.prototype.writeUInt32BE,c.prototype.writeInt8=a.prototype.writeInt8,c.prototype.writeInt16LE=a.prototype.writeInt16LE,c.prototype.writeInt16BE=a.prototype.writeInt16BE,c.prototype.writeInt32LE=a.prototype.writeInt32LE,c.prototype.writeInt32BE=a.prototype.writeInt32BE,c.prototype.writeFloatLE=a.prototype.writeFloatLE,c.prototype.writeFloatBE=a.prototype.writeFloatBE,c.prototype.writeDoubleLE=a.prototype.writeDoubleLE,c.prototype.writeDoubleBE=a.prototype.writeDoubleBE},{assert:1,'./buffer_ieee754':5,'base64-js':7}],7:[function(b,a,c){!function(e){'use strict';function c(a){var c,g,h,d,f,e;if(a.length%4>0)throw'Invalid string. Length must be a multiple of 4';for(f=a.indexOf('='),f=f>0?a.length-f:0,e=[],h=f>0?a.length-4:a.length,c=0,g=0;c<h;c+=4,g+=3)d=b.indexOf(a[c])<<18|b.indexOf(a[c+1])<<12|b.indexOf(a[c+2])<<6|b.indexOf(a[c+3]),e.push((d&16711680)>>16),e.push((d&65280)>>8),e.push(d&255);return f===2?(d=b.indexOf(a[c])<<2|b.indexOf(a[c+1])>>4,e.push(d&255)):f===1&&(d=b.indexOf(a[c])<<10|b.indexOf(a[c+1])<<4|b.indexOf(a[c+2])>>2,e.push(d>>8&255),e.push(d&255)),e}function d(a){function h(a){return b[a>>18&63]+b[a>>12&63]+b[a>>6&63]+b[a&63]}var e,f=a.length%3,c='',d,g;for(e=0,g=a.length-f;e<g;e+=3)d=(a[e]<<16)+(a[e+1]<<8)+a[e+2],c+=h(d);switch(f){case 1:d=a[a.length-1];c+=b[d>>2];c+=b[d<<4&63];c+='==';break;case 2:d=(a[a.length-2]<<8)+a[a.length-1];c+=b[d>>10];c+=b[d>>4&63];c+=b[d<<2&63];c+='=';break}return c}var b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';a.exports.toByteArray=c,a.exports.fromByteArray=d}()},{}],8:[function(b,c,a){a.readIEEE754=function(h,l,n,f,m){var b,d,i=m*8-f-1,j=(1<<i)-1,k=j>>1,a=-7,c=n?0:m-1,g=n?1:-1,e=h[l+c];for(c+=g,b=e&(1<<-a)-1,e>>=-a,a+=i;a>0;b=b*256+h[l+c],c+=g,a-=8);for(d=b&(1<<-a)-1,b>>=-a,a+=f;a>0;d=d*256+h[l+c],c+=g,a-=8);if(b===0)b=1-k;else if(b===j)return d?NaN:(e?-1:1)*Infinity;else d+=Math.pow(2,f),b-=k;return(e?-1:1)*d*Math.pow(2,b-f)},a.writeIEEE754=function(k,b,m,n,c,p){var a,d,f,h=p*8-c-1,i=(1<<h)-1,e=i>>1,l=c===23?Math.pow(2,-24)-Math.pow(2,-77):0,g=n?p-1:0,j=n?-1:1,o=b<0||b===0&&1/b<0?1:0;for(b=Math.abs(b),isNaN(b)||b===Infinity?(d=isNaN(b)?1:0,a=i):(a=Math.floor(Math.log(b)/Math.LN2),b*(f=Math.pow(2,-a))<1&&(a--,f*=2),a+e>=1?b+=l/f:b+=l*Math.pow(2,1-e),b*f>=2&&(a++,f/=2),a+e>=i?(d=0,a=i):a+e>=1?(d=(b*f-1)*Math.pow(2,c),a+=e):(d=b*Math.pow(2,e-1)*Math.pow(2,c),a=0));c>=8;k[m+g]=d&255,g+=j,d/=256,c-=8);for(a=a<<c|d,h+=c;h>0;k[m+g]=a&255,g+=j,a/=256,h-=8);k[m+g-j]|=o*128}},{}],3:[function(e,E,f){function c(a){this.length=a}function i(a){return a<16?'0'+a.toString(16):a.toString(16)}function w(b){var c=[];for(var a=0;a<b.length;a++)if(b.charCodeAt(a)<=127)c.push(b.charCodeAt(a));else{var e=encodeURIComponent(b.charAt(a)).substr(1).split('%');for(var d=0;d<e.length;d++)c.push(parseInt(e[d],16))}return c}function B(c){var b=[];for(var a=0;a<c.length;a++)b.push(c.charCodeAt(a)&255);return b}function p(a){return e('base64-js').toByteArray(a)}function j(b,c,d,e){var a=0;while(a<e){if(a+d>=c.length||a>=b.length)break;c[a+d]=b[a],a++}return a}function u(a){try{return decodeURIComponent(a)}catch(a){return String.fromCharCode(65533)}}function l(a){return a=~~Math.ceil(+a),a<0?0:a}function a(b,f,g){if(!(this instanceof a))return new a(b,f,g);var h;if(typeof g==='number')this.length=l(f),this.parent=b,this.offset=g;else{switch(h=typeof b){case'number':this.length=l(b);break;case'string':this.length=a.byteLength(b,f);break;case'object':this.length=l(b.length);break;default:throw new Error('First argument needs to be a number, array or string.')}if(this.length>a.poolSize?(this.parent=new c(this.length),this.offset=0):((!d||d.length-d.used<this.length)&&C(),this.parent=d,this.offset=d.used,d.used+=this.length),D(b))for(var e=0;e<this.length;e++)this.parent[e+this.offset]=b[e];else h=='string'&&(this.length=this.write(b,0,f))}}function D(b){return Array.isArray(b)||a.isBuffer(b)||b&&typeof b==='object'&&typeof b.length==='number'}function C(){d=new c(a.poolSize),d.used=0}function o(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<a.length,'Trying to read beyond buffer length')),e?(d=a.parent[a.offset+c]<<8,d|=a.parent[a.offset+c+1]):(d=a.parent[a.offset+c],d|=a.parent[a.offset+c+1]<<8),d}function n(a,c,e,f){var d=0;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e?(d=a.parent[a.offset+c+1]<<16,d|=a.parent[a.offset+c+2]<<8,d|=a.parent[a.offset+c+3],d+=a.parent[a.offset+c]<<24>>>0):(d=a.parent[a.offset+c+2]<<16,d|=a.parent[a.offset+c+1]<<8,d|=a.parent[a.offset+c],d+=a.parent[a.offset+c+3]<<24>>>0),d}function v(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+1<d.length,'Trying to read beyond buffer length')),c=o(d,a,e,f),g=c&32768,g?(65535-c+1)*-1:c}function r(d,a,e,f){var g,c;return f||(b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a+3<d.length,'Trying to read beyond buffer length')),c=n(d,a,e,f),g=c&2147483648,g?(4294967295-c+1)*-1:c}function s(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+3<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,23,4)}function t(a,c,d,f){return f||(b.ok(typeof d==='boolean','missing or invalid endian'),b.ok(c+7<a.length,'Trying to read beyond buffer length')),e('./buffer_ieee754').readIEEE754(a,c,d,52,8)}function k(a,c){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a>=0,'specified a negative value for writing an unsigned value'),b.ok(a<=c,'value is larger than maximum value for type'),b.ok(Math.floor(a)===a,'value has a fractional component')}function h(a,c,d,e,f){f||(b.ok(c!==undefined&&c!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(d!==undefined&&d!==null,'missing offset'),b.ok(d+1<a.length,'trying to write beyond buffer length'),k(c,65535)),e?(a.parent[a.offset+d]=(c&65280)>>>8,a.parent[a.offset+d+1]=c&255):(a.parent[a.offset+d+1]=(c&65280)>>>8,a.parent[a.offset+d]=c&255)}function g(a,c,d,e,f){f||(b.ok(c!==undefined&&c!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(d!==undefined&&d!==null,'missing offset'),b.ok(d+3<a.length,'trying to write beyond buffer length'),k(c,4294967295)),e?(a.parent[a.offset+d]=c>>>24&255,a.parent[a.offset+d+1]=c>>>16&255,a.parent[a.offset+d+2]=c>>>8&255,a.parent[a.offset+d+3]=c&255):(a.parent[a.offset+d+3]=c>>>24&255,a.parent[a.offset+d+2]=c>>>16&255,a.parent[a.offset+d+1]=c>>>8&255,a.parent[a.offset+d]=c&255)}function m(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value'),b.ok(Math.floor(a)===a,'value has a fractional component')}function x(a,c,d){b.ok(typeof a=='number','cannot write a non-number as a number'),b.ok(a<=c,'value larger than maximum allowed value'),b.ok(a>=d,'value smaller than minimum allowed value')}function y(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+1<d.length,'Trying to write beyond buffer length'),m(a,32767,-32768)),a>=0?h(d,a,c,e,f):h(d,65535+a+1,c,e,f)}function z(d,a,c,e,f){f||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof e==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),m(a,2147483647,-2147483648)),a>=0?g(d,a,c,e,f):g(d,4294967295+a+1,c,e,f)}function A(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+3<d.length,'Trying to write beyond buffer length'),x(a,3.4028234663852886e38,-3.4028234663852886e38)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,23,4)}function q(d,a,c,f,g){g||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(typeof f==='boolean','missing or invalid endian'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c+7<d.length,'Trying to write beyond buffer length'),x(a,1.7976931348623157e308,-1.7976931348623157e308)),e('./buffer_ieee754').writeIEEE754(d,a,c,f,52,8)}var b=e('assert');f.INSPECT_MAX_BYTES=50,c.byteLength=function(a,b){switch(b||'utf8'){case'hex':return a.length/2;case'utf8':case'utf-8':return w(a).length;case'ascii':return a.length;case'base64':return p(a).length;default:throw new Error('Unknown encoding')}},c.prototype.utf8Write=function(a,b,d){return c._charsWritten=j(w(a),this,b,d)},c.prototype.asciiWrite=function(a,b,d){return c._charsWritten=j(B(a),this,b,d)},c.prototype.base64Write=function(a,b,d){return c._charsWritten=j(p(a),this,b,d)},c.prototype.base64Slice=function(b,c){var a=Array.prototype.slice.apply(this,arguments);return e('base64-js').fromByteArray(a)},c.prototype.utf8Slice=function(){var b=Array.prototype.slice.apply(this,arguments),d='',c='',a=0;while(a<b.length)b[a]<=127?(d+=u(c)+String.fromCharCode(b[a]),c=''):c+='%'+b[a].toString(16),a++;return d+u(c)},c.prototype.asciiSlice=function(){var b=Array.prototype.slice.apply(this,arguments),c='';for(var a=0;a<b.length;a++)c+=String.fromCharCode(b[a]);return c},c.prototype.inspect=function(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this[a]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<SlowBuffer '+b.join(' ')+'>'},c.prototype.hexSlice=function(b,a){var d=this.length;(!b||b<0)&&(b=0),(!a||a<0||a>d)&&(a=d);var e='';for(var c=b;c<a;c++)e+=i(this[c]);return e},c.prototype.toString=function(c,a,b){if(c=String(c||'utf8').toLowerCase(),a=+a||0,b===void 0&&(b=this.length),+b==a)return'';switch(c){case'hex':return this.hexSlice(a,b);case'utf8':case'utf-8':return this.utf8Slice(a,b);case'ascii':return this.asciiSlice(a,b);case'binary':return this.binarySlice(a,b);case'base64':return this.base64Slice(a,b);case'ucs2':case'ucs-2':return this.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},c.prototype.hexWrite=function(h,d,a){d=+d||0;var e=this.length-d;a?(a=+a,a>e&&(a=e)):a=e;var f=h.length;if(f%2)throw new Error('Invalid hex string');a>f/2&&(a=f/2);for(var b=0;b<a;b++){var g=parseInt(h.substr(b*2,2),16);if(isNaN(g))throw new Error('Invalid hex string');this[d+b]=g}return c._charsWritten=b*2,b},c.prototype.write=function(c,b,a,d){if(isFinite(b))isFinite(a)||(d=a,a=undefined);else{var f=d;d=b,b=a,a=f}b=+b||0;var e=this.length-b;a?(a=+a,a>e&&(a=e)):a=e,d=String(d||'utf8').toLowerCase();switch(d){case'hex':return this.hexWrite(c,b,a);case'utf8':case'utf-8':return this.utf8Write(c,b,a);case'ascii':return this.asciiWrite(c,b,a);case'binary':return this.binaryWrite(c,b,a);case'base64':return this.base64Write(c,b,a);case'ucs2':case'ucs-2':return this.ucs2Write(c,b,a);default:throw new Error('Unknown encoding')}},c.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this,b-c,+c)},c.prototype.copy=function(e,d,f,g){var c=[];for(var a=f;a<g;a++)b.ok(this[a]!==void 0,'copying undefined buffer bytes!'),c.push(this[a]);for(var a=d;a<d+c.length;a++)e[a]=c[a-d]},f.SlowBuffer=c,f.Buffer=a,a.poolSize=8192;var d;a.isBuffer=function b(b){return b instanceof a||b instanceof c},a.concat=function(c,e){if(!Array.isArray(c))throw new Error('Usage: Buffer.concat(list, [totalLength])\n       list should be an Array.');if(c.length===0)return new a(0);if(c.length===1)return c[0];if(typeof e!=='number'){e=0;for(var b=0;b<c.length;b++){var d=c[b];e+=d.length}}var f=new a(e),g=0;for(var b=0;b<c.length;b++){var d=c[b];d.copy(f,g),g+=d.length}return f},a.prototype.inspect=function a(){var b=[],c=this.length;for(var a=0;a<c;a++)if(b[a]=i(this.parent[a+this.offset]),a==f.INSPECT_MAX_BYTES){b[a+1]='...';break}return'<Buffer '+b.join(' ')+'>'},a.prototype.get=function a(a){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]},a.prototype.set=function a(a,b){if(a<0||a>=this.length)throw new Error('oob');return this.parent[this.offset+a]=b},a.prototype.write=function(f,d,b,g){if(isFinite(d))isFinite(b)||(g=b,b=undefined);else{var i=g;g=d,d=b,b=i}d=+d||0;var h=this.length-d;b?(b=+b,b>h&&(b=h)):b=h,g=String(g||'utf8').toLowerCase();var e;switch(g){case'hex':e=this.parent.hexWrite(f,this.offset+d,b);break;case'utf8':case'utf-8':e=this.parent.utf8Write(f,this.offset+d,b);break;case'ascii':e=this.parent.asciiWrite(f,this.offset+d,b);break;case'binary':e=this.parent.binaryWrite(f,this.offset+d,b);break;case'base64':e=this.parent.base64Write(f,this.offset+d,b);break;case'ucs2':case'ucs-2':e=this.parent.ucs2Write(f,this.offset+d,b);break;default:throw new Error('Unknown encoding')}return a._charsWritten=c._charsWritten,e},a.prototype.toString=function(c,a,b){c=String(c||'utf8').toLowerCase(),a===void 0||a<0?a=0:a>this.length&&(a=this.length),b===void 0||b>this.length?b=this.length:b<0&&(b=0),a+=this.offset,b+=this.offset;switch(c){case'hex':return this.parent.hexSlice(a,b);case'utf8':case'utf-8':return this.parent.utf8Slice(a,b);case'ascii':return this.parent.asciiSlice(a,b);case'binary':return this.parent.binarySlice(a,b);case'base64':return this.parent.base64Slice(a,b);case'ucs2':case'ucs-2':return this.parent.ucs2Slice(a,b);default:throw new Error('Unknown encoding')}},a.byteLength=c.byteLength,a.prototype.fill=function a(a,b,c){if(a||(a=0),b||(b=0),c||(c=this.length),typeof a==='string'&&(a=a.charCodeAt(0)),!(typeof a==='number')||isNaN(a))throw new Error('value is not a number');if(c<b)throw new Error('end < start');if(c===b)return 0;if(this.length==0)return 0;if(b<0||b>=this.length)throw new Error('start out of bounds');if(c<0||c>this.length)throw new Error('end out of bounds');return this.parent.fill(a,b+this.offset,c+this.offset)},a.prototype.copy=function(d,c,b,a){var e=this;if(b||(b=0),a||(a=this.length),c||(c=0),a<b)throw new Error('sourceEnd < sourceStart');if(a===b)return 0;if(d.length==0||e.length==0)return 0;if(c<0||c>=d.length)throw new Error('targetStart out of bounds');if(b<0||b>=e.length)throw new Error('sourceStart out of bounds');if(a<0||a>e.length)throw new Error('sourceEnd out of bounds');return a>this.length&&(a=this.length),d.length-c<a-b&&(a=d.length-c+b),this.parent.copy(d.parent,c+d.offset,b+this.offset,a+this.offset)},a.prototype.slice=function(c,b){if(b===undefined&&(b=this.length),b>this.length)throw new Error('oob');if(c>b)throw new Error('oob');return new a(this.parent,b-c,+c+this.offset)},a.prototype.utf8Slice=function(a,b){return this.toString('utf8',a,b)},a.prototype.binarySlice=function(a,b){return this.toString('binary',a,b)},a.prototype.asciiSlice=function(a,b){return this.toString('ascii',a,b)},a.prototype.utf8Write=function(a,b){return this.write(a,b,'utf8')},a.prototype.binaryWrite=function(a,b){return this.write(a,b,'binary')},a.prototype.asciiWrite=function(a,b){return this.write(a,b,'ascii')},a.prototype.readUInt8=function(a,d){var c=this;return d||(b.ok(a!==undefined&&a!==null,'missing offset'),b.ok(a<c.length,'Trying to read beyond buffer length')),c.parent[c.offset+a]},a.prototype.readUInt16LE=function(a,b){return o(this,a,!1,b)},a.prototype.readUInt16BE=function(a,b){return o(this,a,!0,b)},a.prototype.readUInt32LE=function(a,b){return n(this,a,!1,b)},a.prototype.readUInt32BE=function(a,b){return n(this,a,!0,b)},a.prototype.readInt8=function(c,e){var a=this,d;return e||(b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<a.length,'Trying to read beyond buffer length')),d=a.parent[a.offset+c]&128,d?(255-a.parent[a.offset+c]+1)*-1:a.parent[a.offset+c]},a.prototype.readInt16LE=function(a,b){return v(this,a,!1,b)},a.prototype.readInt16BE=function(a,b){return v(this,a,!0,b)},a.prototype.readInt32LE=function(a,b){return r(this,a,!1,b)},a.prototype.readInt32BE=function(a,b){return r(this,a,!0,b)},a.prototype.readFloatLE=function(a,b){return s(this,a,!1,b)},a.prototype.readFloatBE=function(a,b){return s(this,a,!0,b)},a.prototype.readDoubleLE=function(a,b){return t(this,a,!1,b)},a.prototype.readDoubleBE=function(a,b){return t(this,a,!0,b)},a.prototype.writeUInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'trying to write beyond buffer length'),k(a,255)),d.parent[d.offset+c]=a},a.prototype.writeUInt16LE=function(a,b,c){h(this,a,b,!1,c)},a.prototype.writeUInt16BE=function(a,b,c){h(this,a,b,!0,c)},a.prototype.writeUInt32LE=function(a,b,c){g(this,a,b,!1,c)},a.prototype.writeUInt32BE=function(a,b,c){g(this,a,b,!0,c)},a.prototype.writeInt8=function(a,c,e){var d=this;e||(b.ok(a!==undefined&&a!==null,'missing value'),b.ok(c!==undefined&&c!==null,'missing offset'),b.ok(c<d.length,'Trying to write beyond buffer length'),m(a,127,-128)),a>=0?d.writeUInt8(a,c,e):d.writeUInt8(255+a+1,c,e)},a.prototype.writeInt16LE=function(a,b,c){y(this,a,b,!1,c)},a.prototype.writeInt16BE=function(a,b,c){y(this,a,b,!0,c)},a.prototype.writeInt32LE=function(a,b,c){z(this,a,b,!1,c)},a.prototype.writeInt32BE=function(a,b,c){z(this,a,b,!0,c)},a.prototype.writeFloatLE=function(a,b,c){A(this,a,b,!1,c)},a.prototype.writeFloatBE=function(a,b,c){A(this,a,b,!0,c)},a.prototype.writeDoubleLE=function(a,b,c){q(this,a,b,!1,c)},a.prototype.writeDoubleBE=function(a,b,c){q(this,a,b,!0,c)},c.prototype.readUInt8=a.prototype.readUInt8,c.prototype.readUInt16LE=a.prototype.readUInt16LE,c.prototype.readUInt16BE=a.prototype.readUInt16BE,c.prototype.readUInt32LE=a.prototype.readUInt32LE,c.prototype.readUInt32BE=a.prototype.readUInt32BE,c.prototype.readInt8=a.prototype.readInt8,c.prototype.readInt16LE=a.prototype.readInt16LE,c.prototype.readInt16BE=a.prototype.readInt16BE,c.prototype.readInt32LE=a.prototype.readInt32LE,c.prototype.readInt32BE=a.prototype.readInt32BE,c.prototype.readFloatLE=a.prototype.readFloatLE,c.prototype.readFloatBE=a.prototype.readFloatBE,c.prototype.readDoubleLE=a.prototype.readDoubleLE,c.prototype.readDoubleBE=a.prototype.readDoubleBE,c.prototype.writeUInt8=a.prototype.writeUInt8,c.prototype.writeUInt16LE=a.prototype.writeUInt16LE,c.prototype.writeUInt16BE=a.prototype.writeUInt16BE,c.prototype.writeUInt32LE=a.prototype.writeUInt32LE,c.prototype.writeUInt32BE=a.prototype.writeUInt32BE,c.prototype.writeInt8=a.prototype.writeInt8,c.prototype.writeInt16LE=a.prototype.writeInt16LE,c.prototype.writeInt16BE=a.prototype.writeInt16BE,c.prototype.writeInt32LE=a.prototype.writeInt32LE,c.prototype.writeInt32BE=a.prototype.writeInt32BE,c.prototype.writeFloatLE=a.prototype.writeFloatLE,c.prototype.writeFloatBE=a.prototype.writeFloatBE,c.prototype.writeDoubleLE=a.prototype.writeDoubleLE,c.prototype.writeDoubleBE=a.prototype.writeDoubleBE},{assert:1,'./buffer_ieee754':8,'base64-js':9}],9:[function(b,a,c){!function(e){'use strict';function c(a){var c,g,h,d,f,e;if(a.length%4>0)throw'Invalid string. Length must be a multiple of 4';for(f=a.indexOf('='),f=f>0?a.length-f:0,e=[],h=f>0?a.length-4:a.length,c=0,g=0;c<h;c+=4,g+=3)d=b.indexOf(a[c])<<18|b.indexOf(a[c+1])<<12|b.indexOf(a[c+2])<<6|b.indexOf(a[c+3]),e.push((d&16711680)>>16),e.push((d&65280)>>8),e.push(d&255);return f===2?(d=b.indexOf(a[c])<<2|b.indexOf(a[c+1])>>4,e.push(d&255)):f===1&&(d=b.indexOf(a[c])<<10|b.indexOf(a[c+1])<<4|b.indexOf(a[c+2])>>2,e.push(d>>8&255),e.push(d&255)),e}function d(a){function h(a){return b[a>>18&63]+b[a>>12&63]+b[a>>6&63]+b[a&63]}var e,f=a.length%3,c='',d,g;for(e=0,g=a.length-f;e<g;e+=3)d=(a[e]<<16)+(a[e+1]<<8)+a[e+2],c+=h(d);switch(f){case 1:d=a[a.length-1];c+=b[d>>2];c+=b[d<<4&63];c+='==';break;case 2:d=(a[a.length-2]<<8)+a[a.length-1];c+=b[d>>10];c+=b[d>>4&63];c+=b[d<<2&63];c+='=';break}return c}var b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';a.exports.toByteArray=c,a.exports.fromByteArray=d}()},{}]},{},[]),b.exports=a('buffer-browserify')},{}],14:[function(c,b,d){var a=b.exports={};a.nextTick=function(b,c,a){return b=typeof window!=='undefined'&&window.setImmediate,c=typeof window!=='undefined'&&window.postMessage&&window.addEventListener,b?function(a){return window.setImmediate(a)}:c?(a=[],window.addEventListener('message',function(b){var c=b.source;if((c===window||c===null)&&b.data==='process-tick'&&(b.stopPropagation(),a.length>0)){var d=a.shift();d()}},!0),function b(b){a.push(b),window.postMessage('process-tick','*')}):function a(a){setTimeout(a,0)}}(),a.title='browser',a.browser=!0,a.env={},a.argv=[],a.binding=function(a){throw new Error('process.binding is not supported')},a.cwd=function(){return'/'},a.chdir=function(a){throw new Error('process.chdir is not supported')}},{}],15:[function(c,e,a){var d=c('events').EventEmitter,b=c('through');a=e.exports=function(b){return typeof b.pipe==='function'?a.fromStream(b):a.toStream(b)},a.toStream=function(a){var c=b(function a(a){this.emit('data',a)},function b(){var b=a._emitStreams.indexOf(c);a._emitStreams.splice(b,1)});if(!a._emitStreams){a._emitStreams=[];var d=a.emit;a.emit=function(){var b=[].slice.call(arguments);a._emitStreams.forEach(function(a){a.writable&&a.write(b)}),d.apply(a,arguments)}}return a._emitStreams.push(c),c},a.fromStream=function(c){var a=new d;return c.pipe(b(function(b){a.emit.apply(a,b)})),a}},{events:7,through:16}],16:[function(b,e,f){function a(g,f,j){function k(){while(b.length&&!a.paused){var c=b.shift();if(null===c)return a.emit('end');a.emit('data',c)}}function l(){a.writable=!1,f.call(a),!a.readable&&a.autoDestroy&&a.destroy()}g=g||function(a){this.queue(a)},f=f||function(){this.queue(null)};var e=!1,h=!1,b=[],i=!1,a=new d;return a.readable=a.writable=!0,a.paused=!1,a.autoDestroy=!(j&&j.autoDestroy===!1),a.write=function(b){return g.call(this,b),!a.paused},a.queue=a.push=function(c){return i?a:(c==null&&(i=!0),b.push(c),k(),a)},a.on('end',function(){a.readable=!1,!a.writable&&a.autoDestroy&&c.nextTick(function(){a.destroy()})}),a.end=function(b){return e?void 0:(e=!0,arguments.length&&a.write(b),l(),a)},a.destroy=function(){return h?void 0:(h=!0,e=!0,b.length=0,a.writable=a.readable=!1,a.emit('close'),a)},a.pause=function(){return a.paused?void 0:(a.paused=!0,a)},a.resume=function(){return a.paused&&(a.paused=!1,a.emit('resume')),k(),a.paused||a.emit('drain'),a},a}var c=b('__browserify_process'),d=b('stream');f=e.exports=a,a.through=a},{__browserify_process:14,stream:10}],17:[function(a,b,c){!function(a){typeof define=='function'?define(a):typeof YUI=='function'?YUI.add('es5',a):a()}(function(){function j(){}function q(a){return a=+a,a!==a?a=0:a!==0&&a!==1/0&&a!==-(1/0)&&(a=(a>0||-1)*Math.floor(Math.abs(a))),a}function i(b){var a=typeof b;return b===null||a==='undefined'||a==='boolean'||a==='number'||a==='string'}function F(a){var b,c,d;if(i(a))return a;if(c=a.valueOf,typeof c==='function'&&(b=c.call(a),i(b)))return b;if(d=a.toString,typeof d==='function'&&(b=d.call(a),i(b)))return b;throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function a(d){var a=this;if(typeof a!='function')throw new TypeError('Function.prototype.bind called on incompatible '+a);var c=g.call(arguments,1),b=function(){if(this instanceof b){var e=a.apply(this,c.concat(g.call(arguments)));return Object(e)===e?e:this}else return a.apply(d,c.concat(g.call(arguments)))};return a.prototype&&(j.prototype=a.prototype,b.prototype=new j,j.prototype=null),b});var f=Function.prototype.call,s=Array.prototype,d=Object.prototype,g=s.slice,a=f.bind(d.toString),h=f.bind(d.hasOwnProperty),E,D,C,B,A;if((A=h(d,'__defineGetter__'))&&(E=f.bind(d.__defineGetter__),D=f.bind(d.__defineSetter__),C=f.bind(d.__lookupGetter__),B=f.bind(d.__lookupSetter__)),[1,2].splice(0).length!=2){var u=Array.prototype.splice;Array.prototype.splice=function(a,b){return arguments.length?u.apply(this,[a===void 0?0:a,b===void 0?this.length-a:b].concat(g.call(arguments,2))):[]}}if([].unshift(0)!=1){var r=Array.prototype.unshift;Array.prototype.unshift=function(){return r.apply(this,arguments),this.length}}Array.isArray||(Array.isArray=function b(b){return a(b)=='[object Array]'});var k=Object('a'),c=k[0]!='a'||!(0 in k);if(Array.prototype.forEach||(Array.prototype.forEach=function d(g){var f=b(this),e=c&&a(this)=='[object String]'?this.split(''):f,h=arguments[1],d=-1,i=e.length>>>0;if(a(g)!='[object Function]')throw new TypeError;while(++d<i)d in e&&g.call(h,e[d],d,f)}),Array.prototype.map||(Array.prototype.map=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=Array(h),j=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)d in e&&(i[d]=f.call(j,e[d],d,g));return i}),Array.prototype.filter||(Array.prototype.filter=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,j=e.length>>>0,h=[],i,k=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<j;d++)d in e&&(i=e[d],f.call(k,i,d,g)&&h.push(i));return h}),Array.prototype.every||(Array.prototype.every=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)if(d in e&&!f.call(i,e[d],d,g))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function d(f){var g=b(this),e=c&&a(this)=='[object String]'?this.split(''):g,h=e.length>>>0,i=arguments[1];if(a(f)!='[object Function]')throw new TypeError(f+' is not a function');for(var d=0;d<h;d++)if(d in e&&f.call(i,e[d],d,g))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function d(h){var i=b(this),e=c&&a(this)=='[object String]'?this.split(''):i,g=e.length>>>0;if(a(h)!='[object Function]')throw new TypeError(h+' is not a function');if(!g&&arguments.length==1)throw new TypeError('reduce of empty array with no initial value');var d=0,f;if(arguments.length>=2)f=arguments[1];else do{if(d in e){f=e[d++];break}if(++d>=g)throw new TypeError('reduce of empty array with no initial value')}while(!0);for(;d<g;d++)d in e&&(f=h.call(void 0,f,e[d],d,i));return f}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function d(g){var h=b(this),e=c&&a(this)=='[object String]'?this.split(''):h,i=e.length>>>0;if(a(g)!='[object Function]')throw new TypeError(g+' is not a function');if(!i&&arguments.length==1)throw new TypeError('reduceRight of empty array with no initial value');var f,d=i-1;if(arguments.length>=2)f=arguments[1];else do{if(d in e){f=e[d--];break}if(--d<0)throw new TypeError('reduceRight of empty array with no initial value')}while(!0);do d in this&&(f=g.call(void 0,f,e[d],d,h));while(d--);return f}),(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)&&(Array.prototype.indexOf=function d(g){var e=c&&a(this)=='[object String]'?this.split(''):b(this),f=e.length>>>0;if(!f)return-1;var d=0;for(arguments.length>1&&(d=q(arguments[1])),d=d>=0?d:Math.max(0,f+d);d<f;d++)if(d in e&&e[d]===g)return d;return-1}),(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)&&(Array.prototype.lastIndexOf=function d(g){var e=c&&a(this)=='[object String]'?this.split(''):b(this),f=e.length>>>0;if(!f)return-1;var d=f-1;for(arguments.length>1&&(d=Math.min(d,q(arguments[1]))),d=d>=0?d:f-Math.abs(d);d>=0;d--)if(d in e&&g===e[d])return d;return-1}),!Object.keys){var m=!0,n=['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','propertyIsEnumerable','constructor'],w=n.length;for(var z in{toString:null})m=!1;Object.keys=function a(a){if(typeof a!='object'&&typeof a!='function'||a===null)throw new TypeError('Object.keys called on a non-object');var b=[];for(var d in a)h(a,d)&&b.push(d);if(m)for(var c=0,f=w;c<f;c++){var e=n[c];h(a,e)&&b.push(e)}return b}}var l=-621987552e5,o='-000001';(!Date.prototype.toISOString||new Date(l).toISOString().indexOf(o)===-1)&&(Date.prototype.toISOString=function a(){var b,d,e,a,c;if(!isFinite(this))throw new RangeError('Date.prototype.toISOString called on non-finite value.');a=this.getUTCFullYear(),c=this.getUTCMonth(),a+=Math.floor(c/12),c=(c%12+12)%12,b=[c+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()],a=(a<0?'-':a>9999?'+':'')+('00000'+Math.abs(a)).slice(0<=a&&a<=9999?-4:-6),d=b.length;while(d--)e=b[d],e<10&&(b[d]='0'+e);return a+'-'+b.slice(0,2).join('-')+'T'+b.slice(2).join(':')+'.'+('000'+this.getUTCMilliseconds()).slice(-3)+'Z'});var p=!1;try{p=Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(l).toJSON().indexOf(o)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(a){}if(p||(Date.prototype.toJSON=function a(d){var a=Object(this),b=F(a),c;if(typeof b==='number'&&!isFinite(b))return null;if(c=a.toISOString,typeof c!='function')throw new TypeError('toISOString property is not callable');return c.call(a)}),(!Date.parse||'Date.parse is buggy')&&(Date=function(a,e,f,c){function b(c,e,f,g,h,j,k){var d=arguments.length;if(this instanceof a){var i=d==1&&String(c)===c?new a(b.parse(c)):d>=7?new a(c,e,f,g,h,j,k):d>=6?new a(c,e,f,g,h,j):d>=5?new a(c,e,f,g,h):d>=4?new a(c,e,f,g):d>=3?new a(c,e,f):d>=2?new a(c,e):d>=1?new a(c):new a;return i.constructor=b,i}return a.apply(this,arguments)}function d(a,c){var b=c>1?1:0;return f[c]+Math.floor((a-1969+b)/4)-Math.floor((a-1901+b)/100)+Math.floor((a-1601+b)/400)+365*(a-1970)}e=new RegExp('^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$'),f=[0,31,59,90,120,151,181,212,243,273,304,334,365];for(c in a)b[c]=a[c];return b.now=a.now,b.UTC=a.UTC,b.prototype=a.prototype,b.prototype.constructor=b,b.parse=function b(q){var b=e.exec(q);if(b){var g=Number(b[1]),f=Number(b[2]||1)-1,i=Number(b[3]||1)-1,l=Number(b[4]||0),h=Number(b[5]||0),k=Number(b[6]||0),j=Number(b[7]||0),p=!b[4]||b[8]?0:Number(new a(1970,0)),m=b[9]==='-'?1:-1,n=Number(b[10]||0),o=Number(b[11]||0),c;return l<(h>0||k>0||j>0?24:25)&&h<60&&k<60&&j<1e3&&f>-1&&f<12&&n<24&&o<60&&i>-1&&i<d(g,f+1)-d(g,f)&&(c=((d(g,f)+i)*24+l+n*m)*60,c=((c+h+o*m)*60+k)*1e3+j+p,-864e13<=c&&c<=864e13)?c:NaN}return a.parse.apply(this,arguments)},b}(Date)),Date.now||(Date.now=function a(){return new Date().getTime()}),'0'.split(void 0,0).length){var x=String.prototype.split;String.prototype.split=function(a,b){return a===void 0&&b===0?[]:x.apply(this,arguments)}}if(''.substr&&'0b'.substr(-1)!=='b'){var v=String.prototype.substr;String.prototype.substr=function(a,b){return v.call(this,a<0?(a=this.length+a)<0?0:a:a,b)}}var e='	\n\r Â áš€á Žâ€€â€â€‚â€ƒâ€„â€…â€†â€‡â€ˆâ€‰â€Šâ€¯âŸã€€\u2028\u2029';if(!String.prototype.trim||e.trim()){e='['+e+']';var t=new RegExp('^'+e+e+'*'),y=new RegExp(e+e+'*$');String.prototype.trim=function a(){if(this===undefined||this===null)throw new TypeError("can't convert "+this+' to object');return String(this).replace(t,'').replace(y,'')}}var b=function(a){if(a==null)throw new TypeError("can't convert "+a+' to object');return Object(a)}})},{}],18:[function(a,d,e){var b=a('./inject'),c=a('stream-serializer');d.exports=b(function(b,a){return c(a&&a.wrapper)(b)})},{'./inject':19,'stream-serializer':21}],19:[function(a,e,f){'use strict';var b=a('through'),c=a('xtend'),d=a('duplex');e.exports=function(a){function e(h,k){function n(){return Math.random().toString(16).slice(2)+Math.random().toString(16).slice(2)}function g(d){e.removeListener('end',g),e.removeListener('error',g),e.removeListener('close',g);var b=d||new Error('unexpected disconnection');for(var c in i){var a=i[c];a.destroyed=!0,h.error!==!0?a.end():(a.emit('error',b),a.destroy())}}function l(c,g,d){j++;var a=b(function(d){if(!this.writable){var b=Error('stream is not writable: '+c);return b.stream=this,f.emit('error',b)}e._data([a.id,'data',d])},function(){e._data([a.id,'end']),this.readable&&!d.allowHalfOpen&&!this.ended&&this.emit('end')});return a.pause=function(){e._data([a.id,'pause'])},a.resume=function(){e._data([a.id,'resume'])},a.error=function(b){e._data([a.id,'error',b])},a.once('close',function(){delete i[c],j--,e._data([a.id,'close']),j===0&&e.emit('zero')}),a.writable=d.writable,a.readable=d.readable,i[a.id=c]=a,a.meta=g,a}'function'===typeof h&&(k=h,h=null),h=h||{};var i={},j=0,e=d();e.on('_data',function(a){if(!(Array.isArray(a)&&'string'===typeof a[0]&&'__proto__'!==a[0]&&'string'===typeof a[1]&&'__proto__'!==a[1]))return;var h=a.shift(),g=a[0],b=i[h];if(!b){if(g=='close')return;if(g!='new')return f.emit('unknown',h);e.emit('connection',l(h,a[1].meta,a[1].opts))}else if(g==='pause')b.paused=!0;else if(g==='resume'){var k=b.paused;b.paused=!1,k&&b.emit('drain')}else if(g==='error'){var d=a[1];if(typeof d==='string')b.emit('error',new Error(d));else if(typeof d.message==='string'){var j=new Error(d.message);c(j,d),b.emit('error',j)}else b.emit('error',d)}else b.emit.apply(b,a)}).on('_end',function(){g(),e._end()});var f=a(e,h);e!==f&&e.on('connection',function(a){f.emit('connection',a)}),f.close=function(a){return e.once('zero',function(){e._end(),a&&a()}),this},k&&f.on('connection',k),f.on('connection',function(a){f.listeners('connection').length===1&&a.error('remote end lacks connection listener '+f.listeners('connection').length)});var m=f.pipe;return f.pipe=function(a,b){return m.call(f,a,b),e.on('end',g),e.on('close',g),e.on('error',g),a},f.createStream=function(c,a){a=a||{},a.writable||a.readable||(a.readable=a.writable=!0);var b=l(n(),c,a),d={writable:a.readable,readable:a.writable};return e._data([b.id,'new',{meta:c,opts:d}]),b},f.createWriteStream=function(a){return f.createStream(a,{writable:!0,readable:!1})},f.createReadStream=function(a){return f.createStream(a,{writable:!1,readable:!0})},f}return e}},{duplex:20,through:22,xtend:23}],20:[function(b,d,e){var a=b('__browserify_process'),c=b('stream');d.exports=function(h,i){var b=new c,d=[],g=!1,e;b.writable=b.readable=!0,b.paused=!1,b._paused=!1,b.buffer=d,b.on('pause',function(){b._paused=!0}).on('drain',function(){b._paused=!1}),h&&b.on('_data',h),i&&b.on('_end',i),b.once('end',function(){b.readable=!1,b.writable||a.nextTick(function(){b.destroy()})}),b.once('_end',function(){b.writable=!1,b.readable||b.destroy()}),b._data=function(a){return b.paused||d.length?d.push(a):b.emit('data',a),!(b.paused||d.length)},b._end=function(a){if(a&&b._data(a),e)return;e=!0,b.drain()},b.write=function(a){return b.emit('_data',a),!b._paused},b.end=function(){if(b.writable=!1,b.ended)return;b.ended=!0,b.emit('_end')},b.drain=function(){if(!(d.length||e))return;while(!b.paused)if(d.length)b.emit('data',d.shift()),d.length==0&&b.emit('_drain');else if(e&&b.readable){b.readable=!1,b.emit('end');return}else return!0};var f=!1;return b.resume=function(){return f=!0,b.paused=!1,b.drain(),b},b.destroy=function(){if(g)return;g=!0,d.length=0,b.emit('close')},b.pause=function(){return f=!0,b.paused=!0,b.emit('_pause'),b},b._pause=function(){return b._paused||(b._paused=!0,b.emit('pause')),this},b.paused=!0,a.nextTick(function(){if(f)return;b.resume()}),b}},{__browserify_process:14,stream:10}],21:[function(c,d,a){var b=c('events').EventEmitter;a=d.exports=function(b){return'function'==typeof b?b:a[b]||a.json},a.json=function(a,d){function e(c){var b;try{b=d.parse(c)}catch(b){return b.line=c,a.emit('error',b)}b!==undefined&&f.call(a,b)}function h(b){var a=(c+b).split('\n');c=a.pop();while(a.length)e(a.shift())}d=d||JSON;var f=a.write,c='';a.write=h;var g=a.end;return a.end=function(b){return b&&a.write(b),c&&e(c),g.call(a)},a.emit=function(e,c){e=='data'&&(c=d.stringify(c)+'\n'),b.prototype.emit.call(a,e,c)},a},a.raw=function(a){return a}},{events:7}],22:[function(a,b,c){b.exports=a(16)},{__browserify_process:14,stream:10}],23:[function(c,a,d){function b(f){for(var a=1;a<arguments.length;a++){var c=arguments[a],d=Object.keys(c);for(var b=0;b<d.length;b++){var e=d[b];f[e]=c[e]}}return f}a.exports=b},{}],24:[function(a,f,g){var b=a('stream'),c=a('sockjs-client'),d=a('url').resolve,e=a('url').parse;f.exports=function(i,j){var k=e(i).protocol?i:d(window.location.href,i),a=new b;a.readable=!0,a.writable=!0;var h=!1,g=[],f=c(k);return a.sock=f,a.write=function(a){!h||g.length?g.push(a):f.send(a)},a.end=function(b){if(b!==undefined&&a.write(b),!h){a._ended=!0;return}a.writable=!1,f.close()},a.destroy=function(){a._ended=!0,a.writable=a.readable=!1,g.length=0,f.close()},f.onopen=function(){typeof j==='function'&&j(),h=!0;for(var b=0;b<g.length;b++)f.send(g[b]);g=[],a.emit('connect'),a._ended&&a.end()},f.onmessage=function(b){a.emit('data',b.data)},f.onclose=function(){a.emit('end'),a.writable=!1,a.readable=!1},a}},{'sockjs-client':25,stream:10,url:11}],25:[function(require,module,exports){var JSON;JSON||(JSON={}),function(){function str(h,i){var b,e,c,g,f=gap,d,a=i[h];a&&typeof a=='object'&&typeof a.toJSON=='function'&&(a=a.toJSON(h)),typeof rep=='function'&&(a=rep.call(i,h,a));switch(typeof a){case'string':return quote(a);case'number':return isFinite(a)?String(a):'null';case'boolean':case'null':return String(a);case'object':if(!a)return'null';gap+=indent,d=[];if(Object.prototype.toString.apply(a)==='[object Array]'){for(g=a.length,b=0;b<g;b+=1)d[b]=str(b,a)||'null';return c=d.length===0?'[]':gap?'[\n'+gap+d.join(',\n'+gap)+'\n'+f+']':'['+d.join(',')+']',gap=f,c}if(rep&&typeof rep=='object')for(g=rep.length,b=0;b<g;b+=1)typeof rep[b]=='string'&&(e=rep[b],c=str(e,a),c&&d.push(quote(e)+(gap?': ':':')+c));else for(e in a)Object.prototype.hasOwnProperty.call(a,e)&&(c=str(e,a),c&&d.push(quote(e)+(gap?': ':':')+c));c=d.length===0?'{}':gap?'{\n'+gap+d.join(',\n'+gap)+'\n'+f+'}':'{'+d.join(',')+'}',gap=f;return c}}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(b){var a=meta[b];return typeof a=='string'?a:'\\u'+('0000'+b.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function f(a){return a<10?'0'+a:a}typeof Date.prototype.toJSON!='function'&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z':null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'':'\\b','	':'\\t','\n':'\\n','':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;typeof JSON.stringify!='function'&&(JSON.stringify=function(d,a,b){var c;if(gap='',indent='',typeof b=='number')for(c=0;c<b;c+=1)indent+=' ';else typeof b=='string'&&(indent=b);if(rep=a,!a||typeof a=='function'||typeof a=='object'&&typeof a.length=='number')return str('',{'':d});throw new Error('JSON.stringify')}),typeof JSON.parse!='function'&&(JSON.parse=function(text,reviver){function walk(d,e){var b,c,a=d[e];if(a&&typeof a=='object')for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&(c=walk(a,b),c!==undefined?a[b]=c:delete a[b]);return reviver.call(d,e,a)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'')))return j=eval('('+text+')'),typeof reviver=='function'?walk({'':j},''):j;throw new SyntaxError('JSON.parse')})}();var SockJS=function(d,c,a,m,f,l,M,g,D,S,s,O,V,a3,E,z,n,C,Q,P,p,Z,a0,x,b,t,j,X,R,$,r,a1,i,q,u,B,J,e,N,F,h,o,L,K,T,U,y,W,w,Y,v,_,G,A,I,a2,H,k){return d=document,c=window,a={},m=function(){},m.prototype.addEventListener=function(b,d){this._listeners||(this._listeners={}),b in this._listeners||(this._listeners[b]=[]);var c=this._listeners[b];a.arrIndexOf(c,d)===-1&&c.push(d);return},m.prototype.removeEventListener=function(c,e){if(!(this._listeners&&c in this._listeners))return;var b=this._listeners[c],d=a.arrIndexOf(b,e);if(d!==-1){b.length>1?this._listeners[c]=b.slice(0,d).concat(b.slice(d+1)):delete this._listeners[c];return}return},m.prototype.dispatchEvent=function(d){var a=d.type,c=Array.prototype.slice.call(arguments,0);if(this['on'+a]&&this['on'+a].apply(this,c),this._listeners&&a in this._listeners)for(var b=0;b<this._listeners[a].length;b++)this._listeners[a][b].apply(this,c)},f=function(c,a){if(this.type=c,a!==void 0)for(var b in a){if(!a.hasOwnProperty(b))continue;this[b]=a[b]}},f.prototype.toString=function(){var c=[];for(var a in this){if(!this.hasOwnProperty(a))continue;var b=this[a];typeof b==='function'&&(b='[function]'),c.push(a+'='+b)}return'SimpleEvent('+c.join(', ')+')'},l=function(a){this.events=a||[]},l.prototype.emit=function(c){var b=this,d=Array.prototype.slice.call(arguments,1);!b.nuked&&b['on'+c]&&b['on'+c].apply(b,d),a.arrIndexOf(b.events,c)===-1&&a.log('Event '+JSON.stringify(c)+' not listed '+JSON.stringify(b.events)+' in '+b)},l.prototype.nuke=function(c){var a=this;a.nuked=!0;for(var b=0;b<a.events.length;b++)delete a[a.events[b]]},M='abcdefghijklmnopqrstuvwxyz0123456789_',a.random_string=function(d,a){a=a||M.length;var b,c=[];for(b=0;b<d;b++)c.push(M.substr(Math.floor(Math.random()*a),1));return c.join('')},a.random_number=function(a){return Math.floor(Math.random()*a)},a.random_number_string=function(c){var b=(''+(c-1)).length,d=Array(b+1).join('0');return(d+a.random_number(c)).slice(-b)},a.getOrigin=function(a){a+='/';var b=a.split('/').slice(0,3);return b.join('/')},a.isSameOriginUrl=function(b,a){return a||(a=c.location.href),b.split('/').slice(0,3).join('/')===a.split('/').slice(0,3).join('/')},a.getParentDomain=function(a){if(/^[0-9.]*$/.test(a))return a;if(/^\[/.test(a))return a;if(!/[.]/.test(a))return a;var b=a.split('.').slice(1);return b.join('.')},a.objectExtend=function(c,b){for(var a in b)b.hasOwnProperty(a)&&(c[a]=b[a]);return c},g='_jp',a.polluteGlobalNamespace=function(){g in c||(c[g]={})},a.closeFrame=function(a,b){return'c'+JSON.stringify([a,b])},a.userSetCode=function(a){return a===1e3||a>=3e3&&a<=4999},a.countRTO=function(a){var b;return a>100?b=3*a:b=a+200,b},a.log=function(){c.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},a.bind=function(a,b){return a.bind?a.bind(b):function(){return a.apply(b,arguments)}},a.flatUrl=function(a){return a.indexOf('?')===-1&&a.indexOf('#')===-1},a.amendUrl=function(b){var c=d.location;if(!b)throw new Error('Wrong url for SockJS');if(!a.flatUrl(b))throw new Error('Only basic urls are supported in SockJS');return b.indexOf('//')===0&&(b=c.protocol+b),b.indexOf('/')===0&&(b=c.protocol+'//'+c.host+b),b=b.replace(/[/]+$/,''),b},a.arrIndexOf=function(b,c){for(var a=0;a<b.length;a++)if(b[a]===c)return a;return-1},a.arrSkip=function(b,e){var c=a.arrIndexOf(b,e);if(c===-1)return b.slice();else{var d=b.slice(0,c);return d.concat(b.slice(c+1))}},a.isArray=Array.isArray||function(a){return{}.toString.call(a).indexOf('Array')>=0},a.delay=function(a,b){return typeof a==='function'&&(b=a,a=0),setTimeout(b,a)},D=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,S={'�':'\\u0000','':'\\u0001','':'\\u0002','':'\\u0003','':'\\u0004','':'\\u0005','':'\\u0006','':'\\u0007','':'\\b','	':'\\t','\n':'\\n','':'\\u000b','':'\\f','\r':'\\r','':'\\u000e','':'\\u000f','':'\\u0010','':'\\u0011','':'\\u0012','':'\\u0013','':'\\u0014','':'\\u0015','':'\\u0016','':'\\u0017','':'\\u0018','':'\\u0019','':'\\u001a','':'\\u001b','':'\\u001c','':'\\u001d','':'\\u001e','':'\\u001f','"':'\\"','\\':'\\\\','':'\\u007f','€':'\\u0080','':'\\u0081','‚':'\\u0082','ƒ':'\\u0083','„':'\\u0084','Â…':'\\u0085','†':'\\u0086','‡':'\\u0087','ˆ':'\\u0088','‰':'\\u0089','Š':'\\u008a','‹':'\\u008b','ÂŒ':'\\u008c','':'\\u008d','ÂŽ':'\\u008e','':'\\u008f','':'\\u0090','‘':'\\u0091','Â’':'\\u0092','“':'\\u0093','”':'\\u0094','•':'\\u0095','–':'\\u0096','—':'\\u0097','˜':'\\u0098','™':'\\u0099','š':'\\u009a','›':'\\u009b','œ':'\\u009c','':'\\u009d','ž':'\\u009e','Ÿ':'\\u009f','­':'\\u00ad','Ø€':'\\u0600','؁':'\\u0601','Ø‚':'\\u0602','؃':'\\u0603','Ø„':'\\u0604','܏':'\\u070f','áž´':'\\u17b4','ážµ':'\\u17b5','‌':'\\u200c','‍':'\\u200d','‎':'\\u200e','‏':'\\u200f','\u2028':'\\u2028','\u2029':'\\u2029','‪':'\\u202a','‫':'\\u202b','‬':'\\u202c','‭':'\\u202d','‮':'\\u202e',' ':'\\u202f','⁠':'\\u2060','⁡':'\\u2061','⁢':'\\u2062','⁣':'\\u2063','⁤':'\\u2064','⁥':'\\u2065','⁦':'\\u2066','⁧':'\\u2067','⁨':'\\u2068','⁩':'\\u2069','':'\\u206a','':'\\u206b','':'\\u206c','':'\\u206d','':'\\u206e','':'\\u206f','':'\\ufeff','ï¿°':'\\ufff0','￱':'\\ufff1','￲':'\\ufff2','￳':'\\ufff3','ï¿´':'\\ufff4','￵':'\\ufff5','ï¿¶':'\\ufff6','ï¿·':'\\ufff7','￸':'\\ufff8','':'\\ufff9','':'\\ufffa','ï¿»':'\\ufffb','':'\\ufffc','�':'\\ufffd','￾':'\\ufffe','ï¿¿':'\\uffff'},s=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,V=JSON&&JSON.stringify||function(a){return D.lastIndex=0,D.test(a)&&(a=a.replace(D,function(a){return S[a]})),'"'+a+'"'},a3=function(b){var a,c={},d=[];for(a=0;a<65536;a++)d.push(String.fromCharCode(a));return b.lastIndex=0,d.join('').replace(b,function(a){return c[a]='\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4),''}),b.lastIndex=0,c},a.quote=function(b){var a=V(b);return s.lastIndex=0,s.test(a)?(O||(O=a3(s)),a.replace(s,function(a){return O[a]})):a},E=['websocket','xdr-streaming','xhr-streaming','iframe-eventsource','iframe-htmlfile','xdr-polling','xhr-polling','iframe-xhr-polling','jsonp-polling'],a.probeProtocols=function(){var d={};for(var a=0;a<E.length;a++){var c=E[a];d[c]=b[c]&&b[c].enabled()}return d},a.detectProtocols=function(h,e,a){var b={},c=[];e||(e=E);for(var f=0;f<e.length;f++){var g=e[f];b[g]=h[g]}var d=function(a){var e=a.shift();b[e]?c.push(e):a.length>0&&d(a)};return a.websocket!==!1&&d(['websocket']),b['xhr-streaming']&&!a.null_origin?c.push('xhr-streaming'):b['xdr-streaming']&&!a.cookie_needed&&!a.null_origin?c.push('xdr-streaming'):d(['iframe-eventsource','iframe-htmlfile']),b['xhr-polling']&&!a.null_origin?c.push('xhr-polling'):b['xdr-polling']&&!a.cookie_needed&&!a.null_origin?c.push('xdr-polling'):d(['iframe-xhr-polling','jsonp-polling']),c},z='_sockjs_global',a.createHook=function(){var d='a'+a.random_string(8);if(!(z in c)){var b={};c[z]=function(a){return a in b||(b[a]={id:a,del:function(){delete b[a]}}),b[a]}}return c[z](d)},a.attachMessage=function(b){a.attachEvent('message',b)},a.attachEvent=function(a,b){c.addEventListener!==void 0?c.addEventListener(a,b,!1):(d.attachEvent('on'+a,b),c.attachEvent('on'+a,b))},a.detachMessage=function(b){a.detachEvent('message',b)},a.detachEvent=function(a,b){c.addEventListener!==void 0?c.removeEventListener(a,b,!1):(d.detachEvent('on'+a,b),c.detachEvent('on'+a,b))},n={},C=!1,Q=function(){for(var a in n)n[a](),delete n[a]},P=function(){if(C)return;C=!0,Q()},a.attachEvent('beforeunload',P),a.attachEvent('unload',P),a.unload_add=function(c){var b=a.random_string(8);return n[b]=c,C&&a.delay(Q),b},a.unload_del=function(a){a in n&&delete n[a]},a.createIframe=function(j,k){var b=d.createElement('iframe'),c,h,g=function(){clearTimeout(c);try{b.onload=null}catch(a){}b.onerror=null},e=function(){b&&(g(),setTimeout(function(){b&&b.parentNode.removeChild(b),b=null},0),a.unload_del(h))},f=function(a){b&&(e(),k(a))},i=function(a,c){try{b&&b.contentWindow&&b.contentWindow.postMessage(a,c)}catch(a){}};return b.src=j,b.style.display='none',b.style.position='absolute',b.onerror=function(){f('onerror')},b.onload=function(){clearTimeout(c),c=setTimeout(function(){f('onload timeout')},2e3)},d.body.appendChild(b),c=setTimeout(function(){f('timeout')},15e3),h=a.unload_add(e),{post:i,cleanup:e,loaded:g}},a.createHtmlfile=function(m,n){var b=new ActiveXObject('htmlfile'),j,i,d,h=function(){clearTimeout(j)},e=function(){b&&(h(),a.unload_del(i),d.parentNode.removeChild(d),d=b=null,CollectGarbage())},k=function(a){b&&(e(),n(a))},l=function(a,b){try{d&&d.contentWindow&&d.contentWindow.postMessage(a,b)}catch(a){}};b.open(),b.write('<html><script>document.domain="'+document.domain+'";'+'</s'+'cript></html>'),b.close(),b.parentWindow[g]=c[g];var f=b.createElement('div');return b.body.appendChild(f),d=b.createElement('iframe'),f.appendChild(d),d.src=m,j=setTimeout(function(){k('timeout')},15e3),i=a.unload_add(e),{post:l,cleanup:e,loaded:h}},p=function(){},p.prototype=new l(['chunk','finish']),p.prototype._start=function(g,e,h,d){var b=this;try{b.xhr=new XMLHttpRequest}catch(a){}if(!b.xhr)try{b.xhr=new c.ActiveXObject('Microsoft.XMLHTTP')}catch(a){}(c.ActiveXObject||c.XDomainRequest)&&(e+=(e.indexOf('?')===-1?'?t=':'&t=')+ +new Date),b.unload_ref=a.unload_add(function(){b._cleanup(!0)});try{b.xhr.open(g,e,!0)}catch(a){b.emit('finish',0,''),b._cleanup();return}if(d&&d.no_credentials||(b.xhr.withCredentials='true'),d&&d.headers)for(var f in d.headers)b.xhr.setRequestHeader(f,d.headers[f]);b.xhr.onreadystatechange=function(){if(b.xhr){var a=b.xhr;switch(a.readyState){case 3:try{var d=a.status,c=a.responseText}catch(a){}c&&c.length>0&&b.emit('chunk',d,c);break;case 4:b.emit('finish',a.status,a.responseText);b._cleanup(!1);break}}},b.xhr.send(h)},p.prototype._cleanup=function(c){var b=this;if(!b.xhr)return;if(a.unload_del(b.unload_ref),b.xhr.onreadystatechange=function(){},c)try{b.xhr.abort()}catch(a){}b.unload_ref=b.xhr=null},p.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)},Z=a.XHRCorsObject=function(){var b=this,c=arguments;a.delay(function(){b._start.apply(b,c)})},Z.prototype=new p,a0=a.XHRLocalObject=function(c,d,e){var b=this;a.delay(function(){b._start(c,d,e,{no_credentials:!0})})},a0.prototype=new p,x=a.XDRObject=function(c,d,e){var b=this;a.delay(function(){b._start(c,d,e)})},x.prototype=new l(['chunk','finish']),x.prototype._start=function(f,d,g){var b=this,c=new XDomainRequest;d+=(d.indexOf('?')===-1?'?t=':'&t=')+ +new Date;var e=c.ontimeout=c.onerror=function(){b.emit('finish',0,''),b._cleanup(!1)};c.onprogress=function(){b.emit('chunk',200,c.responseText)},c.onload=function(){b.emit('finish',200,c.responseText),b._cleanup(!1)},b.xdr=c,b.unload_ref=a.unload_add(function(){b._cleanup(!0)});try{b.xdr.open(f,d),b.xdr.send(g)}catch(a){e()}},x.prototype._cleanup=function(c){var b=this;if(!b.xdr)return;if(a.unload_del(b.unload_ref),b.xdr.ontimeout=b.xdr.onerror=b.xdr.onprogress=b.xdr.onload=null,c)try{b.xdr.abort()}catch(a){}b.unload_ref=b.xdr=null},x.prototype.close=function(){var a=this;a.nuke(),a._cleanup(!0)},a.isXHRCorsCapable=function(){return c.XMLHttpRequest&&'withCredentials'in new XMLHttpRequest?1:c.XDomainRequest&&d.domain?2:e.enabled()?3:4},b=function(g,d,f){if(this===window)return new b(g,d,f);var c=this,e;c._options={devel:!1,debug:!1,protocols_whitelist:[],info:undefined,rtt:undefined},f&&a.objectExtend(c._options,f),c._base_url=a.amendUrl(g),c._server=c._options.server||a.random_number_string(1e3),c._options.protocols_whitelist&&c._options.protocols_whitelist.length?e=c._options.protocols_whitelist:(typeof d==='string'&&d.length>0?e=[d]:a.isArray(d)?e=d:e=null,e&&c._debug('Deprecated API: Use "protocols_whitelist" option instead of supplying protocol list as a second parameter to SockJS constructor.')),c._protocols=[],c.protocol=null,c.readyState=b.CONNECTING,c._ir=T(c._base_url),c._ir.onfinish=function(b,d){c._ir=null,b?(c._options.info&&(b=a.objectExtend(b,c._options.info)),c._options.rtt&&(d=c._options.rtt),c._applyInfo(b,d,e),c._didClose()):c._didClose(1002,"Can't connect to server",!0)}},b.prototype=new m,b.version='0.3.1.7.ga67f.dirty',b.CONNECTING=0,b.OPEN=1,b.CLOSING=2,b.CLOSED=3,b.prototype._debug=function(){this._options.debug&&a.log.apply(a,arguments)},b.prototype._dispatchOpen=function(){var a=this;a.readyState===b.CONNECTING?(a._transport_tref&&(clearTimeout(a._transport_tref),a._transport_tref=null),a.readyState=b.OPEN,a.dispatchEvent(new f('open'))):a._didClose(1006,'Server lost session')},b.prototype._dispatchMessage=function(c){var a=this;if(a.readyState!==b.OPEN)return;a.dispatchEvent(new f('message',{data:c}))},b.prototype._dispatchHeartbeat=function(c){var a=this;if(a.readyState!==b.OPEN)return;a.dispatchEvent(new f('heartbeat',{}))},b.prototype._didClose=function(e,g,h){var c=this;if(c.readyState!==b.CONNECTING&&c.readyState!==b.OPEN&&c.readyState!==b.CLOSING)throw new Error('INVALID_STATE_ERR');c._ir&&(c._ir.nuke(),c._ir=null),c._transport&&(c._transport.doCleanup(),c._transport=null);var d=new f('close',{code:e,reason:g,wasClean:a.userSetCode(e)});if(!a.userSetCode(e)&&c.readyState===b.CONNECTING&&!h){if(c._try_next_protocol(d))return;d=new f('close',{code:2e3,reason:'All transports failed',wasClean:!1,last_event:d})}c.readyState=b.CLOSED,a.delay(function(){c.dispatchEvent(d)})},b.prototype._didMessage=function(c){var b=this,e=c.slice(0,1);switch(e){case'o':b._dispatchOpen();break;case'a':var a=JSON.parse(c.slice(1)||'[]');for(var d=0;d<a.length;d++)b._dispatchMessage(a[d]);break;case'm':var a=JSON.parse(c.slice(1)||'null');b._dispatchMessage(a);break;case'c':var a=JSON.parse(c.slice(1)||'[]');b._didClose(a[0],a[1]);break;case'h':b._dispatchHeartbeat();break}},b.prototype._try_next_protocol=function(j){var c=this;c.protocol&&(c._debug('Closed transport:',c.protocol,''+j),c.protocol=null),c._transport_tref&&(clearTimeout(c._transport_tref),c._transport_tref=null);while(1){var e=c.protocol=c._protocols.shift();if(!e)return!1;if(b[e]&&b[e].need_body===!0&&(!d.body||d.readyState!==void 0&&d.readyState!=='complete'))return c._protocols.unshift(e),c.protocol='waiting-for-load',a.attachEvent('load',function(){c._try_next_protocol()}),!0;if(b[e]&&b[e].enabled(c._options)){var g=b[e].roundTrips||1,h=(c._options.rto||0)*g||5e3;c._transport_tref=a.delay(h,function(){c.readyState===b.CONNECTING&&c._didClose(2007,'Transport timeouted')});var i=a.random_string(8),f=c._base_url+'/'+c._server+'/'+i;return c._debug('Opening transport:',e,' url:'+f,' RTO:'+c._options.rto),c._transport=new b[e](c,f,c._base_url),!0}c._debug('Skipping transport:',e)}},b.prototype.close=function(d,e){var c=this;if(d&&!a.userSetCode(d))throw new Error('INVALID_ACCESS_ERR');return c.readyState!==b.CONNECTING&&c.readyState!==b.OPEN?!1:(c.readyState=b.CLOSING,c._didClose(d||1e3,e||'Normal closure'),!0)},b.prototype.send=function(d){var c=this;if(c.readyState===b.CONNECTING)throw new Error('INVALID_STATE_ERR');return c.readyState===b.OPEN&&c._transport.doSend(a.quote(''+d)),!0},b.prototype._applyInfo=function(c,e,g){var b=this;b._options.info=c,b._options.rtt=e,b._options.rto=a.countRTO(e),b._options.info.null_origin=!d.domain;var f=a.probeProtocols();b._protocols=a.detectProtocols(f,g,c)},t=b.websocket=function(f,g){var b=this,d=g+'/websocket';d.slice(0,5)==='https'?d='wss'+d.slice(5):d='ws'+d.slice(4),b.ri=f,b.url=d;var e=c.WebSocket||c.MozWebSocket;b.ws=new e(b.url),b.ws.onmessage=function(a){b.ri._didMessage(a.data)},b.unload_ref=a.unload_add(function(){b.ws.close()}),b.ws.onclose=function(){b.ri._didMessage(a.closeFrame(1006,'WebSocket connection broken'))}},t.prototype.doSend=function(a){this.ws.send('['+a+']')},t.prototype.doCleanup=function(){var b=this,c=b.ws;c&&(c.onmessage=c.onclose=null,c.close(),a.unload_del(b.unload_ref),b.unload_ref=b.ri=b.ws=null)},t.enabled=function(){return!!(c.WebSocket||c.MozWebSocket)},t.roundTrips=2,j=function(){},j.prototype.send_constructor=function(b){var a=this;a.send_buffer=[],a.sender=b},j.prototype.doSend=function(b){var a=this;a.send_buffer.push(b),a.send_stop||a.send_schedule()},j.prototype.send_schedule_wait=function(){var b=this,c;b.send_stop=function(){b.send_stop=null,clearTimeout(c)},c=a.delay(25,function(){b.send_stop=null,b.send_schedule()})},j.prototype.send_schedule=function(){var a=this;if(a.send_buffer.length>0){var b='['+a.send_buffer.join(',')+']';a.send_stop=a.sender(a.trans_url,b,function(){a.send_stop=null,a.send_schedule_wait()}),a.send_buffer=[]}},j.prototype.send_destructor=function(){var a=this;a._send_stop&&a._send_stop(),a._send_stop=null},X=function(i,j,k){var f=this;if(!('_send_form'in f)){var c=f._send_form=d.createElement('form'),e=f._send_area=d.createElement('textarea');e.name='d',c.style.display='none',c.style.position='absolute',c.method='POST',c.enctype='application/x-www-form-urlencoded',c.acceptCharset='UTF-8',c.appendChild(e),d.body.appendChild(c)}var c=f._send_form,e=f._send_area,g='a'+a.random_string(8);c.target=g,c.action=i+'/jsonp_send?i='+g;var b;try{b=d.createElement('<iframe name="'+g+'">')}catch(a){b=d.createElement('iframe'),b.name=g}b.id=g,c.appendChild(b),b.style.display='none';try{e.value=j}catch(b){a.log('Your browser is seriously broken. Go home! '+b.message)}c.submit();var h=function(c){if(!b.onerror)return;b.onreadystatechange=b.onerror=b.onload=null,a.delay(500,function(){b.parentNode.removeChild(b),b=null}),e.value='',k()};return b.onerror=b.onload=h,b.onreadystatechange=function(a){b.readyState=='complete'&&h()},h},R=function(a){return function(d,e,b){var c=new a('POST',d+'/xhr_send',e);return c.onfinish=function(a,c){b(a)},function(a){b(0,a)}}},$=function(k,i){var j,b=d.createElement('script'),c,e=function(a){c&&(c.parentNode.removeChild(c),c=null),b&&(clearTimeout(j),b.parentNode.removeChild(b),b.onreadystatechange=b.onerror=b.onload=b.onclick=null,b=null,i(a),i=null)},g=!1,h=null;if(b.id='a'+a.random_string(8),b.src=k,b.type='text/javascript',b.charset='UTF-8',b.onerror=function(b){h||(h=setTimeout(function(){g||e(a.closeFrame(1006,'JSONP script loaded abnormally (onerror)'))},1e3))},b.onload=function(b){e(a.closeFrame(1006,'JSONP script loaded abnormally (onload)'))},b.onreadystatechange=function(c){if(/loaded|closed/.test(b.readyState)){if(b&&b.htmlFor&&b.onclick){g=!0;try{b.onclick()}catch(a){}}b&&e(a.closeFrame(1006,'JSONP script loaded abnormally (onreadystatechange)'))}},b.async===void 0&&d.attachEvent)if(!/opera/i.test(navigator.userAgent)){try{b.htmlFor=b.id,b.event='onclick'}catch(a){}b.async=!0}else c=d.createElement('script'),c.text="try{var a = document.getElementById('"+b.id+"'); if(a)a.onerror();}catch(x){};",b.async=c.async=!1;b.async!==void 0&&(b.async=!0),j=setTimeout(function(){e(a.closeFrame(1006,'JSONP script loaded abnormally (timeout)'))},35e3);var f=d.getElementsByTagName('head')[0];return f.insertBefore(b,f.firstChild),c&&f.insertBefore(c,f.firstChild),e},r=b['jsonp-polling']=function(c,d){a.polluteGlobalNamespace();var b=this;b.ri=c,b.trans_url=d,b.send_constructor(X),b._schedule_recv()},r.prototype=new j,r.prototype._schedule_recv=function(){var a=this,b=function(b){a._recv_stop=null,b&&(a._is_closing||a.ri._didMessage(b)),a._is_closing||a._schedule_recv()};a._recv_stop=a1(a.trans_url+'/jsonp',$,b)},r.enabled=function(){return!0},r.need_body=!0,r.prototype.doCleanup=function(){var a=this;a._is_closing=!0,a._recv_stop&&a._recv_stop(),a.ri=a._recv_stop=null,a.send_destructor()},a1=function(i,j,k){var b='a'+a.random_string(6),d=i+'?c='+escape(g+'.'+b),e=function(a){delete c[g][b],k(a)},f=j(d,e);c[g][b]=f;var h=function(){c[g][b]&&c[g][b](a.closeFrame(1e3,'JSONP user aborted read'))};return h},i=function(){},i.prototype=new j,i.prototype.run=function(b,c,e,f,d){var a=this;a.ri=b,a.trans_url=c,a.send_constructor(R(d)),a.poll=new G(b,f,c+e,d)},i.prototype.doCleanup=function(){var a=this;a.poll&&(a.poll.abort(),a.poll=null)},q=b['xhr-streaming']=function(b,c){this.run(b,c,'/xhr_streaming',k,a.XHRCorsObject)},q.prototype=new i,q.enabled=function(){return c.XMLHttpRequest&&'withCredentials'in new XMLHttpRequest&&!/opera/i.test(navigator.userAgent)},q.roundTrips=2,q.need_body=!0,u=b['xdr-streaming']=function(b,c){this.run(b,c,'/xhr_streaming',k,a.XDRObject)},u.prototype=new i,u.enabled=function(){return!!c.XDomainRequest},u.roundTrips=2,B=b['xhr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XHRCorsObject)},B.prototype=new i,B.enabled=q.enabled,B.roundTrips=2,J=b['xdr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XDRObject)},J.prototype=new i,J.enabled=u.enabled,J.roundTrips=2,e=function(){},e.prototype.i_constructor=function(e,f,d){var b=this;b.ri=e,b.origin=a.getOrigin(d),b.base_url=d,b.trans_url=f;var c=d+'/iframe.html';b.ri._options.devel&&(c+='?t='+ +new Date),b.window_id=a.random_string(8),c+='#'+b.window_id,b.iframeObj=a.createIframe(c,function(a){b.ri._didClose(1006,'Unable to load an iframe ('+a+')')}),b.onmessage_cb=a.bind(b.onmessage,b),a.attachMessage(b.onmessage_cb)},e.prototype.doCleanup=function(){var b=this;if(b.iframeObj){a.detachMessage(b.onmessage_cb);try{b.iframeObj.iframe.contentWindow&&b.postMessage('c')}catch(a){}b.iframeObj.cleanup(),b.iframeObj=null,b.onmessage_cb=b.iframeObj=null}},e.prototype.onmessage=function(c){var a=this;if(c.origin!==a.origin)return;var d=c.data.slice(0,8),e=c.data.slice(8,9),f=c.data.slice(9);if(d!==a.window_id)return;switch(e){case's':a.iframeObj.loaded();a.postMessage('s',JSON.stringify([b.version,a.protocol,a.trans_url,a.base_url]));break;case't':a.ri._didMessage(f);break}},e.prototype.postMessage=function(b,c){var a=this;a.iframeObj.post(a.window_id+b+(c||''),a.origin)},e.prototype.doSend=function(a){this.postMessage('m',a)},e.enabled=function(){var a=navigator&&navigator.userAgent&&navigator.userAgent.indexOf('Konqueror')!==-1;return(typeof c.postMessage==='function'||typeof c.postMessage==='object')&&!a},F=function(b,d){parent!==c?parent.postMessage(N+b+(d||''),'*'):a.log("Can't postMessage, no parent window.",b,d)},h=function(){},h.prototype._didClose=function(b,c){F('t',a.closeFrame(b,c))},h.prototype._didMessage=function(a){F('t',a)},h.prototype._doSend=function(a){this._transport.doSend(a)},h.prototype._doCleanup=function(){this._transport.doCleanup()},a.parent_origin=undefined,b.bootstrap_iframe=function(){var e;N=d.location.hash.slice(1);var f=function(d){if(d.source!==parent)return;if(a.parent_origin===void 0&&(a.parent_origin=d.origin),d.origin!==a.parent_origin)return;var l=d.data.slice(0,8),m=d.data.slice(8,9),j=d.data.slice(9);if(l!==N)return;switch(m){case's':var f=JSON.parse(j);var k=f[0];var n=f[1];var g=f[2];var i=f[3];k!==b.version&&a.log('Incompatibile SockJS! Main site uses: "'+k+'", the iframe:'+' "'+b.version+'".');if(!(a.flatUrl(g)&&a.flatUrl(i))){a.log('Only basic urls are supported in SockJS');return}if(!(a.isSameOriginUrl(g)&&a.isSameOriginUrl(i))){a.log("Can't connect to different domain from within an iframe. ("+JSON.stringify([c.location.href,g,i])+')');return}e=new h;e._transport=new h[n](e,g,i);break;case'm':e._doSend(j);break;case'c':e&&e._doCleanup();e=null;break}};a.attachMessage(f),F('s')},o=function(c,d){var b=this;a.delay(function(){b.doXhr(c,d)})},o.prototype=new l(['finish']),o.prototype.doXhr=function(f,g){var c=this,e=new Date().getTime(),b=new g('GET',f+'/info'),d=a.delay(8e3,function(){b.ontimeout()});b.onfinish=function(f,g){if(clearTimeout(d),d=null,f===200){var b=new Date().getTime()-e,a=JSON.parse(g);typeof a!=='object'&&(a={}),c.emit('finish',a,b)}else c.emit('finish')},b.ontimeout=function(){b.close(),c.emit('finish')}},L=function(f){var b=this,c=function(){var a=new e;a.protocol='w-iframe-info-receiver';var c=function(c){if(typeof c==='string'&&c.substr(0,1)==='m'){var d=JSON.parse(c.substr(1)),e=d[0],f=d[1];b.emit('finish',e,f)}else b.emit('finish');a.doCleanup(),a=null},d={_options:{},_didClose:c,_didMessage:c};a.i_constructor(d,f,f)};d.body?c():a.attachEvent('load',c)},L.prototype=new l(['finish']),K=function(){var b=this;a.delay(function(){b.emit('finish',{},2e3)})},K.prototype=new l(['finish']),T=function(b){if(a.isSameOriginUrl(b))return new o(b,a.XHRLocalObject);switch(a.isXHRCorsCapable()){case 1:return new o(b,a.XHRCorsObject);case 2:return new o(b,a.XDRObject);case 3:return new L(b);default:return new K}},U=h['w-iframe-info-receiver']=function(b,e,d){var c=new o(d,a.XHRLocalObject);c.onfinish=function(a,c){b._didMessage('m'+JSON.stringify([a,c])),b._didClose()}},U.prototype.doCleanup=function(){},y=b['iframe-eventsource']=function(){var a=this;a.protocol='w-iframe-eventsource',a.i_constructor.apply(a,arguments)},y.prototype=new e,y.enabled=function(){return'EventSource'in c&&e.enabled()},y.need_body=!0,y.roundTrips=3,W=h['w-iframe-eventsource']=function(b,c){this.run(b,c,'/eventsource',A,a.XHRLocalObject)},W.prototype=new i,w=b['iframe-xhr-polling']=function(){var a=this;a.protocol='w-iframe-xhr-polling',a.i_constructor.apply(a,arguments)},w.prototype=new e,w.enabled=function(){return c.XMLHttpRequest&&e.enabled()},w.need_body=!0,w.roundTrips=3,Y=h['w-iframe-xhr-polling']=function(b,c){this.run(b,c,'/xhr',k,a.XHRLocalObject)},Y.prototype=new i,v=b['iframe-htmlfile']=function(){var a=this;a.protocol='w-iframe-htmlfile',a.i_constructor.apply(a,arguments)},v.prototype=new e,v.enabled=function(){return e.enabled()},v.need_body=!0,v.roundTrips=3,_=h['w-iframe-htmlfile']=function(b,c){this.run(b,c,'/htmlfile',H,a.XHRLocalObject)},_.prototype=new i,G=function(b,c,d,e){var a=this;a.ri=b,a.Receiver=c,a.recv_url=d,a.AjaxObject=e,a._scheduleRecv()},G.prototype._scheduleRecv=function(){var a=this,b=a.poll=new a.Receiver(a.recv_url,a.AjaxObject),c=0;b.onmessage=function(b){c+=1,a.ri._didMessage(b.data)},b.onclose=function(c){a.poll=b=b.onmessage=b.onclose=null,a.poll_is_closing||(c.reason==='permanent'?a.ri._didClose(1006,'Polling error ('+c.reason+')'):a._scheduleRecv())}},G.prototype.abort=function(){var a=this;a.poll_is_closing=!0,a.poll&&a.poll.abort()},A=function(d){var c=this,b=new EventSource(d);b.onmessage=function(a){c.dispatchEvent(new f('message',{data:unescape(a.data)}))},c.es_close=b.onerror=function(g,e){var d=e?'user':b.readyState!==2?'network':'permanent';c.es_close=b.onmessage=b.onerror=null,b.close(),b=null,a.delay(200,function(){c.dispatchEvent(new f('close',{reason:d}))})}},A.prototype=new m,A.prototype.abort=function(){var a=this;a.es_close&&a.es_close({},!0)},a2=function(){if(I===undefined)if('ActiveXObject'in c)try{I=!!new ActiveXObject('htmlfile')}catch(a){}else I=!1;return I},H=function(e){var b=this;a.polluteGlobalNamespace(),b.id='a'+a.random_string(6,26),e+=(e.indexOf('?')===-1?'?c=':'&c=')+escape(g+'.'+b.id);var h=a2()?a.createHtmlfile:a.createIframe,d;c[g][b.id]={start:function(){d.loaded()},message:function(a){b.dispatchEvent(new f('message',{data:a}))},stop:function(){b.iframe_close({},'network')}},b.iframe_close=function(e,a){d.cleanup(),b.iframe_close=d=null,delete c[g][b.id],b.dispatchEvent(new f('close',{reason:a}))},d=h(e,function(a){b.iframe_close({},'permanent')})},H.prototype=new m,H.prototype.abort=function(){var a=this;a.iframe_close&&a.iframe_close({},'user')},k=function(c,d){var a=this,b=0;a.xo=new d('POST',c,null),a.xo.onchunk=function(g,h){if(g!==200)return;while(1){var d=h.slice(b),c=d.indexOf('\n');if(c===-1)break;b+=c+1;var e=d.slice(0,c);a.dispatchEvent(new f('message',{data:e}))}},a.xo.onfinish=function(b,d){a.xo.onchunk(b,d),a.xo=null;var c=b===200?'network':'permanent';a.dispatchEvent(new f('close',{reason:c}))}},k.prototype=new m,k.prototype.abort=function(){var a=this;a.xo&&(a.xo.close(),a.dispatchEvent(new f('close',{reason:'user'})),a.xo=null)},b.getUtils=function(){return a},b.getIframeTransport=function(){return e},b}();'_sockjs_onload'in window&&setTimeout(_sockjs_onload,1),typeof define==='function'&&define.amd&&define('sockjs',[],function(){return SockJS}),typeof module==='object'&&module&&module.exports&&(module.exports=SockJS)},{}],26:[function(a,b,c){b.exports=a('./lib/index.js')},{'./lib/index.js':27}],27:[function(b,e,f){function a(b){return new a.Terminal(b)}var c=b('__browserify_Buffer').Buffer,d='/../../node_modules/term.js/lib';a.middleware=function(d){var e=b('url');return d=d||{},d.path=d.path||'/term.js',function(f,b,g){if(e.parse(f.url).pathname!==d.path)return g();if(+new Date(f.headers['if-modified-since'])===a.last){b.statusCode=304,b.end();return}b.writeHead(200,{'Content-Type':'application/javascript; charset=utf-8','Content-Length':c.byteLength(a.script),'Last-Modified':a.last}),b.end(a.script)}},a.path=d+'/../src/term.js',a.__defineGetter__('script',function(){return a._script?a._script:(a.last=+new Date,a._script=b('fs').readFileSync(a.path,'utf8'))}),a.__defineGetter__('Terminal',function(){return a._Terminal?a._Terminal:a._Terminal=b('../src/term')}),e.exports=a},{'../src/term':28,__browserify_Buffer:13,fs:8,url:11}],28:[function(c,a,d){var b=self;(function(){'use strict';function f(){this._events=this._events||{}}function b(a){var c=this;if(!(this instanceof b))return new b(arguments[0],arguments[1],arguments[2]);f.call(this),typeof a==='number'&&(a={cols:arguments[0],rows:arguments[1],handler:arguments[2]}),a=a||{},v(t(b.defaults),function(d){a[d]==null&&(a[d]=b.options[d],b[d]!==b.defaults[d]&&(a[d]=b[d])),c[d]=a[d]}),a.colors.length===8?a.colors=a.colors.concat(b._colors.slice(8)):a.colors.length===16?a.colors=a.colors.concat(b._colors.slice(16)):a.colors.length===10?a.colors=a.colors.slice(0,-2).concat(b._colors.slice(8,-2),a.colors.slice(-2)):a.colors.length===18&&(a.colors=a.colors.concat(b._colors.slice(16,-2),a.colors.slice(-2))),this.colors=a.colors,this.options=a,this.parent=a.body||a.parent||(l?l.getElementsByTagName('body')[0]:null),this.cols=a.cols||a.geometry[0],this.rows=a.rows||a.geometry[1],a.handler&&this.on('data',a.handler),this.ybase=0,this.ydisp=0,this.x=0,this.y=0,this.cursorState=0,this.cursorHidden=!1,this.convertEol,this.state=0,this.queue='',this.scrollTop=0,this.scrollBottom=this.rows-1,this.applicationKeypad=!1,this.applicationCursor=!1,this.originMode=!1,this.insertMode=!1,this.wraparoundMode=!1,this.normal=null,this.prefixMode=!1,this.selectMode=!1,this.visualMode=!1,this.searchMode=!1,this.searchDown,this.entry='',this.entryPrefix='Search: ',this._real,this._selected,this._textarea,this.charset=null,this.gcharset=null,this.glevel=0,this.charsets=[null],this.decLocator,this.x10Mouse,this.vt200Mouse,this.vt300Mouse,this.normalMouse,this.mouseEvents,this.sendFocus,this.utfMouse,this.sgrMouse,this.urxvtMouse,this.element,this.children,this.refreshStart,this.refreshEnd,this.savedX,this.savedY,this.savedCols,this.readable=!0,this.writable=!0,this.defAttr=131840,this.curAttr=this.defAttr,this.params=[],this.currentParam=0,this.prefix='',this.postfix='',this.lines=[];var d=this.rows;while(d--)this.lines.push(this.blankLine());this.tabs,this.setupStops()}function e(a,b,c,d){a.addEventListener(b,c,d||!1)}function q(a,b,c,d){a.removeEventListener(b,c,d||!1)}function d(a){return a.preventDefault&&a.preventDefault(),a.returnValue=!1,a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0,!1}function u(a,c){function b(){this.constructor=a}b.prototype=c.prototype,a.prototype=new b}function x(c){var b=c.getElementsByTagName('body')[0],a=c.createElement('span');a.innerHTML='hello world',b.appendChild(a);var d=a.scrollWidth;a.style.fontWeight='bold';var e=a.scrollWidth;return b.removeChild(a),d!==e}function w(b,c){var a=b.length;while(a--)if(b[a]===c)return a;return-1}function m(a){return a<='ï¼€'?!1:a>='!'&&a<='ï¾¾'||a>='ï¿‚'&&a<='ᅦ'||a>='ᅧ'&&a<='ᅬ'||a>='ï¿’'&&a<='ï¿—'||a>='ᅳ'&&a<='ᅵ'||a>='ï¿ '&&a<='₩'||a>='│'&&a<='ï¿®'}function h(i,k,j){var f=i<<16|k<<8|j;if(h._cache[f]!=null)return h._cache[f];var g=Infinity,c=-1,a=0,d,l,m,n,e;for(;a<b.vcolors.length;a++){if(d=b.vcolors[a],l=d[0],m=d[1],n=d[2],e=h.distance(i,k,j,l,m,n),e===0){c=a;break}e<g&&(g=e,c=a)}return h._cache[f]=c}function v(a,c,d){if(a.forEach)return a.forEach(c,d);for(var b=0;b<a.length;b++)c.call(d,a[b],b,a)}function t(a){if(Object.keys)return Object.keys(a);var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}var l=this.document;f.prototype.addListener=function(a,b){this._events[a]=this._events[a]||[],this._events[a].push(b)},f.prototype.on=f.prototype.addListener,f.prototype.removeListener=function(c,d){if(!this._events[c])return;var a=this._events[c],b=a.length;while(b--)if(a[b]===d||a[b].listener===d){a.splice(b,1);return}},f.prototype.off=f.prototype.removeListener,f.prototype.removeAllListeners=function(a){this._events[a]&&delete this._events[a]},f.prototype.once=function(b,c){function a(){var d=Array.prototype.slice.call(arguments);return this.removeListener(b,a),c.apply(this,d)}return a.listener=c,this.on(b,a)},f.prototype.emit=function(c){if(!this._events[c])return;var d=Array.prototype.slice.call(arguments,1),b=this._events[c],e=b.length,a=0;for(;a<e;a++)b[a].apply(this,d)},f.prototype.listeners=function(a){return this._events[a]=this._events[a]||[]};var c=0,n=1,o=2,p=3,k=4,r=5,j=6;u(b,f),b.prototype.eraseAttr=function(){return this.defAttr&-512|this.curAttr&511},b.tangoColors=['#2e3436','#cc0000','#4e9a06','#c4a000','#3465a4','#75507b','#06989a','#d3d7cf','#555753','#ef2929','#8ae234','#fce94f','#729fcf','#ad7fa8','#34e2e2','#eeeeec'],b.xtermColors=['#000000','#cd0000','#00cd00','#cdcd00','#0000ee','#cd00cd','#00cdcd','#e5e5e5','#7f7f7f','#ff0000','#00ff00','#ffff00','#5c5cff','#ff00ff','#00ffff','#ffffff'],b.colors=function(d,c,a){function f(a,b,c){d.push('#'+e(a)+e(b)+e(c))}function e(a){return a=a.toString(16),a.length<2?'0'+a:a}for(d=b.tangoColors.slice(),c=[0,95,135,175,215,255],a=0;a<216;a++)f(c[a/36%6|0],c[a/6%6|0],c[a%6]);for(a=0;a<24;a++)c=8+a*10,f(c,c,c);return d}(),b.colors[256]='#000000',b.colors[257]='#f0f0f0',b._colors=b.colors.slice(),b.vcolors=function(d,e,a,c){for(d=[],e=b.colors,a=0;a<256;a++)c=parseInt(e[a].substring(1),16),d.push([c>>16&255,c>>8&255,c&255]);return d}(),b.defaults={colors:b.colors,convertEol:!1,termName:'xterm',geometry:[80,24],cursorBlink:!0,visualBell:!1,popOnBell:!1,scrollback:1e3,screenKeys:!1,debug:!1,useStyle:!1},b.options={},v(t(b.defaults),function(a){b[a]=b.defaults[a],b.options[a]=b.defaults[a]}),b.focus=null,b.prototype.focus=function(){if(b.focus===this)return;b.focus&&b.focus.blur(),this.sendFocus&&this.send(''),this.showCursor(),b.focus=this},b.prototype.blur=function(){if(b.focus!==this)return;this.cursorState=0,this.refresh(this.y,this.y),this.sendFocus&&this.send(''),b.focus=null},b.prototype.initGlobal=function(){var a=this.document;if(b._boundDocs=b._boundDocs||[],~w(b._boundDocs,a))return;b._boundDocs.push(a),b.bindPaste(a),b.bindKeys(a),b.bindCopy(a),b.fixIpad(a)},b.bindPaste=function(c){var a=c.defaultView;e(a,'paste',function(c){var a=b.focus;return a?(c.clipboardData?a.send(c.clipboardData.getData('text/plain')):a.context.clipboardData&&a.send(a.context.clipboardData.getData('Text')),a.element.contentEditable='inherit',d(c)):void 0})},b.bindKeys=function(a){e(a,'keydown',function(c){if(!b.focus)return;var a=c.target||c.srcElement;return a?a===b.focus.element||a===b.focus.context||a===b.focus.document||a===b.focus.body||a===b._textarea||a===b.focus.parent?b.focus.keyDown(c):void 0:void 0},!0),e(a,'keypress',function(c){if(!b.focus)return;var a=c.target||c.srcElement;return a?a===b.focus.element||a===b.focus.context||a===b.focus.document||a===b.focus.body||a===b._textarea||a===b.focus.parent?b.focus.keyPress(c):void 0:void 0},!0),e(a,'mousedown',function(c){if(!b.focus)return;var a=c.target||c.srcElement;if(!a)return;do if(a===b.focus.element)return;while(a=a.parentNode);b.focus.blur()})},b.bindCopy=function(c){var a=c.defaultView;e(a,'copy',function(e){var a=b.focus;if(!a)return;if(!a._selected)return;var c=a.getCopyTextarea(),d=a.grabText(a._selected.x1,a._selected.x2,a._selected.y1,a._selected.y2);a.emit('copy',d),c.focus(),c.textContent=d,c.value=d,c.setSelectionRange(0,d.length),i(function(){a.element.focus(),a.focus()},1)})},b.fixIpad=function(c){var a=c.createElement('textarea');a.style.position='absolute',a.style.width='0px',a.style.height='0px',a.style.opacity='0',a.style.backgroundColor='transparent',a.style.borderStyle='none',a.style.outlineStyle='none',a.autocapitalize='none',a.autocorrect='off',c.getElementsByTagName('body')[0].appendChild(a),b._textarea=a},b.prototype.open=function(f){var a=this,c=0,d;if(this.parent=f||this.parent,!this.parent)throw new Error('Terminal requires a parent element.');for(this.context=this.parent.ownerDocument.defaultView,this.document=this.parent.ownerDocument,this.body=this.document.getElementsByTagName('body')[0],this.context.navigator&&this.context.navigator.userAgent&&(this.isMac=!!~this.context.navigator.userAgent.indexOf('Mac'),this.isIpad=!!~this.context.navigator.userAgent.indexOf('iPad'),this.isIphone=!!~this.context.navigator.userAgent.indexOf('iPhone'),this.isMSIE=!!~this.context.navigator.userAgent.indexOf('MSIE')),this.element=this.document.createElement('div'),this.element.className='terminal',this.element.style.outline='none',this.element.setAttribute('tabindex',0),this.element.style.backgroundColor=this.colors[256],this.element.style.color=this.colors[257],this.children=[];c<this.rows;c++)d=this.document.createElement('div'),this.element.appendChild(d),this.children.push(d);this.parent.appendChild(this.element),this.refresh(0,this.rows-1),this.initGlobal(),this.focus(),this.startBlink(),e(this.element,'focus',function(){a.focus(),b._textarea.focus()}),e(this.element,'mousedown',function(){a.focus()}),e(this.element,'mousedown',function(c){var b=c.button!=null?+c.button:c.which!=null?c.which-1:null;if(a.isMSIE&&(b=b===1?0:b===4?1:b),b!==2)return;a.element.contentEditable='true',i(function(){a.element.contentEditable='inherit'},1)},!0),this.bindMouse(),b.brokenBold==null&&(b.brokenBold=x(this.document))},b.prototype.bindMouse=function(){function c(a){var c,d;if(c=m(a),d=l(a),!d)return;k(c,d);switch(a.type){case'mousedown':h=c;break;case'mouseup':h=32;break;case b:break}}function j(c){var a=h,b;if(b=l(c),!b)return;a+=32,k(a,b)}function i(c,b){if(!a.utfMouse){if(b===255)return c.push(0);b>127&&(b=127),c.push(b)}else{if(b===2047)return c.push(0);b<127?c.push(b):(b>2047&&(b=2047),c.push(192|b>>6),c.push(128|b&63))}}function k(b,c){if(a.vt300Mouse){b&=3,c.x-=32,c.y-=32;var d='[24';if(b===0)d+='1';else if(b===1)d+='3';else if(b===2)d+='5';else if(b===3)return;else d+='0';d+='~['+c.x+','+c.y+']\r',a.send(d);return}if(a.decLocator){b&=3,c.x-=32,c.y-=32,b===0?b=2:b===1?b=4:b===2?b=6:b===3&&(b=3),a.send('['+b+';'+(b===3?4:0)+';'+c.y+';'+c.x+';'+(c.page||0)+'&w');return}if(a.urxvtMouse){c.x-=32,c.y-=32,c.x++,c.y++,a.send('['+b+';'+c.x+';'+c.y+'M');return}if(a.sgrMouse){c.x-=32,c.y-=32,a.send('[<'+((b&3)===3?b&-4:b)+';'+c.x+';'+c.y+((b&3)===3?'m':'M'));return}var d=[];i(d,b),i(d,c.x),i(d,c.y),a.send(''+g.fromCharCode.apply(g,d))}function m(c){var b,f,g,e,d;switch(c.type){case'mousedown':b=c.button!=null?+c.button:c.which!=null?c.which-1:null;a.isMSIE&&(b=b===1?0:b===4?1:b);break;case'mouseup':b=3;break;case'DOMMouseScroll':b=c.detail<0?64:65;break;case'mousewheel':b=c.wheelDeltaY>0?64:65;break}return f=c.shiftKey?4:0,g=c.metaKey?8:0,e=c.ctrlKey?16:0,d=f|g|e,a.vt200Mouse?d&=e:a.normalMouse||(d=0),b=32+(d<<2)+b,b}function l(f){var c,d,g,h,e;if(f.pageX==null)return;c=f.pageX,d=f.pageY,e=a.element;while(e&&e!==a.document.documentElement)c-=e.offsetLeft,d-=e.offsetTop,e='offsetParent'in e?e.offsetParent:e.parentNode;return g=a.element.clientWidth,h=a.element.clientHeight,c=Math.round(c/g*a.cols),d=Math.round(d/h*a.rows),c<0&&(c=0),c>a.cols&&(c=a.cols),d<0&&(d=0),d>a.rows&&(d=a.rows),c+=32,d+=32,{x:c,y:d,type:f.type===b?'mousewheel':f.type}}var f=this.element,a=this,h=32,b='onmousewheel'in this.context?'mousewheel':'DOMMouseScroll';e(f,'mousedown',function(b){return a.mouseEvents?(c(b),a.focus(),a.vt200Mouse?(c({__proto__:b,type:'mouseup'}),d(b)):(a.normalMouse&&e(a.document,'mousemove',j),a.x10Mouse||e(a.document,'mouseup',function b(e){return c(e),a.normalMouse&&q(a.document,'mousemove',j),q(a.document,'mouseup',b),d(e)}),d(b))):void 0}),e(f,b,function(b){return a.mouseEvents?a.x10Mouse||a.vt300Mouse||a.decLocator?void 0:(c(b),d(b)):void 0}),e(f,b,function(b){return a.mouseEvents?void 0:a.applicationKeypad?void 0:(b.type==='DOMMouseScroll'?a.scrollDisp(b.detail<0?-5:5):a.scrollDisp(b.wheelDeltaY>0?-5:5),d(b))})},b.prototype.destroy=function(){this.readable=!1,this.writable=!1,this._events={},this.handler=function(){},this.write=function(){},this.element.parentNode&&this.element.parentNode.removeChild(this.element)},b.prototype.refresh=function(q,l){var o,g,f,n,a,h,p,c,j,k,e,d,r,i;for(l-q>=this.rows/2&&(i=this.element.parentNode,i&&i.removeChild(this.element)),p=this.cols,g=q,l>=this.lines.length&&(this.log('`end` is too large. Most likely a bad CSR.'),l=this.lines.length-1);g<=l;g++){for(r=g+this.ydisp,n=this.lines[r],a='',g===this.y&&this.cursorState&&(this.ydisp===this.ybase||this.selectMode)&&!this.cursorHidden?o=this.x:o=-1,j=this.defAttr,f=0;f<p;f++){c=n[f][0],h=n[f][1],f===o&&(c=-1),c!==j&&(j!==this.defAttr&&(a+='</span>'),c!==this.defAttr)&&(c===-1?a+='<span class="reverse-video terminal-cursor">':(a+='<span style="',k=c&511,e=c>>9&511,d=c>>18,d&1&&(b.brokenBold||(a+='font-weight:bold;'),e<8&&(e+=8)),d&2&&(a+='text-decoration:underline;'),d&4&&(d&2?(a=a.slice(0,-1),a+=' blink;'):a+='text-decoration:blink;'),d&8&&(k=c>>9&511,e=c&511,d&1&&e<8&&(e+=8)),d&16&&(a+='visibility:hidden;'),k!==256&&(a+='background-color:'+this.colors[k]+';'),e!==257&&(a+='color:'+this.colors[e]+';'),a+='">'));switch(h){case'&':a+='&amp;';break;case'<':a+='&lt;';break;case'>':a+='&gt;';break;default:h<=' '?a+='&nbsp;':(m(h)&&f++,a+=h);break}j=c}j!==this.defAttr&&(a+='</span>'),this.children[g].innerHTML=a}i&&i.appendChild(this.element)},b.prototype._cursorBlink=function(){if(b.focus!==this)return;this.cursorState^=1,this.refresh(this.y,this.y)},b.prototype.showCursor=function(){this.cursorState||(this.cursorState=1,this.refresh(this.y,this.y))},b.prototype.startBlink=function(){if(!this.cursorBlink)return;var a=this;this._blinker=function(){a._cursorBlink()},this._blink=s(this._blinker,500)},b.prototype.refreshBlink=function(){if(!this.cursorBlink)return;clearInterval(this._blink),this._blink=s(this._blinker,500)},b.prototype.scroll=function(){var a;++this.ybase===this.scrollback&&(this.ybase=this.ybase/2|0,this.lines=this.lines.slice(-(this.ybase+this.rows)+1)),this.ydisp=this.ybase,a=this.ybase+this.rows-1,a-=this.rows-1-this.scrollBottom,a===this.lines.length?this.lines.push(this.blankLine()):this.lines.splice(a,0,this.blankLine()),this.scrollTop!==0&&(this.ybase!==0&&(this.ybase--,this.ydisp=this.ybase),this.lines.splice(this.ybase+this.scrollTop,1)),this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.scrollDisp=function(a){this.ydisp+=a,this.ydisp>this.ybase?this.ydisp=this.ybase:this.ydisp<0&&(this.ydisp=0),this.refresh(0,this.rows-1)},b.prototype.write=function(i){var l=i.length,f=0,h,d,a;for(this.refreshStart=this.y,this.refreshEnd=this.y,this.ybase!==this.ydisp&&(this.ydisp=this.ybase,this.maxRange());f<l;f++){a=i[f];switch(this.state){case c:switch(a){case'':this.bell();break;case'\n':case'':case'':this.convertEol&&(this.x=0);this.y++;this.y>this.scrollBottom&&(this.y--,this.scroll());break;case'\r':this.x=0;break;case'':this.x>0&&this.x--;break;case'	':this.x=this.nextStop();break;case'':this.setgLevel(1);break;case'':this.setgLevel(0);break;case'':this.state=n;break;default:if(a>=' '&&(this.charset&&this.charset[a]&&(a=this.charset[a]),this.x>=this.cols&&(this.x=0,this.y++,this.y>this.scrollBottom&&(this.y--,this.scroll())),this.lines[this.y+this.ybase][this.x]=[this.curAttr,a],this.x++,this.updateRange(this.y),m(a))){if(h=this.y+this.ybase,this.cols<2||this.x>=this.cols){this.lines[h][this.x-1]=[this.curAttr,' '];break}this.lines[h][this.x]=[this.curAttr,' '],this.x++}break}break;case n:switch(a){case'[':this.params=[];this.currentParam=0;this.state=o;break;case']':this.params=[];this.currentParam=0;this.state=p;break;case'P':this.params=[];this.currentParam=0;this.state=r;break;case'_':this.state=j;break;case'^':this.state=j;break;case'c':this.reset();break;case'E':this.x=0;case'D':this.index();break;case'M':this.reverseIndex();break;case'%':this.setgLevel(0);this.setgCharset(0,b.charsets.US);this.state=c;f++;break;case'(':case')':case'*':case'+':case'-':case'.':switch(a){case'(':this.gcharset=0;break;case')':this.gcharset=1;break;case'*':this.gcharset=2;break;case'+':this.gcharset=3;break;case'-':this.gcharset=1;break;case'.':this.gcharset=2;break}this.state=k;break;case'/':this.gcharset=3;this.state=k;f--;break;case'N':break;case'O':break;case'n':this.setgLevel(2);break;case'o':this.setgLevel(3);break;case'|':this.setgLevel(3);break;case'}':this.setgLevel(2);break;case'~':this.setgLevel(1);break;case'7':this.saveCursor();this.state=c;break;case'8':this.restoreCursor();this.state=c;break;case'#':this.state=c;f++;break;case'H':this.tabSet();break;case'=':this.log('Serial port requested application keypad.');this.applicationKeypad=!0;this.state=c;break;case'>':this.log('Switching back to normal keypad.');this.applicationKeypad=!1;this.state=c;break;default:this.state=c;this.error('Unknown ESC control: %s.',a);break}break;case k:switch(a){case'0':d=b.charsets.SCLD;break;case'A':d=b.charsets.UK;break;case'B':d=b.charsets.US;break;case'4':d=b.charsets.Dutch;break;case'C':case'5':d=b.charsets.Finnish;break;case'R':d=b.charsets.French;break;case'Q':d=b.charsets.FrenchCanadian;break;case'K':d=b.charsets.German;break;case'Y':d=b.charsets.Italian;break;case'E':case'6':d=b.charsets.NorwegianDanish;break;case'Z':d=b.charsets.Spanish;break;case'H':case'7':d=b.charsets.Swedish;break;case'=':d=b.charsets.Swiss;break;case'/':d=b.charsets.ISOLatin;f++;break;default:d=b.charsets.US;break}this.setgCharset(this.gcharset,d);this.gcharset=null;this.state=c;break;case p:if(a===''||a===''){a===''&&f++,this.params.push(this.currentParam);switch(this.params[0]){case 0:case 1:case 2:this.params[1]&&(this.title=this.params[1],this.handleTitle(this.title));break;case 3:break;case 4:case 5:break;case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:break;case 46:break;case 50:break;case 51:break;case 52:break;case 104:case 105:case 110:case 111:case 112:case 113:case 114:case 115:case 116:case 117:case 118:break}this.params=[],this.currentParam=0,this.state=c}else this.params.length?this.currentParam+=a:a>='0'&&a<='9'?this.currentParam=this.currentParam*10+a.charCodeAt(0)-48:a===';'&&(this.params.push(this.currentParam),this.currentParam='');break;case o:if(a==='?'||a==='>'||a==='!'){this.prefix=a;break}if(a>='0'&&a<='9'){this.currentParam=this.currentParam*10+a.charCodeAt(0)-48;break}if(a==='$'||a==='"'||a===' '||a==="'"){this.postfix=a;break}this.params.push(this.currentParam);this.currentParam=0;if(a===';')break;this.state=c;switch(a){case'A':this.cursorUp(this.params);break;case'B':this.cursorDown(this.params);break;case'C':this.cursorForward(this.params);break;case'D':this.cursorBackward(this.params);break;case'H':this.cursorPos(this.params);break;case'J':this.eraseInDisplay(this.params);break;case'K':this.eraseInLine(this.params);break;case'm':this.prefix||this.charAttributes(this.params);break;case'n':this.prefix||this.deviceStatus(this.params);break;case'@':this.insertChars(this.params);break;case'E':this.cursorNextLine(this.params);break;case'F':this.cursorPrecedingLine(this.params);break;case'G':this.cursorCharAbsolute(this.params);break;case'L':this.insertLines(this.params);break;case'M':this.deleteLines(this.params);break;case'P':this.deleteChars(this.params);break;case'X':this.eraseChars(this.params);break;case'`':this.charPosAbsolute(this.params);break;case'a':this.HPositionRelative(this.params);break;case'c':this.sendDeviceAttributes(this.params);break;case'd':this.linePosAbsolute(this.params);break;case'e':this.VPositionRelative(this.params);break;case'f':this.HVPosition(this.params);break;case'h':this.setMode(this.params);break;case'l':this.resetMode(this.params);break;case'r':this.setScrollRegion(this.params);break;case's':this.saveCursor(this.params);break;case'u':this.restoreCursor(this.params);break;case'I':this.cursorForwardTab(this.params);break;case'S':this.scrollUp(this.params);break;case'T':this.params.length<2&&!this.prefix&&this.scrollDown(this.params);break;case'Z':this.cursorBackwardTab(this.params);break;case'b':this.repeatPrecedingCharacter(this.params);break;case'g':this.tabClear(this.params);break;case'p':switch(this.prefix){case'!':this.softReset(this.params);break}break;default:this.error('Unknown CSI code: %s.',a);break}this.prefix='';this.postfix='';break;case r:if(a===''||a===''){a===''&&f++;switch(this.prefix){case'':break;case'$q':var e=this.currentParam,g=!1;switch(e){case'"q':e='0"q';break;case'"p':e='61"p';break;case'r':e=''+(this.scrollTop+1)+';'+(this.scrollBottom+1)+'r';break;case'm':e='0m';break;default:this.error('Unknown DCS Pt: %s.',e);e='';break}this.send('P'+ +g+'$r'+e+'\\');break;case'+p':break;case'+q':var e=this.currentParam,g=!1;this.send('P'+ +g+'+r'+e+'\\');break;default:this.error('Unknown DCS prefix: %s.',this.prefix);break}this.currentParam=0,this.prefix='',this.state=c}else this.currentParam?this.currentParam+=a:!this.prefix&&a!=='$'&&a!=='+'?this.currentParam=a:this.prefix.length===2?this.currentParam=a:this.prefix+=a;break;case j:(a===''||a==='')&&(a===''&&f++,this.state=c);break}}this.updateRange(this.y),this.refresh(this.refreshStart,this.refreshEnd)},b.prototype.writeln=function(a){this.write(a+'\r\n')},b.prototype.keyDown=function(b){var c=this,a;switch(b.keyCode){case 8:if(b.shiftKey){a='';break}a='';break;case 9:if(b.shiftKey){a='';break}a='	';break;case 13:a='\r';break;case 27:a='';break;case 37:if(this.applicationCursor){a='OD';break}a='';break;case 39:if(this.applicationCursor){a='OC';break}a='';break;case 38:if(this.applicationCursor){a='OA';break}if(b.ctrlKey)return this.scrollDisp(-1),d(b);a='';break;case 40:if(this.applicationCursor){a='OB';break}if(b.ctrlKey)return this.scrollDisp(1),d(b);a='';break;case 46:a='[3~';break;case 45:a='[2~';break;case 36:if(this.applicationKeypad){a='OH';break}a='OH';break;case 35:if(this.applicationKeypad){a='OF';break}a='OF';break;case 33:if(b.shiftKey)return this.scrollDisp(-(this.rows-1)),d(b);a='[5~';break;case 34:if(b.shiftKey)return this.scrollDisp(this.rows-1),d(b);a='[6~';break;case 112:a='OP';break;case 113:a='OQ';break;case 114:a='OR';break;case 115:a='OS';break;case 116:a='[15~';break;case 117:a='[17~';break;case 118:a='[18~';break;case 119:a='[19~';break;case 120:a='[20~';break;case 121:a='[21~';break;case 122:a='[23~';break;case 123:a='[24~';break;default:if(b.ctrlKey)if(b.keyCode>=65&&b.keyCode<=90){if(this.screenKeys&&!(this.prefixMode||this.selectMode)&&b.keyCode===65)return this.enterPrefix(),d(b);if(this.prefixMode&&b.keyCode===86){this.leavePrefix();return}if((this.prefixMode||this.selectMode)&&b.keyCode===67){this.visualMode&&i(function(){c.leaveVisual()},1);return}a=g.fromCharCode(b.keyCode-64)}else b.keyCode===32?a=g.fromCharCode(0):b.keyCode>=51&&b.keyCode<=55?a=g.fromCharCode(b.keyCode-51+27):b.keyCode===56?a=g.fromCharCode(127):b.keyCode===219?a=g.fromCharCode(27):b.keyCode===221&&(a=g.fromCharCode(29));else(!this.isMac&&b.altKey||this.isMac&&b.metaKey)&&(b.keyCode>=65&&b.keyCode<=90?a=''+g.fromCharCode(b.keyCode+32):b.keyCode===192?a='`':b.keyCode>=48&&b.keyCode<=57&&(a=''+(b.keyCode-48)));break}return a?this.prefixMode?(this.leavePrefix(),d(b)):this.selectMode?(this.keySelect(b,a),d(b)):(this.emit('keydown',b),this.emit('key',a,b),this.showCursor(),this.handler(a),b.keyCode===86&&(this.isMac&&b.metaKey||!this.isMac&&b.ctrlKey)?!0:d(b)):!0},b.prototype.setgLevel=function(a){this.glevel=a,this.charset=this.charsets[a]},b.prototype.setgCharset=function(a,b){this.charsets[a]=b,this.glevel===a&&(this.charset=b)},b.prototype.keyPress=function(a){var b;if(a.charCode)b=a.charCode;else if(a.which==null)b=a.keyCode;else if(a.which!==0&&a.charCode!==0)b=a.which;else return!1;return b===118&&(this.isMac&&a.metaKey||!this.isMac&&a.ctrlKey)||d(a),!b||a.ctrlKey||a.altKey&&b!=118||a.metaKey&&b!=118?!1:(b=g.fromCharCode(b),this.prefixMode?(this.leavePrefix(),this.keyPrefix(a,b),!1):this.selectMode?(this.keySelect(a,b),!1):(this.emit('keypress',b,a),this.emit('key',b,a),this.showCursor(),b==='v'&&(this.isMac&&a.metaKey||!this.isMac&&a.ctrlKey)||this.handler(b),!1))},b.prototype.send=function(b){var a=this;this.queue||i(function(){a.handler(a.queue),a.queue=''},1),this.queue+=b},b.prototype.bell=function(){if(!this.visualBell)return;var a=this;this.element.style.borderColor='white',i(function(){a.element.style.borderColor=''},10),this.popOnBell&&this.focus()},b.prototype.log=function(){if(!this.debug)return;if(!(this.context.console&&this.context.console.log))return;var a=Array.prototype.slice.call(arguments);this.context.console.log.apply(this.context.console,a)},b.prototype.error=function(){if(!this.debug)return;if(!(this.context.console&&this.context.console.error))return;var a=Array.prototype.slice.call(arguments);this.context.console.error.apply(this.context.console,a)},b.prototype.resize=function(b,a){var f,e,d,c,g;if(b<1&&(b=1),a<1&&(a=1),c=this.cols,c<b){g=[this.defAttr,' '],d=this.lines.length;while(d--)while(this.lines[d].length<b)this.lines[d].push(g)}else if(c>b){d=this.lines.length;while(d--)while(this.lines[d].length>b)this.lines[d].pop()}if(this.setupStops(c),this.cols=b,c=this.rows,c<a){e=this.element;while(c++<a)this.lines.length<a+this.ybase&&this.lines.push(this.blankLine()),this.children.length<a&&(f=this.document.createElement('div'),e.appendChild(f),this.children.push(f))}else if(c>a)while(c-->a)if(this.lines.length>a+this.ybase&&this.lines.pop(),this.children.length>a){if(e=this.children.pop(),!e)continue;e.parentNode.removeChild(e)}this.rows=a,this.y>=a&&(this.y=a-1),this.x>=b&&(this.x=b-1),this.scrollTop=0,this.scrollBottom=a-1,this.refresh(0,this.rows-1),this.normal=null},b.prototype.updateRange=function(a){a<this.refreshStart&&(this.refreshStart=a),a>this.refreshEnd&&(this.refreshEnd=a)},b.prototype.maxRange=function(){this.refreshStart=0,this.refreshEnd=this.rows-1},b.prototype.setupStops=function(a){for(a!=null?this.tabs[a]||(a=this.prevStop(a)):(this.tabs={},a=0);a<this.cols;a+=8)this.tabs[a]=!0},b.prototype.prevStop=function(a){a==null&&(a=this.x);while(!this.tabs[--a]&&a>0);return a>=this.cols?this.cols-1:a<0?0:a},b.prototype.nextStop=function(a){a==null&&(a=this.x);while(!this.tabs[++a]&&a<this.cols);return a>=this.cols?this.cols-1:a<0?0:a},b.prototype.eraseRight=function(a,b){var c=this.lines[this.ybase+b],d=[this.eraseAttr(),' '];for(;a<this.cols;a++)c[a]=d;this.updateRange(b)},b.prototype.eraseLeft=function(a,b){var c=this.lines[this.ybase+b],d=[this.eraseAttr(),' '];a++;while(a--)c[a]=d;this.updateRange(b)},b.prototype.eraseLine=function(a){this.eraseRight(0,a)},b.prototype.blankLine=function(e){var c=e?this.eraseAttr():this.defAttr,d=[c,' '],b=[],a=0;for(;a<this.cols;a++)b[a]=d;return b},b.prototype.ch=function(a){return a?[this.eraseAttr(),' ']:[this.defAttr,' ']},b.prototype.is=function(b){var a=this.termName;return(a+'').indexOf(b)===0},b.prototype.handler=function(a){this.emit('data',a)},b.prototype.handleTitle=function(a){this.emit('title',a)},b.prototype.index=function(){this.y++,this.y>this.scrollBottom&&(this.y--,this.scroll()),this.state=c},b.prototype.reverseIndex=function(){var a;this.y--,this.y<this.scrollTop&&(this.y++,this.lines.splice(this.y+this.ybase,0,this.blankLine(!0)),a=this.rows-1-this.scrollBottom,this.lines.splice(this.rows-1+this.ybase-a+1,1),this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)),this.state=c},b.prototype.reset=function(){this.options.rows=this.rows,this.options.cols=this.cols,b.call(this,this.options),this.refresh(0,this.rows-1)},b.prototype.tabSet=function(){this.tabs[this.x]=!0,this.state=c},b.prototype.cursorUp=function(b){var a=b[0];a<1&&(a=1),this.y-=a,this.y<0&&(this.y=0)},b.prototype.cursorDown=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.cursorForward=function(b){var a=b[0];a<1&&(a=1),this.x+=a,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.cursorBackward=function(b){var a=b[0];a<1&&(a=1),this.x-=a,this.x<0&&(this.x=0)},b.prototype.cursorPos=function(c){var b,a;b=c[0]-1,c.length>=2?a=c[1]-1:a=0,b<0?b=0:b>=this.rows&&(b=this.rows-1),a<0?a=0:a>=this.cols&&(a=this.cols-1),this.x=a,this.y=b},b.prototype.eraseInDisplay=function(b){var a;switch(b[0]){case 0:this.eraseRight(this.x,this.y);a=this.y+1;for(;a<this.rows;a++)this.eraseLine(a);break;case 1:this.eraseLeft(this.x,this.y);a=this.y;while(a--)this.eraseLine(a);break;case 2:a=this.rows;while(a--)this.eraseLine(a);break;case 3:break}},b.prototype.eraseInLine=function(a){switch(a[0]){case 0:this.eraseRight(this.x,this.y);break;case 1:this.eraseLeft(this.x,this.y);break;case 2:this.eraseLine(this.y);break}},b.prototype.charAttributes=function(c){if(c.length===1&&c[0]===0){this.curAttr=this.defAttr;return}var g=c.length,b=0,d=this.curAttr>>18,e=this.curAttr>>9&511,f=this.curAttr&511,a;for(;b<g;b++)a=c[b],a>=30&&a<=37?e=a-30:a>=40&&a<=47?f=a-40:a>=90&&a<=97?(a+=8,e=a-90):a>=100&&a<=107?(a+=8,f=a-100):a===0?(d=this.defAttr>>18,e=this.defAttr>>9&511,f=this.defAttr&511):a===1?d|=1:a===4?d|=2:a===5?d|=4:a===7?d|=8:a===8?d|=16:a===22?d&=-2:a===24?d&=-3:a===25?d&=-5:a===27?d&=-9:a===28?d&=-17:a===39?e=this.defAttr>>9&511:a===49?f=this.defAttr&511:a===38?c[b+1]===2?(b+=2,e=h(c[b]&255,c[b+1]&255,c[b+2]&255),e===-1&&(e=511),b+=2):c[b+1]===5&&(b+=2,a=c[b]&255,e=a):a===48?c[b+1]===2?(b+=2,f=h(c[b]&255,c[b+1]&255,c[b+2]&255),f===-1&&(f=511),b+=2):c[b+1]===5&&(b+=2,a=c[b]&255,f=a):a===100?(e=this.defAttr>>9&511,f=this.defAttr&511):this.error('Unknown SGR attribute: %d.',a);this.curAttr=d<<18|e<<9|f},b.prototype.deviceStatus=function(a){if(!this.prefix)switch(a[0]){case 5:this.send('');break;case 6:this.send('['+(this.y+1)+';'+(this.x+1)+'R');break}else if(this.prefix==='?')switch(a[0]){case 6:this.send('[?'+(this.y+1)+';'+(this.x+1)+'R');break;case 15:break;case 25:break;case 26:break;case 53:break}},b.prototype.insertChars=function(e){var a,b,c,d;a=e[0],a<1&&(a=1),b=this.y+this.ybase,c=this.x,d=[this.eraseAttr(),' '];while(a--&&c<this.cols)this.lines[b].splice(c++,0,d),this.lines[b].pop()},b.prototype.cursorNextLine=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1),this.x=0},b.prototype.cursorPrecedingLine=function(b){var a=b[0];a<1&&(a=1),this.y-=a,this.y<0&&(this.y=0),this.x=0},b.prototype.cursorCharAbsolute=function(b){var a=b[0];a<1&&(a=1),this.x=a-1},b.prototype.insertLines=function(d){var a,c,b;a=d[0],a<1&&(a=1),c=this.y+this.ybase,b=this.rows-1-this.scrollBottom,b=this.rows-1+this.ybase-b+1;while(a--)this.lines.splice(c,0,this.blankLine(!0)),this.lines.splice(b,1);this.updateRange(this.y),this.updateRange(this.scrollBottom)},b.prototype.deleteLines=function(d){var a,c,b;a=d[0],a<1&&(a=1),c=this.y+this.ybase,b=this.rows-1-this.scrollBottom,b=this.rows-1+this.ybase-b;while(a--)this.lines.splice(b+1,0,this.blankLine(!0)),this.lines.splice(c,1);this.updateRange(this.y),this.updateRange(this.scrollBottom)},b.prototype.deleteChars=function(d){var a,b,c;a=d[0],a<1&&(a=1),b=this.y+this.ybase,c=[this.eraseAttr(),' '];while(a--)this.lines[b].splice(this.x,1),this.lines[b].push(c)},b.prototype.eraseChars=function(e){var a,c,b,d;a=e[0],a<1&&(a=1),c=this.y+this.ybase,b=this.x,d=[this.eraseAttr(),' '];while(a--&&b<this.cols)this.lines[c][b++]=d},b.prototype.charPosAbsolute=function(b){var a=b[0];a<1&&(a=1),this.x=a-1,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.HPositionRelative=function(b){var a=b[0];a<1&&(a=1),this.x+=a,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.sendDeviceAttributes=function(a){if(a[0]>0)return;this.prefix?this.prefix==='>'&&(this.is('xterm')?this.send('[>0;276;0c'):this.is('rxvt-unicode')?this.send('[>85;95;0c'):this.is('linux')?this.send(a[0]+'c'):this.is('screen')&&this.send('[>83;40003;0c')):this.is('xterm')||this.is('rxvt-unicode')||this.is('screen')?this.send('[?1;2c'):this.is('linux')&&this.send('[?6c')},b.prototype.linePosAbsolute=function(b){var a=b[0];a<1&&(a=1),this.y=a-1,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.VPositionRelative=function(b){var a=b[0];a<1&&(a=1),this.y+=a,this.y>=this.rows&&(this.y=this.rows-1)},b.prototype.HVPosition=function(a){a[0]<1&&(a[0]=1),a[1]<1&&(a[1]=1),this.y=a[0]-1,this.y>=this.rows&&(this.y=this.rows-1),this.x=a[1]-1,this.x>=this.cols&&(this.x=this.cols-1)},b.prototype.setMode=function(a){if(typeof a==='object'){var d=a.length,c=0;for(;c<d;c++)this.setMode(a[c]);return}if(!this.prefix)switch(a){case 4:this.insertMode=!0;break;case 20:break}else if(this.prefix==='?')switch(a){case 1:this.applicationCursor=!0;break;case 2:this.setgCharset(0,b.charsets.US);this.setgCharset(1,b.charsets.US);this.setgCharset(2,b.charsets.US);this.setgCharset(3,b.charsets.US);break;case 3:this.savedCols=this.cols;this.resize(132,this.rows);break;case 6:this.originMode=!0;break;case 7:this.wraparoundMode=!0;break;case 12:break;case 66:this.log('Serial port requested application keypad.');this.applicationKeypad=!0;break;case 9:case 1e3:case 1002:case 1003:this.x10Mouse=a===9;this.vt200Mouse=a===1e3;this.normalMouse=a>1e3;this.mouseEvents=!0;this.element.style.cursor='default';this.log('Binding to mouse events.');break;case 1004:this.sendFocus=!0;break;case 1005:this.utfMouse=!0;break;case 1006:this.sgrMouse=!0;break;case 1015:this.urxvtMouse=!0;break;case 25:this.cursorHidden=!1;break;case 1049:case 47:case 1047:if(!this.normal){var e={lines:this.lines,ybase:this.ybase,ydisp:this.ydisp,x:this.x,y:this.y,scrollTop:this.scrollTop,scrollBottom:this.scrollBottom,tabs:this.tabs};this.reset(),this.normal=e,this.showCursor()}break}},b.prototype.resetMode=function(a){if(typeof a==='object'){var c=a.length,b=0;for(;b<c;b++)this.resetMode(a[b]);return}if(!this.prefix)switch(a){case 4:this.insertMode=!1;break;case 20:break}else if(this.prefix==='?')switch(a){case 1:this.applicationCursor=!1;break;case 3:this.cols===132&&this.savedCols&&this.resize(this.savedCols,this.rows);delete this.savedCols;break;case 6:this.originMode=!1;break;case 7:this.wraparoundMode=!1;break;case 12:break;case 66:this.log('Switching back to normal keypad.');this.applicationKeypad=!1;break;case 9:case 1e3:case 1002:case 1003:this.x10Mouse=!1;this.vt200Mouse=!1;this.normalMouse=!1;this.mouseEvents=!1;this.element.style.cursor='';break;case 1004:this.sendFocus=!1;break;case 1005:this.utfMouse=!1;break;case 1006:this.sgrMouse=!1;break;case 1015:this.urxvtMouse=!1;break;case 25:this.cursorHidden=!0;break;case 1049:case 47:case 1047:this.normal&&(this.lines=this.normal.lines,this.ybase=this.normal.ybase,this.ydisp=this.normal.ydisp,this.x=this.normal.x,this.y=this.normal.y,this.scrollTop=this.normal.scrollTop,this.scrollBottom=this.normal.scrollBottom,this.tabs=this.normal.tabs,this.normal=null,this.refresh(0,this.rows-1),this.showCursor());break}},b.prototype.setScrollRegion=function(a){if(this.prefix)return;this.scrollTop=(a[0]||1)-1,this.scrollBottom=(a[1]||this.rows)-1,this.x=0,this.y=0},b.prototype.saveCursor=function(a){this.savedX=this.x,this.savedY=this.y},b.prototype.restoreCursor=function(a){this.x=this.savedX||0,this.y=this.savedY||0},b.prototype.cursorForwardTab=function(b){var a=b[0]||1;while(a--)this.x=this.nextStop()},b.prototype.scrollUp=function(b){var a=b[0]||1;while(a--)this.lines.splice(this.ybase+this.scrollTop,1),this.lines.splice(this.ybase+this.scrollBottom,0,this.blankLine());this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.scrollDown=function(b){var a=b[0]||1;while(a--)this.lines.splice(this.ybase+this.scrollBottom,1),this.lines.splice(this.ybase+this.scrollTop,0,this.blankLine());this.updateRange(this.scrollTop),this.updateRange(this.scrollBottom)},b.prototype.initMouseTracking=function(a){},b.prototype.resetTitleModes=function(a){},b.prototype.cursorBackwardTab=function(b){var a=b[0]||1;while(a--)this.x=this.prevStop()},b.prototype.repeatPrecedingCharacter=function(d){var b=d[0]||1,a=this.lines[this.ybase+this.y],c=a[this.x-1]||[this.defAttr,' '];while(b--)a[this.x++]=c},b.prototype.tabClear=function(b){var a=b[0];a<=0?delete this.tabs[this.x]:a===3&&(this.tabs={})},b.prototype.mediaCopy=function(a){},b.prototype.setResources=function(a){},b.prototype.disableModifiers=function(a){},b.prototype.setPointerMode=function(a){},b.prototype.softReset=function(a){this.cursorHidden=!1,this.insertMode=!1,this.originMode=!1,this.wraparoundMode=!1,this.applicationKeypad=!1,this.applicationCursor=!1,this.scrollTop=0,this.scrollBottom=this.rows-1,this.curAttr=this.defAttr,this.x=this.y=0,this.charset=null,this.glevel=0,this.charsets=[null]},b.prototype.requestAnsiMode=function(a){},b.prototype.requestPrivateMode=function(a){},b.prototype.setConformanceLevel=function(a){},b.prototype.loadLEDs=function(a){},b.prototype.setCursorStyle=function(a){},b.prototype.setCharProtectionAttr=function(a){},b.prototype.restorePrivateValues=function(a){},b.prototype.setAttrInRectangle=function(a){var c=a[0],e=a[1],f=a[2],g=a[3],h=a[4],d,b;for(;c<f+1;c++)for(d=this.lines[this.ybase+c],b=e;b<g;b++)d[b]=[h,d[b][1]];this.updateRange(a[0]),this.updateRange(a[2])},b.prototype.savePrivateValues=function(a){},b.prototype.manipulateWindow=function(a){},b.prototype.reverseAttrInRectangle=function(a){},b.prototype.setTitleModeFeature=function(a){},b.prototype.setWarningBellVolume=function(a){},b.prototype.setMarginBellVolume=function(a){},b.prototype.copyRectangle=function(a){},b.prototype.enableFilterRectangle=function(a){},b.prototype.requestParameters=function(a){},b.prototype.selectChangeExtent=function(a){},b.prototype.fillRectangle=function(a){var e=a[0],c=a[1],f=a[2],h=a[3],i=a[4],d,b;for(;c<h+1;c++)for(d=this.lines[this.ybase+c],b=f;b<i;b++)d[b]=[d[b][0],g.fromCharCode(e)];this.updateRange(a[1]),this.updateRange(a[3])},b.prototype.enableLocatorReporting=function(a){var b=a[0]>0},b.prototype.eraseRectangle=function(a){var b=a[0],d=a[1],e=a[2],f=a[3],g,c,h;for(h=[this.eraseAttr(),' '];b<e+1;b++)for(g=this.lines[this.ybase+b],c=d;c<f;c++)g[c]=h;this.updateRange(a[0]),this.updateRange(a[2])},b.prototype.setLocatorEvents=function(a){},b.prototype.selectiveEraseRectangle=function(a){},b.prototype.requestLocatorPosition=function(a){},b.prototype.insertColumns=function(){var b=params[0],c=this.ybase+this.rows,d=[this.eraseAttr(),' '],a;while(b--)for(a=this.ybase;a<c;a++)this.lines[a].splice(this.x+1,0,d),this.lines[a].pop();this.maxRange()},b.prototype.deleteColumns=function(){var b=params[0],c=this.ybase+this.rows,d=[this.eraseAttr(),' '],a;while(b--)for(a=this.ybase;a<c;a++)this.lines[a].splice(this.x,1),this.lines[a].push(d);this.maxRange()},b.prototype.enterPrefix=function(){this.prefixMode=!0},b.prototype.leavePrefix=function(){this.prefixMode=!1},b.prototype.enterSelect=function(){this._real={x:this.x,y:this.y,ydisp:this.ydisp,ybase:this.ybase,cursorHidden:this.cursorHidden,lines:this.copyBuffer(this.lines),write:this.write},this.write=function(){},this.selectMode=!0,this.visualMode=!1,this.cursorHidden=!1,this.refresh(this.y,this.y)},b.prototype.leaveSelect=function(){this.x=this._real.x,this.y=this._real.y,this.ydisp=this._real.ydisp,this.ybase=this._real.ybase,this.cursorHidden=this._real.cursorHidden,this.lines=this._real.lines,this.write=this._real.write,delete this._real,this.selectMode=!1,this.visualMode=!1,this.refresh(0,this.rows-1)},b.prototype.enterVisual=function(){this._real.preVisual=this.copyBuffer(this.lines),this.selectText(this.x,this.x,this.ydisp+this.y,this.ydisp+this.y),this.visualMode=!0},b.prototype.leaveVisual=function(){this.lines=this._real.preVisual,delete this._real.preVisual,delete this._selected,this.visualMode=!1,this.refresh(0,this.rows-1)},b.prototype.enterSearch=function(c){this.entry='',this.searchMode=!0,this.searchDown=c,this._real.preSearch=this.copyBuffer(this.lines),this._real.preSearchX=this.x,this._real.preSearchY=this.y;var b=this.ydisp+this.rows-1;for(var a=0;a<this.entryPrefix.length;a++)this.lines[b][a]=[this.defAttr&-512|4,this.entryPrefix[a]];this.y=this.rows-1,this.x=this.entryPrefix.length,this.refresh(this.rows-1,this.rows-1)},b.prototype.leaveSearch=function(){this.searchMode=!1,this._real.preSearch&&(this.lines=this._real.preSearch,this.x=this._real.preSearchX,this.y=this._real.preSearchY,delete this._real.preSearch,delete this._real.preSearchX,delete this._real.preSearchY),this.refresh(this.rows-1,this.rows-1)},b.prototype.copyBuffer=function(b){var b=b||this.lines,d=[];for(var a=0;a<b.length;a++){d[a]=[];for(var c=0;c<b[a].length;c++)d[a][c]=[b[a][c][0],b[a][c][1]]}return d},b.prototype.getCopyTextarea=function(c){var a=this._copyTextarea,b=this.document;return a||(a=b.createElement('textarea'),a.style.position='absolute',a.style.left='-32000px',a.style.top='-32000px',a.style.width='0px',a.style.height='0px',a.style.opacity='0',a.style.backgroundColor='transparent',a.style.borderStyle='none',a.style.outlineStyle='none',b.getElementsByTagName('body')[0].appendChild(a),this._copyTextarea=a),a},b.prototype.copyText=function(b){var c=this,a=this.getCopyTextarea();this.emit('copy',b),a.focus(),a.textContent=b,a.value=b,a.setSelectionRange(0,b.length),i(function(){c.element.focus(),c.focus()},1)},b.prototype.selectText=function(f,g,b,d){var j,k,i,h,e,c,a,l,m;if(this._selected){for(j=this._selected.x1,k=this._selected.x2,i=this._selected.y1,h=this._selected.y2,h<i&&(e=k,k=j,j=e,e=h,h=i,i=e),k<j&&i===h&&(e=k,k=j,j=e),a=i;a<=h;a++)for(c=0,l=this.cols-1,a===i&&(c=j),a===h&&(l=k);c<=l;c++)this.lines[a][c].old!=null&&(m=this.lines[a][c].old,delete this.lines[a][c].old,this.lines[a][c]=[m,this.lines[a][c][1]]);b=this._selected.y1,f=this._selected.x1}for(b=Math.max(b,0),b=Math.min(b,this.ydisp+this.rows-1),d=Math.max(d,0),d=Math.min(d,this.ydisp+this.rows-1),this._selected={x1:f,x2:g,y1:b,y2:d},d<b&&(e=g,g=f,f=e,e=d,d=b,b=e),g<f&&b===d&&(e=g,g=f,f=e),a=b;a<=d;a++)for(c=0,l=this.cols-1,a===b&&(c=f),a===d&&(l=g);c<=l;c++)m=this.lines[a][c][0],this.lines[a][c]=[m&-512|261636,this.lines[a][c][1]],this.lines[a][c].old=m;b-=this.ydisp,d-=this.ydisp,b=Math.max(b,0),b=Math.min(b,this.rows-1),d=Math.max(d,0),d=Math.min(d,this.rows-1),this.refresh(0,this.rows-1)},b.prototype.grabText=function(g,c,i,d){var e='',f='',j,a,b,k,h;for(d<i&&(h=c,c=g,g=h,h=d,d=i,i=h),c<g&&i===d&&(h=c,c=g,g=h),b=i;b<=d;b++){for(a=0,k=this.cols-1,b===i&&(a=g),b===d&&(k=c);a<=k;a++){if(j=this.lines[b][a][1],j===' '){f+=j;continue}f&&(e+=f,f=''),e+=j,m(j)&&a++}f='',e+='\n'}for(a=c,b=d;a<this.cols;a++)if(this.lines[b][a][1]!==' '){e=e.slice(0,-1);break}return e},b.prototype.keyPrefix=function(b,a){a==='k'||a==='&'?this.destroy():a==='p'||a===']'?this.emit('request paste'):a==='c'?this.emit('request create'):a>='0'&&a<='9'?(a=+a-1,~a||(a=9),this.emit('request term',a)):a==='n'?this.emit('request term next'):a==='P'?this.emit('request term previous'):a===':'?this.emit('request command mode'):a==='['&&this.enterSelect()},b.prototype.keySelect=function(o,b){if(this.showCursor(),this.searchMode||b==='n'||b==='N')return this.keySearch(o,b);if(b===''){var c=this.ydisp+this.y;this.ydisp===this.ybase?(this.y=Math.min(this.y+(this.rows-1)/2|0,this.rows-1),this.refresh(0,this.rows-1)):this.scrollDisp((this.rows-1)/2|0),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.ydisp===0?(this.y=Math.max(this.y-(this.rows-1)/2|0,0),this.refresh(0,this.rows-1)):this.scrollDisp(-(this.rows-1)/2|0),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.scrollDisp(this.rows-1),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b===''){var c=this.ydisp+this.y;this.scrollDisp(-(this.rows-1)),this.visualMode&&this.selectText(this.x,this.x,c,this.ydisp+this.y);return}if(b==='k'||b===''){var c=this.ydisp+this.y;this.y--,this.y<0&&(this.y=0,this.scrollDisp(-1)),this.visualMode?this.selectText(this.x,this.x,c,this.ydisp+this.y):this.refresh(this.y,this.y+1);return}if(b==='j'||b===''){var c=this.ydisp+this.y;this.y++,this.y>=this.rows&&(this.y=this.rows-1,this.scrollDisp(1)),this.visualMode?this.selectText(this.x,this.x,c,this.ydisp+this.y):this.refresh(this.y-1,this.y);return}if(b==='h'||b===''){var a=this.x;this.x--,this.x<0&&(this.x=0),this.visualMode?this.selectText(a,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='l'||b===''){var a=this.x;this.x++,this.x>=this.cols&&(this.x=this.cols-1),this.visualMode?this.selectText(a,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='v'||b===' '){this.visualMode?this.leaveVisual():this.enterVisual();return}if(b==='y'){if(this.visualMode){var n=this.grabText(this._selected.x1,this._selected.x2,this._selected.y1,this._selected.y2);this.copyText(n),this.leaveVisual()}return}if(b==='q'||b===''){this.visualMode?this.leaveVisual():this.leaveSelect();return}if(b==='w'||b==='W'){var f=this.x,g=this.y,h=this.ydisp,a=this.x,c=this.y,d=this.ydisp,i=!1;for(;;){var e=this.lines[d+c];while(a<this.cols){if(e[a][1]<=' ')i=!0;else if(i)break;a++}if(a>=this.cols&&(a=this.cols-1),a===this.cols-1&&e[a][1]<=' '){if(a=0,++c>=this.rows&&(c--,++d>this.ybase)){d=this.ybase,a=this.x;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='b'||b==='B'){var f=this.x,g=this.y,h=this.ydisp,a=this.x,c=this.y,d=this.ydisp;for(;;){var e=this.lines[d+c],i=a>0&&e[a][1]>' '&&e[a-1][1]>' ';while(a>=0){if(e[a][1]<=' ')if(i&&a+1<this.cols&&e[a+1][1]>' '){a++;break}else i=!0;a--}if(a<0&&(a=0),a===0&&(e[a][1]<=' '||!i)){if(a=this.cols-1,--c<0&&(c++,--d<0)){d++,a=0;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='e'||b==='E'){var a=this.x+1,c=this.y,d=this.ydisp;for(a>=this.cols&&a--;;){var e=this.lines[d+c];while(a<this.cols)if(e[a][1]<=' ')a++;else break;while(a<this.cols){if(e[a][1]<=' '&&a-1>=0&&e[a-1][1]>' '){a--;break}a++}if(a>=this.cols&&(a=this.cols-1),a===this.cols-1&&e[a][1]<=' '){if(a=0,++c>=this.rows&&(c--,++d>this.ybase)){d=this.ybase;break}continue}break}this.x=a,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='^'||b==='0'){var f=this.x;if(b==='0')this.x=0;else if(b==='^'){var e=this.lines[this.ydisp+this.y],a=0;while(a<this.cols){if(e[a][1]>' ')break;a++}a>=this.cols&&(a=this.cols-1),this.x=a}this.visualMode?this.selectText(f,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='$'){var f=this.x,e=this.lines[this.ydisp+this.y],a=this.cols-1;while(a>=0){if(e[a][1]>' '){this.visualMode&&a<this.cols-1&&a++;break}a--}a<0&&(a=0),this.x=a,this.visualMode?this.selectText(f,this.x,this.ydisp+this.y,this.ydisp+this.y):this.refresh(this.y,this.y);return}if(b==='g'||b==='G'){var f=this.x,g=this.y,h=this.ydisp;b==='g'?(this.x=0,this.y=0,this.scrollDisp(-this.ydisp)):b==='G'&&(this.x=0,this.y=this.rows-1,this.scrollDisp(this.ybase)),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='H'||b==='M'||b==='L'){var f=this.x,g=this.y;b==='H'?(this.x=0,this.y=0):b==='M'?(this.x=0,this.y=this.rows/2|0):b==='L'&&(this.x=0,this.y=this.rows-1),this.visualMode?this.selectText(f,this.x,this.ydisp+g,this.ydisp+this.y):(this.refresh(g,g),this.refresh(this.y,this.y));return}if(b==='{'||b==='}'){var f=this.x,g=this.y,h=this.ydisp,e,m=!1,k=!1,j=-1,c=this.y+(b==='{'?-1:1),d=this.ydisp,l;for(b==='{'?c<0&&(c++,d>0&&d--):b==='}'&&c>=this.rows&&(c--,d<this.ybase&&d++);;){for(e=this.lines[d+c],l=0;l<this.cols;l++)if(e[l][1]>' '){j===-1&&(j=0),m=!0;break}else if(l===this.cols-1){j===-1?j=1:j===0?k=!0:j===1&&m&&(k=!0);break}if(k)break;if(b==='{'){if(c--,c<0){if(c++,!(d>0))break;d--}}else if(b==='}'&&(c++,c>=this.rows)){if(c--,!(d<this.ybase))break;d++}}k||(b==='{'?(c=0,d=0):b==='}'&&(c=this.rows-1,d=this.ybase)),this.x=0,this.y=c,this.scrollDisp(-this.ydisp+d),this.visualMode&&this.selectText(f,this.x,g+h,this.ydisp+this.y);return}if(b==='/'||b==='?'){this.visualMode||this.enterSearch(b==='/');return}return!1},b.prototype.keySearch=function(o,c){if(c===''){this.leaveSearch();return}if(c==='\r'||!this.searchMode&&(c==='n'||c==='N')){this.leaveSearch();var f=this.entry;if(!f){this.refresh(0,this.rows-1);return}var m=this.x,l=this.y,k=this.ydisp,j,h=!1,i=!1,d=this.x+1,b=this.ydisp+this.y,g,a,n=c==='N'?this.searchDown:!this.searchDown;for(;;){j=this.lines[b];while(d<this.cols){for(a=0;a<f.length;a++){if(d+a>=this.cols)break;if(j[d+a][1]!==f[a])break;if(j[d+a][1]===f[a]&&a===f.length-1){h=!0;break}}if(h)break;d+=a+1}if(h)break;if(d=0,!n){if(b++,b>this.ybase+this.rows-1){if(i)break;i=!0,b=0}}else if(b--,b<0){if(i)break;i=!0,b=this.ybase+this.rows-1}}if(h){b-this.ybase<0?(g=b,b=0,g>this.ybase&&(b=g-this.ybase,g=this.ybase)):(g=this.ybase,b-=this.ybase),this.x=d,this.y=b,this.scrollDisp(-this.ydisp+g),this.visualMode&&this.selectText(m,this.x,l+k,this.ydisp+this.y);return}this.refresh(0,this.rows-1);return}if(c===''||c===''){if(this.entry.length===0)return;var e=this.ydisp+this.rows-1;this.entry=this.entry.slice(0,-1);var a=this.entryPrefix.length+this.entry.length;this.lines[e][a]=[this.lines[e][a][0],' '],this.x--,this.refresh(this.rows-1,this.rows-1),this.refresh(this.y,this.y);return}if(c.length===1&&c>=' '&&c<='~'){var e=this.ydisp+this.rows-1;this.entry+=c;var a=this.entryPrefix.length+this.entry.length-1;this.lines[e][a]=[this.defAttr&-512|4,c],this.x++,this.refresh(this.rows-1,this.rows-1),this.refresh(this.y,this.y);return}return!1},b.charsets={},b.charsets.SCLD={'`':'â—†',a:'â–’',b:'	',c:'',d:'\r',e:'\n',f:'°',g:'±',h:'␤',i:'',j:'┘',k:'┐',l:'┌',m:'â””',n:'┼',o:'⎺',p:'⎻',q:'─',r:'⎼',s:'⎽',t:'├',u:'┤',v:'â”´',w:'┬',x:'│',y:'≤',z:'≥','{':'Ï€','|':'≠','}':'£','~':'·'},b.charsets.UK=null,b.charsets.US=null,b.charsets.Dutch=null,b.charsets.Finnish=null,b.charsets.French=null,b.charsets.FrenchCanadian=null,b.charsets.German=null,b.charsets.Italian=null,b.charsets.NorwegianDanish=null,b.charsets.Spanish=null,b.charsets.Swedish=null,b.charsets.Swiss=null,b.charsets.ISOLatin=null;var g=this.String,i=this.setTimeout,s=this.setInterval;h._cache={},h.distance=function(a,b,c,d,e,f){return Math.pow(30*(a-d),2)+Math.pow(59*(b-e),2)+Math.pow(11*(c-f),2)},b.EventEmitter=f,b.inherits=u,b.on=e,b.off=q,b.cancel=d,a!==void 0?a.exports=b:this.Terminal=b}.call(function(){return this||(typeof window!=='undefined'?window:b)}()))},{}]},{},[1])
     2.5 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/DESIGN_NOTES__14_Jn_22.txt	Sun Jul 06 12:02:12 2014 -0700
     3.3 @@ -0,0 +1,117 @@
     3.4 +
     3.5 +Working on getting visual of a POP syntax graph
     3.6 +
     3.7 +-] Have Famo.us, which has hierarchical drawning structure that fits well to what had in mind for POP
     3.8 +
     3.9 +-] Famo.us has animations and physics engine, so as user modifies things, they can fly around in pleasing ways.
    3.10 +
    3.11 +-] Famo.us structure is almost one-to-one with the visualizer's internal structure that I was imagining..  seems wasteful to duplicate..
    3.12 +
    3.13 +-] However..  need the visualization to be independent of any particular drawing facility..  for example, the visualization should be reusable with a Java based canvas that is painted via Swing, as well as via Famo.us and via C++ drawing code..
    3.14 +
    3.15 +-] The visualization must be specific to the data format..  therefore, it should be part of the holder that the data is inside of.  Don't want case where new syntax is added, and have to go around to all the different places, like Java app, and javascript displayer, and so on, and change code in all those! (even if they all take a plugin, that plugin will have to be in terms of the language -- java, javascript, C++, whatever -- and the plugin will have to spit out some standard thing anyway!)  
    3.16 +Rather, want the visualizer to be written once, in POP, and plugged into the data-holder.  It spits out standardized visual elements..  any technology can then take those visual elements and paint them to a screen.
    3.17 +The visualizer has fingers directly on the raw data, in whatever the internal format is for the holder..  A holder can have a different internal format vs external format..
    3.18 +
    3.19 +(update: fighting with text -- haven't found any general way of calculating the width of text, given the font..  entry after entry from google search has variations on applying the text to a canvas, causing it to render, then getting the bounding box that was generated during render..  there doesn't seem to be, even for SVG, any way to predict the bounding box!!!?!?!?!  So.. there is a cascade effect..  the text must be contained within something, like a rectangle or elipse or whatever..  and, as worked out during the rest of this design session, the visualizer is responsible for calculating the placement of all the SVG shapes..  then the visualizer MUST know the size of the text, in order to know the size of the shape, in order to calculate a reasonable placement of shapes..  
    3.20 +   it is tempting to leave all the shape placements specified as relative, and let the final values be figured out inside the Display..  this would also allow things like employing the Famous physics engine to calculate placements, even let the placements evolve by themselves (like the D3 examples with the graph nodes flying around to find their own placement).. that would happen without the visualizer setting the placements..  rather, the visualizer would establish the visual "connectivity".. noooo..  that D3 thing relied upon knowing that it was a graph and that arcs acted like springs and nodes acted like weights, and nodes exerted n-body attraction..  but that is all specific to graphs..  would it generalize to arbitrary syntax?  Hmmmm..  if had an "atomic" level, where inside an atomic unit nothing moves relative,  then, yes, can treat the connections between these atomic things as springs, and each atomic thing has attractive mass and inertia..  can let them run around and find a stable configuration..
    3.21 +   Okay, so two issues: what about connections that go off-screen to out-side-the-view portions of syntax graph, and what about the user wanting to pin particular things in particular places..  often what a feeling of solidity, reliable placement so you know where everything is..
    3.22 +   Right, so this: for now, visualizer calculates fixed positions, but have in back of mind keeping ability for multiple kinds of visualizer within the same srcHolder..  and visualizer has ability to expect things of the Display, such as providing physics, and visualizer can maybe ask Display what kinds of visualization list it understands..  so then can add, say, dynamic view hierarchy, where visualizer specifies things like masses and springs and lets Display move them around as it sees fit..  can evolve standard view lists over time..  the Commander will have to include some facility for not allowing a user to select a visualizer that is unable to generate any of the list types acceptable to the Display the user is interacting with.)
    3.23 +
    3.24 +-] A holder may also have other data-format-and-semantics specific things, such as a querier -- the querier defines the format of queries it accepts, and those queries are tailored to the nature of the data in the holder.  Hence, say, a video holder might have a querier plugged in that accepts canonical shapes, and then searches the raw video data for frames that contain that shape.  The querier would spit out things in a format that it defines.  For example, it may have a data structure for a video frame, and spit out a stream of frames that contain the requested shape.
    3.25 +
    3.26 +-] Data formats should be visually defined.. for example, I should be able to draw a picture of a graph node, and that picture is the code that defines the data structure, which can then be used in other places in the code.  For example, in the Hamiltonian Path code, could have included a picture of a graph node, and connected a line to the portion being accessed, say, in a test, or in the "for all" construct..
    3.27 +
    3.28 +-] Seeing a hierarchy of holders..  so a higher level holder could have multiple lower level holders inside of it..  getting a bit awkward, say with combining queriers and visualizers -- how do you combine visualizations from siblings?  there's something fundamental here.. 
    3.29 +
    3.30 +-] No data may be warehoused outside a holder..  the holder collects the things needed to interact with the data, such as modifier, visualizer, querier, and not sure yet what all else..
    3.31 +
    3.32 +-] Data outside a holder must be in the form of a data structure instance, where the structure was defined by the holder the data came from.  The holder took whatever internal format the data resided in and placed it into the data structure form.  All data within a POP system that is not inside a holder must be in the format of a structure defined using POP primitives.  NO RAW BYTES!  Bit twidling only upon bit-vector structures.  An adaptor is necessary in order to get a more primitive format of data (IE, can always do conditional tests on bits held in a bit-vector format, and build up values within a higher level format structure based on the test results.. example, do the math to accumulate individual bit values from a bit-vector, but accumulate them into an integer format.  Or, can test bits that represent graph edges, and build up a graph data structure.  aso..)
    3.33 +
    3.34 +-] A visualizer can include animations as visual elements that it spits out.
    3.35 +
    3.36 +-] Famous will generate events that are gestures such as mouse clicks.  The event handler will use the event data to connect the event to one of the original visual elements that was visualized.  It will construct a structure that states the visual element and the gesture details, and send that to the commander.
    3.37 +
    3.38 +-] the commander will convert the visual element plus gesture into some action, such as moving the insertion point, or zooming the view, or adding a syntax node..  the command sends the command to the appropriate place -- could be the drawing engine (for zoom or pan actions).. or could be the modifier for insertion point or syntax element actions..  or could be some entity that carries out the action. For example when viewing a worksheet, a gesture could trigger re-calculation, so the action would be a "perform calculation" sent to one or more processors that are connected to the worksheet.
    3.39 +
    3.40 +-] The modifier has access to the holder's internal data format, and can manipulate it directly.  It receives commands, such as generated by gestures performed on the display.  
    3.41 +
    3.42 +-] A worksheet lives inside a holder as well..  the worksheet can talk to processors..  for example, the visualizer may simply include a reference to a processor that spits out data, and sends the reference in the visual element.  An image may be a good example..  the image is on the worksheet for some reason..  the visualizer embeds reference to image in an element and sends that to the display.  The display then directly gets the image data and paints it.
    3.43 +
    3.44 +-] Right, so one way to combine visualizers in a hierarchy, is for higher level visualizers to specify a lower-level one that is to fill in the internals of a given bounding box.  So the lower-level is sent the bounding box, and it generates a view hierarchy that fits inside of that.  Not sure whether the Display should be the one that sends the requests and integrates the various responses, or the Visualizer should send the requests and integrate the responses.
    3.45 +
    3.46 +==============================================
    3.47 +=
    3.48 +=
    3.49 +==============================================
    3.50 +So, question..  what do display list elements look like?  Does visualizer produce the layout, for example, specify a bounding box and position for each element, including text, lines, etc?  Does it produce the bezier curves in SVG that connect syntax graph elements?
    3.51 +
    3.52 +Or, does it send something with fewer details?  Let the Display calculate exact placement of visual elements?
    3.53 +
    3.54 +What about pan and zoom?  Does Visualizer handle that, or Display..  pan means moving some elements out of the painted canvas and moving others in..  zoom does too, in addition to calculating new transforms for each element painted..  So, if Display does this, then it must either have all the visual elements in it, or else it much send a request to Visualizer that triggers sending what's needed..
    3.55 +
    3.56 +Soooo..  make a two-way path between Display and Visualizer, in order to handle pan, zoom, 3D rotates, and so forth?
    3.57 +
    3.58 +Orrrr..  leave that to the MVDM loop..  the pan/zoom/rotate gestures go into the command-maker, and thence into the visualizer, which then sends view update..
    3.59 +
    3.60 +sooo..  this view update stuff..  does Display keep a full representation of the visual elements, and then translate that into Famo.us elements?  Or, does it keep, say, a current visualizer list..  where visualizer updates simply modify the previous list sent..  then Display translates the updated list into Famo.us elements..  given that Famo.us doesn't support removing render tree elements, that might be a good approach..  and it simplifies the thing about how to figure out what a visualizer update is and what to do with it inside the Display.
    3.61 +
    3.62 +Okay.. now..  just need to figure out what the Visualizer actually sends..  how much detail..
    3.63 +
    3.64 +You know what?  I don't want to think about it!  Just going to do something, see what happens, and then can modify later..  probably will never get modified, these choices have a way of sticking, due to momentum of volume of work and low improvement in changing..  but, don't want to stall myself, need to keep moving..
    3.65 +
    3.66 +sooooo...  something has to calculate placement of bounding boxes, and calculate translations and sizing..  and move things in and out based on zoom, pan, rotate..  and trigger redraws and resends of display data for graphs and calculation results..  seems like if put placement and transform calcs inside Display then are making the Display an active thing, giving it intelligence and control..  then, run into problems when have a view that is composed of pieces from many different holders and different processors..  for example, displaying a worksheet, where the worksheet itself is in a holder that generates a view, and locations on the worksheet are calculated by live processors, and locations are graphs which are generated by graphing processors that take calculations from other processors..  want the worksheet holder to handle generating the view, and collecting the data from the other processors..  don't want the Display to have any kind of intelligence related to this!  
    3.67 +
    3.68 +Hmmm..  so, if the worksheet holder is doing all of the collecting of data and triggering re-calcs, and melding together into a view..  then Display is simply passively painting that and collecting gestures that it sends back..  the holder then knows what to do with the gestures performed upon view elements..  
    3.69 +
    3.70 +So that means that the Display should not be calculating pan and zoom and rotate!!  Those are responses to gestures, and those trigger behaviors from the visualizer (which may, in turn, have to trigger behaviors from other processors in order to get updated calcs to put into the view)
    3.71 +
    3.72 +Got it, so as tempting as it is to peel off such gestures in the Display and build intelligence into there..  it will cause problems..  so best to have all the visual related processing be done inside the visualizers..  
    3.73 +
    3.74 +so..  means the visualizer should send out things pretty close to renderable..
    3.75 +
    3.76 +Now.  The question comes up..  what format?  Does the visualizer send out SVG?  Is that universal enough?  Will that cause problems with non-browser based approaches?  If not SVG, then what?  Will need to represent paths..  does visualizer calculate Bezier curves and send those?  Or does it just say "here are end points, connect these with a smooth path"?  Does the visualizer calculate how to route arcs within a graph around the other nodes in an optimal way?  If the user supplies helpers by moving things, does the Display remember that, or the Visualizer?  
    3.77 +
    3.78 +Ahhhh..  okay..  if what the user to be able to affect the visual arrangement, then need to remember the gestures they give that are related to visual arrangement..  for example, they grab bezier control points and move them, in order to affect a curve, or add new points within a path in order to route it..  those things have to be remembered!  The Display has no place to store such things!!
    3.79 +
    3.80 +Right..  that means that the holder must store info related to viewing the holder contents!  sooooo..  the visualizer must be the thing that generates any details that a person may want to adjust.
    3.81 +
    3.82 +Right.  Any visual arrangement that a person might want to adjust must be stored inside the holder, and so the visualizer must be the thing that generates that level of detail.  Right.  Got it.
    3.83 +
    3.84 +So.  Yes.  That means that the visualizer must send out bounding boxes, translations, sizing, path points, control points, and so forth.  So.  Yes.  SVG is looking like a good way to go..  has to be something!  Can invent my own equivalent, which specifies paths, shapes, widths, and so forth..  but what is the gain?  The only potential is sending in binary, to save the overhead of SVG's text embodiment.  The savings worth the effort?  NO!
    3.85 +
    3.86 +Okay then.  SVG.  That is the visualizer's format for POP.  Or perhaps it just sends the values that go into the SVG?  The Display does the final conversion to text-based SVG format?  Hmmmm, what about custom syntax, which is SVG from the programmer?  Just send indication of SVG elements, together with the values?  Maybe enums for the SVG indicators, or something..
    3.87 +
    3.88 +Now.  Question is, how much effort?  Is it more effort to send a representation, then construct text-repr inside Display?  Or more effort to construct SVG text in visualizer and send it ready-made?
    3.89 +
    3.90 +Seems easier to just construct SVG text inside visualizer and send that.. 
    3.91 +
    3.92 +Heck, if send representation, then are already forcing SVG!  It doesn't constrain the Display if send the text form..  the display is just as free to convert the binary form to something else as it is to convert the text form to something else..  so if Display is not browser, and doesn't have SVG drawing primitives, it has to do the extra step of parsing SVG in order to extract the values from the text, and then generate whatever internal form it has, such as calculating paths or even pixels itself..  the extraction from text does not seem like a terribly large burden compared to the rest.
    3.93 +
    3.94 +Buuuut..  don't really care!  Going to generate text form inside visualizer, because, why not?  Then the Display only translates displayList elements into its internal thing that paints.  In the case of browser, Display translates display list into famo.us elements, placing the SVG verbatim onto famous surfaces, and makes the SVG bounding box the same as the famous surface size.
    3.95 +
    3.96 +In fact, display list is going to represent almost verbatim what a Famo.us render tree will look like!  It is a fairly universal declaration..  hierarchy of local visual contexts, with relationship among those contexts, including relative placement in 3D space and relative sizing from one to another.
    3.97 +
    3.98 +Alright, getting to it now..  display list will be a serialization of a hierarchy..  The top of the hierarchy is the view painted onto.  The Display tells the visualizer what the pixel dimensions are of the view.  The visualizer makes that the top level bounding box.  It then inserts bounding boxes within that, and inserts bounding boxes within those, and so forth down.  Each bounding box is either a hierarchy element, relationship element, or a painted element.  Hierarchy elements simply state what elements are included, and give their own bounding box.  Relationship elements are attached by the parent hierarchy element.  For example, it is the job of the parent to make sure all the children fit inside its bounding box.  The bounding box may be 2D or 3D.  A parent ensures the fit by attaching relationships to the children elements.  The relationships can be translations or scalings or rotations.. or actually any arbitrary 3D transform.  A hierarchy element knows nothing of the context in which it fits, so it has no way of attaching relationships to itself!  Each hierarchy element is responsible for ensuring that all descendants fit within its bounding box.  Any relationship attached to a hierarchy element is transitively applied to all descendants of the hierarchy element.  For example, if one is rotated in 3D, then it, together with all its contents, is rotated as a unit.  Each descendant maintains the same relationship to its parent as before..  but the entire bundle has been rotated as a unit!
    3.99 +
   3.100 +Great..  so that is the display list..  it is a serialization of that hierarchy.  A display update then assumes a given hierarchy, and says "change this relationship between this parent and this child" or "remove this parent and all descendants" etc..  in effect, it specifies a change to the hierarchical structure..
   3.101 +
   3.102 +Sooooo..  means that have two copies of the view hierarchy..  one inside the visualizer, which is serialized, and another inside the Display, which is translated into Display-local elements that are then painted.
   3.103 +
   3.104 +Not the most efficient..  hurts me..  but, well, what are you going to do?  What's better?  Need the flexibility of having the visualizer control all changes to the view hierarchy.. and need the visualizer to calculate all placement and path details so that user changes can be remembered inside the holder (without something clunky like "save this view modification info as a black box and hand it to the Display, which knows what it means" yuck, just begging for loss of sync when move from one Display to another or even upgrade the Display!)..  
   3.105 +
   3.106 +so, then, there's no way around having the visualizer internally represent the bounding box hierarchy as it constructs the details.  Thennnnn..  something must translate that representation into the internal Display representation!  The Display could have any native form internally..  canvas with paths drawn upon it, Java 2D, even just pixels, with all the code in between..  well, in effect, every Display ends up being everything between that hierarchy and on down to pixels!!
   3.107 +
   3.108 +So, could just hand the data structure from visualizer to the Display..?  This is fine if both are inside same hardware, sharing memory..  but need a serialization if Display has separate memory..  which it will if the src holder is on a server and the display is a browser on a client!
   3.109 +
   3.110 +Hmmm..  what about just handing the data structure to the Display for now..  can always add the serialization later, it's not functional!  :-)  Ahhh, yes.. less work.  Good.  Okay, will do that.  save serialization for later.  For now, in javascript, will build a src holder that saves syntax graph natively in JSON, as an internal data structure of the form made for GabePatterns.  The visualizer in the src holder will generate a view hierarchy from that data structure.  It will save any view related data within the syntax graph data structure as extra properties added to the nodes.  The visualizer will then hand a reference to the view hierarchy directly to the display object.  The display object will then generate famous elements from the view hierarcy elements.  View updates will simply be the visualizer changing the view hierarchy then calling the display with a reference to the changed hierarchy.
   3.111 +
   3.112 +Done.  Make it so.
   3.113 +
   3.114 +BTW, thinking to introduce another component, which is a helper, that maybe takes some higher level view form and generates the view hierarchy from that..  this will ease the burden on developers who make custom syntax.. it will act as a library for them, essentially..  (and, of course, there will be a serializer that turns a view hierarchy into a stream of visual objects sent to the Display, which will reconstruct the view hierarchy then translate that into into elements that it paints.. for now, that serializer is just JSON!  It has provision to translate javascript objects into text form, and then on the other side parse that text form to reproduce the javascript objects.. might need extra logic in order to recreate the links among parents and children.. not sure whether JSON can go deep that way..).
   3.115 +
   3.116 +
   3.117 + 
   3.118 +
   3.119 +
   3.120 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.html	Sun Jul 06 12:02:12 2014 -0700
     4.3 @@ -0,0 +1,35 @@
     4.4 +<!DOCTYPE html>
     4.5 +<html>
     4.6 +    <head>
     4.7 +        <title>POP Display</title>
     4.8 +        <script data-main="startUpApp" src="lib/require.js"></script>
     4.9 +
    4.10 +		<script src="lib/jquery.min.js"></script>
    4.11 +		
    4.12 +        <!--  -->
    4.13 +		<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
    4.14 +        <meta name="mobile-web-app-capable" content="yes" />
    4.15 +        <meta name="apple-mobile-web-app-capable" content="yes" />
    4.16 +        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    4.17 +
    4.18 +        <!-- shims for backwards compatibility -->
    4.19 +        <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script>
    4.20 +        <script type="text/javascript" src="../lib/classList.js"></script>
    4.21 +        <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script>
    4.22 +
    4.23 +        <!-- module loader -->
    4.24 +        <script type="text/javascript" src="../lib/require.js"></script>
    4.25 +
    4.26 +        <!-- famous -->
    4.27 +        <link rel="stylesheet" type="text/css" href="../lib/famous.css" />
    4.28 +        <script type="text/javascript" src="../lib/famous.js"></script>
    4.29 +		
    4.30 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. -->
    4.31 +        <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" />
    4.32 +
    4.33 +    </head>
    4.34 +
    4.35 +<body>
    4.36 +
    4.37 +</body>
    4.38 +</html>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/POPDisplay.js	Sun Jul 06 12:02:12 2014 -0700
     5.3 @@ -0,0 +1,78 @@
     5.4 +
     5.5 +
     5.6 +//Make a Display object, and a number of functions that operate on it.
     5.7 +// One of the functions accepts an array of visual element objects as
     5.8 +// input, and turns those visual elements into a famous render tree.
     5.9 +//The famous context, and the surfaces, and so on exist inside the Display
    5.10 +// object.
    5.11 +
    5.12 +//This uses require.js to create a module.  This module has the name of the
    5.13 +// file (POPDisplay).  Inside the define, a number of data structures and 
    5.14 +// functions are created, then returned at the end.  The returned things are
    5.15 +// what can be accessed by external functions that load this module, via
    5.16 +// themselves using the require("POPDisplay") call
    5.17 +define(function(require, exports, module) {
    5.18 +    //Create the famous infrastructure, which is used for rendering on screen
    5.19 +    var Engine           = require("famous/core/Engine");
    5.20 +    var Surface          = require("famous/core/Surface");
    5.21 +    var Modifier         = require("famous/core/Modifier");
    5.22 +    var Transform        = require('famous/core/Transform');
    5.23 +    var StateModifier    = require('famous/modifiers/StateModifier');
    5.24 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
    5.25 +
    5.26 +	//make the context, which controls rendering to the screen
    5.27 +	// once add something to this context, that add makes the thing visibly
    5.28 +	// have effect.
    5.29 +	//Note, these are available to the render function via the closure
    5.30 +	// mechanism
    5.31 +    var mainContext = Engine.createContext();
    5.32 +
    5.33 +	//the functions that access the Display object will be returned below
    5.34 +	var Display = {
    5.35 +		acceptViewList : function( inViewList ) {
    5.36 +			//modify the render tree of the mainContext according to the
    5.37 +			// in coming view list
    5.38 +		}
    5.39 +		
    5.40 +		handleGesture : function( event ) {
    5.41 +			//not sure this is the right form, but provide a handler for
    5.42 +			// gestures made by the programmer/user
    5.43 +			//This will make an object that pairs the gesture to the view
    5.44 +			// element that is represented by the surface(s) involved in
    5.45 +			// the gesture.
    5.46 +			//It will then send the object to the command generator, which 
    5.47 +			// is part of the source holder
    5.48 +		}
    5.49 +	}
    5.50 +	function acceptViewList (viewList) {
    5.51 +		//access Display object and its values here, as a closure
    5.52 +	}
    5.53 +	
    5.54 +	function init() {
    5.55 +		//	var POPStuffToDraw = 
    5.56 +		var mySurface = new Surface({
    5.57 +		  size: [100, 100],
    5.58 +		  content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
    5.59 +		  properties: {
    5.60 +			color: 'white',
    5.61 +			lineHeight: '200%',
    5.62 +			textAlign: 'center',
    5.63 +			fontSize: '36px',
    5.64 +			cursor: 'pointer'
    5.65 +		  }
    5.66 +		});
    5.67 +		var stateModifier = new StateModifier({
    5.68 +			transform: Transform.translate(250, 100, 0)
    5.69 +		});
    5.70 +		mainContext.add(stateModifier).add(mySurface);
    5.71 +
    5.72 +
    5.73 +
    5.74 +	return{
    5.75 +		init: init,
    5.76 +		display: Display,
    5.77 +		acceptViewList: acceptViewList
    5.78 +	}
    5.79 +});
    5.80 +
    5.81 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/CalcCombosOfWord.js	Sun Jul 06 12:02:12 2014 -0700
     6.3 @@ -0,0 +1,112 @@
     6.4 +define(function () {
     6.5 +
     6.6 +var sortedLetters = [];
     6.7 +
     6.8 +var fact = [];
     6.9 +var total = 0;
    6.10 +var i = 0;
    6.11 +fact[0] = 0;
    6.12 +fact[1] = 1;
    6.13 +//fill up the array of factorial values
    6.14 +for( i = 2; i <= 25; i++) {
    6.15 +	fact[i] = i * fact[i-1]; 
    6.16 +}
    6.17 +
    6.18 +//Function to sort the letters in the input word.  Returns an array of
    6.19 +// objects.  Each object has a field for the letter, and a field for the
    6.20 +// number of times that letter appears in the input word.
    6.21 +var sortLettersOfWord = function( inputWord ) {
    6.22 +	var letterArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
    6.23 +	var currLetter = '';
    6.24 +
    6.25 +	for( i = 0; i < inputWord.length; i++ ) {
    6.26 +		currLetter = inputWord.charCodeAt(i);
    6.27 +//		console.log(currLetter);
    6.28 +		index = currLetter - 'a'.charCodeAt(0);
    6.29 +		console.log(index);
    6.30 +		letterArray[index] += 1;
    6.31 +	}
    6.32 +	console.log('sorted letter A: ' + letterArray[0]);
    6.33 +	return letterArray;
    6.34 +}
    6.35 +
    6.36 +//Calc the number of unique "words" producible from the sorted letters
    6.37 +var calcCombosOfLetters = function( sortedLetters, totalNumLetters ) {
    6.38 +	console.log( "num letters: " + totalNumLetters );
    6.39 +	numCombos = fact[ totalNumLetters ];
    6.40 +//	console.log("numCombos: " + numCombos);
    6.41 +	//now, divide that by factorial of the multiplicity of each letter.
    6.42 +	// skip letters that only appear once (or zero).
    6.43 +	for( i=0; i<26; i++) { //be sure sortedLetters shrinks
    6.44 +		//when remove a letter object from it, so .size reflects that!
    6.45 +		if( sortedLetters[i] > 1 ) {
    6.46 +			//divide the number of combos by the factorial of, the number of
    6.47 +			// times the letter is repeated within the input word.
    6.48 +			numCombos /= fact[ sortedLetters[i] ];
    6.49 +		}
    6.50 +	}
    6.51 +	console.log("numCombos: " + numCombos);
    6.52 +	return numCombos;
    6.53 +} 
    6.54 +
    6.55 +//Find number of rearrangements of the word's letters that come
    6.56 +// alphabetically before the word. 
    6.57 +var rankThisWord = function(inputWordRaw) {
    6.58 +	var inputWord = inputWordRaw.toLowerCase();
    6.59 +	
    6.60 +        console.log('started rank this word: ' + inputWord);
    6.61 +	var totalCombosComeBefore = 0;
    6.62 +	var numCombos = 0;
    6.63 +	var currPosInInputWord = 0;
    6.64 +	var numLettersInInputWord = inputWord.length;
    6.65 +	console.log("num letters: " + numLettersInInputWord);
    6.66 +	var numInputWordLettersLeft = inputWord.length;
    6.67 +	var sortedLetters = sortLettersOfWord( inputWord ); //returns array of
    6.68 +	//objs. Each obj pairs a letter with the multiplicity of that letter
    6.69 +	//the order of the objs matches the alphabetical order of the obj letters
    6.70 +	var firstLetter = 0;
    6.71 +	
    6.72 +	//repeat, marching down the letters of the input word
    6.73 +	while(currPosInInputWord < numLettersInInputWord) {
    6.74 +		//calc index (pos in alphabet) of current first letter in word)
    6.75 +		firstLetter = inputWord.charCodeAt(currPosInInputWord) - 'a'.charCodeAt(0);
    6.76 +		console.log("first letter:" + firstLetter + " at pos: " + currPosInInputWord);
    6.77 +		//Iterate over the letters that come before first
    6.78 +		for( currLetter=0; currLetter<26; currLetter++ ) {
    6.79 +			//if completed all earlier letters then terminate loop
    6.80 +//Q: count duplicates of first letter?
    6.81 +			if( currLetter >= firstLetter ) break;
    6.82 +			else if( sortedLetters[currLetter] > 0) {
    6.83 +				console.log("earlier letter: " + currLetter);
    6.84 +				//for a given earlier letter, remove it from
    6.85 +				// the letter pool, leaving duplicates.
    6.86 +				sortedLetters[currLetter] -= 1; 
    6.87 +				
    6.88 +				//Calculate the number of unique rearrangements of the
    6.89 +				// remaining letters, using the formula.
    6.90 +				numCombos = calcCombosOfLetters( sortedLetters, numInputWordLettersLeft - 1 ); 
    6.91 +				
    6.92 +				//accumulate the total number of combos:
    6.93 +				totalCombosComeBefore += numCombos;
    6.94 +				
    6.95 +				//add the letter back! Need it while do other earlier letters
    6.96 +				sortedLetters[currLetter] += 1;
    6.97 +			}
    6.98 +		}
    6.99 +		
   6.100 +		//Now, done with first letter of input word.  Delete that letter from
   6.101 +		// the input word, and from the sorted pool of letters, leaving
   6.102 +		// duplicates.
   6.103 +		numInputWordLettersLeft -= 1;
   6.104 +		currPosInInputWord += 1;
   6.105 +		sortedLetters[firstLetter] -= 1;
   6.106 +	}
   6.107 +	console.log("total combos come before: " + totalCombosComeBefore);
   6.108 +	return totalCombosComeBefore;
   6.109 +}
   6.110 +
   6.111 +	
   6.112 +    return {
   6.113 +        rankThisWord: rankThisWord
   6.114 +    };
   6.115 +});
   6.116 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/POPDisplay.js	Sun Jul 06 12:02:12 2014 -0700
     7.3 @@ -0,0 +1,74 @@
     7.4 +
     7.5 +
     7.6 +//Make a Display object, and a number of functions that operate on it.
     7.7 +// One of the functions accepts an array of visual element objects as
     7.8 +// input, and turns those visual elements into a famous render tree.
     7.9 +//The famous context, and the surfaces, and so on exist inside the Display
    7.10 +// object.
    7.11 +
    7.12 +//This uses require.js to create a module.  This module has the name of the
    7.13 +// file (POPDisplay).  Inside the define, a number of data structures and 
    7.14 +// functions are created, then returned at the end.  The returned things are
    7.15 +// what can be accessed by external functions that load this module, via
    7.16 +// themselves using the require("POPDisplay") call
    7.17 +define(function(require, exports, module) {
    7.18 +    //Create the famous infrastructure, which is used for rendering on screen
    7.19 +    var Engine           = require("famous/core/Engine");
    7.20 +    var Surface          = require("famous/core/Surface");
    7.21 +    var Modifier         = require("famous/core/Modifier");
    7.22 +    var Transform        = require('famous/core/Transform');
    7.23 +    var StateModifier    = require('famous/modifiers/StateModifier');
    7.24 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
    7.25 +
    7.26 +	//make the context, which controls rendering to the screen
    7.27 +	// once add something to this context, that add makes the thing visibly
    7.28 +	// have effect.
    7.29 +	//Note, these are available to the render function via the closure
    7.30 +	// mechanism
    7.31 +    var mainContext = Engine.createContext();
    7.32 +
    7.33 +	
    7.34 +	var handleGesture = function( event ) {
    7.35 +			//not sure this is the right form, but provide a handler for
    7.36 +			// gestures made by the programmer/user
    7.37 +			//This will make an object that pairs the gesture to the view
    7.38 +			// element that is represented by the surface(s) involved in
    7.39 +			// the gesture.
    7.40 +			//It will then send the object to the command generator, which 
    7.41 +			// is part of the source holder
    7.42 +		console.log("handleGesture");
    7.43 +	}
    7.44 +	function acceptViewList (viewList) {
    7.45 +		//access Display object and its values here, as a closure
    7.46 +		console.log("acceptViewList");
    7.47 +	}
    7.48 +	
    7.49 +	function init() {
    7.50 +		console.log("init");
    7.51 +		//	var POPStuffToDraw = 
    7.52 +		var mySurface = new Surface({
    7.53 +		  size: [100, 100],
    7.54 +		  content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
    7.55 +		  properties: {
    7.56 +			color: 'white',
    7.57 +			lineHeight: '200%',
    7.58 +			textAlign: 'center',
    7.59 +			fontSize: '36px',
    7.60 +			cursor: 'pointer'
    7.61 +		  }
    7.62 +		});
    7.63 +		var stateModifier = new StateModifier({
    7.64 +			transform: Transform.translate(250, 100, 0)
    7.65 +		});
    7.66 +		mainContext.add(stateModifier).add(mySurface);
    7.67 +	}
    7.68 +
    7.69 +
    7.70 +	return{
    7.71 +		init: init,
    7.72 +		handleGesture: handleGesture,
    7.73 +		acceptViewList: acceptViewList
    7.74 +	};
    7.75 +});
    7.76 +
    7.77 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/epocratesPuzzle.js	Sun Jul 06 12:02:12 2014 -0700
     8.3 @@ -0,0 +1,57 @@
     8.4 +define(function (require) {
     8.5 +
     8.6 +//load the code that calculates the rank
     8.7 +var calcNumCombos = require('./CalcCombosOfWord');
     8.8 +
     8.9 +//Show title and explanation -- via DOM manipulation
    8.10 +var el =  document.createElement("h1")
    8.11 +el.id="title";
    8.12 +el.innerHTML = "Epocrates Puzzle Test";
    8.13 +document.body.appendChild(el);
    8.14 +
    8.15 +
    8.16 +el =  document.createElement("span")
    8.17 +el.style.display="block";
    8.18 +el.style.width="100%";
    8.19 +el.innerHTML = 'This program calculates the "rank" of a word.  The rank equals the number of combinations of its letters, that happen to come before it alphabetically (plus 1 for itself)';
    8.20 +document.body.appendChild(el);
    8.21 +
    8.22 +//Get the word to calc combinations of
    8.23 +//var inputword = prompt('Here you go, your chance to enter the word that you would like ranked!');
    8.24 +el1 =  document.createElement("span")
    8.25 +el1.style.display="block";
    8.26 +el1.style.width="100%";
    8.27 +el1.innerHTML ='<br><br>Here you go, your chance to enter the word that you would like ranked!';
    8.28 +document.body.appendChild(el1);
    8.29 +
    8.30 +el = document.createElement("INPUT");
    8.31 +el.setAttribute("id", "inputWord");
    8.32 +el.setAttribute("type", "text");
    8.33 +//el.setAttribute("value", "type word here, click button when done");
    8.34 +el.style.display="block";
    8.35 +el.style.width="50%";
    8.36 +document.body.appendChild(el);
    8.37 +
    8.38 +var inputWord = "";
    8.39 +//Now use jquery to create a button, display it, and set click event handler
    8.40 +$('<button/>', {
    8.41 +	text: "Calc rank on this word!",
    8.42 +	id: 'inputIsReadyBtn',
    8.43 +	click: function () { inputWord = $("#inputWord").val(); 
    8.44 +		var numEarlierWords = calcNumCombos.rankThisWord(inputWord);
    8.45 +		showResult( numEarlierWords );		
    8.46 +	}
    8.47 +}).appendTo('body');
    8.48 +
    8.49 +
    8.50 +
    8.51 +//Output the result
    8.52 +var showResult = function( numEarlierWords ) {
    8.53 +	el =  document.createElement("span")
    8.54 +	el.style.display="block";
    8.55 +	el.style.width="100%";
    8.56 +	el.innerHTML = "The rank of: " + inputWord + " is: " + (numEarlierWords + 1);
    8.57 +	document.body.appendChild(el);
    8.58 +}
    8.59 +
    8.60 +});
    8.61 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/app/renderPOPSyntaxGraph.js	Sun Jul 06 12:02:12 2014 -0700
     9.3 @@ -0,0 +1,358 @@
     9.4 +
     9.5 +
     9.6 +define(function(require, exports, module) {
     9.7 +    var Engine           = require("famous/core/Engine");
     9.8 +    var Surface          = require("famous/core/Surface");
     9.9 +    var Modifier         = require("famous/core/Modifier");
    9.10 +    var Transform = require('famous/core/Transform');
    9.11 +    var StateModifier = require('famous/modifiers/StateModifier');
    9.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
    9.13 +	
    9.14 +	var POPDisplay = require('./POPDisplay');
    9.15 +	POPDisplay.acceptViewList("foo");
    9.16 +	POPDisplay.init();
    9.17 +	POPDisplay.handleGesture("foo");
    9.18 +	
    9.19 +    var mainContext = Engine.createContext();
    9.20 +	
    9.21 +	var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">';
    9.22 +	var boxSVG = [];
    9.23 +	boxSVG[1] = '<svg width="';
    9.24 +	boxSVG[2] = '" height="';
    9.25 +	boxSVG[3] = '"><rect x="';
    9.26 +	boxSVG[4] = '" y="';
    9.27 +	boxSVG[5] = '" rx="'
    9.28 +	boxSVG[6] = '" ry="';
    9.29 +	boxSVG[7] = '" width="'
    9.30 +	boxSVG[8] = '" height="'
    9.31 +	boxSVG[9] = '" style="fill:'
    9.32 +	boxSVG[10] = ';stroke:'
    9.33 +	boxSVG[11] = ';stroke-width:'
    9.34 +	boxSVG[12] = ';opacity:'
    9.35 +	boxSVG[13] = '">';
    9.36 +	
    9.37 +
    9.38 +//Draw a simple syntax graph, with a box of the correct color for each
    9.39 +// node, and curvy links with arrows going from text inside one node to
    9.40 +// text inside another node.
    9.41 +//Approach taken:
    9.42 +//Generate the SVG from calculations -- hold strings in an array, and
    9.43 +// build up an SVG string by adding string piece, then variable value then
    9.44 +// another string piece, and so on.
    9.45 +//Make each box a surface holding an SVG
    9.46 +//Sizing of the box happens inside the SVG string
    9.47 +//Positioning the box happens via a modifier
    9.48 +
    9.49 +//Make one container surface to hold each element node together with its
    9.50 +// properties and ports
    9.51 +//Make a separate surface for each SVG element -- one for each box, one for
    9.52 +// each text in a box, one for each curvy connector arrow between boxes or
    9.53 +// between texts.  
    9.54 +//For each surface, make a modifier that positions the box relative to the
    9.55 +// container surface's origin
    9.56 +//At the end, make transforms to move the entire container around
    9.57 +
    9.58 +	//elem1 is the root element from the Gabe Pattern syntax graph
    9.59 +	// here, make the visual elements that reproduce what see in the .pdf
    9.60 +    var elem1Container = new ContainerSurface({
    9.61 +        size: [600, 600], //size it big for now, trim to contents later
    9.62 +        properties: {
    9.63 +            overflow: 'hidden'
    9.64 +        }
    9.65 +    });
    9.66 +	
    9.67 +//==
    9.68 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
    9.69 +//  11:stroke-width 12:opacity
    9.70 +	var box1_1width = 66;
    9.71 +	var box1_1height = 86
    9.72 +//	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
    9.73 +	var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2;
    9.74 +	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
    9.75 +
    9.76 +//== elem1 box 1 --> box1_1
    9.77 +	var box1_1 = new Surface({
    9.78 +	  size: [true, true],
    9.79 +      content: boxSVGFromParts1_1
    9.80 +	});
    9.81 +	var box1_1x = 0;
    9.82 +	var box1_1y = 2;
    9.83 +	var boxMod1_1_1 = new StateModifier({
    9.84 +        transform: Transform.translate(box1_1x, box1_1y, 0)
    9.85 +    });
    9.86 +	
    9.87 +//== elem1 box 1 text 1 --> text1_1_1
    9.88 +	var text1_1_1 = new Surface({
    9.89 +	  size: [true, 11],
    9.90 +      content: "properties",
    9.91 +      properties: {
    9.92 +        color: 'black',
    9.93 +        textAlign: 'left',
    9.94 +        fontSize: '11px',
    9.95 +        cursor: 'hand'
    9.96 +      }
    9.97 +	});
    9.98 +	var text1_1_2 = new Surface({
    9.99 +	  size: [true, true],
   9.100 +      content: "portsIn",
   9.101 +      properties: {
   9.102 +        color: 'black',
   9.103 +        textAlign: 'left',
   9.104 +        fontSize: '11px',
   9.105 +        cursor: 'pointer'
   9.106 +      }
   9.107 +	});
   9.108 +	var text1_1_3 = new Surface({
   9.109 +	  size: [true, true],
   9.110 +      content: "portsOut",
   9.111 +      properties: {
   9.112 +        color: 'black',
   9.113 +        textAlign: 'left',
   9.114 +        fontSize: '11px',
   9.115 +        cursor: 'pointer'
   9.116 +      }
   9.117 +	});
   9.118 +	var text1_1_4 = new Surface({
   9.119 +	  size: [true, true],
   9.120 +      content: "subElems",
   9.121 +      properties: {
   9.122 +        color: 'black',
   9.123 +        textAlign: 'left',
   9.124 +        fontSize: '11px',
   9.125 +        cursor: 'pointer'
   9.126 +     }
   9.127 +	});
   9.128 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1
   9.129 +	var text1_1_1x = 8;
   9.130 +	var text1_1_1y = 8;
   9.131 +	var textMod1_1_1_1 = new StateModifier({
   9.132 +        transform: Transform.translate(text1_1_1x, text1_1_1y, 0)
   9.133 +    });
   9.134 +	var textMod1_1_2_1 = new StateModifier({
   9.135 +        transform: Transform.translate(8, 25, 0)
   9.136 +    });
   9.137 +	var textMod1_1_3_1 = new StateModifier({
   9.138 +        transform: Transform.translate(8, 42, 0)
   9.139 +    });
   9.140 +	var textMod1_1_4_1 = new StateModifier({
   9.141 +        transform: Transform.translate(8, 59, 0)
   9.142 +    });
   9.143 +//==
   9.144 +	elem1Container.add(boxMod1_1_1).add(box1_1);
   9.145 +	elem1Container.add(textMod1_1_1_1).add(text1_1_1);
   9.146 +	elem1Container.add(textMod1_1_2_1).add(text1_1_2);
   9.147 +	elem1Container.add(textMod1_1_3_1).add(text1_1_3);
   9.148 +	elem1Container.add(textMod1_1_4_1).add(text1_1_4);
   9.149 +
   9.150 +//== elem 1 box 2 --> box1_2
   9.151 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
   9.152 +//  11:stroke-width 12:opacity
   9.153 +	var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2;
   9.154 +	var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   9.155 +	var box1_2 = new Surface({
   9.156 +	  size: [true, true],
   9.157 +      content: boxSVGFromParts1_2
   9.158 + 	});
   9.159 +	var box1_2x = 100;
   9.160 +	var box1_2y = 2;
   9.161 +	var boxMod1_2_1 = new StateModifier({
   9.162 +        transform: Transform.translate(box1_2x, box1_2y, 0)
   9.163 +    });
   9.164 +//== elem 1 box 2 text 1 --> text1_2_1
   9.165 +	var text1_2_1 = new Surface({
   9.166 +	  size: [true, true],
   9.167 +      content: "propertyName:  TypeOfElement",
   9.168 +      properties: {
   9.169 +        color: 'black',
   9.170 +        textAlign: 'left',
   9.171 +        fontSize: '11px',
   9.172 +        cursor: 'pointer'
   9.173 +      }
   9.174 +	});
   9.175 +	var text1_2_2 = new Surface({
   9.176 +	  size: [true, true],
   9.177 +      content: "propertyValue:  GabeTransfromRule",
   9.178 +      properties: {
   9.179 +        color: 'black',
   9.180 +        textAlign: 'left',
   9.181 +        fontSize: '11px',
   9.182 +        cursor: 'pointer'
   9.183 +      }
   9.184 +	});
   9.185 +	var text1_2_3 = new Surface({
   9.186 +	  size: [true, true],
   9.187 +      content: "subProperties",
   9.188 +      properties: {
   9.189 +        color: 'black',
   9.190 +        textAlign: 'left',
   9.191 +        fontSize: '11px',
   9.192 +        cursor: 'pointer'
   9.193 +      }
   9.194 +	});
   9.195 +//==
   9.196 +	var textMod1_2_1_1 = new StateModifier({
   9.197 +        transform: Transform.translate(108, 8, 0)
   9.198 +    });
   9.199 +	var textMod1_2_2_1 = new StateModifier({
   9.200 +        transform: Transform.translate(108, 25, 0)
   9.201 +    });
   9.202 +	var textMod1_2_3_1 = new StateModifier({
   9.203 +        transform: Transform.translate(108, 42, 0)
   9.204 +    });
   9.205 +//==
   9.206 +	elem1Container.add(boxMod1_2_1).add(box1_2);
   9.207 +	elem1Container.add(textMod1_2_1_1).add(text1_2_1);
   9.208 +	elem1Container.add(textMod1_2_2_1).add(text1_2_2);
   9.209 +	elem1Container.add(textMod1_2_3_1).add(text1_2_3);
   9.210 +
   9.211 +//Now, add bezier curve, in SVG..
   9.212 +//One end point is the end of "properties" text surface inside the elem box
   9.213 +//Other end point is the middle of side of properties box
   9.214 +	
   9.215 +	var bezierSVG1 = '<svg width="106" height="106"> <path d="M3,3 C0,100 100,0 100,100" style="fill:none;stroke:black;stroke-width:4;opacity:1">';
   9.216 +
   9.217 +	var bezSVG = [];
   9.218 +	bezSVG[1] = '<svg width="'
   9.219 +	bezSVG[2] = '" height="'
   9.220 +	bezSVG[3] = '"><path d="M' //start pt x
   9.221 +	bezSVG[4] = ','  //start pt y
   9.222 +	bezSVG[5] = ' C' //control pt 1 x
   9.223 +	bezSVG[6] = ','  //control pt 1 y
   9.224 +	bezSVG[7] = ' '  //control pt 2 x
   9.225 +	bezSVG[8] = ','  //control pt 2 y
   9.226 +	bezSVG[9] = ' '  //end pt x
   9.227 +	bezSVG[10] = ',' //end pt y
   9.228 +	bezSVG[11] = '" style="fill:'
   9.229 +	bezSVG[12] = ';stroke:'
   9.230 +	bezSVG[13] = ';stroke-width:'
   9.231 +	bezSVG[14] = ';opacity:'
   9.232 +	bezSVG[15] = '">';
   9.233 +	
   9.234 +	//now calculate the end points of the curve -- they connect to the
   9.235 +	// right edge of the "properties" text in the left box, and to the
   9.236 +	// middle of the left side of the right box
   9.237 +	var bezPoints = [{},{}];
   9.238 +	var fontSz = 11;
   9.239 +	bezPoints[0].x = box1_1x + box1_1w;
   9.240 +	bezPoints[0].y = text1_1_1y + fontSz/2 + 8;
   9.241 +	bezPoints[1].x = box1_2x;
   9.242 +	bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2;
   9.243 +
   9.244 +	var controlPoints = [];
   9.245 +	controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y};
   9.246 +	controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y};
   9.247 +
   9.248 +
   9.249 +	//	1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x
   9.250 +	// 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity
   9.251 +	var bezSVG1 = "";
   9.252 +	bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6);
   9.253 +	bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6);
   9.254 +	bezSVG1 += bezSVG[3] + bezPoints[0].x; 
   9.255 +	bezSVG1 += bezSVG[4] + bezPoints[0].y; 
   9.256 +	bezSVG1 += bezSVG[5] + controlPoints[0].x;
   9.257 +	bezSVG1 += bezSVG[6] + controlPoints[0].y;
   9.258 +	bezSVG1 += bezSVG[7] + controlPoints[1].x;
   9.259 +	bezSVG1 += bezSVG[8] + controlPoints[1].y;
   9.260 +	bezSVG1 += bezSVG[9] + bezPoints[1].x; 
   9.261 +	bezSVG1 += bezSVG[10] + bezPoints[1].y; 
   9.262 +	bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15];
   9.263 +
   9.264 +var bezSVG2 = '<svg width="400" height="170"><path d="M66,13.5 C66,2.5 100,13.5 100,2.5" style="fill:none;stroke:black;stroke-width:2;opacity:1">';	
   9.265 +var x1 = 59; var x2 = 100; var y1 = 22; var y2 = 40;
   9.266 +var bezSVG3 = '<svg width="200" height="200"><path d="M59,21 C100,21 59,38 100,38" style="fill:none;stroke:black;stroke-width:2;opacity:1">';	
   9.267 +	var bez1_1 = new Surface({
   9.268 +	  size: [true, true],
   9.269 +      content: bezSVG1
   9.270 + 	});
   9.271 +
   9.272 +	elem1Container.add(bez1_1);
   9.273 +
   9.274 +var el1 =  document.createElement("span")
   9.275 +var displayStr = bezSVG1.replace(/</g, "&lt");//make the html display as text
   9.276 +el1.innerHTML = (displayStr + "<br>");
   9.277 +document.body.appendChild(el1);
   9.278 +el1 =  document.createElement("span")
   9.279 +displayStr = bezSVG3.replace(/</g, "&lt");//make the html display as text
   9.280 +el1.innerHTML = displayStr;
   9.281 +document.body.appendChild(el1);
   9.282 +
   9.283 +
   9.284 +//== elem 1 Modifer 1 --> contMod1_1
   9.285 +	var contMod1_1 = new StateModifier({
   9.286 +        transform: Transform.translate(50, 50, 0)
   9.287 +    });
   9.288 +	var contMod1_2 = new StateModifier({
   9.289 +		transform: Transform.scale(1, 1)
   9.290 +    });	
   9.291 +//==
   9.292 +
   9.293 +	mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container);
   9.294 +
   9.295 +	//elem2 is 
   9.296 +    var elem2Container = new ContainerSurface({
   9.297 +        size: [200, 200],
   9.298 +        properties: {
   9.299 +            overflow: 'hidden'
   9.300 +        }
   9.301 +    });
   9.302 +	
   9.303 +	
   9.304 +	
   9.305 +//== elem 2 box 1 --> box2_1
   9.306 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
   9.307 +//  11:stroke-width 12:opacity
   9.308 +	var boxSVGFromParts2_1 = boxSVG[1] + '68' + boxSVG[2] + '88' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '66' + boxSVG[8] + '86' + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   9.309 +	var box2_1 = new Surface({
   9.310 +	  size: [100, 100],
   9.311 +      content: boxSVGFromParts2_1,
   9.312 +	});
   9.313 +	var box2_3 = new Surface({
   9.314 +	  size: [100, 100],
   9.315 +      content: boxSVGFromParts2_1,
   9.316 +      properties: {
   9.317 +      }
   9.318 +	});
   9.319 +	var box2_4 = new Surface({
   9.320 +	  size: [100, 100],
   9.321 +      content: boxSVGFromParts2_1,
   9.322 +      properties: {
   9.323 +      }
   9.324 +	});
   9.325 +	
   9.326 +//==
   9.327 +	var boxMod2_1_1 = new StateModifier({
   9.328 +        transform: Transform.translate(7, 90, 0)
   9.329 +    });
   9.330 +	var boxMod2_1_2 = new StateModifier({
   9.331 +		transform: Transform.scale(.3, .3)
   9.332 +    });
   9.333 +//==
   9.334 +	var boxMod2_2_1 = new StateModifier({
   9.335 +        transform: Transform.translate(42, 90, 0)
   9.336 +    });
   9.337 +	var boxMod2_2_2 = new StateModifier({
   9.338 +		transform: Transform.scale(.3, .3)
   9.339 +    });
   9.340 +//==
   9.341 +	var boxMod2_3_1 = new StateModifier({
   9.342 +        transform: Transform.translate(42, 2, 0)
   9.343 +    });
   9.344 +	var boxMod2_3_2 = new StateModifier({
   9.345 +		transform: Transform.scale(.3, .3)
   9.346 +    });
   9.347 +//==
   9.348 +	var boxMod2_4_1 = new StateModifier({
   9.349 +        transform: Transform.translate(57, 20, 0)
   9.350 +    });
   9.351 +	var boxMod2_4_2 = new StateModifier({
   9.352 +		transform: Transform.scale(1.22, 1.22)
   9.353 +    });
   9.354 +//==	
   9.355 +	var equalMod = new StateModifier({
   9.356 +        transform: Transform.translate(27, 85, 0)
   9.357 +    });
   9.358 +	
   9.359 +
   9.360 +//	summationContainer.add(sigmaMod1).add(sigmaSurf);
   9.361 +});
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/displayLoadPage.html	Sun Jul 06 12:02:12 2014 -0700
    10.3 @@ -0,0 +1,52 @@
    10.4 +<!DOCTYPE html>
    10.5 +<html>
    10.6 +    <head>
    10.7 +        <title>famo.us App</title>
    10.8 +        <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
    10.9 +        <meta name="mobile-web-app-capable" content="yes" />
   10.10 +        <meta name="apple-mobile-web-app-capable" content="yes" />
   10.11 +        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
   10.12 +
   10.13 +        <!-- shims for backwards compatibility -->
   10.14 +        <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script>
   10.15 +        <script type="text/javascript" src="../lib/classList.js"></script>
   10.16 +        <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script>
   10.17 +
   10.18 +        <!-- module loader -->
   10.19 +        <script type="text/javascript" src="../lib/require.js"></script>
   10.20 +
   10.21 +        <!-- famous -->
   10.22 +        <link rel="stylesheet" type="text/css" href="../lib/famous.css" />
   10.23 +        <script type="text/javascript" src="../lib/famous.js"></script>
   10.24 +		
   10.25 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. -->
   10.26 +        <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" />
   10.27 +		
   10.28 +        <!-- load D3, to play around with also! -->
   10.29 +		<!--script type="text/javascript" src="d3/d3.v3.js"></script-->
   10.30 +		
   10.31 +    </head>
   10.32 +
   10.33 +<!--
   10.34 +<script src="terminal.js">
   10.35 +</script>
   10.36 +<body onload="window.start('terminal');">
   10.37 +
   10.38 +<div id="loader">...</div>
   10.39 +
   10.40 +<script type="text/javascript">require(['POP_Display']);</script>
   10.41 +
   10.42 +<script src="POP_Display.js">
   10.43 +</script>
   10.44 +
   10.45 +<body onload="window.start('Display.render');">
   10.46 +
   10.47 +-->
   10.48 +<body>
   10.49 +
   10.50 +<script type="text/javascript">require(['render_POP_syntax_graph']);</script>
   10.51 +
   10.52 +</body>
   10.53 +</html>
   10.54 +
   10.55 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/index.html	Sun Jul 06 12:02:12 2014 -0700
    11.3 @@ -0,0 +1,35 @@
    11.4 +<!DOCTYPE html>
    11.5 +<html>
    11.6 +    <head>
    11.7 +        <title>POP Display</title>
    11.8 +        <script data-main="startUpApp" src="lib/require.js"></script>
    11.9 +
   11.10 +		<script src="lib/jquery.min.js"></script>
   11.11 +		
   11.12 +        <!--  -->
   11.13 +		<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
   11.14 +        <meta name="mobile-web-app-capable" content="yes" />
   11.15 +        <meta name="apple-mobile-web-app-capable" content="yes" />
   11.16 +        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
   11.17 +
   11.18 +        <!-- shims for backwards compatibility -->
   11.19 +        <script type="text/javascript" src="../lib/functionPrototypeBind.js"></script>
   11.20 +        <script type="text/javascript" src="../lib/classList.js"></script>
   11.21 +        <script type="text/javascript" src="../lib/requestAnimationFrame.js"></script>
   11.22 +
   11.23 +        <!-- module loader -->
   11.24 +        <script type="text/javascript" src="../lib/require.js"></script>
   11.25 +
   11.26 +        <!-- famous -->
   11.27 +        <link rel="stylesheet" type="text/css" href="../lib/famous.css" />
   11.28 +        <script type="text/javascript" src="../lib/famous.js"></script>
   11.29 +		
   11.30 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. -->
   11.31 +        <link rel="stylesheet" type="text/css" href="../lib/famous_styles.css" />
   11.32 +
   11.33 +    </head>
   11.34 +
   11.35 +<body>
   11.36 +
   11.37 +</body>
   11.38 +</html>
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/jquery.min.js	Sun Jul 06 12:02:12 2014 -0700
    12.3 @@ -0,0 +1,4 @@
    12.4 +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
    12.5 +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
    12.6 +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"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){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
    12.7 +},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
    12.8 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/lib/require.js	Sun Jul 06 12:02:12 2014 -0700
    13.3 @@ -0,0 +1,2076 @@
    13.4 +/** vim: et:ts=4:sw=4:sts=4
    13.5 + * @license RequireJS 2.1.14 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
    13.6 + * Available via the MIT or new BSD license.
    13.7 + * see: http://github.com/jrburke/requirejs for details
    13.8 + */
    13.9 +//Not using strict: uneven strict support in browsers, #392, and causes
   13.10 +//problems with requirejs.exec()/transpiler plugins that may not be strict.
   13.11 +/*jslint regexp: true, nomen: true, sloppy: true */
   13.12 +/*global window, navigator, document, importScripts, setTimeout, opera */
   13.13 +
   13.14 +var requirejs, require, define;
   13.15 +(function (global) {
   13.16 +    var req, s, head, baseElement, dataMain, src,
   13.17 +        interactiveScript, currentlyAddingScript, mainScript, subPath,
   13.18 +        version = '2.1.14',
   13.19 +        commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
   13.20 +        cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
   13.21 +        jsSuffixRegExp = /\.js$/,
   13.22 +        currDirRegExp = /^\.\//,
   13.23 +        op = Object.prototype,
   13.24 +        ostring = op.toString,
   13.25 +        hasOwn = op.hasOwnProperty,
   13.26 +        ap = Array.prototype,
   13.27 +        apsp = ap.splice,
   13.28 +        isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
   13.29 +        isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
   13.30 +        //PS3 indicates loaded and complete, but need to wait for complete
   13.31 +        //specifically. Sequence is 'loading', 'loaded', execution,
   13.32 +        // then 'complete'. The UA check is unfortunate, but not sure how
   13.33 +        //to feature test w/o causing perf issues.
   13.34 +        readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
   13.35 +                      /^complete$/ : /^(complete|loaded)$/,
   13.36 +        defContextName = '_',
   13.37 +        //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
   13.38 +        isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
   13.39 +        contexts = {},
   13.40 +        cfg = {},
   13.41 +        globalDefQueue = [],
   13.42 +        useInteractive = false;
   13.43 +
   13.44 +    function isFunction(it) {
   13.45 +        return ostring.call(it) === '[object Function]';
   13.46 +    }
   13.47 +
   13.48 +    function isArray(it) {
   13.49 +        return ostring.call(it) === '[object Array]';
   13.50 +    }
   13.51 +
   13.52 +    /**
   13.53 +     * Helper function for iterating over an array. If the func returns
   13.54 +     * a true value, it will break out of the loop.
   13.55 +     */
   13.56 +    function each(ary, func) {
   13.57 +        if (ary) {
   13.58 +            var i;
   13.59 +            for (i = 0; i < ary.length; i += 1) {
   13.60 +                if (ary[i] && func(ary[i], i, ary)) {
   13.61 +                    break;
   13.62 +                }
   13.63 +            }
   13.64 +        }
   13.65 +    }
   13.66 +
   13.67 +    /**
   13.68 +     * Helper function for iterating over an array backwards. If the func
   13.69 +     * returns a true value, it will break out of the loop.
   13.70 +     */
   13.71 +    function eachReverse(ary, func) {
   13.72 +        if (ary) {
   13.73 +            var i;
   13.74 +            for (i = ary.length - 1; i > -1; i -= 1) {
   13.75 +                if (ary[i] && func(ary[i], i, ary)) {
   13.76 +                    break;
   13.77 +                }
   13.78 +            }
   13.79 +        }
   13.80 +    }
   13.81 +
   13.82 +    function hasProp(obj, prop) {
   13.83 +        return hasOwn.call(obj, prop);
   13.84 +    }
   13.85 +
   13.86 +    function getOwn(obj, prop) {
   13.87 +        return hasProp(obj, prop) && obj[prop];
   13.88 +    }
   13.89 +
   13.90 +    /**
   13.91 +     * Cycles over properties in an object and calls a function for each
   13.92 +     * property value. If the function returns a truthy value, then the
   13.93 +     * iteration is stopped.
   13.94 +     */
   13.95 +    function eachProp(obj, func) {
   13.96 +        var prop;
   13.97 +        for (prop in obj) {
   13.98 +            if (hasProp(obj, prop)) {
   13.99 +                if (func(obj[prop], prop)) {
  13.100 +                    break;
  13.101 +                }
  13.102 +            }
  13.103 +        }
  13.104 +    }
  13.105 +
  13.106 +    /**
  13.107 +     * Simple function to mix in properties from source into target,
  13.108 +     * but only if target does not already have a property of the same name.
  13.109 +     */
  13.110 +    function mixin(target, source, force, deepStringMixin) {
  13.111 +        if (source) {
  13.112 +            eachProp(source, function (value, prop) {
  13.113 +                if (force || !hasProp(target, prop)) {
  13.114 +                    if (deepStringMixin && typeof value === 'object' && value &&
  13.115 +                        !isArray(value) && !isFunction(value) &&
  13.116 +                        !(value instanceof RegExp)) {
  13.117 +
  13.118 +                        if (!target[prop]) {
  13.119 +                            target[prop] = {};
  13.120 +                        }
  13.121 +                        mixin(target[prop], value, force, deepStringMixin);
  13.122 +                    } else {
  13.123 +                        target[prop] = value;
  13.124 +                    }
  13.125 +                }
  13.126 +            });
  13.127 +        }
  13.128 +        return target;
  13.129 +    }
  13.130 +
  13.131 +    //Similar to Function.prototype.bind, but the 'this' object is specified
  13.132 +    //first, since it is easier to read/figure out what 'this' will be.
  13.133 +    function bind(obj, fn) {
  13.134 +        return function () {
  13.135 +            return fn.apply(obj, arguments);
  13.136 +        };
  13.137 +    }
  13.138 +
  13.139 +    function scripts() {
  13.140 +        return document.getElementsByTagName('script');
  13.141 +    }
  13.142 +
  13.143 +    function defaultOnError(err) {
  13.144 +        throw err;
  13.145 +    }
  13.146 +
  13.147 +    //Allow getting a global that is expressed in
  13.148 +    //dot notation, like 'a.b.c'.
  13.149 +    function getGlobal(value) {
  13.150 +        if (!value) {
  13.151 +            return value;
  13.152 +        }
  13.153 +        var g = global;
  13.154 +        each(value.split('.'), function (part) {
  13.155 +            g = g[part];
  13.156 +        });
  13.157 +        return g;
  13.158 +    }
  13.159 +
  13.160 +    /**
  13.161 +     * Constructs an error with a pointer to an URL with more information.
  13.162 +     * @param {String} id the error ID that maps to an ID on a web page.
  13.163 +     * @param {String} message human readable error.
  13.164 +     * @param {Error} [err] the original error, if there is one.
  13.165 +     *
  13.166 +     * @returns {Error}
  13.167 +     */
  13.168 +    function makeError(id, msg, err, requireModules) {
  13.169 +        var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
  13.170 +        e.requireType = id;
  13.171 +        e.requireModules = requireModules;
  13.172 +        if (err) {
  13.173 +            e.originalError = err;
  13.174 +        }
  13.175 +        return e;
  13.176 +    }
  13.177 +
  13.178 +    if (typeof define !== 'undefined') {
  13.179 +        //If a define is already in play via another AMD loader,
  13.180 +        //do not overwrite.
  13.181 +        return;
  13.182 +    }
  13.183 +
  13.184 +    if (typeof requirejs !== 'undefined') {
  13.185 +        if (isFunction(requirejs)) {
  13.186 +            //Do not overwrite an existing requirejs instance.
  13.187 +            return;
  13.188 +        }
  13.189 +        cfg = requirejs;
  13.190 +        requirejs = undefined;
  13.191 +    }
  13.192 +
  13.193 +    //Allow for a require config object
  13.194 +    if (typeof require !== 'undefined' && !isFunction(require)) {
  13.195 +        //assume it is a config object.
  13.196 +        cfg = require;
  13.197 +        require = undefined;
  13.198 +    }
  13.199 +
  13.200 +    function newContext(contextName) {
  13.201 +        var inCheckLoaded, Module, context, handlers,
  13.202 +            checkLoadedTimeoutId,
  13.203 +            config = {
  13.204 +                //Defaults. Do not set a default for map
  13.205 +                //config to speed up normalize(), which
  13.206 +                //will run faster if there is no default.
  13.207 +                waitSeconds: 7,
  13.208 +                baseUrl: './',
  13.209 +                paths: {},
  13.210 +                bundles: {},
  13.211 +                pkgs: {},
  13.212 +                shim: {},
  13.213 +                config: {}
  13.214 +            },
  13.215 +            registry = {},
  13.216 +            //registry of just enabled modules, to speed
  13.217 +            //cycle breaking code when lots of modules
  13.218 +            //are registered, but not activated.
  13.219 +            enabledRegistry = {},
  13.220 +            undefEvents = {},
  13.221 +            defQueue = [],
  13.222 +            defined = {},
  13.223 +            urlFetched = {},
  13.224 +            bundlesMap = {},
  13.225 +            requireCounter = 1,
  13.226 +            unnormalizedCounter = 1;
  13.227 +
  13.228 +        /**
  13.229 +         * Trims the . and .. from an array of path segments.
  13.230 +         * It will keep a leading path segment if a .. will become
  13.231 +         * the first path segment, to help with module name lookups,
  13.232 +         * which act like paths, but can be remapped. But the end result,
  13.233 +         * all paths that use this function should look normalized.
  13.234 +         * NOTE: this method MODIFIES the input array.
  13.235 +         * @param {Array} ary the array of path segments.
  13.236 +         */
  13.237 +        function trimDots(ary) {
  13.238 +            var i, part;
  13.239 +            for (i = 0; i < ary.length; i++) {
  13.240 +                part = ary[i];
  13.241 +                if (part === '.') {
  13.242 +                    ary.splice(i, 1);
  13.243 +                    i -= 1;
  13.244 +                } else if (part === '..') {
  13.245 +                    // If at the start, or previous value is still ..,
  13.246 +                    // keep them so that when converted to a path it may
  13.247 +                    // still work when converted to a path, even though
  13.248 +                    // as an ID it is less than ideal. In larger point
  13.249 +                    // releases, may be better to just kick out an error.
  13.250 +                    if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') {
  13.251 +                        continue;
  13.252 +                    } else if (i > 0) {
  13.253 +                        ary.splice(i - 1, 2);
  13.254 +                        i -= 2;
  13.255 +                    }
  13.256 +                }
  13.257 +            }
  13.258 +        }
  13.259 +
  13.260 +        /**
  13.261 +         * Given a relative module name, like ./something, normalize it to
  13.262 +         * a real name that can be mapped to a path.
  13.263 +         * @param {String} name the relative name
  13.264 +         * @param {String} baseName a real name that the name arg is relative
  13.265 +         * to.
  13.266 +         * @param {Boolean} applyMap apply the map config to the value. Should
  13.267 +         * only be done if this normalization is for a dependency ID.
  13.268 +         * @returns {String} normalized name
  13.269 +         */
  13.270 +        function normalize(name, baseName, applyMap) {
  13.271 +            var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
  13.272 +                foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
  13.273 +                baseParts = (baseName && baseName.split('/')),
  13.274 +                map = config.map,
  13.275 +                starMap = map && map['*'];
  13.276 +
  13.277 +            //Adjust any relative paths.
  13.278 +            if (name) {
  13.279 +                name = name.split('/');
  13.280 +                lastIndex = name.length - 1;
  13.281 +
  13.282 +                // If wanting node ID compatibility, strip .js from end
  13.283 +                // of IDs. Have to do this here, and not in nameToUrl
  13.284 +                // because node allows either .js or non .js to map
  13.285 +                // to same file.
  13.286 +                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
  13.287 +                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
  13.288 +                }
  13.289 +
  13.290 +                // Starts with a '.' so need the baseName
  13.291 +                if (name[0].charAt(0) === '.' && baseParts) {
  13.292 +                    //Convert baseName to array, and lop off the last part,
  13.293 +                    //so that . matches that 'directory' and not name of the baseName's
  13.294 +                    //module. For instance, baseName of 'one/two/three', maps to
  13.295 +                    //'one/two/three.js', but we want the directory, 'one/two' for
  13.296 +                    //this normalization.
  13.297 +                    normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
  13.298 +                    name = normalizedBaseParts.concat(name);
  13.299 +                }
  13.300 +
  13.301 +                trimDots(name);
  13.302 +                name = name.join('/');
  13.303 +            }
  13.304 +
  13.305 +            //Apply map config if available.
  13.306 +            if (applyMap && map && (baseParts || starMap)) {
  13.307 +                nameParts = name.split('/');
  13.308 +
  13.309 +                outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
  13.310 +                    nameSegment = nameParts.slice(0, i).join('/');
  13.311 +
  13.312 +                    if (baseParts) {
  13.313 +                        //Find the longest baseName segment match in the config.
  13.314 +                        //So, do joins on the biggest to smallest lengths of baseParts.
  13.315 +                        for (j = baseParts.length; j > 0; j -= 1) {
  13.316 +                            mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
  13.317 +
  13.318 +                            //baseName segment has config, find if it has one for
  13.319 +                            //this name.
  13.320 +                            if (mapValue) {
  13.321 +                                mapValue = getOwn(mapValue, nameSegment);
  13.322 +                                if (mapValue) {
  13.323 +                                    //Match, update name to the new value.
  13.324 +                                    foundMap = mapValue;
  13.325 +                                    foundI = i;
  13.326 +                                    break outerLoop;
  13.327 +                                }
  13.328 +                            }
  13.329 +                        }
  13.330 +                    }
  13.331 +
  13.332 +                    //Check for a star map match, but just hold on to it,
  13.333 +                    //if there is a shorter segment match later in a matching
  13.334 +                    //config, then favor over this star map.
  13.335 +                    if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
  13.336 +                        foundStarMap = getOwn(starMap, nameSegment);
  13.337 +                        starI = i;
  13.338 +                    }
  13.339 +                }
  13.340 +
  13.341 +                if (!foundMap && foundStarMap) {
  13.342 +                    foundMap = foundStarMap;
  13.343 +                    foundI = starI;
  13.344 +                }
  13.345 +
  13.346 +                if (foundMap) {
  13.347 +                    nameParts.splice(0, foundI, foundMap);
  13.348 +                    name = nameParts.join('/');
  13.349 +                }
  13.350 +            }
  13.351 +
  13.352 +            // If the name points to a package's name, use
  13.353 +            // the package main instead.
  13.354 +            pkgMain = getOwn(config.pkgs, name);
  13.355 +
  13.356 +            return pkgMain ? pkgMain : name;
  13.357 +        }
  13.358 +
  13.359 +        function removeScript(name) {
  13.360 +            if (isBrowser) {
  13.361 +                each(scripts(), function (scriptNode) {
  13.362 +                    if (scriptNode.getAttribute('data-requiremodule') === name &&
  13.363 +                            scriptNode.getAttribute('data-requirecontext') === context.contextName) {
  13.364 +                        scriptNode.parentNode.removeChild(scriptNode);
  13.365 +                        return true;
  13.366 +                    }
  13.367 +                });
  13.368 +            }
  13.369 +        }
  13.370 +
  13.371 +        function hasPathFallback(id) {
  13.372 +            var pathConfig = getOwn(config.paths, id);
  13.373 +            if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
  13.374 +                //Pop off the first array value, since it failed, and
  13.375 +                //retry
  13.376 +                pathConfig.shift();
  13.377 +                context.require.undef(id);
  13.378 +
  13.379 +                //Custom require that does not do map translation, since
  13.380 +                //ID is "absolute", already mapped/resolved.
  13.381 +                context.makeRequire(null, {
  13.382 +                    skipMap: true
  13.383 +                })([id]);
  13.384 +
  13.385 +                return true;
  13.386 +            }
  13.387 +        }
  13.388 +
  13.389 +        //Turns a plugin!resource to [plugin, resource]
  13.390 +        //with the plugin being undefined if the name
  13.391 +        //did not have a plugin prefix.
  13.392 +        function splitPrefix(name) {
  13.393 +            var prefix,
  13.394 +                index = name ? name.indexOf('!') : -1;
  13.395 +            if (index > -1) {
  13.396 +                prefix = name.substring(0, index);
  13.397 +                name = name.substring(index + 1, name.length);
  13.398 +            }
  13.399 +            return [prefix, name];
  13.400 +        }
  13.401 +
  13.402 +        /**
  13.403 +         * Creates a module mapping that includes plugin prefix, module
  13.404 +         * name, and path. If parentModuleMap is provided it will
  13.405 +         * also normalize the name via require.normalize()
  13.406 +         *
  13.407 +         * @param {String} name the module name
  13.408 +         * @param {String} [parentModuleMap] parent module map
  13.409 +         * for the module name, used to resolve relative names.
  13.410 +         * @param {Boolean} isNormalized: is the ID already normalized.
  13.411 +         * This is true if this call is done for a define() module ID.
  13.412 +         * @param {Boolean} applyMap: apply the map config to the ID.
  13.413 +         * Should only be true if this map is for a dependency.
  13.414 +         *
  13.415 +         * @returns {Object}
  13.416 +         */
  13.417 +        function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
  13.418 +            var url, pluginModule, suffix, nameParts,
  13.419 +                prefix = null,
  13.420 +                parentName = parentModuleMap ? parentModuleMap.name : null,
  13.421 +                originalName = name,
  13.422 +                isDefine = true,
  13.423 +                normalizedName = '';
  13.424 +
  13.425 +            //If no name, then it means it is a require call, generate an
  13.426 +            //internal name.
  13.427 +            if (!name) {
  13.428 +                isDefine = false;
  13.429 +                name = '_@r' + (requireCounter += 1);
  13.430 +            }
  13.431 +
  13.432 +            nameParts = splitPrefix(name);
  13.433 +            prefix = nameParts[0];
  13.434 +            name = nameParts[1];
  13.435 +
  13.436 +            if (prefix) {
  13.437 +                prefix = normalize(prefix, parentName, applyMap);
  13.438 +                pluginModule = getOwn(defined, prefix);
  13.439 +            }
  13.440 +
  13.441 +            //Account for relative paths if there is a base name.
  13.442 +            if (name) {
  13.443 +                if (prefix) {
  13.444 +                    if (pluginModule && pluginModule.normalize) {
  13.445 +                        //Plugin is loaded, use its normalize method.
  13.446 +                        normalizedName = pluginModule.normalize(name, function (name) {
  13.447 +                            return normalize(name, parentName, applyMap);
  13.448 +                        });
  13.449 +                    } else {
  13.450 +                        // If nested plugin references, then do not try to
  13.451 +                        // normalize, as it will not normalize correctly. This
  13.452 +                        // places a restriction on resourceIds, and the longer
  13.453 +                        // term solution is not to normalize until plugins are
  13.454 +                        // loaded and all normalizations to allow for async
  13.455 +                        // loading of a loader plugin. But for now, fixes the
  13.456 +                        // common uses. Details in #1131
  13.457 +                        normalizedName = name.indexOf('!') === -1 ?
  13.458 +                                         normalize(name, parentName, applyMap) :
  13.459 +                                         name;
  13.460 +                    }
  13.461 +                } else {
  13.462 +                    //A regular module.
  13.463 +                    normalizedName = normalize(name, parentName, applyMap);
  13.464 +
  13.465 +                    //Normalized name may be a plugin ID due to map config
  13.466 +                    //application in normalize. The map config values must
  13.467 +                    //already be normalized, so do not need to redo that part.
  13.468 +                    nameParts = splitPrefix(normalizedName);
  13.469 +                    prefix = nameParts[0];
  13.470 +                    normalizedName = nameParts[1];
  13.471 +                    isNormalized = true;
  13.472 +
  13.473 +                    url = context.nameToUrl(normalizedName);
  13.474 +                }
  13.475 +            }
  13.476 +
  13.477 +            //If the id is a plugin id that cannot be determined if it needs
  13.478 +            //normalization, stamp it with a unique ID so two matching relative
  13.479 +            //ids that may conflict can be separate.
  13.480 +            suffix = prefix && !pluginModule && !isNormalized ?
  13.481 +                     '_unnormalized' + (unnormalizedCounter += 1) :
  13.482 +                     '';
  13.483 +
  13.484 +            return {
  13.485 +                prefix: prefix,
  13.486 +                name: normalizedName,
  13.487 +                parentMap: parentModuleMap,
  13.488 +                unnormalized: !!suffix,
  13.489 +                url: url,
  13.490 +                originalName: originalName,
  13.491 +                isDefine: isDefine,
  13.492 +                id: (prefix ?
  13.493 +                        prefix + '!' + normalizedName :
  13.494 +                        normalizedName) + suffix
  13.495 +            };
  13.496 +        }
  13.497 +
  13.498 +        function getModule(depMap) {
  13.499 +            var id = depMap.id,
  13.500 +                mod = getOwn(registry, id);
  13.501 +
  13.502 +            if (!mod) {
  13.503 +                mod = registry[id] = new context.Module(depMap);
  13.504 +            }
  13.505 +
  13.506 +            return mod;
  13.507 +        }
  13.508 +
  13.509 +        function on(depMap, name, fn) {
  13.510 +            var id = depMap.id,
  13.511 +                mod = getOwn(registry, id);
  13.512 +
  13.513 +            if (hasProp(defined, id) &&
  13.514 +                    (!mod || mod.defineEmitComplete)) {
  13.515 +                if (name === 'defined') {
  13.516 +                    fn(defined[id]);
  13.517 +                }
  13.518 +            } else {
  13.519 +                mod = getModule(depMap);
  13.520 +                if (mod.error && name === 'error') {
  13.521 +                    fn(mod.error);
  13.522 +                } else {
  13.523 +                    mod.on(name, fn);
  13.524 +                }
  13.525 +            }
  13.526 +        }
  13.527 +
  13.528 +        function onError(err, errback) {
  13.529 +            var ids = err.requireModules,
  13.530 +                notified = false;
  13.531 +
  13.532 +            if (errback) {
  13.533 +                errback(err);
  13.534 +            } else {
  13.535 +                each(ids, function (id) {
  13.536 +                    var mod = getOwn(registry, id);
  13.537 +                    if (mod) {
  13.538 +                        //Set error on module, so it skips timeout checks.
  13.539 +                        mod.error = err;
  13.540 +                        if (mod.events.error) {
  13.541 +                            notified = true;
  13.542 +                            mod.emit('error', err);
  13.543 +                        }
  13.544 +                    }
  13.545 +                });
  13.546 +
  13.547 +                if (!notified) {
  13.548 +                    req.onError(err);
  13.549 +                }
  13.550 +            }
  13.551 +        }
  13.552 +
  13.553 +        /**
  13.554 +         * Internal method to transfer globalQueue items to this context's
  13.555 +         * defQueue.
  13.556 +         */
  13.557 +        function takeGlobalQueue() {
  13.558 +            //Push all the globalDefQueue items into the context's defQueue
  13.559 +            if (globalDefQueue.length) {
  13.560 +                //Array splice in the values since the context code has a
  13.561 +                //local var ref to defQueue, so cannot just reassign the one
  13.562 +                //on context.
  13.563 +                apsp.apply(defQueue,
  13.564 +                           [defQueue.length, 0].concat(globalDefQueue));
  13.565 +                globalDefQueue = [];
  13.566 +            }
  13.567 +        }
  13.568 +
  13.569 +        handlers = {
  13.570 +            'require': function (mod) {
  13.571 +                if (mod.require) {
  13.572 +                    return mod.require;
  13.573 +                } else {
  13.574 +                    return (mod.require = context.makeRequire(mod.map));
  13.575 +                }
  13.576 +            },
  13.577 +            'exports': function (mod) {
  13.578 +                mod.usingExports = true;
  13.579 +                if (mod.map.isDefine) {
  13.580 +                    if (mod.exports) {
  13.581 +                        return (defined[mod.map.id] = mod.exports);
  13.582 +                    } else {
  13.583 +                        return (mod.exports = defined[mod.map.id] = {});
  13.584 +                    }
  13.585 +                }
  13.586 +            },
  13.587 +            'module': function (mod) {
  13.588 +                if (mod.module) {
  13.589 +                    return mod.module;
  13.590 +                } else {
  13.591 +                    return (mod.module = {
  13.592 +                        id: mod.map.id,
  13.593 +                        uri: mod.map.url,
  13.594 +                        config: function () {
  13.595 +                            return  getOwn(config.config, mod.map.id) || {};
  13.596 +                        },
  13.597 +                        exports: mod.exports || (mod.exports = {})
  13.598 +                    });
  13.599 +                }
  13.600 +            }
  13.601 +        };
  13.602 +
  13.603 +        function cleanRegistry(id) {
  13.604 +            //Clean up machinery used for waiting modules.
  13.605 +            delete registry[id];
  13.606 +            delete enabledRegistry[id];
  13.607 +        }
  13.608 +
  13.609 +        function breakCycle(mod, traced, processed) {
  13.610 +            var id = mod.map.id;
  13.611 +
  13.612 +            if (mod.error) {
  13.613 +                mod.emit('error', mod.error);
  13.614 +            } else {
  13.615 +                traced[id] = true;
  13.616 +                each(mod.depMaps, function (depMap, i) {
  13.617 +                    var depId = depMap.id,
  13.618 +                        dep = getOwn(registry, depId);
  13.619 +
  13.620 +                    //Only force things that have not completed
  13.621 +                    //being defined, so still in the registry,
  13.622 +                    //and only if it has not been matched up
  13.623 +                    //in the module already.
  13.624 +                    if (dep && !mod.depMatched[i] && !processed[depId]) {
  13.625 +                        if (getOwn(traced, depId)) {
  13.626 +                            mod.defineDep(i, defined[depId]);
  13.627 +                            mod.check(); //pass false?
  13.628 +                        } else {
  13.629 +                            breakCycle(dep, traced, processed);
  13.630 +                        }
  13.631 +                    }
  13.632 +                });
  13.633 +                processed[id] = true;
  13.634 +            }
  13.635 +        }
  13.636 +
  13.637 +        function checkLoaded() {
  13.638 +            var err, usingPathFallback,
  13.639 +                waitInterval = config.waitSeconds * 1000,
  13.640 +                //It is possible to disable the wait interval by using waitSeconds of 0.
  13.641 +                expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
  13.642 +                noLoads = [],
  13.643 +                reqCalls = [],
  13.644 +                stillLoading = false,
  13.645 +                needCycleCheck = true;
  13.646 +
  13.647 +            //Do not bother if this call was a result of a cycle break.
  13.648 +            if (inCheckLoaded) {
  13.649 +                return;
  13.650 +            }
  13.651 +
  13.652 +            inCheckLoaded = true;
  13.653 +
  13.654 +            //Figure out the state of all the modules.
  13.655 +            eachProp(enabledRegistry, function (mod) {
  13.656 +                var map = mod.map,
  13.657 +                    modId = map.id;
  13.658 +
  13.659 +                //Skip things that are not enabled or in error state.
  13.660 +                if (!mod.enabled) {
  13.661 +                    return;
  13.662 +                }
  13.663 +
  13.664 +                if (!map.isDefine) {
  13.665 +                    reqCalls.push(mod);
  13.666 +                }
  13.667 +
  13.668 +                if (!mod.error) {
  13.669 +                    //If the module should be executed, and it has not
  13.670 +                    //been inited and time is up, remember it.
  13.671 +                    if (!mod.inited && expired) {
  13.672 +                        if (hasPathFallback(modId)) {
  13.673 +                            usingPathFallback = true;
  13.674 +                            stillLoading = true;
  13.675 +                        } else {
  13.676 +                            noLoads.push(modId);
  13.677 +                            removeScript(modId);
  13.678 +                        }
  13.679 +                    } else if (!mod.inited && mod.fetched && map.isDefine) {
  13.680 +                        stillLoading = true;
  13.681 +                        if (!map.prefix) {
  13.682 +                            //No reason to keep looking for unfinished
  13.683 +                            //loading. If the only stillLoading is a
  13.684 +                            //plugin resource though, keep going,
  13.685 +                            //because it may be that a plugin resource
  13.686 +                            //is waiting on a non-plugin cycle.
  13.687 +                            return (needCycleCheck = false);
  13.688 +                        }
  13.689 +                    }
  13.690 +                }
  13.691 +            });
  13.692 +
  13.693 +            if (expired && noLoads.length) {
  13.694 +                //If wait time expired, throw error of unloaded modules.
  13.695 +                err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
  13.696 +                err.contextName = context.contextName;
  13.697 +                return onError(err);
  13.698 +            }
  13.699 +
  13.700 +            //Not expired, check for a cycle.
  13.701 +            if (needCycleCheck) {
  13.702 +                each(reqCalls, function (mod) {
  13.703 +                    breakCycle(mod, {}, {});
  13.704 +                });
  13.705 +            }
  13.706 +
  13.707 +            //If still waiting on loads, and the waiting load is something
  13.708 +            //other than a plugin resource, or there are still outstanding
  13.709 +            //scripts, then just try back later.
  13.710 +            if ((!expired || usingPathFallback) && stillLoading) {
  13.711 +                //Something is still waiting to load. Wait for it, but only
  13.712 +                //if a timeout is not already in effect.
  13.713 +                if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
  13.714 +                    checkLoadedTimeoutId = setTimeout(function () {
  13.715 +                        checkLoadedTimeoutId = 0;
  13.716 +                        checkLoaded();
  13.717 +                    }, 50);
  13.718 +                }
  13.719 +            }
  13.720 +
  13.721 +            inCheckLoaded = false;
  13.722 +        }
  13.723 +
  13.724 +        Module = function (map) {
  13.725 +            this.events = getOwn(undefEvents, map.id) || {};
  13.726 +            this.map = map;
  13.727 +            this.shim = getOwn(config.shim, map.id);
  13.728 +            this.depExports = [];
  13.729 +            this.depMaps = [];
  13.730 +            this.depMatched = [];
  13.731 +            this.pluginMaps = {};
  13.732 +            this.depCount = 0;
  13.733 +
  13.734 +            /* this.exports this.factory
  13.735 +               this.depMaps = [],
  13.736 +               this.enabled, this.fetched
  13.737 +            */
  13.738 +        };
  13.739 +
  13.740 +        Module.prototype = {
  13.741 +            init: function (depMaps, factory, errback, options) {
  13.742 +                options = options || {};
  13.743 +
  13.744 +                //Do not do more inits if already done. Can happen if there
  13.745 +                //are multiple define calls for the same module. That is not
  13.746 +                //a normal, common case, but it is also not unexpected.
  13.747 +                if (this.inited) {
  13.748 +                    return;
  13.749 +                }
  13.750 +
  13.751 +                this.factory = factory;
  13.752 +
  13.753 +                if (errback) {
  13.754 +                    //Register for errors on this module.
  13.755 +                    this.on('error', errback);
  13.756 +                } else if (this.events.error) {
  13.757 +                    //If no errback already, but there are error listeners
  13.758 +                    //on this module, set up an errback to pass to the deps.
  13.759 +                    errback = bind(this, function (err) {
  13.760 +                        this.emit('error', err);
  13.761 +                    });
  13.762 +                }
  13.763 +
  13.764 +                //Do a copy of the dependency array, so that
  13.765 +                //source inputs are not modified. For example
  13.766 +                //"shim" deps are passed in here directly, and
  13.767 +                //doing a direct modification of the depMaps array
  13.768 +                //would affect that config.
  13.769 +                this.depMaps = depMaps && depMaps.slice(0);
  13.770 +
  13.771 +                this.errback = errback;
  13.772 +
  13.773 +                //Indicate this module has be initialized
  13.774 +                this.inited = true;
  13.775 +
  13.776 +                this.ignore = options.ignore;
  13.777 +
  13.778 +                //Could have option to init this module in enabled mode,
  13.779 +                //or could have been previously marked as enabled. However,
  13.780 +                //the dependencies are not known until init is called. So
  13.781 +                //if enabled previously, now trigger dependencies as enabled.
  13.782 +                if (options.enabled || this.enabled) {
  13.783 +                    //Enable this module and dependencies.
  13.784 +                    //Will call this.check()
  13.785 +                    this.enable();
  13.786 +                } else {
  13.787 +                    this.check();
  13.788 +                }
  13.789 +            },
  13.790 +
  13.791 +            defineDep: function (i, depExports) {
  13.792 +                //Because of cycles, defined callback for a given
  13.793 +                //export can be called more than once.
  13.794 +                if (!this.depMatched[i]) {
  13.795 +                    this.depMatched[i] = true;
  13.796 +                    this.depCount -= 1;
  13.797 +                    this.depExports[i] = depExports;
  13.798 +                }
  13.799 +            },
  13.800 +
  13.801 +            fetch: function () {
  13.802 +                if (this.fetched) {
  13.803 +                    return;
  13.804 +                }
  13.805 +                this.fetched = true;
  13.806 +
  13.807 +                context.startTime = (new Date()).getTime();
  13.808 +
  13.809 +                var map = this.map;
  13.810 +
  13.811 +                //If the manager is for a plugin managed resource,
  13.812 +                //ask the plugin to load it now.
  13.813 +                if (this.shim) {
  13.814 +                    context.makeRequire(this.map, {
  13.815 +                        enableBuildCallback: true
  13.816 +                    })(this.shim.deps || [], bind(this, function () {
  13.817 +                        return map.prefix ? this.callPlugin() : this.load();
  13.818 +                    }));
  13.819 +                } else {
  13.820 +                    //Regular dependency.
  13.821 +                    return map.prefix ? this.callPlugin() : this.load();
  13.822 +                }
  13.823 +            },
  13.824 +
  13.825 +            load: function () {
  13.826 +                var url = this.map.url;
  13.827 +
  13.828 +                //Regular dependency.
  13.829 +                if (!urlFetched[url]) {
  13.830 +                    urlFetched[url] = true;
  13.831 +                    context.load(this.map.id, url);
  13.832 +                }
  13.833 +            },
  13.834 +
  13.835 +            /**
  13.836 +             * Checks if the module is ready to define itself, and if so,
  13.837 +             * define it.
  13.838 +             */
  13.839 +            check: function () {
  13.840 +                if (!this.enabled || this.enabling) {
  13.841 +                    return;
  13.842 +                }
  13.843 +
  13.844 +                var err, cjsModule,
  13.845 +                    id = this.map.id,
  13.846 +                    depExports = this.depExports,
  13.847 +                    exports = this.exports,
  13.848 +                    factory = this.factory;
  13.849 +
  13.850 +                if (!this.inited) {
  13.851 +                    this.fetch();
  13.852 +                } else if (this.error) {
  13.853 +                    this.emit('error', this.error);
  13.854 +                } else if (!this.defining) {
  13.855 +                    //The factory could trigger another require call
  13.856 +                    //that would result in checking this module to
  13.857 +                    //define itself again. If already in the process
  13.858 +                    //of doing that, skip this work.
  13.859 +                    this.defining = true;
  13.860 +
  13.861 +                    if (this.depCount < 1 && !this.defined) {
  13.862 +                        if (isFunction(factory)) {
  13.863 +                            //If there is an error listener, favor passing
  13.864 +                            //to that instead of throwing an error. However,
  13.865 +                            //only do it for define()'d  modules. require
  13.866 +                            //errbacks should not be called for failures in
  13.867 +                            //their callbacks (#699). However if a global
  13.868 +                            //onError is set, use that.
  13.869 +                            if ((this.events.error && this.map.isDefine) ||
  13.870 +                                req.onError !== defaultOnError) {
  13.871 +                                try {
  13.872 +                                    exports = context.execCb(id, factory, depExports, exports);
  13.873 +                                } catch (e) {
  13.874 +                                    err = e;
  13.875 +                                }
  13.876 +                            } else {
  13.877 +                                exports = context.execCb(id, factory, depExports, exports);
  13.878 +                            }
  13.879 +
  13.880 +                            // Favor return value over exports. If node/cjs in play,
  13.881 +                            // then will not have a return value anyway. Favor
  13.882 +                            // module.exports assignment over exports object.
  13.883 +                            if (this.map.isDefine && exports === undefined) {
  13.884 +                                cjsModule = this.module;
  13.885 +                                if (cjsModule) {
  13.886 +                                    exports = cjsModule.exports;
  13.887 +                                } else if (this.usingExports) {
  13.888 +                                    //exports already set the defined value.
  13.889 +                                    exports = this.exports;
  13.890 +                                }
  13.891 +                            }
  13.892 +
  13.893 +                            if (err) {
  13.894 +                                err.requireMap = this.map;
  13.895 +                                err.requireModules = this.map.isDefine ? [this.map.id] : null;
  13.896 +                                err.requireType = this.map.isDefine ? 'define' : 'require';
  13.897 +                                return onError((this.error = err));
  13.898 +                            }
  13.899 +
  13.900 +                        } else {
  13.901 +                            //Just a literal value
  13.902 +                            exports = factory;
  13.903 +                        }
  13.904 +
  13.905 +                        this.exports = exports;
  13.906 +
  13.907 +                        if (this.map.isDefine && !this.ignore) {
  13.908 +                            defined[id] = exports;
  13.909 +
  13.910 +                            if (req.onResourceLoad) {
  13.911 +                                req.onResourceLoad(context, this.map, this.depMaps);
  13.912 +                            }
  13.913 +                        }
  13.914 +
  13.915 +                        //Clean up
  13.916 +                        cleanRegistry(id);
  13.917 +
  13.918 +                        this.defined = true;
  13.919 +                    }
  13.920 +
  13.921 +                    //Finished the define stage. Allow calling check again
  13.922 +                    //to allow define notifications below in the case of a
  13.923 +                    //cycle.
  13.924 +                    this.defining = false;
  13.925 +
  13.926 +                    if (this.defined && !this.defineEmitted) {
  13.927 +                        this.defineEmitted = true;
  13.928 +                        this.emit('defined', this.exports);
  13.929 +                        this.defineEmitComplete = true;
  13.930 +                    }
  13.931 +
  13.932 +                }
  13.933 +            },
  13.934 +
  13.935 +            callPlugin: function () {
  13.936 +                var map = this.map,
  13.937 +                    id = map.id,
  13.938 +                    //Map already normalized the prefix.
  13.939 +                    pluginMap = makeModuleMap(map.prefix);
  13.940 +
  13.941 +                //Mark this as a dependency for this plugin, so it
  13.942 +                //can be traced for cycles.
  13.943 +                this.depMaps.push(pluginMap);
  13.944 +
  13.945 +                on(pluginMap, 'defined', bind(this, function (plugin) {
  13.946 +                    var load, normalizedMap, normalizedMod,
  13.947 +                        bundleId = getOwn(bundlesMap, this.map.id),
  13.948 +                        name = this.map.name,
  13.949 +                        parentName = this.map.parentMap ? this.map.parentMap.name : null,
  13.950 +                        localRequire = context.makeRequire(map.parentMap, {
  13.951 +                            enableBuildCallback: true
  13.952 +                        });
  13.953 +
  13.954 +                    //If current map is not normalized, wait for that
  13.955 +                    //normalized name to load instead of continuing.
  13.956 +                    if (this.map.unnormalized) {
  13.957 +                        //Normalize the ID if the plugin allows it.
  13.958 +                        if (plugin.normalize) {
  13.959 +                            name = plugin.normalize(name, function (name) {
  13.960 +                                return normalize(name, parentName, true);
  13.961 +                            }) || '';
  13.962 +                        }
  13.963 +
  13.964 +                        //prefix and name should already be normalized, no need
  13.965 +                        //for applying map config again either.
  13.966 +                        normalizedMap = makeModuleMap(map.prefix + '!' + name,
  13.967 +                                                      this.map.parentMap);
  13.968 +                        on(normalizedMap,
  13.969 +                            'defined', bind(this, function (value) {
  13.970 +                                this.init([], function () { return value; }, null, {
  13.971 +                                    enabled: true,
  13.972 +                                    ignore: true
  13.973 +                                });
  13.974 +                            }));
  13.975 +
  13.976 +                        normalizedMod = getOwn(registry, normalizedMap.id);
  13.977 +                        if (normalizedMod) {
  13.978 +                            //Mark this as a dependency for this plugin, so it
  13.979 +                            //can be traced for cycles.
  13.980 +                            this.depMaps.push(normalizedMap);
  13.981 +
  13.982 +                            if (this.events.error) {
  13.983 +                                normalizedMod.on('error', bind(this, function (err) {
  13.984 +                                    this.emit('error', err);
  13.985 +                                }));
  13.986 +                            }
  13.987 +                            normalizedMod.enable();
  13.988 +                        }
  13.989 +
  13.990 +                        return;
  13.991 +                    }
  13.992 +
  13.993 +                    //If a paths config, then just load that file instead to
  13.994 +                    //resolve the plugin, as it is built into that paths layer.
  13.995 +                    if (bundleId) {
  13.996 +                        this.map.url = context.nameToUrl(bundleId);
  13.997 +                        this.load();
  13.998 +                        return;
  13.999 +                    }
 13.1000 +
 13.1001 +                    load = bind(this, function (value) {
 13.1002 +                        this.init([], function () { return value; }, null, {
 13.1003 +                            enabled: true
 13.1004 +                        });
 13.1005 +                    });
 13.1006 +
 13.1007 +                    load.error = bind(this, function (err) {
 13.1008 +                        this.inited = true;
 13.1009 +                        this.error = err;
 13.1010 +                        err.requireModules = [id];
 13.1011 +
 13.1012 +                        //Remove temp unnormalized modules for this module,
 13.1013 +                        //since they will never be resolved otherwise now.
 13.1014 +                        eachProp(registry, function (mod) {
 13.1015 +                            if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
 13.1016 +                                cleanRegistry(mod.map.id);
 13.1017 +                            }
 13.1018 +                        });
 13.1019 +
 13.1020 +                        onError(err);
 13.1021 +                    });
 13.1022 +
 13.1023 +                    //Allow plugins to load other code without having to know the
 13.1024 +                    //context or how to 'complete' the load.
 13.1025 +                    load.fromText = bind(this, function (text, textAlt) {
 13.1026 +                        /*jslint evil: true */
 13.1027 +                        var moduleName = map.name,
 13.1028 +                            moduleMap = makeModuleMap(moduleName),
 13.1029 +                            hasInteractive = useInteractive;
 13.1030 +
 13.1031 +                        //As of 2.1.0, support just passing the text, to reinforce
 13.1032 +                        //fromText only being called once per resource. Still
 13.1033 +                        //support old style of passing moduleName but discard
 13.1034 +                        //that moduleName in favor of the internal ref.
 13.1035 +                        if (textAlt) {
 13.1036 +                            text = textAlt;
 13.1037 +                        }
 13.1038 +
 13.1039 +                        //Turn off interactive script matching for IE for any define
 13.1040 +                        //calls in the text, then turn it back on at the end.
 13.1041 +                        if (hasInteractive) {
 13.1042 +                            useInteractive = false;
 13.1043 +                        }
 13.1044 +
 13.1045 +                        //Prime the system by creating a module instance for
 13.1046 +                        //it.
 13.1047 +                        getModule(moduleMap);
 13.1048 +
 13.1049 +                        //Transfer any config to this other module.
 13.1050 +                        if (hasProp(config.config, id)) {
 13.1051 +                            config.config[moduleName] = config.config[id];
 13.1052 +                        }
 13.1053 +
 13.1054 +                        try {
 13.1055 +                            req.exec(text);
 13.1056 +                        } catch (e) {
 13.1057 +                            return onError(makeError('fromtexteval',
 13.1058 +                                             'fromText eval for ' + id +
 13.1059 +                                            ' failed: ' + e,
 13.1060 +                                             e,
 13.1061 +                                             [id]));
 13.1062 +                        }
 13.1063 +
 13.1064 +                        if (hasInteractive) {
 13.1065 +                            useInteractive = true;
 13.1066 +                        }
 13.1067 +
 13.1068 +                        //Mark this as a dependency for the plugin
 13.1069 +                        //resource
 13.1070 +                        this.depMaps.push(moduleMap);
 13.1071 +
 13.1072 +                        //Support anonymous modules.
 13.1073 +                        context.completeLoad(moduleName);
 13.1074 +
 13.1075 +                        //Bind the value of that module to the value for this
 13.1076 +                        //resource ID.
 13.1077 +                        localRequire([moduleName], load);
 13.1078 +                    });
 13.1079 +
 13.1080 +                    //Use parentName here since the plugin's name is not reliable,
 13.1081 +                    //could be some weird string with no path that actually wants to
 13.1082 +                    //reference the parentName's path.
 13.1083 +                    plugin.load(map.name, localRequire, load, config);
 13.1084 +                }));
 13.1085 +
 13.1086 +                context.enable(pluginMap, this);
 13.1087 +                this.pluginMaps[pluginMap.id] = pluginMap;
 13.1088 +            },
 13.1089 +
 13.1090 +            enable: function () {
 13.1091 +                enabledRegistry[this.map.id] = this;
 13.1092 +                this.enabled = true;
 13.1093 +
 13.1094 +                //Set flag mentioning that the module is enabling,
 13.1095 +                //so that immediate calls to the defined callbacks
 13.1096 +                //for dependencies do not trigger inadvertent load
 13.1097 +                //with the depCount still being zero.
 13.1098 +                this.enabling = true;
 13.1099 +
 13.1100 +                //Enable each dependency
 13.1101 +                each(this.depMaps, bind(this, function (depMap, i) {
 13.1102 +                    var id, mod, handler;
 13.1103 +
 13.1104 +                    if (typeof depMap === 'string') {
 13.1105 +                        //Dependency needs to be converted to a depMap
 13.1106 +                        //and wired up to this module.
 13.1107 +                        depMap = makeModuleMap(depMap,
 13.1108 +                                               (this.map.isDefine ? this.map : this.map.parentMap),
 13.1109 +                                               false,
 13.1110 +                                               !this.skipMap);
 13.1111 +                        this.depMaps[i] = depMap;
 13.1112 +
 13.1113 +                        handler = getOwn(handlers, depMap.id);
 13.1114 +
 13.1115 +                        if (handler) {
 13.1116 +                            this.depExports[i] = handler(this);
 13.1117 +                            return;
 13.1118 +                        }
 13.1119 +
 13.1120 +                        this.depCount += 1;
 13.1121 +
 13.1122 +                        on(depMap, 'defined', bind(this, function (depExports) {
 13.1123 +                            this.defineDep(i, depExports);
 13.1124 +                            this.check();
 13.1125 +                        }));
 13.1126 +
 13.1127 +                        if (this.errback) {
 13.1128 +                            on(depMap, 'error', bind(this, this.errback));
 13.1129 +                        }
 13.1130 +                    }
 13.1131 +
 13.1132 +                    id = depMap.id;
 13.1133 +                    mod = registry[id];
 13.1134 +
 13.1135 +                    //Skip special modules like 'require', 'exports', 'module'
 13.1136 +                    //Also, don't call enable if it is already enabled,
 13.1137 +                    //important in circular dependency cases.
 13.1138 +                    if (!hasProp(handlers, id) && mod && !mod.enabled) {
 13.1139 +                        context.enable(depMap, this);
 13.1140 +                    }
 13.1141 +                }));
 13.1142 +
 13.1143 +                //Enable each plugin that is used in
 13.1144 +                //a dependency
 13.1145 +                eachProp(this.pluginMaps, bind(this, function (pluginMap) {
 13.1146 +                    var mod = getOwn(registry, pluginMap.id);
 13.1147 +                    if (mod && !mod.enabled) {
 13.1148 +                        context.enable(pluginMap, this);
 13.1149 +                    }
 13.1150 +                }));
 13.1151 +
 13.1152 +                this.enabling = false;
 13.1153 +
 13.1154 +                this.check();
 13.1155 +            },
 13.1156 +
 13.1157 +            on: function (name, cb) {
 13.1158 +                var cbs = this.events[name];
 13.1159 +                if (!cbs) {
 13.1160 +                    cbs = this.events[name] = [];
 13.1161 +                }
 13.1162 +                cbs.push(cb);
 13.1163 +            },
 13.1164 +
 13.1165 +            emit: function (name, evt) {
 13.1166 +                each(this.events[name], function (cb) {
 13.1167 +                    cb(evt);
 13.1168 +                });
 13.1169 +                if (name === 'error') {
 13.1170 +                    //Now that the error handler was triggered, remove
 13.1171 +                    //the listeners, since this broken Module instance
 13.1172 +                    //can stay around for a while in the registry.
 13.1173 +                    delete this.events[name];
 13.1174 +                }
 13.1175 +            }
 13.1176 +        };
 13.1177 +
 13.1178 +        function callGetModule(args) {
 13.1179 +            //Skip modules already defined.
 13.1180 +            if (!hasProp(defined, args[0])) {
 13.1181 +                getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
 13.1182 +            }
 13.1183 +        }
 13.1184 +
 13.1185 +        function removeListener(node, func, name, ieName) {
 13.1186 +            //Favor detachEvent because of IE9
 13.1187 +            //issue, see attachEvent/addEventListener comment elsewhere
 13.1188 +            //in this file.
 13.1189 +            if (node.detachEvent && !isOpera) {
 13.1190 +                //Probably IE. If not it will throw an error, which will be
 13.1191 +                //useful to know.
 13.1192 +                if (ieName) {
 13.1193 +                    node.detachEvent(ieName, func);
 13.1194 +                }
 13.1195 +            } else {
 13.1196 +                node.removeEventListener(name, func, false);
 13.1197 +            }
 13.1198 +        }
 13.1199 +
 13.1200 +        /**
 13.1201 +         * Given an event from a script node, get the requirejs info from it,
 13.1202 +         * and then removes the event listeners on the node.
 13.1203 +         * @param {Event} evt
 13.1204 +         * @returns {Object}
 13.1205 +         */
 13.1206 +        function getScriptData(evt) {
 13.1207 +            //Using currentTarget instead of target for Firefox 2.0's sake. Not
 13.1208 +            //all old browsers will be supported, but this one was easy enough
 13.1209 +            //to support and still makes sense.
 13.1210 +            var node = evt.currentTarget || evt.srcElement;
 13.1211 +
 13.1212 +            //Remove the listeners once here.
 13.1213 +            removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
 13.1214 +            removeListener(node, context.onScriptError, 'error');
 13.1215 +
 13.1216 +            return {
 13.1217 +                node: node,
 13.1218 +                id: node && node.getAttribute('data-requiremodule')
 13.1219 +            };
 13.1220 +        }
 13.1221 +
 13.1222 +        function intakeDefines() {
 13.1223 +            var args;
 13.1224 +
 13.1225 +            //Any defined modules in the global queue, intake them now.
 13.1226 +            takeGlobalQueue();
 13.1227 +
 13.1228 +            //Make sure any remaining defQueue items get properly processed.
 13.1229 +            while (defQueue.length) {
 13.1230 +                args = defQueue.shift();
 13.1231 +                if (args[0] === null) {
 13.1232 +                    return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
 13.1233 +                } else {
 13.1234 +                    //args are id, deps, factory. Should be normalized by the
 13.1235 +                    //define() function.
 13.1236 +                    callGetModule(args);
 13.1237 +                }
 13.1238 +            }
 13.1239 +        }
 13.1240 +
 13.1241 +        context = {
 13.1242 +            config: config,
 13.1243 +            contextName: contextName,
 13.1244 +            registry: registry,
 13.1245 +            defined: defined,
 13.1246 +            urlFetched: urlFetched,
 13.1247 +            defQueue: defQueue,
 13.1248 +            Module: Module,
 13.1249 +            makeModuleMap: makeModuleMap,
 13.1250 +            nextTick: req.nextTick,
 13.1251 +            onError: onError,
 13.1252 +
 13.1253 +            /**
 13.1254 +             * Set a configuration for the context.
 13.1255 +             * @param {Object} cfg config object to integrate.
 13.1256 +             */
 13.1257 +            configure: function (cfg) {
 13.1258 +                //Make sure the baseUrl ends in a slash.
 13.1259 +                if (cfg.baseUrl) {
 13.1260 +                    if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
 13.1261 +                        cfg.baseUrl += '/';
 13.1262 +                    }
 13.1263 +                }
 13.1264 +
 13.1265 +                //Save off the paths since they require special processing,
 13.1266 +                //they are additive.
 13.1267 +                var shim = config.shim,
 13.1268 +                    objs = {
 13.1269 +                        paths: true,
 13.1270 +                        bundles: true,
 13.1271 +                        config: true,
 13.1272 +                        map: true
 13.1273 +                    };
 13.1274 +
 13.1275 +                eachProp(cfg, function (value, prop) {
 13.1276 +                    if (objs[prop]) {
 13.1277 +                        if (!config[prop]) {
 13.1278 +                            config[prop] = {};
 13.1279 +                        }
 13.1280 +                        mixin(config[prop], value, true, true);
 13.1281 +                    } else {
 13.1282 +                        config[prop] = value;
 13.1283 +                    }
 13.1284 +                });
 13.1285 +
 13.1286 +                //Reverse map the bundles
 13.1287 +                if (cfg.bundles) {
 13.1288 +                    eachProp(cfg.bundles, function (value, prop) {
 13.1289 +                        each(value, function (v) {
 13.1290 +                            if (v !== prop) {
 13.1291 +                                bundlesMap[v] = prop;
 13.1292 +                            }
 13.1293 +                        });
 13.1294 +                    });
 13.1295 +                }
 13.1296 +
 13.1297 +                //Merge shim
 13.1298 +                if (cfg.shim) {
 13.1299 +                    eachProp(cfg.shim, function (value, id) {
 13.1300 +                        //Normalize the structure
 13.1301 +                        if (isArray(value)) {
 13.1302 +                            value = {
 13.1303 +                                deps: value
 13.1304 +                            };
 13.1305 +                        }
 13.1306 +                        if ((value.exports || value.init) && !value.exportsFn) {
 13.1307 +                            value.exportsFn = context.makeShimExports(value);
 13.1308 +                        }
 13.1309 +                        shim[id] = value;
 13.1310 +                    });
 13.1311 +                    config.shim = shim;
 13.1312 +                }
 13.1313 +
 13.1314 +                //Adjust packages if necessary.
 13.1315 +                if (cfg.packages) {
 13.1316 +                    each(cfg.packages, function (pkgObj) {
 13.1317 +                        var location, name;
 13.1318 +
 13.1319 +                        pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
 13.1320 +
 13.1321 +                        name = pkgObj.name;
 13.1322 +                        location = pkgObj.location;
 13.1323 +                        if (location) {
 13.1324 +                            config.paths[name] = pkgObj.location;
 13.1325 +                        }
 13.1326 +
 13.1327 +                        //Save pointer to main module ID for pkg name.
 13.1328 +                        //Remove leading dot in main, so main paths are normalized,
 13.1329 +                        //and remove any trailing .js, since different package
 13.1330 +                        //envs have different conventions: some use a module name,
 13.1331 +                        //some use a file name.
 13.1332 +                        config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
 13.1333 +                                     .replace(currDirRegExp, '')
 13.1334 +                                     .replace(jsSuffixRegExp, '');
 13.1335 +                    });
 13.1336 +                }
 13.1337 +
 13.1338 +                //If there are any "waiting to execute" modules in the registry,
 13.1339 +                //update the maps for them, since their info, like URLs to load,
 13.1340 +                //may have changed.
 13.1341 +                eachProp(registry, function (mod, id) {
 13.1342 +                    //If module already has init called, since it is too
 13.1343 +                    //late to modify them, and ignore unnormalized ones
 13.1344 +                    //since they are transient.
 13.1345 +                    if (!mod.inited && !mod.map.unnormalized) {
 13.1346 +                        mod.map = makeModuleMap(id);
 13.1347 +                    }
 13.1348 +                });
 13.1349 +
 13.1350 +                //If a deps array or a config callback is specified, then call
 13.1351 +                //require with those args. This is useful when require is defined as a
 13.1352 +                //config object before require.js is loaded.
 13.1353 +                if (cfg.deps || cfg.callback) {
 13.1354 +                    context.require(cfg.deps || [], cfg.callback);
 13.1355 +                }
 13.1356 +            },
 13.1357 +
 13.1358 +            makeShimExports: function (value) {
 13.1359 +                function fn() {
 13.1360 +                    var ret;
 13.1361 +                    if (value.init) {
 13.1362 +                        ret = value.init.apply(global, arguments);
 13.1363 +                    }
 13.1364 +                    return ret || (value.exports && getGlobal(value.exports));
 13.1365 +                }
 13.1366 +                return fn;
 13.1367 +            },
 13.1368 +
 13.1369 +            makeRequire: function (relMap, options) {
 13.1370 +                options = options || {};
 13.1371 +
 13.1372 +                function localRequire(deps, callback, errback) {
 13.1373 +                    var id, map, requireMod;
 13.1374 +
 13.1375 +                    if (options.enableBuildCallback && callback && isFunction(callback)) {
 13.1376 +                        callback.__requireJsBuild = true;
 13.1377 +                    }
 13.1378 +
 13.1379 +                    if (typeof deps === 'string') {
 13.1380 +                        if (isFunction(callback)) {
 13.1381 +                            //Invalid call
 13.1382 +                            return onError(makeError('requireargs', 'Invalid require call'), errback);
 13.1383 +                        }
 13.1384 +
 13.1385 +                        //If require|exports|module are requested, get the
 13.1386 +                        //value for them from the special handlers. Caveat:
 13.1387 +                        //this only works while module is being defined.
 13.1388 +                        if (relMap && hasProp(handlers, deps)) {
 13.1389 +                            return handlers[deps](registry[relMap.id]);
 13.1390 +                        }
 13.1391 +
 13.1392 +                        //Synchronous access to one module. If require.get is
 13.1393 +                        //available (as in the Node adapter), prefer that.
 13.1394 +                        if (req.get) {
 13.1395 +                            return req.get(context, deps, relMap, localRequire);
 13.1396 +                        }
 13.1397 +
 13.1398 +                        //Normalize module name, if it contains . or ..
 13.1399 +                        map = makeModuleMap(deps, relMap, false, true);
 13.1400 +                        id = map.id;
 13.1401 +
 13.1402 +                        if (!hasProp(defined, id)) {
 13.1403 +                            return onError(makeError('notloaded', 'Module name "' +
 13.1404 +                                        id +
 13.1405 +                                        '" has not been loaded yet for context: ' +
 13.1406 +                                        contextName +
 13.1407 +                                        (relMap ? '' : '. Use require([])')));
 13.1408 +                        }
 13.1409 +                        return defined[id];
 13.1410 +                    }
 13.1411 +
 13.1412 +                    //Grab defines waiting in the global queue.
 13.1413 +                    intakeDefines();
 13.1414 +
 13.1415 +                    //Mark all the dependencies as needing to be loaded.
 13.1416 +                    context.nextTick(function () {
 13.1417 +                        //Some defines could have been added since the
 13.1418 +                        //require call, collect them.
 13.1419 +                        intakeDefines();
 13.1420 +
 13.1421 +                        requireMod = getModule(makeModuleMap(null, relMap));
 13.1422 +
 13.1423 +                        //Store if map config should be applied to this require
 13.1424 +                        //call for dependencies.
 13.1425 +                        requireMod.skipMap = options.skipMap;
 13.1426 +
 13.1427 +                        requireMod.init(deps, callback, errback, {
 13.1428 +                            enabled: true
 13.1429 +                        });
 13.1430 +
 13.1431 +                        checkLoaded();
 13.1432 +                    });
 13.1433 +
 13.1434 +                    return localRequire;
 13.1435 +                }
 13.1436 +
 13.1437 +                mixin(localRequire, {
 13.1438 +                    isBrowser: isBrowser,
 13.1439 +
 13.1440 +                    /**
 13.1441 +                     * Converts a module name + .extension into an URL path.
 13.1442 +                     * *Requires* the use of a module name. It does not support using
 13.1443 +                     * plain URLs like nameToUrl.
 13.1444 +                     */
 13.1445 +                    toUrl: function (moduleNamePlusExt) {
 13.1446 +                        var ext,
 13.1447 +                            index = moduleNamePlusExt.lastIndexOf('.'),
 13.1448 +                            segment = moduleNamePlusExt.split('/')[0],
 13.1449 +                            isRelative = segment === '.' || segment === '..';
 13.1450 +
 13.1451 +                        //Have a file extension alias, and it is not the
 13.1452 +                        //dots from a relative path.
 13.1453 +                        if (index !== -1 && (!isRelative || index > 1)) {
 13.1454 +                            ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
 13.1455 +                            moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
 13.1456 +                        }
 13.1457 +
 13.1458 +                        return context.nameToUrl(normalize(moduleNamePlusExt,
 13.1459 +                                                relMap && relMap.id, true), ext,  true);
 13.1460 +                    },
 13.1461 +
 13.1462 +                    defined: function (id) {
 13.1463 +                        return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
 13.1464 +                    },
 13.1465 +
 13.1466 +                    specified: function (id) {
 13.1467 +                        id = makeModuleMap(id, relMap, false, true).id;
 13.1468 +                        return hasProp(defined, id) || hasProp(registry, id);
 13.1469 +                    }
 13.1470 +                });
 13.1471 +
 13.1472 +                //Only allow undef on top level require calls
 13.1473 +                if (!relMap) {
 13.1474 +                    localRequire.undef = function (id) {
 13.1475 +                        //Bind any waiting define() calls to this context,
 13.1476 +                        //fix for #408
 13.1477 +                        takeGlobalQueue();
 13.1478 +
 13.1479 +                        var map = makeModuleMap(id, relMap, true),
 13.1480 +                            mod = getOwn(registry, id);
 13.1481 +
 13.1482 +                        removeScript(id);
 13.1483 +
 13.1484 +                        delete defined[id];
 13.1485 +                        delete urlFetched[map.url];
 13.1486 +                        delete undefEvents[id];
 13.1487 +
 13.1488 +                        //Clean queued defines too. Go backwards
 13.1489 +                        //in array so that the splices do not
 13.1490 +                        //mess up the iteration.
 13.1491 +                        eachReverse(defQueue, function(args, i) {
 13.1492 +                            if(args[0] === id) {
 13.1493 +                                defQueue.splice(i, 1);
 13.1494 +                            }
 13.1495 +                        });
 13.1496 +
 13.1497 +                        if (mod) {
 13.1498 +                            //Hold on to listeners in case the
 13.1499 +                            //module will be attempted to be reloaded
 13.1500 +                            //using a different config.
 13.1501 +                            if (mod.events.defined) {
 13.1502 +                                undefEvents[id] = mod.events;
 13.1503 +                            }
 13.1504 +
 13.1505 +                            cleanRegistry(id);
 13.1506 +                        }
 13.1507 +                    };
 13.1508 +                }
 13.1509 +
 13.1510 +                return localRequire;
 13.1511 +            },
 13.1512 +
 13.1513 +            /**
 13.1514 +             * Called to enable a module if it is still in the registry
 13.1515 +             * awaiting enablement. A second arg, parent, the parent module,
 13.1516 +             * is passed in for context, when this method is overridden by
 13.1517 +             * the optimizer. Not shown here to keep code compact.
 13.1518 +             */
 13.1519 +            enable: function (depMap) {
 13.1520 +                var mod = getOwn(registry, depMap.id);
 13.1521 +                if (mod) {
 13.1522 +                    getModule(depMap).enable();
 13.1523 +                }
 13.1524 +            },
 13.1525 +
 13.1526 +            /**
 13.1527 +             * Internal method used by environment adapters to complete a load event.
 13.1528 +             * A load event could be a script load or just a load pass from a synchronous
 13.1529 +             * load call.
 13.1530 +             * @param {String} moduleName the name of the module to potentially complete.
 13.1531 +             */
 13.1532 +            completeLoad: function (moduleName) {
 13.1533 +                var found, args, mod,
 13.1534 +                    shim = getOwn(config.shim, moduleName) || {},
 13.1535 +                    shExports = shim.exports;
 13.1536 +
 13.1537 +                takeGlobalQueue();
 13.1538 +
 13.1539 +                while (defQueue.length) {
 13.1540 +                    args = defQueue.shift();
 13.1541 +                    if (args[0] === null) {
 13.1542 +                        args[0] = moduleName;
 13.1543 +                        //If already found an anonymous module and bound it
 13.1544 +                        //to this name, then this is some other anon module
 13.1545 +                        //waiting for its completeLoad to fire.
 13.1546 +                        if (found) {
 13.1547 +                            break;
 13.1548 +                        }
 13.1549 +                        found = true;
 13.1550 +                    } else if (args[0] === moduleName) {
 13.1551 +                        //Found matching define call for this script!
 13.1552 +                        found = true;
 13.1553 +                    }
 13.1554 +
 13.1555 +                    callGetModule(args);
 13.1556 +                }
 13.1557 +
 13.1558 +                //Do this after the cycle of callGetModule in case the result
 13.1559 +                //of those calls/init calls changes the registry.
 13.1560 +                mod = getOwn(registry, moduleName);
 13.1561 +
 13.1562 +                if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
 13.1563 +                    if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
 13.1564 +                        if (hasPathFallback(moduleName)) {
 13.1565 +                            return;
 13.1566 +                        } else {
 13.1567 +                            return onError(makeError('nodefine',
 13.1568 +                                             'No define call for ' + moduleName,
 13.1569 +                                             null,
 13.1570 +                                             [moduleName]));
 13.1571 +                        }
 13.1572 +                    } else {
 13.1573 +                        //A script that does not call define(), so just simulate
 13.1574 +                        //the call for it.
 13.1575 +                        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
 13.1576 +                    }
 13.1577 +                }
 13.1578 +
 13.1579 +                checkLoaded();
 13.1580 +            },
 13.1581 +
 13.1582 +            /**
 13.1583 +             * Converts a module name to a file path. Supports cases where
 13.1584 +             * moduleName may actually be just an URL.
 13.1585 +             * Note that it **does not** call normalize on the moduleName,
 13.1586 +             * it is assumed to have already been normalized. This is an
 13.1587 +             * internal API, not a public one. Use toUrl for the public API.
 13.1588 +             */
 13.1589 +            nameToUrl: function (moduleName, ext, skipExt) {
 13.1590 +                var paths, syms, i, parentModule, url,
 13.1591 +                    parentPath, bundleId,
 13.1592 +                    pkgMain = getOwn(config.pkgs, moduleName);
 13.1593 +
 13.1594 +                if (pkgMain) {
 13.1595 +                    moduleName = pkgMain;
 13.1596 +                }
 13.1597 +
 13.1598 +                bundleId = getOwn(bundlesMap, moduleName);
 13.1599 +
 13.1600 +                if (bundleId) {
 13.1601 +                    return context.nameToUrl(bundleId, ext, skipExt);
 13.1602 +                }
 13.1603 +
 13.1604 +                //If a colon is in the URL, it indicates a protocol is used and it is just
 13.1605 +                //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
 13.1606 +                //or ends with .js, then assume the user meant to use an url and not a module id.
 13.1607 +                //The slash is important for protocol-less URLs as well as full paths.
 13.1608 +                if (req.jsExtRegExp.test(moduleName)) {
 13.1609 +                    //Just a plain path, not module name lookup, so just return it.
 13.1610 +                    //Add extension if it is included. This is a bit wonky, only non-.js things pass
 13.1611 +                    //an extension, this method probably needs to be reworked.
 13.1612 +                    url = moduleName + (ext || '');
 13.1613 +                } else {
 13.1614 +                    //A module that needs to be converted to a path.
 13.1615 +                    paths = config.paths;
 13.1616 +
 13.1617 +                    syms = moduleName.split('/');
 13.1618 +                    //For each module name segment, see if there is a path
 13.1619 +                    //registered for it. Start with most specific name
 13.1620 +                    //and work up from it.
 13.1621 +                    for (i = syms.length; i > 0; i -= 1) {
 13.1622 +                        parentModule = syms.slice(0, i).join('/');
 13.1623 +
 13.1624 +                        parentPath = getOwn(paths, parentModule);
 13.1625 +                        if (parentPath) {
 13.1626 +                            //If an array, it means there are a few choices,
 13.1627 +                            //Choose the one that is desired
 13.1628 +                            if (isArray(parentPath)) {
 13.1629 +                                parentPath = parentPath[0];
 13.1630 +                            }
 13.1631 +                            syms.splice(0, i, parentPath);
 13.1632 +                            break;
 13.1633 +                        }
 13.1634 +                    }
 13.1635 +
 13.1636 +                    //Join the path parts together, then figure out if baseUrl is needed.
 13.1637 +                    url = syms.join('/');
 13.1638 +                    url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js'));
 13.1639 +                    url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
 13.1640 +                }
 13.1641 +
 13.1642 +                return config.urlArgs ? url +
 13.1643 +                                        ((url.indexOf('?') === -1 ? '?' : '&') +
 13.1644 +                                         config.urlArgs) : url;
 13.1645 +            },
 13.1646 +
 13.1647 +            //Delegates to req.load. Broken out as a separate function to
 13.1648 +            //allow overriding in the optimizer.
 13.1649 +            load: function (id, url) {
 13.1650 +                req.load(context, id, url);
 13.1651 +            },
 13.1652 +
 13.1653 +            /**
 13.1654 +             * Executes a module callback function. Broken out as a separate function
 13.1655 +             * solely to allow the build system to sequence the files in the built
 13.1656 +             * layer in the right sequence.
 13.1657 +             *
 13.1658 +             * @private
 13.1659 +             */
 13.1660 +            execCb: function (name, callback, args, exports) {
 13.1661 +                return callback.apply(exports, args);
 13.1662 +            },
 13.1663 +
 13.1664 +            /**
 13.1665 +             * callback for script loads, used to check status of loading.
 13.1666 +             *
 13.1667 +             * @param {Event} evt the event from the browser for the script
 13.1668 +             * that was loaded.
 13.1669 +             */
 13.1670 +            onScriptLoad: function (evt) {
 13.1671 +                //Using currentTarget instead of target for Firefox 2.0's sake. Not
 13.1672 +                //all old browsers will be supported, but this one was easy enough
 13.1673 +                //to support and still makes sense.
 13.1674 +                if (evt.type === 'load' ||
 13.1675 +                        (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
 13.1676 +                    //Reset interactive script so a script node is not held onto for
 13.1677 +                    //to long.
 13.1678 +                    interactiveScript = null;
 13.1679 +
 13.1680 +                    //Pull out the name of the module and the context.
 13.1681 +                    var data = getScriptData(evt);
 13.1682 +                    context.completeLoad(data.id);
 13.1683 +                }
 13.1684 +            },
 13.1685 +
 13.1686 +            /**
 13.1687 +             * Callback for script errors.
 13.1688 +             */
 13.1689 +            onScriptError: function (evt) {
 13.1690 +                var data = getScriptData(evt);
 13.1691 +                if (!hasPathFallback(data.id)) {
 13.1692 +                    return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
 13.1693 +                }
 13.1694 +            }
 13.1695 +        };
 13.1696 +
 13.1697 +        context.require = context.makeRequire();
 13.1698 +        return context;
 13.1699 +    }
 13.1700 +
 13.1701 +    /**
 13.1702 +     * Main entry point.
 13.1703 +     *
 13.1704 +     * If the only argument to require is a string, then the module that
 13.1705 +     * is represented by that string is fetched for the appropriate context.
 13.1706 +     *
 13.1707 +     * If the first argument is an array, then it will be treated as an array
 13.1708 +     * of dependency string names to fetch. An optional function callback can
 13.1709 +     * be specified to execute when all of those dependencies are available.
 13.1710 +     *
 13.1711 +     * Make a local req variable to help Caja compliance (it assumes things
 13.1712 +     * on a require that are not standardized), and to give a short
 13.1713 +     * name for minification/local scope use.
 13.1714 +     */
 13.1715 +    req = requirejs = function (deps, callback, errback, optional) {
 13.1716 +
 13.1717 +        //Find the right context, use default
 13.1718 +        var context, config,
 13.1719 +            contextName = defContextName;
 13.1720 +
 13.1721 +        // Determine if have config object in the call.
 13.1722 +        if (!isArray(deps) && typeof deps !== 'string') {
 13.1723 +            // deps is a config object
 13.1724 +            config = deps;
 13.1725 +            if (isArray(callback)) {
 13.1726 +                // Adjust args if there are dependencies
 13.1727 +                deps = callback;
 13.1728 +                callback = errback;
 13.1729 +                errback = optional;
 13.1730 +            } else {
 13.1731 +                deps = [];
 13.1732 +            }
 13.1733 +        }
 13.1734 +
 13.1735 +        if (config && config.context) {
 13.1736 +            contextName = config.context;
 13.1737 +        }
 13.1738 +
 13.1739 +        context = getOwn(contexts, contextName);
 13.1740 +        if (!context) {
 13.1741 +            context = contexts[contextName] = req.s.newContext(contextName);
 13.1742 +        }
 13.1743 +
 13.1744 +        if (config) {
 13.1745 +            context.configure(config);
 13.1746 +        }
 13.1747 +
 13.1748 +        return context.require(deps, callback, errback);
 13.1749 +    };
 13.1750 +
 13.1751 +    /**
 13.1752 +     * Support require.config() to make it easier to cooperate with other
 13.1753 +     * AMD loaders on globally agreed names.
 13.1754 +     */
 13.1755 +    req.config = function (config) {
 13.1756 +        return req(config);
 13.1757 +    };
 13.1758 +
 13.1759 +    /**
 13.1760 +     * Execute something after the current tick
 13.1761 +     * of the event loop. Override for other envs
 13.1762 +     * that have a better solution than setTimeout.
 13.1763 +     * @param  {Function} fn function to execute later.
 13.1764 +     */
 13.1765 +    req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
 13.1766 +        setTimeout(fn, 4);
 13.1767 +    } : function (fn) { fn(); };
 13.1768 +
 13.1769 +    /**
 13.1770 +     * Export require as a global, but only if it does not already exist.
 13.1771 +     */
 13.1772 +    if (!require) {
 13.1773 +        require = req;
 13.1774 +    }
 13.1775 +
 13.1776 +    req.version = version;
 13.1777 +
 13.1778 +    //Used to filter out dependencies that are already paths.
 13.1779 +    req.jsExtRegExp = /^\/|:|\?|\.js$/;
 13.1780 +    req.isBrowser = isBrowser;
 13.1781 +    s = req.s = {
 13.1782 +        contexts: contexts,
 13.1783 +        newContext: newContext
 13.1784 +    };
 13.1785 +
 13.1786 +    //Create default context.
 13.1787 +    req({});
 13.1788 +
 13.1789 +    //Exports some context-sensitive methods on global require.
 13.1790 +    each([
 13.1791 +        'toUrl',
 13.1792 +        'undef',
 13.1793 +        'defined',
 13.1794 +        'specified'
 13.1795 +    ], function (prop) {
 13.1796 +        //Reference from contexts instead of early binding to default context,
 13.1797 +        //so that during builds, the latest instance of the default context
 13.1798 +        //with its config gets used.
 13.1799 +        req[prop] = function () {
 13.1800 +            var ctx = contexts[defContextName];
 13.1801 +            return ctx.require[prop].apply(ctx, arguments);
 13.1802 +        };
 13.1803 +    });
 13.1804 +
 13.1805 +    if (isBrowser) {
 13.1806 +        head = s.head = document.getElementsByTagName('head')[0];
 13.1807 +        //If BASE tag is in play, using appendChild is a problem for IE6.
 13.1808 +        //When that browser dies, this can be removed. Details in this jQuery bug:
 13.1809 +        //http://dev.jquery.com/ticket/2709
 13.1810 +        baseElement = document.getElementsByTagName('base')[0];
 13.1811 +        if (baseElement) {
 13.1812 +            head = s.head = baseElement.parentNode;
 13.1813 +        }
 13.1814 +    }
 13.1815 +
 13.1816 +    /**
 13.1817 +     * Any errors that require explicitly generates will be passed to this
 13.1818 +     * function. Intercept/override it if you want custom error handling.
 13.1819 +     * @param {Error} err the error object.
 13.1820 +     */
 13.1821 +    req.onError = defaultOnError;
 13.1822 +
 13.1823 +    /**
 13.1824 +     * Creates the node for the load command. Only used in browser envs.
 13.1825 +     */
 13.1826 +    req.createNode = function (config, moduleName, url) {
 13.1827 +        var node = config.xhtml ?
 13.1828 +                document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
 13.1829 +                document.createElement('script');
 13.1830 +        node.type = config.scriptType || 'text/javascript';
 13.1831 +        node.charset = 'utf-8';
 13.1832 +        node.async = true;
 13.1833 +        return node;
 13.1834 +    };
 13.1835 +
 13.1836 +    /**
 13.1837 +     * Does the request to load a module for the browser case.
 13.1838 +     * Make this a separate function to allow other environments
 13.1839 +     * to override it.
 13.1840 +     *
 13.1841 +     * @param {Object} context the require context to find state.
 13.1842 +     * @param {String} moduleName the name of the module.
 13.1843 +     * @param {Object} url the URL to the module.
 13.1844 +     */
 13.1845 +    req.load = function (context, moduleName, url) {
 13.1846 +        var config = (context && context.config) || {},
 13.1847 +            node;
 13.1848 +        if (isBrowser) {
 13.1849 +            //In the browser so use a script tag
 13.1850 +            node = req.createNode(config, moduleName, url);
 13.1851 +
 13.1852 +            node.setAttribute('data-requirecontext', context.contextName);
 13.1853 +            node.setAttribute('data-requiremodule', moduleName);
 13.1854 +
 13.1855 +            //Set up load listener. Test attachEvent first because IE9 has
 13.1856 +            //a subtle issue in its addEventListener and script onload firings
 13.1857 +            //that do not match the behavior of all other browsers with
 13.1858 +            //addEventListener support, which fire the onload event for a
 13.1859 +            //script right after the script execution. See:
 13.1860 +            //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
 13.1861 +            //UNFORTUNATELY Opera implements attachEvent but does not follow the script
 13.1862 +            //script execution mode.
 13.1863 +            if (node.attachEvent &&
 13.1864 +                    //Check if node.attachEvent is artificially added by custom script or
 13.1865 +                    //natively supported by browser
 13.1866 +                    //read https://github.com/jrburke/requirejs/issues/187
 13.1867 +                    //if we can NOT find [native code] then it must NOT natively supported.
 13.1868 +                    //in IE8, node.attachEvent does not have toString()
 13.1869 +                    //Note the test for "[native code" with no closing brace, see:
 13.1870 +                    //https://github.com/jrburke/requirejs/issues/273
 13.1871 +                    !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
 13.1872 +                    !isOpera) {
 13.1873 +                //Probably IE. IE (at least 6-8) do not fire
 13.1874 +                //script onload right after executing the script, so
 13.1875 +                //we cannot tie the anonymous define call to a name.
 13.1876 +                //However, IE reports the script as being in 'interactive'
 13.1877 +                //readyState at the time of the define call.
 13.1878 +                useInteractive = true;
 13.1879 +
 13.1880 +                node.attachEvent('onreadystatechange', context.onScriptLoad);
 13.1881 +                //It would be great to add an error handler here to catch
 13.1882 +                //404s in IE9+. However, onreadystatechange will fire before
 13.1883 +                //the error handler, so that does not help. If addEventListener
 13.1884 +                //is used, then IE will fire error before load, but we cannot
 13.1885 +                //use that pathway given the connect.microsoft.com issue
 13.1886 +                //mentioned above about not doing the 'script execute,
 13.1887 +                //then fire the script load event listener before execute
 13.1888 +                //next script' that other browsers do.
 13.1889 +                //Best hope: IE10 fixes the issues,
 13.1890 +                //and then destroys all installs of IE 6-9.
 13.1891 +                //node.attachEvent('onerror', context.onScriptError);
 13.1892 +            } else {
 13.1893 +                node.addEventListener('load', context.onScriptLoad, false);
 13.1894 +                node.addEventListener('error', context.onScriptError, false);
 13.1895 +            }
 13.1896 +            node.src = url;
 13.1897 +
 13.1898 +            //For some cache cases in IE 6-8, the script executes before the end
 13.1899 +            //of the appendChild execution, so to tie an anonymous define
 13.1900 +            //call to the module name (which is stored on the node), hold on
 13.1901 +            //to a reference to this node, but clear after the DOM insertion.
 13.1902 +            currentlyAddingScript = node;
 13.1903 +            if (baseElement) {
 13.1904 +                head.insertBefore(node, baseElement);
 13.1905 +            } else {
 13.1906 +                head.appendChild(node);
 13.1907 +            }
 13.1908 +            currentlyAddingScript = null;
 13.1909 +
 13.1910 +            return node;
 13.1911 +        } else if (isWebWorker) {
 13.1912 +            try {
 13.1913 +                //In a web worker, use importScripts. This is not a very
 13.1914 +                //efficient use of importScripts, importScripts will block until
 13.1915 +                //its script is downloaded and evaluated. However, if web workers
 13.1916 +                //are in play, the expectation that a build has been done so that
 13.1917 +                //only one script needs to be loaded anyway. This may need to be
 13.1918 +                //reevaluated if other use cases become common.
 13.1919 +                importScripts(url);
 13.1920 +
 13.1921 +                //Account for anonymous modules
 13.1922 +                context.completeLoad(moduleName);
 13.1923 +            } catch (e) {
 13.1924 +                context.onError(makeError('importscripts',
 13.1925 +                                'importScripts failed for ' +
 13.1926 +                                    moduleName + ' at ' + url,
 13.1927 +                                e,
 13.1928 +                                [moduleName]));
 13.1929 +            }
 13.1930 +        }
 13.1931 +    };
 13.1932 +
 13.1933 +    function getInteractiveScript() {
 13.1934 +        if (interactiveScript && interactiveScript.readyState === 'interactive') {
 13.1935 +            return interactiveScript;
 13.1936 +        }
 13.1937 +
 13.1938 +        eachReverse(scripts(), function (script) {
 13.1939 +            if (script.readyState === 'interactive') {
 13.1940 +                return (interactiveScript = script);
 13.1941 +            }
 13.1942 +        });
 13.1943 +        return interactiveScript;
 13.1944 +    }
 13.1945 +
 13.1946 +    //Look for a data-main script attribute, which could also adjust the baseUrl.
 13.1947 +    if (isBrowser && !cfg.skipDataMain) {
 13.1948 +        //Figure out baseUrl. Get it from the script tag with require.js in it.
 13.1949 +        eachReverse(scripts(), function (script) {
 13.1950 +            //Set the 'head' where we can append children by
 13.1951 +            //using the script's parent.
 13.1952 +            if (!head) {
 13.1953 +                head = script.parentNode;
 13.1954 +            }
 13.1955 +
 13.1956 +            //Look for a data-main attribute to set main script for the page
 13.1957 +            //to load. If it is there, the path to data main becomes the
 13.1958 +            //baseUrl, if it is not already set.
 13.1959 +            dataMain = script.getAttribute('data-main');
 13.1960 +            if (dataMain) {
 13.1961 +                //Preserve dataMain in case it is a path (i.e. contains '?')
 13.1962 +                mainScript = dataMain;
 13.1963 +
 13.1964 +                //Set final baseUrl if there is not already an explicit one.
 13.1965 +                if (!cfg.baseUrl) {
 13.1966 +                    //Pull off the directory of data-main for use as the
 13.1967 +                    //baseUrl.
 13.1968 +                    src = mainScript.split('/');
 13.1969 +                    mainScript = src.pop();
 13.1970 +                    subPath = src.length ? src.join('/')  + '/' : './';
 13.1971 +
 13.1972 +                    cfg.baseUrl = subPath;
 13.1973 +                }
 13.1974 +
 13.1975 +                //Strip off any trailing .js since mainScript is now
 13.1976 +                //like a module name.
 13.1977 +                mainScript = mainScript.replace(jsSuffixRegExp, '');
 13.1978 +
 13.1979 +                 //If mainScript is still a path, fall back to dataMain
 13.1980 +                if (req.jsExtRegExp.test(mainScript)) {
 13.1981 +                    mainScript = dataMain;
 13.1982 +                }
 13.1983 +
 13.1984 +                //Put the data-main script in the files to load.
 13.1985 +                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
 13.1986 +
 13.1987 +                return true;
 13.1988 +            }
 13.1989 +        });
 13.1990 +    }
 13.1991 +
 13.1992 +    /**
 13.1993 +     * The function that handles definitions of modules. Differs from
 13.1994 +     * require() in that a string for the module should be the first argument,
 13.1995 +     * and the function to execute after dependencies are loaded should
 13.1996 +     * return a value to define the module corresponding to the first argument's
 13.1997 +     * name.
 13.1998 +     */
 13.1999 +    define = function (name, deps, callback) {
 13.2000 +        var node, context;
 13.2001 +
 13.2002 +        //Allow for anonymous modules
 13.2003 +        if (typeof name !== 'string') {
 13.2004 +            //Adjust args appropriately
 13.2005 +            callback = deps;
 13.2006 +            deps = name;
 13.2007 +            name = null;
 13.2008 +        }
 13.2009 +
 13.2010 +        //This module may not have dependencies
 13.2011 +        if (!isArray(deps)) {
 13.2012 +            callback = deps;
 13.2013 +            deps = null;
 13.2014 +        }
 13.2015 +
 13.2016 +        //If no name, and callback is a function, then figure out if it a
 13.2017 +        //CommonJS thing with dependencies.
 13.2018 +        if (!deps && isFunction(callback)) {
 13.2019 +            deps = [];
 13.2020 +            //Remove comments from the callback string,
 13.2021 +            //look for require calls, and pull them into the dependencies,
 13.2022 +            //but only if there are function args.
 13.2023 +            if (callback.length) {
 13.2024 +                callback
 13.2025 +                    .toString()
 13.2026 +                    .replace(commentRegExp, '')
 13.2027 +                    .replace(cjsRequireRegExp, function (match, dep) {
 13.2028 +                        deps.push(dep);
 13.2029 +                    });
 13.2030 +
 13.2031 +                //May be a CommonJS thing even without require calls, but still
 13.2032 +                //could use exports, and module. Avoid doing exports and module
 13.2033 +                //work though if it just needs require.
 13.2034 +                //REQUIRES the function to expect the CommonJS variables in the
 13.2035 +                //order listed below.
 13.2036 +                deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
 13.2037 +            }
 13.2038 +        }
 13.2039 +
 13.2040 +        //If in IE 6-8 and hit an anonymous define() call, do the interactive
 13.2041 +        //work.
 13.2042 +        if (useInteractive) {
 13.2043 +            node = currentlyAddingScript || getInteractiveScript();
 13.2044 +            if (node) {
 13.2045 +                if (!name) {
 13.2046 +                    name = node.getAttribute('data-requiremodule');
 13.2047 +                }
 13.2048 +                context = contexts[node.getAttribute('data-requirecontext')];
 13.2049 +            }
 13.2050 +        }
 13.2051 +
 13.2052 +        //Always save off evaluating the def call until the script onload handler.
 13.2053 +        //This allows multiple modules to be in a file without prematurely
 13.2054 +        //tracing dependencies, and allows for anonymous module support,
 13.2055 +        //where the module name is not known until the script onload event
 13.2056 +        //occurs. If no context, use the global queue, and get it processed
 13.2057 +        //in the onscript load callback.
 13.2058 +        (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
 13.2059 +    };
 13.2060 +
 13.2061 +    define.amd = {
 13.2062 +        jQuery: true
 13.2063 +    };
 13.2064 +
 13.2065 +
 13.2066 +    /**
 13.2067 +     * Executes the text. Normally just uses eval, but can be modified
 13.2068 +     * to use a better, environment-specific call. Only used for transpiling
 13.2069 +     * loader plugins, not for plain JS modules.
 13.2070 +     * @param {String} text the text to execute/evaluate.
 13.2071 +     */
 13.2072 +    req.exec = function (text) {
 13.2073 +        /*jslint evil: true */
 13.2074 +        return eval(text);
 13.2075 +    };
 13.2076 +
 13.2077 +    //Set up with config info.
 13.2078 +    req(cfg);
 13.2079 +}(this));
 13.2080 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation.js	Sun Jul 06 12:02:12 2014 -0700
    14.3 @@ -0,0 +1,167 @@
    14.4 +
    14.5 +
    14.6 +define(function(require, exports, module) {
    14.7 +    var Engine           = require("famous/core/Engine");
    14.8 +    var Surface          = require("famous/core/Surface");
    14.9 +    var Modifier         = require("famous/core/Modifier");
   14.10 +    var Transform = require('famous/core/Transform');
   14.11 +    var StateModifier = require('famous/modifiers/StateModifier');
   14.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   14.13 +    var Scrollview       = require("famous/views/Scrollview");
   14.14 +
   14.15 +    var mainContext = Engine.createContext();
   14.16 +	
   14.17 +	var boxSVG = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">';
   14.18 +	var sigmaSVG = '<svg width="500" height="1052.3622" id="svg2"> <g id="g3759"> <path  d="m 54,2 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" id="path2985" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 54,64 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" id="path3757" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> </g> </svg>';
   14.19 +
   14.20 +//Draw the summation symbol, with two boxes below and = sign between, and
   14.21 +// big box next to it, and small box above
   14.22 +//Approach taken:
   14.23 +//Make a container surface to hold the sigma and all the boxes
   14.24 +//Make a separate surface for each SVG element -- one for sigma, one for
   14.25 +// each box.  
   14.26 +//For each surface, make a modifier that positions the boxes
   14.27 +// relative to the sigma and scales the boxes appropriately
   14.28 +//Make all positions relative to the container surface's origin
   14.29 +
   14.30 +    var summationContainer = new ContainerSurface({
   14.31 +        size: [200, 200],
   14.32 +        properties: {
   14.33 +            overflow: 'hidden'
   14.34 +        }
   14.35 +    });
   14.36 +	var sigmaSurf = new Surface({
   14.37 +	  size: [100, 100],
   14.38 +      content: sigmaSVG,
   14.39 +      properties: {
   14.40 +      }
   14.41 +	});
   14.42 +	var box1 = new Surface({
   14.43 +	  size: [100, 100],
   14.44 +      content: boxSVG,
   14.45 +      properties: {
   14.46 +      }
   14.47 +	});
   14.48 +	var box2 = new Surface({
   14.49 +	  size: [100, 100],
   14.50 +      content: boxSVG,
   14.51 +      properties: {
   14.52 +      }
   14.53 +	});
   14.54 +	var box3 = new Surface({
   14.55 +	  size: [100, 100],
   14.56 +      content: boxSVG,
   14.57 +      properties: {
   14.58 +      }
   14.59 +	});
   14.60 +	var box4 = new Surface({
   14.61 +	  size: [100, 100],
   14.62 +      content: boxSVG,
   14.63 +      properties: {
   14.64 +      }
   14.65 +	});
   14.66 +	var equalSurf = new Surface({
   14.67 +	  size: [10, 10],
   14.68 +      content: "=",
   14.69 +      properties: {
   14.70 +      }
   14.71 +	});
   14.72 +	
   14.73 +	var sigmaMod1 = new StateModifier({
   14.74 +        transform: Transform.translate(0, 20, 0)
   14.75 +    });
   14.76 +//==
   14.77 +	var box1Mod1 = new StateModifier({
   14.78 +        transform: Transform.translate(7, 90, 0)
   14.79 +    });
   14.80 +	var box1Mod2 = new StateModifier({
   14.81 +		transform: Transform.scale(.3, .3)
   14.82 +    });
   14.83 +//==
   14.84 +	var box2Mod1 = new StateModifier({
   14.85 +        transform: Transform.translate(42, 90, 0)
   14.86 +    });
   14.87 +	var box2Mod2 = new StateModifier({
   14.88 +		transform: Transform.scale(.3, .3)
   14.89 +    });
   14.90 +//==
   14.91 +	var box3Mod1 = new StateModifier({
   14.92 +        transform: Transform.translate(42, 2, 0)
   14.93 +    });
   14.94 +	var box3Mod2 = new StateModifier({
   14.95 +		transform: Transform.scale(.3, .3)
   14.96 +    });
   14.97 +//==
   14.98 +	var box4Mod1 = new StateModifier({
   14.99 +        transform: Transform.translate(57, 20, 0)
  14.100 +    });
  14.101 +	var box4Mod2 = new StateModifier({
  14.102 +		transform: Transform.scale(1.22, 1.22)
  14.103 +    });
  14.104 +//==	
  14.105 +	var equalMod = new StateModifier({
  14.106 +        transform: Transform.translate(27, 85, 0)
  14.107 +    });
  14.108 +
  14.109 +	summationContainer.add(sigmaMod1).add(sigmaSurf);
  14.110 +	summationContainer.add(equalMod).add(equalSurf);
  14.111 +	summationContainer.add(box1Mod1).add(box1Mod2).add(box1);
  14.112 +	summationContainer.add(box2Mod1).add(box2Mod2).add(box2);
  14.113 +	summationContainer.add(box3Mod1).add(box3Mod2).add(box3);
  14.114 +	summationContainer.add(box4Mod1).add(box4Mod2).add(box4);
  14.115 +	mainContext.add(summationContainer);
  14.116 +
  14.117 +//==================	
  14.118 +	var moveModifier1 = new StateModifier({
  14.119 +        transform: Transform.translate(250, 100, 0)
  14.120 +    });
  14.121 +	var moveModifier2 = new StateModifier({
  14.122 +        transform: Transform.translate(350, 150, 0)
  14.123 +    });
  14.124 +	var rotateModifier = new StateModifier({
  14.125 +		transform: Transform.rotateZ(Math.PI/4)
  14.126 +	});
  14.127 +
  14.128 +//the origin is the point inside the child, relative to the child's
  14.129 +// internal axes, at which the child will be pinned inside its parent.
  14.130 +//The align is the point inside the parent, relative to the parent's axes,
  14.131 +// at which the origins of children will be pinned.
  14.132 +//The origin is also the point about which rotations are performed
  14.133 +	var moveRelativeModifier = new StateModifier({
  14.134 +      size: [20, 20],
  14.135 +      align: [0.5,0],
  14.136 +      origin: [0.5,0]
  14.137 +    });
  14.138 +	var moveRelativeModifier2 = new StateModifier({
  14.139 +      size: [20, 20],
  14.140 +      align: [0.5,0],
  14.141 +      origin: [0.5,0]
  14.142 +    });
  14.143 +
  14.144 +	var moveModifier2 = new StateModifier({
  14.145 +        transform: Transform.translate(350, 150, 0)
  14.146 +    });
  14.147 +	
  14.148 +    var scaleMod = new StateModifier({
  14.149 +        transform: Transform.scale(0.5, 0.5, 1)
  14.150 +    });
  14.151 +
  14.152 +
  14.153 +//can make a tree inside the context -- so, can have a transform applied
  14.154 +// to multiple children..  do so by making a var that holds the transform
  14.155 +// node, then add to that variable multiple times.
  14.156 +//Note, though that a given surface object will only render once!  Have to
  14.157 +// clone it if want multiple versions to be drawn.
  14.158 +//Same goes for modifiers -- cannot put same modifier object at multiple 
  14.159 +// places within tree -- it will only render children of ONE of those places!
  14.160 +//   var node = mainContext.add(rotateModifier);
  14.161 +//   node.add(moveModifier2).add(moveRelativeModifier).add(mySurface);
  14.162 +//   node.add(moveModifier1).add(scaleMod).add(mySurface2);
  14.163 +//   mainContext.add(moveRelativeModifier2).add(sigmaSurf);
  14.164 +
  14.165 +//==========================================
  14.166 +//    scrollview.sequenceFrom(surfaces);
  14.167 +//    container.add(scrollview);
  14.168 +
  14.169 +//    mainContext.add(new Modifier({origin: [.5, .5]})).add(container);
  14.170 +});
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_summation_SVG_in_parts.js	Sun Jul 06 12:02:12 2014 -0700
    15.3 @@ -0,0 +1,138 @@
    15.4 +
    15.5 +
    15.6 +define(function(require, exports, module) {
    15.7 +    var Engine           = require("famous/core/Engine");
    15.8 +    var Surface          = require("famous/core/Surface");
    15.9 +    var Modifier         = require("famous/core/Modifier");
   15.10 +    var Transform = require('famous/core/Transform');
   15.11 +    var StateModifier = require('famous/modifiers/StateModifier');
   15.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   15.13 +    var Scrollview       = require("famous/views/Scrollview");
   15.14 +
   15.15 +    var mainContext = Engine.createContext();
   15.16 +	
   15.17 +	var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">';
   15.18 +	var boxSVG = [];
   15.19 +	boxSVG[1] = '<svg width="';
   15.20 +	boxSVG[2] = '" height="';
   15.21 +	boxSVG[3] = '"><rect x="';
   15.22 +	boxSVG[4] = '" y="';
   15.23 +	boxSVG[5] = '" rx="'
   15.24 +	boxSVG[6] = '" ry="';
   15.25 +	boxSVG[7] = '" width="'
   15.26 +	boxSVG[8] = '" height="'
   15.27 +	boxSVG[9] = '" style="fill:'
   15.28 +	boxSVG[10] = ';stroke:'
   15.29 +	boxSVG[11] = ';stroke-width:'
   15.30 +	boxSVG[12] = ';opacity:'
   15.31 +	boxSVG[13] = '">';
   15.32 +	
   15.33 +	var boxSVGFromParts1 = boxSVG[1] + '19' + boxSVG[2] + '19' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '6.5' + boxSVG[6] + '6.5' + boxSVG[7] + '17' + boxSVG[8] + '17' + boxSVG[9] + 'none' + boxSVG[10] + 'black' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   15.34 +	var boxSVGFromParts2 = boxSVG[1] + '75' + boxSVG[2] + '75' + boxSVG[3] + '2' + boxSVG[4] + '2' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '70' + boxSVG[8] + '70' + boxSVG[9] + 'none' + boxSVG[10] + 'black' + boxSVG[11] + '5' + boxSVG[12] + '1' + boxSVG[13];
   15.35 +	
   15.36 +
   15.37 +//Draw a simple syntax graph, with a box of the correct color for each
   15.38 +// node, and curvy links with arrows going from text inside one node to
   15.39 +// text inside another node.
   15.40 +//Approach taken:
   15.41 +//Generate the SVG from calculations -- hold strings, and insert variable
   15.42 +// values
   15.43 +//Make each box a surface holding an SVG
   15.44 +//Make a container surface to hold each node, together with its properties
   15.45 +//Make a container surface to hold an element node together with its ports
   15.46 +//Make a separate surface for each SVG element -- one for sigma, one for
   15.47 +// each box.  
   15.48 +//For each surface, make a modifier that positions the boxes
   15.49 +// relative to the sigma and scales the boxes appropriately
   15.50 +//Make all positions relative to the container surface's origin
   15.51 +
   15.52 +    var summationContainer = new ContainerSurface({
   15.53 +        size: [200, 200],
   15.54 +        properties: {
   15.55 +            overflow: 'hidden'
   15.56 +        }
   15.57 +    });
   15.58 +	var box1 = new Surface({
   15.59 +	  size: [100, 100],
   15.60 +      content: boxSVGFromParts1,
   15.61 +      properties: {
   15.62 +      }
   15.63 +	});
   15.64 +	var box2 = new Surface({
   15.65 +	  size: [100, 100],
   15.66 +      content: boxSVGFromParts1,
   15.67 +      properties: {
   15.68 +      }
   15.69 +	});
   15.70 +	var box3 = new Surface({
   15.71 +	  size: [100, 100],
   15.72 +      content: boxSVGFromParts1,
   15.73 +      properties: {
   15.74 +      }
   15.75 +	});
   15.76 +	var box4 = new Surface({
   15.77 +	  size: [100, 100],
   15.78 +      content: boxSVGFromParts2,
   15.79 +      properties: {
   15.80 +      }
   15.81 +	});
   15.82 +	var equalSurf = new Surface({
   15.83 +	  size: [10, 10],
   15.84 +      content: "=",
   15.85 +      properties: {
   15.86 +      }
   15.87 +	});
   15.88 +	
   15.89 +	var sigmaMod1 = new StateModifier({
   15.90 +        transform: Transform.translate(0, 20, 0)
   15.91 +    });
   15.92 +//==
   15.93 +	var box1Mod1 = new StateModifier({
   15.94 +        transform: Transform.translate(7, 90, 0)
   15.95 +    });
   15.96 +	var box1Mod2 = new StateModifier({
   15.97 +		transform: Transform.scale(.3, .3)
   15.98 +    });
   15.99 +//==
  15.100 +	var box2Mod1 = new StateModifier({
  15.101 +        transform: Transform.translate(42, 90, 0)
  15.102 +    });
  15.103 +	var box2Mod2 = new StateModifier({
  15.104 +		transform: Transform.scale(.3, .3)
  15.105 +    });
  15.106 +//==
  15.107 +	var box3Mod1 = new StateModifier({
  15.108 +        transform: Transform.translate(42, 2, 0)
  15.109 +    });
  15.110 +	var box3Mod2 = new StateModifier({
  15.111 +		transform: Transform.scale(.3, .3)
  15.112 +    });
  15.113 +//==
  15.114 +	var box4Mod1 = new StateModifier({
  15.115 +        transform: Transform.translate(57, 20, 0)
  15.116 +    });
  15.117 +	var box4Mod2 = new StateModifier({
  15.118 +		transform: Transform.scale(1.22, 1.22)
  15.119 +    });
  15.120 +//==	
  15.121 +	var equalMod = new StateModifier({
  15.122 +        transform: Transform.translate(27, 85, 0)
  15.123 +    });
  15.124 +//==
  15.125 +	var contMod1 = new StateModifier({
  15.126 +        transform: Transform.translate(50, 50, 0)
  15.127 +    });
  15.128 +	var contMod2 = new StateModifier({
  15.129 +		transform: Transform.scale(.5, .5)
  15.130 +    });
  15.131 +	
  15.132 +
  15.133 +//	summationContainer.add(sigmaMod1).add(sigmaSurf);
  15.134 +	summationContainer.add(equalMod).add(equalSurf);
  15.135 +	summationContainer.add(box1Mod1).add(box1);
  15.136 +	summationContainer.add(box2Mod1).add(box2);
  15.137 +	summationContainer.add(box3Mod1).add(box3);
  15.138 +	summationContainer.add(box4Mod1).add(box4);
  15.139 +	mainContext.add(contMod1).add(contMod2).add(summationContainer);
  15.140 +
  15.141 +});
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/render_POP_syntax_graph.js	Sun Jul 06 12:02:12 2014 -0700
    16.3 @@ -0,0 +1,354 @@
    16.4 +
    16.5 +
    16.6 +define(function(require, exports, module) {
    16.7 +    var Engine           = require("famous/core/Engine");
    16.8 +    var Surface          = require("famous/core/Surface");
    16.9 +    var Modifier         = require("famous/core/Modifier");
   16.10 +    var Transform = require('famous/core/Transform');
   16.11 +    var StateModifier = require('famous/modifiers/StateModifier');
   16.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   16.13 +
   16.14 +    var mainContext = Engine.createContext();
   16.15 +	
   16.16 +	var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">';
   16.17 +	var boxSVG = [];
   16.18 +	boxSVG[1] = '<svg width="';
   16.19 +	boxSVG[2] = '" height="';
   16.20 +	boxSVG[3] = '"><rect x="';
   16.21 +	boxSVG[4] = '" y="';
   16.22 +	boxSVG[5] = '" rx="'
   16.23 +	boxSVG[6] = '" ry="';
   16.24 +	boxSVG[7] = '" width="'
   16.25 +	boxSVG[8] = '" height="'
   16.26 +	boxSVG[9] = '" style="fill:'
   16.27 +	boxSVG[10] = ';stroke:'
   16.28 +	boxSVG[11] = ';stroke-width:'
   16.29 +	boxSVG[12] = ';opacity:'
   16.30 +	boxSVG[13] = '">';
   16.31 +	
   16.32 +
   16.33 +//Draw a simple syntax graph, with a box of the correct color for each
   16.34 +// node, and curvy links with arrows going from text inside one node to
   16.35 +// text inside another node.
   16.36 +//Approach taken:
   16.37 +//Generate the SVG from calculations -- hold strings in an array, and
   16.38 +// build up an SVG string by adding string piece, then variable value then
   16.39 +// another string piece, and so on.
   16.40 +//Make each box a surface holding an SVG
   16.41 +//Sizing of the box happens inside the SVG string
   16.42 +//Positioning the box happens via a modifier
   16.43 +
   16.44 +//Make one container surface to hold each element node together with its
   16.45 +// properties and ports
   16.46 +//Make a separate surface for each SVG element -- one for each box, one for
   16.47 +// each text in a box, one for each curvy connector arrow between boxes or
   16.48 +// between texts.  
   16.49 +//For each surface, make a modifier that positions the box relative to the
   16.50 +// container surface's origin
   16.51 +//At the end, make transforms to move the entire container around
   16.52 +
   16.53 +	//elem1 is the root element from the Gabe Pattern syntax graph
   16.54 +	// here, make the visual elements that reproduce what see in the .pdf
   16.55 +    var elem1Container = new ContainerSurface({
   16.56 +        size: [600, 600], //size it big for now, trim to contents later
   16.57 +        properties: {
   16.58 +            overflow: 'hidden'
   16.59 +        }
   16.60 +    });
   16.61 +	
   16.62 +//==
   16.63 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
   16.64 +//  11:stroke-width 12:opacity
   16.65 +	var box1_1width = 66;
   16.66 +	var box1_1height = 86
   16.67 +//	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   16.68 +	var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2;
   16.69 +	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   16.70 +
   16.71 +//== elem1 box 1 --> box1_1
   16.72 +	var box1_1 = new Surface({
   16.73 +	  size: [true, true],
   16.74 +      content: boxSVGFromParts1_1
   16.75 +	});
   16.76 +	var box1_1x = 0;
   16.77 +	var box1_1y = 2;
   16.78 +	var boxMod1_1_1 = new StateModifier({
   16.79 +        transform: Transform.translate(box1_1x, box1_1y, 0)
   16.80 +    });
   16.81 +	
   16.82 +//== elem1 box 1 text 1 --> text1_1_1
   16.83 +	var text1_1_1 = new Surface({
   16.84 +	  size: [true, 11],
   16.85 +      content: "properties",
   16.86 +      properties: {
   16.87 +        color: 'black',
   16.88 +        textAlign: 'left',
   16.89 +        fontSize: '11px',
   16.90 +        cursor: 'hand'
   16.91 +      }
   16.92 +	});
   16.93 +	var text1_1_2 = new Surface({
   16.94 +	  size: [true, true],
   16.95 +      content: "portsIn",
   16.96 +      properties: {
   16.97 +        color: 'black',
   16.98 +        textAlign: 'left',
   16.99 +        fontSize: '11px',
  16.100 +        cursor: 'pointer'
  16.101 +      }
  16.102 +	});
  16.103 +	var text1_1_3 = new Surface({
  16.104 +	  size: [true, true],
  16.105 +      content: "portsOut",
  16.106 +      properties: {
  16.107 +        color: 'black',
  16.108 +        textAlign: 'left',
  16.109 +        fontSize: '11px',
  16.110 +        cursor: 'pointer'
  16.111 +      }
  16.112 +	});
  16.113 +	var text1_1_4 = new Surface({
  16.114 +	  size: [true, true],
  16.115 +      content: "subElems",
  16.116 +      properties: {
  16.117 +        color: 'black',
  16.118 +        textAlign: 'left',
  16.119 +        fontSize: '11px',
  16.120 +        cursor: 'pointer'
  16.121 +     }
  16.122 +	});
  16.123 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1
  16.124 +	var text1_1_1x = 8;
  16.125 +	var text1_1_1y = 8;
  16.126 +	var textMod1_1_1_1 = new StateModifier({
  16.127 +        transform: Transform.translate(text1_1_1x, text1_1_1y, 0)
  16.128 +    });
  16.129 +	var textMod1_1_2_1 = new StateModifier({
  16.130 +        transform: Transform.translate(8, 25, 0)
  16.131 +    });
  16.132 +	var textMod1_1_3_1 = new StateModifier({
  16.133 +        transform: Transform.translate(8, 42, 0)
  16.134 +    });
  16.135 +	var textMod1_1_4_1 = new StateModifier({
  16.136 +        transform: Transform.translate(8, 59, 0)
  16.137 +    });
  16.138 +//==
  16.139 +	elem1Container.add(boxMod1_1_1).add(box1_1);
  16.140 +	elem1Container.add(textMod1_1_1_1).add(text1_1_1);
  16.141 +	elem1Container.add(textMod1_1_2_1).add(text1_1_2);
  16.142 +	elem1Container.add(textMod1_1_3_1).add(text1_1_3);
  16.143 +	elem1Container.add(textMod1_1_4_1).add(text1_1_4);
  16.144 +
  16.145 +//== elem 1 box 2 --> box1_2
  16.146 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
  16.147 +//  11:stroke-width 12:opacity
  16.148 +	var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2;
  16.149 +	var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
  16.150 +	var box1_2 = new Surface({
  16.151 +	  size: [true, true],
  16.152 +      content: boxSVGFromParts1_2
  16.153 + 	});
  16.154 +	var box1_2x = 100;
  16.155 +	var box1_2y = 2;
  16.156 +	var boxMod1_2_1 = new StateModifier({
  16.157 +        transform: Transform.translate(box1_2x, box1_2y, 0)
  16.158 +    });
  16.159 +//== elem 1 box 2 text 1 --> text1_2_1
  16.160 +	var text1_2_1 = new Surface({
  16.161 +	  size: [true, true],
  16.162 +      content: "propertyName:  TypeOfElement",
  16.163 +      properties: {
  16.164 +        color: 'black',
  16.165 +        textAlign: 'left',
  16.166 +        fontSize: '11px',
  16.167 +        cursor: 'pointer'
  16.168 +      }
  16.169 +	});
  16.170 +	var text1_2_2 = new Surface({
  16.171 +	  size: [true, true],
  16.172 +      content: "propertyValue:  GabeTransfromRule",
  16.173 +      properties: {
  16.174 +        color: 'black',
  16.175 +        textAlign: 'left',
  16.176 +        fontSize: '11px',
  16.177 +        cursor: 'pointer'
  16.178 +      }
  16.179 +	});
  16.180 +	var text1_2_3 = new Surface({
  16.181 +	  size: [true, true],
  16.182 +      content: "subProperties",
  16.183 +      properties: {
  16.184 +        color: 'black',
  16.185 +        textAlign: 'left',
  16.186 +        fontSize: '11px',
  16.187 +        cursor: 'pointer'
  16.188 +      }
  16.189 +	});
  16.190 +//==
  16.191 +	var textMod1_2_1_1 = new StateModifier({
  16.192 +        transform: Transform.translate(108, 8, 0)
  16.193 +    });
  16.194 +	var textMod1_2_2_1 = new StateModifier({
  16.195 +        transform: Transform.translate(108, 25, 0)
  16.196 +    });
  16.197 +	var textMod1_2_3_1 = new StateModifier({
  16.198 +        transform: Transform.translate(108, 42, 0)
  16.199 +    });
  16.200 +//==
  16.201 +	elem1Container.add(boxMod1_2_1).add(box1_2);
  16.202 +	elem1Container.add(textMod1_2_1_1).add(text1_2_1);
  16.203 +	elem1Container.add(textMod1_2_2_1).add(text1_2_2);
  16.204 +	elem1Container.add(textMod1_2_3_1).add(text1_2_3);
  16.205 +
  16.206 +//Now, add bezier curve, in SVG..
  16.207 +//One end point is the end of "properties" text surface inside the elem box
  16.208 +//Other end point is the middle of side of properties box
  16.209 +	
  16.210 +	var bezierSVG1 = '<svg width="106" height="106"> <path d="M3,3 C0,100 100,0 100,100" style="fill:none;stroke:black;stroke-width:4;opacity:1">';
  16.211 +
  16.212 +	var bezSVG = [];
  16.213 +	bezSVG[1] = '<svg width="'
  16.214 +	bezSVG[2] = '" height="'
  16.215 +	bezSVG[3] = '"><path d="M' //start pt x
  16.216 +	bezSVG[4] = ','  //start pt y
  16.217 +	bezSVG[5] = ' C' //control pt 1 x
  16.218 +	bezSVG[6] = ','  //control pt 1 y
  16.219 +	bezSVG[7] = ' '  //control pt 2 x
  16.220 +	bezSVG[8] = ','  //control pt 2 y
  16.221 +	bezSVG[9] = ' '  //end pt x
  16.222 +	bezSVG[10] = ',' //end pt y
  16.223 +	bezSVG[11] = '" style="fill:'
  16.224 +	bezSVG[12] = ';stroke:'
  16.225 +	bezSVG[13] = ';stroke-width:'
  16.226 +	bezSVG[14] = ';opacity:'
  16.227 +	bezSVG[15] = '">';
  16.228 +	
  16.229 +	//now calculate the end points of the curve -- they connect to the
  16.230 +	// right edge of the "properties" text in the left box, and to the
  16.231 +	// middle of the left side of the right box
  16.232 +	var bezPoints = [{},{}];
  16.233 +	var fontSz = 11;
  16.234 +	bezPoints[0].x = box1_1x + box1_1w;
  16.235 +	bezPoints[0].y = text1_1_1y + fontSz/2 + 8;
  16.236 +	bezPoints[1].x = box1_2x;
  16.237 +	bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2;
  16.238 +
  16.239 +	var controlPoints = [];
  16.240 +	controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y};
  16.241 +	controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y};
  16.242 +
  16.243 +
  16.244 +	//	1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x
  16.245 +	// 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity
  16.246 +	var bezSVG1 = "";
  16.247 +	bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6);
  16.248 +	bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6);
  16.249 +	bezSVG1 += bezSVG[3] + bezPoints[0].x; 
  16.250 +	bezSVG1 += bezSVG[4] + bezPoints[0].y; 
  16.251 +	bezSVG1 += bezSVG[5] + controlPoints[0].x;
  16.252 +	bezSVG1 += bezSVG[6] + controlPoints[0].y;
  16.253 +	bezSVG1 += bezSVG[7] + controlPoints[1].x;
  16.254 +	bezSVG1 += bezSVG[8] + controlPoints[1].y;
  16.255 +	bezSVG1 += bezSVG[9] + bezPoints[1].x; 
  16.256 +	bezSVG1 += bezSVG[10] + bezPoints[1].y; 
  16.257 +	bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15];
  16.258 +
  16.259 +var bezSVG2 = '<svg width="400" height="170"><path d="M66,13.5 C66,2.5 100,13.5 100,2.5" style="fill:none;stroke:black;stroke-width:2;opacity:1">';	
  16.260 +var x1 = 59; var x2 = 100; var y1 = 22; var y2 = 40;
  16.261 +var bezSVG3 = '<svg width="200" height="200"><path d="M59,21 C100,21 59,38 100,38" style="fill:none;stroke:black;stroke-width:2;opacity:1">';	
  16.262 +	var bez1_1 = new Surface({
  16.263 +	  size: [true, true],
  16.264 +      content: bezSVG1
  16.265 + 	});
  16.266 +
  16.267 +	elem1Container.add(bez1_1);
  16.268 +
  16.269 +var el1 =  document.createElement("span")
  16.270 +var displayStr = bezSVG1.replace(/</g, "&lt");//make the html display as text
  16.271 +el1.innerHTML = (displayStr + "<br>");
  16.272 +document.body.appendChild(el1);
  16.273 +el1 =  document.createElement("span")
  16.274 +displayStr = bezSVG3.replace(/</g, "&lt");//make the html display as text
  16.275 +el1.innerHTML = displayStr;
  16.276 +document.body.appendChild(el1);
  16.277 +
  16.278 +
  16.279 +//== elem 1 Modifer 1 --> contMod1_1
  16.280 +	var contMod1_1 = new StateModifier({
  16.281 +        transform: Transform.translate(50, 50, 0)
  16.282 +    });
  16.283 +	var contMod1_2 = new StateModifier({
  16.284 +		transform: Transform.scale(1, 1)
  16.285 +    });	
  16.286 +//==
  16.287 +
  16.288 +	mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container);
  16.289 +
  16.290 +	//elem2 is 
  16.291 +    var elem2Container = new ContainerSurface({
  16.292 +        size: [200, 200],
  16.293 +        properties: {
  16.294 +            overflow: 'hidden'
  16.295 +        }
  16.296 +    });
  16.297 +	
  16.298 +	
  16.299 +	
  16.300 +//== elem 2 box 1 --> box2_1
  16.301 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
  16.302 +//  11:stroke-width 12:opacity
  16.303 +	var boxSVGFromParts2_1 = boxSVG[1] + '68' + boxSVG[2] + '88' + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + '66' + boxSVG[8] + '86' + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
  16.304 +	var box2_1 = new Surface({
  16.305 +	  size: [100, 100],
  16.306 +      content: boxSVGFromParts2_1,
  16.307 +	});
  16.308 +	var box2_3 = new Surface({
  16.309 +	  size: [100, 100],
  16.310 +      content: boxSVGFromParts2_1,
  16.311 +      properties: {
  16.312 +      }
  16.313 +	});
  16.314 +	var box2_4 = new Surface({
  16.315 +	  size: [100, 100],
  16.316 +      content: boxSVGFromParts2_1,
  16.317 +      properties: {
  16.318 +      }
  16.319 +	});
  16.320 +	
  16.321 +//==
  16.322 +	var boxMod2_1_1 = new StateModifier({
  16.323 +        transform: Transform.translate(7, 90, 0)
  16.324 +    });
  16.325 +	var boxMod2_1_2 = new StateModifier({
  16.326 +		transform: Transform.scale(.3, .3)
  16.327 +    });
  16.328 +//==
  16.329 +	var boxMod2_2_1 = new StateModifier({
  16.330 +        transform: Transform.translate(42, 90, 0)
  16.331 +    });
  16.332 +	var boxMod2_2_2 = new StateModifier({
  16.333 +		transform: Transform.scale(.3, .3)
  16.334 +    });
  16.335 +//==
  16.336 +	var boxMod2_3_1 = new StateModifier({
  16.337 +        transform: Transform.translate(42, 2, 0)
  16.338 +    });
  16.339 +	var boxMod2_3_2 = new StateModifier({
  16.340 +		transform: Transform.scale(.3, .3)
  16.341 +    });
  16.342 +//==
  16.343 +	var boxMod2_4_1 = new StateModifier({
  16.344 +        transform: Transform.translate(57, 20, 0)
  16.345 +    });
  16.346 +	var boxMod2_4_2 = new StateModifier({
  16.347 +		transform: Transform.scale(1.22, 1.22)
  16.348 +    });
  16.349 +//==	
  16.350 +	var equalMod = new StateModifier({
  16.351 +        transform: Transform.translate(27, 85, 0)
  16.352 +    });
  16.353 +	
  16.354 +
  16.355 +//	summationContainer.add(sigmaMod1).add(sigmaSurf);
  16.356 +
  16.357 +});
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display - Copy/startUpApp.js	Sun Jul 06 12:02:12 2014 -0700
    17.3 @@ -0,0 +1,15 @@
    17.4 +// For any third party dependencies, like jQuery, place them in the lib folder.
    17.5 +
    17.6 +// Configure loading modules from the lib directory,
    17.7 +// except for 'app' ones, which are in a sibling
    17.8 +// directory.
    17.9 +requirejs.config({
   17.10 +//    baseUrl: 'lib',
   17.11 +    paths: {
   17.12 +        app: './app'
   17.13 +    }
   17.14 +});
   17.15 +
   17.16 +// Start loading the main app file. Put all of
   17.17 +// your application logic in there.
   17.18 +requirejs(['app/renderPOPSyntaxGraph']);
   17.19 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/POPDisplay.html	Sun Jul 06 12:02:12 2014 -0700
    18.3 @@ -0,0 +1,48 @@
    18.4 +<!DOCTYPE html>
    18.5 +<html>
    18.6 +    <head>
    18.7 +		<!--This page is a Display for a POP system.  Eventually, a user
    18.8 +			will simply open this page in their browser, and it will
    18.9 +			load whatever the last view was for that user.  The user will
   18.10 +			then enter gestures and get responses in the form of new things
   18.11 +			drawn on the display.  For example, they can open worksheets
   18.12 +			or view srcHolder contents, in either syntactic form or syntax
   18.13 +			graph form.  And they can manipulate the environment, such as
   18.14 +			make tunnels to other systems, create persistent processors, 
   18.15 +			expand the running processors made from a particular code
   18.16 +			base (IE, the POP equivalent of running a program) and so on.
   18.17 +			
   18.18 +			For now, this page starts up the entire POP system, but in the
   18.19 +			future it will simply connect to an existing, persistent one.-->
   18.20 +        <title>POP Display</title>
   18.21 +
   18.22 +        <!-- load the POP system via the requirejs module system -->
   18.23 +        <script data-main="startUpApp" src="lib/require.js"></script>
   18.24 +		
   18.25 +        <!-- helper -->
   18.26 +		<script src="lib/jquery.min.js"></script>
   18.27 +		
   18.28 +        <!-- Declare mobile device compatibilites -->
   18.29 +		<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
   18.30 +        <meta name="mobile-web-app-capable" content="yes" />
   18.31 +        <meta name="apple-mobile-web-app-capable" content="yes" />
   18.32 +        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
   18.33 +
   18.34 +        <!-- backwards compatibility for famous stuff -->
   18.35 +        <script type="text/javascript" src="lib/functionPrototypeBind.js"></script>
   18.36 +        <script type="text/javascript" src="lib/classList.js"></script>
   18.37 +        <script type="text/javascript" src="lib/requestAnimationFrame.js"></script>
   18.38 +
   18.39 +        <!-- load the famous stuff -->
   18.40 +        <link rel="stylesheet" type="text/css" href="lib/famous.css" />
   18.41 +        <script type="text/javascript" src="lib/famous.js"></script>
   18.42 +		
   18.43 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. -->
   18.44 +        <link rel="stylesheet" type="text/css" href="lib/famous_styles.css" />
   18.45 +
   18.46 +    </head>
   18.47 +
   18.48 +<body>
   18.49 +
   18.50 +</body>
   18.51 +</html>
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/GabePatternSrcHolder.js	Sun Jul 06 12:02:12 2014 -0700
    19.3 @@ -0,0 +1,15 @@
    19.4 +
    19.5 +
    19.6 +//Make a SrcHolder object
    19.7 +define(function(require, exports, module) {
    19.8 +
    19.9 +	var visualizer = require('./POPSyntaxGraphVisualizer');
   19.10 +	var syntaxGraph = require('./buildGabePatternSyntaxGraph');
   19.11 +
   19.12 +	return{
   19.13 +		visualizer: visualizer,
   19.14 +		syntaxGraph: syntaxGraph
   19.15 +	};
   19.16 +});
   19.17 +
   19.18 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPApp.js	Sun Jul 06 12:02:12 2014 -0700
    20.3 @@ -0,0 +1,52 @@
    20.4 +
    20.5 +//This is testing scaffolding..
    20.6 +//As of July 2, 2014:
    20.7 +//instantiate a Display object
    20.8 +//instantiate a srcHolder object
    20.9 +//invoke the visualizer in the srcHolder object, passing it the Display object
   20.10 +//this should cause the visualizer to generate a view hierarchy and
   20.11 +// pass that to the Display, which then paints it
   20.12 +define(function(require, exports, module) {
   20.13 +	
   20.14 +	//get the Display object, which contains a function for passing a view
   20.15 +	// hierarchy, which the Display then paints onto the screen
   20.16 +	var POPDisplay = require('./POPDisplay');
   20.17 +	
   20.18 +	//test that have the require system working properly -- logs to console
   20.19 +	POPDisplay.acceptViewList("testing accept view list");
   20.20 +
   20.21 +	//invoke the module that paints a canned sub-piece of the gabe pattern
   20.22 +	// syntax graph.. just so have something to see!  (for now.. remove later)
   20.23 +	require('./renderPOPSyntaxGraph');
   20.24 +	
   20.25 +	//cause the source holder object to be made, which will in turn
   20.26 +	// cause a graph of syntax objects to be built inside of it
   20.27 +	// and also cause a visualizer object to be built inside of it
   20.28 +	var srcHolder = require('./GabePatternSrcHolder');
   20.29 +	
   20.30 +	//connect the srcHolder to the Display
   20.31 +	//Not sure yet what final form this will take..  for now..
   20.32 +	srcHolder.visualizer.connectToDisplay( POPDisplay );
   20.33 +	
   20.34 +	//Trigger the visualizer to build a view hierarchy and pass that
   20.35 +	// to the Display object, which in turn triggers the Display to build
   20.36 +	// a famous render tree corresponding to the view hierarchy, which paints
   20.37 +	// the syntax graph representation into the browser
   20.38 +	//This isn't the correct final form of how the visualizer determines
   20.39 +	// the portions of the graph to generate a view hierarchy from, but
   20.40 +	// it works for now, while developing..
   20.41 +	srcHolder.visualizer.setViewSubGraph( srcHolder.visualizer.syntaxGraph );
   20.42 +	
   20.43 +	//Once the system is complete, the view will be initialized to whatever
   20.44 +	// the last view was before suspend.  When first built, the srcHolder
   20.45 +	// will be empty, so the view will have a null viewSubGraph.
   20.46 +	//As the MVDM loop gathers gestures, it will build up the syntax graph,
   20.47 +	// and during the process update the viewSubGraph.
   20.48 +	//Each gesture that modifies a portion of the graph that is currently
   20.49 +	// within the view will cause a change in the viewSubGraph..
   20.50 +	//Thinking perhaps just have markers inside the normal graph that delimit
   20.51 +	// the boundaries of the view sub-graph.  Implies that the view can only
   20.52 +	// include connected portions of the graph..  may be overly restrictive..
   20.53 +	// might have case where filter the kinds of things that are visible, 
   20.54 +	// which will collect disconnected pieces from the main graph.
   20.55 +});
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPDisplay.js	Sun Jul 06 12:02:12 2014 -0700
    21.3 @@ -0,0 +1,73 @@
    21.4 +
    21.5 +
    21.6 +//Make a Display object, and a number of functions that operate on it.
    21.7 +// One of the functions accepts an array of visual element objects as
    21.8 +// input, and turns those visual elements into a famous render tree.
    21.9 +//The famous context, and the surfaces, and so on exist inside the Display
   21.10 +// object.
   21.11 +
   21.12 +//This uses require.js to create a module.  This module has the name of the
   21.13 +// file (POPDisplay).  Inside the define, a number of data structures and 
   21.14 +// functions are created, then returned at the end.  The returned things are
   21.15 +// what can be accessed by external functions that load this module, via
   21.16 +// themselves using the require("POPDisplay") call
   21.17 +define(function(require, exports, module) {
   21.18 +    //Create the famous infrastructure, which is used for rendering on screen
   21.19 +    var Engine           = require("famous/core/Engine");
   21.20 +    var Surface          = require("famous/core/Surface");
   21.21 +    var Modifier         = require("famous/core/Modifier");
   21.22 +    var Transform        = require('famous/core/Transform');
   21.23 +    var StateModifier    = require('famous/modifiers/StateModifier');
   21.24 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   21.25 +
   21.26 +	//make the context, which controls rendering to the screen
   21.27 +	// once add something to this context, that add makes the thing visibly
   21.28 +	// have effect.
   21.29 +	//Note, these are available to the render function via the closure
   21.30 +	// mechanism
   21.31 +    var mainContext = Engine.createContext();
   21.32 +
   21.33 +	var handleGesture = function( event ) {
   21.34 +			//not sure this is the right form, but provide a handler for
   21.35 +			// gestures made by the programmer/user
   21.36 +			//This will make an object that pairs the gesture to the view
   21.37 +			// element that is represented by the surface(s) involved in
   21.38 +			// the gesture.
   21.39 +			//It will then send the object to the command generator, which 
   21.40 +			// is part of the source holder
   21.41 +		console.log("handleGesture");
   21.42 +	}
   21.43 +	function acceptViewList (viewList) {
   21.44 +		//access Display object and its values here, as a closure
   21.45 +		console.log("acceptViewList");
   21.46 +	}
   21.47 +	
   21.48 +	function init() {
   21.49 +		console.log("init");
   21.50 +		//	var POPStuffToDraw = 
   21.51 +		var mySurface = new Surface({
   21.52 +		  size: [100, 100],
   21.53 +		  content: '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
   21.54 +		  properties: {
   21.55 +			color: 'white',
   21.56 +			lineHeight: '200%',
   21.57 +			textAlign: 'center',
   21.58 +			fontSize: '36px',
   21.59 +			cursor: 'pointer'
   21.60 +		  }
   21.61 +		});
   21.62 +		var stateModifier = new StateModifier({
   21.63 +			transform: Transform.translate(250, 100, 0)
   21.64 +		});
   21.65 +		mainContext.add(stateModifier).add(mySurface);
   21.66 +	}
   21.67 +
   21.68 +
   21.69 +	return{
   21.70 +		init: init,
   21.71 +		handleGesture: handleGesture,
   21.72 +		acceptViewList: acceptViewList
   21.73 +	};
   21.74 +});
   21.75 +
   21.76 +
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/POPSyntaxGraphVisualizer.js	Sun Jul 06 12:02:12 2014 -0700
    22.3 @@ -0,0 +1,146 @@
    22.4 +
    22.5 +
    22.6 +//Make a Visualizer object, and a number of functions that operate on it.
    22.7 +// One of the functions accepts 
    22.8 +define(function(require, exports, module) {
    22.9 +    //Create the famous infrastructure, which is used for rendering on screen
   22.10 +	
   22.11 +	var viewHierarchy = {};
   22.12 +	
   22.13 +	var renderer = require('./renderPOPSyntaxGraph');	
   22.14 +	
   22.15 +	function init() {
   22.16 +		//access Visualizer values here, as a closure
   22.17 +		console.log("init visualizer");
   22.18 +	}
   22.19 +	
   22.20 +	function connectToDisplay( POPDisplay ) {
   22.21 +		//access Visualizer values here, as a closure
   22.22 +		console.log("connectToDisplay");
   22.23 +	}
   22.24 +	
   22.25 +	//Calling this function triggers a series of events:
   22.26 +	//1) it generates a view hierarchy that represents the syntax graph
   22.27 +	//2) it sends that view hierarchy to the Display
   22.28 +	//3) the Display creates an internal representation of the hierarchy
   22.29 +	//4) the Display paints that internal representation to some device
   22.30 +	function setViewSubGraph( syntaxSubGraph ) {
   22.31 +		//access Visualizer values here, as a closure
   22.32 +		console.log("setViewSubGraph");
   22.33 +		//for first pass, just build the view hierarchy by hand
   22.34 +		
   22.35 +		//A view hierarchy consists of a bounding boxes arranged in a
   22.36 +		// a hierarchy.  Inside each bounding box is either more bounding
   22.37 +		// boxes or a paintable thing.
   22.38 +		//For now, paintable things are either SVG or text
   22.39 +		//Text includes styles such as font, italics, size
   22.40 +
   22.41 +		//In this test, just construct the hierarchy for the two boxes
   22.42 +		// that already did the by-hand SVG for, with the bezier connecting
   22.43 +		// them..  for now, just make the data structs and populate with
   22.44 +		// info gotten from the by-hand rendering
   22.45 +		//Later, will calculate all the box sizes and positions relative to
   22.46 +		// parents
   22.47 +		viewHierarchy.rootBox = {
   22.48 +			width: 500,
   22.49 +			height: 500,
   22.50 +			subBoxes: []
   22.51 +		} //note, left out parent-relative position and shape!
   22.52 +		
   22.53 +		var children = viewHierarchy.rootBox.subBoxes;
   22.54 +		//first child is the syntactic element box
   22.55 +		svgBox = renderer.getElemBox();
   22.56 +		children[0] = {
   22.57 +			width: 68, //match width and height of the SVG shapes inside
   22.58 +			height: 88,
   22.59 +			xOffset: 0,
   22.60 +			yOffset: 2,
   22.61 +			shape: svgBox,
   22.62 +			subBoxes: []
   22.63 +		}
   22.64 +		//second child is the properties box attached to the first box
   22.65 +		svgBox = renderer.getPropertiesBox();
   22.66 +		children[1] = {
   22.67 +			width: 185, //match width and height of the SVG shapes inside
   22.68 +			height: 71,
   22.69 +			xOffset: 100,
   22.70 +			yOffset: 2,
   22.71 +			shape: svgBox,
   22.72 +			subBoxes: []
   22.73 +		}
   22.74 +		console.log("box2: " + children[1].shape);
   22.75 +		
   22.76 +		//now add the text to the elem box
   22.77 +		children = children[0].subBoxes; //set to subBoxes of elem box
   22.78 +		var text1_1_1 = renderer.getText1_1_1;
   22.79 +		children[0] = {
   22.80 +			width: text1_1_1.width,
   22.81 +			height: text1_1_1.height,
   22.82 +			xOffset: text1_1_1.x,
   22.83 +			yOffset: text1_1_1.y,
   22.84 +			shape: text1_1_1.svg
   22.85 +		}
   22.86 +		var text1_1_2 = renderer.getText1_1_2;
   22.87 +		children[1] = {
   22.88 +			width: text1_1_2.width,
   22.89 +			height: text1_1_2.height,
   22.90 +			xOffset: text1_1_2.x,
   22.91 +			yOffset: text1_1_2.y,
   22.92 +			shape: text1_1_2.svg
   22.93 +		}
   22.94 +		var text1_1_3 = renderer.getText1_1_3;
   22.95 +		children[2] = {
   22.96 +			width: text1_1_3.width,
   22.97 +			height: text1_1_3.height,
   22.98 +			xOffset: text1_1_3.x,
   22.99 +			yOffset: text1_1_3.y,
  22.100 +			shape: text1_1_3.svg
  22.101 +		}
  22.102 +		var text1_1_4 = renderer.getText1_1_4;
  22.103 +		children[3] = {
  22.104 +			width: text1_1_4.width,
  22.105 +			height: text1_1_4.height,
  22.106 +			xOffset: text1_1_4.x,
  22.107 +			yOffset: text1_1_4.y,
  22.108 +			shape: text1_1_4.svg
  22.109 +		}
  22.110 +		
  22.111 +		//now add the text to the properties box
  22.112 +		children = viewHierarchy.rootBox.subBoxes[1].subBoxes;
  22.113 +		var text1_2_1 = renderer.getText1_2_1;
  22.114 +		children[0] = {
  22.115 +			width: text1_2_1.width,
  22.116 +			height: text1_2_1.height,
  22.117 +			xOffset: text1_2_1.x,
  22.118 +			yOffset: text1_2_1.y,
  22.119 +			shape: text1_2_1.svg
  22.120 +		}
  22.121 +		var text1_2_2 = renderer.getText1_2_2;
  22.122 +		children[1] = {
  22.123 +			width: text1_2_2.width,
  22.124 +			height: text1_2_2.height,
  22.125 +			xOffset: text1_2_2.x,
  22.126 +			yOffset: text1_2_2.y,
  22.127 +			shape: text1_2_2.svg
  22.128 +		}
  22.129 +		var text1_2_3 = renderer.getText1_2_3;
  22.130 +		children[2] = {
  22.131 +			width: text1_2_3.width,
  22.132 +			height: text1_2_3.height,
  22.133 +			xOffset: text1_2_3.x,
  22.134 +			yOffset: text1_2_3.y,
  22.135 +			shape: text1_2_3.svg
  22.136 +		}
  22.137 +		
  22.138 +		//now add the bezier curve
  22.139 +		
  22.140 +	}
  22.141 +
  22.142 +	return{
  22.143 +		init: init,
  22.144 +		connectToDisplay: connectToDisplay,
  22.145 +		setViewSubGraph: setViewSubGraph
  22.146 +	};
  22.147 +});
  22.148 +
  22.149 +
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/buildGabePatternSyntaxGraph.js	Sun Jul 06 12:02:12 2014 -0700
    23.3 @@ -0,0 +1,414 @@
    23.4 +//A syntax graph consists of two kinds of nodes: element, port, and property 
    23.5 +//An element node can have sub-elements, and a property node can have
    23.6 +// sub-properties, but a port node may not have sub-ports!
    23.7 +
    23.8 +//This uses require.js to create a module.  This module has the name of the
    23.9 +// file (POPDisplay).  Inside the define, a number of data structures and 
   23.10 +// functions are created, then returned at the end.  The returned things are
   23.11 +// what can be accessed by external functions that load this module, via
   23.12 +// themselves using the require("POPDisplay") call
   23.13 +define(function(require, exports, module) {
   23.14 +
   23.15 +//this is the top level handle to the syntax graph of the gabe transform rule
   23.16 +var firstGabeTransformRule = {};
   23.17 +
   23.18 +//make a variable that holds an empty element struct.. this var will used
   23.19 +// to build up an element, and then reused to build up other elements 
   23.20 +var tempElem = 
   23.21 + { properties: [],
   23.22 +   portsIn:    [],
   23.23 +   portsOut:   [],
   23.24 +   subElems:   []
   23.25 + };
   23.26 + 
   23.27 +//the root of the Gabe Transform to the temp elem, then build up a property
   23.28 +// to place into the elem.
   23.29 +firstGabeTransformRule.root = tempElem; 
   23.30 +
   23.31 +//build the first property
   23.32 +var tempProperty = 
   23.33 + { propertyName: "TypeOfElement",
   23.34 +   propertyValue: "GabeTransformRule",
   23.35 +   subProperties: []
   23.36 + }
   23.37 + 
   23.38 +//attach it to the root elem
   23.39 +firstGabeTransformRule.root.properties[0] = tempProperty;
   23.40 +
   23.41 +//build and attach the second property
   23.42 +var tempProperty = 
   23.43 + { propertyName: "TypeOfSyntacticStructure",
   23.44 +   propertyValue: "syntacticHierarchy",
   23.45 +   subProperties: []
   23.46 + }
   23.47 +
   23.48 +firstGabeTransformRule.root.properties[1] = tempProperty;
   23.49 +
   23.50 +//now reuse tempElem to make the first sub-element of the root elem 
   23.51 +var tempElem = 
   23.52 + { properties: [],
   23.53 +   portsIn:    [],
   23.54 +   portsOut:   [],
   23.55 +   subElems:   []
   23.56 + }
   23.57 +
   23.58 +firstGabeTransformRule.root.subElems[0] = tempElem;
   23.59 +
   23.60 +var tempProperty = 
   23.61 + { propertyName: "TypeOfElement",
   23.62 +   propertyValue: "GabeQueryPattern",
   23.63 +   subProperties: []
   23.64 + }
   23.65 + 
   23.66 +tempElem.properties[0] = tempProperty;
   23.67 +
   23.68 +var tempProperty =
   23.69 + { propertyName: "TypeOfSyntacticStructure",
   23.70 +   propertyValue: "syntacticHierarchy",
   23.71 +   subProperties: []
   23.72 + }
   23.73 +  
   23.74 +tempElem.properties[1] = tempProperty;
   23.75 +
   23.76 +
   23.77 +//Keep going, building up the graph that was drawn
   23.78 +//make the second sub-element of the root elem, the replacement pattern 
   23.79 +var tempElem = 
   23.80 + { properties: [],
   23.81 +   portsIn:    [],
   23.82 +   portsOut:   [],
   23.83 +   subElems:   []
   23.84 + }
   23.85 +
   23.86 +firstGabeTransformRule.root.subElems[1] = tempElem;
   23.87 +
   23.88 +var tempProperty = 
   23.89 + { propertyName: "TypeOfElement",
   23.90 +   propertyValue: "GabeReplacePattern",
   23.91 +   subProperties: []
   23.92 + }
   23.93 + 
   23.94 +tempElem.properties[0] = tempProperty;
   23.95 +
   23.96 +var tempProperty =
   23.97 + { propertyName: "TypeOfSyntacticStructure",
   23.98 +   propertyValue: "syntacticHierarchy",
   23.99 +   subProperties: []
  23.100 + }
  23.101 +  
  23.102 +tempElem.properties[1] = tempProperty;
  23.103 +
  23.104 +//Now, go back and fill in the rest of the query pattern
  23.105 +//First, add the sub-elements of the query pattern node
  23.106 +var tempElem = 
  23.107 + { properties: [],
  23.108 +   portsIn:    [],
  23.109 +   portsOut:   [],
  23.110 +   subElems:   []
  23.111 + };
  23.112 +
  23.113 +firstGabeTransformRule.root.subElems[0].subElems[0] = tempElem;
  23.114 +
  23.115 +var tempProperty = 
  23.116 + { propertyName: "TypeOfElement",
  23.117 +   propertyValue: "Command",
  23.118 +   subProperties: []
  23.119 + };
  23.120 + 
  23.121 +tempElem.properties[0] = tempProperty;
  23.122 +
  23.123 +var tempProperty =
  23.124 + { propertyName: "CommandID",
  23.125 +   propertyValue: "GabePattPush",
  23.126 +   subProperties: []
  23.127 + };
  23.128 +
  23.129 +tempElem.properties[0].subProperties[0] = tempProperty;
  23.130 +
  23.131 + 
  23.132 +var tempProperty =
  23.133 + { propertyName: "TypeOfSyntacticStructure",
  23.134 +   propertyValue: "syntacticPatternRoot",
  23.135 +   subProperties: []
  23.136 + };
  23.137 +  
  23.138 +tempElem.properties[1] = tempProperty;
  23.139 +
  23.140 +//now add the ports to this Command syntactic pattern
  23.141 +var tempPort =
  23.142 + { element: tempElem,
  23.143 +   properties: [],
  23.144 +   pairedPorts: []
  23.145 + };
  23.146 +
  23.147 +tempElem.portsIn[0] = tempPort;
  23.148 +
  23.149 +//add properties to the port
  23.150 +tempPort.properties[0] =
  23.151 + { propertyName: "TypeOfPort",
  23.152 +   propertyValue: "dataComm",
  23.153 +   subProperties: 
  23.154 +    [{ propertyName: "TypeOfCommData",
  23.155 +      propertyValue: "GabePattStack",
  23.156 +      subProperties: []
  23.157 +    }]
  23.158 + };
  23.159 +
  23.160 +//check that syntax was done correctly..
  23.161 +fillText = tempPort.properties[0].subProperties[0].propertyName;
  23.162 +console.log("propertyName: " + fillText);
  23.163 +
  23.164 +
  23.165 +var tempPort =
  23.166 + { element: tempElem,
  23.167 +   properties: [],
  23.168 +   pairedPorts: []
  23.169 + };
  23.170 +
  23.171 +tempElem.portsIn[1] = tempPort;
  23.172 +
  23.173 +//add properties to the port
  23.174 +tempPort.properties[0] =
  23.175 + { propertyName: "TypeOfPort",
  23.176 +   propertyValue: "dataComm",
  23.177 +   subProperties: 
  23.178 +    [{ propertyName: "TypeOfCommData",
  23.179 +      propertyValue: "float",
  23.180 +      subProperties: []
  23.181 +    }]
  23.182 + };
  23.183 + 
  23.184 +
  23.185 +var tempPort =
  23.186 + { element: tempElem,
  23.187 +   properties: [],
  23.188 +   pairedPorts: []
  23.189 + };
  23.190 +
  23.191 +tempElem.portsOut[0] = tempPort;
  23.192 +
  23.193 +//add properties to the port
  23.194 +tempPort.properties[0] =
  23.195 + { propertyName: "TypeOfPort",
  23.196 +   propertyValue: "dataComm",
  23.197 +   subProperties: 
  23.198 +    [{ propertyName: "TypeOfCommData",
  23.199 +      propertyValue: "GabePattStack",
  23.200 +      subProperties: []
  23.201 +    }]
  23.202 + };
  23.203 +
  23.204 +//First command (push) done!  Now make second command (head)
  23.205 +var tempElem = 
  23.206 + { properties: [],
  23.207 +   portsIn:    [],
  23.208 +   portsOut:   [],
  23.209 +   subElems:   []
  23.210 + };
  23.211 +
  23.212 +firstGabeTransformRule.root.subElems[0].subElems[1] = tempElem;
  23.213 +
  23.214 +//getting tired of the temp this and temp that, just make object directly
  23.215 +tempElem.properties[0] = 
  23.216 + { propertyName: "TypeOfElement",
  23.217 +   propertyValue: "Command",
  23.218 +   subProperties: 
  23.219 +    [{ propertyName: "CommandID",
  23.220 +      propertyValue: "GabePattPop",
  23.221 +      subProperties: []
  23.222 +    }]
  23.223 + };
  23.224 +  
  23.225 +tempElem.properties[1] = 
  23.226 + { propertyName: "TypeOfSyntacticStructure",
  23.227 +   propertyValue: "syntacticPatternRoot",
  23.228 +   subProperties: []
  23.229 + };
  23.230 +
  23.231 +//now add the ports to this Command syntactic pattern
  23.232 +tempElem.portsIn[0] = 
  23.233 + { element: tempElem,
  23.234 +   properties: [],
  23.235 +   pairedPorts: []
  23.236 + };
  23.237 +
  23.238 +//add properties to the port
  23.239 +tempElem.portsIn[0].properties[0] =
  23.240 + { propertyName: "TypeOfPort",
  23.241 +   propertyValue: "dataComm",
  23.242 +   subProperties: 
  23.243 +    [{ propertyName: "TypeOfCommData",
  23.244 +      propertyValue: "GabePattStack",
  23.245 +      subProperties: []
  23.246 +    }]
  23.247 + };
  23.248 +
  23.249 +//next port
  23.250 +tempElem.portsOut[0] = 
  23.251 + { element: tempElem,
  23.252 +   properties: [],
  23.253 +   pairedPorts: []
  23.254 + };
  23.255 +
  23.256 +//add properties to the port
  23.257 +tempElem.portsOut[0].properties[0] =
  23.258 + { propertyName: "TypeOfPort",
  23.259 +   propertyValue: "dataComm",
  23.260 +   subProperties: 
  23.261 +    [{ propertyName: "TypeOfCommData",
  23.262 +      propertyValue: "GabePattStack",
  23.263 +      subProperties: []
  23.264 +    }]
  23.265 + };
  23.266 +
  23.267 +
  23.268 +//next port
  23.269 +tempElem.portsOut[1] = 
  23.270 + { element: tempElem,
  23.271 +   properties: [],
  23.272 +   pairedPorts: []
  23.273 + };
  23.274 +
  23.275 +//add properties to the port
  23.276 +tempElem.portsOut[1].properties[0] =
  23.277 + { propertyName: "TypeOfPort",
  23.278 +   propertyValue: "dataComm",
  23.279 +   subProperties: 
  23.280 +    [{ propertyName: "TypeOfCommData",
  23.281 +      propertyValue: "float",
  23.282 +      subProperties: []
  23.283 +    }]
  23.284 + };
  23.285 +
  23.286 +//now pair the ports to each other
  23.287 +var pushElem = firstGabeTransformRule.root.subElems[0].subElems[0];
  23.288 +var popElem = firstGabeTransformRule.root.subElems[0].subElems[1];
  23.289 +
  23.290 +pushElem.portsOut[0].pairedPorts[0] =
  23.291 +   popElem.portsIn[0];
  23.292 +popElem.portsIn[0].pairedPorts[0] =
  23.293 +   pushElem.portsOut[0];
  23.294 +
  23.295 +//Done with the query pattern!
  23.296 +
  23.297 +//========================================
  23.298 +//Now do the replace pattern
  23.299 +//========================================
  23.300 +var tempElem = 
  23.301 + { properties: [],
  23.302 +   portsIn:    [],
  23.303 +   portsOut:   [],
  23.304 +   subElems:   []
  23.305 + };
  23.306 +
  23.307 +firstGabeTransformRule.root.subElems[1].subElems[0] = tempElem;
  23.308 +
  23.309 +//This is the pass through command element
  23.310 +tempElem.properties[0] = 
  23.311 + { propertyName: "TypeOfElement",
  23.312 +   propertyValue: "Command",
  23.313 +   subProperties: 
  23.314 +    [{ propertyName: "CommandID",
  23.315 +      propertyValue: "GabePassThrough",
  23.316 +      subProperties: []
  23.317 +    }]
  23.318 + };
  23.319 +
  23.320 +tempElem.properties[1] = 
  23.321 + { propertyName: "TypeOfSyntacticStructure",
  23.322 +   propertyValue: "syntacticPatternRoot",
  23.323 +   subProperties: []
  23.324 + };
  23.325 +
  23.326 +//now add the ports to this Command syntactic pattern
  23.327 +tempElem.portsIn[0] = 
  23.328 + { element: tempElem,
  23.329 +   properties: [],
  23.330 +   pairedPorts: []
  23.331 + };
  23.332 +
  23.333 +//add properties to the port
  23.334 +tempElem.portsIn[0].properties[0] =
  23.335 + { propertyName: "TypeOfPort",
  23.336 +   propertyValue: "dataComm",
  23.337 +   subProperties: 
  23.338 +    [{ propertyName: "TypeOfCommData",
  23.339 +      propertyValue: "GabePattStack",
  23.340 +      subProperties: []
  23.341 +    }]
  23.342 + };
  23.343 +
  23.344 +//next port
  23.345 +tempElem.portsIn[1] = 
  23.346 + { element: tempElem,
  23.347 +   properties: [],
  23.348 +   pairedPorts: []
  23.349 + };
  23.350 +
  23.351 +//add properties to the port
  23.352 +tempElem.portsIn[1].properties[0] =
  23.353 + { propertyName: "TypeOfPort",
  23.354 +   propertyValue: "dataComm",
  23.355 +   subProperties: 
  23.356 +    [{ propertyName: "TypeOfCommData",
  23.357 +      propertyValue: "float",
  23.358 +      subProperties: []
  23.359 +    }]
  23.360 + };
  23.361 +
  23.362 +
  23.363 +//next port
  23.364 +tempElem.portsOut[0] = 
  23.365 + { element: tempElem,
  23.366 +   properties: [],
  23.367 +   pairedPorts: []
  23.368 + };
  23.369 +
  23.370 +//add properties to the port
  23.371 +tempElem.portsOut[0].properties[0] =
  23.372 + { propertyName: "TypeOfPort",
  23.373 +   propertyValue: "dataComm",
  23.374 +   subProperties: 
  23.375 +    [{ propertyName: "TypeOfCommData",
  23.376 +      propertyValue: "GabePattStack",
  23.377 +      subProperties: []
  23.378 +    }]
  23.379 + };
  23.380 +
  23.381 +
  23.382 +//next port
  23.383 +tempElem.portsOut[1] = 
  23.384 + { element: tempElem,
  23.385 +   properties: [],
  23.386 +   pairedPorts: []
  23.387 + };
  23.388 +
  23.389 +//add properties to the port
  23.390 +tempElem.portsOut[1].properties[0] =
  23.391 + { propertyName: "TypeOfPort",
  23.392 +   propertyValue: "dataComm",
  23.393 +   subProperties: 
  23.394 +    [{ propertyName: "TypeOfCommData",
  23.395 +      propertyValue: "float",
  23.396 +      subProperties: []
  23.397 +    }]
  23.398 + };
  23.399 +
  23.400 +//no paired ports in this one..  done done!!
  23.401 +
  23.402 +//print a few things, just to make sure the data structs are correctly
  23.403 +// created and can be traversed.
  23.404 +var passThroughCmd = firstGabeTransformRule.root.subElems[1].subElems[0];
  23.405 +fillText = passThroughCmd.portsOut[1].properties[0].subProperties[0].propertyValue;
  23.406 +console.log("propertyValue: " + fillText);
  23.407 +
  23.408 +//when this module is "required", the require statement will return the
  23.409 +// syntax graph data structure
  23.410 +return firstGabeTransformRule;
  23.411 +});
  23.412 +
  23.413 +
  23.414 +
  23.415 +
  23.416 +
  23.417 +
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/app/renderPOPSyntaxGraph.js	Sun Jul 06 12:02:12 2014 -0700
    24.3 @@ -0,0 +1,422 @@
    24.4 +
    24.5 +
    24.6 +define(function(require, exports, module) {
    24.7 +    var Engine           = require("famous/core/Engine");
    24.8 +    var Surface          = require("famous/core/Surface");
    24.9 +    var Modifier         = require("famous/core/Modifier");
   24.10 +    var Transform = require('famous/core/Transform');
   24.11 +    var StateModifier = require('famous/modifiers/StateModifier');
   24.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   24.13 +	var EventHandler      = require('famous/core/EventHandler');
   24.14 +	
   24.15 +    var mainContext = Engine.createContext();
   24.16 +	
   24.17 +	var boxSVG1 = '<svg width="55" height="55"><rect x="2" y="2" rx="20" ry="20" width="50" height="50" style="fill:none;stroke:black;stroke-width:5;opacity:1">';
   24.18 +	var boxSVG = [];
   24.19 +	boxSVG[1] = '<svg width="';
   24.20 +	boxSVG[2] = '" height="';
   24.21 +	boxSVG[3] = '"><rect x="';
   24.22 +	boxSVG[4] = '" y="';
   24.23 +	boxSVG[5] = '" rx="'
   24.24 +	boxSVG[6] = '" ry="';
   24.25 +	boxSVG[7] = '" width="'
   24.26 +	boxSVG[8] = '" height="'
   24.27 +	boxSVG[9] = '" style="fill:'
   24.28 +	boxSVG[10] = ';stroke:'
   24.29 +	boxSVG[11] = ';stroke-width:'
   24.30 +	boxSVG[12] = ';opacity:'
   24.31 +	boxSVG[13] = '" vector-effect="non-scaling-stroke">';
   24.32 +
   24.33 +	
   24.34 +//Draw a simple syntax graph, with a box of the correct color for each
   24.35 +// node, and curvy links with arrows going from text inside one node to
   24.36 +// text inside another node.
   24.37 +//Approach taken:
   24.38 +//Generate the SVG from calculations -- hold strings in an array, and
   24.39 +// build up an SVG string by adding string piece, then variable value then
   24.40 +// another string piece, and so on.
   24.41 +//Make each box a surface holding an SVG
   24.42 +//Sizing of the box happens inside the SVG string
   24.43 +//Positioning the box happens via a modifier
   24.44 +
   24.45 +//Make one container surface to hold each element node together with its
   24.46 +// properties and ports
   24.47 +//Make a separate surface for each SVG element -- one for each box, one for
   24.48 +// each text in a box, one for each curvy connector arrow between boxes or
   24.49 +// between texts.  
   24.50 +//For each surface, make a modifier that positions the box relative to the
   24.51 +// container surface's origin
   24.52 +//At the end, make transforms to move the entire container around
   24.53 +
   24.54 +	//elem1 is the root element from the Gabe Pattern syntax graph
   24.55 +	// here, make the visual elements that reproduce what see in the .pdf
   24.56 +    var elem1Container = new ContainerSurface({
   24.57 +        size: [600, 600], //size it big for now, trim to contents later
   24.58 +        properties: {
   24.59 +            overflow: 'hidden'
   24.60 +        }
   24.61 +    });
   24.62 +	
   24.63 +//==
   24.64 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
   24.65 +//  11:stroke-width 12:opacity
   24.66 +	var box1_1width = 66;
   24.67 +	var box1_1height = 86
   24.68 +//	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1width + 2) + boxSVG[2] + (box1_1height + 2) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1width + boxSVG[8] + box1_1height + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   24.69 +	var box1_1w = 66; var box1_1h = 86; var box1_1pad = 2;
   24.70 +	var boxSVGFromParts1_1 = boxSVG[1] + (box1_1w + box1_1pad) + boxSVG[2] + (box1_1h + box1_1pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_1w + boxSVG[8] + box1_1h + boxSVG[9] + 'none' + boxSVG[10] + 'red' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
   24.71 +	function getElemBox(){ return boxSVGFromParts1_1 };
   24.72 +
   24.73 +//== elem1 box 1 --> box1_1
   24.74 +	var box1_1 = new Surface({
   24.75 +	  size: [true, true],
   24.76 +      content: boxSVGFromParts1_1
   24.77 +	});
   24.78 +	var box1_1x = 0;
   24.79 +	var box1_1y = 2;
   24.80 +	var boxMod1_1_1 = new StateModifier({
   24.81 +        transform: Transform.translate(box1_1x, box1_1y, 0)
   24.82 +    });
   24.83 +
   24.84 +	//Below, calculate a bezier curve that is anchored at the end of such
   24.85 +	// text, so need the bounding box of a text element..  to do so, must 
   24.86 +	// first render the text!  That appears to be the only way to calculate
   24.87 +	// the bounding box.. there doesn't seem to be any other means to predict
   24.88 +	// it.
   24.89 +	//So, the famous infrastructure is a bit messed up when it comes to this
   24.90 +	// instead, will directly manipulate the DOM, by placing the text as
   24.91 +	// an SVG element with fill and stroke set to none so it is not
   24.92 +	// visible.  Then use the DOM call to get the bounding box.
   24.93 +	//Unfortunately, there doesn't appear to be any clean way!
   24.94 +	
   24.95 +	//Do this part once, the creating a DOM element and adding it to document
   24.96 +	var el1 =  document.createElement("div");
   24.97 +	document.body.appendChild(el1); //only need to append once then reuse
   24.98 +	
   24.99 +//== elem1 box 1 text 1 --> text1_1_1
  24.100 +	var text1_1_1 = new Surface({
  24.101 +	  size: [true, true],
  24.102 +      content: "properties",
  24.103 +      properties: {
  24.104 +        color: 'black',
  24.105 +        textAlign: 'left',
  24.106 +        fontSize: '11px',
  24.107 +        cursor: 'hand'
  24.108 +      }
  24.109 +	});
  24.110 +	
  24.111 +	//now set the SVG text string -- from this point down can be repeated 
  24.112 +	// for multiple strings without removing or re-adding the element, nor
  24.113 +	// fiddling with the DOM
  24.114 +	var text1_1_1_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_1.content + '</text> </svg>';
  24.115 +	//note that id is inside the text element! Also the fill and stroke are
  24.116 +	// null so that nothing paints
  24.117 +	el1.innerHTML = text1_1_1_SVG; 
  24.118 +
  24.119 +	//get the element -- this seems to be what triggers the bounding box calc
  24.120 +	var gottenElem = document.getElementById("svgText"); //use ID of the text elem
  24.121 +
  24.122 +	//get the box, take the values out of it, and display them
  24.123 +    var rect = gottenElem.getBoundingClientRect();
  24.124 +	console.log("svgText width: " + rect.width + " right: " + rect.right);
  24.125 +	
  24.126 +	var retText1_1_1 = {
  24.127 +		width: rect.width,
  24.128 +		height: rect.height,
  24.129 +		shape: text1_1_1_SVG
  24.130 +	}
  24.131 +	
  24.132 +	var text1_1_2 = new Surface({
  24.133 +	  size: [true, true],
  24.134 +      content: "portsIn",
  24.135 +      properties: {
  24.136 +        color: 'black',
  24.137 +        textAlign: 'left',
  24.138 +        fontSize: '11px',
  24.139 +        cursor: 'pointer'
  24.140 +      }
  24.141 +	});	
  24.142 +	//repeat for the next text surface
  24.143 +	var text1_1_2_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_2.content + '</text> </svg>';
  24.144 +	el1.innerHTML = text1_1_2_SVG; 
  24.145 +	var gottenElem = document.getElementById("svgText");
  24.146 +    var rect = gottenElem.getBoundingClientRect();
  24.147 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);
  24.148 +	
  24.149 +	var retText1_1_2 = {
  24.150 +		width: rect.width,
  24.151 +		height: rect.height,
  24.152 +		shape: text1_1_2_SVG
  24.153 +	}
  24.154 +	
  24.155 +	var text1_1_3 = new Surface({
  24.156 +	  size: [true, true],
  24.157 +      content: "portsOut",
  24.158 +      properties: {
  24.159 +        color: 'black',
  24.160 +        textAlign: 'left',
  24.161 +        fontSize: '11px',
  24.162 +        cursor: 'pointer'
  24.163 +      }
  24.164 +	});
  24.165 +	//repeat for the next text surface
  24.166 +	var text1_1_3_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_3.content + '</text> </svg>';
  24.167 +	el1.innerHTML = text1_1_3_SVG; 
  24.168 +	var gottenElem = document.getElementById("svgText");
  24.169 +    var rect = gottenElem.getBoundingClientRect();
  24.170 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);
  24.171 +	
  24.172 +	var retText1_1_3 = {
  24.173 +		width: rect.width,
  24.174 +		height: rect.height,
  24.175 +		shape: text1_1_3_SVG
  24.176 +	}
  24.177 +	
  24.178 +	var text1_1_4 = new Surface({
  24.179 +	  size: [true, true],
  24.180 +      content: "subElems",
  24.181 +      properties: {
  24.182 +        color: 'black',
  24.183 +        textAlign: 'left',
  24.184 +        fontSize: '11px',
  24.185 +        cursor: 'pointer'
  24.186 +     }
  24.187 +	});
  24.188 +	//repeat for the next text surface
  24.189 +	var text1_1_4_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_1_4.content + '</text> </svg>';
  24.190 +	el1.innerHTML = text1_1_4_SVG; 
  24.191 +	var gottenElem = document.getElementById("svgText");
  24.192 +    var rect = gottenElem.getBoundingClientRect();
  24.193 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);
  24.194 +	
  24.195 +	var retText1_1_4 = {
  24.196 +		width: rect.width,
  24.197 +		height: rect.height,
  24.198 +		shape: text1_1_4_SVG
  24.199 +	}
  24.200 +	
  24.201 +	
  24.202 +//== elem 1 box 1 text 1 mod 1 -> textMod1_1_1_1
  24.203 +	var text1_1_1x = 8;
  24.204 +	var text1_1_1y = 8;
  24.205 +	var textMod1_1_1_1 = new StateModifier({
  24.206 +        transform: Transform.translate(text1_1_1x, text1_1_1y, 0)
  24.207 +    });
  24.208 +	text1_1_1_SVG.x = 8; text1_1_1_SVG.y = 0; //subtract box x & y
  24.209 +	var textMod1_1_2_1 = new StateModifier({
  24.210 +        transform: Transform.translate(8, 25, 0)
  24.211 +    });
  24.212 +	text1_1_2_SVG.x = 8; text1_1_2_SVG.y = 23; //subtract box x & y
  24.213 +	var textMod1_1_3_1 = new StateModifier({
  24.214 +        transform: Transform.translate(8, 42, 0)
  24.215 +    });
  24.216 +	text1_1_3_SVG.x = 8; text1_1_3_SVG.y = 40; //subtract box x & y
  24.217 +	var textMod1_1_4_1 = new StateModifier({
  24.218 +        transform: Transform.translate(8, 59, 0)
  24.219 +    });
  24.220 +	text1_1_4_SVG.x = 8; text1_1_4_SVG.y = 57; //subtract box x & y
  24.221 +//==
  24.222 +	elem1Container.add(boxMod1_1_1).add(box1_1);
  24.223 +	elem1Container.add(textMod1_1_1_1).add(text1_1_1);
  24.224 +	elem1Container.add(textMod1_1_2_1).add(text1_1_2);
  24.225 +	elem1Container.add(textMod1_1_3_1).add(text1_1_3);
  24.226 +	elem1Container.add(textMod1_1_4_1).add(text1_1_4);
  24.227 +
  24.228 +//== elem 1 box 2 --> box1_2
  24.229 +//	1:width 2:height 3:x 4:y 5:rx 6:ry 7:width 8:height 9:fill 10:stroke
  24.230 +//  11:stroke-width 12:opacity
  24.231 +	var box1_2w = 183; var box1_2h = 69; var box1_2pad = 2;
  24.232 +	var boxSVGFromParts1_2 = boxSVG[1] + (box1_2w + box1_2pad) + boxSVG[2] + (box1_2h + box1_2pad) + boxSVG[3] + '1' + boxSVG[4] + '1' + boxSVG[5] + '20' + boxSVG[6] + '20' + boxSVG[7] + box1_2w + boxSVG[8] + box1_2h + boxSVG[9] + 'none' + boxSVG[10] + 'green' + boxSVG[11] + '2' + boxSVG[12] + '1' + boxSVG[13];
  24.233 +	
  24.234 +	function getPropertiesBox(){ return boxSVGFromParts1_2 };
  24.235 +	
  24.236 +	var box1_2 = new Surface({
  24.237 +	  size: [true, true],
  24.238 +      content: boxSVGFromParts1_2
  24.239 + 	});
  24.240 +	var box1_2x = 100;
  24.241 +	var box1_2y = 2;
  24.242 +	var boxMod1_2_1 = new StateModifier({
  24.243 +        transform: Transform.translate(box1_2x, box1_2y, 0)
  24.244 +    });
  24.245 +//== elem 1 box 2 text 1 --> text1_2_1
  24.246 +	var text1_2_1 = new Surface({
  24.247 +	  size: [true, true],
  24.248 +      content: "propertyName:  TypeOfElement",
  24.249 +      properties: {
  24.250 +        color: 'black',
  24.251 +        textAlign: 'left',
  24.252 +        fontSize: '11px',
  24.253 +        cursor: 'pointer'
  24.254 +      }
  24.255 +	});
  24.256 +	//repeat for the next text surface
  24.257 +	var text1_2_1_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:blue;stroke:none" id="svgText">' + text1_2_1.content + '</text> </svg>';
  24.258 +	el1.innerHTML = text1_2_1_SVG; 
  24.259 +	var gottenElem = document.getElementById("svgText");
  24.260 +    var rect = gottenElem.getBoundingClientRect();
  24.261 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);	
  24.262 +	var retText1_2_1 = {
  24.263 +		width: rect.width,
  24.264 +		height: rect.height,
  24.265 +		shape: text1_2_1_SVG
  24.266 +	}
  24.267 +	
  24.268 +	
  24.269 +	var text1_2_2 = new Surface({
  24.270 +	  size: [true, true],
  24.271 +      content: "propertyValue:  GabeTransformRule",
  24.272 +      properties: {
  24.273 +        color: 'black',
  24.274 +        textAlign: 'left',
  24.275 +        fontSize: '11px',
  24.276 +        cursor: 'pointer'
  24.277 +      }
  24.278 +	});
  24.279 +	//repeat for the next text surface
  24.280 +	var text1_2_2_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:red;stroke:none" id="svgText">' + text1_2_2.content + '</text> </svg>';
  24.281 +	el1.innerHTML = text1_2_2_SVG; 
  24.282 +	var gottenElem = document.getElementById("svgText");
  24.283 +    var rect = gottenElem.getBoundingClientRect();
  24.284 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);	
  24.285 +	var retText1_2_2 = {
  24.286 +		width: rect.width,
  24.287 +		height: rect.height,
  24.288 +		shape: text1_2_2_SVG
  24.289 +	}
  24.290 +
  24.291 +	var text1_2_3 = new Surface({
  24.292 +	  size: [true, true],
  24.293 +      content: "subProperties",
  24.294 +      properties: {
  24.295 +        color: 'black',
  24.296 +        textAlign: 'left',
  24.297 +        fontSize: '11px',
  24.298 +        cursor: 'pointer'
  24.299 +      }
  24.300 +	});
  24.301 +	//repeat for the next text surface
  24.302 +	var text1_2_3_SVG = '<svg id="svgTextHolder">  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText">' + text1_2_3.content + '</text> </svg>';
  24.303 +	el1.innerHTML = text1_2_3_SVG; 
  24.304 +	var gottenElem = document.getElementById("svgText");
  24.305 +    var rect = gottenElem.getBoundingClientRect();
  24.306 +	console.log("svgText: " + gottenElem.textContent + " width: " + rect.width + " right: " + rect.right);	
  24.307 +	var retText1_2_3 = {
  24.308 +		width: rect.width,
  24.309 +		height: rect.height,
  24.310 +		shape: text1_2_3_SVG
  24.311 +	}
  24.312 +
  24.313 +//==
  24.314 +	var textMod1_2_1_1 = new StateModifier({
  24.315 +        transform: Transform.translate(108, 8, 0)
  24.316 +    });
  24.317 +	text1_2_1_SVG.x = 8; text1_2_1_SVG.y = 6; //subtract box x & y
  24.318 +	var textMod1_2_2_1 = new StateModifier({
  24.319 +        transform: Transform.translate(108, 25, 0)
  24.320 +    });
  24.321 +	text1_2_2_SVG.x = 8; text1_2_2_SVG.y = 23; //subtract box x & y
  24.322 +	var textMod1_2_3_1 = new StateModifier({
  24.323 +        transform: Transform.translate(108, 42, 0)
  24.324 +    });
  24.325 +	text1_2_3_SVG.x = 8; text1_2_3_SVG.y = 40; //subtract box x & y
  24.326 +//==
  24.327 +	elem1Container.add(boxMod1_2_1).add(box1_2);
  24.328 +	elem1Container.add(textMod1_2_1_1).add(text1_2_1);
  24.329 +	elem1Container.add(textMod1_2_2_1).add(text1_2_2);
  24.330 +	elem1Container.add(textMod1_2_3_1).add(text1_2_3);
  24.331 +
  24.332 +//Now, add bezier curve, in SVG..
  24.333 +//One end point is the end of "properties" text surface inside the elem box
  24.334 +//Other end point is the middle of side of properties box
  24.335 +	var bezSVG = [];
  24.336 +	bezSVG[1] = '<svg width="'
  24.337 +	bezSVG[2] = '" height="'
  24.338 +	bezSVG[3] = '"><path d="M' //start pt x
  24.339 +	bezSVG[4] = ','  //start pt y
  24.340 +	bezSVG[5] = ' C' //control pt 1 x
  24.341 +	bezSVG[6] = ','  //control pt 1 y
  24.342 +	bezSVG[7] = ' '  //control pt 2 x
  24.343 +	bezSVG[8] = ','  //control pt 2 y
  24.344 +	bezSVG[9] = ' '  //end pt x
  24.345 +	bezSVG[10] = ',' //end pt y
  24.346 +	bezSVG[11] = '" style="fill:'
  24.347 +	bezSVG[12] = ';stroke:'
  24.348 +	bezSVG[13] = ';stroke-width:'
  24.349 +	bezSVG[14] = ';opacity:'
  24.350 +	bezSVG[15] = '" vector-effect="non-scaling-stroke">';
  24.351 +	
  24.352 +	//now calculate the end points of the curve -- they connect to the
  24.353 +	// right edge of the "properties" text in the left box, and to the
  24.354 +	// middle of the left side of the right box
  24.355 +	var bezPoints = [{},{}];
  24.356 +	var fontSz = 11;
  24.357 +	bezPoints[0].x = box1_1x + box1_1w;
  24.358 +	bezPoints[0].y = text1_1_1y + fontSz/2 + 8;
  24.359 +	bezPoints[1].x = box1_2x;
  24.360 +	bezPoints[1].y = box1_2y + (box1_2h+box1_2pad)/2;
  24.361 +
  24.362 +	var controlPoints = [];
  24.363 +	controlPoints[0] = {x:bezPoints[1].x, y:bezPoints[0].y};
  24.364 +	controlPoints[1] = {x:bezPoints[0].x, y:bezPoints[1].y};
  24.365 +
  24.366 +
  24.367 +	//	1:width 2:height 3:st x 4:st y 5:c1 x 6:c1 y 7:c2 x 8:c2 y 9: end x
  24.368 +	// 10: end y 11:fill 12:stroke 13:stroke-width 14:opacity
  24.369 +	var bezSVG1 = "";
  24.370 +	bezSVG1 += bezSVG[1] + 200;//(bezPoints[1].x - bezPoints[0].x + 6);
  24.371 +	bezSVG1 += bezSVG[2] + 200;//(bezPoints[0].y - bezPoints[1].y + 6);
  24.372 +	bezSVG1 += bezSVG[3] + bezPoints[0].x; 
  24.373 +	bezSVG1 += bezSVG[4] + bezPoints[0].y; 
  24.374 +	bezSVG1 += bezSVG[5] + controlPoints[0].x;
  24.375 +	bezSVG1 += bezSVG[6] + controlPoints[0].y;
  24.376 +	bezSVG1 += bezSVG[7] + controlPoints[1].x;
  24.377 +	bezSVG1 += bezSVG[8] + controlPoints[1].y;
  24.378 +	bezSVG1 += bezSVG[9] + bezPoints[1].x; 
  24.379 +	bezSVG1 += bezSVG[10] + bezPoints[1].y; 
  24.380 +	bezSVG1 += bezSVG[11] + 'none' + bezSVG[12] + 'black' + bezSVG[13] + '2' + bezSVG[14] + '1' + bezSVG[15];
  24.381 +	
  24.382 +	var bez1_1 = new Surface({
  24.383 +	  size: [true, true],
  24.384 +      content: bezSVG1
  24.385 + 	});
  24.386 +
  24.387 +	elem1Container.add(bez1_1);
  24.388 +
  24.389 +//for some reason, the way use el1 above makes the DOM stop rendering
  24.390 +// So, in order to get these other elements to render, first remove
  24.391 +// the element that have been using to calc bounding box sizes..
  24.392 +var elToRemove = document.getElementById("svgText");
  24.393 +elToRemove.parentNode.parentNode.removeChild(elToRemove.parentNode);
  24.394 +
  24.395 +//okay, now new DOM elements will render
  24.396 +var el2 =  document.createElement("span")
  24.397 +var displayStr = bezSVG1.replace(/</g, "&lt");//make the html display as text
  24.398 +el2.innerHTML = (displayStr + "<br>");
  24.399 +document.body.appendChild(el2);
  24.400 +console.log("bez svg: " + bezSVG1);
  24.401 +
  24.402 +//== elem 1 Modifer 1 --> contMod1_1
  24.403 +	var contMod1_1 = new StateModifier({
  24.404 +        transform: Transform.translate(50, 50, 0)
  24.405 +    });
  24.406 +	var contMod1_2 = new StateModifier({
  24.407 +		transform: Transform.scale(1, 1)
  24.408 +    });	
  24.409 +//==
  24.410 +
  24.411 +	//cause this all to be painted, by adding to the main context
  24.412 +	mainContext.add(contMod1_1).add(contMod1_2).add(elem1Container);
  24.413 +	
  24.414 +	return {
  24.415 +		getElemBox: getElemBox,
  24.416 +		getText1_1_1: retText1_1_1,
  24.417 +		getText1_1_2: retText1_1_2,
  24.418 +		getText1_1_3: retText1_1_3,
  24.419 +		getText1_1_4: retText1_1_4,
  24.420 +		getPropertiesBox: getPropertiesBox,
  24.421 +		getText1_2_1: retText1_2_1,
  24.422 +		getText1_2_2: retText1_2_2,
  24.423 +		getText1_2_3: retText1_2_3
  24.424 +	}
  24.425 +});
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/classList.js	Sun Jul 06 12:02:12 2014 -0700
    25.3 @@ -0,0 +1,138 @@
    25.4 +
    25.5 +/*
    25.6 + * classList.js: Cross-browser full element.classList implementation.
    25.7 + * 2011-06-15
    25.8 + *
    25.9 + * By Eli Grey, http://eligrey.com
   25.10 + * Public Domain.
   25.11 + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
   25.12 + */
   25.13 +
   25.14 +/*global self, document, DOMException */
   25.15 +
   25.16 +/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
   25.17 +
   25.18 +if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
   25.19 +
   25.20 +(function (view) {
   25.21 +
   25.22 +"use strict";
   25.23 +
   25.24 +var
   25.25 +	  classListProp = "classList"
   25.26 +	, protoProp = "prototype"
   25.27 +	, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
   25.28 +	, objCtr = Object
   25.29 +	, strTrim = String[protoProp].trim || function () {
   25.30 +		return this.replace(/^\s+|\s+$/g, "");
   25.31 +	}
   25.32 +	, arrIndexOf = Array[protoProp].indexOf || function (item) {
   25.33 +		var
   25.34 +			  i = 0
   25.35 +			, len = this.length
   25.36 +		;
   25.37 +		for (; i < len; i++) {
   25.38 +			if (i in this && this[i] === item) {
   25.39 +				return i;
   25.40 +			}
   25.41 +		}
   25.42 +		return -1;
   25.43 +	}
   25.44 +	// Vendors: please allow content code to instantiate DOMExceptions
   25.45 +	, DOMEx = function (type, message) {
   25.46 +		this.name = type;
   25.47 +		this.code = DOMException[type];
   25.48 +		this.message = message;
   25.49 +	}
   25.50 +	, checkTokenAndGetIndex = function (classList, token) {
   25.51 +		if (token === "") {
   25.52 +			throw new DOMEx(
   25.53 +				  "SYNTAX_ERR"
   25.54 +				, "An invalid or illegal string was specified"
   25.55 +			);
   25.56 +		}
   25.57 +		if (/\s/.test(token)) {
   25.58 +			throw new DOMEx(
   25.59 +				  "INVALID_CHARACTER_ERR"
   25.60 +				, "String contains an invalid character"
   25.61 +			);
   25.62 +		}
   25.63 +		return arrIndexOf.call(classList, token);
   25.64 +	}
   25.65 +	, ClassList = function (elem) {
   25.66 +		var
   25.67 +			  trimmedClasses = strTrim.call(elem.className)
   25.68 +			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
   25.69 +			, i = 0
   25.70 +			, len = classes.length
   25.71 +		;
   25.72 +		for (; i < len; i++) {
   25.73 +			this.push(classes[i]);
   25.74 +		}
   25.75 +		this._updateClassName = function () {
   25.76 +			elem.className = this.toString();
   25.77 +		};
   25.78 +	}
   25.79 +	, classListProto = ClassList[protoProp] = []
   25.80 +	, classListGetter = function () {
   25.81 +		return new ClassList(this);
   25.82 +	}
   25.83 +;
   25.84 +// Most DOMException implementations don't allow calling DOMException's toString()
   25.85 +// on non-DOMExceptions. Error's toString() is sufficient here.
   25.86 +DOMEx[protoProp] = Error[protoProp];
   25.87 +classListProto.item = function (i) {
   25.88 +	return this[i] || null;
   25.89 +};
   25.90 +classListProto.contains = function (token) {
   25.91 +	token += "";
   25.92 +	return checkTokenAndGetIndex(this, token) !== -1;
   25.93 +};
   25.94 +classListProto.add = function (token) {
   25.95 +	token += "";
   25.96 +	if (checkTokenAndGetIndex(this, token) === -1) {
   25.97 +		this.push(token);
   25.98 +		this._updateClassName();
   25.99 +	}
  25.100 +};
  25.101 +classListProto.remove = function (token) {
  25.102 +	token += "";
  25.103 +	var index = checkTokenAndGetIndex(this, token);
  25.104 +	if (index !== -1) {
  25.105 +		this.splice(index, 1);
  25.106 +		this._updateClassName();
  25.107 +	}
  25.108 +};
  25.109 +classListProto.toggle = function (token) {
  25.110 +	token += "";
  25.111 +	if (checkTokenAndGetIndex(this, token) === -1) {
  25.112 +		this.add(token);
  25.113 +	} else {
  25.114 +		this.remove(token);
  25.115 +	}
  25.116 +};
  25.117 +classListProto.toString = function () {
  25.118 +	return this.join(" ");
  25.119 +};
  25.120 +
  25.121 +if (objCtr.defineProperty) {
  25.122 +	var classListPropDesc = {
  25.123 +		  get: classListGetter
  25.124 +		, enumerable: true
  25.125 +		, configurable: true
  25.126 +	};
  25.127 +	try {
  25.128 +		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  25.129 +	} catch (ex) { // IE 8 doesn't support enumerable:true
  25.130 +		if (ex.number === -0x7FF5EC54) {
  25.131 +			classListPropDesc.enumerable = false;
  25.132 +			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  25.133 +		}
  25.134 +	}
  25.135 +} else if (objCtr[protoProp].__defineGetter__) {
  25.136 +	elemCtrProto.__defineGetter__(classListProp, classListGetter);
  25.137 +}
  25.138 +
  25.139 +}(self));
  25.140 +
  25.141 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.css	Sun Jul 06 12:02:12 2014 -0700
    26.3 @@ -0,0 +1,77 @@
    26.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
    26.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
    26.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    26.7 + *
    26.8 + * Owner: mark@famo.us
    26.9 + * @license MPL 2.0
   26.10 + * @copyright Famous Industries, Inc. 2014
   26.11 + */
   26.12 +
   26.13 +
   26.14 +html {
   26.15 +    width: 100%;
   26.16 +    height: 100%;
   26.17 +    margin: 0px;
   26.18 +    padding: 0px;
   26.19 +    overflow: hidden;
   26.20 +    -webkit-transform-style: preserve-3d;
   26.21 +    transform-style: preserve-3d;
   26.22 +}
   26.23 +
   26.24 +body {
   26.25 +    position: absolute;
   26.26 +    width: 100%;
   26.27 +    height: 100%;
   26.28 +    margin: 0px;
   26.29 +    padding: 0px;
   26.30 +    -webkit-transform-style: preserve-3d;
   26.31 +    transform-style: preserve-3d;
   26.32 +    -webkit-font-smoothing: antialiased;
   26.33 +    -webkit-tap-highlight-color: transparent;
   26.34 +    -webkit-perspective: 0;
   26.35 +    perspective: none;
   26.36 +    overflow: hidden;
   26.37 +}
   26.38 +
   26.39 +.famous-container, .famous-group {
   26.40 +    position: absolute;
   26.41 +    top: 0px;
   26.42 +    left: 0px;
   26.43 +    bottom: 0px;
   26.44 +    right: 0px;
   26.45 +    overflow: visible;
   26.46 +    -webkit-transform-style: preserve-3d;
   26.47 +    transform-style: preserve-3d;
   26.48 +    -webkit-backface-visibility: visible;
   26.49 +    backface-visibility: visible;
   26.50 +    pointer-events: none;
   26.51 +}
   26.52 +
   26.53 +.famous-group {
   26.54 +    width: 0px;
   26.55 +    height: 0px;
   26.56 +    margin: 0px;
   26.57 +    padding: 0px;
   26.58 +    -webkit-transform-style: preserve-3d;
   26.59 +    transform-style: preserve-3d;
   26.60 +}
   26.61 +
   26.62 +.famous-surface {
   26.63 +    position: absolute;
   26.64 +    -webkit-transform-origin: center center;
   26.65 +    transform-origin: center center;
   26.66 +    -webkit-backface-visibility: hidden;
   26.67 +    backface-visibility: hidden;
   26.68 +    -webkit-transform-style: flat;
   26.69 +    transform-style: preserve-3d; /* performance */
   26.70 +    -webkit-box-sizing: border-box;
   26.71 +    -moz-box-sizing: border-box;
   26.72 +    -webkit-tap-highlight-color: transparent;
   26.73 +    pointer-events: auto;
   26.74 +}
   26.75 +
   26.76 +.famous-container-group {
   26.77 +    position: relative;
   26.78 +    width: 100%;
   26.79 +    height: 100%;
   26.80 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous.js	Sun Jul 06 12:02:12 2014 -0700
    27.3 @@ -0,0 +1,17609 @@
    27.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
    27.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
    27.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    27.7 + *
    27.8 + * Owner: mark@famo.us
    27.9 + * @license MPL 2.0
   27.10 + * @copyright Famous Industries, Inc. 2014
   27.11 + */
   27.12 +
   27.13 +define('famous/core/Entity',['require','exports','module'],function(require, exports, module) {
   27.14 +    /**
   27.15 +     * A singleton that maintains a global registry of Surfaces.
   27.16 +     *   Private.
   27.17 +     *
   27.18 +     * @private
   27.19 +     * @static
   27.20 +     * @class Entity
   27.21 +     */
   27.22 +
   27.23 +    var entities = [];
   27.24 +
   27.25 +    /**
   27.26 +     * Get entity from global index.
   27.27 +     *
   27.28 +     * @private
   27.29 +     * @method get
   27.30 +     * @param {Number} id entity reigstration id
   27.31 +     * @return {Surface} entity in the global index
   27.32 +     */
   27.33 +    function get(id) {
   27.34 +        return entities[id];
   27.35 +    }
   27.36 +
   27.37 +    /**
   27.38 +     * Overwrite entity in the global index
   27.39 +     *
   27.40 +     * @private
   27.41 +     * @method set
   27.42 +     * @param {Number} id entity reigstration id
   27.43 +     * @return {Surface} entity to add to the global index
   27.44 +     */
   27.45 +    function set(id, entity) {
   27.46 +        entities[id] = entity;
   27.47 +    }
   27.48 +
   27.49 +    /**
   27.50 +     * Add entity to global index
   27.51 +     *
   27.52 +     * @private
   27.53 +     * @method register
   27.54 +     * @param {Surface} entity to add to global index
   27.55 +     * @return {Number} new id
   27.56 +     */
   27.57 +    function register(entity) {
   27.58 +        var id = entities.length;
   27.59 +        set(id, entity);
   27.60 +        return id;
   27.61 +    }
   27.62 +
   27.63 +    /**
   27.64 +     * Remove entity from global index
   27.65 +     *
   27.66 +     * @private
   27.67 +     * @method unregister
   27.68 +     * @param {Number} id entity reigstration id
   27.69 +     */
   27.70 +    function unregister(id) {
   27.71 +        set(id, null);
   27.72 +    }
   27.73 +
   27.74 +    module.exports = {
   27.75 +        register: register,
   27.76 +        unregister: unregister,
   27.77 +        get: get,
   27.78 +        set: set
   27.79 +    };
   27.80 +});
   27.81 +
   27.82 +/* This Source Code Form is subject to the terms of the Mozilla Public
   27.83 + * License, v. 2.0. If a copy of the MPL was not distributed with this
   27.84 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   27.85 + *
   27.86 + * Owner: mark@famo.us
   27.87 + * @license MPL 2.0
   27.88 + * @copyright Famous Industries, Inc. 2014
   27.89 + */
   27.90 +
   27.91 +define('famous/core/Transform',['require','exports','module'],function(require, exports, module) {
   27.92 +
   27.93 +    /**
   27.94 +     *  A high-performance static matrix math library used to calculate
   27.95 +     *    affine transforms on surfaces and other renderables.
   27.96 +     *    Famo.us uses 4x4 matrices corresponding directly to
   27.97 +     *    WebKit matrices (column-major order).
   27.98 +     *
   27.99 +     *    The internal "type" of a Matrix is a 16-long float array in
  27.100 +     *    row-major order, with:
  27.101 +     *    elements [0],[1],[2],[4],[5],[6],[8],[9],[10] forming the 3x3
  27.102 +     *          transformation matrix;
  27.103 +     *    elements [12], [13], [14] corresponding to the t_x, t_y, t_z
  27.104 +     *           translation;
  27.105 +     *    elements [3], [7], [11] set to 0;
  27.106 +     *    element [15] set to 1.
  27.107 +     *    All methods are static.
  27.108 +     *
  27.109 +     * @static
  27.110 +     *
  27.111 +     * @class Transform
  27.112 +     */
  27.113 +    var Transform = {};
  27.114 +
  27.115 +    // WARNING: these matrices correspond to WebKit matrices, which are
  27.116 +    //    transposed from their math counterparts
  27.117 +    Transform.precision = 1e-6;
  27.118 +    Transform.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  27.119 +
  27.120 +    /**
  27.121 +     * Multiply two or more Transform matrix types to return a Transform matrix.
  27.122 +     *
  27.123 +     * @method multiply4x4
  27.124 +     * @static
  27.125 +     * @param {Transform} a left Transform
  27.126 +     * @param {Transform} b right Transform
  27.127 +     * @return {Transform}
  27.128 +     */
  27.129 +    Transform.multiply4x4 = function multiply4x4(a, b) {
  27.130 +        return [
  27.131 +            a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
  27.132 +            a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
  27.133 +            a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
  27.134 +            a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
  27.135 +            a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
  27.136 +            a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
  27.137 +            a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
  27.138 +            a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
  27.139 +            a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
  27.140 +            a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
  27.141 +            a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
  27.142 +            a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
  27.143 +            a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
  27.144 +            a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
  27.145 +            a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
  27.146 +            a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]
  27.147 +        ];
  27.148 +    };
  27.149 +
  27.150 +    /**
  27.151 +     * Fast-multiply two or more Transform matrix types to return a
  27.152 +     *    Matrix, assuming bottom row on each is [0 0 0 1].
  27.153 +     *
  27.154 +     * @method multiply
  27.155 +     * @static
  27.156 +     * @param {Transform} a left Transform
  27.157 +     * @param {Transform} b right Transform
  27.158 +     * @return {Transform}
  27.159 +     */
  27.160 +    Transform.multiply = function multiply(a, b) {
  27.161 +        return [
  27.162 +            a[0] * b[0] + a[4] * b[1] + a[8] * b[2],
  27.163 +            a[1] * b[0] + a[5] * b[1] + a[9] * b[2],
  27.164 +            a[2] * b[0] + a[6] * b[1] + a[10] * b[2],
  27.165 +            0,
  27.166 +            a[0] * b[4] + a[4] * b[5] + a[8] * b[6],
  27.167 +            a[1] * b[4] + a[5] * b[5] + a[9] * b[6],
  27.168 +            a[2] * b[4] + a[6] * b[5] + a[10] * b[6],
  27.169 +            0,
  27.170 +            a[0] * b[8] + a[4] * b[9] + a[8] * b[10],
  27.171 +            a[1] * b[8] + a[5] * b[9] + a[9] * b[10],
  27.172 +            a[2] * b[8] + a[6] * b[9] + a[10] * b[10],
  27.173 +            0,
  27.174 +            a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12],
  27.175 +            a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13],
  27.176 +            a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14],
  27.177 +            1
  27.178 +        ];
  27.179 +    };
  27.180 +
  27.181 +    /**
  27.182 +     * Return a Transform translated by additional amounts in each
  27.183 +     *    dimension. This is equivalent to the result of
  27.184 +     *
  27.185 +     *    Transform.multiply(Matrix.translate(t[0], t[1], t[2]), m).
  27.186 +     *
  27.187 +     * @method thenMove
  27.188 +     * @static
  27.189 +     * @param {Transform} m a Transform
  27.190 +     * @param {Array.Number} t floats delta vector of length 2 or 3
  27.191 +     * @return {Transform}
  27.192 +     */
  27.193 +    Transform.thenMove = function thenMove(m, t) {
  27.194 +        if (!t[2]) t[2] = 0;
  27.195 +        return [m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, m[12] + t[0], m[13] + t[1], m[14] + t[2], 1];
  27.196 +    };
  27.197 +
  27.198 +    /**
  27.199 +     * Return a Transform atrix which represents the result of a transform matrix
  27.200 +     *    applied after a move. This is faster than the equivalent multiply.
  27.201 +     *    This is equivalent to the result of:
  27.202 +     *
  27.203 +     *    Transform.multiply(m, Transform.translate(t[0], t[1], t[2])).
  27.204 +     *
  27.205 +     * @method moveThen
  27.206 +     * @static
  27.207 +     * @param {Array.Number} v vector representing initial movement
  27.208 +     * @param {Transform} m matrix to apply afterwards
  27.209 +     * @return {Transform} the resulting matrix
  27.210 +     */
  27.211 +    Transform.moveThen = function moveThen(v, m) {
  27.212 +        if (!v[2]) v[2] = 0;
  27.213 +        var t0 = v[0] * m[0] + v[1] * m[4] + v[2] * m[8];
  27.214 +        var t1 = v[0] * m[1] + v[1] * m[5] + v[2] * m[9];
  27.215 +        var t2 = v[0] * m[2] + v[1] * m[6] + v[2] * m[10];
  27.216 +        return Transform.thenMove(m, [t0, t1, t2]);
  27.217 +    };
  27.218 +
  27.219 +    /**
  27.220 +     * Return a Transform which represents a translation by specified
  27.221 +     *    amounts in each dimension.
  27.222 +     *
  27.223 +     * @method translate
  27.224 +     * @static
  27.225 +     * @param {Number} x x translation
  27.226 +     * @param {Number} y y translation
  27.227 +     * @param {Number} z z translation
  27.228 +     * @return {Transform}
  27.229 +     */
  27.230 +    Transform.translate = function translate(x, y, z) {
  27.231 +        if (z === undefined) z = 0;
  27.232 +        return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
  27.233 +    };
  27.234 +
  27.235 +    /**
  27.236 +     * Return a Transform scaled by a vector in each
  27.237 +     *    dimension. This is a more performant equivalent to the result of
  27.238 +     *
  27.239 +     *    Transform.multiply(Transform.scale(s[0], s[1], s[2]), m).
  27.240 +     *
  27.241 +     * @method thenScale
  27.242 +     * @static
  27.243 +     * @param {Transform} m a matrix
  27.244 +     * @param {Array.Number} s delta vector (array of floats &&
  27.245 +     *    array.length == 3)
  27.246 +     * @return {Transform}
  27.247 +     */
  27.248 +    Transform.thenScale = function thenScale(m, s) {
  27.249 +        return [
  27.250 +            s[0] * m[0], s[1] * m[1], s[2] * m[2], 0,
  27.251 +            s[0] * m[4], s[1] * m[5], s[2] * m[6], 0,
  27.252 +            s[0] * m[8], s[1] * m[9], s[2] * m[10], 0,
  27.253 +            s[0] * m[12], s[1] * m[13], s[2] * m[14], 1
  27.254 +        ];
  27.255 +    };
  27.256 +
  27.257 +    /**
  27.258 +     * Return a Transform which represents a scale by specified amounts
  27.259 +     *    in each dimension.
  27.260 +     *
  27.261 +     * @method scale
  27.262 +     * @static
  27.263 +     * @param {Number} x x scale factor
  27.264 +     * @param {Number} y y scale factor
  27.265 +     * @param {Number} z z scale factor
  27.266 +     * @return {Transform}
  27.267 +     */
  27.268 +    Transform.scale = function scale(x, y, z) {
  27.269 +        if (z === undefined) z = 1;
  27.270 +        return [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1];
  27.271 +    };
  27.272 +
  27.273 +    /**
  27.274 +     * Return a Transform which represents a clockwise
  27.275 +     *    rotation around the x axis.
  27.276 +     *
  27.277 +     * @method rotateX
  27.278 +     * @static
  27.279 +     * @param {Number} theta radians
  27.280 +     * @return {Transform}
  27.281 +     */
  27.282 +    Transform.rotateX = function rotateX(theta) {
  27.283 +        var cosTheta = Math.cos(theta);
  27.284 +        var sinTheta = Math.sin(theta);
  27.285 +        return [1, 0, 0, 0, 0, cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1];
  27.286 +    };
  27.287 +
  27.288 +    /**
  27.289 +     * Return a Transform which represents a clockwise
  27.290 +     *    rotation around the y axis.
  27.291 +     *
  27.292 +     * @method rotateY
  27.293 +     * @static
  27.294 +     * @param {Number} theta radians
  27.295 +     * @return {Transform}
  27.296 +     */
  27.297 +    Transform.rotateY = function rotateY(theta) {
  27.298 +        var cosTheta = Math.cos(theta);
  27.299 +        var sinTheta = Math.sin(theta);
  27.300 +        return [cosTheta, 0, -sinTheta, 0, 0, 1, 0, 0, sinTheta, 0, cosTheta, 0, 0, 0, 0, 1];
  27.301 +    };
  27.302 +
  27.303 +    /**
  27.304 +     * Return a Transform which represents a clockwise
  27.305 +     *    rotation around the z axis.
  27.306 +     *
  27.307 +     * @method rotateZ
  27.308 +     * @static
  27.309 +     * @param {Number} theta radians
  27.310 +     * @return {Transform}
  27.311 +     */
  27.312 +    Transform.rotateZ = function rotateZ(theta) {
  27.313 +        var cosTheta = Math.cos(theta);
  27.314 +        var sinTheta = Math.sin(theta);
  27.315 +        return [cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  27.316 +    };
  27.317 +
  27.318 +    /**
  27.319 +     * Return a Transform which represents composed clockwise
  27.320 +     *    rotations along each of the axes. Equivalent to the result of
  27.321 +     *    Matrix.multiply(rotateX(phi), rotateY(theta), rotateZ(psi)).
  27.322 +     *
  27.323 +     * @method rotate
  27.324 +     * @static
  27.325 +     * @param {Number} phi radians to rotate about the positive x axis
  27.326 +     * @param {Number} theta radians to rotate about the positive y axis
  27.327 +     * @param {Number} psi radians to rotate about the positive z axis
  27.328 +     * @return {Transform}
  27.329 +     */
  27.330 +    Transform.rotate = function rotate(phi, theta, psi) {
  27.331 +        var cosPhi = Math.cos(phi);
  27.332 +        var sinPhi = Math.sin(phi);
  27.333 +        var cosTheta = Math.cos(theta);
  27.334 +        var sinTheta = Math.sin(theta);
  27.335 +        var cosPsi = Math.cos(psi);
  27.336 +        var sinPsi = Math.sin(psi);
  27.337 +        var result = [
  27.338 +            cosTheta * cosPsi,
  27.339 +            cosPhi * sinPsi + sinPhi * sinTheta * cosPsi,
  27.340 +            sinPhi * sinPsi - cosPhi * sinTheta * cosPsi,
  27.341 +            0,
  27.342 +            -cosTheta * sinPsi,
  27.343 +            cosPhi * cosPsi - sinPhi * sinTheta * sinPsi,
  27.344 +            sinPhi * cosPsi + cosPhi * sinTheta * sinPsi,
  27.345 +            0,
  27.346 +            sinTheta,
  27.347 +            -sinPhi * cosTheta,
  27.348 +            cosPhi * cosTheta,
  27.349 +            0,
  27.350 +            0, 0, 0, 1
  27.351 +        ];
  27.352 +        return result;
  27.353 +    };
  27.354 +
  27.355 +    /**
  27.356 +     * Return a Transform which represents an axis-angle rotation
  27.357 +     *
  27.358 +     * @method rotateAxis
  27.359 +     * @static
  27.360 +     * @param {Array.Number} v unit vector representing the axis to rotate about
  27.361 +     * @param {Number} theta radians to rotate clockwise about the axis
  27.362 +     * @return {Transform}
  27.363 +     */
  27.364 +    Transform.rotateAxis = function rotateAxis(v, theta) {
  27.365 +        var sinTheta = Math.sin(theta);
  27.366 +        var cosTheta = Math.cos(theta);
  27.367 +        var verTheta = 1 - cosTheta; // versine of theta
  27.368 +
  27.369 +        var xxV = v[0] * v[0] * verTheta;
  27.370 +        var xyV = v[0] * v[1] * verTheta;
  27.371 +        var xzV = v[0] * v[2] * verTheta;
  27.372 +        var yyV = v[1] * v[1] * verTheta;
  27.373 +        var yzV = v[1] * v[2] * verTheta;
  27.374 +        var zzV = v[2] * v[2] * verTheta;
  27.375 +        var xs = v[0] * sinTheta;
  27.376 +        var ys = v[1] * sinTheta;
  27.377 +        var zs = v[2] * sinTheta;
  27.378 +
  27.379 +        var result = [
  27.380 +            xxV + cosTheta, xyV + zs, xzV - ys, 0,
  27.381 +            xyV - zs, yyV + cosTheta, yzV + xs, 0,
  27.382 +            xzV + ys, yzV - xs, zzV + cosTheta, 0,
  27.383 +            0, 0, 0, 1
  27.384 +        ];
  27.385 +        return result;
  27.386 +    };
  27.387 +
  27.388 +    /**
  27.389 +     * Return a Transform which represents a transform matrix applied about
  27.390 +     * a separate origin point.
  27.391 +     *
  27.392 +     * @method aboutOrigin
  27.393 +     * @static
  27.394 +     * @param {Array.Number} v origin point to apply matrix
  27.395 +     * @param {Transform} m matrix to apply
  27.396 +     * @return {Transform}
  27.397 +     */
  27.398 +    Transform.aboutOrigin = function aboutOrigin(v, m) {
  27.399 +        var t0 = v[0] - (v[0] * m[0] + v[1] * m[4] + v[2] * m[8]);
  27.400 +        var t1 = v[1] - (v[0] * m[1] + v[1] * m[5] + v[2] * m[9]);
  27.401 +        var t2 = v[2] - (v[0] * m[2] + v[1] * m[6] + v[2] * m[10]);
  27.402 +        return Transform.thenMove(m, [t0, t1, t2]);
  27.403 +    };
  27.404 +
  27.405 +    /**
  27.406 +     * Return a Transform representation of a skew transformation
  27.407 +     *
  27.408 +     * @method skew
  27.409 +     * @static
  27.410 +     * @param {Number} phi scale factor skew in the x axis
  27.411 +     * @param {Number} theta scale factor skew in the y axis
  27.412 +     * @param {Number} psi scale factor skew in the z axis
  27.413 +     * @return {Transform}
  27.414 +     */
  27.415 +    Transform.skew = function skew(phi, theta, psi) {
  27.416 +        return [1, 0, 0, 0, Math.tan(psi), 1, 0, 0, Math.tan(theta), Math.tan(phi), 1, 0, 0, 0, 0, 1];
  27.417 +    };
  27.418 +
  27.419 +    /**
  27.420 +     * Return a Transform representation of a skew in the x-direction
  27.421 +     *
  27.422 +     * @method skewX
  27.423 +     * @static
  27.424 +     * @param {Number} angle the angle between the top and left sides
  27.425 +     * @return {Transform}
  27.426 +     */
  27.427 +    Transform.skewX = function skewX(angle) {
  27.428 +        return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  27.429 +    };
  27.430 +
  27.431 +    /**
  27.432 +     * Return a Transform representation of a skew in the y-direction
  27.433 +     *
  27.434 +     * @method skewY
  27.435 +     * @static
  27.436 +     * @param {Number} angle the angle between the top and right sides
  27.437 +     * @return {Transform}
  27.438 +     */
  27.439 +    Transform.skewY = function skewY(angle) {
  27.440 +        return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  27.441 +    };
  27.442 +
  27.443 +    /**
  27.444 +     * Returns a perspective Transform matrix
  27.445 +     *
  27.446 +     * @method perspective
  27.447 +     * @static
  27.448 +     * @param {Number} focusZ z position of focal point
  27.449 +     * @return {Transform}
  27.450 +     */
  27.451 +    Transform.perspective = function perspective(focusZ) {
  27.452 +        return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1 / focusZ, 0, 0, 0, 1];
  27.453 +    };
  27.454 +
  27.455 +    /**
  27.456 +     * Return translation vector component of given Transform
  27.457 +     *
  27.458 +     * @method getTranslate
  27.459 +     * @static
  27.460 +     * @param {Transform} m Transform
  27.461 +     * @return {Array.Number} the translation vector [t_x, t_y, t_z]
  27.462 +     */
  27.463 +    Transform.getTranslate = function getTranslate(m) {
  27.464 +        return [m[12], m[13], m[14]];
  27.465 +    };
  27.466 +
  27.467 +    /**
  27.468 +     * Return inverse affine transform for given Transform.
  27.469 +     *   Note: This assumes m[3] = m[7] = m[11] = 0, and m[15] = 1.
  27.470 +     *   Will provide incorrect results if not invertible or preconditions not met.
  27.471 +     *
  27.472 +     * @method inverse
  27.473 +     * @static
  27.474 +     * @param {Transform} m Transform
  27.475 +     * @return {Transform}
  27.476 +     */
  27.477 +    Transform.inverse = function inverse(m) {
  27.478 +        // only need to consider 3x3 section for affine
  27.479 +        var c0 = m[5] * m[10] - m[6] * m[9];
  27.480 +        var c1 = m[4] * m[10] - m[6] * m[8];
  27.481 +        var c2 = m[4] * m[9] - m[5] * m[8];
  27.482 +        var c4 = m[1] * m[10] - m[2] * m[9];
  27.483 +        var c5 = m[0] * m[10] - m[2] * m[8];
  27.484 +        var c6 = m[0] * m[9] - m[1] * m[8];
  27.485 +        var c8 = m[1] * m[6] - m[2] * m[5];
  27.486 +        var c9 = m[0] * m[6] - m[2] * m[4];
  27.487 +        var c10 = m[0] * m[5] - m[1] * m[4];
  27.488 +        var detM = m[0] * c0 - m[1] * c1 + m[2] * c2;
  27.489 +        var invD = 1 / detM;
  27.490 +        var result = [
  27.491 +            invD * c0, -invD * c4, invD * c8, 0,
  27.492 +            -invD * c1, invD * c5, -invD * c9, 0,
  27.493 +            invD * c2, -invD * c6, invD * c10, 0,
  27.494 +            0, 0, 0, 1
  27.495 +        ];
  27.496 +        result[12] = -m[12] * result[0] - m[13] * result[4] - m[14] * result[8];
  27.497 +        result[13] = -m[12] * result[1] - m[13] * result[5] - m[14] * result[9];
  27.498 +        result[14] = -m[12] * result[2] - m[13] * result[6] - m[14] * result[10];
  27.499 +        return result;
  27.500 +    };
  27.501 +
  27.502 +    /**
  27.503 +     * Returns the transpose of a 4x4 matrix
  27.504 +     *
  27.505 +     * @method transpose
  27.506 +     * @static
  27.507 +     * @param {Transform} m matrix
  27.508 +     * @return {Transform} the resulting transposed matrix
  27.509 +     */
  27.510 +    Transform.transpose = function transpose(m) {
  27.511 +        return [m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]];
  27.512 +    };
  27.513 +
  27.514 +    function _normSquared(v) {
  27.515 +        return (v.length === 2) ? v[0] * v[0] + v[1] * v[1] : v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
  27.516 +    }
  27.517 +    function _norm(v) {
  27.518 +        return Math.sqrt(_normSquared(v));
  27.519 +    }
  27.520 +    function _sign(n) {
  27.521 +        return (n < 0) ? -1 : 1;
  27.522 +    }
  27.523 +
  27.524 +    /**
  27.525 +     * Decompose Transform into separate .translate, .rotate, .scale,
  27.526 +     *    and .skew components.
  27.527 +     *
  27.528 +     * @method interpret
  27.529 +     * @static
  27.530 +     * @param {Transform} M transform matrix
  27.531 +     * @return {Object} matrix spec object with component matrices .translate,
  27.532 +     *    .rotate, .scale, .skew
  27.533 +     */
  27.534 +    Transform.interpret = function interpret(M) {
  27.535 +
  27.536 +        // QR decomposition via Householder reflections
  27.537 +        //FIRST ITERATION
  27.538 +
  27.539 +        //default Q1 to the identity matrix;
  27.540 +        var x = [M[0], M[1], M[2]];                // first column vector
  27.541 +        var sgn = _sign(x[0]);                     // sign of first component of x (for stability)
  27.542 +        var xNorm = _norm(x);                      // norm of first column vector
  27.543 +        var v = [x[0] + sgn * xNorm, x[1], x[2]];  // v = x + sign(x[0])|x|e1
  27.544 +        var mult = 2 / _normSquared(v);            // mult = 2/v'v
  27.545 +
  27.546 +        //bail out if our Matrix is singular
  27.547 +        if (mult >= Infinity) {
  27.548 +            return {translate: Transform.getTranslate(M), rotate: [0, 0, 0], scale: [0, 0, 0], skew: [0, 0, 0]};
  27.549 +        }
  27.550 +
  27.551 +        //evaluate Q1 = I - 2vv'/v'v
  27.552 +        var Q1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
  27.553 +
  27.554 +        //diagonals
  27.555 +        Q1[0]  = 1 - mult * v[0] * v[0];    // 0,0 entry
  27.556 +        Q1[5]  = 1 - mult * v[1] * v[1];    // 1,1 entry
  27.557 +        Q1[10] = 1 - mult * v[2] * v[2];    // 2,2 entry
  27.558 +
  27.559 +        //upper diagonal
  27.560 +        Q1[1] = -mult * v[0] * v[1];        // 0,1 entry
  27.561 +        Q1[2] = -mult * v[0] * v[2];        // 0,2 entry
  27.562 +        Q1[6] = -mult * v[1] * v[2];        // 1,2 entry
  27.563 +
  27.564 +        //lower diagonal
  27.565 +        Q1[4] = Q1[1];                      // 1,0 entry
  27.566 +        Q1[8] = Q1[2];                      // 2,0 entry
  27.567 +        Q1[9] = Q1[6];                      // 2,1 entry
  27.568 +
  27.569 +        //reduce first column of M
  27.570 +        var MQ1 = Transform.multiply(Q1, M);
  27.571 +
  27.572 +        //SECOND ITERATION on (1,1) minor
  27.573 +        var x2 = [MQ1[5], MQ1[6]];
  27.574 +        var sgn2 = _sign(x2[0]);                    // sign of first component of x (for stability)
  27.575 +        var x2Norm = _norm(x2);                     // norm of first column vector
  27.576 +        var v2 = [x2[0] + sgn2 * x2Norm, x2[1]];    // v = x + sign(x[0])|x|e1
  27.577 +        var mult2 = 2 / _normSquared(v2);           // mult = 2/v'v
  27.578 +
  27.579 +        //evaluate Q2 = I - 2vv'/v'v
  27.580 +        var Q2 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
  27.581 +
  27.582 +        //diagonal
  27.583 +        Q2[5]  = 1 - mult2 * v2[0] * v2[0]; // 1,1 entry
  27.584 +        Q2[10] = 1 - mult2 * v2[1] * v2[1]; // 2,2 entry
  27.585 +
  27.586 +        //off diagonals
  27.587 +        Q2[6] = -mult2 * v2[0] * v2[1];     // 2,1 entry
  27.588 +        Q2[9] = Q2[6];                      // 1,2 entry
  27.589 +
  27.590 +        //calc QR decomposition. Q = Q1*Q2, R = Q'*M
  27.591 +        var Q = Transform.multiply(Q2, Q1);      //note: really Q transpose
  27.592 +        var R = Transform.multiply(Q, M);
  27.593 +
  27.594 +        //remove negative scaling
  27.595 +        var remover = Transform.scale(R[0] < 0 ? -1 : 1, R[5] < 0 ? -1 : 1, R[10] < 0 ? -1 : 1);
  27.596 +        R = Transform.multiply(R, remover);
  27.597 +        Q = Transform.multiply(remover, Q);
  27.598 +
  27.599 +        //decompose into rotate/scale/skew matrices
  27.600 +        var result = {};
  27.601 +        result.translate = Transform.getTranslate(M);
  27.602 +        result.rotate = [Math.atan2(-Q[6], Q[10]), Math.asin(Q[2]), Math.atan2(-Q[1], Q[0])];
  27.603 +        if (!result.rotate[0]) {
  27.604 +            result.rotate[0] = 0;
  27.605 +            result.rotate[2] = Math.atan2(Q[4], Q[5]);
  27.606 +        }
  27.607 +        result.scale = [R[0], R[5], R[10]];
  27.608 +        result.skew = [Math.atan2(R[9], result.scale[2]), Math.atan2(R[8], result.scale[2]), Math.atan2(R[4], result.scale[0])];
  27.609 +
  27.610 +        //double rotation workaround
  27.611 +        if (Math.abs(result.rotate[0]) + Math.abs(result.rotate[2]) > 1.5 * Math.PI) {
  27.612 +            result.rotate[1] = Math.PI - result.rotate[1];
  27.613 +            if (result.rotate[1] > Math.PI) result.rotate[1] -= 2 * Math.PI;
  27.614 +            if (result.rotate[1] < -Math.PI) result.rotate[1] += 2 * Math.PI;
  27.615 +            if (result.rotate[0] < 0) result.rotate[0] += Math.PI;
  27.616 +            else result.rotate[0] -= Math.PI;
  27.617 +            if (result.rotate[2] < 0) result.rotate[2] += Math.PI;
  27.618 +            else result.rotate[2] -= Math.PI;
  27.619 +        }
  27.620 +
  27.621 +        return result;
  27.622 +    };
  27.623 +
  27.624 +    /**
  27.625 +     * Weighted average between two matrices by averaging their
  27.626 +     *     translation, rotation, scale, skew components.
  27.627 +     *     f(M1,M2,t) = (1 - t) * M1 + t * M2
  27.628 +     *
  27.629 +     * @method average
  27.630 +     * @static
  27.631 +     * @param {Transform} M1 f(M1,M2,0) = M1
  27.632 +     * @param {Transform} M2 f(M1,M2,1) = M2
  27.633 +     * @param {Number} t
  27.634 +     * @return {Transform}
  27.635 +     */
  27.636 +    Transform.average = function average(M1, M2, t) {
  27.637 +        t = (t === undefined) ? 0.5 : t;
  27.638 +        var specM1 = Transform.interpret(M1);
  27.639 +        var specM2 = Transform.interpret(M2);
  27.640 +
  27.641 +        var specAvg = {
  27.642 +            translate: [0, 0, 0],
  27.643 +            rotate: [0, 0, 0],
  27.644 +            scale: [0, 0, 0],
  27.645 +            skew: [0, 0, 0]
  27.646 +        };
  27.647 +
  27.648 +        for (var i = 0; i < 3; i++) {
  27.649 +            specAvg.translate[i] = (1 - t) * specM1.translate[i] + t * specM2.translate[i];
  27.650 +            specAvg.rotate[i] = (1 - t) * specM1.rotate[i] + t * specM2.rotate[i];
  27.651 +            specAvg.scale[i] = (1 - t) * specM1.scale[i] + t * specM2.scale[i];
  27.652 +            specAvg.skew[i] = (1 - t) * specM1.skew[i] + t * specM2.skew[i];
  27.653 +        }
  27.654 +        return Transform.build(specAvg);
  27.655 +    };
  27.656 +
  27.657 +    /**
  27.658 +     * Compose .translate, .rotate, .scale, .skew components into
  27.659 +     * Transform matrix
  27.660 +     *
  27.661 +     * @method build
  27.662 +     * @static
  27.663 +     * @param {matrixSpec} spec object with component matrices .translate,
  27.664 +     *    .rotate, .scale, .skew
  27.665 +     * @return {Transform} composed transform
  27.666 +     */
  27.667 +    Transform.build = function build(spec) {
  27.668 +        var scaleMatrix = Transform.scale(spec.scale[0], spec.scale[1], spec.scale[2]);
  27.669 +        var skewMatrix = Transform.skew(spec.skew[0], spec.skew[1], spec.skew[2]);
  27.670 +        var rotateMatrix = Transform.rotate(spec.rotate[0], spec.rotate[1], spec.rotate[2]);
  27.671 +        return Transform.thenMove(Transform.multiply(Transform.multiply(rotateMatrix, skewMatrix), scaleMatrix), spec.translate);
  27.672 +    };
  27.673 +
  27.674 +    /**
  27.675 +     * Determine if two Transforms are component-wise equal
  27.676 +     *   Warning: breaks on perspective Transforms
  27.677 +     *
  27.678 +     * @method equals
  27.679 +     * @static
  27.680 +     * @param {Transform} a matrix
  27.681 +     * @param {Transform} b matrix
  27.682 +     * @return {boolean}
  27.683 +     */
  27.684 +    Transform.equals = function equals(a, b) {
  27.685 +        return !Transform.notEquals(a, b);
  27.686 +    };
  27.687 +
  27.688 +    /**
  27.689 +     * Determine if two Transforms are component-wise unequal
  27.690 +     *   Warning: breaks on perspective Transforms
  27.691 +     *
  27.692 +     * @method notEquals
  27.693 +     * @static
  27.694 +     * @param {Transform} a matrix
  27.695 +     * @param {Transform} b matrix
  27.696 +     * @return {boolean}
  27.697 +     */
  27.698 +    Transform.notEquals = function notEquals(a, b) {
  27.699 +        if (a === b) return false;
  27.700 +
  27.701 +        // shortci
  27.702 +        return !(a && b) ||
  27.703 +            a[12] !== b[12] || a[13] !== b[13] || a[14] !== b[14] ||
  27.704 +            a[0] !== b[0] || a[1] !== b[1] || a[2] !== b[2] ||
  27.705 +            a[4] !== b[4] || a[5] !== b[5] || a[6] !== b[6] ||
  27.706 +            a[8] !== b[8] || a[9] !== b[9] || a[10] !== b[10];
  27.707 +    };
  27.708 +
  27.709 +    /**
  27.710 +     * Constrain angle-trio components to range of [-pi, pi).
  27.711 +     *
  27.712 +     * @method normalizeRotation
  27.713 +     * @static
  27.714 +     * @param {Array.Number} rotation phi, theta, psi (array of floats
  27.715 +     *    && array.length == 3)
  27.716 +     * @return {Array.Number} new phi, theta, psi triplet
  27.717 +     *    (array of floats && array.length == 3)
  27.718 +     */
  27.719 +    Transform.normalizeRotation = function normalizeRotation(rotation) {
  27.720 +        var result = rotation.slice(0);
  27.721 +        if (result[0] === Math.PI * 0.5 || result[0] === -Math.PI * 0.5) {
  27.722 +            result[0] = -result[0];
  27.723 +            result[1] = Math.PI - result[1];
  27.724 +            result[2] -= Math.PI;
  27.725 +        }
  27.726 +        if (result[0] > Math.PI * 0.5) {
  27.727 +            result[0] = result[0] - Math.PI;
  27.728 +            result[1] = Math.PI - result[1];
  27.729 +            result[2] -= Math.PI;
  27.730 +        }
  27.731 +        if (result[0] < -Math.PI * 0.5) {
  27.732 +            result[0] = result[0] + Math.PI;
  27.733 +            result[1] = -Math.PI - result[1];
  27.734 +            result[2] -= Math.PI;
  27.735 +        }
  27.736 +        while (result[1] < -Math.PI) result[1] += 2 * Math.PI;
  27.737 +        while (result[1] >= Math.PI) result[1] -= 2 * Math.PI;
  27.738 +        while (result[2] < -Math.PI) result[2] += 2 * Math.PI;
  27.739 +        while (result[2] >= Math.PI) result[2] -= 2 * Math.PI;
  27.740 +        return result;
  27.741 +    };
  27.742 +
  27.743 +    /**
  27.744 +     * (Property) Array defining a translation forward in z by 1
  27.745 +     *
  27.746 +     * @property {array} inFront
  27.747 +     * @static
  27.748 +     * @final
  27.749 +     */
  27.750 +    Transform.inFront = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1e-3, 1];
  27.751 +
  27.752 +    /**
  27.753 +     * (Property) Array defining a translation backwards in z by 1
  27.754 +     *
  27.755 +     * @property {array} behind
  27.756 +     * @static
  27.757 +     * @final
  27.758 +     */
  27.759 +    Transform.behind = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1e-3, 1];
  27.760 +
  27.761 +    module.exports = Transform;
  27.762 +});
  27.763 +
  27.764 +
  27.765 +/* This Source Code Form is subject to the terms of the Mozilla Public
  27.766 + * License, v. 2.0. If a copy of the MPL was not distributed with this
  27.767 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  27.768 + *
  27.769 + * Owner: mark@famo.us
  27.770 + * @license MPL 2.0
  27.771 + * @copyright Famous Industries, Inc. 2014
  27.772 + */
  27.773 +
  27.774 +define('famous/core/SpecParser',['require','exports','module','./Transform'],function(require, exports, module) {
  27.775 +    var Transform = require('./Transform');
  27.776 +
  27.777 +    /**
  27.778 +     *
  27.779 +     * This object translates the rendering instructions ("render specs")
  27.780 +     *   that renderable components generate into document update
  27.781 +     *   instructions ("update specs").  Private.
  27.782 +     *
  27.783 +     * @private
  27.784 +     * @class SpecParser
  27.785 +     * @constructor
  27.786 +     */
  27.787 +    function SpecParser() {
  27.788 +        this.result = {};
  27.789 +    }
  27.790 +    SpecParser._instance = new SpecParser();
  27.791 +
  27.792 +    /**
  27.793 +     * Convert a render spec coming from the context's render chain to an
  27.794 +     *    update spec for the update chain. This is the only major entry point
  27.795 +     *    for a consumer of this class.
  27.796 +     *
  27.797 +     * @method parse
  27.798 +     * @static
  27.799 +     * @private
  27.800 +     *
  27.801 +     * @param {renderSpec} spec input render spec
  27.802 +     * @param {Object} context context to do the parse in
  27.803 +     * @return {Object} the resulting update spec (if no callback
  27.804 +     *   specified, else none)
  27.805 +     */
  27.806 +    SpecParser.parse = function parse(spec, context) {
  27.807 +        return SpecParser._instance.parse(spec, context);
  27.808 +    };
  27.809 +
  27.810 +    /**
  27.811 +     * Convert a renderSpec coming from the context's render chain to an update
  27.812 +     *    spec for the update chain. This is the only major entrypoint for a
  27.813 +     *    consumer of this class.
  27.814 +     *
  27.815 +     * @method parse
  27.816 +     *
  27.817 +     * @private
  27.818 +     * @param {renderSpec} spec input render spec
  27.819 +     * @param {Context} context
  27.820 +     * @return {updateSpec} the resulting update spec
  27.821 +     */
  27.822 +    SpecParser.prototype.parse = function parse(spec, context) {
  27.823 +        this.reset();
  27.824 +        this._parseSpec(spec, context, Transform.identity);
  27.825 +        return this.result;
  27.826 +    };
  27.827 +
  27.828 +    /**
  27.829 +     * Prepare SpecParser for re-use (or first use) by setting internal state
  27.830 +     *  to blank.
  27.831 +     *
  27.832 +     * @private
  27.833 +     * @method reset
  27.834 +     */
  27.835 +    SpecParser.prototype.reset = function reset() {
  27.836 +        this.result = {};
  27.837 +    };
  27.838 +
  27.839 +    // Multiply matrix M by vector v
  27.840 +    function _vecInContext(v, m) {
  27.841 +        return [
  27.842 +            v[0] * m[0] + v[1] * m[4] + v[2] * m[8],
  27.843 +            v[0] * m[1] + v[1] * m[5] + v[2] * m[9],
  27.844 +            v[0] * m[2] + v[1] * m[6] + v[2] * m[10]
  27.845 +        ];
  27.846 +    }
  27.847 +
  27.848 +    var _originZeroZero = [0, 0];
  27.849 +
  27.850 +    // From the provided renderSpec tree, recursively compose opacities,
  27.851 +    //    origins, transforms, and sizes corresponding to each surface id from
  27.852 +    //    the provided renderSpec tree structure. On completion, those
  27.853 +    //    properties of 'this' object should be ready to use to build an
  27.854 +    //    updateSpec.
  27.855 +    SpecParser.prototype._parseSpec = function _parseSpec(spec, parentContext, sizeContext) {
  27.856 +        var id;
  27.857 +        var target;
  27.858 +        var transform;
  27.859 +        var opacity;
  27.860 +        var origin;
  27.861 +        var align;
  27.862 +        var size;
  27.863 +
  27.864 +        if (typeof spec === 'number') {
  27.865 +            id = spec;
  27.866 +            transform = parentContext.transform;
  27.867 +            align = parentContext.align || parentContext.origin;
  27.868 +            if (parentContext.size && align && (align[0] || align[1])) {
  27.869 +                var alignAdjust = [align[0] * parentContext.size[0], align[1] * parentContext.size[1], 0];
  27.870 +                transform = Transform.thenMove(transform, _vecInContext(alignAdjust, sizeContext));
  27.871 +            }
  27.872 +            this.result[id] = {
  27.873 +                transform: transform,
  27.874 +                opacity: parentContext.opacity,
  27.875 +                origin: parentContext.origin || _originZeroZero,
  27.876 +                align: parentContext.align || parentContext.origin || _originZeroZero,
  27.877 +                size: parentContext.size
  27.878 +            };
  27.879 +        }
  27.880 +        else if (!spec) { // placed here so 0 will be cached earlier
  27.881 +            return;
  27.882 +        }
  27.883 +        else if (spec instanceof Array) {
  27.884 +            for (var i = 0; i < spec.length; i++) {
  27.885 +                this._parseSpec(spec[i], parentContext, sizeContext);
  27.886 +            }
  27.887 +        }
  27.888 +        else {
  27.889 +            target = spec.target;
  27.890 +            transform = parentContext.transform;
  27.891 +            opacity = parentContext.opacity;
  27.892 +            origin = parentContext.origin;
  27.893 +            align = parentContext.align;
  27.894 +            size = parentContext.size;
  27.895 +            var nextSizeContext = sizeContext;
  27.896 +
  27.897 +            if (spec.opacity !== undefined) opacity = parentContext.opacity * spec.opacity;
  27.898 +            if (spec.transform) transform = Transform.multiply(parentContext.transform, spec.transform);
  27.899 +            if (spec.origin) {
  27.900 +                origin = spec.origin;
  27.901 +                nextSizeContext = parentContext.transform;
  27.902 +            }
  27.903 +            if (spec.align) align = spec.align;
  27.904 +            if (spec.size) {
  27.905 +                var parentSize = parentContext.size;
  27.906 +                size = [
  27.907 +                    spec.size[0] !== undefined ? spec.size[0] : parentSize[0],
  27.908 +                    spec.size[1] !== undefined ? spec.size[1] : parentSize[1]
  27.909 +                ];
  27.910 +                if (parentSize) {
  27.911 +                    if (!align) align = origin;
  27.912 +                    if (align && (align[0] || align[1])) transform = Transform.thenMove(transform, _vecInContext([align[0] * parentSize[0], align[1] * parentSize[1], 0], sizeContext));
  27.913 +                    if (origin && (origin[0] || origin[1])) transform = Transform.moveThen([-origin[0] * size[0], -origin[1] * size[1], 0], transform);
  27.914 +                }
  27.915 +                nextSizeContext = parentContext.transform;
  27.916 +                origin = null;
  27.917 +                align = null;
  27.918 +            }
  27.919 +
  27.920 +            this._parseSpec(target, {
  27.921 +                transform: transform,
  27.922 +                opacity: opacity,
  27.923 +                origin: origin,
  27.924 +                align: align,
  27.925 +                size: size
  27.926 +            }, nextSizeContext);
  27.927 +        }
  27.928 +    };
  27.929 +
  27.930 +    module.exports = SpecParser;
  27.931 +});
  27.932 +
  27.933 +/* This Source Code Form is subject to the terms of the Mozilla Public
  27.934 + * License, v. 2.0. If a copy of the MPL was not distributed with this
  27.935 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  27.936 + *
  27.937 + * Owner: mark@famo.us
  27.938 + * @license MPL 2.0
  27.939 + * @copyright Famous Industries, Inc. 2014
  27.940 + */
  27.941 +
  27.942 +define('famous/core/RenderNode',['require','exports','module','./Entity','./SpecParser'],function(require, exports, module) {
  27.943 +    var Entity = require('./Entity');
  27.944 +    var SpecParser = require('./SpecParser');
  27.945 +
  27.946 +    /**
  27.947 +     * A wrapper for inserting a renderable component (like a Modifer or
  27.948 +     *   Surface) into the render tree.
  27.949 +     *
  27.950 +     * @class RenderNode
  27.951 +     * @constructor
  27.952 +     *
  27.953 +     * @param {Object} object Target renderable component
  27.954 +     */
  27.955 +    function RenderNode(object) {
  27.956 +        this._object = null;
  27.957 +        this._child = null;
  27.958 +        this._hasMultipleChildren = false;
  27.959 +        this._isRenderable = false;
  27.960 +        this._isModifier = false;
  27.961 +
  27.962 +        this._resultCache = {};
  27.963 +        this._prevResults = {};
  27.964 +
  27.965 +        this._childResult = null;
  27.966 +
  27.967 +        if (object) this.set(object);
  27.968 +    }
  27.969 +
  27.970 +    /**
  27.971 +     * Append a renderable to the list of this node's children.
  27.972 +     *   This produces a new RenderNode in the tree.
  27.973 +     *   Note: Does not double-wrap if child is a RenderNode already.
  27.974 +     *
  27.975 +     * @method add
  27.976 +     * @param {Object} child renderable object
  27.977 +     * @return {RenderNode} new render node wrapping child
  27.978 +     */
  27.979 +    RenderNode.prototype.add = function add(child) {
  27.980 +        var childNode = (child instanceof RenderNode) ? child : new RenderNode(child);
  27.981 +        if (this._child instanceof Array) this._child.push(childNode);
  27.982 +        else if (this._child) {
  27.983 +            this._child = [this._child, childNode];
  27.984 +            this._hasMultipleChildren = true;
  27.985 +            this._childResult = []; // to be used later
  27.986 +        }
  27.987 +        else this._child = childNode;
  27.988 +
  27.989 +        return childNode;
  27.990 +    };
  27.991 +
  27.992 +    /**
  27.993 +     * Return the single wrapped object.  Returns null if this node has multiple child nodes.
  27.994 +     *
  27.995 +     * @method get
  27.996 +     *
  27.997 +     * @return {Ojbect} contained renderable object
  27.998 +     */
  27.999 +    RenderNode.prototype.get = function get() {
 27.1000 +        return this._object || (this._hasMultipleChildren ? null : (this._child ? this._child.get() : null));
 27.1001 +    };
 27.1002 +
 27.1003 +    /**
 27.1004 +     * Overwrite the list of children to contain the single provided object
 27.1005 +     *
 27.1006 +     * @method set
 27.1007 +     * @param {Object} child renderable object
 27.1008 +     * @return {RenderNode} this render node, or child if it is a RenderNode
 27.1009 +     */
 27.1010 +    RenderNode.prototype.set = function set(child) {
 27.1011 +        this._childResult = null;
 27.1012 +        this._hasMultipleChildren = false;
 27.1013 +        this._isRenderable = child.render ? true : false;
 27.1014 +        this._isModifier = child.modify ? true : false;
 27.1015 +        this._object = child;
 27.1016 +        this._child = null;
 27.1017 +        if (child instanceof RenderNode) return child;
 27.1018 +        else return this;
 27.1019 +    };
 27.1020 +
 27.1021 +    /**
 27.1022 +     * Get render size of contained object.
 27.1023 +     *
 27.1024 +     * @method getSize
 27.1025 +     * @return {Array.Number} size of this or size of single child.
 27.1026 +     */
 27.1027 +    RenderNode.prototype.getSize = function getSize() {
 27.1028 +        var result = null;
 27.1029 +        var target = this.get();
 27.1030 +        if (target && target.getSize) result = target.getSize();
 27.1031 +        if (!result && this._child && this._child.getSize) result = this._child.getSize();
 27.1032 +        return result;
 27.1033 +    };
 27.1034 +
 27.1035 +    // apply results of rendering this subtree to the document
 27.1036 +    function _applyCommit(spec, context, cacheStorage) {
 27.1037 +        var result = SpecParser.parse(spec, context);
 27.1038 +        var keys = Object.keys(result);
 27.1039 +        for (var i = 0; i < keys.length; i++) {
 27.1040 +            var id = keys[i];
 27.1041 +            var childNode = Entity.get(id);
 27.1042 +            var commitParams = result[id];
 27.1043 +            commitParams.allocator = context.allocator;
 27.1044 +            var commitResult = childNode.commit(commitParams);
 27.1045 +            if (commitResult) _applyCommit(commitResult, context, cacheStorage);
 27.1046 +            else cacheStorage[id] = commitParams;
 27.1047 +        }
 27.1048 +    }
 27.1049 +
 27.1050 +    /**
 27.1051 +     * Commit the content change from this node to the document.
 27.1052 +     *
 27.1053 +     * @private
 27.1054 +     * @method commit
 27.1055 +     * @param {Context} context render context
 27.1056 +     */
 27.1057 +    RenderNode.prototype.commit = function commit(context) {
 27.1058 +        // free up some divs from the last loop
 27.1059 +        var prevKeys = Object.keys(this._prevResults);
 27.1060 +        for (var i = 0; i < prevKeys.length; i++) {
 27.1061 +            var id = prevKeys[i];
 27.1062 +            if (this._resultCache[id] === undefined) {
 27.1063 +                var object = Entity.get(id);
 27.1064 +                if (object.cleanup) object.cleanup(context.allocator);
 27.1065 +            }
 27.1066 +        }
 27.1067 +
 27.1068 +        this._prevResults = this._resultCache;
 27.1069 +        this._resultCache = {};
 27.1070 +        _applyCommit(this.render(), context, this._resultCache);
 27.1071 +    };
 27.1072 +
 27.1073 +    /**
 27.1074 +     * Generate a render spec from the contents of the wrapped component.
 27.1075 +     *
 27.1076 +     * @private
 27.1077 +     * @method render
 27.1078 +     *
 27.1079 +     * @return {Object} render specification for the component subtree
 27.1080 +     *    only under this node.
 27.1081 +     */
 27.1082 +    RenderNode.prototype.render = function render() {
 27.1083 +        if (this._isRenderable) return this._object.render();
 27.1084 +
 27.1085 +        var result = null;
 27.1086 +        if (this._hasMultipleChildren) {
 27.1087 +            result = this._childResult;
 27.1088 +            var children = this._child;
 27.1089 +            for (var i = 0; i < children.length; i++) {
 27.1090 +                result[i] = children[i].render();
 27.1091 +            }
 27.1092 +        }
 27.1093 +        else if (this._child) result = this._child.render();
 27.1094 +
 27.1095 +        return this._isModifier ? this._object.modify(result) : result;
 27.1096 +    };
 27.1097 +
 27.1098 +    module.exports = RenderNode;
 27.1099 +});
 27.1100 +
 27.1101 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1102 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1103 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1104 + *
 27.1105 + * Owner: mark@famo.us
 27.1106 + * @license MPL 2.0
 27.1107 + * @copyright Famous Industries, Inc. 2014
 27.1108 + */
 27.1109 +
 27.1110 +define('famous/core/EventEmitter',['require','exports','module'],function(require, exports, module) {
 27.1111 +    /**
 27.1112 +     * EventEmitter represents a channel for events.
 27.1113 +     *
 27.1114 +     * @class EventEmitter
 27.1115 +     * @constructor
 27.1116 +     */
 27.1117 +    function EventEmitter() {
 27.1118 +        this.listeners = {};
 27.1119 +        this._owner = this;
 27.1120 +    }
 27.1121 +
 27.1122 +    /**
 27.1123 +     * Trigger an event, sending to all downstream handlers
 27.1124 +     *   listening for provided 'type' key.
 27.1125 +     *
 27.1126 +     * @method emit
 27.1127 +     *
 27.1128 +     * @param {string} type event type key (for example, 'click')
 27.1129 +     * @param {Object} event event data
 27.1130 +     * @return {EventHandler} this
 27.1131 +     */
 27.1132 +    EventEmitter.prototype.emit = function emit(type, event) {
 27.1133 +        var handlers = this.listeners[type];
 27.1134 +        if (handlers) {
 27.1135 +            for (var i = 0; i < handlers.length; i++) {
 27.1136 +                handlers[i].call(this._owner, event);
 27.1137 +            }
 27.1138 +        }
 27.1139 +        return this;
 27.1140 +    };
 27.1141 +
 27.1142 +    /**
 27.1143 +     * Bind a callback function to an event type handled by this object.
 27.1144 +     *
 27.1145 +     * @method "on"
 27.1146 +     *
 27.1147 +     * @param {string} type event type key (for example, 'click')
 27.1148 +     * @param {function(string, Object)} handler callback
 27.1149 +     * @return {EventHandler} this
 27.1150 +     */
 27.1151 +   EventEmitter.prototype.on = function on(type, handler) {
 27.1152 +        if (!(type in this.listeners)) this.listeners[type] = [];
 27.1153 +        var index = this.listeners[type].indexOf(handler);
 27.1154 +        if (index < 0) this.listeners[type].push(handler);
 27.1155 +        return this;
 27.1156 +    };
 27.1157 +
 27.1158 +    /**
 27.1159 +     * Alias for "on".
 27.1160 +     * @method addListener
 27.1161 +     */
 27.1162 +    EventEmitter.prototype.addListener = EventEmitter.prototype.on;
 27.1163 +
 27.1164 +   /**
 27.1165 +     * Unbind an event by type and handler.
 27.1166 +     *   This undoes the work of "on".
 27.1167 +     *
 27.1168 +     * @method removeListener
 27.1169 +     *
 27.1170 +     * @param {string} type event type key (for example, 'click')
 27.1171 +     * @param {function} handler function object to remove
 27.1172 +     * @return {EventEmitter} this
 27.1173 +     */
 27.1174 +    EventEmitter.prototype.removeListener = function removeListener(type, handler) {
 27.1175 +        var index = this.listeners[type].indexOf(handler);
 27.1176 +        if (index >= 0) this.listeners[type].splice(index, 1);
 27.1177 +        return this;
 27.1178 +    };
 27.1179 +
 27.1180 +    /**
 27.1181 +     * Call event handlers with this set to owner.
 27.1182 +     *
 27.1183 +     * @method bindThis
 27.1184 +     *
 27.1185 +     * @param {Object} owner object this EventEmitter belongs to
 27.1186 +     */
 27.1187 +    EventEmitter.prototype.bindThis = function bindThis(owner) {
 27.1188 +        this._owner = owner;
 27.1189 +    };
 27.1190 +
 27.1191 +    module.exports = EventEmitter;
 27.1192 +});
 27.1193 +
 27.1194 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1195 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1196 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1197 + *
 27.1198 + * Owner: mark@famo.us
 27.1199 + * @license MPL 2.0
 27.1200 + * @copyright Famous Industries, Inc. 2014
 27.1201 + */
 27.1202 +
 27.1203 +define('famous/core/EventHandler',['require','exports','module','./EventEmitter'],function(require, exports, module) {
 27.1204 +    var EventEmitter = require('./EventEmitter');
 27.1205 +
 27.1206 +    /**
 27.1207 +     * EventHandler forwards received events to a set of provided callback functions.
 27.1208 +     * It allows events to be captured, processed, and optionally piped through to other event handlers.
 27.1209 +     *
 27.1210 +     * @class EventHandler
 27.1211 +     * @extends EventEmitter
 27.1212 +     * @constructor
 27.1213 +     */
 27.1214 +    function EventHandler() {
 27.1215 +        EventEmitter.apply(this, arguments);
 27.1216 +
 27.1217 +        this.downstream = []; // downstream event handlers
 27.1218 +        this.downstreamFn = []; // downstream functions
 27.1219 +
 27.1220 +        this.upstream = []; // upstream event handlers
 27.1221 +        this.upstreamListeners = {}; // upstream listeners
 27.1222 +    }
 27.1223 +    EventHandler.prototype = Object.create(EventEmitter.prototype);
 27.1224 +    EventHandler.prototype.constructor = EventHandler;
 27.1225 +
 27.1226 +    /**
 27.1227 +     * Assign an event handler to receive an object's input events.
 27.1228 +     *
 27.1229 +     * @method setInputHandler
 27.1230 +     * @static
 27.1231 +     *
 27.1232 +     * @param {Object} object object to mix trigger, subscribe, and unsubscribe functions into
 27.1233 +     * @param {EventHandler} handler assigned event handler
 27.1234 +     */
 27.1235 +    EventHandler.setInputHandler = function setInputHandler(object, handler) {
 27.1236 +        object.trigger = handler.trigger.bind(handler);
 27.1237 +        if (handler.subscribe && handler.unsubscribe) {
 27.1238 +            object.subscribe = handler.subscribe.bind(handler);
 27.1239 +            object.unsubscribe = handler.unsubscribe.bind(handler);
 27.1240 +        }
 27.1241 +    };
 27.1242 +
 27.1243 +    /**
 27.1244 +     * Assign an event handler to receive an object's output events.
 27.1245 +     *
 27.1246 +     * @method setOutputHandler
 27.1247 +     * @static
 27.1248 +     *
 27.1249 +     * @param {Object} object object to mix pipe, unpipe, on, addListener, and removeListener functions into
 27.1250 +     * @param {EventHandler} handler assigned event handler
 27.1251 +     */
 27.1252 +    EventHandler.setOutputHandler = function setOutputHandler(object, handler) {
 27.1253 +        if (handler instanceof EventHandler) handler.bindThis(object);
 27.1254 +        object.pipe = handler.pipe.bind(handler);
 27.1255 +        object.unpipe = handler.unpipe.bind(handler);
 27.1256 +        object.on = handler.on.bind(handler);
 27.1257 +        object.addListener = object.on;
 27.1258 +        object.removeListener = handler.removeListener.bind(handler);
 27.1259 +    };
 27.1260 +
 27.1261 +    /**
 27.1262 +     * Trigger an event, sending to all downstream handlers
 27.1263 +     *   listening for provided 'type' key.
 27.1264 +     *
 27.1265 +     * @method emit
 27.1266 +     *
 27.1267 +     * @param {string} type event type key (for example, 'click')
 27.1268 +     * @param {Object} event event data
 27.1269 +     * @return {EventHandler} this
 27.1270 +     */
 27.1271 +    EventHandler.prototype.emit = function emit(type, event) {
 27.1272 +        EventEmitter.prototype.emit.apply(this, arguments);
 27.1273 +        var i = 0;
 27.1274 +        for (i = 0; i < this.downstream.length; i++) {
 27.1275 +            if (this.downstream[i].trigger) this.downstream[i].trigger(type, event);
 27.1276 +        }
 27.1277 +        for (i = 0; i < this.downstreamFn.length; i++) {
 27.1278 +            this.downstreamFn[i](type, event);
 27.1279 +        }
 27.1280 +        return this;
 27.1281 +    };
 27.1282 +
 27.1283 +    /**
 27.1284 +     * Alias for emit
 27.1285 +     * @method addListener
 27.1286 +     */
 27.1287 +    EventHandler.prototype.trigger = EventHandler.prototype.emit;
 27.1288 +
 27.1289 +    /**
 27.1290 +     * Add event handler object to set of downstream handlers.
 27.1291 +     *
 27.1292 +     * @method pipe
 27.1293 +     *
 27.1294 +     * @param {EventHandler} target event handler target object
 27.1295 +     * @return {EventHandler} passed event handler
 27.1296 +     */
 27.1297 +    EventHandler.prototype.pipe = function pipe(target) {
 27.1298 +        if (target.subscribe instanceof Function) return target.subscribe(this);
 27.1299 +
 27.1300 +        var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream;
 27.1301 +        var index = downstreamCtx.indexOf(target);
 27.1302 +        if (index < 0) downstreamCtx.push(target);
 27.1303 +
 27.1304 +        if (target instanceof Function) target('pipe', null);
 27.1305 +        else if (target.trigger) target.trigger('pipe', null);
 27.1306 +
 27.1307 +        return target;
 27.1308 +    };
 27.1309 +
 27.1310 +    /**
 27.1311 +     * Remove handler object from set of downstream handlers.
 27.1312 +     *   Undoes work of "pipe".
 27.1313 +     *
 27.1314 +     * @method unpipe
 27.1315 +     *
 27.1316 +     * @param {EventHandler} target target handler object
 27.1317 +     * @return {EventHandler} provided target
 27.1318 +     */
 27.1319 +    EventHandler.prototype.unpipe = function unpipe(target) {
 27.1320 +        if (target.unsubscribe instanceof Function) return target.unsubscribe(this);
 27.1321 +
 27.1322 +        var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream;
 27.1323 +        var index = downstreamCtx.indexOf(target);
 27.1324 +        if (index >= 0) {
 27.1325 +            downstreamCtx.splice(index, 1);
 27.1326 +            if (target instanceof Function) target('unpipe', null);
 27.1327 +            else if (target.trigger) target.trigger('unpipe', null);
 27.1328 +            return target;
 27.1329 +        }
 27.1330 +        else return false;
 27.1331 +    };
 27.1332 +
 27.1333 +    /**
 27.1334 +     * Bind a callback function to an event type handled by this object.
 27.1335 +     *
 27.1336 +     * @method "on"
 27.1337 +     *
 27.1338 +     * @param {string} type event type key (for example, 'click')
 27.1339 +     * @param {function(string, Object)} handler callback
 27.1340 +     * @return {EventHandler} this
 27.1341 +     */
 27.1342 +    EventHandler.prototype.on = function on(type, handler) {
 27.1343 +        EventEmitter.prototype.on.apply(this, arguments);
 27.1344 +        if (!(type in this.upstreamListeners)) {
 27.1345 +            var upstreamListener = this.trigger.bind(this, type);
 27.1346 +            this.upstreamListeners[type] = upstreamListener;
 27.1347 +            for (var i = 0; i < this.upstream.length; i++) {
 27.1348 +                this.upstream[i].on(type, upstreamListener);
 27.1349 +            }
 27.1350 +        }
 27.1351 +        return this;
 27.1352 +    };
 27.1353 +
 27.1354 +    /**
 27.1355 +     * Alias for "on"
 27.1356 +     * @method addListener
 27.1357 +     */
 27.1358 +    EventHandler.prototype.addListener = EventHandler.prototype.on;
 27.1359 +
 27.1360 +    /**
 27.1361 +     * Listen for events from an upstream event handler.
 27.1362 +     *
 27.1363 +     * @method subscribe
 27.1364 +     *
 27.1365 +     * @param {EventEmitter} source source emitter object
 27.1366 +     * @return {EventHandler} this
 27.1367 +     */
 27.1368 +    EventHandler.prototype.subscribe = function subscribe(source) {
 27.1369 +        var index = this.upstream.indexOf(source);
 27.1370 +        if (index < 0) {
 27.1371 +            this.upstream.push(source);
 27.1372 +            for (var type in this.upstreamListeners) {
 27.1373 +                source.on(type, this.upstreamListeners[type]);
 27.1374 +            }
 27.1375 +        }
 27.1376 +        return this;
 27.1377 +    };
 27.1378 +
 27.1379 +    /**
 27.1380 +     * Stop listening to events from an upstream event handler.
 27.1381 +     *
 27.1382 +     * @method unsubscribe
 27.1383 +     *
 27.1384 +     * @param {EventEmitter} source source emitter object
 27.1385 +     * @return {EventHandler} this
 27.1386 +     */
 27.1387 +    EventHandler.prototype.unsubscribe = function unsubscribe(source) {
 27.1388 +        var index = this.upstream.indexOf(source);
 27.1389 +        if (index >= 0) {
 27.1390 +            this.upstream.splice(index, 1);
 27.1391 +            for (var type in this.upstreamListeners) {
 27.1392 +                source.removeListener(type, this.upstreamListeners[type]);
 27.1393 +            }
 27.1394 +        }
 27.1395 +        return this;
 27.1396 +    };
 27.1397 +
 27.1398 +    module.exports = EventHandler;
 27.1399 +});
 27.1400 +
 27.1401 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1402 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1403 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1404 + *
 27.1405 + * Owner: mark@famo.us
 27.1406 + * @license MPL 2.0
 27.1407 + * @copyright Famous Industries, Inc. 2014
 27.1408 + */
 27.1409 +
 27.1410 +define('famous/core/ElementAllocator',['require','exports','module'],function(require, exports, module) {
 27.1411 +
 27.1412 +    /**
 27.1413 +     * Internal helper object to Context that handles the process of
 27.1414 +     *   creating and allocating DOM elements within a managed div.
 27.1415 +     *   Private.
 27.1416 +     *
 27.1417 +     * @class ElementAllocator
 27.1418 +     * @constructor
 27.1419 +     * @private
 27.1420 +     * @param {Node} container document element in which Famo.us content will be inserted
 27.1421 +     */
 27.1422 +    function ElementAllocator(container) {
 27.1423 +        if (!container) container = document.createDocumentFragment();
 27.1424 +        this.container = container;
 27.1425 +        this.detachedNodes = {};
 27.1426 +        this.nodeCount = 0;
 27.1427 +    }
 27.1428 +
 27.1429 +    /**
 27.1430 +     * Move the document elements from their original container to a new one.
 27.1431 +     *
 27.1432 +     * @private
 27.1433 +     * @method migrate
 27.1434 +     *
 27.1435 +     * @param {Node} container document element to which Famo.us content will be migrated
 27.1436 +     */
 27.1437 +    ElementAllocator.prototype.migrate = function migrate(container) {
 27.1438 +        var oldContainer = this.container;
 27.1439 +        if (container === oldContainer) return;
 27.1440 +
 27.1441 +        if (oldContainer instanceof DocumentFragment) {
 27.1442 +            container.appendChild(oldContainer);
 27.1443 +        }
 27.1444 +        else {
 27.1445 +            while (oldContainer.hasChildNodes()) {
 27.1446 +                container.appendChild(oldContainer.removeChild(oldContainer.firstChild));
 27.1447 +            }
 27.1448 +        }
 27.1449 +
 27.1450 +        this.container = container;
 27.1451 +    };
 27.1452 +
 27.1453 +    /**
 27.1454 +     * Allocate an element of specified type from the pool.
 27.1455 +     *
 27.1456 +     * @private
 27.1457 +     * @method allocate
 27.1458 +     *
 27.1459 +     * @param {string} type type of element, e.g. 'div'
 27.1460 +     * @return {Node} allocated document element
 27.1461 +     */
 27.1462 +    ElementAllocator.prototype.allocate = function allocate(type) {
 27.1463 +        type = type.toLowerCase();
 27.1464 +        if (!(type in this.detachedNodes)) this.detachedNodes[type] = [];
 27.1465 +        var nodeStore = this.detachedNodes[type];
 27.1466 +        var result;
 27.1467 +        if (nodeStore.length > 0) {
 27.1468 +            result = nodeStore.pop();
 27.1469 +        }
 27.1470 +        else {
 27.1471 +            result = document.createElement(type);
 27.1472 +            this.container.appendChild(result);
 27.1473 +        }
 27.1474 +        this.nodeCount++;
 27.1475 +        return result;
 27.1476 +    };
 27.1477 +
 27.1478 +    /**
 27.1479 +     * De-allocate an element of specified type to the pool.
 27.1480 +     *
 27.1481 +     * @private
 27.1482 +     * @method deallocate
 27.1483 +     *
 27.1484 +     * @param {Node} element document element to deallocate
 27.1485 +     */
 27.1486 +    ElementAllocator.prototype.deallocate = function deallocate(element) {
 27.1487 +        var nodeType = element.nodeName.toLowerCase();
 27.1488 +        var nodeStore = this.detachedNodes[nodeType];
 27.1489 +        nodeStore.push(element);
 27.1490 +        this.nodeCount--;
 27.1491 +    };
 27.1492 +
 27.1493 +    /**
 27.1494 +     * Get count of total allocated nodes in the document.
 27.1495 +     *
 27.1496 +     * @private
 27.1497 +     * @method getNodeCount
 27.1498 +     *
 27.1499 +     * @return {Number} total node count
 27.1500 +     */
 27.1501 +    ElementAllocator.prototype.getNodeCount = function getNodeCount() {
 27.1502 +        return this.nodeCount;
 27.1503 +    };
 27.1504 +
 27.1505 +    module.exports = ElementAllocator;
 27.1506 +});
 27.1507 +
 27.1508 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1509 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1510 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1511 + *
 27.1512 + * Owner: mark@famo.us
 27.1513 + * @license MPL 2.0
 27.1514 + * @copyright Famous Industries, Inc. 2014
 27.1515 + */
 27.1516 +
 27.1517 +define('famous/utilities/Utility',['require','exports','module'],function(require, exports, module) {
 27.1518 +    /**
 27.1519 +     * This namespace holds standalone functionality.
 27.1520 +     *  Currently includes name mapping for transition curves,
 27.1521 +     *  name mapping for origin pairs, and the after() function.
 27.1522 +     *
 27.1523 +     * @class Utility
 27.1524 +     * @static
 27.1525 +     */
 27.1526 +    var Utility = {};
 27.1527 +
 27.1528 +    /**
 27.1529 +     * Table of direction array positions
 27.1530 +     *
 27.1531 +     * @property {object} Direction
 27.1532 +     * @final
 27.1533 +     */
 27.1534 +    Utility.Direction = {
 27.1535 +        X: 0,
 27.1536 +        Y: 1,
 27.1537 +        Z: 2
 27.1538 +    };
 27.1539 +
 27.1540 +    /**
 27.1541 +     * Return wrapper around callback function. Once the wrapper is called N
 27.1542 +     *   times, invoke the callback function. Arguments and scope preserved.
 27.1543 +     *
 27.1544 +     * @method after
 27.1545 +     *
 27.1546 +     * @param {number} count number of calls before callback function invoked
 27.1547 +     * @param {Function} callback wrapped callback function
 27.1548 +     *
 27.1549 +     * @return {function} wrapped callback with coundown feature
 27.1550 +     */
 27.1551 +    Utility.after = function after(count, callback) {
 27.1552 +        var counter = count;
 27.1553 +        return function() {
 27.1554 +            counter--;
 27.1555 +            if (counter === 0) callback.apply(this, arguments);
 27.1556 +        };
 27.1557 +    };
 27.1558 +
 27.1559 +    /**
 27.1560 +     * Load a URL and return its contents in a callback
 27.1561 +     *
 27.1562 +     * @method loadURL
 27.1563 +     *
 27.1564 +     * @param {string} url URL of object
 27.1565 +     * @param {function} callback callback to dispatch with content
 27.1566 +     */
 27.1567 +    Utility.loadURL = function loadURL(url, callback) {
 27.1568 +        var xhr = new XMLHttpRequest();
 27.1569 +        xhr.onreadystatechange = function onreadystatechange() {
 27.1570 +            if (this.readyState === 4) {
 27.1571 +                if (callback) callback(this.responseText);
 27.1572 +            }
 27.1573 +        };
 27.1574 +        xhr.open('GET', url);
 27.1575 +        xhr.send();
 27.1576 +    };
 27.1577 +
 27.1578 +    /**
 27.1579 +     * Create a document fragment from a string of HTML
 27.1580 +     *
 27.1581 +     * @method createDocumentFragmentFromHTML
 27.1582 +     *
 27.1583 +     * @param {string} html HTML to convert to DocumentFragment
 27.1584 +     *
 27.1585 +     * @return {DocumentFragment} DocumentFragment representing input HTML
 27.1586 +     */
 27.1587 +    Utility.createDocumentFragmentFromHTML = function createDocumentFragmentFromHTML(html) {
 27.1588 +        var element = document.createElement('div');
 27.1589 +        element.innerHTML = html;
 27.1590 +        var result = document.createDocumentFragment();
 27.1591 +        while (element.hasChildNodes()) result.appendChild(element.firstChild);
 27.1592 +        return result;
 27.1593 +    };
 27.1594 +
 27.1595 +    module.exports = Utility;
 27.1596 +});
 27.1597 +
 27.1598 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1599 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1600 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1601 + *
 27.1602 + * Owner: david@famo.us
 27.1603 + * @license MPL 2.0
 27.1604 + * @copyright Famous Industries, Inc. 2014
 27.1605 + */
 27.1606 +
 27.1607 +define('famous/transitions/MultipleTransition',['require','exports','module','famous/utilities/Utility'],function(require, exports, module) {
 27.1608 +    var Utility = require('famous/utilities/Utility');
 27.1609 +
 27.1610 +    /**
 27.1611 +     * Transition meta-method to support transitioning multiple
 27.1612 +     *   values with scalar-only methods.
 27.1613 +     *
 27.1614 +     *
 27.1615 +     * @class MultipleTransition
 27.1616 +     * @constructor
 27.1617 +     *
 27.1618 +     * @param {Object} method Transionable class to multiplex
 27.1619 +     */
 27.1620 +    function MultipleTransition(method) {
 27.1621 +        this.method = method;
 27.1622 +        this._instances = [];
 27.1623 +        this.state = [];
 27.1624 +    }
 27.1625 +
 27.1626 +    MultipleTransition.SUPPORTS_MULTIPLE = true;
 27.1627 +
 27.1628 +    /**
 27.1629 +     * Get the state of each transition.
 27.1630 +     *
 27.1631 +     * @method get
 27.1632 +     *
 27.1633 +     * @return state {Number|Array} state array
 27.1634 +     */
 27.1635 +    MultipleTransition.prototype.get = function get() {
 27.1636 +        for (var i = 0; i < this._instances.length; i++) {
 27.1637 +            this.state[i] = this._instances[i].get();
 27.1638 +        }
 27.1639 +        return this.state;
 27.1640 +    };
 27.1641 +
 27.1642 +    /**
 27.1643 +     * Set the end states with a shared transition, with optional callback.
 27.1644 +     *
 27.1645 +     * @method set
 27.1646 +     *
 27.1647 +     * @param {Number|Array} endState Final State.  Use a multi-element argument for multiple transitions.
 27.1648 +     * @param {Object} transition Transition definition, shared among all instances
 27.1649 +     * @param {Function} callback called when all endStates have been reached.
 27.1650 +     */
 27.1651 +    MultipleTransition.prototype.set = function set(endState, transition, callback) {
 27.1652 +        var _allCallback = Utility.after(endState.length, callback);
 27.1653 +        for (var i = 0; i < endState.length; i++) {
 27.1654 +            if (!this._instances[i]) this._instances[i] = new (this.method)();
 27.1655 +            this._instances[i].set(endState[i], transition, _allCallback);
 27.1656 +        }
 27.1657 +    };
 27.1658 +
 27.1659 +    /**
 27.1660 +     * Reset all transitions to start state.
 27.1661 +     *
 27.1662 +     * @method reset
 27.1663 +     *
 27.1664 +     * @param  {Number|Array} startState Start state
 27.1665 +     */
 27.1666 +    MultipleTransition.prototype.reset = function reset(startState) {
 27.1667 +        for (var i = 0; i < startState.length; i++) {
 27.1668 +            if (!this._instances[i]) this._instances[i] = new (this.method)();
 27.1669 +            this._instances[i].reset(startState[i]);
 27.1670 +        }
 27.1671 +    };
 27.1672 +
 27.1673 +    module.exports = MultipleTransition;
 27.1674 +});
 27.1675 +
 27.1676 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.1677 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.1678 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.1679 + *
 27.1680 + * Owner: david@famo.us
 27.1681 + * @license MPL 2.0
 27.1682 + * @copyright Famous Industries, Inc. 2014
 27.1683 + */
 27.1684 +
 27.1685 +define('famous/transitions/TweenTransition',['require','exports','module'],function(require, exports, module) {
 27.1686 +
 27.1687 +    /**
 27.1688 +     *
 27.1689 +     * A state maintainer for a smooth transition between
 27.1690 +     *    numerically-specified states.  Example numeric states include floats or
 27.1691 +     *    Transfornm objects.
 27.1692 +     *
 27.1693 +     *    An initial state is set with the constructor or set(startValue). A
 27.1694 +     *    corresponding end state and transition are set with set(endValue,
 27.1695 +     *    transition). Subsequent calls to set(endValue, transition) begin at
 27.1696 +     *    the last state. Calls to get(timestamp) provide the _interpolated state
 27.1697 +     *    along the way.
 27.1698 +     *
 27.1699 +     *   Note that there is no event loop here - calls to get() are the only way
 27.1700 +     *    to find out state projected to the current (or provided) time and are
 27.1701 +     *    the only way to trigger callbacks. Usually this kind of object would
 27.1702 +     *    be part of the render() path of a visible component.
 27.1703 +     *
 27.1704 +     * @class TweenTransition
 27.1705 +     * @constructor
 27.1706 +     *
 27.1707 +     * @param {Object} options TODO
 27.1708 +     *    beginning state
 27.1709 +     */
 27.1710 +    function TweenTransition(options) {
 27.1711 +        this.options = Object.create(TweenTransition.DEFAULT_OPTIONS);
 27.1712 +        if (options) this.setOptions(options);
 27.1713 +
 27.1714 +        this._startTime = 0;
 27.1715 +        this._startValue = 0;
 27.1716 +        this._updateTime = 0;
 27.1717 +        this._endValue = 0;
 27.1718 +        this._curve = undefined;
 27.1719 +        this._duration = 0;
 27.1720 +        this._active = false;
 27.1721 +        this._callback = undefined;
 27.1722 +        this.state = 0;
 27.1723 +        this.velocity = undefined;
 27.1724 +    }
 27.1725 +
 27.1726 +    /**
 27.1727 +     * Transition curves mapping independent variable t from domain [0,1] to a
 27.1728 +     *    range within [0,1]. Includes functions 'linear', 'easeIn', 'easeOut',
 27.1729 +     *    'easeInOut', 'easeOutBounce', 'spring'.
 27.1730 +     *
 27.1731 +     * @property {object} Curve
 27.1732 +     * @final
 27.1733 +     */
 27.1734 +    TweenTransition.Curves = {
 27.1735 +        linear: function(t) {
 27.1736 +            return t;
 27.1737 +        },
 27.1738 +        easeIn: function(t) {
 27.1739 +            return t*t;
 27.1740 +        },
 27.1741 +        easeOut: function(t) {
 27.1742 +            return t*(2-t);
 27.1743 +        },
 27.1744 +        easeInOut: function(t) {
 27.1745 +            if (t <= 0.5) return 2*t*t;
 27.1746 +            else return -2*t*t + 4*t - 1;
 27.1747 +        },
 27.1748 +        easeOutBounce: function(t) {
 27.1749 +            return t*(3 - 2*t);
 27.1750 +        },
 27.1751 +        spring: function(t) {
 27.1752 +            return (1 - t) * Math.sin(6 * Math.PI * t) + t;
 27.1753 +        }
 27.1754 +    };
 27.1755 +
 27.1756 +    TweenTransition.SUPPORTS_MULTIPLE = true;
 27.1757 +    TweenTransition.DEFAULT_OPTIONS = {
 27.1758 +        curve: TweenTransition.Curves.linear,
 27.1759 +        duration: 500,
 27.1760 +        speed: 0 /* considered only if positive */
 27.1761 +    };
 27.1762 +
 27.1763 +    var registeredCurves = {};
 27.1764 +
 27.1765 +    /**
 27.1766 +     * Add "unit" curve to internal dictionary of registered curves.
 27.1767 +     *
 27.1768 +     * @method registerCurve
 27.1769 +     *
 27.1770 +     * @static
 27.1771 +     *
 27.1772 +     * @param {string} curveName dictionary key
 27.1773 +     * @param {unitCurve} curve function of one numeric variable mapping [0,1]
 27.1774 +     *    to range inside [0,1]
 27.1775 +     * @return {boolean} false if key is taken, else true
 27.1776 +     */
 27.1777 +    TweenTransition.registerCurve = function registerCurve(curveName, curve) {
 27.1778 +        if (!registeredCurves[curveName]) {
 27.1779 +            registeredCurves[curveName] = curve;
 27.1780 +            return true;
 27.1781 +        }
 27.1782 +        else {
 27.1783 +            return false;
 27.1784 +        }
 27.1785 +    };
 27.1786 +
 27.1787 +    /**
 27.1788 +     * Remove object with key "curveName" from internal dictionary of registered
 27.1789 +     *    curves.
 27.1790 +     *
 27.1791 +     * @method unregisterCurve
 27.1792 +     *
 27.1793 +     * @static
 27.1794 +     *
 27.1795 +     * @param {string} curveName dictionary key
 27.1796 +     * @return {boolean} false if key has no dictionary value
 27.1797 +     */
 27.1798 +    TweenTransition.unregisterCurve = function unregisterCurve(curveName) {
 27.1799 +        if (registeredCurves[curveName]) {
 27.1800 +            delete registeredCurves[curveName];
 27.1801 +            return true;
 27.1802 +        }
 27.1803 +        else {
 27.1804 +            return false;
 27.1805 +        }
 27.1806 +    };
 27.1807 +
 27.1808 +    /**
 27.1809 +     * Retrieve function with key "curveName" from internal dictionary of
 27.1810 +     *    registered curves. Default curves are defined in the
 27.1811 +     *    TweenTransition.Curves array, where the values represent
 27.1812 +     *    unitCurve functions.
 27.1813 +     *
 27.1814 +     * @method getCurve
 27.1815 +     *
 27.1816 +     * @static
 27.1817 +     *
 27.1818 +     * @param {string} curveName dictionary key
 27.1819 +     * @return {unitCurve} curve function of one numeric variable mapping [0,1]
 27.1820 +     *    to range inside [0,1]
 27.1821 +     */
 27.1822 +    TweenTransition.getCurve = function getCurve(curveName) {
 27.1823 +        var curve = registeredCurves[curveName];
 27.1824 +        if (curve !== undefined) return curve;
 27.1825 +        else throw new Error('curve not registered');
 27.1826 +    };
 27.1827 +
 27.1828 +    /**
 27.1829 +     * Retrieve all available curves.
 27.1830 +     *
 27.1831 +     * @method getCurves
 27.1832 +     *
 27.1833 +     * @static
 27.1834 +     *
 27.1835 +     * @return {object} curve functions of one numeric variable mapping [0,1]
 27.1836 +     *    to range inside [0,1]
 27.1837 +     */
 27.1838 +    TweenTransition.getCurves = function getCurves() {
 27.1839 +        return registeredCurves;
 27.1840 +    };
 27.1841 +
 27.1842 +     // Interpolate: If a linear function f(0) = a, f(1) = b, then return f(t)
 27.1843 +    function _interpolate(a, b, t) {
 27.1844 +        return ((1 - t) * a) + (t * b);
 27.1845 +    }
 27.1846 +
 27.1847 +    function _clone(obj) {
 27.1848 +        if (obj instanceof Object) {
 27.1849 +            if (obj instanceof Array) return obj.slice(0);
 27.1850 +            else return Object.create(obj);
 27.1851 +        }
 27.1852 +        else return obj;
 27.1853 +    }
 27.1854 +
 27.1855 +    // Fill in missing properties in "transition" with those in defaultTransition, and
 27.1856 +    //   convert internal named curve to function object, returning as new
 27.1857 +    //   object.
 27.1858 +    function _normalize(transition, defaultTransition) {
 27.1859 +        var result = {curve: defaultTransition.curve};
 27.1860 +        if (defaultTransition.duration) result.duration = defaultTransition.duration;
 27.1861 +        if (defaultTransition.speed) result.speed = defaultTransition.speed;
 27.1862 +        if (transition instanceof Object) {
 27.1863 +            if (transition.duration !== undefined) result.duration = transition.duration;
 27.1864 +            if (transition.curve) result.curve = transition.curve;
 27.1865 +            if (transition.speed) result.speed = transition.speed;
 27.1866 +        }
 27.1867 +        if (typeof result.curve === 'string') result.curve = TweenTransition.getCurve(result.curve);
 27.1868 +        return result;
 27.1869 +    }
 27.1870 +
 27.1871 +    /**
 27.1872 +     * Set internal options, overriding any default options.
 27.1873 +     *
 27.1874 +     * @method setOptions
 27.1875 +     *
 27.1876 +     *
 27.1877 +     * @param {Object} options options object
 27.1878 +     * @param {Object} [options.curve] function mapping [0,1] to [0,1] or identifier
 27.1879 +     * @param {Number} [options.duration] duration in ms
 27.1880 +     * @param {Number} [options.speed] speed in pixels per ms
 27.1881 +     */
 27.1882 +    TweenTransition.prototype.setOptions = function setOptions(options) {
 27.1883 +        if (options.curve !== undefined) this.options.curve = options.curve;
 27.1884 +        if (options.duration !== undefined) this.options.duration = options.duration;
 27.1885 +        if (options.speed !== undefined) this.options.speed = options.speed;
 27.1886 +    };
 27.1887 +
 27.1888 +    /**
 27.1889 +     * Add transition to end state to the queue of pending transitions. Special
 27.1890 +     *    Use: calling without a transition resets the object to that state with
 27.1891 +     *    no pending actions
 27.1892 +     *
 27.1893 +     * @method set
 27.1894 +     *
 27.1895 +     *
 27.1896 +     * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endValue
 27.1897 +     *    end state to which we _interpolate
 27.1898 +     * @param {transition=} transition object of type {duration: number, curve:
 27.1899 +     *    f[0,1] -> [0,1] or name}. If transition is omitted, change will be
 27.1900 +     *    instantaneous.
 27.1901 +     * @param {function()=} callback Zero-argument function to call on observed
 27.1902 +     *    completion (t=1)
 27.1903 +     */
 27.1904 +    TweenTransition.prototype.set = function set(endValue, transition, callback) {
 27.1905 +        if (!transition) {
 27.1906 +            this.reset(endValue);
 27.1907 +            if (callback) callback();
 27.1908 +            return;
 27.1909 +        }
 27.1910 +
 27.1911 +        this._startValue = _clone(this.get());
 27.1912 +        transition = _normalize(transition, this.options);
 27.1913 +        if (transition.speed) {
 27.1914 +            var startValue = this._startValue;
 27.1915 +            if (startValue instanceof Object) {
 27.1916 +                var variance = 0;
 27.1917 +                for (var i in startValue) variance += (endValue[i] - startValue[i]) * (endValue[i] - startValue[i]);
 27.1918 +                transition.duration = Math.sqrt(variance) / transition.speed;
 27.1919 +            }
 27.1920 +            else {
 27.1921 +                transition.duration = Math.abs(endValue - startValue) / transition.speed;
 27.1922 +            }
 27.1923 +        }
 27.1924 +
 27.1925 +        this._startTime = Date.now();
 27.1926 +        this._endValue = _clone(endValue);
 27.1927 +        this._startVelocity = _clone(transition.velocity);
 27.1928 +        this._duration = transition.duration;
 27.1929 +        this._curve = transition.curve;
 27.1930 +        this._active = true;
 27.1931 +        this._callback = callback;
 27.1932 +    };
 27.1933 +
 27.1934 +    /**
 27.1935 +     * Cancel all transitions and reset to a stable state
 27.1936 +     *
 27.1937 +     * @method reset
 27.1938 +     *
 27.1939 +     * @param {number|Array.Number|Object.<number, number>} startValue
 27.1940 +     *    starting state
 27.1941 +     * @param {number} startVelocity
 27.1942 +     *    starting velocity
 27.1943 +     */
 27.1944 +    TweenTransition.prototype.reset = function reset(startValue, startVelocity) {
 27.1945 +        if (this._callback) {
 27.1946 +            var callback = this._callback;
 27.1947 +            this._callback = undefined;
 27.1948 +            callback();
 27.1949 +        }
 27.1950 +        this.state = _clone(startValue);
 27.1951 +        this.velocity = _clone(startVelocity);
 27.1952 +        this._startTime = 0;
 27.1953 +        this._duration = 0;
 27.1954 +        this._updateTime = 0;
 27.1955 +        this._startValue = this.state;
 27.1956 +        this._startVelocity = this.velocity;
 27.1957 +        this._endValue = this.state;
 27.1958 +        this._active = false;
 27.1959 +    };
 27.1960 +
 27.1961 +    /**
 27.1962 +     * Get current velocity
 27.1963 +     *
 27.1964 +     * @method getVelocity
 27.1965 +     *
 27.1966 +     * @returns {Number} velocity
 27.1967 +     */
 27.1968 +    TweenTransition.prototype.getVelocity = function getVelocity() {
 27.1969 +        return this.velocity;
 27.1970 +    };
 27.1971 +
 27.1972 +    /**
 27.1973 +     * Get interpolated state of current action at provided time. If the last
 27.1974 +     *    action has completed, invoke its callback.
 27.1975 +     *
 27.1976 +     * @method get
 27.1977 +     *
 27.1978 +     *
 27.1979 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 27.1980 +     *    time. If omitted, use current time. (Unix epoch time)
 27.1981 +     * @return {number|Object.<number|string, number>} beginning state
 27.1982 +     *    _interpolated to this point in time.
 27.1983 +     */
 27.1984 +    TweenTransition.prototype.get = function get(timestamp) {
 27.1985 +        this.update(timestamp);
 27.1986 +        return this.state;
 27.1987 +    };
 27.1988 +
 27.1989 +    function _calculateVelocity(current, start, curve, duration, t) {
 27.1990 +        var velocity;
 27.1991 +        var eps = 1e-7;
 27.1992 +        var speed = (curve(t) - curve(t - eps)) / eps;
 27.1993 +        if (current instanceof Array) {
 27.1994 +            velocity = [];
 27.1995 +            for (var i = 0; i < current.length; i++){
 27.1996 +                if (typeof current[i] === 'number')
 27.1997 +                    velocity[i] = speed * (current[i] - start[i]) / duration;
 27.1998 +                else
 27.1999 +                    velocity[i] = 0;
 27.2000 +            }
 27.2001 +
 27.2002 +        }
 27.2003 +        else velocity = speed * (current - start) / duration;
 27.2004 +        return velocity;
 27.2005 +    }
 27.2006 +
 27.2007 +    function _calculateState(start, end, t) {
 27.2008 +        var state;
 27.2009 +        if (start instanceof Array) {
 27.2010 +            state = [];
 27.2011 +            for (var i = 0; i < start.length; i++) {
 27.2012 +                if (typeof start[i] === 'number')
 27.2013 +                    state[i] = _interpolate(start[i], end[i], t);
 27.2014 +                else
 27.2015 +                    state[i] = start[i];
 27.2016 +            }
 27.2017 +        }
 27.2018 +        else state = _interpolate(start, end, t);
 27.2019 +        return state;
 27.2020 +    }
 27.2021 +
 27.2022 +    /**
 27.2023 +     * Update internal state to the provided timestamp. This may invoke the last
 27.2024 +     *    callback and begin a new action.
 27.2025 +     *
 27.2026 +     * @method update
 27.2027 +     *
 27.2028 +     *
 27.2029 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 27.2030 +     *    time. If omitted, use current time. (Unix epoch time)
 27.2031 +     */
 27.2032 +    TweenTransition.prototype.update = function update(timestamp) {
 27.2033 +        if (!this._active) {
 27.2034 +            if (this._callback) {
 27.2035 +                var callback = this._callback;
 27.2036 +                this._callback = undefined;
 27.2037 +                callback();
 27.2038 +            }
 27.2039 +            return;
 27.2040 +        }
 27.2041 +
 27.2042 +        if (!timestamp) timestamp = Date.now();
 27.2043 +        if (this._updateTime >= timestamp) return;
 27.2044 +        this._updateTime = timestamp;
 27.2045 +
 27.2046 +        var timeSinceStart = timestamp - this._startTime;
 27.2047 +        if (timeSinceStart >= this._duration) {
 27.2048 +            this.state = this._endValue;
 27.2049 +            this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, 1);
 27.2050 +            this._active = false;
 27.2051 +        }
 27.2052 +        else if (timeSinceStart < 0) {
 27.2053 +            this.state = this._startValue;
 27.2054 +            this.velocity = this._startVelocity;
 27.2055 +        }
 27.2056 +        else {
 27.2057 +            var t = timeSinceStart / this._duration;
 27.2058 +            this.state = _calculateState(this._startValue, this._endValue, this._curve(t));
 27.2059 +            this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, t);
 27.2060 +        }
 27.2061 +    };
 27.2062 +
 27.2063 +    /**
 27.2064 +     * Is there at least one action pending completion?
 27.2065 +     *
 27.2066 +     * @method isActive
 27.2067 +     *
 27.2068 +     *
 27.2069 +     * @return {boolean}
 27.2070 +     */
 27.2071 +    TweenTransition.prototype.isActive = function isActive() {
 27.2072 +        return this._active;
 27.2073 +    };
 27.2074 +
 27.2075 +    /**
 27.2076 +     * Halt transition at current state and erase all pending actions.
 27.2077 +     *
 27.2078 +     * @method halt
 27.2079 +     *
 27.2080 +     */
 27.2081 +    TweenTransition.prototype.halt = function halt() {
 27.2082 +        this.reset(this.get());
 27.2083 +    };
 27.2084 +
 27.2085 +    // Register all the default curves
 27.2086 +    TweenTransition.registerCurve('linear', TweenTransition.Curves.linear);
 27.2087 +    TweenTransition.registerCurve('easeIn', TweenTransition.Curves.easeIn);
 27.2088 +    TweenTransition.registerCurve('easeOut', TweenTransition.Curves.easeOut);
 27.2089 +    TweenTransition.registerCurve('easeInOut', TweenTransition.Curves.easeInOut);
 27.2090 +    TweenTransition.registerCurve('easeOutBounce', TweenTransition.Curves.easeOutBounce);
 27.2091 +    TweenTransition.registerCurve('spring', TweenTransition.Curves.spring);
 27.2092 +
 27.2093 +    TweenTransition.customCurve = function customCurve(v1, v2) {
 27.2094 +        v1 = v1 || 0; v2 = v2 || 0;
 27.2095 +        return function(t) {
 27.2096 +            return v1*t + (-2*v1 - v2 + 3)*t*t + (v1 + v2 - 2)*t*t*t;
 27.2097 +        };
 27.2098 +    };
 27.2099 +
 27.2100 +    module.exports = TweenTransition;
 27.2101 +});
 27.2102 +
 27.2103 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.2104 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.2105 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.2106 + *
 27.2107 + * Owner: david@famo.us
 27.2108 + * @license MPL 2.0
 27.2109 + * @copyright Famous Industries, Inc. 2014
 27.2110 + */
 27.2111 +
 27.2112 +define('famous/transitions/Transitionable',['require','exports','module','./MultipleTransition','./TweenTransition'],function(require, exports, module) {
 27.2113 +    var MultipleTransition = require('./MultipleTransition');
 27.2114 +    var TweenTransition = require('./TweenTransition');
 27.2115 +
 27.2116 +    /**
 27.2117 +     * A state maintainer for a smooth transition between
 27.2118 +     *    numerically-specified states. Example numeric states include floats or
 27.2119 +     *    Transform objects.
 27.2120 +     *
 27.2121 +     * An initial state is set with the constructor or set(startState). A
 27.2122 +     *    corresponding end state and transition are set with set(endState,
 27.2123 +     *    transition). Subsequent calls to set(endState, transition) begin at
 27.2124 +     *    the last state. Calls to get(timestamp) provide the interpolated state
 27.2125 +     *    along the way.
 27.2126 +     *
 27.2127 +     * Note that there is no event loop here - calls to get() are the only way
 27.2128 +     *    to find state projected to the current (or provided) time and are
 27.2129 +     *    the only way to trigger callbacks. Usually this kind of object would
 27.2130 +     *    be part of the render() path of a visible component.
 27.2131 +     *
 27.2132 +     * @class Transitionable
 27.2133 +     * @constructor
 27.2134 +     * @param {number|Array.Number|Object.<number|string, number>} start
 27.2135 +     *    beginning state
 27.2136 +     */
 27.2137 +    function Transitionable(start) {
 27.2138 +        this.currentAction = null;
 27.2139 +        this.actionQueue = [];
 27.2140 +        this.callbackQueue = [];
 27.2141 +
 27.2142 +        this.state = 0;
 27.2143 +        this.velocity = undefined;
 27.2144 +        this._callback = undefined;
 27.2145 +        this._engineInstance = null;
 27.2146 +        this._currentMethod = null;
 27.2147 +
 27.2148 +        this.set(start);
 27.2149 +    }
 27.2150 +
 27.2151 +    var transitionMethods = {};
 27.2152 +
 27.2153 +    Transitionable.registerMethod = function registerMethod(name, engineClass) {
 27.2154 +        if (!(name in transitionMethods)) {
 27.2155 +            transitionMethods[name] = engineClass;
 27.2156 +            return true;
 27.2157 +        }
 27.2158 +        else return false;
 27.2159 +    };
 27.2160 +
 27.2161 +    Transitionable.unregisterMethod = function unregisterMethod(name) {
 27.2162 +        if (name in transitionMethods) {
 27.2163 +            delete transitionMethods[name];
 27.2164 +            return true;
 27.2165 +        }
 27.2166 +        else return false;
 27.2167 +    };
 27.2168 +
 27.2169 +    function _loadNext() {
 27.2170 +        if (this._callback) {
 27.2171 +            var callback = this._callback;
 27.2172 +            this._callback = undefined;
 27.2173 +            callback();
 27.2174 +        }
 27.2175 +        if (this.actionQueue.length <= 0) {
 27.2176 +            this.set(this.get()); // no update required
 27.2177 +            return;
 27.2178 +        }
 27.2179 +        this.currentAction = this.actionQueue.shift();
 27.2180 +        this._callback = this.callbackQueue.shift();
 27.2181 +
 27.2182 +        var method = null;
 27.2183 +        var endValue = this.currentAction[0];
 27.2184 +        var transition = this.currentAction[1];
 27.2185 +        if (transition instanceof Object && transition.method) {
 27.2186 +            method = transition.method;
 27.2187 +            if (typeof method === 'string') method = transitionMethods[method];
 27.2188 +        }
 27.2189 +        else {
 27.2190 +            method = TweenTransition;
 27.2191 +        }
 27.2192 +
 27.2193 +        if (this._currentMethod !== method) {
 27.2194 +            if (!(endValue instanceof Object) || method.SUPPORTS_MULTIPLE === true || endValue.length <= method.SUPPORTS_MULTIPLE) {
 27.2195 +                this._engineInstance = new method();
 27.2196 +            }
 27.2197 +            else {
 27.2198 +                this._engineInstance = new MultipleTransition(method);
 27.2199 +            }
 27.2200 +            this._currentMethod = method;
 27.2201 +        }
 27.2202 +
 27.2203 +        this._engineInstance.reset(this.state, this.velocity);
 27.2204 +        if (this.velocity !== undefined) transition.velocity = this.velocity;
 27.2205 +        this._engineInstance.set(endValue, transition, _loadNext.bind(this));
 27.2206 +    }
 27.2207 +
 27.2208 +    /**
 27.2209 +     * Add transition to end state to the queue of pending transitions. Special
 27.2210 +     *    Use: calling without a transition resets the object to that state with
 27.2211 +     *    no pending actions
 27.2212 +     *
 27.2213 +     * @method set
 27.2214 +     *
 27.2215 +     * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endState
 27.2216 +     *    end state to which we interpolate
 27.2217 +     * @param {transition=} transition object of type {duration: number, curve:
 27.2218 +     *    f[0,1] -> [0,1] or name}. If transition is omitted, change will be
 27.2219 +     *    instantaneous.
 27.2220 +     * @param {function()=} callback Zero-argument function to call on observed
 27.2221 +     *    completion (t=1)
 27.2222 +     */
 27.2223 +    Transitionable.prototype.set = function set(endState, transition, callback) {
 27.2224 +        if (!transition) {
 27.2225 +            this.reset(endState);
 27.2226 +            if (callback) callback();
 27.2227 +            return this;
 27.2228 +        }
 27.2229 +
 27.2230 +        var action = [endState, transition];
 27.2231 +        this.actionQueue.push(action);
 27.2232 +        this.callbackQueue.push(callback);
 27.2233 +        if (!this.currentAction) _loadNext.call(this);
 27.2234 +        return this;
 27.2235 +    };
 27.2236 +
 27.2237 +    /**
 27.2238 +     * Cancel all transitions and reset to a stable state
 27.2239 +     *
 27.2240 +     * @method reset
 27.2241 +     *
 27.2242 +     * @param {number|Array.Number|Object.<number, number>} startState
 27.2243 +     *    stable state to set to
 27.2244 +     */
 27.2245 +    Transitionable.prototype.reset = function reset(startState, startVelocity) {
 27.2246 +        this._currentMethod = null;
 27.2247 +        this._engineInstance = null;
 27.2248 +        this._callback = undefined;
 27.2249 +        this.state = startState;
 27.2250 +        this.velocity = startVelocity;
 27.2251 +        this.currentAction = null;
 27.2252 +        this.actionQueue = [];
 27.2253 +        this.callbackQueue = [];
 27.2254 +    };
 27.2255 +
 27.2256 +    /**
 27.2257 +     * Add delay action to the pending action queue queue.
 27.2258 +     *
 27.2259 +     * @method delay
 27.2260 +     *
 27.2261 +     * @param {number} duration delay time (ms)
 27.2262 +     * @param {function} callback Zero-argument function to call on observed
 27.2263 +     *    completion (t=1)
 27.2264 +     */
 27.2265 +    Transitionable.prototype.delay = function delay(duration, callback) {
 27.2266 +        this.set(this.get(), {duration: duration,
 27.2267 +            curve: function() {
 27.2268 +                return 0;
 27.2269 +            }},
 27.2270 +            callback
 27.2271 +        );
 27.2272 +    };
 27.2273 +
 27.2274 +    /**
 27.2275 +     * Get interpolated state of current action at provided time. If the last
 27.2276 +     *    action has completed, invoke its callback.
 27.2277 +     *
 27.2278 +     * @method get
 27.2279 +     *
 27.2280 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 27.2281 +     *    time. If omitted, use current time. (Unix epoch time)
 27.2282 +     * @return {number|Object.<number|string, number>} beginning state
 27.2283 +     *    interpolated to this point in time.
 27.2284 +     */
 27.2285 +    Transitionable.prototype.get = function get(timestamp) {
 27.2286 +        if (this._engineInstance) {
 27.2287 +            if (this._engineInstance.getVelocity)
 27.2288 +                this.velocity = this._engineInstance.getVelocity();
 27.2289 +            this.state = this._engineInstance.get(timestamp);
 27.2290 +        }
 27.2291 +        return this.state;
 27.2292 +    };
 27.2293 +
 27.2294 +    /**
 27.2295 +     * Is there at least one action pending completion?
 27.2296 +     *
 27.2297 +     * @method isActive
 27.2298 +     *
 27.2299 +     * @return {boolean}
 27.2300 +     */
 27.2301 +    Transitionable.prototype.isActive = function isActive() {
 27.2302 +        return !!this.currentAction;
 27.2303 +    };
 27.2304 +
 27.2305 +    /**
 27.2306 +     * Halt transition at current state and erase all pending actions.
 27.2307 +     *
 27.2308 +     * @method halt
 27.2309 +     */
 27.2310 +    Transitionable.prototype.halt = function halt() {
 27.2311 +        this.set(this.get());
 27.2312 +    };
 27.2313 +
 27.2314 +    module.exports = Transitionable;
 27.2315 +});
 27.2316 +
 27.2317 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.2318 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.2319 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.2320 + *
 27.2321 + * Owner: mark@famo.us
 27.2322 + * @license MPL 2.0
 27.2323 + * @copyright Famous Industries, Inc. 2014
 27.2324 + */
 27.2325 +
 27.2326 +define('famous/core/Context',['require','exports','module','./RenderNode','./EventHandler','./ElementAllocator','./Transform','famous/transitions/Transitionable'],function(require, exports, module) {
 27.2327 +    var RenderNode = require('./RenderNode');
 27.2328 +    var EventHandler = require('./EventHandler');
 27.2329 +    var ElementAllocator = require('./ElementAllocator');
 27.2330 +    var Transform = require('./Transform');
 27.2331 +    var Transitionable = require('famous/transitions/Transitionable');
 27.2332 +
 27.2333 +    var _originZeroZero = [0, 0];
 27.2334 +
 27.2335 +    function _getElementSize(element) {
 27.2336 +        return [element.clientWidth, element.clientHeight];
 27.2337 +    }
 27.2338 +
 27.2339 +    /**
 27.2340 +     * The top-level container for a Famous-renderable piece of the document.
 27.2341 +     *   It is directly updated by the process-wide Engine object, and manages one
 27.2342 +     *   render tree root, which can contain other renderables.
 27.2343 +     *
 27.2344 +     * @class Context
 27.2345 +     * @constructor
 27.2346 +     * @private
 27.2347 +     * @param {Node} container Element in which content will be inserted
 27.2348 +     */
 27.2349 +    function Context(container) {
 27.2350 +        this.container = container;
 27.2351 +        this._allocator = new ElementAllocator(container);
 27.2352 +
 27.2353 +        this._node = new RenderNode();
 27.2354 +        this._eventOutput = new EventHandler();
 27.2355 +        this._size = _getElementSize(this.container);
 27.2356 +
 27.2357 +        this._perspectiveState = new Transitionable(0);
 27.2358 +        this._perspective = undefined;
 27.2359 +
 27.2360 +        this._nodeContext = {
 27.2361 +            allocator: this._allocator,
 27.2362 +            transform: Transform.identity,
 27.2363 +            opacity: 1,
 27.2364 +            origin: _originZeroZero,
 27.2365 +            align: null,
 27.2366 +            size: this._size
 27.2367 +        };
 27.2368 +
 27.2369 +        this._eventOutput.on('resize', function() {
 27.2370 +            this.setSize(_getElementSize(this.container));
 27.2371 +        }.bind(this));
 27.2372 +
 27.2373 +    }
 27.2374 +
 27.2375 +    // Note: Unused
 27.2376 +    Context.prototype.getAllocator = function getAllocator() {
 27.2377 +        return this._allocator;
 27.2378 +    };
 27.2379 +
 27.2380 +    /**
 27.2381 +     * Add renderables to this Context's render tree.
 27.2382 +     *
 27.2383 +     * @method add
 27.2384 +     *
 27.2385 +     * @param {Object} obj renderable object
 27.2386 +     * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode
 27.2387 +     */
 27.2388 +    Context.prototype.add = function add(obj) {
 27.2389 +        return this._node.add(obj);
 27.2390 +    };
 27.2391 +
 27.2392 +    /**
 27.2393 +     * Move this Context to another containing document element.
 27.2394 +     *
 27.2395 +     * @method migrate
 27.2396 +     *
 27.2397 +     * @param {Node} container Element to which content will be migrated
 27.2398 +     */
 27.2399 +    Context.prototype.migrate = function migrate(container) {
 27.2400 +        if (container === this.container) return;
 27.2401 +        this.container = container;
 27.2402 +        this._allocator.migrate(container);
 27.2403 +    };
 27.2404 +
 27.2405 +    /**
 27.2406 +     * Gets viewport size for Context.
 27.2407 +     *
 27.2408 +     * @method getSize
 27.2409 +     *
 27.2410 +     * @return {Array.Number} viewport size as [width, height]
 27.2411 +     */
 27.2412 +    Context.prototype.getSize = function getSize() {
 27.2413 +        return this._size;
 27.2414 +    };
 27.2415 +
 27.2416 +    /**
 27.2417 +     * Sets viewport size for Context.
 27.2418 +     *
 27.2419 +     * @method setSize
 27.2420 +     *
 27.2421 +     * @param {Array.Number} size [width, height].  If unspecified, use size of root document element.
 27.2422 +     */
 27.2423 +    Context.prototype.setSize = function setSize(size) {
 27.2424 +        if (!size) size = _getElementSize(this.container);
 27.2425 +        this._size[0] = size[0];
 27.2426 +        this._size[1] = size[1];
 27.2427 +    };
 27.2428 +
 27.2429 +    /**
 27.2430 +     * Commit this Context's content changes to the document.
 27.2431 +     *
 27.2432 +     * @private
 27.2433 +     * @method update
 27.2434 +     * @param {Object} contextParameters engine commit specification
 27.2435 +     */
 27.2436 +    Context.prototype.update = function update(contextParameters) {
 27.2437 +        if (contextParameters) {
 27.2438 +            if (contextParameters.transform) this._nodeContext.transform = contextParameters.transform;
 27.2439 +            if (contextParameters.opacity) this._nodeContext.opacity = contextParameters.opacity;
 27.2440 +            if (contextParameters.origin) this._nodeContext.origin = contextParameters.origin;
 27.2441 +            if (contextParameters.align) this._nodeContext.align = contextParameters.align;
 27.2442 +            if (contextParameters.size) this._nodeContext.size = contextParameters.size;
 27.2443 +        }
 27.2444 +        var perspective = this._perspectiveState.get();
 27.2445 +        if (perspective !== this._perspective) {
 27.2446 +            this.container.style.perspective = perspective ? perspective.toFixed() + 'px' : '';
 27.2447 +            this.container.style.webkitPerspective = perspective ? perspective.toFixed() : '';
 27.2448 +            this._perspective = perspective;
 27.2449 +        }
 27.2450 +
 27.2451 +        this._node.commit(this._nodeContext);
 27.2452 +    };
 27.2453 +
 27.2454 +    /**
 27.2455 +     * Get current perspective of this context in pixels.
 27.2456 +     *
 27.2457 +     * @method getPerspective
 27.2458 +     * @return {Number} depth perspective in pixels
 27.2459 +     */
 27.2460 +    Context.prototype.getPerspective = function getPerspective() {
 27.2461 +        return this._perspectiveState.get();
 27.2462 +    };
 27.2463 +
 27.2464 +    /**
 27.2465 +     * Set current perspective of this context in pixels.
 27.2466 +     *
 27.2467 +     * @method setPerspective
 27.2468 +     * @param {Number} perspective in pixels
 27.2469 +     * @param {Object} [transition] Transitionable object for applying the change
 27.2470 +     * @param {function(Object)} callback function called on completion of transition
 27.2471 +     */
 27.2472 +    Context.prototype.setPerspective = function setPerspective(perspective, transition, callback) {
 27.2473 +        return this._perspectiveState.set(perspective, transition, callback);
 27.2474 +    };
 27.2475 +
 27.2476 +    /**
 27.2477 +     * Trigger an event, sending to all downstream handlers
 27.2478 +     *   listening for provided 'type' key.
 27.2479 +     *
 27.2480 +     * @method emit
 27.2481 +     *
 27.2482 +     * @param {string} type event type key (for example, 'click')
 27.2483 +     * @param {Object} event event data
 27.2484 +     * @return {EventHandler} this
 27.2485 +     */
 27.2486 +    Context.prototype.emit = function emit(type, event) {
 27.2487 +        return this._eventOutput.emit(type, event);
 27.2488 +    };
 27.2489 +
 27.2490 +    /**
 27.2491 +     * Bind a callback function to an event type handled by this object.
 27.2492 +     *
 27.2493 +     * @method "on"
 27.2494 +     *
 27.2495 +     * @param {string} type event type key (for example, 'click')
 27.2496 +     * @param {function(string, Object)} handler callback
 27.2497 +     * @return {EventHandler} this
 27.2498 +     */
 27.2499 +    Context.prototype.on = function on(type, handler) {
 27.2500 +        return this._eventOutput.on(type, handler);
 27.2501 +    };
 27.2502 +
 27.2503 +    /**
 27.2504 +     * Unbind an event by type and handler.
 27.2505 +     *   This undoes the work of "on".
 27.2506 +     *
 27.2507 +     * @method removeListener
 27.2508 +     *
 27.2509 +     * @param {string} type event type key (for example, 'click')
 27.2510 +     * @param {function} handler function object to remove
 27.2511 +     * @return {EventHandler} internal event handler object (for chaining)
 27.2512 +     */
 27.2513 +    Context.prototype.removeListener = function removeListener(type, handler) {
 27.2514 +        return this._eventOutput.removeListener(type, handler);
 27.2515 +    };
 27.2516 +
 27.2517 +    /**
 27.2518 +     * Add event handler object to set of downstream handlers.
 27.2519 +     *
 27.2520 +     * @method pipe
 27.2521 +     *
 27.2522 +     * @param {EventHandler} target event handler target object
 27.2523 +     * @return {EventHandler} passed event handler
 27.2524 +     */
 27.2525 +    Context.prototype.pipe = function pipe(target) {
 27.2526 +        return this._eventOutput.pipe(target);
 27.2527 +    };
 27.2528 +
 27.2529 +    /**
 27.2530 +     * Remove handler object from set of downstream handlers.
 27.2531 +     *   Undoes work of "pipe".
 27.2532 +     *
 27.2533 +     * @method unpipe
 27.2534 +     *
 27.2535 +     * @param {EventHandler} target target handler object
 27.2536 +     * @return {EventHandler} provided target
 27.2537 +     */
 27.2538 +    Context.prototype.unpipe = function unpipe(target) {
 27.2539 +        return this._eventOutput.unpipe(target);
 27.2540 +    };
 27.2541 +
 27.2542 +    module.exports = Context;
 27.2543 +});
 27.2544 +
 27.2545 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.2546 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.2547 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.2548 + *
 27.2549 + * Owner: mark@famo.us
 27.2550 + * @license MPL 2.0
 27.2551 + * @copyright Famous Industries, Inc. 2014
 27.2552 + */
 27.2553 +
 27.2554 +define('famous/core/OptionsManager',['require','exports','module','./EventHandler'],function(require, exports, module) {
 27.2555 +    var EventHandler = require('./EventHandler');
 27.2556 +
 27.2557 +    /**
 27.2558 +     *  A collection of methods for setting options which can be extended
 27.2559 +     *  onto other classes.
 27.2560 +     *
 27.2561 +     *
 27.2562 +     *  **** WARNING ****
 27.2563 +     *  You can only pass through objects that will compile into valid JSON.
 27.2564 +     *
 27.2565 +     *  Valid options:
 27.2566 +     *      Strings,
 27.2567 +     *      Arrays,
 27.2568 +     *      Objects,
 27.2569 +     *      Numbers,
 27.2570 +     *      Nested Objects,
 27.2571 +     *      Nested Arrays.
 27.2572 +     *
 27.2573 +     *    This excludes:
 27.2574 +     *        Document Fragments,
 27.2575 +     *        Functions
 27.2576 +     * @class OptionsManager
 27.2577 +     * @constructor
 27.2578 +     * @param {Object} value options dictionary
 27.2579 +     */
 27.2580 +    function OptionsManager(value) {
 27.2581 +        this._value = value;
 27.2582 +        this.eventOutput = null;
 27.2583 +    }
 27.2584 +
 27.2585 +    /**
 27.2586 +     * Create options manager from source dictionary with arguments overriden by patch dictionary.
 27.2587 +     *
 27.2588 +     * @static
 27.2589 +     * @method OptionsManager.patch
 27.2590 +     *
 27.2591 +     * @param {Object} source source arguments
 27.2592 +     * @param {...Object} data argument additions and overwrites
 27.2593 +     * @return {Object} source object
 27.2594 +     */
 27.2595 +    OptionsManager.patch = function patchObject(source, data) {
 27.2596 +        var manager = new OptionsManager(source);
 27.2597 +        for (var i = 1; i < arguments.length; i++) manager.patch(arguments[i]);
 27.2598 +        return source;
 27.2599 +    };
 27.2600 +
 27.2601 +    function _createEventOutput() {
 27.2602 +        this.eventOutput = new EventHandler();
 27.2603 +        this.eventOutput.bindThis(this);
 27.2604 +        EventHandler.setOutputHandler(this, this.eventOutput);
 27.2605 +    }
 27.2606 +
 27.2607 +    /**
 27.2608 +     * Create OptionsManager from source with arguments overriden by patches.
 27.2609 +     *   Triggers 'change' event on this object's event handler if the state of
 27.2610 +     *   the OptionsManager changes as a result.
 27.2611 +     *
 27.2612 +     * @method patch
 27.2613 +     *
 27.2614 +     * @param {...Object} arguments list of patch objects
 27.2615 +     * @return {OptionsManager} this
 27.2616 +     */
 27.2617 +    OptionsManager.prototype.patch = function patch() {
 27.2618 +        var myState = this._value;
 27.2619 +        for (var i = 0; i < arguments.length; i++) {
 27.2620 +            var data = arguments[i];
 27.2621 +            for (var k in data) {
 27.2622 +                if ((k in myState) && (data[k] && data[k].constructor === Object) && (myState[k] && myState[k].constructor === Object)) {
 27.2623 +                    if (!myState.hasOwnProperty(k)) myState[k] = Object.create(myState[k]);
 27.2624 +                    this.key(k).patch(data[k]);
 27.2625 +                    if (this.eventOutput) this.eventOutput.emit('change', {id: k, value: this.key(k).value()});
 27.2626 +                }
 27.2627 +                else this.set(k, data[k]);
 27.2628 +            }
 27.2629 +        }
 27.2630 +        return this;
 27.2631 +    };
 27.2632 +
 27.2633 +    /**
 27.2634 +     * Alias for patch
 27.2635 +     *
 27.2636 +     * @method setOptions
 27.2637 +     *
 27.2638 +     */
 27.2639 +    OptionsManager.prototype.setOptions = OptionsManager.prototype.patch;
 27.2640 +
 27.2641 +    /**
 27.2642 +     * Return OptionsManager based on sub-object retrieved by key
 27.2643 +     *
 27.2644 +     * @method key
 27.2645 +     *
 27.2646 +     * @param {string} identifier key
 27.2647 +     * @return {OptionsManager} new options manager with the value
 27.2648 +     */
 27.2649 +    OptionsManager.prototype.key = function key(identifier) {
 27.2650 +        var result = new OptionsManager(this._value[identifier]);
 27.2651 +        if (!(result._value instanceof Object) || result._value instanceof Array) result._value = {};
 27.2652 +        return result;
 27.2653 +    };
 27.2654 +
 27.2655 +    /**
 27.2656 +     * Look up value by key
 27.2657 +     * @method get
 27.2658 +     *
 27.2659 +     * @param {string} key key
 27.2660 +     * @return {Object} associated object
 27.2661 +     */
 27.2662 +    OptionsManager.prototype.get = function get(key) {
 27.2663 +        return this._value[key];
 27.2664 +    };
 27.2665 +
 27.2666 +    /**
 27.2667 +     * Alias for get
 27.2668 +     * @method getOptions
 27.2669 +     */
 27.2670 +    OptionsManager.prototype.getOptions = OptionsManager.prototype.get;
 27.2671 +
 27.2672 +    /**
 27.2673 +     * Set key to value.  Outputs 'change' event if a value is overwritten.
 27.2674 +     *
 27.2675 +     * @method set
 27.2676 +     *
 27.2677 +     * @param {string} key key string
 27.2678 +     * @param {Object} value value object
 27.2679 +     * @return {OptionsManager} new options manager based on the value object
 27.2680 +     */
 27.2681 +    OptionsManager.prototype.set = function set(key, value) {
 27.2682 +        var originalValue = this.get(key);
 27.2683 +        this._value[key] = value;
 27.2684 +        if (this.eventOutput && value !== originalValue) this.eventOutput.emit('change', {id: key, value: value});
 27.2685 +        return this;
 27.2686 +    };
 27.2687 +
 27.2688 +    /**
 27.2689 +     * Return entire object contents of this OptionsManager.
 27.2690 +     *
 27.2691 +     * @method value
 27.2692 +     *
 27.2693 +     * @return {Object} current state of options
 27.2694 +     */
 27.2695 +    OptionsManager.prototype.value = function value() {
 27.2696 +        return this._value;
 27.2697 +    };
 27.2698 +
 27.2699 +    /**
 27.2700 +     * Bind a callback function to an event type handled by this object.
 27.2701 +     *
 27.2702 +     * @method "on"
 27.2703 +     *
 27.2704 +     * @param {string} type event type key (for example, 'change')
 27.2705 +     * @param {function(string, Object)} handler callback
 27.2706 +     * @return {EventHandler} this
 27.2707 +     */
 27.2708 +    OptionsManager.prototype.on = function on() {
 27.2709 +        _createEventOutput.call(this);
 27.2710 +        return this.on.apply(this, arguments);
 27.2711 +    };
 27.2712 +
 27.2713 +    /**
 27.2714 +     * Unbind an event by type and handler.
 27.2715 +     *   This undoes the work of "on".
 27.2716 +     *
 27.2717 +     * @method removeListener
 27.2718 +     *
 27.2719 +     * @param {string} type event type key (for example, 'change')
 27.2720 +     * @param {function} handler function object to remove
 27.2721 +     * @return {EventHandler} internal event handler object (for chaining)
 27.2722 +     */
 27.2723 +    OptionsManager.prototype.removeListener = function removeListener() {
 27.2724 +        _createEventOutput.call(this);
 27.2725 +        return this.removeListener.apply(this, arguments);
 27.2726 +    };
 27.2727 +
 27.2728 +    /**
 27.2729 +     * Add event handler object to set of downstream handlers.
 27.2730 +     *
 27.2731 +     * @method pipe
 27.2732 +     *
 27.2733 +     * @param {EventHandler} target event handler target object
 27.2734 +     * @return {EventHandler} passed event handler
 27.2735 +     */
 27.2736 +    OptionsManager.prototype.pipe = function pipe() {
 27.2737 +        _createEventOutput.call(this);
 27.2738 +        return this.pipe.apply(this, arguments);
 27.2739 +    };
 27.2740 +
 27.2741 +    /**
 27.2742 +     * Remove handler object from set of downstream handlers.
 27.2743 +     * Undoes work of "pipe"
 27.2744 +     *
 27.2745 +     * @method unpipe
 27.2746 +     *
 27.2747 +     * @param {EventHandler} target target handler object
 27.2748 +     * @return {EventHandler} provided target
 27.2749 +     */
 27.2750 +    OptionsManager.prototype.unpipe = function unpipe() {
 27.2751 +        _createEventOutput.call(this);
 27.2752 +        return this.unpipe.apply(this, arguments);
 27.2753 +    };
 27.2754 +
 27.2755 +    module.exports = OptionsManager;
 27.2756 +});
 27.2757 +
 27.2758 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.2759 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.2760 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.2761 + *
 27.2762 + * Owner: mark@famo.us
 27.2763 + * @license MPL 2.0
 27.2764 + * @copyright Famous Industries, Inc. 2014
 27.2765 + */
 27.2766 +
 27.2767 +define('famous/core/Engine',['require','exports','module','./Context','./EventHandler','./OptionsManager'],function(require, exports, module) {
 27.2768 +
 27.2769 +    /**
 27.2770 +     * The singleton object initiated upon process
 27.2771 +     *   startup which manages all active Context instances, runs
 27.2772 +     *   the render dispatch loop, and acts as a listener and dispatcher
 27.2773 +     *   for events.  All methods are therefore static.
 27.2774 +     *
 27.2775 +     *   On static initialization, window.requestAnimationFrame is called with
 27.2776 +     *     the event loop function.
 27.2777 +     *
 27.2778 +     *   Note: Any window in which Engine runs will prevent default
 27.2779 +     *     scrolling behavior on the 'touchmove' event.
 27.2780 +     *
 27.2781 +     * @static
 27.2782 +     * @class Engine
 27.2783 +     */
 27.2784 +    var Context = require('./Context');
 27.2785 +    var EventHandler = require('./EventHandler');
 27.2786 +    var OptionsManager = require('./OptionsManager');
 27.2787 +
 27.2788 +    var Engine = {};
 27.2789 +
 27.2790 +    var contexts = [];
 27.2791 +    var nextTickQueue = [];
 27.2792 +    var deferQueue = [];
 27.2793 +
 27.2794 +    var lastTime = Date.now();
 27.2795 +    var frameTime;
 27.2796 +    var frameTimeLimit;
 27.2797 +    var loopEnabled = true;
 27.2798 +    var eventForwarders = {};
 27.2799 +    var eventHandler = new EventHandler();
 27.2800 +
 27.2801 +    var options = {
 27.2802 +        containerType: 'div',
 27.2803 +        containerClass: 'famous-container',
 27.2804 +        fpsCap: undefined,
 27.2805 +        runLoop: true
 27.2806 +    };
 27.2807 +    var optionsManager = new OptionsManager(options);
 27.2808 +
 27.2809 +    /** @const */
 27.2810 +    var MAX_DEFER_FRAME_TIME = 10;
 27.2811 +
 27.2812 +    /**
 27.2813 +     * Inside requestAnimationFrame loop, step() is called, which:
 27.2814 +     *   calculates current FPS (throttling loop if it is over limit set in setFPSCap),
 27.2815 +     *   emits dataless 'prerender' event on start of loop,
 27.2816 +     *   calls in order any one-shot functions registered by nextTick on last loop,
 27.2817 +     *   calls Context.update on all Context objects registered,
 27.2818 +     *   and emits dataless 'postrender' event on end of loop.
 27.2819 +     *
 27.2820 +     * @static
 27.2821 +     * @private
 27.2822 +     * @method step
 27.2823 +     */
 27.2824 +    Engine.step = function step() {
 27.2825 +        var currentTime = Date.now();
 27.2826 +
 27.2827 +        // skip frame if we're over our framerate cap
 27.2828 +        if (frameTimeLimit && currentTime - lastTime < frameTimeLimit) return;
 27.2829 +
 27.2830 +        var i = 0;
 27.2831 +
 27.2832 +        frameTime = currentTime - lastTime;
 27.2833 +        lastTime = currentTime;
 27.2834 +
 27.2835 +        eventHandler.emit('prerender');
 27.2836 +
 27.2837 +        // empty the queue
 27.2838 +        for (i = 0; i < nextTickQueue.length; i++) nextTickQueue[i].call(this);
 27.2839 +        nextTickQueue.splice(0);
 27.2840 +
 27.2841 +        // limit total execution time for deferrable functions
 27.2842 +        while (deferQueue.length && (Date.now() - currentTime) < MAX_DEFER_FRAME_TIME) {
 27.2843 +            deferQueue.shift().call(this);
 27.2844 +        }
 27.2845 +
 27.2846 +        for (i = 0; i < contexts.length; i++) contexts[i].update();
 27.2847 +
 27.2848 +        eventHandler.emit('postrender');
 27.2849 +    };
 27.2850 +
 27.2851 +    // engage requestAnimationFrame
 27.2852 +    function loop() {
 27.2853 +        if (options.runLoop) {
 27.2854 +            Engine.step();
 27.2855 +            requestAnimationFrame(loop);
 27.2856 +        }
 27.2857 +        else loopEnabled = false;
 27.2858 +    }
 27.2859 +    requestAnimationFrame(loop);
 27.2860 +
 27.2861 +    //
 27.2862 +    // Upon main document window resize (unless on an "input" HTML element):
 27.2863 +    //   scroll to the top left corner of the window,
 27.2864 +    //   and for each managed Context: emit the 'resize' event and update its size.
 27.2865 +    // @param {Object=} event document event
 27.2866 +    //
 27.2867 +    function handleResize(event) {
 27.2868 +        for (var i = 0; i < contexts.length; i++) {
 27.2869 +            contexts[i].emit('resize');
 27.2870 +        }
 27.2871 +        eventHandler.emit('resize');
 27.2872 +    }
 27.2873 +    window.addEventListener('resize', handleResize, false);
 27.2874 +    handleResize();
 27.2875 +
 27.2876 +    // prevent scrolling via browser
 27.2877 +    window.addEventListener('touchmove', function(event) {
 27.2878 +        event.preventDefault();
 27.2879 +    }, true);
 27.2880 +
 27.2881 +    /**
 27.2882 +     * Add event handler object to set of downstream handlers.
 27.2883 +     *
 27.2884 +     * @method pipe
 27.2885 +     *
 27.2886 +     * @param {EventHandler} target event handler target object
 27.2887 +     * @return {EventHandler} passed event handler
 27.2888 +     */
 27.2889 +    Engine.pipe = function pipe(target) {
 27.2890 +        if (target.subscribe instanceof Function) return target.subscribe(Engine);
 27.2891 +        else return eventHandler.pipe(target);
 27.2892 +    };
 27.2893 +
 27.2894 +    /**
 27.2895 +     * Remove handler object from set of downstream handlers.
 27.2896 +     *   Undoes work of "pipe".
 27.2897 +     *
 27.2898 +     * @method unpipe
 27.2899 +     *
 27.2900 +     * @param {EventHandler} target target handler object
 27.2901 +     * @return {EventHandler} provided target
 27.2902 +     */
 27.2903 +    Engine.unpipe = function unpipe(target) {
 27.2904 +        if (target.unsubscribe instanceof Function) return target.unsubscribe(Engine);
 27.2905 +        else return eventHandler.unpipe(target);
 27.2906 +    };
 27.2907 +
 27.2908 +    /**
 27.2909 +     * Bind a callback function to an event type handled by this object.
 27.2910 +     *
 27.2911 +     * @static
 27.2912 +     * @method "on"
 27.2913 +     *
 27.2914 +     * @param {string} type event type key (for example, 'click')
 27.2915 +     * @param {function(string, Object)} handler callback
 27.2916 +     * @return {EventHandler} this
 27.2917 +     */
 27.2918 +    Engine.on = function on(type, handler) {
 27.2919 +        if (!(type in eventForwarders)) {
 27.2920 +            eventForwarders[type] = eventHandler.emit.bind(eventHandler, type);
 27.2921 +            if (document.body) {
 27.2922 +                document.body.addEventListener(type, eventForwarders[type]);
 27.2923 +            }
 27.2924 +            else {
 27.2925 +                Engine.nextTick(function(type, forwarder) {
 27.2926 +                    document.body.addEventListener(type, forwarder);
 27.2927 +                }.bind(this, type, eventForwarders[type]));
 27.2928 +            }
 27.2929 +        }
 27.2930 +        return eventHandler.on(type, handler);
 27.2931 +    };
 27.2932 +
 27.2933 +    /**
 27.2934 +     * Trigger an event, sending to all downstream handlers
 27.2935 +     *   listening for provided 'type' key.
 27.2936 +     *
 27.2937 +     * @method emit
 27.2938 +     *
 27.2939 +     * @param {string} type event type key (for example, 'click')
 27.2940 +     * @param {Object} event event data
 27.2941 +     * @return {EventHandler} this
 27.2942 +     */
 27.2943 +    Engine.emit = function emit(type, event) {
 27.2944 +        return eventHandler.emit(type, event);
 27.2945 +    };
 27.2946 +
 27.2947 +    /**
 27.2948 +     * Unbind an event by type and handler.
 27.2949 +     *   This undoes the work of "on".
 27.2950 +     *
 27.2951 +     * @static
 27.2952 +     * @method removeListener
 27.2953 +     *
 27.2954 +     * @param {string} type event type key (for example, 'click')
 27.2955 +     * @param {function} handler function object to remove
 27.2956 +     * @return {EventHandler} internal event handler object (for chaining)
 27.2957 +     */
 27.2958 +    Engine.removeListener = function removeListener(type, handler) {
 27.2959 +        return eventHandler.removeListener(type, handler);
 27.2960 +    };
 27.2961 +
 27.2962 +    /**
 27.2963 +     * Return the current calculated frames per second of the Engine.
 27.2964 +     *
 27.2965 +     * @static
 27.2966 +     * @method getFPS
 27.2967 +     *
 27.2968 +     * @return {Number} calculated fps
 27.2969 +     */
 27.2970 +    Engine.getFPS = function getFPS() {
 27.2971 +        return 1000 / frameTime;
 27.2972 +    };
 27.2973 +
 27.2974 +    /**
 27.2975 +     * Set the maximum fps at which the system should run. If internal render
 27.2976 +     *    loop is called at a greater frequency than this FPSCap, Engine will
 27.2977 +     *    throttle render and update until this rate is achieved.
 27.2978 +     *
 27.2979 +     * @static
 27.2980 +     * @method setFPSCap
 27.2981 +     *
 27.2982 +     * @param {Number} fps maximum frames per second
 27.2983 +     */
 27.2984 +    Engine.setFPSCap = function setFPSCap(fps) {
 27.2985 +        frameTimeLimit = Math.floor(1000 / fps);
 27.2986 +    };
 27.2987 +
 27.2988 +    /**
 27.2989 +     * Return engine options.
 27.2990 +     *
 27.2991 +     * @static
 27.2992 +     * @method getOptions
 27.2993 +     * @param {string} key
 27.2994 +     * @return {Object} engine options
 27.2995 +     */
 27.2996 +    Engine.getOptions = function getOptions() {
 27.2997 +        return optionsManager.getOptions.apply(optionsManager, arguments);
 27.2998 +    };
 27.2999 +
 27.3000 +    /**
 27.3001 +     * Set engine options
 27.3002 +     *
 27.3003 +     * @static
 27.3004 +     * @method setOptions
 27.3005 +     *
 27.3006 +     * @param {Object} [options] overrides of default options
 27.3007 +     * @param {Number} [options.fpsCap]  maximum fps at which the system should run
 27.3008 +     * @param {boolean} [options.runLoop=true] whether the run loop should continue
 27.3009 +     * @param {string} [options.containerType="div"] type of container element.  Defaults to 'div'.
 27.3010 +     * @param {string} [options.containerClass="famous-container"] type of container element.  Defaults to 'famous-container'.
 27.3011 +     */
 27.3012 +    Engine.setOptions = function setOptions(options) {
 27.3013 +        return optionsManager.setOptions.apply(optionsManager, arguments);
 27.3014 +    };
 27.3015 +
 27.3016 +    /**
 27.3017 +     * Creates a new Context for rendering and event handling with
 27.3018 +     *    provided document element as top of each tree. This will be tracked by the
 27.3019 +     *    process-wide Engine.
 27.3020 +     *
 27.3021 +     * @static
 27.3022 +     * @method createContext
 27.3023 +     *
 27.3024 +     * @param {Node} el will be top of Famo.us document element tree
 27.3025 +     * @return {Context} new Context within el
 27.3026 +     */
 27.3027 +    Engine.createContext = function createContext(el) {
 27.3028 +        var needMountContainer = false;
 27.3029 +        if (!el) {
 27.3030 +            el = document.createElement(options.containerType);
 27.3031 +            el.classList.add(options.containerClass);
 27.3032 +            needMountContainer = true;
 27.3033 +        }
 27.3034 +        var context = new Context(el);
 27.3035 +        Engine.registerContext(context);
 27.3036 +        if (needMountContainer) {
 27.3037 +            Engine.nextTick(function(context, el) {
 27.3038 +                document.body.appendChild(el);
 27.3039 +                context.emit('resize');
 27.3040 +            }.bind(this, context, el));
 27.3041 +        }
 27.3042 +        return context;
 27.3043 +    };
 27.3044 +
 27.3045 +    /**
 27.3046 +     * Registers an existing context to be updated within the run loop.
 27.3047 +     *
 27.3048 +     * @static
 27.3049 +     * @method registerContext
 27.3050 +     *
 27.3051 +     * @param {Context} context Context to register
 27.3052 +     * @return {FamousContext} provided context
 27.3053 +     */
 27.3054 +    Engine.registerContext = function registerContext(context) {
 27.3055 +        contexts.push(context);
 27.3056 +        return context;
 27.3057 +    };
 27.3058 +
 27.3059 +    /**
 27.3060 +     * Queue a function to be executed on the next tick of the
 27.3061 +     *    Engine.
 27.3062 +     *
 27.3063 +     * @static
 27.3064 +     * @method nextTick
 27.3065 +     *
 27.3066 +     * @param {function(Object)} fn function accepting window object
 27.3067 +     */
 27.3068 +    Engine.nextTick = function nextTick(fn) {
 27.3069 +        nextTickQueue.push(fn);
 27.3070 +    };
 27.3071 +
 27.3072 +    /**
 27.3073 +     * Queue a function to be executed sometime soon, at a time that is
 27.3074 +     *    unlikely to affect frame rate.
 27.3075 +     *
 27.3076 +     * @static
 27.3077 +     * @method defer
 27.3078 +     *
 27.3079 +     * @param {Function} fn
 27.3080 +     */
 27.3081 +    Engine.defer = function defer(fn) {
 27.3082 +        deferQueue.push(fn);
 27.3083 +    };
 27.3084 +
 27.3085 +    optionsManager.on('change', function(data) {
 27.3086 +        if (data.id === 'fpsCap') Engine.setFPSCap(data.value);
 27.3087 +        else if (data.id === 'runLoop') {
 27.3088 +            // kick off the loop only if it was stopped
 27.3089 +            if (!loopEnabled && data.value) {
 27.3090 +                loopEnabled = true;
 27.3091 +                requestAnimationFrame(loop);
 27.3092 +            }
 27.3093 +        }
 27.3094 +    });
 27.3095 +
 27.3096 +    module.exports = Engine;
 27.3097 +});
 27.3098 +
 27.3099 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.3100 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.3101 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.3102 + *
 27.3103 + * Owner: mark@famo.us
 27.3104 + * @license MPL 2.0
 27.3105 + * @copyright Famous Industries, Inc. 2014
 27.3106 + */
 27.3107 +
 27.3108 +define('famous/core/Surface',['require','exports','module','./Entity','./EventHandler','./Transform'],function(require, exports, module) {
 27.3109 +    var Entity = require('./Entity');
 27.3110 +    var EventHandler = require('./EventHandler');
 27.3111 +    var Transform = require('./Transform');
 27.3112 +
 27.3113 +    var devicePixelRatio = window.devicePixelRatio || 1;
 27.3114 +    var usePrefix = document.createElement('div').style.webkitTransform !== undefined;
 27.3115 +
 27.3116 +    /**
 27.3117 +     * A base class for viewable content and event
 27.3118 +     *   targets inside a Famo.us application, containing a renderable document
 27.3119 +     *   fragment. Like an HTML div, it can accept internal markup,
 27.3120 +     *   properties, classes, and handle events.
 27.3121 +     *
 27.3122 +     * @class Surface
 27.3123 +     * @constructor
 27.3124 +     *
 27.3125 +     * @param {Object} [options] default option overrides
 27.3126 +     * @param {Array.Number} [options.size] [width, height] in pixels
 27.3127 +     * @param {Array.string} [options.classes] CSS classes to set on inner content
 27.3128 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
 27.3129 +     * @param {string} [options.content] inner (HTML) content of surface
 27.3130 +     */
 27.3131 +    function Surface(options) {
 27.3132 +        this.options = {};
 27.3133 +
 27.3134 +        this.properties = {};
 27.3135 +        this.content = '';
 27.3136 +        this.classList = [];
 27.3137 +        this.size = null;
 27.3138 +
 27.3139 +        this._classesDirty = true;
 27.3140 +        this._stylesDirty = true;
 27.3141 +        this._sizeDirty = true;
 27.3142 +        this._contentDirty = true;
 27.3143 +
 27.3144 +        this._dirtyClasses = [];
 27.3145 +
 27.3146 +        this._matrix = null;
 27.3147 +        this._opacity = 1;
 27.3148 +        this._origin = null;
 27.3149 +        this._size = null;
 27.3150 +
 27.3151 +        /** @ignore */
 27.3152 +        this.eventForwarder = function eventForwarder(event) {
 27.3153 +            this.emit(event.type, event);
 27.3154 +        }.bind(this);
 27.3155 +        this.eventHandler = new EventHandler();
 27.3156 +        this.eventHandler.bindThis(this);
 27.3157 +
 27.3158 +        this.id = Entity.register(this);
 27.3159 +
 27.3160 +        if (options) this.setOptions(options);
 27.3161 +
 27.3162 +        this._currTarget = null;
 27.3163 +    }
 27.3164 +    Surface.prototype.elementType = 'div';
 27.3165 +    Surface.prototype.elementClass = 'famous-surface';
 27.3166 +
 27.3167 +    /**
 27.3168 +     * Bind a callback function to an event type handled by this object.
 27.3169 +     *
 27.3170 +     * @method "on"
 27.3171 +     *
 27.3172 +     * @param {string} type event type key (for example, 'click')
 27.3173 +     * @param {function(string, Object)} fn handler callback
 27.3174 +     * @return {EventHandler} this
 27.3175 +     */
 27.3176 +    Surface.prototype.on = function on(type, fn) {
 27.3177 +        if (this._currTarget) this._currTarget.addEventListener(type, this.eventForwarder);
 27.3178 +        this.eventHandler.on(type, fn);
 27.3179 +    };
 27.3180 +
 27.3181 +    /**
 27.3182 +     * Unbind an event by type and handler.
 27.3183 +     *   This undoes the work of "on"
 27.3184 +     *
 27.3185 +     * @method removeListener
 27.3186 +     * @param {string} type event type key (for example, 'click')
 27.3187 +     * @param {function(string, Object)} fn handler
 27.3188 +     */
 27.3189 +    Surface.prototype.removeListener = function removeListener(type, fn) {
 27.3190 +        this.eventHandler.removeListener(type, fn);
 27.3191 +    };
 27.3192 +
 27.3193 +    /**
 27.3194 +     * Trigger an event, sending to all downstream handlers
 27.3195 +     *   listening for provided 'type' key.
 27.3196 +     *
 27.3197 +     * @method emit
 27.3198 +     *
 27.3199 +     * @param {string} type event type key (for example, 'click')
 27.3200 +     * @param {Object} [event] event data
 27.3201 +     * @return {EventHandler} this
 27.3202 +     */
 27.3203 +    Surface.prototype.emit = function emit(type, event) {
 27.3204 +        if (event && !event.origin) event.origin = this;
 27.3205 +        var handled = this.eventHandler.emit(type, event);
 27.3206 +        if (handled && event && event.stopPropagation) event.stopPropagation();
 27.3207 +        return handled;
 27.3208 +    };
 27.3209 +
 27.3210 +    /**
 27.3211 +     * Add event handler object to set of downstream handlers.
 27.3212 +     *
 27.3213 +     * @method pipe
 27.3214 +     *
 27.3215 +     * @param {EventHandler} target event handler target object
 27.3216 +     * @return {EventHandler} passed event handler
 27.3217 +     */
 27.3218 +    Surface.prototype.pipe = function pipe(target) {
 27.3219 +        return this.eventHandler.pipe(target);
 27.3220 +    };
 27.3221 +
 27.3222 +    /**
 27.3223 +     * Remove handler object from set of downstream handlers.
 27.3224 +     *   Undoes work of "pipe"
 27.3225 +     *
 27.3226 +     * @method unpipe
 27.3227 +     *
 27.3228 +     * @param {EventHandler} target target handler object
 27.3229 +     * @return {EventHandler} provided target
 27.3230 +     */
 27.3231 +    Surface.prototype.unpipe = function unpipe(target) {
 27.3232 +        return this.eventHandler.unpipe(target);
 27.3233 +    };
 27.3234 +
 27.3235 +    /**
 27.3236 +     * Return spec for this surface. Note that for a base surface, this is
 27.3237 +     *    simply an id.
 27.3238 +     *
 27.3239 +     * @method render
 27.3240 +     * @private
 27.3241 +     * @return {Object} render spec for this surface (spec id)
 27.3242 +     */
 27.3243 +    Surface.prototype.render = function render() {
 27.3244 +        return this.id;
 27.3245 +    };
 27.3246 +
 27.3247 +    /**
 27.3248 +     * Set CSS-style properties on this Surface. Note that this will cause
 27.3249 +     *    dirtying and thus re-rendering, even if values do not change.
 27.3250 +     *
 27.3251 +     * @method setProperties
 27.3252 +     * @param {Object} properties property dictionary of "key" => "value"
 27.3253 +     */
 27.3254 +    Surface.prototype.setProperties = function setProperties(properties) {
 27.3255 +        for (var n in properties) {
 27.3256 +            this.properties[n] = properties[n];
 27.3257 +        }
 27.3258 +        this._stylesDirty = true;
 27.3259 +    };
 27.3260 +
 27.3261 +    /**
 27.3262 +     * Get CSS-style properties on this Surface.
 27.3263 +     *
 27.3264 +     * @method getProperties
 27.3265 +     *
 27.3266 +     * @return {Object} Dictionary of this Surface's properties.
 27.3267 +     */
 27.3268 +    Surface.prototype.getProperties = function getProperties() {
 27.3269 +        return this.properties;
 27.3270 +    };
 27.3271 +
 27.3272 +    /**
 27.3273 +     * Add CSS-style class to the list of classes on this Surface. Note
 27.3274 +     *   this will map directly to the HTML property of the actual
 27.3275 +     *   corresponding rendered <div>.
 27.3276 +     *
 27.3277 +     * @method addClass
 27.3278 +     * @param {string} className name of class to add
 27.3279 +     */
 27.3280 +    Surface.prototype.addClass = function addClass(className) {
 27.3281 +        if (this.classList.indexOf(className) < 0) {
 27.3282 +            this.classList.push(className);
 27.3283 +            this._classesDirty = true;
 27.3284 +        }
 27.3285 +    };
 27.3286 +
 27.3287 +    /**
 27.3288 +     * Remove CSS-style class from the list of classes on this Surface.
 27.3289 +     *   Note this will map directly to the HTML property of the actual
 27.3290 +     *   corresponding rendered <div>.
 27.3291 +     *
 27.3292 +     * @method removeClass
 27.3293 +     * @param {string} className name of class to remove
 27.3294 +     */
 27.3295 +    Surface.prototype.removeClass = function removeClass(className) {
 27.3296 +        var i = this.classList.indexOf(className);
 27.3297 +        if (i >= 0) {
 27.3298 +            this._dirtyClasses.push(this.classList.splice(i, 1)[0]);
 27.3299 +            this._classesDirty = true;
 27.3300 +        }
 27.3301 +    };
 27.3302 +
 27.3303 +    /**
 27.3304 +     * Reset class list to provided dictionary.
 27.3305 +     * @method setClasses
 27.3306 +     * @param {Array.string} classList
 27.3307 +     */
 27.3308 +    Surface.prototype.setClasses = function setClasses(classList) {
 27.3309 +        var i = 0;
 27.3310 +        var removal = [];
 27.3311 +        for (i = 0; i < this.classList.length; i++) {
 27.3312 +            if (classList.indexOf(this.classList[i]) < 0) removal.push(this.classList[i]);
 27.3313 +        }
 27.3314 +        for (i = 0; i < removal.length; i++) this.removeClass(removal[i]);
 27.3315 +        // duplicates are already checked by addClass()
 27.3316 +        for (i = 0; i < classList.length; i++) this.addClass(classList[i]);
 27.3317 +    };
 27.3318 +
 27.3319 +    /**
 27.3320 +     * Get array of CSS-style classes attached to this div.
 27.3321 +     *
 27.3322 +     * @method getClasslist
 27.3323 +     * @return {Array.string} array of class names
 27.3324 +     */
 27.3325 +    Surface.prototype.getClassList = function getClassList() {
 27.3326 +        return this.classList;
 27.3327 +    };
 27.3328 +
 27.3329 +    /**
 27.3330 +     * Set or overwrite inner (HTML) content of this surface. Note that this
 27.3331 +     *    causes a re-rendering if the content has changed.
 27.3332 +     *
 27.3333 +     * @method setContent
 27.3334 +     * @param {string|Document Fragment} content HTML content
 27.3335 +     */
 27.3336 +    Surface.prototype.setContent = function setContent(content) {
 27.3337 +        if (this.content !== content) {
 27.3338 +            this.content = content;
 27.3339 +            this._contentDirty = true;
 27.3340 +        }
 27.3341 +    };
 27.3342 +
 27.3343 +    /**
 27.3344 +     * Return inner (HTML) content of this surface.
 27.3345 +     *
 27.3346 +     * @method getContent
 27.3347 +     *
 27.3348 +     * @return {string} inner (HTML) content
 27.3349 +     */
 27.3350 +    Surface.prototype.getContent = function getContent() {
 27.3351 +        return this.content;
 27.3352 +    };
 27.3353 +
 27.3354 +    /**
 27.3355 +     * Set options for this surface
 27.3356 +     *
 27.3357 +     * @method setOptions
 27.3358 +     * @param {Object} [options] overrides for default options.  See constructor.
 27.3359 +     */
 27.3360 +    Surface.prototype.setOptions = function setOptions(options) {
 27.3361 +        if (options.size) this.setSize(options.size);
 27.3362 +        if (options.classes) this.setClasses(options.classes);
 27.3363 +        if (options.properties) this.setProperties(options.properties);
 27.3364 +        if (options.content) this.setContent(options.content);
 27.3365 +    };
 27.3366 +
 27.3367 +    //  Attach Famous event handling to document events emanating from target
 27.3368 +    //    document element.  This occurs just after deployment to the document.
 27.3369 +    //    Calling this enables methods like #on and #pipe.
 27.3370 +    function _addEventListeners(target) {
 27.3371 +        for (var i in this.eventHandler.listeners) {
 27.3372 +            target.addEventListener(i, this.eventForwarder);
 27.3373 +        }
 27.3374 +    }
 27.3375 +
 27.3376 +    //  Detach Famous event handling from document events emanating from target
 27.3377 +    //  document element.  This occurs just before recall from the document.
 27.3378 +    function _removeEventListeners(target) {
 27.3379 +        for (var i in this.eventHandler.listeners) {
 27.3380 +            target.removeEventListener(i, this.eventForwarder);
 27.3381 +        }
 27.3382 +    }
 27.3383 +
 27.3384 +     //  Apply to document all changes from removeClass() since last setup().
 27.3385 +    function _cleanupClasses(target) {
 27.3386 +        for (var i = 0; i < this._dirtyClasses.length; i++) target.classList.remove(this._dirtyClasses[i]);
 27.3387 +        this._dirtyClasses = [];
 27.3388 +    }
 27.3389 +
 27.3390 +    // Apply values of all Famous-managed styles to the document element.
 27.3391 +    //  These will be deployed to the document on call to #setup().
 27.3392 +    function _applyStyles(target) {
 27.3393 +        for (var n in this.properties) {
 27.3394 +            target.style[n] = this.properties[n];
 27.3395 +        }
 27.3396 +    }
 27.3397 +
 27.3398 +    // Clear all Famous-managed styles from the document element.
 27.3399 +    // These will be deployed to the document on call to #setup().
 27.3400 +    function _cleanupStyles(target) {
 27.3401 +        for (var n in this.properties) {
 27.3402 +            target.style[n] = '';
 27.3403 +        }
 27.3404 +    }
 27.3405 +
 27.3406 +    /**
 27.3407 +     * Return a Matrix's webkit css representation to be used with the
 27.3408 +     *    CSS3 -webkit-transform style.
 27.3409 +     *    Example: -webkit-transform: matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,716,243,0,1)
 27.3410 +     *
 27.3411 +     * @method _formatCSSTransform
 27.3412 +     * @private
 27.3413 +     * @param {FamousMatrix} m matrix
 27.3414 +     * @return {string} matrix3d CSS style representation of the transform
 27.3415 +     */
 27.3416 +    function _formatCSSTransform(m) {
 27.3417 +        m[12] = Math.round(m[12] * devicePixelRatio) / devicePixelRatio;
 27.3418 +        m[13] = Math.round(m[13] * devicePixelRatio) / devicePixelRatio;
 27.3419 +
 27.3420 +        var result = 'matrix3d(';
 27.3421 +        for (var i = 0; i < 15; i++) {
 27.3422 +            result += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ',';
 27.3423 +        }
 27.3424 +        result += m[15] + ')';
 27.3425 +        return result;
 27.3426 +    }
 27.3427 +
 27.3428 +    /**
 27.3429 +     * Directly apply given FamousMatrix to the document element as the
 27.3430 +     *   appropriate webkit CSS style.
 27.3431 +     *
 27.3432 +     * @method setMatrix
 27.3433 +     *
 27.3434 +     * @static
 27.3435 +     * @private
 27.3436 +     * @param {Element} element document element
 27.3437 +     * @param {FamousMatrix} matrix
 27.3438 +     */
 27.3439 +
 27.3440 +    var _setMatrix;
 27.3441 +    if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
 27.3442 +        _setMatrix = function(element, matrix) {
 27.3443 +            element.style.zIndex = (matrix[14] * 1000000) | 0;    // fix for Firefox z-buffer issues
 27.3444 +            element.style.transform = _formatCSSTransform(matrix);
 27.3445 +        };
 27.3446 +    }
 27.3447 +    else if (usePrefix) {
 27.3448 +        _setMatrix = function(element, matrix) {
 27.3449 +            element.style.webkitTransform = _formatCSSTransform(matrix);
 27.3450 +        };
 27.3451 +    }
 27.3452 +    else {
 27.3453 +        _setMatrix = function(element, matrix) {
 27.3454 +            element.style.transform = _formatCSSTransform(matrix);
 27.3455 +        };
 27.3456 +    }
 27.3457 +
 27.3458 +    // format origin as CSS percentage string
 27.3459 +    function _formatCSSOrigin(origin) {
 27.3460 +        return (100 * origin[0]) + '% ' + (100 * origin[1]) + '%';
 27.3461 +    }
 27.3462 +
 27.3463 +     // Directly apply given origin coordinates to the document element as the
 27.3464 +     // appropriate webkit CSS style.
 27.3465 +    var _setOrigin = usePrefix ? function(element, origin) {
 27.3466 +        element.style.webkitTransformOrigin = _formatCSSOrigin(origin);
 27.3467 +    } : function(element, origin) {
 27.3468 +        element.style.transformOrigin = _formatCSSOrigin(origin);
 27.3469 +    };
 27.3470 +
 27.3471 +     // Shrink given document element until it is effectively invisible.
 27.3472 +    var _setInvisible = usePrefix ? function(element) {
 27.3473 +        element.style.webkitTransform = 'scale3d(0.0001,0.0001,1)';
 27.3474 +        element.style.opacity = 0;
 27.3475 +    } : function(element) {
 27.3476 +        element.style.transform = 'scale3d(0.0001,0.0001,1)';
 27.3477 +        element.style.opacity = 0;
 27.3478 +    };
 27.3479 +
 27.3480 +    function _xyNotEquals(a, b) {
 27.3481 +        return (a && b) ? (a[0] !== b[0] || a[1] !== b[1]) : a !== b;
 27.3482 +    }
 27.3483 +
 27.3484 +    /**
 27.3485 +     * One-time setup for an element to be ready for commits to document.
 27.3486 +     *
 27.3487 +     * @private
 27.3488 +     * @method setup
 27.3489 +     *
 27.3490 +     * @param {ElementAllocator} allocator document element pool for this context
 27.3491 +     */
 27.3492 +    Surface.prototype.setup = function setup(allocator) {
 27.3493 +        var target = allocator.allocate(this.elementType);
 27.3494 +        if (this.elementClass) {
 27.3495 +            if (this.elementClass instanceof Array) {
 27.3496 +                for (var i = 0; i < this.elementClass.length; i++) {
 27.3497 +                    target.classList.add(this.elementClass[i]);
 27.3498 +                }
 27.3499 +            }
 27.3500 +            else {
 27.3501 +                target.classList.add(this.elementClass);
 27.3502 +            }
 27.3503 +        }
 27.3504 +        target.style.display = '';
 27.3505 +        _addEventListeners.call(this, target);
 27.3506 +        this._currTarget = target;
 27.3507 +        this._stylesDirty = true;
 27.3508 +        this._classesDirty = true;
 27.3509 +        this._sizeDirty = true;
 27.3510 +        this._contentDirty = true;
 27.3511 +        this._matrix = null;
 27.3512 +        this._opacity = undefined;
 27.3513 +        this._origin = null;
 27.3514 +        this._size = null;
 27.3515 +    };
 27.3516 +
 27.3517 +    /**
 27.3518 +     * Apply changes from this component to the corresponding document element.
 27.3519 +     * This includes changes to classes, styles, size, content, opacity, origin,
 27.3520 +     * and matrix transforms.
 27.3521 +     *
 27.3522 +     * @private
 27.3523 +     * @method commit
 27.3524 +     * @param {Context} context commit context
 27.3525 +     */
 27.3526 +    Surface.prototype.commit = function commit(context) {
 27.3527 +        if (!this._currTarget) this.setup(context.allocator);
 27.3528 +        var target = this._currTarget;
 27.3529 +
 27.3530 +        var matrix = context.transform;
 27.3531 +        var opacity = context.opacity;
 27.3532 +        var origin = context.origin;
 27.3533 +        var size = context.size;
 27.3534 +
 27.3535 +        if (this._classesDirty) {
 27.3536 +            _cleanupClasses.call(this, target);
 27.3537 +            var classList = this.getClassList();
 27.3538 +            for (var i = 0; i < classList.length; i++) target.classList.add(classList[i]);
 27.3539 +            this._classesDirty = false;
 27.3540 +        }
 27.3541 +
 27.3542 +        if (this._stylesDirty) {
 27.3543 +            _applyStyles.call(this, target);
 27.3544 +            this._stylesDirty = false;
 27.3545 +        }
 27.3546 +
 27.3547 +        if (this._contentDirty) {
 27.3548 +            this.deploy(target);
 27.3549 +            this.eventHandler.emit('deploy');
 27.3550 +            this._contentDirty = false;
 27.3551 +        }
 27.3552 +
 27.3553 +        if (this.size) {
 27.3554 +            var origSize = size;
 27.3555 +            size = [this.size[0], this.size[1]];
 27.3556 +            if (size[0] === undefined && origSize[0]) size[0] = origSize[0];
 27.3557 +            if (size[1] === undefined && origSize[1]) size[1] = origSize[1];
 27.3558 +        }
 27.3559 +
 27.3560 +        if (size[0] === true) size[0] = target.clientWidth;
 27.3561 +        if (size[1] === true) size[1] = target.clientHeight;
 27.3562 +
 27.3563 +        if (_xyNotEquals(this._size, size)) {
 27.3564 +            if (!this._size) this._size = [0, 0];
 27.3565 +            this._size[0] = size[0];
 27.3566 +            this._size[1] = size[1];
 27.3567 +            this._sizeDirty = true;
 27.3568 +        }
 27.3569 +
 27.3570 +        if (!matrix && this._matrix) {
 27.3571 +            this._matrix = null;
 27.3572 +            this._opacity = 0;
 27.3573 +            _setInvisible(target);
 27.3574 +            return;
 27.3575 +        }
 27.3576 +
 27.3577 +        if (this._opacity !== opacity) {
 27.3578 +            this._opacity = opacity;
 27.3579 +            target.style.opacity = (opacity >= 1) ? '0.999999' : opacity;
 27.3580 +        }
 27.3581 +
 27.3582 +        if (_xyNotEquals(this._origin, origin) || Transform.notEquals(this._matrix, matrix) || this._sizeDirty) {
 27.3583 +            if (!matrix) matrix = Transform.identity;
 27.3584 +            this._matrix = matrix;
 27.3585 +            var aaMatrix = matrix;
 27.3586 +            if (origin) {
 27.3587 +                if (!this._origin) this._origin = [0, 0];
 27.3588 +                this._origin[0] = origin[0];
 27.3589 +                this._origin[1] = origin[1];
 27.3590 +                aaMatrix = Transform.thenMove(matrix, [-this._size[0] * origin[0], -this._size[1] * origin[1], 0]);
 27.3591 +                _setOrigin(target, origin);
 27.3592 +            }
 27.3593 +            _setMatrix(target, aaMatrix);
 27.3594 +        }
 27.3595 +
 27.3596 +        if (this._sizeDirty) {
 27.3597 +            if (this._size) {
 27.3598 +                target.style.width = (this.size && this.size[0] === true) ? '' : this._size[0] + 'px';
 27.3599 +                target.style.height = (this.size && this.size[1] === true) ?  '' : this._size[1] + 'px';
 27.3600 +            }
 27.3601 +            this._sizeDirty = false;
 27.3602 +        }
 27.3603 +    };
 27.3604 +
 27.3605 +    /**
 27.3606 +     *  Remove all Famous-relevant attributes from a document element.
 27.3607 +     *    This is called by SurfaceManager's detach().
 27.3608 +     *    This is in some sense the reverse of .deploy().
 27.3609 +     *
 27.3610 +     * @private
 27.3611 +     * @method cleanup
 27.3612 +     * @param {ElementAllocator} allocator
 27.3613 +     */
 27.3614 +    Surface.prototype.cleanup = function cleanup(allocator) {
 27.3615 +        var i = 0;
 27.3616 +        var target = this._currTarget;
 27.3617 +        this.eventHandler.emit('recall');
 27.3618 +        this.recall(target);
 27.3619 +        target.style.display = 'none';
 27.3620 +        target.style.width = '';
 27.3621 +        target.style.height = '';
 27.3622 +        this._size = null;
 27.3623 +        _cleanupStyles.call(this, target);
 27.3624 +        var classList = this.getClassList();
 27.3625 +        _cleanupClasses.call(this, target);
 27.3626 +        for (i = 0; i < classList.length; i++) target.classList.remove(classList[i]);
 27.3627 +        if (this.elementClass) {
 27.3628 +            if (this.elementClass instanceof Array) {
 27.3629 +                for (i = 0; i < this.elementClass.length; i++) {
 27.3630 +                    target.classList.remove(this.elementClass[i]);
 27.3631 +                }
 27.3632 +            }
 27.3633 +            else {
 27.3634 +                target.classList.remove(this.elementClass);
 27.3635 +            }
 27.3636 +        }
 27.3637 +        _removeEventListeners.call(this, target);
 27.3638 +        this._currTarget = null;
 27.3639 +        allocator.deallocate(target);
 27.3640 +        _setInvisible(target);
 27.3641 +    };
 27.3642 +
 27.3643 +    /**
 27.3644 +     * Place the document element that this component manages into the document.
 27.3645 +     *
 27.3646 +     * @private
 27.3647 +     * @method deploy
 27.3648 +     * @param {Node} target document parent of this container
 27.3649 +     */
 27.3650 +    Surface.prototype.deploy = function deploy(target) {
 27.3651 +        var content = this.getContent();
 27.3652 +        if (content instanceof Node) {
 27.3653 +            while (target.hasChildNodes()) target.removeChild(target.firstChild);
 27.3654 +            target.appendChild(content);
 27.3655 +        }
 27.3656 +        else target.innerHTML = content;
 27.3657 +    };
 27.3658 +
 27.3659 +    /**
 27.3660 +     * Remove any contained document content associated with this surface
 27.3661 +     *   from the actual document.
 27.3662 +     *
 27.3663 +     * @private
 27.3664 +     * @method recall
 27.3665 +     */
 27.3666 +    Surface.prototype.recall = function recall(target) {
 27.3667 +        var df = document.createDocumentFragment();
 27.3668 +        while (target.hasChildNodes()) df.appendChild(target.firstChild);
 27.3669 +        this.setContent(df);
 27.3670 +    };
 27.3671 +
 27.3672 +    /**
 27.3673 +     *  Get the x and y dimensions of the surface.
 27.3674 +     *
 27.3675 +     * @method getSize
 27.3676 +     * @param {boolean} actual return computed size rather than provided
 27.3677 +     * @return {Array.Number} [x,y] size of surface
 27.3678 +     */
 27.3679 +    Surface.prototype.getSize = function getSize(actual) {
 27.3680 +        return actual ? this._size : (this.size || this._size);
 27.3681 +    };
 27.3682 +
 27.3683 +    /**
 27.3684 +     * Set x and y dimensions of the surface.
 27.3685 +     *
 27.3686 +     * @method setSize
 27.3687 +     * @param {Array.Number} size as [width, height]
 27.3688 +     */
 27.3689 +    Surface.prototype.setSize = function setSize(size) {
 27.3690 +        this.size = size ? [size[0], size[1]] : null;
 27.3691 +        this._sizeDirty = true;
 27.3692 +    };
 27.3693 +
 27.3694 +    module.exports = Surface;
 27.3695 +});
 27.3696 +
 27.3697 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.3698 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.3699 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.3700 + *
 27.3701 + * Owner: mark@famo.us
 27.3702 + * @license MPL 2.0
 27.3703 + * @copyright Famous Industries, Inc. 2014
 27.3704 + */
 27.3705 +
 27.3706 +define('famous/core/Group',['require','exports','module','./Context','./Transform','./Surface'],function(require, exports, module) {
 27.3707 +    var Context = require('./Context');
 27.3708 +    var Transform = require('./Transform');
 27.3709 +    var Surface = require('./Surface');
 27.3710 +
 27.3711 +    /**
 27.3712 +     * A Context designed to contain surfaces and set properties
 27.3713 +     *   to be applied to all of them at once.
 27.3714 +     *   This is primarily used for specific performance improvements in the rendering engine.
 27.3715 +     *   Private.
 27.3716 +     *
 27.3717 +     * @private
 27.3718 +     * @class Group
 27.3719 +     * @extends Surface
 27.3720 +     * @constructor
 27.3721 +     * @param {Object} [options] Surface options array (see Surface})
 27.3722 +     */
 27.3723 +    function Group(options) {
 27.3724 +        Surface.call(this, options);
 27.3725 +        this._shouldRecalculateSize = false;
 27.3726 +        this._container = document.createDocumentFragment();
 27.3727 +        this.context = new Context(this._container);
 27.3728 +        this.setContent(this._container);
 27.3729 +        this._groupSize = [undefined, undefined];
 27.3730 +    }
 27.3731 +
 27.3732 +    /** @const */
 27.3733 +    Group.SIZE_ZERO = [0, 0];
 27.3734 +
 27.3735 +    Group.prototype = Object.create(Surface.prototype);
 27.3736 +    Group.prototype.elementType = 'div';
 27.3737 +    Group.prototype.elementClass = 'famous-group';
 27.3738 +
 27.3739 +    /**
 27.3740 +     * Add renderables to this component's render tree.
 27.3741 +     *
 27.3742 +     * @method add
 27.3743 +     * @private
 27.3744 +     * @param {Object} obj renderable object
 27.3745 +     * @return {RenderNode} Render wrapping provided object, if not already a RenderNode
 27.3746 +     */
 27.3747 +    Group.prototype.add = function add() {
 27.3748 +        return this.context.add.apply(this.context, arguments);
 27.3749 +    };
 27.3750 +
 27.3751 +    /**
 27.3752 +     * Generate a render spec from the contents of this component.
 27.3753 +     *
 27.3754 +     * @private
 27.3755 +     * @method render
 27.3756 +     * @return {Number} Render spec for this component
 27.3757 +     */
 27.3758 +    Group.prototype.render = function render() {
 27.3759 +        return Surface.prototype.render.call(this);
 27.3760 +    };
 27.3761 +
 27.3762 +    /**
 27.3763 +     * Place the document element this component manages into the document.
 27.3764 +     *
 27.3765 +     * @private
 27.3766 +     * @method deploy
 27.3767 +     * @param {Node} target document parent of this container
 27.3768 +     */
 27.3769 +    Group.prototype.deploy = function deploy(target) {
 27.3770 +        this.context.migrate(target);
 27.3771 +    };
 27.3772 +
 27.3773 +    /**
 27.3774 +     * Remove this component and contained content from the document
 27.3775 +     *
 27.3776 +     * @private
 27.3777 +     * @method recall
 27.3778 +     *
 27.3779 +     * @param {Node} target node to which the component was deployed
 27.3780 +     */
 27.3781 +    Group.prototype.recall = function recall(target) {
 27.3782 +        this._container = document.createDocumentFragment();
 27.3783 +        this.context.migrate(this._container);
 27.3784 +    };
 27.3785 +
 27.3786 +    /**
 27.3787 +     * Apply changes from this component to the corresponding document element.
 27.3788 +     *
 27.3789 +     * @private
 27.3790 +     * @method commit
 27.3791 +     *
 27.3792 +     * @param {Object} context update spec passed in from above in the render tree.
 27.3793 +     */
 27.3794 +    Group.prototype.commit = function commit(context) {
 27.3795 +        var transform = context.transform;
 27.3796 +        var origin = context.origin;
 27.3797 +        var opacity = context.opacity;
 27.3798 +        var size = context.size;
 27.3799 +        var result = Surface.prototype.commit.call(this, {
 27.3800 +            allocator: context.allocator,
 27.3801 +            transform: Transform.thenMove(transform, [-origin[0] * size[0], -origin[1] * size[1], 0]),
 27.3802 +            opacity: opacity,
 27.3803 +            origin: origin,
 27.3804 +            size: Group.SIZE_ZERO
 27.3805 +        });
 27.3806 +        if (size[0] !== this._groupSize[0] || size[1] !== this._groupSize[1]) {
 27.3807 +            this._groupSize[0] = size[0];
 27.3808 +            this._groupSize[1] = size[1];
 27.3809 +            this.context.setSize(size);
 27.3810 +        }
 27.3811 +        this.context.update({
 27.3812 +            transform: Transform.translate(-origin[0] * size[0], -origin[1] * size[1], 0),
 27.3813 +            origin: origin,
 27.3814 +            size: size
 27.3815 +        });
 27.3816 +        return result;
 27.3817 +    };
 27.3818 +
 27.3819 +    module.exports = Group;
 27.3820 +});
 27.3821 +
 27.3822 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.3823 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.3824 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.3825 + *
 27.3826 + * Owner: david@famo.us
 27.3827 + * @license MPL 2.0
 27.3828 + * @copyright Famous Industries, Inc. 2014
 27.3829 + */
 27.3830 +
 27.3831 +define('famous/transitions/TransitionableTransform',['require','exports','module','./Transitionable','famous/core/Transform','famous/utilities/Utility'],function(require, exports, module) {
 27.3832 +    var Transitionable = require('./Transitionable');
 27.3833 +    var Transform = require('famous/core/Transform');
 27.3834 +    var Utility = require('famous/utilities/Utility');
 27.3835 +
 27.3836 +    /**
 27.3837 +     * A class for transitioning the state of a Transform by transitioning
 27.3838 +     * its translate, scale, skew and rotate components independently.
 27.3839 +     *
 27.3840 +     * @class TransitionableTransform
 27.3841 +     * @constructor
 27.3842 +     *
 27.3843 +     * @param [transform=Transform.identity] {Transform} The initial transform state
 27.3844 +     */
 27.3845 +    function TransitionableTransform(transform) {
 27.3846 +        this._final = Transform.identity.slice();
 27.3847 +        this.translate = new Transitionable([0, 0, 0]);
 27.3848 +        this.rotate = new Transitionable([0, 0, 0]);
 27.3849 +        this.skew = new Transitionable([0, 0, 0]);
 27.3850 +        this.scale = new Transitionable([1, 1, 1]);
 27.3851 +
 27.3852 +        if (transform) this.set(transform);
 27.3853 +    }
 27.3854 +
 27.3855 +    function _build() {
 27.3856 +        return Transform.build({
 27.3857 +            translate: this.translate.get(),
 27.3858 +            rotate: this.rotate.get(),
 27.3859 +            skew: this.skew.get(),
 27.3860 +            scale: this.scale.get()
 27.3861 +        });
 27.3862 +    }
 27.3863 +
 27.3864 +    /**
 27.3865 +     * An optimized way of setting only the translation component of a Transform
 27.3866 +     *
 27.3867 +     * @method setTranslate
 27.3868 +     * @chainable
 27.3869 +     *
 27.3870 +     * @param translate {Array}     New translation state
 27.3871 +     * @param [transition] {Object} Transition definition
 27.3872 +     * @param [callback] {Function} Callback
 27.3873 +     * @return {TransitionableTransform}
 27.3874 +     */
 27.3875 +    TransitionableTransform.prototype.setTranslate = function setTranslate(translate, transition, callback) {
 27.3876 +        this.translate.set(translate, transition, callback);
 27.3877 +        this._final = this._final.slice();
 27.3878 +        this._final[12] = translate[0];
 27.3879 +        this._final[13] = translate[1];
 27.3880 +        if (translate[2] !== undefined) this._final[14] = translate[2];
 27.3881 +        return this;
 27.3882 +    };
 27.3883 +
 27.3884 +    /**
 27.3885 +     * An optimized way of setting only the scale component of a Transform
 27.3886 +     *
 27.3887 +     * @method setScale
 27.3888 +     * @chainable
 27.3889 +     *
 27.3890 +     * @param scale {Array}         New scale state
 27.3891 +     * @param [transition] {Object} Transition definition
 27.3892 +     * @param [callback] {Function} Callback
 27.3893 +     * @return {TransitionableTransform}
 27.3894 +     */
 27.3895 +    TransitionableTransform.prototype.setScale = function setScale(scale, transition, callback) {
 27.3896 +        this.scale.set(scale, transition, callback);
 27.3897 +        this._final = this._final.slice();
 27.3898 +        this._final[0] = scale[0];
 27.3899 +        this._final[5] = scale[1];
 27.3900 +        if (scale[2] !== undefined) this._final[10] = scale[2];
 27.3901 +        return this;
 27.3902 +    };
 27.3903 +
 27.3904 +    /**
 27.3905 +     * An optimized way of setting only the rotational component of a Transform
 27.3906 +     *
 27.3907 +     * @method setRotate
 27.3908 +     * @chainable
 27.3909 +     *
 27.3910 +     * @param eulerAngles {Array}   Euler angles for new rotation state
 27.3911 +     * @param [transition] {Object} Transition definition
 27.3912 +     * @param [callback] {Function} Callback
 27.3913 +     * @return {TransitionableTransform}
 27.3914 +     */
 27.3915 +    TransitionableTransform.prototype.setRotate = function setRotate(eulerAngles, transition, callback) {
 27.3916 +        this.rotate.set(eulerAngles, transition, callback);
 27.3917 +        this._final = _build.call(this);
 27.3918 +        this._final = Transform.build({
 27.3919 +            translate: this.translate.get(),
 27.3920 +            rotate: eulerAngles,
 27.3921 +            scale: this.scale.get(),
 27.3922 +            skew: this.skew.get()
 27.3923 +        });
 27.3924 +        return this;
 27.3925 +    };
 27.3926 +
 27.3927 +    /**
 27.3928 +     * An optimized way of setting only the skew component of a Transform
 27.3929 +     *
 27.3930 +     * @method setSkew
 27.3931 +     * @chainable
 27.3932 +     *
 27.3933 +     * @param skewAngles {Array}    New skew state
 27.3934 +     * @param [transition] {Object} Transition definition
 27.3935 +     * @param [callback] {Function} Callback
 27.3936 +     * @return {TransitionableTransform}
 27.3937 +     */
 27.3938 +    TransitionableTransform.prototype.setSkew = function setSkew(skewAngles, transition, callback) {
 27.3939 +        this.skew.set(skewAngles, transition, callback);
 27.3940 +        this._final = Transform.build({
 27.3941 +            translate: this.translate.get(),
 27.3942 +            rotate: this.rotate.get(),
 27.3943 +            scale: this.scale.get(),
 27.3944 +            skew: skewAngles
 27.3945 +        });
 27.3946 +        return this;
 27.3947 +    };
 27.3948 +
 27.3949 +    /**
 27.3950 +     * Setter for a TransitionableTransform with optional parameters to transition
 27.3951 +     * between Transforms
 27.3952 +     *
 27.3953 +     * @method set
 27.3954 +     * @chainable
 27.3955 +     *
 27.3956 +     * @param transform {Array}     New transform state
 27.3957 +     * @param [transition] {Object} Transition definition
 27.3958 +     * @param [callback] {Function} Callback
 27.3959 +     * @return {TransitionableTransform}
 27.3960 +     */
 27.3961 +    TransitionableTransform.prototype.set = function set(transform, transition, callback) {
 27.3962 +        this._final = transform;
 27.3963 +        var components = Transform.interpret(transform);
 27.3964 +
 27.3965 +        var _callback = callback ? Utility.after(4, callback) : null;
 27.3966 +        this.translate.set(components.translate, transition, _callback);
 27.3967 +        this.rotate.set(components.rotate, transition, _callback);
 27.3968 +        this.skew.set(components.skew, transition, _callback);
 27.3969 +        this.scale.set(components.scale, transition, _callback);
 27.3970 +        return this;
 27.3971 +    };
 27.3972 +
 27.3973 +    /**
 27.3974 +     * Sets the default transition to use for transitioning betwen Transform states
 27.3975 +     *
 27.3976 +     * @method setDefaultTransition
 27.3977 +     *
 27.3978 +     * @param transition {Object} Transition definition
 27.3979 +     */
 27.3980 +    TransitionableTransform.prototype.setDefaultTransition = function setDefaultTransition(transition) {
 27.3981 +        this.translate.setDefault(transition);
 27.3982 +        this.rotate.setDefault(transition);
 27.3983 +        this.skew.setDefault(transition);
 27.3984 +        this.scale.setDefault(transition);
 27.3985 +    };
 27.3986 +
 27.3987 +    /**
 27.3988 +     * Getter. Returns the current state of the Transform
 27.3989 +     *
 27.3990 +     * @method get
 27.3991 +     *
 27.3992 +     * @return {Transform}
 27.3993 +     */
 27.3994 +    TransitionableTransform.prototype.get = function get() {
 27.3995 +        if (this.isActive()) {
 27.3996 +            return _build.call(this);
 27.3997 +        }
 27.3998 +        else return this._final;
 27.3999 +    };
 27.4000 +
 27.4001 +    /**
 27.4002 +     * Get the destination state of the Transform
 27.4003 +     *
 27.4004 +     * @method getFinal
 27.4005 +     *
 27.4006 +     * @return Transform {Transform}
 27.4007 +     */
 27.4008 +    TransitionableTransform.prototype.getFinal = function getFinal() {
 27.4009 +        return this._final;
 27.4010 +    };
 27.4011 +
 27.4012 +    /**
 27.4013 +     * Determine if the TransitionalTransform is currently transitioning
 27.4014 +     *
 27.4015 +     * @method isActive
 27.4016 +     *
 27.4017 +     * @return {Boolean}
 27.4018 +     */
 27.4019 +    TransitionableTransform.prototype.isActive = function isActive() {
 27.4020 +        return this.translate.isActive() || this.rotate.isActive() || this.scale.isActive() || this.skew.isActive();
 27.4021 +    };
 27.4022 +
 27.4023 +    /**
 27.4024 +     * Halts the transition
 27.4025 +     *
 27.4026 +     * @method halt
 27.4027 +     */
 27.4028 +    TransitionableTransform.prototype.halt = function halt() {
 27.4029 +        this._final = this.get();
 27.4030 +        this.translate.halt();
 27.4031 +        this.rotate.halt();
 27.4032 +        this.skew.halt();
 27.4033 +        this.scale.halt();
 27.4034 +    };
 27.4035 +
 27.4036 +    module.exports = TransitionableTransform;
 27.4037 +});
 27.4038 +
 27.4039 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.4040 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.4041 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.4042 + *
 27.4043 + * Owner: mark@famo.us
 27.4044 + * @license MPL 2.0
 27.4045 + * @copyright Famous Industries, Inc. 2014
 27.4046 + */
 27.4047 +
 27.4048 +define('famous/core/Modifier',['require','exports','module','./Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
 27.4049 +    var Transform = require('./Transform');
 27.4050 +
 27.4051 +    /* TODO: remove these dependencies when deprecation complete */
 27.4052 +    var Transitionable = require('famous/transitions/Transitionable');
 27.4053 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
 27.4054 +
 27.4055 +    /**
 27.4056 +     *
 27.4057 +     *  A collection of visual changes to be
 27.4058 +     *    applied to another renderable component. This collection includes a
 27.4059 +     *    transform matrix, an opacity constant, a size, an origin specifier.
 27.4060 +     *    Modifier objects can be added to any RenderNode or object
 27.4061 +     *    capable of displaying renderables.  The Modifier's children and descendants
 27.4062 +     *    are transformed by the amounts specified in the Modifier's properties.
 27.4063 +     *
 27.4064 +     * @class Modifier
 27.4065 +     * @constructor
 27.4066 +     * @param {Object} [options] overrides of default options
 27.4067 +     * @param {Transform} [options.transform] affine transformation matrix
 27.4068 +     * @param {Number} [options.opacity]
 27.4069 +     * @param {Array.Number} [options.origin] origin adjustment
 27.4070 +     * @param {Array.Number} [options.size] size to apply to descendants
 27.4071 +     */
 27.4072 +    function Modifier(options) {
 27.4073 +        this._transformGetter = null;
 27.4074 +        this._opacityGetter = null;
 27.4075 +        this._originGetter = null;
 27.4076 +        this._alignGetter = null;
 27.4077 +        this._sizeGetter = null;
 27.4078 +
 27.4079 +        /* TODO: remove this when deprecation complete */
 27.4080 +        this._legacyStates = {};
 27.4081 +
 27.4082 +        this._output = {
 27.4083 +            transform: Transform.identity,
 27.4084 +            opacity: 1,
 27.4085 +            origin: null,
 27.4086 +            align: null,
 27.4087 +            size: null,
 27.4088 +            target: null
 27.4089 +        };
 27.4090 +
 27.4091 +        if (options) {
 27.4092 +            if (options.transform) this.transformFrom(options.transform);
 27.4093 +            if (options.opacity !== undefined) this.opacityFrom(options.opacity);
 27.4094 +            if (options.origin) this.originFrom(options.origin);
 27.4095 +            if (options.align) this.alignFrom(options.align);
 27.4096 +            if (options.size) this.sizeFrom(options.size);
 27.4097 +        }
 27.4098 +    }
 27.4099 +
 27.4100 +    /**
 27.4101 +     * Function, object, or static transform matrix which provides the transform.
 27.4102 +     *   This is evaluated on every tick of the engine.
 27.4103 +     *
 27.4104 +     * @method transformFrom
 27.4105 +     *
 27.4106 +     * @param {Object} transform transform provider object
 27.4107 +     * @return {Modifier} this
 27.4108 +     */
 27.4109 +    Modifier.prototype.transformFrom = function transformFrom(transform) {
 27.4110 +        if (transform instanceof Function) this._transformGetter = transform;
 27.4111 +        else if (transform instanceof Object && transform.get) this._transformGetter = transform.get.bind(transform);
 27.4112 +        else {
 27.4113 +            this._transformGetter = null;
 27.4114 +            this._output.transform = transform;
 27.4115 +        }
 27.4116 +        return this;
 27.4117 +    };
 27.4118 +
 27.4119 +    /**
 27.4120 +     * Set function, object, or number to provide opacity, in range [0,1].
 27.4121 +     *
 27.4122 +     * @method opacityFrom
 27.4123 +     *
 27.4124 +     * @param {Object} opacity provider object
 27.4125 +     * @return {Modifier} this
 27.4126 +     */
 27.4127 +    Modifier.prototype.opacityFrom = function opacityFrom(opacity) {
 27.4128 +        if (opacity instanceof Function) this._opacityGetter = opacity;
 27.4129 +        else if (opacity instanceof Object && opacity.get) this._opacityGetter = opacity.get.bind(opacity);
 27.4130 +        else {
 27.4131 +            this._opacityGetter = null;
 27.4132 +            this._output.opacity = opacity;
 27.4133 +        }
 27.4134 +        return this;
 27.4135 +    };
 27.4136 +
 27.4137 +    /**
 27.4138 +     * Set function, object, or numerical array to provide origin, as [x,y],
 27.4139 +     *   where x and y are in the range [0,1].
 27.4140 +     *
 27.4141 +     * @method originFrom
 27.4142 +     *
 27.4143 +     * @param {Object} origin provider object
 27.4144 +     * @return {Modifier} this
 27.4145 +     */
 27.4146 +    Modifier.prototype.originFrom = function originFrom(origin) {
 27.4147 +        if (origin instanceof Function) this._originGetter = origin;
 27.4148 +        else if (origin instanceof Object && origin.get) this._originGetter = origin.get.bind(origin);
 27.4149 +        else {
 27.4150 +            this._originGetter = null;
 27.4151 +            this._output.origin = origin;
 27.4152 +        }
 27.4153 +        return this;
 27.4154 +    };
 27.4155 +
 27.4156 +    /**
 27.4157 +     * Set function, object, or numerical array to provide align, as [x,y],
 27.4158 +     *   where x and y are in the range [0,1].
 27.4159 +     *
 27.4160 +     * @method alignFrom
 27.4161 +     *
 27.4162 +     * @param {Object} align provider object
 27.4163 +     * @return {Modifier} this
 27.4164 +     */
 27.4165 +    Modifier.prototype.alignFrom = function alignFrom(align) {
 27.4166 +        if (align instanceof Function) this._alignGetter = align;
 27.4167 +        else if (align instanceof Object && align.get) this._alignGetter = align.get.bind(align);
 27.4168 +        else {
 27.4169 +            this._alignGetter = null;
 27.4170 +            this._output.align = align;
 27.4171 +        }
 27.4172 +        return this;
 27.4173 +    };
 27.4174 +
 27.4175 +    /**
 27.4176 +     * Set function, object, or numerical array to provide size, as [width, height].
 27.4177 +     *
 27.4178 +     * @method sizeFrom
 27.4179 +     *
 27.4180 +     * @param {Object} size provider object
 27.4181 +     * @return {Modifier} this
 27.4182 +     */
 27.4183 +    Modifier.prototype.sizeFrom = function sizeFrom(size) {
 27.4184 +        if (size instanceof Function) this._sizeGetter = size;
 27.4185 +        else if (size instanceof Object && size.get) this._sizeGetter = size.get.bind(size);
 27.4186 +        else {
 27.4187 +            this._sizeGetter = null;
 27.4188 +            this._output.size = size;
 27.4189 +        }
 27.4190 +        return this;
 27.4191 +    };
 27.4192 +
 27.4193 +     /**
 27.4194 +     * Deprecated: Prefer transformFrom with static Transform, or use a TransitionableTransform.
 27.4195 +     * @deprecated
 27.4196 +     * @method setTransform
 27.4197 +     *
 27.4198 +     * @param {Transform} transform Transform to transition to
 27.4199 +     * @param {Transitionable} transition Valid transitionable object
 27.4200 +     * @param {Function} callback callback to call after transition completes
 27.4201 +     * @return {Modifier} this
 27.4202 +     */
 27.4203 +    Modifier.prototype.setTransform = function setTransform(transform, transition, callback) {
 27.4204 +        if (transition || this._legacyStates.transform) {
 27.4205 +            if (!this._legacyStates.transform) {
 27.4206 +                this._legacyStates.transform = new TransitionableTransform(this._output.transform);
 27.4207 +            }
 27.4208 +            if (!this._transformGetter) this.transformFrom(this._legacyStates.transform);
 27.4209 +
 27.4210 +            this._legacyStates.transform.set(transform, transition, callback);
 27.4211 +            return this;
 27.4212 +        }
 27.4213 +        else return this.transformFrom(transform);
 27.4214 +    };
 27.4215 +
 27.4216 +    /**
 27.4217 +     * Deprecated: Prefer opacityFrom with static opacity array, or use a Transitionable with that opacity.
 27.4218 +     * @deprecated
 27.4219 +     * @method setOpacity
 27.4220 +     *
 27.4221 +     * @param {Number} opacity Opacity value to transition to.
 27.4222 +     * @param {Transitionable} transition Valid transitionable object
 27.4223 +     * @param {Function} callback callback to call after transition completes
 27.4224 +     * @return {Modifier} this
 27.4225 +     */
 27.4226 +    Modifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) {
 27.4227 +        if (transition || this._legacyStates.opacity) {
 27.4228 +            if (!this._legacyStates.opacity) {
 27.4229 +                this._legacyStates.opacity = new Transitionable(this._output.opacity);
 27.4230 +            }
 27.4231 +            if (!this._opacityGetter) this.opacityFrom(this._legacyStates.opacity);
 27.4232 +
 27.4233 +            return this._legacyStates.opacity.set(opacity, transition, callback);
 27.4234 +        }
 27.4235 +        else return this.opacityFrom(opacity);
 27.4236 +    };
 27.4237 +
 27.4238 +    /**
 27.4239 +     * Deprecated: Prefer originFrom with static origin array, or use a Transitionable with that origin.
 27.4240 +     * @deprecated
 27.4241 +     * @method setOrigin
 27.4242 +     *
 27.4243 +     * @param {Array.Number} origin two element array with values between 0 and 1.
 27.4244 +     * @param {Transitionable} transition Valid transitionable object
 27.4245 +     * @param {Function} callback callback to call after transition completes
 27.4246 +     * @return {Modifier} this
 27.4247 +     */
 27.4248 +    Modifier.prototype.setOrigin = function setOrigin(origin, transition, callback) {
 27.4249 +        /* TODO: remove this if statement when deprecation complete */
 27.4250 +        if (transition || this._legacyStates.origin) {
 27.4251 +
 27.4252 +            if (!this._legacyStates.origin) {
 27.4253 +                this._legacyStates.origin = new Transitionable(this._output.origin || [0, 0]);
 27.4254 +            }
 27.4255 +            if (!this._originGetter) this.originFrom(this._legacyStates.origin);
 27.4256 +
 27.4257 +            this._legacyStates.origin.set(origin, transition, callback);
 27.4258 +            return this;
 27.4259 +        }
 27.4260 +        else return this.originFrom(origin);
 27.4261 +    };
 27.4262 +
 27.4263 +    /**
 27.4264 +     * Deprecated: Prefer alignFrom with static align array, or use a Transitionable with that align.
 27.4265 +     * @deprecated
 27.4266 +     * @method setAlign
 27.4267 +     *
 27.4268 +     * @param {Array.Number} align two element array with values between 0 and 1.
 27.4269 +     * @param {Transitionable} transition Valid transitionable object
 27.4270 +     * @param {Function} callback callback to call after transition completes
 27.4271 +     * @return {Modifier} this
 27.4272 +     */
 27.4273 +    Modifier.prototype.setAlign = function setAlign(align, transition, callback) {
 27.4274 +        /* TODO: remove this if statement when deprecation complete */
 27.4275 +        if (transition || this._legacyStates.align) {
 27.4276 +
 27.4277 +            if (!this._legacyStates.align) {
 27.4278 +                this._legacyStates.align = new Transitionable(this._output.align || [0, 0]);
 27.4279 +            }
 27.4280 +            if (!this._alignGetter) this.alignFrom(this._legacyStates.align);
 27.4281 +
 27.4282 +            this._legacyStates.align.set(align, transition, callback);
 27.4283 +            return this;
 27.4284 +        }
 27.4285 +        else return this.alignFrom(align);
 27.4286 +    };
 27.4287 +
 27.4288 +    /**
 27.4289 +     * Deprecated: Prefer sizeFrom with static origin array, or use a Transitionable with that size.
 27.4290 +     * @deprecated
 27.4291 +     * @method setSize
 27.4292 +     * @param {Array.Number} size two element array of [width, height]
 27.4293 +     * @param {Transitionable} transition Valid transitionable object
 27.4294 +     * @param {Function} callback callback to call after transition completes
 27.4295 +     * @return {Modifier} this
 27.4296 +     */
 27.4297 +    Modifier.prototype.setSize = function setSize(size, transition, callback) {
 27.4298 +        if (size && (transition || this._legacyStates.size)) {
 27.4299 +            if (!this._legacyStates.size) {
 27.4300 +                this._legacyStates.size = new Transitionable(this._output.size || [0, 0]);
 27.4301 +            }
 27.4302 +            if (!this._sizeGetter) this.sizeFrom(this._legacyStates.size);
 27.4303 +
 27.4304 +            this._legacyStates.size.set(size, transition, callback);
 27.4305 +            return this;
 27.4306 +        }
 27.4307 +        else return this.sizeFrom(size);
 27.4308 +    };
 27.4309 +
 27.4310 +    /**
 27.4311 +     * Deprecated: Prefer to stop transform in your provider object.
 27.4312 +     * @deprecated
 27.4313 +     * @method halt
 27.4314 +     */
 27.4315 +    Modifier.prototype.halt = function halt() {
 27.4316 +        if (this._legacyStates.transform) this._legacyStates.transform.halt();
 27.4317 +        if (this._legacyStates.opacity) this._legacyStates.opacity.halt();
 27.4318 +        if (this._legacyStates.origin) this._legacyStates.origin.halt();
 27.4319 +        if (this._legacyStates.align) this._legacyStates.align.halt();
 27.4320 +        if (this._legacyStates.size) this._legacyStates.size.halt();
 27.4321 +        this._transformGetter = null;
 27.4322 +        this._opacityGetter = null;
 27.4323 +        this._originGetter = null;
 27.4324 +        this._alignGetter = null;
 27.4325 +        this._sizeGetter = null;
 27.4326 +    };
 27.4327 +
 27.4328 +    /**
 27.4329 +     * Deprecated: Prefer to use your provided transform or output of your transform provider.
 27.4330 +     * @deprecated
 27.4331 +     * @method getTransform
 27.4332 +     * @return {Object} transform provider object
 27.4333 +     */
 27.4334 +    Modifier.prototype.getTransform = function getTransform() {
 27.4335 +        return this._transformGetter();
 27.4336 +    };
 27.4337 +
 27.4338 +    /**
 27.4339 +     * Deprecated: Prefer to determine the end state of your transform from your transform provider
 27.4340 +     * @deprecated
 27.4341 +     * @method getFinalTransform
 27.4342 +     * @return {Transform} transform matrix
 27.4343 +     */
 27.4344 +    Modifier.prototype.getFinalTransform = function getFinalTransform() {
 27.4345 +        return this._legacyStates.transform ? this._legacyStates.transform.getFinal() : this._output.transform;
 27.4346 +    };
 27.4347 +
 27.4348 +    /**
 27.4349 +     * Deprecated: Prefer to use your provided opacity or output of your opacity provider.
 27.4350 +     * @deprecated
 27.4351 +     * @method getOpacity
 27.4352 +     * @return {Object} opacity provider object
 27.4353 +     */
 27.4354 +    Modifier.prototype.getOpacity = function getOpacity() {
 27.4355 +        return this._opacityGetter();
 27.4356 +    };
 27.4357 +
 27.4358 +    /**
 27.4359 +     * Deprecated: Prefer to use your provided origin or output of your origin provider.
 27.4360 +     * @deprecated
 27.4361 +     * @method getOrigin
 27.4362 +     * @return {Object} origin provider object
 27.4363 +     */
 27.4364 +    Modifier.prototype.getOrigin = function getOrigin() {
 27.4365 +        return this._originGetter();
 27.4366 +    };
 27.4367 +
 27.4368 +    /**
 27.4369 +     * Deprecated: Prefer to use your provided align or output of your align provider.
 27.4370 +     * @deprecated
 27.4371 +     * @method getAlign
 27.4372 +     * @return {Object} align provider object
 27.4373 +     */
 27.4374 +    Modifier.prototype.getAlign = function getAlign() {
 27.4375 +        return this._alignGetter();
 27.4376 +    };
 27.4377 +
 27.4378 +    /**
 27.4379 +     * Deprecated: Prefer to use your provided size or output of your size provider.
 27.4380 +     * @deprecated
 27.4381 +     * @method getSize
 27.4382 +     * @return {Object} size provider object
 27.4383 +     */
 27.4384 +    Modifier.prototype.getSize = function getSize() {
 27.4385 +        return this._sizeGetter ? this._sizeGetter() : this._output.size;
 27.4386 +    };
 27.4387 +
 27.4388 +    // call providers on tick to receive render spec elements to apply
 27.4389 +    function _update() {
 27.4390 +        if (this._transformGetter) this._output.transform = this._transformGetter();
 27.4391 +        if (this._opacityGetter) this._output.opacity = this._opacityGetter();
 27.4392 +        if (this._originGetter) this._output.origin = this._originGetter();
 27.4393 +        if (this._alignGetter) this._output.align = this._alignGetter();
 27.4394 +        if (this._sizeGetter) this._output.size = this._sizeGetter();
 27.4395 +    }
 27.4396 +
 27.4397 +    /**
 27.4398 +     * Return render spec for this Modifier, applying to the provided
 27.4399 +     *    target component.  This is similar to render() for Surfaces.
 27.4400 +     *
 27.4401 +     * @private
 27.4402 +     * @method modify
 27.4403 +     *
 27.4404 +     * @param {Object} target (already rendered) render spec to
 27.4405 +     *    which to apply the transform.
 27.4406 +     * @return {Object} render spec for this Modifier, including the
 27.4407 +     *    provided target
 27.4408 +     */
 27.4409 +    Modifier.prototype.modify = function modify(target) {
 27.4410 +        _update.call(this);
 27.4411 +        this._output.target = target;
 27.4412 +        return this._output;
 27.4413 +    };
 27.4414 +
 27.4415 +    module.exports = Modifier;
 27.4416 +});
 27.4417 +
 27.4418 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.4419 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.4420 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.4421 + *
 27.4422 + * Owner: mark@famo.us
 27.4423 + * @license MPL 2.0
 27.4424 + * @copyright Famous Industries, Inc. 2014
 27.4425 + */
 27.4426 +
 27.4427 +define('famous/core/Scene',['require','exports','module','./Transform','./Modifier','./RenderNode'],function(require, exports, module) {
 27.4428 +    var Transform = require('./Transform');
 27.4429 +    var Modifier = require('./Modifier');
 27.4430 +    var RenderNode = require('./RenderNode');
 27.4431 +
 27.4432 +    /**
 27.4433 +     * Builds and renders a scene graph based on a declarative structure definition.
 27.4434 +     * See the Scene examples in the examples distribution (http://github.com/Famous/examples.git).
 27.4435 +     *
 27.4436 +     * @class Scene
 27.4437 +     * @constructor
 27.4438 +     * @param {Object} definition in the format of a render spec.
 27.4439 +     */
 27.4440 +    function Scene(definition) {
 27.4441 +        this.id = null;
 27.4442 +        this._objects = null;
 27.4443 +
 27.4444 +        this.node = new RenderNode();
 27.4445 +        this._definition = null;
 27.4446 +
 27.4447 +        if (definition) this.load(definition);
 27.4448 +    }
 27.4449 +
 27.4450 +    var _MATRIX_GENERATORS = {
 27.4451 +        'translate': Transform.translate,
 27.4452 +        'rotate': Transform.rotate,
 27.4453 +        'rotateX': Transform.rotateX,
 27.4454 +        'rotateY': Transform.rotateY,
 27.4455 +        'rotateZ': Transform.rotateZ,
 27.4456 +        'rotateAxis': Transform.rotateAxis,
 27.4457 +        'scale': Transform.scale,
 27.4458 +        'skew': Transform.skew,
 27.4459 +        'matrix3d': function() {
 27.4460 +            return arguments;
 27.4461 +        }
 27.4462 +    };
 27.4463 +
 27.4464 +    /**
 27.4465 +     * Clone this scene
 27.4466 +     *
 27.4467 +     * @method create
 27.4468 +     * @return {Scene} deep copy of this scene
 27.4469 +     */
 27.4470 +    Scene.prototype.create = function create() {
 27.4471 +        return new Scene(this._definition);
 27.4472 +    };
 27.4473 +
 27.4474 +    function _resolveTransformMatrix(matrixDefinition) {
 27.4475 +        for (var type in _MATRIX_GENERATORS) {
 27.4476 +            if (type in matrixDefinition) {
 27.4477 +                var args = matrixDefinition[type];
 27.4478 +                if (!(args instanceof Array)) args = [args];
 27.4479 +                return _MATRIX_GENERATORS[type].apply(this, args);
 27.4480 +            }
 27.4481 +        }
 27.4482 +    }
 27.4483 +
 27.4484 +    // parse transform into tree of render nodes, doing matrix multiplication
 27.4485 +    // when available
 27.4486 +    function _parseTransform(definition) {
 27.4487 +        var transformDefinition = definition.transform;
 27.4488 +        var opacity = definition.opacity;
 27.4489 +        var origin = definition.origin;
 27.4490 +        var size = definition.size;
 27.4491 +        var transform = Transform.identity;
 27.4492 +        if (transformDefinition instanceof Array) {
 27.4493 +            if (transformDefinition.length === 16 && typeof transformDefinition[0] === 'number') {
 27.4494 +                transform = transformDefinition;
 27.4495 +            }
 27.4496 +            else {
 27.4497 +                for (var i = 0; i < transformDefinition.length; i++) {
 27.4498 +                    transform = Transform.multiply(transform, _resolveTransformMatrix(transformDefinition[i]));
 27.4499 +                }
 27.4500 +            }
 27.4501 +        }
 27.4502 +        else if (transformDefinition instanceof Object) {
 27.4503 +            transform = _resolveTransformMatrix(transformDefinition);
 27.4504 +        }
 27.4505 +
 27.4506 +        var result = new Modifier({
 27.4507 +            transform: transform,
 27.4508 +            opacity: opacity,
 27.4509 +            origin: origin,
 27.4510 +            size: size
 27.4511 +        });
 27.4512 +        return result;
 27.4513 +    }
 27.4514 +
 27.4515 +    function _parseArray(definition) {
 27.4516 +        var result = new RenderNode();
 27.4517 +        for (var i = 0; i < definition.length; i++) {
 27.4518 +            var obj = _parse.call(this, definition[i]);
 27.4519 +            if (obj) result.add(obj);
 27.4520 +        }
 27.4521 +        return result;
 27.4522 +    }
 27.4523 +
 27.4524 +    // parse object directly into tree of RenderNodes
 27.4525 +    function _parse(definition) {
 27.4526 +        var result;
 27.4527 +        var id;
 27.4528 +        if (definition instanceof Array) {
 27.4529 +            result = _parseArray.call(this, definition);
 27.4530 +        }
 27.4531 +        else {
 27.4532 +            id = this._objects.length;
 27.4533 +            if (definition.render && (definition.render instanceof Function)) {
 27.4534 +                result = definition;
 27.4535 +            }
 27.4536 +            else if (definition.target) {
 27.4537 +                var targetObj = _parse.call(this, definition.target);
 27.4538 +                var obj = _parseTransform.call(this, definition);
 27.4539 +
 27.4540 +                result = new RenderNode(obj);
 27.4541 +                result.add(targetObj);
 27.4542 +                if (definition.id) this.id[definition.id] = obj;
 27.4543 +            }
 27.4544 +            else if (definition.id) {
 27.4545 +                result = new RenderNode();
 27.4546 +                this.id[definition.id] = result;
 27.4547 +            }
 27.4548 +        }
 27.4549 +        this._objects[id] = result;
 27.4550 +        return result;
 27.4551 +    }
 27.4552 +
 27.4553 +    /**
 27.4554 +     * Builds and renders a scene graph based on a canonical declarative scene definition.
 27.4555 +     * See examples/Scene/example.js.
 27.4556 +     *
 27.4557 +     * @method load
 27.4558 +     * @param {Object} definition definition in the format of a render spec.
 27.4559 +     */
 27.4560 +    Scene.prototype.load = function load(definition) {
 27.4561 +        this._definition = definition;
 27.4562 +        this.id = {};
 27.4563 +        this._objects = [];
 27.4564 +        this.node.set(_parse.call(this, definition));
 27.4565 +    };
 27.4566 +
 27.4567 +    /**
 27.4568 +     * Add renderables to this component's render tree
 27.4569 +     *
 27.4570 +     * @method add
 27.4571 +     *
 27.4572 +     * @param {Object} obj renderable object
 27.4573 +     * @return {RenderNode} Render wrapping provided object, if not already a RenderNode
 27.4574 +     */
 27.4575 +    Scene.prototype.add = function add() {
 27.4576 +        return this.node.add.apply(this.node, arguments);
 27.4577 +    };
 27.4578 +
 27.4579 +    /**
 27.4580 +     * Generate a render spec from the contents of this component.
 27.4581 +     *
 27.4582 +     * @private
 27.4583 +     * @method render
 27.4584 +     * @return {number} Render spec for this component
 27.4585 +     */
 27.4586 +    Scene.prototype.render = function render() {
 27.4587 +        return this.node.render.apply(this.node, arguments);
 27.4588 +    };
 27.4589 +
 27.4590 +    module.exports = Scene;
 27.4591 +});
 27.4592 +
 27.4593 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.4594 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.4595 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.4596 + *
 27.4597 + * Owner: mark@famo.us
 27.4598 + * @license MPL 2.0
 27.4599 + * @copyright Famous Industries, Inc. 2014
 27.4600 + */
 27.4601 +
 27.4602 +define('famous/core/View',['require','exports','module','./EventHandler','./OptionsManager','./RenderNode'],function(require, exports, module) {
 27.4603 +    var EventHandler = require('./EventHandler');
 27.4604 +    var OptionsManager = require('./OptionsManager');
 27.4605 +    var RenderNode = require('./RenderNode');
 27.4606 +
 27.4607 +    /**
 27.4608 +     * Useful for quickly creating elements within applications
 27.4609 +     *   with large event systems.  Consists of a RenderNode paired with
 27.4610 +     *   an input EventHandler and an output EventHandler.
 27.4611 +     *   Meant to be extended by the developer.
 27.4612 +     *
 27.4613 +     * @class View
 27.4614 +     * @uses EventHandler
 27.4615 +     * @uses OptionsManager
 27.4616 +     * @uses RenderNode
 27.4617 +     * @constructor
 27.4618 +     */
 27.4619 +    function View(options) {
 27.4620 +        this._node = new RenderNode();
 27.4621 +
 27.4622 +        this._eventInput = new EventHandler();
 27.4623 +        this._eventOutput = new EventHandler();
 27.4624 +        EventHandler.setInputHandler(this, this._eventInput);
 27.4625 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.4626 +
 27.4627 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS || View.DEFAULT_OPTIONS);
 27.4628 +        this._optionsManager = new OptionsManager(this.options);
 27.4629 +
 27.4630 +        if (options) this.setOptions(options);
 27.4631 +    }
 27.4632 +
 27.4633 +    View.DEFAULT_OPTIONS = {}; // no defaults
 27.4634 +
 27.4635 +    /**
 27.4636 +     * Look up options value by key
 27.4637 +     * @method getOptions
 27.4638 +     *
 27.4639 +     * @param {string} key key
 27.4640 +     * @return {Object} associated object
 27.4641 +     */
 27.4642 +    View.prototype.getOptions = function getOptions() {
 27.4643 +        return this._optionsManager.value();
 27.4644 +    };
 27.4645 +
 27.4646 +    /*
 27.4647 +     *  Set internal options.
 27.4648 +     *  No defaults options are set in View.
 27.4649 +     *
 27.4650 +     *  @method setOptions
 27.4651 +     *  @param {Object} options
 27.4652 +     */
 27.4653 +    View.prototype.setOptions = function setOptions(options) {
 27.4654 +        this._optionsManager.patch(options);
 27.4655 +    };
 27.4656 +
 27.4657 +    /**
 27.4658 +     * Add a child renderable to the view.
 27.4659 +     *   Note: This is meant to be used by an inheriting class
 27.4660 +     *   rather than from outside the prototype chain.
 27.4661 +     *
 27.4662 +     * @method add
 27.4663 +     * @return {RenderNode}
 27.4664 +     * @protected
 27.4665 +     */
 27.4666 +    View.prototype.add = function add() {
 27.4667 +        return this._node.add.apply(this._node, arguments);
 27.4668 +    };
 27.4669 +
 27.4670 +    /**
 27.4671 +     * Alias for add
 27.4672 +     * @method _add
 27.4673 +     */
 27.4674 +    View.prototype._add = View.prototype.add;
 27.4675 +
 27.4676 +    /**
 27.4677 +     * Generate a render spec from the contents of this component.
 27.4678 +     *
 27.4679 +     * @private
 27.4680 +     * @method render
 27.4681 +     * @return {number} Render spec for this component
 27.4682 +     */
 27.4683 +    View.prototype.render = function render() {
 27.4684 +        return this._node.render();
 27.4685 +    };
 27.4686 +
 27.4687 +    /**
 27.4688 +     * Return size of contained element.
 27.4689 +     *
 27.4690 +     * @method getSize
 27.4691 +     * @return {Array.Number} [width, height]
 27.4692 +     */
 27.4693 +    View.prototype.getSize = function getSize() {
 27.4694 +        if (this._node && this._node.getSize) {
 27.4695 +            return this._node.getSize.apply(this._node, arguments) || this.options.size;
 27.4696 +        }
 27.4697 +        else return this.options.size;
 27.4698 +    };
 27.4699 +
 27.4700 +    module.exports = View;
 27.4701 +});
 27.4702 +
 27.4703 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.4704 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.4705 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.4706 + *
 27.4707 + * Owner: mark@famo.us
 27.4708 + * @license MPL 2.0
 27.4709 + * @copyright Famous Industries, Inc. 2014
 27.4710 + */
 27.4711 +
 27.4712 +define('famous/core/ViewSequence',['require','exports','module'],function(require, exports, module) {
 27.4713 +
 27.4714 +    /**
 27.4715 +     * Helper object used to iterate through items sequentially. Used in
 27.4716 +     *   views that deal with layout.  A ViewSequence object conceptually points
 27.4717 +     *   to a node in a linked list.
 27.4718 +     *
 27.4719 +     * @class ViewSequence
 27.4720 +     *
 27.4721 +     * @constructor
 27.4722 +     * @param {Object|Array} options Options object, or content array.
 27.4723 +     * @param {Number} [options.index] starting index.
 27.4724 +     * @param {Number} [options.array] Array of elements to populate the ViewSequence
 27.4725 +     * @param {Object} [options._] Optional backing store (internal
 27.4726 +     * @param {Boolean} [options.loop] Whether to wrap when accessing elements just past the end
 27.4727 +     *   (or beginning) of the sequence.
 27.4728 +     */
 27.4729 +    function ViewSequence(options) {
 27.4730 +        if (!options) options = [];
 27.4731 +        if (options instanceof Array) options = {array: options};
 27.4732 +
 27.4733 +        this._ = null;
 27.4734 +        this.index = options.index || 0;
 27.4735 +
 27.4736 +        if (options.array) this._ = new (this.constructor.Backing)(options.array);
 27.4737 +        else if (options._) this._ = options._;
 27.4738 +
 27.4739 +        if (this.index === this._.firstIndex) this._.firstNode = this;
 27.4740 +        if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this;
 27.4741 +
 27.4742 +        if (options.loop !== undefined) this._.loop = options.loop;
 27.4743 +
 27.4744 +        this._previousNode = null;
 27.4745 +        this._nextNode = null;
 27.4746 +    }
 27.4747 +
 27.4748 +    // constructor for internal storage
 27.4749 +    ViewSequence.Backing = function Backing(array) {
 27.4750 +        this.array = array;
 27.4751 +        this.firstIndex = 0;
 27.4752 +        this.loop = false;
 27.4753 +        this.firstNode = null;
 27.4754 +        this.lastNode = null;
 27.4755 +    };
 27.4756 +
 27.4757 +    // Get value "i" slots away from the first index.
 27.4758 +    ViewSequence.Backing.prototype.getValue = function getValue(i) {
 27.4759 +        var _i = i - this.firstIndex;
 27.4760 +        if (_i < 0 || _i >= this.array.length) return null;
 27.4761 +        return this.array[_i];
 27.4762 +    };
 27.4763 +
 27.4764 +    // Set value "i" slots away from the first index.
 27.4765 +    ViewSequence.Backing.prototype.setValue = function setValue(i, value) {
 27.4766 +        this.array[i - this.firstIndex] = value;
 27.4767 +    };
 27.4768 +
 27.4769 +    // After splicing into the backing store, restore the indexes of each node correctly.
 27.4770 +    ViewSequence.Backing.prototype.reindex = function reindex(start, removeCount, insertCount) {
 27.4771 +        if (!this.array[0]) return;
 27.4772 +
 27.4773 +        var i = 0;
 27.4774 +        var index = this.firstIndex;
 27.4775 +        var indexShiftAmount = insertCount - removeCount;
 27.4776 +        var node = this.firstNode;
 27.4777 +
 27.4778 +        // find node to begin
 27.4779 +        while (index < start - 1) {
 27.4780 +            node = node.getNext();
 27.4781 +            index++;
 27.4782 +        }
 27.4783 +        // skip removed nodes
 27.4784 +        var spliceStartNode = node;
 27.4785 +        for (i = 0; i < removeCount; i++) {
 27.4786 +            node = node.getNext();
 27.4787 +            if (node) node._previousNode = spliceStartNode;
 27.4788 +        }
 27.4789 +        var spliceResumeNode = node ? node.getNext() : null;
 27.4790 +        // generate nodes for inserted items
 27.4791 +        spliceStartNode._nextNode = null;
 27.4792 +        node = spliceStartNode;
 27.4793 +        for (i = 0; i < insertCount; i++) node = node.getNext();
 27.4794 +        index += insertCount;
 27.4795 +        // resume the chain
 27.4796 +        if (node !== spliceResumeNode) {
 27.4797 +            node._nextNode = spliceResumeNode;
 27.4798 +            if (spliceResumeNode) spliceResumeNode._previousNode = node;
 27.4799 +        }
 27.4800 +        if (spliceResumeNode) {
 27.4801 +            node = spliceResumeNode;
 27.4802 +            index++;
 27.4803 +            while (node && index < this.array.length + this.firstIndex) {
 27.4804 +                if (node._nextNode) node.index += indexShiftAmount;
 27.4805 +                else node.index = index;
 27.4806 +                node = node.getNext();
 27.4807 +                index++;
 27.4808 +            }
 27.4809 +        }
 27.4810 +    };
 27.4811 +
 27.4812 +    /**
 27.4813 +     * Return ViewSequence node previous to this node in the list, respecting looping if applied.
 27.4814 +     *
 27.4815 +     * @method getPrevious
 27.4816 +     * @return {ViewSequence} previous node.
 27.4817 +     */
 27.4818 +    ViewSequence.prototype.getPrevious = function getPrevious() {
 27.4819 +        if (this.index === this._.firstIndex) {
 27.4820 +            if (this._.loop) {
 27.4821 +                this._previousNode = this._.lastNode || new (this.constructor)({_: this._, index: this._.firstIndex + this._.array.length - 1});
 27.4822 +                this._previousNode._nextNode = this;
 27.4823 +            }
 27.4824 +            else {
 27.4825 +                this._previousNode = null;
 27.4826 +            }
 27.4827 +        }
 27.4828 +        else if (!this._previousNode) {
 27.4829 +            this._previousNode = new (this.constructor)({_: this._, index: this.index - 1});
 27.4830 +            this._previousNode._nextNode = this;
 27.4831 +        }
 27.4832 +        return this._previousNode;
 27.4833 +    };
 27.4834 +
 27.4835 +    /**
 27.4836 +     * Return ViewSequence node next after this node in the list, respecting looping if applied.
 27.4837 +     *
 27.4838 +     * @method getNext
 27.4839 +     * @return {ViewSequence} previous node.
 27.4840 +     */
 27.4841 +    ViewSequence.prototype.getNext = function getNext() {
 27.4842 +        if (this.index === this._.firstIndex + this._.array.length - 1) {
 27.4843 +            if (this._.loop) {
 27.4844 +                this._nextNode = this._.firstNode || new (this.constructor)({_: this._, index: this._.firstIndex});
 27.4845 +                this._nextNode._previousNode = this;
 27.4846 +            }
 27.4847 +            else {
 27.4848 +                this._nextNode = null;
 27.4849 +            }
 27.4850 +        }
 27.4851 +        else if (!this._nextNode) {
 27.4852 +            this._nextNode = new (this.constructor)({_: this._, index: this.index + 1});
 27.4853 +            this._nextNode._previousNode = this;
 27.4854 +        }
 27.4855 +        return this._nextNode;
 27.4856 +    };
 27.4857 +
 27.4858 +    /**
 27.4859 +     * Return index of this ViewSequence node.
 27.4860 +     *
 27.4861 +     * @method getIndex
 27.4862 +     * @return {Number} index
 27.4863 +     */
 27.4864 +    ViewSequence.prototype.getIndex = function getIndex() {
 27.4865 +        return this.index;
 27.4866 +    };
 27.4867 +
 27.4868 +    /**
 27.4869 +     * Return printable version of this ViewSequence node.
 27.4870 +     *
 27.4871 +     * @method toString
 27.4872 +     * @return {string} this index as a string
 27.4873 +     */
 27.4874 +    ViewSequence.prototype.toString = function toString() {
 27.4875 +        return '' + this.index;
 27.4876 +    };
 27.4877 +
 27.4878 +    /**
 27.4879 +     * Add one or more objects to the beginning of the sequence.
 27.4880 +     *
 27.4881 +     * @method unshift
 27.4882 +     * @param {...Object} value arguments array of objects
 27.4883 +     */
 27.4884 +    ViewSequence.prototype.unshift = function unshift(value) {
 27.4885 +        this._.array.unshift.apply(this._.array, arguments);
 27.4886 +        this._.firstIndex -= arguments.length;
 27.4887 +    };
 27.4888 +
 27.4889 +    /**
 27.4890 +     * Add one or more objects to the end of the sequence.
 27.4891 +     *
 27.4892 +     * @method push
 27.4893 +     * @param {...Object} value arguments array of objects
 27.4894 +     */
 27.4895 +    ViewSequence.prototype.push = function push(value) {
 27.4896 +        this._.array.push.apply(this._.array, arguments);
 27.4897 +    };
 27.4898 +
 27.4899 +    /**
 27.4900 +     * Remove objects from the sequence
 27.4901 +     *
 27.4902 +     * @method splice
 27.4903 +     * @param {Number} index starting index for removal
 27.4904 +     * @param {Number} howMany how many elements to remove
 27.4905 +     * @param {...Object} value arguments array of objects
 27.4906 +     */
 27.4907 +    ViewSequence.prototype.splice = function splice(index, howMany) {
 27.4908 +        var values = Array.prototype.slice.call(arguments, 2);
 27.4909 +        this._.array.splice.apply(this._.array, [index - this._.firstIndex, howMany].concat(values));
 27.4910 +        this._.reindex(index, howMany, values.length);
 27.4911 +    };
 27.4912 +
 27.4913 +    /**
 27.4914 +     * Exchange this element's sequence position with another's.
 27.4915 +     *
 27.4916 +     * @method swap
 27.4917 +     * @param {ViewSequence} other element to swap with.
 27.4918 +     */
 27.4919 +    ViewSequence.prototype.swap = function swap(other) {
 27.4920 +        var otherValue = other.get();
 27.4921 +        var myValue = this.get();
 27.4922 +        this._.setValue(this.index, otherValue);
 27.4923 +        this._.setValue(other.index, myValue);
 27.4924 +
 27.4925 +        var myPrevious = this._previousNode;
 27.4926 +        var myNext = this._nextNode;
 27.4927 +        var myIndex = this.index;
 27.4928 +        var otherPrevious = other._previousNode;
 27.4929 +        var otherNext = other._nextNode;
 27.4930 +        var otherIndex = other.index;
 27.4931 +
 27.4932 +        this.index = otherIndex;
 27.4933 +        this._previousNode = (otherPrevious === this) ? other : otherPrevious;
 27.4934 +        if (this._previousNode) this._previousNode._nextNode = this;
 27.4935 +        this._nextNode = (otherNext === this) ? other : otherNext;
 27.4936 +        if (this._nextNode) this._nextNode._previousNode = this;
 27.4937 +
 27.4938 +        other.index = myIndex;
 27.4939 +        other._previousNode = (myPrevious === other) ? this : myPrevious;
 27.4940 +        if (other._previousNode) other._previousNode._nextNode = other;
 27.4941 +        other._nextNode = (myNext === other) ? this : myNext;
 27.4942 +        if (other._nextNode) other._nextNode._previousNode = other;
 27.4943 +
 27.4944 +        if (this.index === this._.firstIndex) this._.firstNode = this;
 27.4945 +        else if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this;
 27.4946 +        if (other.index === this._.firstIndex) this._.firstNode = other;
 27.4947 +        else if (other.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = other;
 27.4948 +    };
 27.4949 +
 27.4950 +   /**
 27.4951 +     * Return value of this ViewSequence node.
 27.4952 +     *
 27.4953 +     * @method get
 27.4954 +     * @return {Object} value of thiss
 27.4955 +     */
 27.4956 +    ViewSequence.prototype.get = function get() {
 27.4957 +        return this._.getValue(this.index);
 27.4958 +    };
 27.4959 +
 27.4960 +   /**
 27.4961 +     * Call getSize() on the contained View.
 27.4962 +     *
 27.4963 +     * @method getSize
 27.4964 +     * @return {Array.Number} [width, height]
 27.4965 +     */
 27.4966 +    ViewSequence.prototype.getSize = function getSize() {
 27.4967 +        var target = this.get();
 27.4968 +        return target ? target.getSize() : null;
 27.4969 +    };
 27.4970 +
 27.4971 +    /**
 27.4972 +     * Generate a render spec from the contents of this component.
 27.4973 +     * Specifically, this will render the value at the current index.
 27.4974 +     * @private
 27.4975 +     * @method render
 27.4976 +     * @return {number} Render spec for this component
 27.4977 +     */
 27.4978 +    ViewSequence.prototype.render = function render() {
 27.4979 +        var target = this.get();
 27.4980 +        return target ? target.render.apply(target, arguments) : null;
 27.4981 +    };
 27.4982 +
 27.4983 +    module.exports = ViewSequence;
 27.4984 +});
 27.4985 +
 27.4986 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.4987 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.4988 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.4989 + *
 27.4990 + * Owner: mark@famo.us
 27.4991 + * @license MPL 2.0
 27.4992 + * @copyright Famous Industries, Inc. 2014
 27.4993 + */
 27.4994 +
 27.4995 +define('famous/math/Utilities',['require','exports','module'],function(require, exports, module) {
 27.4996 +    /**
 27.4997 +     * A few static methods.
 27.4998 +     *
 27.4999 +     * @class Utilities
 27.5000 +     * @static
 27.5001 +     */
 27.5002 +    var Utilities = {};
 27.5003 +
 27.5004 +    /**
 27.5005 +     * Constrain input to range.
 27.5006 +     *
 27.5007 +     * @method clamp
 27.5008 +     * @param {Number} value input
 27.5009 +     * @param {Array.Number} range [min, max]
 27.5010 +     * @static
 27.5011 +     */
 27.5012 +    Utilities.clamp = function clamp(value, range) {
 27.5013 +        return Math.max(Math.min(value, range[1]), range[0]);
 27.5014 +    };
 27.5015 +
 27.5016 +    /**
 27.5017 +     * Euclidean length of numerical array.
 27.5018 +     *
 27.5019 +     * @method length
 27.5020 +     * @param {Array.Number} array array of numbers
 27.5021 +     * @static
 27.5022 +     */
 27.5023 +    Utilities.length = function length(array) {
 27.5024 +        var distanceSquared = 0;
 27.5025 +        for (var i = 0; i < array.length; i++) {
 27.5026 +            distanceSquared += array[i] * array[i];
 27.5027 +        }
 27.5028 +        return Math.sqrt(distanceSquared);
 27.5029 +    };
 27.5030 +
 27.5031 +    module.exports = Utilities;
 27.5032 +});
 27.5033 +
 27.5034 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.5035 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.5036 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.5037 + *
 27.5038 + * Owner: mark@famo.us
 27.5039 + * @license MPL 2.0
 27.5040 + * @copyright Famous Industries, Inc. 2014
 27.5041 + */
 27.5042 +
 27.5043 +define('famous/inputs/GenericSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.5044 +    var EventHandler = require('famous/core/EventHandler');
 27.5045 +
 27.5046 +    /**
 27.5047 +     * Combines multiple types of sync classes (e.g. mouse, touch,
 27.5048 +     *  scrolling) into one standardized interface for inclusion in widgets.
 27.5049 +     *
 27.5050 +     *  Sync classes are first registered with a key, and then can be accessed
 27.5051 +     *  globally by key.
 27.5052 +     *
 27.5053 +     *  Emits 'start', 'update' and 'end' events as a union of the sync class
 27.5054 +     *  providers.
 27.5055 +     *
 27.5056 +     * @class GenericSync
 27.5057 +     * @constructor
 27.5058 +     * @param syncs {Object|Array} object with fields {sync key : sync options}
 27.5059 +     *    or an array of registered sync keys
 27.5060 +     * @param [options] {Object|Array} options object to set on all syncs
 27.5061 +     */
 27.5062 +    function GenericSync(syncs, options) {
 27.5063 +        this._eventInput = new EventHandler();
 27.5064 +        this._eventOutput = new EventHandler();
 27.5065 +
 27.5066 +        EventHandler.setInputHandler(this, this._eventInput);
 27.5067 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.5068 +
 27.5069 +        this._syncs = {};
 27.5070 +        if (syncs) this.addSync(syncs);
 27.5071 +        if (options) this.setOptions(options);
 27.5072 +    }
 27.5073 +
 27.5074 +    GenericSync.DIRECTION_X = 0;
 27.5075 +    GenericSync.DIRECTION_Y = 1;
 27.5076 +    GenericSync.DIRECTION_Z = 2;
 27.5077 +
 27.5078 +    // Global registry of sync classes. Append only.
 27.5079 +    var registry = {};
 27.5080 +
 27.5081 +    /**
 27.5082 +     * Register a global sync class with an identifying key
 27.5083 +     *
 27.5084 +     * @static
 27.5085 +     * @method register
 27.5086 +     *
 27.5087 +     * @param syncObject {Object} an object of {sync key : sync options} fields
 27.5088 +     */
 27.5089 +    GenericSync.register = function register(syncObject) {
 27.5090 +        for (var key in syncObject){
 27.5091 +            if (registry[key]){
 27.5092 +                if (registry[key] === syncObject[key]) return; // redundant registration
 27.5093 +                else throw new Error('this key is registered to a different sync class');
 27.5094 +            }
 27.5095 +            else registry[key] = syncObject[key];
 27.5096 +        }
 27.5097 +    };
 27.5098 +
 27.5099 +    /**
 27.5100 +     * Helper to set options on all sync instances
 27.5101 +     *
 27.5102 +     * @method setOptions
 27.5103 +     * @param options {Object} options object
 27.5104 +     */
 27.5105 +    GenericSync.prototype.setOptions = function(options) {
 27.5106 +        for (var key in this._syncs){
 27.5107 +            this._syncs[key].setOptions(options);
 27.5108 +        }
 27.5109 +    };
 27.5110 +
 27.5111 +    /**
 27.5112 +     * Pipe events to a sync class
 27.5113 +     *
 27.5114 +     * @method pipeSync
 27.5115 +     * @param key {String} identifier for sync class
 27.5116 +     */
 27.5117 +    GenericSync.prototype.pipeSync = function pipeToSync(key) {
 27.5118 +        var sync = this._syncs[key];
 27.5119 +        this._eventInput.pipe(sync);
 27.5120 +        sync.pipe(this._eventOutput);
 27.5121 +    };
 27.5122 +
 27.5123 +    /**
 27.5124 +     * Unpipe events from a sync class
 27.5125 +     *
 27.5126 +     * @method unpipeSync
 27.5127 +     * @param key {String} identifier for sync class
 27.5128 +     */
 27.5129 +    GenericSync.prototype.unpipeSync = function unpipeFromSync(key) {
 27.5130 +        var sync = this._syncs[key];
 27.5131 +        this._eventInput.unpipe(sync);
 27.5132 +        sync.unpipe(this._eventOutput);
 27.5133 +    };
 27.5134 +
 27.5135 +    function _addSingleSync(key, options) {
 27.5136 +        if (!registry[key]) return;
 27.5137 +        this._syncs[key] = new (registry[key])(options);
 27.5138 +        this.pipeSync(key);
 27.5139 +    }
 27.5140 +
 27.5141 +    /**
 27.5142 +     * Add a sync class to from the registered classes
 27.5143 +     *
 27.5144 +     * @method addSync
 27.5145 +     * @param syncs {Object|Array.String} an array of registered sync keys
 27.5146 +     *    or an object with fields {sync key : sync options}
 27.5147 +     */
 27.5148 +    GenericSync.prototype.addSync = function addSync(syncs) {
 27.5149 +        if (syncs instanceof Array)
 27.5150 +            for (var i = 0; i < syncs.length; i++)
 27.5151 +                _addSingleSync.call(this, syncs[i]);
 27.5152 +        else if (syncs instanceof Object)
 27.5153 +            for (var key in syncs)
 27.5154 +                _addSingleSync.call(this, key, syncs[key]);
 27.5155 +    };
 27.5156 +
 27.5157 +    module.exports = GenericSync;
 27.5158 +});
 27.5159 +
 27.5160 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.5161 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.5162 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.5163 + *
 27.5164 + * Owner: mark@famo.us
 27.5165 + * @license MPL 2.0
 27.5166 + * @copyright Famous Industries, Inc. 2014
 27.5167 + */
 27.5168 +
 27.5169 +define('famous/inputs/MouseSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.5170 +    var EventHandler = require('famous/core/EventHandler');
 27.5171 +
 27.5172 +    /**
 27.5173 +     * Handles piped in mouse drag events. Outputs an object with two
 27.5174 +     *   properties, position and velocity.
 27.5175 +     *   Emits 'start', 'update' and 'end' events with DOM event passthroughs,
 27.5176 +     *   with position, velocity, and a delta key.
 27.5177 +     *
 27.5178 +     * @class MouseSync
 27.5179 +     * @constructor
 27.5180 +     *
 27.5181 +     * @param [options] {Object}             default options overrides
 27.5182 +     * @param [options.direction] {Number}   read from a particular axis
 27.5183 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 27.5184 +     * @param [options.propogate] {Boolean}  add listened to document on mouseleave
 27.5185 +     */
 27.5186 +    function MouseSync(options) {
 27.5187 +        this.options =  Object.create(MouseSync.DEFAULT_OPTIONS);
 27.5188 +        if (options) this.setOptions(options);
 27.5189 +
 27.5190 +        this._eventInput = new EventHandler();
 27.5191 +        this._eventOutput = new EventHandler();
 27.5192 +
 27.5193 +        EventHandler.setInputHandler(this, this._eventInput);
 27.5194 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.5195 +
 27.5196 +        this._eventInput.on('mousedown', _handleStart.bind(this));
 27.5197 +        this._eventInput.on('mousemove', _handleMove.bind(this));
 27.5198 +        this._eventInput.on('mouseup', _handleEnd.bind(this));
 27.5199 +
 27.5200 +        if (this.options.propogate) this._eventInput.on('mouseleave', _handleLeave.bind(this));
 27.5201 +        else this._eventInput.on('mouseleave', _handleEnd.bind(this));
 27.5202 +
 27.5203 +        this._payload = {
 27.5204 +            delta    : null,
 27.5205 +            position : null,
 27.5206 +            velocity : null,
 27.5207 +            clientX  : 0,
 27.5208 +            clientY  : 0,
 27.5209 +            offsetX  : 0,
 27.5210 +            offsetY  : 0
 27.5211 +        };
 27.5212 +
 27.5213 +        this._position = null;      // to be deprecated
 27.5214 +        this._prevCoord = undefined;
 27.5215 +        this._prevTime = undefined;
 27.5216 +        this._down = false;
 27.5217 +        this._moved = false;
 27.5218 +    }
 27.5219 +
 27.5220 +    MouseSync.DEFAULT_OPTIONS = {
 27.5221 +        direction: undefined,
 27.5222 +        rails: false,
 27.5223 +        scale: 1,
 27.5224 +        propogate: true  // events piped to document on mouseleave
 27.5225 +    };
 27.5226 +
 27.5227 +    MouseSync.DIRECTION_X = 0;
 27.5228 +    MouseSync.DIRECTION_Y = 1;
 27.5229 +
 27.5230 +    var MINIMUM_TICK_TIME = 8;
 27.5231 +
 27.5232 +    var _now = Date.now;
 27.5233 +
 27.5234 +    function _handleStart(event) {
 27.5235 +        var delta;
 27.5236 +        var velocity;
 27.5237 +        event.preventDefault(); // prevent drag
 27.5238 +
 27.5239 +        var x = event.clientX;
 27.5240 +        var y = event.clientY;
 27.5241 +
 27.5242 +        this._prevCoord = [x, y];
 27.5243 +        this._prevTime = _now();
 27.5244 +        this._down = true;
 27.5245 +        this._move = false;
 27.5246 +
 27.5247 +        if (this.options.direction !== undefined){
 27.5248 +            this._position = 0;
 27.5249 +            delta = 0;
 27.5250 +            velocity = 0;
 27.5251 +        }
 27.5252 +        else {
 27.5253 +            this._position = [0, 0];
 27.5254 +            delta = [0, 0];
 27.5255 +            velocity = [0, 0];
 27.5256 +        }
 27.5257 +
 27.5258 +        var payload = this._payload;
 27.5259 +        payload.delta = delta;
 27.5260 +        payload.position = this._position;
 27.5261 +        payload.velocity = velocity;
 27.5262 +        payload.clientX = x;
 27.5263 +        payload.clientY = y;
 27.5264 +        payload.offsetX = event.offsetX;
 27.5265 +        payload.offsetY = event.offsetY;
 27.5266 +
 27.5267 +        this._eventOutput.emit('start', payload);
 27.5268 +    }
 27.5269 +
 27.5270 +    function _handleMove(event) {
 27.5271 +        if (!this._prevCoord) return;
 27.5272 +
 27.5273 +        var prevCoord = this._prevCoord;
 27.5274 +        var prevTime = this._prevTime;
 27.5275 +
 27.5276 +        var x = event.clientX;
 27.5277 +        var y = event.clientY;
 27.5278 +
 27.5279 +        var currTime = _now();
 27.5280 +
 27.5281 +        var diffX = x - prevCoord[0];
 27.5282 +        var diffY = y - prevCoord[1];
 27.5283 +
 27.5284 +        if (this.options.rails) {
 27.5285 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 27.5286 +            else diffX = 0;
 27.5287 +        }
 27.5288 +
 27.5289 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time
 27.5290 +
 27.5291 +        var velX = diffX / diffTime;
 27.5292 +        var velY = diffY / diffTime;
 27.5293 +
 27.5294 +        var scale = this.options.scale;
 27.5295 +        var nextVel;
 27.5296 +        var nextDelta;
 27.5297 +
 27.5298 +        if (this.options.direction === MouseSync.DIRECTION_X) {
 27.5299 +            nextDelta = scale * diffX;
 27.5300 +            nextVel = scale * velX;
 27.5301 +            this._position += nextDelta;
 27.5302 +        }
 27.5303 +        else if (this.options.direction === MouseSync.DIRECTION_Y) {
 27.5304 +            nextDelta = scale * diffY;
 27.5305 +            nextVel = scale * velY;
 27.5306 +            this._position += nextDelta;
 27.5307 +        }
 27.5308 +        else {
 27.5309 +            nextDelta = [scale * diffX, scale * diffY];
 27.5310 +            nextVel = [scale * velX, scale * velY];
 27.5311 +            this._position[0] += nextDelta[0];
 27.5312 +            this._position[1] += nextDelta[1];
 27.5313 +        }
 27.5314 +
 27.5315 +        var payload = this._payload;
 27.5316 +        payload.delta    = nextDelta;
 27.5317 +        payload.position = this._position;
 27.5318 +        payload.velocity = nextVel;
 27.5319 +        payload.clientX  = x;
 27.5320 +        payload.clientY  = y;
 27.5321 +        payload.offsetX  = event.offsetX;
 27.5322 +        payload.offsetY  = event.offsetY;
 27.5323 +
 27.5324 +        this._eventOutput.emit('update', payload);
 27.5325 +
 27.5326 +        this._prevCoord = [x, y];
 27.5327 +        this._prevTime = currTime;
 27.5328 +        this._move = true;
 27.5329 +    }
 27.5330 +
 27.5331 +    function _handleEnd(event) {
 27.5332 +        if (!this._down) return;
 27.5333 +
 27.5334 +        this._eventOutput.emit('end', this._payload);
 27.5335 +        this._prevCoord = undefined;
 27.5336 +        this._prevTime = undefined;
 27.5337 +        this._down = false;
 27.5338 +        this._move = false;
 27.5339 +    }
 27.5340 +
 27.5341 +    function _handleLeave(event) {
 27.5342 +        if (!this._down || !this._move) return;
 27.5343 +
 27.5344 +        var boundMove = _handleMove.bind(this);
 27.5345 +        var boundEnd = function(event) {
 27.5346 +            _handleEnd.call(this, event);
 27.5347 +            document.removeEventListener('mousemove', boundMove);
 27.5348 +            document.removeEventListener('mouseup', boundEnd);
 27.5349 +        }.bind(this, event);
 27.5350 +
 27.5351 +        document.addEventListener('mousemove', boundMove);
 27.5352 +        document.addEventListener('mouseup', boundEnd);
 27.5353 +    }
 27.5354 +
 27.5355 +    /**
 27.5356 +     * Return entire options dictionary, including defaults.
 27.5357 +     *
 27.5358 +     * @method getOptions
 27.5359 +     * @return {Object} configuration options
 27.5360 +     */
 27.5361 +    MouseSync.prototype.getOptions = function getOptions() {
 27.5362 +        return this.options;
 27.5363 +    };
 27.5364 +
 27.5365 +    /**
 27.5366 +     * Set internal options, overriding any default options
 27.5367 +     *
 27.5368 +     * @method setOptions
 27.5369 +     *
 27.5370 +     * @param [options] {Object}             default options overrides
 27.5371 +     * @param [options.direction] {Number}   read from a particular axis
 27.5372 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 27.5373 +     * @param [options.propogate] {Boolean}  add listened to document on mouseleave
 27.5374 +     */
 27.5375 +    MouseSync.prototype.setOptions = function setOptions(options) {
 27.5376 +        if (options.direction !== undefined) this.options.direction = options.direction;
 27.5377 +        if (options.rails !== undefined) this.options.rails = options.rails;
 27.5378 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.5379 +        if (options.propogate !== undefined) this.options.propogate = options.propogate;
 27.5380 +    };
 27.5381 +
 27.5382 +    module.exports = MouseSync;
 27.5383 +});
 27.5384 +
 27.5385 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.5386 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.5387 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.5388 + *
 27.5389 + * Owner: mark@famo.us
 27.5390 + * @license MPL 2.0
 27.5391 + * @copyright Famous Industries, Inc. 2014
 27.5392 + */
 27.5393 +
 27.5394 +define('famous/inputs/TouchTracker',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.5395 +    var EventHandler = require('famous/core/EventHandler');
 27.5396 +
 27.5397 +    var _now = Date.now;
 27.5398 +
 27.5399 +    function _timestampTouch(touch, event, history) {
 27.5400 +        return {
 27.5401 +            x: touch.clientX,
 27.5402 +            y: touch.clientY,
 27.5403 +            identifier : touch.identifier,
 27.5404 +            origin: event.origin,
 27.5405 +            timestamp: _now(),
 27.5406 +            count: event.touches.length,
 27.5407 +            history: history
 27.5408 +        };
 27.5409 +    }
 27.5410 +
 27.5411 +    function _handleStart(event) {
 27.5412 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.5413 +            var touch = event.changedTouches[i];
 27.5414 +            var data = _timestampTouch(touch, event, null);
 27.5415 +            this.eventOutput.emit('trackstart', data);
 27.5416 +            if (!this.selective && !this.touchHistory[touch.identifier]) this.track(data);
 27.5417 +        }
 27.5418 +    }
 27.5419 +
 27.5420 +    function _handleMove(event) {
 27.5421 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.5422 +            var touch = event.changedTouches[i];
 27.5423 +            var history = this.touchHistory[touch.identifier];
 27.5424 +            if (history) {
 27.5425 +                var data = _timestampTouch(touch, event, history);
 27.5426 +                this.touchHistory[touch.identifier].push(data);
 27.5427 +                this.eventOutput.emit('trackmove', data);
 27.5428 +            }
 27.5429 +        }
 27.5430 +    }
 27.5431 +
 27.5432 +    function _handleEnd(event) {
 27.5433 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.5434 +            var touch = event.changedTouches[i];
 27.5435 +            var history = this.touchHistory[touch.identifier];
 27.5436 +            if (history) {
 27.5437 +                var data = _timestampTouch(touch, event, history);
 27.5438 +                this.eventOutput.emit('trackend', data);
 27.5439 +                delete this.touchHistory[touch.identifier];
 27.5440 +            }
 27.5441 +        }
 27.5442 +    }
 27.5443 +
 27.5444 +    function _handleUnpipe() {
 27.5445 +        for (var i in this.touchHistory) {
 27.5446 +            var history = this.touchHistory[i];
 27.5447 +            this.eventOutput.emit('trackend', {
 27.5448 +                touch: history[history.length - 1].touch,
 27.5449 +                timestamp: Date.now(),
 27.5450 +                count: 0,
 27.5451 +                history: history
 27.5452 +            });
 27.5453 +            delete this.touchHistory[i];
 27.5454 +        }
 27.5455 +    }
 27.5456 +
 27.5457 +    /**
 27.5458 +     * Helper to TouchSync – tracks piped in touch events, organizes touch
 27.5459 +     *   events by ID, and emits track events back to TouchSync.
 27.5460 +     *   Emits 'trackstart', 'trackmove', and 'trackend' events upstream.
 27.5461 +     *
 27.5462 +     * @class TouchTracker
 27.5463 +     * @constructor
 27.5464 +     * @param {Boolean} selective if false, save state for each touch.
 27.5465 +     */
 27.5466 +    function TouchTracker(selective) {
 27.5467 +        this.selective = selective;
 27.5468 +        this.touchHistory = {};
 27.5469 +
 27.5470 +        this.eventInput = new EventHandler();
 27.5471 +        this.eventOutput = new EventHandler();
 27.5472 +
 27.5473 +        EventHandler.setInputHandler(this, this.eventInput);
 27.5474 +        EventHandler.setOutputHandler(this, this.eventOutput);
 27.5475 +
 27.5476 +        this.eventInput.on('touchstart', _handleStart.bind(this));
 27.5477 +        this.eventInput.on('touchmove', _handleMove.bind(this));
 27.5478 +        this.eventInput.on('touchend', _handleEnd.bind(this));
 27.5479 +        this.eventInput.on('touchcancel', _handleEnd.bind(this));
 27.5480 +        this.eventInput.on('unpipe', _handleUnpipe.bind(this));
 27.5481 +    }
 27.5482 +
 27.5483 +    /**
 27.5484 +     * Record touch data, if selective is false.
 27.5485 +     * @private
 27.5486 +     * @method track
 27.5487 +     * @param {Object} data touch data
 27.5488 +     */
 27.5489 +    TouchTracker.prototype.track = function track(data) {
 27.5490 +        this.touchHistory[data.identifier] = [data];
 27.5491 +    };
 27.5492 +
 27.5493 +    module.exports = TouchTracker;
 27.5494 +});
 27.5495 +
 27.5496 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.5497 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.5498 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.5499 + *
 27.5500 + * Owner: mark@famo.us
 27.5501 + * @license MPL 2.0
 27.5502 + * @copyright Famous Industries, Inc. 2014
 27.5503 + */
 27.5504 +
 27.5505 +define('famous/inputs/TouchSync',['require','exports','module','./TouchTracker','famous/core/EventHandler'],function(require, exports, module) {
 27.5506 +    var TouchTracker = require('./TouchTracker');
 27.5507 +    var EventHandler = require('famous/core/EventHandler');
 27.5508 +
 27.5509 +    /**
 27.5510 +     * Handles piped in touch events. Emits 'start', 'update', and 'events'
 27.5511 +     *   events with position, velocity, acceleration, and touch id.
 27.5512 +     *   Useful for dealing with inputs on touch devices.
 27.5513 +     *
 27.5514 +     *
 27.5515 +     * @class TouchSync
 27.5516 +     * @constructor
 27.5517 +     *
 27.5518 +     * @param [options] {Object}             default options overrides
 27.5519 +     * @param [options.direction] {Number}   read from a particular axis
 27.5520 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 27.5521 +     * @param [options.scale] {Number}       constant factor to scale velocity output
 27.5522 +     */
 27.5523 +    function TouchSync(options) {
 27.5524 +        this.options =  Object.create(TouchSync.DEFAULT_OPTIONS);
 27.5525 +        if (options) this.setOptions(options);
 27.5526 +
 27.5527 +        this._eventOutput = new EventHandler();
 27.5528 +        this._touchTracker = new TouchTracker();
 27.5529 +
 27.5530 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.5531 +        EventHandler.setInputHandler(this, this._touchTracker);
 27.5532 +
 27.5533 +        this._touchTracker.on('trackstart', _handleStart.bind(this));
 27.5534 +        this._touchTracker.on('trackmove', _handleMove.bind(this));
 27.5535 +        this._touchTracker.on('trackend', _handleEnd.bind(this));
 27.5536 +
 27.5537 +        this._payload = {
 27.5538 +            delta    : null,
 27.5539 +            position : null,
 27.5540 +            velocity : null,
 27.5541 +            clientX  : undefined,
 27.5542 +            clientY  : undefined,
 27.5543 +            count    : 0,
 27.5544 +            touch    : undefined
 27.5545 +        };
 27.5546 +
 27.5547 +        this._position = null; // to be deprecated
 27.5548 +    }
 27.5549 +
 27.5550 +    TouchSync.DEFAULT_OPTIONS = {
 27.5551 +        direction: undefined,
 27.5552 +        rails: false,
 27.5553 +        scale: 1
 27.5554 +    };
 27.5555 +
 27.5556 +    TouchSync.DIRECTION_X = 0;
 27.5557 +    TouchSync.DIRECTION_Y = 1;
 27.5558 +
 27.5559 +    var MINIMUM_TICK_TIME = 8;
 27.5560 +
 27.5561 +    // handle 'trackstart'
 27.5562 +    function _handleStart(data) {
 27.5563 +        var velocity;
 27.5564 +        var delta;
 27.5565 +        if (this.options.direction !== undefined){
 27.5566 +            this._position = 0;
 27.5567 +            velocity = 0;
 27.5568 +            delta = 0;
 27.5569 +        }
 27.5570 +        else {
 27.5571 +            this._position = [0, 0];
 27.5572 +            velocity = [0, 0];
 27.5573 +            delta = [0, 0];
 27.5574 +        }
 27.5575 +
 27.5576 +        var payload = this._payload;
 27.5577 +        payload.delta = delta;
 27.5578 +        payload.position = this._position;
 27.5579 +        payload.velocity = velocity;
 27.5580 +        payload.clientX = data.x;
 27.5581 +        payload.clientY = data.y;
 27.5582 +        payload.count = data.count;
 27.5583 +        payload.touch = data.identifier;
 27.5584 +
 27.5585 +        this._eventOutput.emit('start', payload);
 27.5586 +    }
 27.5587 +
 27.5588 +    // handle 'trackmove'
 27.5589 +    function _handleMove(data) {
 27.5590 +        var history = data.history;
 27.5591 +
 27.5592 +        var currHistory = history[history.length - 1];
 27.5593 +        var prevHistory = history[history.length - 2];
 27.5594 +
 27.5595 +        var prevTime = prevHistory.timestamp;
 27.5596 +        var currTime = currHistory.timestamp;
 27.5597 +
 27.5598 +        var diffX = currHistory.x - prevHistory.x;
 27.5599 +        var diffY = currHistory.y - prevHistory.y;
 27.5600 +
 27.5601 +        if (this.options.rails) {
 27.5602 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 27.5603 +            else diffX = 0;
 27.5604 +        }
 27.5605 +
 27.5606 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME);
 27.5607 +
 27.5608 +        var velX = diffX / diffTime;
 27.5609 +        var velY = diffY / diffTime;
 27.5610 +
 27.5611 +        var scale = this.options.scale;
 27.5612 +        var nextVel;
 27.5613 +        var nextDelta;
 27.5614 +
 27.5615 +        if (this.options.direction === TouchSync.DIRECTION_X) {
 27.5616 +            nextDelta = scale * diffX;
 27.5617 +            nextVel = scale * velX;
 27.5618 +            this._position += nextDelta;
 27.5619 +        }
 27.5620 +        else if (this.options.direction === TouchSync.DIRECTION_Y) {
 27.5621 +            nextDelta = scale * diffY;
 27.5622 +            nextVel = scale * velY;
 27.5623 +            this._position += nextDelta;
 27.5624 +        }
 27.5625 +        else {
 27.5626 +            nextDelta = [scale * diffX, scale * diffY];
 27.5627 +            nextVel = [scale * velX, scale * velY];
 27.5628 +            this._position[0] += nextDelta[0];
 27.5629 +            this._position[1] += nextDelta[1];
 27.5630 +        }
 27.5631 +
 27.5632 +        var payload = this._payload;
 27.5633 +        payload.delta    = nextDelta;
 27.5634 +        payload.velocity = nextVel;
 27.5635 +        payload.position = this._position;
 27.5636 +        payload.clientX  = data.x;
 27.5637 +        payload.clientY  = data.y;
 27.5638 +        payload.count    = data.count;
 27.5639 +        payload.touch    = data.identifier;
 27.5640 +
 27.5641 +        this._eventOutput.emit('update', payload);
 27.5642 +    }
 27.5643 +
 27.5644 +    // handle 'trackend'
 27.5645 +    function _handleEnd(data) {
 27.5646 +        this._payload.count = data.count;
 27.5647 +        this._eventOutput.emit('end', this._payload);
 27.5648 +    }
 27.5649 +
 27.5650 +    /**
 27.5651 +     * Set internal options, overriding any default options
 27.5652 +     *
 27.5653 +     * @method setOptions
 27.5654 +     *
 27.5655 +     * @param [options] {Object}             default options overrides
 27.5656 +     * @param [options.direction] {Number}   read from a particular axis
 27.5657 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 27.5658 +     * @param [options.scale] {Number}       constant factor to scale velocity output
 27.5659 +     */
 27.5660 +    TouchSync.prototype.setOptions = function setOptions(options) {
 27.5661 +        if (options.direction !== undefined) this.options.direction = options.direction;
 27.5662 +        if (options.rails !== undefined) this.options.rails = options.rails;
 27.5663 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.5664 +    };
 27.5665 +
 27.5666 +    /**
 27.5667 +     * Return entire options dictionary, including defaults.
 27.5668 +     *
 27.5669 +     * @method getOptions
 27.5670 +     * @return {Object} configuration options
 27.5671 +     */
 27.5672 +    TouchSync.prototype.getOptions = function getOptions() {
 27.5673 +        return this.options;
 27.5674 +    };
 27.5675 +
 27.5676 +    module.exports = TouchSync;
 27.5677 +});
 27.5678 +
 27.5679 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.5680 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.5681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.5682 + *
 27.5683 + * Owner: david@famo.us
 27.5684 + * @license MPL 2.0
 27.5685 + * @copyright Famous Industries, Inc. 2014
 27.5686 + */
 27.5687 +
 27.5688 +define('famous/modifiers/Draggable',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/EventHandler','famous/math/Utilities','famous/inputs/GenericSync','famous/inputs/MouseSync','famous/inputs/TouchSync'],function(require, exports, module) {
 27.5689 +    var Transform = require('famous/core/Transform');
 27.5690 +    var Transitionable = require('famous/transitions/Transitionable');
 27.5691 +    var EventHandler = require('famous/core/EventHandler');
 27.5692 +    var Utilities = require('famous/math/Utilities');
 27.5693 +
 27.5694 +    var GenericSync = require('famous/inputs/GenericSync');
 27.5695 +    var MouseSync = require('famous/inputs/MouseSync');
 27.5696 +    var TouchSync = require('famous/inputs/TouchSync');
 27.5697 +    GenericSync.register({'mouse': MouseSync, 'touch': TouchSync});
 27.5698 +
 27.5699 +    /**
 27.5700 +     * Makes added render nodes responsive to drag beahvior.
 27.5701 +     *   Emits events 'start', 'update', 'end'.
 27.5702 +     * @class Draggable
 27.5703 +     * @constructor
 27.5704 +     * @param {Object} [options] options configuration object.
 27.5705 +     * @param {Number} [options.snapX] grid width for snapping during drag
 27.5706 +     * @param {Number} [options.snapY] grid height for snapping during drag
 27.5707 +     * @param {Array.Number} [options.xRange] maxmimum [negative, positive] x displacement from start of drag
 27.5708 +     * @param {Array.Number} [options.yRange] maxmimum [negative, positive] y displacement from start of drag
 27.5709 +     * @param {Number} [options.scale] one pixel of input motion translates to this many pixels of output drag motion
 27.5710 +     * @param {Number} [options.projection] User should set to Draggable._direction.x or
 27.5711 +     *    Draggable._direction.y to constrain to one axis.
 27.5712 +     *
 27.5713 +     */
 27.5714 +    function Draggable(options) {
 27.5715 +        this.options = Object.create(Draggable.DEFAULT_OPTIONS);
 27.5716 +        if (options) this.setOptions(options);
 27.5717 +
 27.5718 +        this._positionState = new Transitionable([0,0]);
 27.5719 +        this._differential  = [0,0];
 27.5720 +        this._active = true;
 27.5721 +
 27.5722 +        this.sync = new GenericSync(['mouse', 'touch'], {scale : this.options.scale});
 27.5723 +        this.eventOutput = new EventHandler();
 27.5724 +        EventHandler.setInputHandler(this,  this.sync);
 27.5725 +        EventHandler.setOutputHandler(this, this.eventOutput);
 27.5726 +
 27.5727 +        _bindEvents.call(this);
 27.5728 +    }
 27.5729 +
 27.5730 +    //binary representation of directions for bitwise operations
 27.5731 +    var _direction = {
 27.5732 +        x : 0x01,         //001
 27.5733 +        y : 0x02          //010
 27.5734 +    };
 27.5735 +
 27.5736 +    Draggable.DIRECTION_X = _direction.x;
 27.5737 +    Draggable.DIRECTION_Y = _direction.y;
 27.5738 +
 27.5739 +    var _clamp = Utilities.clamp;
 27.5740 +
 27.5741 +    Draggable.DEFAULT_OPTIONS = {
 27.5742 +        projection  : _direction.x | _direction.y,
 27.5743 +        scale       : 1,
 27.5744 +        xRange      : null,
 27.5745 +        yRange      : null,
 27.5746 +        snapX       : 0,
 27.5747 +        snapY       : 0,
 27.5748 +        transition  : {duration : 0}
 27.5749 +    };
 27.5750 +
 27.5751 +    function _mapDifferential(differential) {
 27.5752 +        var opts        = this.options;
 27.5753 +        var projection  = opts.projection;
 27.5754 +        var snapX       = opts.snapX;
 27.5755 +        var snapY       = opts.snapY;
 27.5756 +
 27.5757 +        //axes
 27.5758 +        var tx = (projection & _direction.x) ? differential[0] : 0;
 27.5759 +        var ty = (projection & _direction.y) ? differential[1] : 0;
 27.5760 +
 27.5761 +        //snapping
 27.5762 +        if (snapX > 0) tx -= tx % snapX;
 27.5763 +        if (snapY > 0) ty -= ty % snapY;
 27.5764 +
 27.5765 +        return [tx, ty];
 27.5766 +    }
 27.5767 +
 27.5768 +    function _handleStart() {
 27.5769 +        if (!this._active) return;
 27.5770 +        if (this._positionState.isActive()) this._positionState.halt();
 27.5771 +        this.eventOutput.emit('start', {position : this.getPosition()});
 27.5772 +    }
 27.5773 +
 27.5774 +    function _handleMove(event) {
 27.5775 +        if (!this._active) return;
 27.5776 +
 27.5777 +        var options = this.options;
 27.5778 +        this._differential = event.position;
 27.5779 +        var newDifferential = _mapDifferential.call(this, this._differential);
 27.5780 +
 27.5781 +        //buffer the differential if snapping is set
 27.5782 +        this._differential[0] -= newDifferential[0];
 27.5783 +        this._differential[1] -= newDifferential[1];
 27.5784 +
 27.5785 +        var pos = this.getPosition();
 27.5786 +
 27.5787 +        //modify position, retain reference
 27.5788 +        pos[0] += newDifferential[0];
 27.5789 +        pos[1] += newDifferential[1];
 27.5790 +
 27.5791 +        //handle bounding box
 27.5792 +        if (options.xRange){
 27.5793 +            var xRange = [options.xRange[0] + 0.5 * options.snapX, options.xRange[1] - 0.5 * options.snapX];
 27.5794 +            pos[0] = _clamp(pos[0], xRange);
 27.5795 +        }
 27.5796 +
 27.5797 +        if (options.yRange){
 27.5798 +            var yRange = [options.yRange[0] + 0.5 * options.snapY, options.yRange[1] - 0.5 * options.snapY];
 27.5799 +            pos[1] = _clamp(pos[1], yRange);
 27.5800 +        }
 27.5801 +
 27.5802 +        this.eventOutput.emit('update', {position : pos});
 27.5803 +    }
 27.5804 +
 27.5805 +    function _handleEnd() {
 27.5806 +        if (!this._active) return;
 27.5807 +        this.eventOutput.emit('end', {position : this.getPosition()});
 27.5808 +    }
 27.5809 +
 27.5810 +    function _bindEvents() {
 27.5811 +        this.sync.on('start', _handleStart.bind(this));
 27.5812 +        this.sync.on('update', _handleMove.bind(this));
 27.5813 +        this.sync.on('end', _handleEnd.bind(this));
 27.5814 +    }
 27.5815 +
 27.5816 +    /**
 27.5817 +     * Set internal options, overriding any default options
 27.5818 +     *
 27.5819 +     * @method setOptions
 27.5820 +     *
 27.5821 +     * @param {Object} [options] overrides of default options.  See constructor.
 27.5822 +     */
 27.5823 +    Draggable.prototype.setOptions = function setOptions(options) {
 27.5824 +        var currentOptions = this.options;
 27.5825 +        if (options.projection !== undefined) {
 27.5826 +            var proj = options.projection;
 27.5827 +            this.options.projection = 0;
 27.5828 +            ['x', 'y'].forEach(function(val) {
 27.5829 +                if (proj.indexOf(val) !== -1) currentOptions.projection |= _direction[val];
 27.5830 +            });
 27.5831 +        }
 27.5832 +        if (options.scale  !== undefined) {
 27.5833 +            currentOptions.scale  = options.scale;
 27.5834 +            this.sync.setOptions({
 27.5835 +                scale: options.scale
 27.5836 +            });
 27.5837 +        }
 27.5838 +        if (options.xRange !== undefined) currentOptions.xRange = options.xRange;
 27.5839 +        if (options.yRange !== undefined) currentOptions.yRange = options.yRange;
 27.5840 +        if (options.snapX  !== undefined) currentOptions.snapX  = options.snapX;
 27.5841 +        if (options.snapY  !== undefined) currentOptions.snapY  = options.snapY;
 27.5842 +    };
 27.5843 +
 27.5844 +    /**
 27.5845 +     * Get current delta in position from where this draggable started.
 27.5846 +     *
 27.5847 +     * @method getPosition
 27.5848 +     *
 27.5849 +     * @return {array<number>} [x, y] position delta from start.
 27.5850 +     */
 27.5851 +    Draggable.prototype.getPosition = function getPosition() {
 27.5852 +        return this._positionState.get();
 27.5853 +    };
 27.5854 +
 27.5855 +    /**
 27.5856 +     * Transition the element to the desired relative position via provided transition.
 27.5857 +     *  For example, calling this with [0,0] will not change the position.
 27.5858 +     *  Callback will be executed on completion.
 27.5859 +     *
 27.5860 +     * @method setRelativePosition
 27.5861 +     *
 27.5862 +     * @param {array<number>} position end state to which we interpolate
 27.5863 +     * @param {transition} transition transition object specifying how object moves to new position
 27.5864 +     * @param {function} callback zero-argument function to call on observed completion
 27.5865 +     */
 27.5866 +    Draggable.prototype.setRelativePosition = function setRelativePosition(position, transition, callback) {
 27.5867 +        var currPos = this.getPosition();
 27.5868 +        var relativePosition = [currPos[0] + position[0], currPos[1] + position[1]];
 27.5869 +        this.setPosition(relativePosition, transition, callback);
 27.5870 +    };
 27.5871 +
 27.5872 +    /**
 27.5873 +     * Transition the element to the desired absolute position via provided transition.
 27.5874 +     *  Callback will be executed on completion.
 27.5875 +     *
 27.5876 +     * @method setPosition
 27.5877 +     *
 27.5878 +     * @param {array<number>} position end state to which we interpolate
 27.5879 +     * @param {transition} transition transition object specifying how object moves to new position
 27.5880 +     * @param {function} callback zero-argument function to call on observed completion
 27.5881 +     */
 27.5882 +    Draggable.prototype.setPosition = function setPosition(position, transition, callback) {
 27.5883 +        if (this._positionState.isActive()) this._positionState.halt();
 27.5884 +        this._positionState.set(position, transition, callback);
 27.5885 +    };
 27.5886 +
 27.5887 +    /**
 27.5888 +     * Set this draggable to respond to user input.
 27.5889 +     *
 27.5890 +     * @method activate
 27.5891 +     *
 27.5892 +     */
 27.5893 +    Draggable.prototype.activate = function activate() {
 27.5894 +        this._active = true;
 27.5895 +    };
 27.5896 +
 27.5897 +    /**
 27.5898 +     * Set this draggable to ignore user input.
 27.5899 +     *
 27.5900 +     * @method deactivate
 27.5901 +     *
 27.5902 +     */
 27.5903 +    Draggable.prototype.deactivate = function deactivate() {
 27.5904 +        this._active = false;
 27.5905 +    };
 27.5906 +
 27.5907 +    /**
 27.5908 +     * Switch the input response stage between active and inactive.
 27.5909 +     *
 27.5910 +     * @method toggle
 27.5911 +     *
 27.5912 +     */
 27.5913 +    Draggable.prototype.toggle = function toggle() {
 27.5914 +        this._active = !this._active;
 27.5915 +    };
 27.5916 +
 27.5917 +    /**
 27.5918 +     * Return render spec for this Modifier, applying to the provided
 27.5919 +     *    target component.  This is similar to render() for Surfaces.
 27.5920 +     *
 27.5921 +     * @private
 27.5922 +     * @method modify
 27.5923 +     *
 27.5924 +     * @param {Object} target (already rendered) render spec to
 27.5925 +     *    which to apply the transform.
 27.5926 +     * @return {Object} render spec for this Modifier, including the
 27.5927 +     *    provided target
 27.5928 +     */
 27.5929 +    Draggable.prototype.modify = function modify(target) {
 27.5930 +        var pos = this.getPosition();
 27.5931 +        return {
 27.5932 +            transform: Transform.translate(pos[0], pos[1]),
 27.5933 +            target: target
 27.5934 +        };
 27.5935 +    };
 27.5936 +
 27.5937 +    module.exports = Draggable;
 27.5938 +});
 27.5939 +
 27.5940 +define('famous/modifiers/Fader',['require','exports','module','famous/transitions/Transitionable','famous/core/OptionsManager'],function(require, exports, module) {
 27.5941 +    var Transitionable = require('famous/transitions/Transitionable');
 27.5942 +    var OptionsManager = require('famous/core/OptionsManager');
 27.5943 +
 27.5944 +    /**
 27.5945 +     * Modifier that allows you to fade the opacity of affected renderables in and out.
 27.5946 +     * @class Fader
 27.5947 +     * @constructor
 27.5948 +     * @param {Object} [options] options configuration object.
 27.5949 +     * @param {Boolean} [options.cull=false] Stops returning affected renderables up the tree when they're fully faded when true.
 27.5950 +     * @param {Transition} [options.transition=true] The main transition for showing and hiding.
 27.5951 +     * @param {Transition} [options.pulseInTransition=true] Controls the transition to a pulsed state when the Fader instance's pulse
 27.5952 +     * method is called.
 27.5953 +     * @param {Transition} [options.pulseOutTransition=true]Controls the transition back from a pulsed state when the Fader instance's pulse
 27.5954 +     * method is called.
 27.5955 +     *
 27.5956 +     */
 27.5957 +    function Fader(options, startState) {
 27.5958 +        this.options = Object.create(Fader.DEFAULT_OPTIONS);
 27.5959 +        this._optionsManager = new OptionsManager(this.options);
 27.5960 +
 27.5961 +        if (options) this.setOptions(options);
 27.5962 +
 27.5963 +        if (!startState) startState = 0;
 27.5964 +        this.transitionHelper = new Transitionable(startState);
 27.5965 +    }
 27.5966 +
 27.5967 +    Fader.DEFAULT_OPTIONS = {
 27.5968 +        cull: false,
 27.5969 +        transition: true,
 27.5970 +        pulseInTransition: true,
 27.5971 +        pulseOutTransition: true
 27.5972 +    };
 27.5973 +
 27.5974 +    /**
 27.5975 +     * Set internal options, overriding any default options
 27.5976 +     *
 27.5977 +     * @method setOptions
 27.5978 +     *
 27.5979 +     * @param {Object} [options] overrides of default options.  See constructor.
 27.5980 +     */
 27.5981 +    Fader.prototype.setOptions = function setOptions(options) {
 27.5982 +        return this._optionsManager.setOptions(options);
 27.5983 +    };
 27.5984 +
 27.5985 +    /**
 27.5986 +     * Fully displays the Fader instance's associated renderables.
 27.5987 +     *
 27.5988 +     * @method show
 27.5989 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 27.5990 +     * @param {Function} [callback] A callback that executes once you've transitioned to the fully shown state.
 27.5991 +     */
 27.5992 +    Fader.prototype.show = function show(transition, callback) {
 27.5993 +        transition = transition || this.options.transition;
 27.5994 +        this.set(1, transition, callback);
 27.5995 +    };
 27.5996 +
 27.5997 +    /**
 27.5998 +     * Fully fades the Fader instance's associated renderables.
 27.5999 +     *
 27.6000 +     * @method hide
 27.6001 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 27.6002 +     * @param {Function} [callback] A callback that executes once you've transitioned to the fully faded state.
 27.6003 +     */
 27.6004 +    Fader.prototype.hide = function hide(transition, callback) {
 27.6005 +        transition = transition || this.options.transition;
 27.6006 +        this.set(0, transition, callback);
 27.6007 +    };
 27.6008 +
 27.6009 +    /**
 27.6010 +     * Manually sets the opacity state of the fader to the passed-in one. Executes with an optional
 27.6011 +     * transition and callback.
 27.6012 +     *
 27.6013 +     * @method set
 27.6014 +     * @param {Number} state A number from zero to one: the amount of opacity you want to set to.
 27.6015 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 27.6016 +     * @param {Function} [callback] A callback that executes once you've finished executing the pulse.
 27.6017 +     */
 27.6018 +    Fader.prototype.set = function set(state, transition, callback) {
 27.6019 +        this.halt();
 27.6020 +        this.transitionHelper.set(state, transition, callback);
 27.6021 +    };
 27.6022 +
 27.6023 +    /**
 27.6024 +     * Halt the transition
 27.6025 +     *
 27.6026 +     * @method halt
 27.6027 +     */
 27.6028 +    Fader.prototype.halt = function halt() {
 27.6029 +        this.transitionHelper.halt();
 27.6030 +    };
 27.6031 +
 27.6032 +    /**
 27.6033 +     * Tells you if your Fader instance is above its visibility threshold.
 27.6034 +     *
 27.6035 +     * @method isVisible
 27.6036 +     * @return {Boolean} Whether or not your Fader instance is visible.
 27.6037 +     */
 27.6038 +    Fader.prototype.isVisible = function isVisible() {
 27.6039 +        return (this.transitionHelper.get() > 0);
 27.6040 +    };
 27.6041 +
 27.6042 +    /**
 27.6043 +     * Return render spec for this Modifier, applying to the provided
 27.6044 +     *    target component.  This is similar to render() for Surfaces.
 27.6045 +     *
 27.6046 +     * @private
 27.6047 +     * @method modify
 27.6048 +     *
 27.6049 +     * @param {Object} target (already rendered) render spec to
 27.6050 +     *    which to apply the transform.
 27.6051 +     * @return {Object} render spec for this Modifier, including the
 27.6052 +     *    provided target
 27.6053 +     */
 27.6054 +    Fader.prototype.modify = function modify(target) {
 27.6055 +        var currOpacity = this.transitionHelper.get();
 27.6056 +        if (this.options.cull && !currOpacity) return undefined;
 27.6057 +        else return {opacity: currOpacity, target: target};
 27.6058 +    };
 27.6059 +
 27.6060 +    module.exports = Fader;
 27.6061 +});
 27.6062 +
 27.6063 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.6064 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.6065 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.6066 + *
 27.6067 + * Owner: david@famo.us
 27.6068 + * @license MPL 2.0
 27.6069 + * @copyright Famous Industries, Inc. 2014
 27.6070 + */
 27.6071 +
 27.6072 +define('famous/modifiers/ModifierChain',['require','exports','module'],function(require, exports, module) {
 27.6073 +
 27.6074 +    /**
 27.6075 +     * A class to add and remove a chain of modifiers
 27.6076 +     *   at a single point in the render tree
 27.6077 +     *
 27.6078 +     * @class ModifierChain
 27.6079 +     * @constructor
 27.6080 +     */
 27.6081 +    function ModifierChain() {
 27.6082 +        this._chain = [];
 27.6083 +        if (arguments.length) this.addModifier.apply(this, arguments);
 27.6084 +    }
 27.6085 +
 27.6086 +    /**
 27.6087 +     * Add a modifier, or comma separated modifiers, to the modifier chain.
 27.6088 +     *
 27.6089 +     * @method addModifier
 27.6090 +     *
 27.6091 +     * @param {...Modifier*} varargs args list of Modifiers
 27.6092 +     */
 27.6093 +    ModifierChain.prototype.addModifier = function addModifier(varargs) {
 27.6094 +        Array.prototype.push.apply(this._chain, arguments);
 27.6095 +    };
 27.6096 +
 27.6097 +    /**
 27.6098 +     * Remove a modifier from the modifier chain.
 27.6099 +     *
 27.6100 +     * @method removeModifier
 27.6101 +     *
 27.6102 +     * @param {Modifier} modifier
 27.6103 +     */
 27.6104 +    ModifierChain.prototype.removeModifier = function removeModifier(modifier) {
 27.6105 +        var index = this._chain.indexOf(modifier);
 27.6106 +        if (index < 0) return;
 27.6107 +        this._chain.splice(index, 1);
 27.6108 +    };
 27.6109 +
 27.6110 +    /**
 27.6111 +     * Return render spec for this Modifier, applying to the provided
 27.6112 +     *    target component.  This is similar to render() for Surfaces.
 27.6113 +     *
 27.6114 +     * @private
 27.6115 +     * @method modify
 27.6116 +     *
 27.6117 +     * @param {Object} input (already rendered) render spec to
 27.6118 +     *    which to apply the transform.
 27.6119 +     * @return {Object} render spec for this Modifier, including the
 27.6120 +     *    provided target
 27.6121 +     */
 27.6122 +    ModifierChain.prototype.modify = function modify(input) {
 27.6123 +        var chain  = this._chain;
 27.6124 +        var result = input;
 27.6125 +        for (var i = 0; i < chain.length; i++) {
 27.6126 +            result = chain[i].modify(result);
 27.6127 +        }
 27.6128 +        return result;
 27.6129 +    };
 27.6130 +
 27.6131 +    module.exports = ModifierChain;
 27.6132 +});
 27.6133 +
 27.6134 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.6135 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.6136 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.6137 + *
 27.6138 + * Owner: mark@famo.us
 27.6139 + * @license MPL 2.0
 27.6140 + * @copyright Famous Industries, Inc. 2014
 27.6141 + */
 27.6142 +
 27.6143 +define('famous/modifiers/StateModifier',['require','exports','module','famous/core/Modifier','famous/core/Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
 27.6144 +    var Modifier = require('famous/core/Modifier');
 27.6145 +    var Transform = require('famous/core/Transform');
 27.6146 +    var Transitionable = require('famous/transitions/Transitionable');
 27.6147 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
 27.6148 +
 27.6149 +    /**
 27.6150 +     *  A collection of visual changes to be
 27.6151 +     *    applied to another renderable component, strongly coupled with the state that defines
 27.6152 +     *    those changes. This collection includes a
 27.6153 +     *    transform matrix, an opacity constant, a size, an origin specifier, and an alignment specifier.
 27.6154 +     *    StateModifier objects can be added to any RenderNode or object
 27.6155 +     *    capable of displaying renderables.  The StateModifier's children and descendants
 27.6156 +     *    are transformed by the amounts specified in the modifier's properties.
 27.6157 +     *
 27.6158 +     * @class StateModifier
 27.6159 +     * @constructor
 27.6160 +     * @param {Object} [options] overrides of default options
 27.6161 +     * @param {Transform} [options.transform] affine transformation matrix
 27.6162 +     * @param {Number} [options.opacity]
 27.6163 +     * @param {Array.Number} [options.origin] origin adjustment
 27.6164 +     * @param {Array.Number} [options.align] align adjustment
 27.6165 +     * @param {Array.Number} [options.size] size to apply to descendants
 27.6166 +     */
 27.6167 +    function StateModifier(options) {
 27.6168 +        this._transformState = new TransitionableTransform(Transform.identity);
 27.6169 +        this._opacityState = new Transitionable(1);
 27.6170 +        this._originState = new Transitionable([0, 0]);
 27.6171 +        this._alignState = new Transitionable([0, 0]);
 27.6172 +        this._sizeState = new Transitionable([0, 0]);
 27.6173 +
 27.6174 +        this._modifier = new Modifier({
 27.6175 +            transform: this._transformState,
 27.6176 +            opacity: this._opacityState,
 27.6177 +            origin: null,
 27.6178 +            align: null,
 27.6179 +            size: null
 27.6180 +        });
 27.6181 +
 27.6182 +        this._hasOrigin = false;
 27.6183 +        this._hasAlign = false;
 27.6184 +        this._hasSize = false;
 27.6185 +
 27.6186 +        if (options) {
 27.6187 +            if (options.transform) this.setTransform(options.transform);
 27.6188 +            if (options.opacity !== undefined) this.setOpacity(options.opacity);
 27.6189 +            if (options.origin) this.setOrigin(options.origin);
 27.6190 +            if (options.align) this.setAlign(options.align);
 27.6191 +            if (options.size) this.setSize(options.size);
 27.6192 +        }
 27.6193 +    }
 27.6194 +
 27.6195 +    /**
 27.6196 +     * Set the transform matrix of this modifier, either statically or
 27.6197 +     *   through a provided Transitionable.
 27.6198 +     *
 27.6199 +     * @method setTransform
 27.6200 +     *
 27.6201 +     * @param {Transform} transform Transform to transition to.
 27.6202 +     * @param {Transitionable} [transition] Valid transitionable object
 27.6203 +     * @param {Function} [callback] callback to call after transition completes
 27.6204 +     * @return {StateModifier} this
 27.6205 +     */
 27.6206 +    StateModifier.prototype.setTransform = function setTransform(transform, transition, callback) {
 27.6207 +        this._transformState.set(transform, transition, callback);
 27.6208 +        return this;
 27.6209 +    };
 27.6210 +
 27.6211 +    /**
 27.6212 +     * Set the opacity of this modifier, either statically or
 27.6213 +     *   through a provided Transitionable.
 27.6214 +     *
 27.6215 +     * @method setOpacity
 27.6216 +     *
 27.6217 +     * @param {Number} opacity Opacity value to transition to.
 27.6218 +     * @param {Transitionable} transition Valid transitionable object
 27.6219 +     * @param {Function} callback callback to call after transition completes
 27.6220 +     * @return {StateModifier} this
 27.6221 +     */
 27.6222 +    StateModifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) {
 27.6223 +        this._opacityState.set(opacity, transition, callback);
 27.6224 +        return this;
 27.6225 +    };
 27.6226 +
 27.6227 +    /**
 27.6228 +     * Set the origin of this modifier, either statically or
 27.6229 +     *   through a provided Transitionable.
 27.6230 +     *
 27.6231 +     * @method setOrigin
 27.6232 +     *
 27.6233 +     * @param {Array.Number} origin two element array with values between 0 and 1.
 27.6234 +     * @param {Transitionable} transition Valid transitionable object
 27.6235 +     * @param {Function} callback callback to call after transition completes
 27.6236 +     * @return {StateModifier} this
 27.6237 +     */
 27.6238 +    StateModifier.prototype.setOrigin = function setOrigin(origin, transition, callback) {
 27.6239 +        if (origin === null) {
 27.6240 +            if (this._hasOrigin) {
 27.6241 +                this._modifier.originFrom(null);
 27.6242 +                this._hasOrigin = false;
 27.6243 +            }
 27.6244 +            return this;
 27.6245 +        }
 27.6246 +        else if (!this._hasOrigin) {
 27.6247 +            this._hasOrigin = true;
 27.6248 +            this._modifier.originFrom(this._originState);
 27.6249 +        }
 27.6250 +        this._originState.set(origin, transition, callback);
 27.6251 +        return this;
 27.6252 +    };
 27.6253 +
 27.6254 +    /**
 27.6255 +     * Set the alignment of this modifier, either statically or
 27.6256 +     *   through a provided Transitionable.
 27.6257 +     *
 27.6258 +     * @method setAlign
 27.6259 +     *
 27.6260 +     * @param {Array.Number} align two element array with values between 0 and 1.
 27.6261 +     * @param {Transitionable} transition Valid transitionable object
 27.6262 +     * @param {Function} callback callback to call after transition completes
 27.6263 +     * @return {StateModifier} this
 27.6264 +     */
 27.6265 +    StateModifier.prototype.setAlign = function setOrigin(align, transition, callback) {
 27.6266 +        if (align === null) {
 27.6267 +            if (this._hasAlign) {
 27.6268 +                this._modifier.alignFrom(null);
 27.6269 +                this._hasAlign = false;
 27.6270 +            }
 27.6271 +            return this;
 27.6272 +        }
 27.6273 +        else if (!this._hasAlign) {
 27.6274 +            this._hasAlign = true;
 27.6275 +            this._modifier.alignFrom(this._alignState);
 27.6276 +        }
 27.6277 +        this._alignState.set(align, transition, callback);
 27.6278 +        return this;
 27.6279 +    };
 27.6280 +
 27.6281 +    /**
 27.6282 +     * Set the size of this modifier, either statically or
 27.6283 +     *   through a provided Transitionable.
 27.6284 +     *
 27.6285 +     * @method setSize
 27.6286 +     *
 27.6287 +     * @param {Array.Number} size two element array with values between 0 and 1.
 27.6288 +     * @param {Transitionable} transition Valid transitionable object
 27.6289 +     * @param {Function} callback callback to call after transition completes
 27.6290 +     * @return {StateModifier} this
 27.6291 +     */
 27.6292 +    StateModifier.prototype.setSize = function setSize(size, transition, callback) {
 27.6293 +        if (size === null) {
 27.6294 +            if (this._hasSize) {
 27.6295 +                this._modifier.sizeFrom(null);
 27.6296 +                this._hasSize = false;
 27.6297 +            }
 27.6298 +            return this;
 27.6299 +        }
 27.6300 +        else if (!this._hasSize) {
 27.6301 +            this._hasSize = true;
 27.6302 +            this._modifier.sizeFrom(this._sizeState);
 27.6303 +        }
 27.6304 +        this._sizeState.set(size, transition, callback);
 27.6305 +        return this;
 27.6306 +    };
 27.6307 +
 27.6308 +    /**
 27.6309 +     * Stop the transition.
 27.6310 +     *
 27.6311 +     * @method halt
 27.6312 +     */
 27.6313 +    StateModifier.prototype.halt = function halt() {
 27.6314 +        this._transformState.halt();
 27.6315 +        this._opacityState.halt();
 27.6316 +        this._originState.halt();
 27.6317 +        this._alignState.halt();
 27.6318 +        this._sizeState.halt();
 27.6319 +    };
 27.6320 +
 27.6321 +    /**
 27.6322 +     * Get the current state of the transform matrix component.
 27.6323 +     *
 27.6324 +     * @method getTransform
 27.6325 +     * @return {Object} transform provider object
 27.6326 +     */
 27.6327 +    StateModifier.prototype.getTransform = function getTransform() {
 27.6328 +        return this._transformState.get();
 27.6329 +    };
 27.6330 +
 27.6331 +    /**
 27.6332 +     * Get the destination state of the transform component.
 27.6333 +     *
 27.6334 +     * @method getFinalTransform
 27.6335 +     * @return {Transform} transform matrix
 27.6336 +     */
 27.6337 +    StateModifier.prototype.getFinalTransform = function getFinalTransform() {
 27.6338 +        return this._transformState.getFinal();
 27.6339 +    };
 27.6340 +
 27.6341 +    /**
 27.6342 +     * Get the current state of the opacity component.
 27.6343 +     *
 27.6344 +     * @method getOpacity
 27.6345 +     * @return {Object} opacity provider object
 27.6346 +     */
 27.6347 +    StateModifier.prototype.getOpacity = function getOpacity() {
 27.6348 +        return this._opacityState.get();
 27.6349 +    };
 27.6350 +
 27.6351 +    /**
 27.6352 +     * Get the current state of the origin component.
 27.6353 +     *
 27.6354 +     * @method getOrigin
 27.6355 +     * @return {Object} origin provider object
 27.6356 +     */
 27.6357 +    StateModifier.prototype.getOrigin = function getOrigin() {
 27.6358 +        return this._hasOrigin ? this._originState.get() : null;
 27.6359 +    };
 27.6360 +
 27.6361 +    /**
 27.6362 +     * Get the current state of the align component.
 27.6363 +     *
 27.6364 +     * @method getAlign
 27.6365 +     * @return {Object} align provider object
 27.6366 +     */
 27.6367 +    StateModifier.prototype.getAlign = function getAlign() {
 27.6368 +        return this._hasAlign ? this._alignState.get() : null;
 27.6369 +    };
 27.6370 +
 27.6371 +    /**
 27.6372 +     * Get the current state of the size component.
 27.6373 +     *
 27.6374 +     * @method getSize
 27.6375 +     * @return {Object} size provider object
 27.6376 +     */
 27.6377 +    StateModifier.prototype.getSize = function getSize() {
 27.6378 +        return this._hasSize ? this._sizeState.get() : null;
 27.6379 +    };
 27.6380 +
 27.6381 +    /**
 27.6382 +     * Return render spec for this StateModifier, applying to the provided
 27.6383 +     *    target component.  This is similar to render() for Surfaces.
 27.6384 +     *
 27.6385 +     * @private
 27.6386 +     * @method modify
 27.6387 +     *
 27.6388 +     * @param {Object} target (already rendered) render spec to
 27.6389 +     *    which to apply the transform.
 27.6390 +     * @return {Object} render spec for this StateModifier, including the
 27.6391 +     *    provided target
 27.6392 +     */
 27.6393 +    StateModifier.prototype.modify = function modify(target) {
 27.6394 +        return this._modifier.modify(target);
 27.6395 +    };
 27.6396 +
 27.6397 +    module.exports = StateModifier;
 27.6398 +});
 27.6399 +
 27.6400 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.6401 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.6402 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.6403 + *
 27.6404 + * Owner: david@famo.us
 27.6405 + * @license MPL 2.0
 27.6406 + * @copyright Famous Industries, Inc. 2014
 27.6407 + */
 27.6408 +
 27.6409 +define('famous/math/Vector',['require','exports','module'],function(require, exports, module) {
 27.6410 +
 27.6411 +    /**
 27.6412 +     * Three-element floating point vector.
 27.6413 +     *
 27.6414 +     * @class Vector
 27.6415 +     * @constructor
 27.6416 +     *
 27.6417 +     * @param {number} x x element value
 27.6418 +     * @param {number} y y element value
 27.6419 +     * @param {number} z z element value
 27.6420 +     */
 27.6421 +    function Vector(x,y,z) {
 27.6422 +        if (arguments.length === 1) this.set(x);
 27.6423 +        else {
 27.6424 +            this.x = x || 0;
 27.6425 +            this.y = y || 0;
 27.6426 +            this.z = z || 0;
 27.6427 +        }
 27.6428 +        return this;
 27.6429 +    }
 27.6430 +
 27.6431 +    var _register = new Vector(0,0,0);
 27.6432 +
 27.6433 +    /**
 27.6434 +     * Add this element-wise to another Vector, element-wise.
 27.6435 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6436 +     *
 27.6437 +     * @method add
 27.6438 +     * @param {Vector} v addend
 27.6439 +     * @return {Vector} vector sum
 27.6440 +     */
 27.6441 +    Vector.prototype.add = function add(v) {
 27.6442 +        return _setXYZ.call(_register,
 27.6443 +            this.x + v.x,
 27.6444 +            this.y + v.y,
 27.6445 +            this.z + v.z
 27.6446 +        );
 27.6447 +    };
 27.6448 +
 27.6449 +    /**
 27.6450 +     * Subtract another vector from this vector, element-wise.
 27.6451 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6452 +     *
 27.6453 +     * @method sub
 27.6454 +     * @param {Vector} v subtrahend
 27.6455 +     * @return {Vector} vector difference
 27.6456 +     */
 27.6457 +    Vector.prototype.sub = function sub(v) {
 27.6458 +        return _setXYZ.call(_register,
 27.6459 +            this.x - v.x,
 27.6460 +            this.y - v.y,
 27.6461 +            this.z - v.z
 27.6462 +        );
 27.6463 +    };
 27.6464 +
 27.6465 +    /**
 27.6466 +     * Scale Vector by floating point r.
 27.6467 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6468 +     *
 27.6469 +     * @method mult
 27.6470 +     *
 27.6471 +     * @param {number} r scalar
 27.6472 +     * @return {Vector} vector result
 27.6473 +     */
 27.6474 +    Vector.prototype.mult = function mult(r) {
 27.6475 +        return _setXYZ.call(_register,
 27.6476 +            r * this.x,
 27.6477 +            r * this.y,
 27.6478 +            r * this.z
 27.6479 +        );
 27.6480 +    };
 27.6481 +
 27.6482 +    /**
 27.6483 +     * Scale Vector by floating point 1/r.
 27.6484 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6485 +     *
 27.6486 +     * @method div
 27.6487 +     *
 27.6488 +     * @param {number} r scalar
 27.6489 +     * @return {Vector} vector result
 27.6490 +     */
 27.6491 +    Vector.prototype.div = function div(r) {
 27.6492 +        return this.mult(1 / r);
 27.6493 +    };
 27.6494 +
 27.6495 +    /**
 27.6496 +     * Given another vector v, return cross product (v)x(this).
 27.6497 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6498 +     *
 27.6499 +     * @method cross
 27.6500 +     * @param {Vector} v Left Hand Vector
 27.6501 +     * @return {Vector} vector result
 27.6502 +     */
 27.6503 +    Vector.prototype.cross = function cross(v) {
 27.6504 +        var x = this.x;
 27.6505 +        var y = this.y;
 27.6506 +        var z = this.z;
 27.6507 +        var vx = v.x;
 27.6508 +        var vy = v.y;
 27.6509 +        var vz = v.z;
 27.6510 +
 27.6511 +        return _setXYZ.call(_register,
 27.6512 +            z * vy - y * vz,
 27.6513 +            x * vz - z * vx,
 27.6514 +            y * vx - x * vy
 27.6515 +        );
 27.6516 +    };
 27.6517 +
 27.6518 +    /**
 27.6519 +     * Component-wise equality test between this and Vector v.
 27.6520 +     * @method equals
 27.6521 +     * @param {Vector} v vector to compare
 27.6522 +     * @return {boolean}
 27.6523 +     */
 27.6524 +    Vector.prototype.equals = function equals(v) {
 27.6525 +        return (v.x === this.x && v.y === this.y && v.z === this.z);
 27.6526 +    };
 27.6527 +
 27.6528 +    /**
 27.6529 +     * Rotate clockwise around x-axis by theta radians.
 27.6530 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6531 +     * @method rotateX
 27.6532 +     * @param {number} theta radians
 27.6533 +     * @return {Vector} rotated vector
 27.6534 +     */
 27.6535 +    Vector.prototype.rotateX = function rotateX(theta) {
 27.6536 +        var x = this.x;
 27.6537 +        var y = this.y;
 27.6538 +        var z = this.z;
 27.6539 +
 27.6540 +        var cosTheta = Math.cos(theta);
 27.6541 +        var sinTheta = Math.sin(theta);
 27.6542 +
 27.6543 +        return _setXYZ.call(_register,
 27.6544 +            x,
 27.6545 +            y * cosTheta - z * sinTheta,
 27.6546 +            y * sinTheta + z * cosTheta
 27.6547 +        );
 27.6548 +    };
 27.6549 +
 27.6550 +    /**
 27.6551 +     * Rotate clockwise around y-axis by theta radians.
 27.6552 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6553 +     * @method rotateY
 27.6554 +     * @param {number} theta radians
 27.6555 +     * @return {Vector} rotated vector
 27.6556 +     */
 27.6557 +    Vector.prototype.rotateY = function rotateY(theta) {
 27.6558 +        var x = this.x;
 27.6559 +        var y = this.y;
 27.6560 +        var z = this.z;
 27.6561 +
 27.6562 +        var cosTheta = Math.cos(theta);
 27.6563 +        var sinTheta = Math.sin(theta);
 27.6564 +
 27.6565 +        return _setXYZ.call(_register,
 27.6566 +            z * sinTheta + x * cosTheta,
 27.6567 +            y,
 27.6568 +            z * cosTheta - x * sinTheta
 27.6569 +        );
 27.6570 +    };
 27.6571 +
 27.6572 +    /**
 27.6573 +     * Rotate clockwise around z-axis by theta radians.
 27.6574 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6575 +     * @method rotateZ
 27.6576 +     * @param {number} theta radians
 27.6577 +     * @return {Vector} rotated vector
 27.6578 +     */
 27.6579 +    Vector.prototype.rotateZ = function rotateZ(theta) {
 27.6580 +        var x = this.x;
 27.6581 +        var y = this.y;
 27.6582 +        var z = this.z;
 27.6583 +
 27.6584 +        var cosTheta = Math.cos(theta);
 27.6585 +        var sinTheta = Math.sin(theta);
 27.6586 +
 27.6587 +        return _setXYZ.call(_register,
 27.6588 +            x * cosTheta - y * sinTheta,
 27.6589 +            x * sinTheta + y * cosTheta,
 27.6590 +            z
 27.6591 +        );
 27.6592 +    };
 27.6593 +
 27.6594 +    /**
 27.6595 +     * Return dot product of this with a second Vector
 27.6596 +     * @method dot
 27.6597 +     * @param {Vector} v second vector
 27.6598 +     * @return {number} dot product
 27.6599 +     */
 27.6600 +    Vector.prototype.dot = function dot(v) {
 27.6601 +        return this.x * v.x + this.y * v.y + this.z * v.z;
 27.6602 +    };
 27.6603 +
 27.6604 +    /**
 27.6605 +     * Return squared length of this vector
 27.6606 +     * @method normSquared
 27.6607 +     * @return {number} squared length
 27.6608 +     */
 27.6609 +    Vector.prototype.normSquared = function normSquared() {
 27.6610 +        return this.dot(this);
 27.6611 +    };
 27.6612 +
 27.6613 +    /**
 27.6614 +     * Return length of this vector
 27.6615 +     * @method norm
 27.6616 +     * @return {number} length
 27.6617 +     */
 27.6618 +    Vector.prototype.norm = function norm() {
 27.6619 +        return Math.sqrt(this.normSquared());
 27.6620 +    };
 27.6621 +
 27.6622 +    /**
 27.6623 +     * Scale Vector to specified length.
 27.6624 +     *   If length is less than internal tolerance, set vector to [length, 0, 0].
 27.6625 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6626 +     * @method normalize
 27.6627 +     *
 27.6628 +     * @param {number} length target length, default 1.0
 27.6629 +     * @return {Vector}
 27.6630 +     */
 27.6631 +    Vector.prototype.normalize = function normalize(length) {
 27.6632 +        if (arguments.length === 0) length = 1;
 27.6633 +        var norm = this.norm();
 27.6634 +
 27.6635 +        if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm));
 27.6636 +        else return _setXYZ.call(_register, length, 0, 0);
 27.6637 +    };
 27.6638 +
 27.6639 +    /**
 27.6640 +     * Make a separate copy of the Vector.
 27.6641 +     *
 27.6642 +     * @method clone
 27.6643 +     *
 27.6644 +     * @return {Vector}
 27.6645 +     */
 27.6646 +    Vector.prototype.clone = function clone() {
 27.6647 +        return new Vector(this);
 27.6648 +    };
 27.6649 +
 27.6650 +    /**
 27.6651 +     * True if and only if every value is 0 (or falsy)
 27.6652 +     *
 27.6653 +     * @method isZero
 27.6654 +     *
 27.6655 +     * @return {boolean}
 27.6656 +     */
 27.6657 +    Vector.prototype.isZero = function isZero() {
 27.6658 +        return !(this.x || this.y || this.z);
 27.6659 +    };
 27.6660 +
 27.6661 +    function _setXYZ(x,y,z) {
 27.6662 +        this.x = x;
 27.6663 +        this.y = y;
 27.6664 +        this.z = z;
 27.6665 +        return this;
 27.6666 +    }
 27.6667 +
 27.6668 +    function _setFromArray(v) {
 27.6669 +        return _setXYZ.call(this,v[0],v[1],v[2] || 0);
 27.6670 +    }
 27.6671 +
 27.6672 +    function _setFromVector(v) {
 27.6673 +        return _setXYZ.call(this, v.x, v.y, v.z);
 27.6674 +    }
 27.6675 +
 27.6676 +    function _setFromNumber(x) {
 27.6677 +        return _setXYZ.call(this,x,0,0);
 27.6678 +    }
 27.6679 +
 27.6680 +    /**
 27.6681 +     * Set this Vector to the values in the provided Array or Vector.
 27.6682 +     *
 27.6683 +     * @method set
 27.6684 +     * @param {object} v array, Vector, or number
 27.6685 +     * @return {Vector} this
 27.6686 +     */
 27.6687 +    Vector.prototype.set = function set(v) {
 27.6688 +        if (v instanceof Array)    return _setFromArray.call(this, v);
 27.6689 +        if (v instanceof Vector)   return _setFromVector.call(this, v);
 27.6690 +        if (typeof v === 'number') return _setFromNumber.call(this, v);
 27.6691 +    };
 27.6692 +
 27.6693 +    Vector.prototype.setXYZ = function(x,y,z) {
 27.6694 +        return _setXYZ.apply(this, arguments);
 27.6695 +    };
 27.6696 +
 27.6697 +    Vector.prototype.set1D = function(x) {
 27.6698 +        return _setFromNumber.call(this, x);
 27.6699 +    };
 27.6700 +
 27.6701 +    /**
 27.6702 +     * Put result of last internal register calculation in specified output vector.
 27.6703 +     *
 27.6704 +     * @method put
 27.6705 +     * @param {Vector} v destination vector
 27.6706 +     * @return {Vector} destination vector
 27.6707 +     */
 27.6708 +
 27.6709 +    Vector.prototype.put = function put(v) {
 27.6710 +        _setFromVector.call(v, _register);
 27.6711 +    };
 27.6712 +
 27.6713 +    /**
 27.6714 +     * Set this vector to [0,0,0]
 27.6715 +     *
 27.6716 +     * @method clear
 27.6717 +     */
 27.6718 +    Vector.prototype.clear = function clear() {
 27.6719 +        return _setXYZ.call(this,0,0,0);
 27.6720 +    };
 27.6721 +
 27.6722 +    /**
 27.6723 +     * Scale this Vector down to specified "cap" length.
 27.6724 +     *   If Vector shorter than cap, or cap is Infinity, do nothing.
 27.6725 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6726 +     *
 27.6727 +     * @method cap
 27.6728 +     * @return {Vector} capped vector
 27.6729 +     */
 27.6730 +    Vector.prototype.cap = function cap(cap) {
 27.6731 +        if (cap === Infinity) return _setFromVector.call(_register, this);
 27.6732 +        var norm = this.norm();
 27.6733 +        if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm));
 27.6734 +        else return _setFromVector.call(_register, this);
 27.6735 +    };
 27.6736 +
 27.6737 +    /**
 27.6738 +     * Return projection of this Vector onto another.
 27.6739 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6740 +     *
 27.6741 +     * @method project
 27.6742 +     * @param {Vector} n vector to project upon
 27.6743 +     * @return {Vector} projected vector
 27.6744 +     */
 27.6745 +    Vector.prototype.project = function project(n) {
 27.6746 +        return n.mult(this.dot(n));
 27.6747 +    };
 27.6748 +
 27.6749 +    /**
 27.6750 +     * Reflect this Vector across provided vector.
 27.6751 +     *   Note: This sets the internal result register, so other references to that vector will change.
 27.6752 +     *
 27.6753 +     * @method reflectAcross
 27.6754 +     * @param {Vector} n vector to reflect across
 27.6755 +     * @return {Vector} reflected vector
 27.6756 +     */
 27.6757 +    Vector.prototype.reflectAcross = function reflectAcross(n) {
 27.6758 +        n.normalize().put(n);
 27.6759 +        return _setFromVector(_register, this.sub(this.project(n).mult(2)));
 27.6760 +    };
 27.6761 +
 27.6762 +    /**
 27.6763 +     * Convert Vector to three-element array.
 27.6764 +     *
 27.6765 +     * @method get
 27.6766 +     * @return {array<number>} three-element array
 27.6767 +     */
 27.6768 +    Vector.prototype.get = function get() {
 27.6769 +        return [this.x, this.y, this.z];
 27.6770 +    };
 27.6771 +
 27.6772 +    Vector.prototype.get1D = function() {
 27.6773 +        return this.x;
 27.6774 +    };
 27.6775 +
 27.6776 +    module.exports = Vector;
 27.6777 +
 27.6778 +});
 27.6779 +
 27.6780 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.6781 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.6782 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.6783 + *
 27.6784 + * Owner: david@famo.us
 27.6785 + * @license MPL 2.0
 27.6786 + * @copyright Famous Industries, Inc. 2014
 27.6787 + */
 27.6788 +
 27.6789 +define('famous/math/Matrix',['require','exports','module','./Vector'],function(require, exports, module) {
 27.6790 +    var Vector = require('./Vector');
 27.6791 +
 27.6792 +    /**
 27.6793 +     * A library for using a 3x3 numerical matrix, represented as a two-level array.
 27.6794 +     *
 27.6795 +     * @class Matrix
 27.6796 +     * @constructor
 27.6797 +     *
 27.6798 +     * @param {Array.Array} values array of rows
 27.6799 +     */
 27.6800 +    function Matrix(values) {
 27.6801 +        this.values = values ||
 27.6802 +            [
 27.6803 +                [1,0,0],
 27.6804 +                [0,1,0],
 27.6805 +                [0,0,1]
 27.6806 +            ];
 27.6807 +
 27.6808 +        return this;
 27.6809 +    }
 27.6810 +
 27.6811 +    var _register = new Matrix();
 27.6812 +    var _vectorRegister = new Vector();
 27.6813 +
 27.6814 +    /**
 27.6815 +     * Return the values in the matrix as an array of numerical row arrays
 27.6816 +     *
 27.6817 +     * @method get
 27.6818 +     *
 27.6819 +     * @return {Array.array} matrix values as array of rows.
 27.6820 +     */
 27.6821 +    Matrix.prototype.get = function get() {
 27.6822 +        return this.values;
 27.6823 +    };
 27.6824 +
 27.6825 +    /**
 27.6826 +     * Set the nested array of rows in the matrix.
 27.6827 +     *
 27.6828 +     * @method set
 27.6829 +     *
 27.6830 +     * @param {Array.array} values matrix values as array of rows.
 27.6831 +     */
 27.6832 +    Matrix.prototype.set = function set(values) {
 27.6833 +        this.values = values;
 27.6834 +    };
 27.6835 +
 27.6836 +    /**
 27.6837 +     * Take this matrix as A, input vector V as a column vector, and return matrix product (A)(V).
 27.6838 +     *   Note: This sets the internal vector register.  Current handles to the vector register
 27.6839 +     *   will see values changed.
 27.6840 +     *
 27.6841 +     * @method vectorMultiply
 27.6842 +     *
 27.6843 +     * @param {Vector} v input vector V
 27.6844 +     * @return {Vector} result of multiplication, as a handle to the internal vector register
 27.6845 +     */
 27.6846 +    Matrix.prototype.vectorMultiply = function vectorMultiply(v) {
 27.6847 +        var M = this.get();
 27.6848 +        var v0 = v.x;
 27.6849 +        var v1 = v.y;
 27.6850 +        var v2 = v.z;
 27.6851 +
 27.6852 +        var M0 = M[0];
 27.6853 +        var M1 = M[1];
 27.6854 +        var M2 = M[2];
 27.6855 +
 27.6856 +        var M00 = M0[0];
 27.6857 +        var M01 = M0[1];
 27.6858 +        var M02 = M0[2];
 27.6859 +        var M10 = M1[0];
 27.6860 +        var M11 = M1[1];
 27.6861 +        var M12 = M1[2];
 27.6862 +        var M20 = M2[0];
 27.6863 +        var M21 = M2[1];
 27.6864 +        var M22 = M2[2];
 27.6865 +
 27.6866 +        return _vectorRegister.setXYZ(
 27.6867 +            M00*v0 + M01*v1 + M02*v2,
 27.6868 +            M10*v0 + M11*v1 + M12*v2,
 27.6869 +            M20*v0 + M21*v1 + M22*v2
 27.6870 +        );
 27.6871 +    };
 27.6872 +
 27.6873 +    /**
 27.6874 +     * Multiply the provided matrix M2 with this matrix.  Result is (this) * (M2).
 27.6875 +     *   Note: This sets the internal matrix register.  Current handles to the register
 27.6876 +     *   will see values changed.
 27.6877 +     *
 27.6878 +     * @method multiply
 27.6879 +     *
 27.6880 +     * @param {Matrix} M2 input matrix to multiply on the right
 27.6881 +     * @return {Matrix} result of multiplication, as a handle to the internal register
 27.6882 +     */
 27.6883 +    Matrix.prototype.multiply = function multiply(M2) {
 27.6884 +        var M1 = this.get();
 27.6885 +        var result = [[]];
 27.6886 +        for (var i = 0; i < 3; i++) {
 27.6887 +            result[i] = [];
 27.6888 +            for (var j = 0; j < 3; j++) {
 27.6889 +                var sum = 0;
 27.6890 +                for (var k = 0; k < 3; k++) {
 27.6891 +                    sum += M1[i][k] * M2[k][j];
 27.6892 +                }
 27.6893 +                result[i][j] = sum;
 27.6894 +            }
 27.6895 +        }
 27.6896 +        return _register.set(result);
 27.6897 +    };
 27.6898 +
 27.6899 +    /**
 27.6900 +     * Creates a Matrix which is the transpose of this matrix.
 27.6901 +     *   Note: This sets the internal matrix register.  Current handles to the register
 27.6902 +     *   will see values changed.
 27.6903 +     *
 27.6904 +     * @method transpose
 27.6905 +     *
 27.6906 +     * @return {Matrix} result of transpose, as a handle to the internal register
 27.6907 +     */
 27.6908 +    Matrix.prototype.transpose = function transpose() {
 27.6909 +        var result = [];
 27.6910 +        var M = this.get();
 27.6911 +        for (var row = 0; row < 3; row++) {
 27.6912 +            for (var col = 0; col < 3; col++) {
 27.6913 +                result[row][col] = M[col][row];
 27.6914 +            }
 27.6915 +        }
 27.6916 +        return _register.set(result);
 27.6917 +    };
 27.6918 +
 27.6919 +    /**
 27.6920 +     * Clones the matrix
 27.6921 +     *
 27.6922 +     * @method clone
 27.6923 +     * @return {Matrix} New copy of the original matrix
 27.6924 +     */
 27.6925 +    Matrix.prototype.clone = function clone() {
 27.6926 +        var values = this.get();
 27.6927 +        var M = [];
 27.6928 +        for (var row = 0; row < 3; row++)
 27.6929 +            M[row] = values[row].slice();
 27.6930 +        return new Matrix(M);
 27.6931 +    };
 27.6932 +
 27.6933 +    module.exports = Matrix;
 27.6934 +});
 27.6935 +
 27.6936 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.6937 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.6938 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.6939 + *
 27.6940 + * Owner: david@famo.us
 27.6941 + * @license MPL 2.0
 27.6942 + * @copyright Famous Industries, Inc. 2014
 27.6943 + */
 27.6944 +
 27.6945 +define('famous/math/Quaternion',['require','exports','module','./Matrix'],function(require, exports, module) {
 27.6946 +    var Matrix = require('./Matrix');
 27.6947 +
 27.6948 +    /**
 27.6949 +     * @class Quaternion
 27.6950 +     * @constructor
 27.6951 +     *
 27.6952 +     * @param {Number} w
 27.6953 +     * @param {Number} x
 27.6954 +     * @param {Number} y
 27.6955 +     * @param {Number} z
 27.6956 +     */
 27.6957 +    function Quaternion(w,x,y,z) {
 27.6958 +        if (arguments.length === 1) this.set(w);
 27.6959 +        else {
 27.6960 +            this.w = (w !== undefined) ? w : 1;  //Angle
 27.6961 +            this.x = (x !== undefined) ? x : 0;  //Axis.x
 27.6962 +            this.y = (y !== undefined) ? y : 0;  //Axis.y
 27.6963 +            this.z = (z !== undefined) ? z : 0;  //Axis.z
 27.6964 +        }
 27.6965 +        return this;
 27.6966 +    }
 27.6967 +
 27.6968 +    var register = new Quaternion(1,0,0,0);
 27.6969 +
 27.6970 +    /**
 27.6971 +     * Doc: TODO
 27.6972 +     * @method add
 27.6973 +     * @param {Quaternion} q
 27.6974 +     * @return {Quaternion}
 27.6975 +     */
 27.6976 +    Quaternion.prototype.add = function add(q) {
 27.6977 +        return register.setWXYZ(
 27.6978 +            this.w + q.w,
 27.6979 +            this.x + q.x,
 27.6980 +            this.y + q.y,
 27.6981 +            this.z + q.z
 27.6982 +        );
 27.6983 +    };
 27.6984 +
 27.6985 +    /*
 27.6986 +     * Docs: TODO
 27.6987 +     *
 27.6988 +     * @method sub
 27.6989 +     * @param {Quaternion} q
 27.6990 +     * @return {Quaternion}
 27.6991 +     */
 27.6992 +    Quaternion.prototype.sub = function sub(q) {
 27.6993 +        return register.setWXYZ(
 27.6994 +            this.w - q.w,
 27.6995 +            this.x - q.x,
 27.6996 +            this.y - q.y,
 27.6997 +            this.z - q.z
 27.6998 +        );
 27.6999 +    };
 27.7000 +
 27.7001 +    /**
 27.7002 +     * Doc: TODO
 27.7003 +     *
 27.7004 +     * @method scalarDivide
 27.7005 +     * @param {Number} s
 27.7006 +     * @return {Quaternion}
 27.7007 +     */
 27.7008 +    Quaternion.prototype.scalarDivide = function scalarDivide(s) {
 27.7009 +        return this.scalarMultiply(1/s);
 27.7010 +    };
 27.7011 +
 27.7012 +    /*
 27.7013 +     * Docs: TODO
 27.7014 +     *
 27.7015 +     * @method scalarMultiply
 27.7016 +     * @param {Number} s
 27.7017 +     * @return {Quaternion}
 27.7018 +     */
 27.7019 +    Quaternion.prototype.scalarMultiply = function scalarMultiply(s) {
 27.7020 +        return register.setWXYZ(
 27.7021 +            this.w * s,
 27.7022 +            this.x * s,
 27.7023 +            this.y * s,
 27.7024 +            this.z * s
 27.7025 +        );
 27.7026 +    };
 27.7027 +
 27.7028 +    /*
 27.7029 +     * Docs: TODO
 27.7030 +     *
 27.7031 +     * @method multiply
 27.7032 +     * @param {Quaternion} q
 27.7033 +     * @return {Quaternion}
 27.7034 +     */
 27.7035 +    Quaternion.prototype.multiply = function multiply(q) {
 27.7036 +        //left-handed coordinate system multiplication
 27.7037 +        var x1 = this.x;
 27.7038 +        var y1 = this.y;
 27.7039 +        var z1 = this.z;
 27.7040 +        var w1 = this.w;
 27.7041 +        var x2 = q.x;
 27.7042 +        var y2 = q.y;
 27.7043 +        var z2 = q.z;
 27.7044 +        var w2 = q.w || 0;
 27.7045 +
 27.7046 +        return register.setWXYZ(
 27.7047 +            w1*w2 - x1*x2 - y1*y2 - z1*z2,
 27.7048 +            x1*w2 + x2*w1 + y2*z1 - y1*z2,
 27.7049 +            y1*w2 + y2*w1 + x1*z2 - x2*z1,
 27.7050 +            z1*w2 + z2*w1 + x2*y1 - x1*y2
 27.7051 +        );
 27.7052 +    };
 27.7053 +
 27.7054 +    var conj = new Quaternion(1,0,0,0);
 27.7055 +
 27.7056 +    /*
 27.7057 +     * Docs: TODO
 27.7058 +     *
 27.7059 +     * @method rotateVector
 27.7060 +     * @param {Vector} v
 27.7061 +     * @return {Quaternion}
 27.7062 +     */
 27.7063 +    Quaternion.prototype.rotateVector = function rotateVector(v) {
 27.7064 +        conj.set(this.conj());
 27.7065 +        return register.set(this.multiply(v).multiply(conj));
 27.7066 +    };
 27.7067 +
 27.7068 +    /*
 27.7069 +     * Docs: TODO
 27.7070 +     *
 27.7071 +     * @method inverse
 27.7072 +     * @return {Quaternion}
 27.7073 +     */
 27.7074 +    Quaternion.prototype.inverse = function inverse() {
 27.7075 +        return register.set(this.conj().scalarDivide(this.normSquared()));
 27.7076 +    };
 27.7077 +
 27.7078 +    /*
 27.7079 +     * Docs: TODO
 27.7080 +     *
 27.7081 +     * @method negate
 27.7082 +     * @return {Quaternion}
 27.7083 +     */
 27.7084 +    Quaternion.prototype.negate = function negate() {
 27.7085 +        return this.scalarMultiply(-1);
 27.7086 +    };
 27.7087 +
 27.7088 +    /*
 27.7089 +     * Docs: TODO
 27.7090 +     *
 27.7091 +     * @method conj
 27.7092 +     * @return {Quaternion}
 27.7093 +     */
 27.7094 +    Quaternion.prototype.conj = function conj() {
 27.7095 +        return register.setWXYZ(
 27.7096 +             this.w,
 27.7097 +            -this.x,
 27.7098 +            -this.y,
 27.7099 +            -this.z
 27.7100 +        );
 27.7101 +    };
 27.7102 +
 27.7103 +    /*
 27.7104 +     * Docs: TODO
 27.7105 +     *
 27.7106 +     * @method normalize
 27.7107 +     * @param {Number} length
 27.7108 +     * @return {Quaternion}
 27.7109 +     */
 27.7110 +    Quaternion.prototype.normalize = function normalize(length) {
 27.7111 +        length = (length === undefined) ? 1 : length;
 27.7112 +        return this.scalarDivide(length * this.norm());
 27.7113 +    };
 27.7114 +
 27.7115 +    /*
 27.7116 +     * Docs: TODO
 27.7117 +     *
 27.7118 +     * @method makeFromAngleAndAxis
 27.7119 +     * @param {Number} angle
 27.7120 +     * @param {Vector} v
 27.7121 +     * @return {Quaternion}
 27.7122 +     */
 27.7123 +    Quaternion.prototype.makeFromAngleAndAxis = function makeFromAngleAndAxis(angle, v) {
 27.7124 +        //left handed quaternion creation: theta -> -theta
 27.7125 +        var n  = v.normalize();
 27.7126 +        var ha = angle*0.5;
 27.7127 +        var s  = -Math.sin(ha);
 27.7128 +        this.x = s*n.x;
 27.7129 +        this.y = s*n.y;
 27.7130 +        this.z = s*n.z;
 27.7131 +        this.w = Math.cos(ha);
 27.7132 +        return this;
 27.7133 +    };
 27.7134 +
 27.7135 +    /*
 27.7136 +     * Docs: TODO
 27.7137 +     *
 27.7138 +     * @method setWXYZ
 27.7139 +     * @param {Number} w
 27.7140 +     * @param {Number} x
 27.7141 +     * @param {Number} y
 27.7142 +     * @param {Number} z
 27.7143 +     * @return {Quaternion}
 27.7144 +     */
 27.7145 +    Quaternion.prototype.setWXYZ = function setWXYZ(w,x,y,z) {
 27.7146 +        register.clear();
 27.7147 +        this.w = w;
 27.7148 +        this.x = x;
 27.7149 +        this.y = y;
 27.7150 +        this.z = z;
 27.7151 +        return this;
 27.7152 +    };
 27.7153 +
 27.7154 +    /*
 27.7155 +     * Docs: TODO
 27.7156 +     *
 27.7157 +     * @method set
 27.7158 +     * @param {Array|Quaternion} v
 27.7159 +     * @return {Quaternion}
 27.7160 +     */
 27.7161 +    Quaternion.prototype.set = function set(v) {
 27.7162 +        if (v instanceof Array) {
 27.7163 +            this.w = v[0];
 27.7164 +            this.x = v[1];
 27.7165 +            this.y = v[2];
 27.7166 +            this.z = v[3];
 27.7167 +        }
 27.7168 +        else {
 27.7169 +            this.w = v.w;
 27.7170 +            this.x = v.x;
 27.7171 +            this.y = v.y;
 27.7172 +            this.z = v.z;
 27.7173 +        }
 27.7174 +        if (this !== register) register.clear();
 27.7175 +        return this;
 27.7176 +    };
 27.7177 +
 27.7178 +    /**
 27.7179 +     * Docs: TODO
 27.7180 +     *
 27.7181 +     * @method put
 27.7182 +     * @param {Quaternion} q
 27.7183 +     * @return {Quaternion}
 27.7184 +     */
 27.7185 +    Quaternion.prototype.put = function put(q) {
 27.7186 +        q.set(register);
 27.7187 +    };
 27.7188 +
 27.7189 +    /**
 27.7190 +     * Doc: TODO
 27.7191 +     *
 27.7192 +     * @method clone
 27.7193 +     * @return {Quaternion}
 27.7194 +     */
 27.7195 +    Quaternion.prototype.clone = function clone() {
 27.7196 +        return new Quaternion(this);
 27.7197 +    };
 27.7198 +
 27.7199 +    /**
 27.7200 +     * Doc: TODO
 27.7201 +     *
 27.7202 +     * @method clear
 27.7203 +     * @return {Quaternion}
 27.7204 +     */
 27.7205 +    Quaternion.prototype.clear = function clear() {
 27.7206 +        this.w = 1;
 27.7207 +        this.x = 0;
 27.7208 +        this.y = 0;
 27.7209 +        this.z = 0;
 27.7210 +        return this;
 27.7211 +    };
 27.7212 +
 27.7213 +    /**
 27.7214 +     * Doc: TODO
 27.7215 +     *
 27.7216 +     * @method isEqual
 27.7217 +     * @param {Quaternion} q
 27.7218 +     * @return {Boolean}
 27.7219 +     */
 27.7220 +    Quaternion.prototype.isEqual = function isEqual(q) {
 27.7221 +        return q.w === this.w && q.x === this.x && q.y === this.y && q.z === this.z;
 27.7222 +    };
 27.7223 +
 27.7224 +    /**
 27.7225 +     * Doc: TODO
 27.7226 +     *
 27.7227 +     * @method dot
 27.7228 +     * @param {Quaternion} q
 27.7229 +     * @return {Number}
 27.7230 +     */
 27.7231 +    Quaternion.prototype.dot = function dot(q) {
 27.7232 +        return this.w * q.w + this.x * q.x + this.y * q.y + this.z * q.z;
 27.7233 +    };
 27.7234 +
 27.7235 +    /**
 27.7236 +     * Doc: TODO
 27.7237 +     *
 27.7238 +     * @method normSquared
 27.7239 +     * @return {Number}
 27.7240 +     */
 27.7241 +    Quaternion.prototype.normSquared = function normSquared() {
 27.7242 +        return this.dot(this);
 27.7243 +    };
 27.7244 +
 27.7245 +    /**
 27.7246 +     * Doc: TODO
 27.7247 +     *
 27.7248 +     * @method norm
 27.7249 +     * @return {Number}
 27.7250 +     */
 27.7251 +    Quaternion.prototype.norm = function norm() {
 27.7252 +        return Math.sqrt(this.normSquared());
 27.7253 +    };
 27.7254 +
 27.7255 +    /**
 27.7256 +     * Doc: TODO
 27.7257 +     *
 27.7258 +     * @method isZero
 27.7259 +     * @return {Boolean}
 27.7260 +     */
 27.7261 +    Quaternion.prototype.isZero = function isZero() {
 27.7262 +        return !(this.x || this.y || this.z);
 27.7263 +    };
 27.7264 +
 27.7265 +    /**
 27.7266 +     * Doc: TODO
 27.7267 +     *
 27.7268 +     * @method getTransform
 27.7269 +     * @return {Transform}
 27.7270 +     */
 27.7271 +    Quaternion.prototype.getTransform = function getTransform() {
 27.7272 +        var temp = this.normalize(1);
 27.7273 +        var x = temp.x;
 27.7274 +        var y = temp.y;
 27.7275 +        var z = temp.z;
 27.7276 +        var w = temp.w;
 27.7277 +
 27.7278 +        //LHC system flattened to column major = RHC flattened to row major
 27.7279 +        return [
 27.7280 +            1 - 2*y*y - 2*z*z,
 27.7281 +                2*x*y - 2*z*w,
 27.7282 +                2*x*z + 2*y*w,
 27.7283 +            0,
 27.7284 +                2*x*y + 2*z*w,
 27.7285 +            1 - 2*x*x - 2*z*z,
 27.7286 +                2*y*z - 2*x*w,
 27.7287 +            0,
 27.7288 +                2*x*z - 2*y*w,
 27.7289 +                2*y*z + 2*x*w,
 27.7290 +            1 - 2*x*x - 2*y*y,
 27.7291 +            0,
 27.7292 +            0,
 27.7293 +            0,
 27.7294 +            0,
 27.7295 +            1
 27.7296 +        ];
 27.7297 +    };
 27.7298 +
 27.7299 +    var matrixRegister = new Matrix();
 27.7300 +
 27.7301 +    /**
 27.7302 +     * Doc: TODO
 27.7303 +     *
 27.7304 +     * @method getMatrix
 27.7305 +     * @return {Transform}
 27.7306 +     */
 27.7307 +    Quaternion.prototype.getMatrix = function getMatrix() {
 27.7308 +        var temp = this.normalize(1);
 27.7309 +        var x = temp.x;
 27.7310 +        var y = temp.y;
 27.7311 +        var z = temp.z;
 27.7312 +        var w = temp.w;
 27.7313 +
 27.7314 +        //LHC system flattened to row major
 27.7315 +        return matrixRegister.set([
 27.7316 +            [
 27.7317 +                1 - 2*y*y - 2*z*z,
 27.7318 +                    2*x*y + 2*z*w,
 27.7319 +                    2*x*z - 2*y*w
 27.7320 +            ],
 27.7321 +            [
 27.7322 +                    2*x*y - 2*z*w,
 27.7323 +                1 - 2*x*x - 2*z*z,
 27.7324 +                    2*y*z + 2*x*w
 27.7325 +            ],
 27.7326 +            [
 27.7327 +                    2*x*z + 2*y*w,
 27.7328 +                    2*y*z - 2*x*w,
 27.7329 +                1 - 2*x*x - 2*y*y
 27.7330 +            ]
 27.7331 +        ]);
 27.7332 +    };
 27.7333 +
 27.7334 +    var epsilon = 1e-5;
 27.7335 +
 27.7336 +    /**
 27.7337 +     * Doc: TODO
 27.7338 +     *
 27.7339 +     * @method slerp
 27.7340 +     * @param {Quaternion} q
 27.7341 +     * @param {Number} t
 27.7342 +     * @return {Transform}
 27.7343 +     */
 27.7344 +    Quaternion.prototype.slerp = function slerp(q, t) {
 27.7345 +        var omega;
 27.7346 +        var cosomega;
 27.7347 +        var sinomega;
 27.7348 +        var scaleFrom;
 27.7349 +        var scaleTo;
 27.7350 +
 27.7351 +        cosomega = this.dot(q);
 27.7352 +        if ((1.0 - cosomega) > epsilon) {
 27.7353 +            omega       = Math.acos(cosomega);
 27.7354 +            sinomega    = Math.sin(omega);
 27.7355 +            scaleFrom   = Math.sin((1.0 - t) * omega) / sinomega;
 27.7356 +            scaleTo     = Math.sin(t * omega) / sinomega;
 27.7357 +        }
 27.7358 +        else {
 27.7359 +            scaleFrom   = 1.0 - t;
 27.7360 +            scaleTo     = t;
 27.7361 +        }
 27.7362 +        return register.set(this.scalarMultiply(scaleFrom/scaleTo).add(q).multiply(scaleTo));
 27.7363 +    };
 27.7364 +
 27.7365 +    module.exports = Quaternion;
 27.7366 +
 27.7367 +});
 27.7368 +
 27.7369 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.7370 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.7371 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.7372 + *
 27.7373 + * Owner: david@famo.us
 27.7374 + * @license MPL 2.0
 27.7375 + * @copyright Famous Industries, Inc. 2014
 27.7376 + */
 27.7377 +
 27.7378 +define('famous/math/Random',['require','exports','module'],function(require, exports, module) {
 27.7379 +
 27.7380 +    var RAND = Math.random;
 27.7381 +
 27.7382 +    function _randomFloat(min,max) {
 27.7383 +        return min + RAND() * (max - min);
 27.7384 +    }
 27.7385 +
 27.7386 +    function _randomInteger(min,max) {
 27.7387 +        return (min + RAND() * (max - min + 1)) >> 0;
 27.7388 +    }
 27.7389 +
 27.7390 +    /**
 27.7391 +     * Very simple uniform random number generator library wrapping Math.random().
 27.7392 +     *
 27.7393 +     * @class Random
 27.7394 +     * @static
 27.7395 +     */
 27.7396 +    var Random = {};
 27.7397 +
 27.7398 +    /**
 27.7399 +     * Get single random integer between min and max (inclusive), or array
 27.7400 +     *   of size dim if specified.
 27.7401 +     *
 27.7402 +     * @method integer
 27.7403 +     *
 27.7404 +     * @param {Number} min lower bound, default 0
 27.7405 +     * @param {Number} max upper bound, default 1
 27.7406 +     * @param {Number} dim (optional) dimension of output array, if specified
 27.7407 +     * @return {number | array<number>} random integer, or optionally, an array of random integers
 27.7408 +     */
 27.7409 +    Random.integer = function integer(min,max,dim) {
 27.7410 +        min = (min !== undefined) ? min : 0;
 27.7411 +        max = (max !== undefined) ? max : 1;
 27.7412 +        if (dim !== undefined) {
 27.7413 +            var result = [];
 27.7414 +            for (var i = 0; i < dim; i++) result.push(_randomInteger(min,max));
 27.7415 +            return result;
 27.7416 +        }
 27.7417 +        else return _randomInteger(min,max);
 27.7418 +    };
 27.7419 +
 27.7420 +    /**
 27.7421 +     * Get single random float between min and max (inclusive), or array
 27.7422 +     *   of size dim if specified
 27.7423 +     *
 27.7424 +     * @method range
 27.7425 +     *
 27.7426 +     * @param {Number} min lower bound, default 0
 27.7427 +     * @param {Number} max upper bound, default 1
 27.7428 +     * @param {Number} [dim] dimension of output array, if specified
 27.7429 +     * @return {Number} random float, or optionally an array
 27.7430 +     */
 27.7431 +    Random.range = function range(min,max,dim) {
 27.7432 +        min = (min !== undefined) ? min : 0;
 27.7433 +        max = (max !== undefined) ? max : 1;
 27.7434 +        if (dim !== undefined) {
 27.7435 +            var result = [];
 27.7436 +            for (var i = 0; i < dim; i++) result.push(_randomFloat(min,max));
 27.7437 +            return result;
 27.7438 +        }
 27.7439 +        else return _randomFloat(min,max);
 27.7440 +    };
 27.7441 +
 27.7442 +    /**
 27.7443 +     * Return random number among the set {-1 ,1}
 27.7444 +     *
 27.7445 +     * @method sign
 27.7446 +     *
 27.7447 +     * @param {Number} prob probability of returning 1, default 0.5
 27.7448 +     * @return {Number} random sign (-1 or 1)
 27.7449 +     */
 27.7450 +    Random.sign = function sign(prob) {
 27.7451 +        prob = (prob !== undefined) ? prob : 0.5;
 27.7452 +        return (RAND() < prob) ? 1 : -1;
 27.7453 +    };
 27.7454 +
 27.7455 +    /**
 27.7456 +     * Return random boolean value, true or false.
 27.7457 +     *
 27.7458 +     * @method bool
 27.7459 +     *
 27.7460 +     * @param {Number} prob probability of returning true, default 0.5
 27.7461 +     * @return {Boolean} random boolean
 27.7462 +     */
 27.7463 +    Random.bool = function bool(prob) {
 27.7464 +        prob = (prob !== undefined) ? prob : 0.5;
 27.7465 +        return RAND() < prob;
 27.7466 +    };
 27.7467 +
 27.7468 +    module.exports = Random;
 27.7469 +});
 27.7470 +
 27.7471 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.7472 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.7473 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.7474 + *
 27.7475 + * Owner: david@famo.us
 27.7476 + * @license MPL 2.0
 27.7477 + * @copyright Famous Industries, Inc. 2014
 27.7478 + */
 27.7479 +
 27.7480 +define('famous/events/EventArbiter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.7481 +    var EventHandler = require('famous/core/EventHandler');
 27.7482 +
 27.7483 +    /**
 27.7484 +     * A switch which wraps several event destinations and
 27.7485 +     *  redirects received events to at most one of them.
 27.7486 +     *  Setting the 'mode' of the object dictates which one
 27.7487 +     *  of these destinations will receive events.
 27.7488 +     *
 27.7489 +     * @class EventArbiter
 27.7490 +     * @constructor
 27.7491 +     *
 27.7492 +     * @param {Number | string} startMode initial setting of switch,
 27.7493 +     */
 27.7494 +    function EventArbiter(startMode) {
 27.7495 +        this.dispatchers = {};
 27.7496 +        this.currMode = undefined;
 27.7497 +        this.setMode(startMode);
 27.7498 +    }
 27.7499 +
 27.7500 +    /**
 27.7501 +     * Set switch to this mode, passing events to the corresponding
 27.7502 +     *   EventHandler.  If mode has changed, emits 'change' event,
 27.7503 +     *   emits 'unpipe' event to the old mode's handler, and emits 'pipe'
 27.7504 +     *   event to the new mode's handler.
 27.7505 +     *
 27.7506 +     * @method setMode
 27.7507 +     *
 27.7508 +     * @param {string | number} mode indicating which event handler to send to.
 27.7509 +     */
 27.7510 +    EventArbiter.prototype.setMode = function setMode(mode) {
 27.7511 +        if (mode !== this.currMode) {
 27.7512 +            var startMode = this.currMode;
 27.7513 +
 27.7514 +            if (this.dispatchers[this.currMode]) this.dispatchers[this.currMode].trigger('unpipe');
 27.7515 +            this.currMode = mode;
 27.7516 +            if (this.dispatchers[mode]) this.dispatchers[mode].emit('pipe');
 27.7517 +            this.emit('change', {from: startMode, to: mode});
 27.7518 +        }
 27.7519 +    };
 27.7520 +
 27.7521 +    /**
 27.7522 +     * Return the existing EventHandler corresponding to this
 27.7523 +     *   mode, creating one if it doesn't exist.
 27.7524 +     *
 27.7525 +     * @method forMode
 27.7526 +     *
 27.7527 +     * @param {string | number} mode mode to which this eventHandler corresponds
 27.7528 +     *
 27.7529 +     * @return {EventHandler} eventHandler corresponding to this mode
 27.7530 +     */
 27.7531 +    EventArbiter.prototype.forMode = function forMode(mode) {
 27.7532 +        if (!this.dispatchers[mode]) this.dispatchers[mode] = new EventHandler();
 27.7533 +        return this.dispatchers[mode];
 27.7534 +    };
 27.7535 +
 27.7536 +    /**
 27.7537 +     * Trigger an event, sending to currently selected handler, if
 27.7538 +     *   it is listening for provided 'type' key.
 27.7539 +     *
 27.7540 +     * @method emit
 27.7541 +     *
 27.7542 +     * @param {string} eventType event type key (for example, 'click')
 27.7543 +     * @param {Object} event event data
 27.7544 +     * @return {EventHandler} this
 27.7545 +     */
 27.7546 +    EventArbiter.prototype.emit = function emit(eventType, event) {
 27.7547 +        if (this.currMode === undefined) return false;
 27.7548 +        if (!event) event = {};
 27.7549 +        var dispatcher = this.dispatchers[this.currMode];
 27.7550 +        if (dispatcher) return dispatcher.trigger(eventType, event);
 27.7551 +    };
 27.7552 +
 27.7553 +    module.exports = EventArbiter;
 27.7554 +});
 27.7555 +
 27.7556 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.7557 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.7558 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.7559 + *
 27.7560 + * Owner: david@famo.us
 27.7561 + * @license MPL 2.0
 27.7562 + * @copyright Famous Industries, Inc. 2014
 27.7563 + */
 27.7564 +
 27.7565 +define('famous/events/EventFilter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.7566 +    var EventHandler = require('famous/core/EventHandler');
 27.7567 +
 27.7568 +    /**
 27.7569 +     * EventFilter regulates the broadcasting of events based on
 27.7570 +     *  a specified condition function of standard event type: function(type, data).
 27.7571 +     *
 27.7572 +     * @class EventFilter
 27.7573 +     * @constructor
 27.7574 +     *
 27.7575 +     * @param {function} condition function to determine whether or not
 27.7576 +     *    events are emitted.
 27.7577 +     */
 27.7578 +    function EventFilter(condition) {
 27.7579 +        EventHandler.call(this);
 27.7580 +        this._condition = condition;
 27.7581 +    }
 27.7582 +    EventFilter.prototype = Object.create(EventHandler.prototype);
 27.7583 +    EventFilter.prototype.constructor = EventFilter;
 27.7584 +
 27.7585 +    /**
 27.7586 +     * If filter condition is met, trigger an event, sending to all downstream handlers
 27.7587 +     *   listening for provided 'type' key.
 27.7588 +     *
 27.7589 +     * @method emit
 27.7590 +     *
 27.7591 +     * @param {string} type event type key (for example, 'click')
 27.7592 +     * @param {Object} data event data
 27.7593 +     * @return {EventHandler} this
 27.7594 +     */
 27.7595 +    EventFilter.prototype.emit = function emit(type, data) {
 27.7596 +        if (this._condition(type, data))
 27.7597 +            return EventHandler.prototype.emit.apply(this, arguments);
 27.7598 +    };
 27.7599 +
 27.7600 +    /**
 27.7601 +     * An alias of emit. Trigger determines whether to send
 27.7602 +     *  events based on the return value of it's condition function
 27.7603 +     *  when passed the event type and associated data.
 27.7604 +     *
 27.7605 +     * @method trigger
 27.7606 +     * @param {string} type name of the event
 27.7607 +     * @param {object} data associated data
 27.7608 +     */
 27.7609 +    EventFilter.prototype.trigger = EventFilter.prototype.emit;
 27.7610 +
 27.7611 +    module.exports = EventFilter;
 27.7612 +});
 27.7613 +
 27.7614 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.7615 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.7616 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.7617 + *
 27.7618 + * Owner: david@famo.us
 27.7619 + * @license MPL 2.0
 27.7620 + * @copyright Famous Industries, Inc. 2014
 27.7621 + */
 27.7622 +
 27.7623 +define('famous/events/EventMapper',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.7624 +    var EventHandler = require('famous/core/EventHandler');
 27.7625 +
 27.7626 +    /**
 27.7627 +     * EventMapper routes events to various event destinations
 27.7628 +     *  based on custom logic.  The function signature is arbitrary.
 27.7629 +     *
 27.7630 +     * @class EventMapper
 27.7631 +     * @constructor
 27.7632 +     *
 27.7633 +     * @param {function} mappingFunction function to determine where
 27.7634 +     *  events are routed to.
 27.7635 +     */
 27.7636 +    function EventMapper(mappingFunction) {
 27.7637 +        EventHandler.call(this);
 27.7638 +        this._mappingFunction = mappingFunction;
 27.7639 +    }
 27.7640 +    EventMapper.prototype = Object.create(EventHandler.prototype);
 27.7641 +    EventMapper.prototype.constructor = EventMapper;
 27.7642 +
 27.7643 +    EventMapper.prototype.subscribe = null;
 27.7644 +    EventMapper.prototype.unsubscribe = null;
 27.7645 +
 27.7646 +    /**
 27.7647 +     * Trigger an event, sending to all mapped downstream handlers
 27.7648 +     *   listening for provided 'type' key.
 27.7649 +     *
 27.7650 +     * @method emit
 27.7651 +     *
 27.7652 +     * @param {string} type event type key (for example, 'click')
 27.7653 +     * @param {Object} data event data
 27.7654 +     * @return {EventHandler} this
 27.7655 +     */
 27.7656 +    EventMapper.prototype.emit = function emit(type, data) {
 27.7657 +        var target = this._mappingFunction.apply(this, arguments);
 27.7658 +        if (target && (target.emit instanceof Function)) target.emit(type, data);
 27.7659 +    };
 27.7660 +
 27.7661 +    /**
 27.7662 +     * Alias of emit.
 27.7663 +     * @method trigger
 27.7664 +     */
 27.7665 +    EventMapper.prototype.trigger = EventMapper.prototype.emit;
 27.7666 +
 27.7667 +    module.exports = EventMapper;
 27.7668 +});
 27.7669 +
 27.7670 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.7671 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.7672 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.7673 + *
 27.7674 + * @license MPL 2.0
 27.7675 + * @copyright Famous Industries, Inc. 2014
 27.7676 + */
 27.7677 +define('famous/physics/PhysicsEngine',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.7678 +    var EventHandler = require('famous/core/EventHandler');
 27.7679 +
 27.7680 +    /**
 27.7681 +     * The Physics Engine is responsible for mediating Bodies and their
 27.7682 +     * interaction with forces and constraints. The Physics Engine handles the
 27.7683 +     * logic of adding and removing bodies, updating their state of the over
 27.7684 +     * time.
 27.7685 +     *
 27.7686 +     * @class PhysicsEngine
 27.7687 +     * @constructor
 27.7688 +     * @param options {Object} options
 27.7689 +     */
 27.7690 +    function PhysicsEngine(options) {
 27.7691 +        this.options = Object.create(PhysicsEngine.DEFAULT_OPTIONS);
 27.7692 +        if (options) this.setOptions(options);
 27.7693 +
 27.7694 +        this._particles      = [];   //list of managed particles
 27.7695 +        this._bodies         = [];   //list of managed bodies
 27.7696 +        this._agents         = {};   //hash of managed agents
 27.7697 +        this._forces         = [];   //list of IDs of agents that are forces
 27.7698 +        this._constraints    = [];   //list of IDs of agents that are constraints
 27.7699 +
 27.7700 +        this._buffer         = 0.0;
 27.7701 +        this._prevTime       = now();
 27.7702 +        this._isSleeping     = false;
 27.7703 +        this._eventHandler   = null;
 27.7704 +        this._currAgentId    = 0;
 27.7705 +        this._hasBodies      = false;
 27.7706 +    }
 27.7707 +
 27.7708 +    var TIMESTEP = 17;
 27.7709 +    var MIN_TIME_STEP = 1000 / 120;
 27.7710 +    var MAX_TIME_STEP = 17;
 27.7711 +
 27.7712 +    /**
 27.7713 +     * @property PhysicsEngine.DEFAULT_OPTIONS
 27.7714 +     * @type Object
 27.7715 +     * @protected
 27.7716 +     * @static
 27.7717 +     */
 27.7718 +    PhysicsEngine.DEFAULT_OPTIONS = {
 27.7719 +
 27.7720 +        /**
 27.7721 +         * The number of iterations the engine takes to resolve constraints
 27.7722 +         * @attribute constraintSteps
 27.7723 +         * @type Number
 27.7724 +         */
 27.7725 +        constraintSteps : 1,
 27.7726 +
 27.7727 +        /**
 27.7728 +         * The energy threshold before the Engine stops updating
 27.7729 +         * @attribute sleepTolerance
 27.7730 +         * @type Number
 27.7731 +         */
 27.7732 +        sleepTolerance  : 1e-7
 27.7733 +    };
 27.7734 +
 27.7735 +    var now = (function() {
 27.7736 +        return Date.now;
 27.7737 +    })();
 27.7738 +
 27.7739 +    /**
 27.7740 +     * Options setter
 27.7741 +     * @method setOptions
 27.7742 +     * @param options {Object}
 27.7743 +     */
 27.7744 +    PhysicsEngine.prototype.setOptions = function setOptions(opts) {
 27.7745 +        for (var key in opts) if (this.options[key]) this.options[key] = opts[key];
 27.7746 +    };
 27.7747 +
 27.7748 +    /**
 27.7749 +     * Method to add a physics body to the engine. Necessary to update the
 27.7750 +     * body over time.
 27.7751 +     *
 27.7752 +     * @method addBody
 27.7753 +     * @param body {Body}
 27.7754 +     * @return body {Body}
 27.7755 +     */
 27.7756 +    PhysicsEngine.prototype.addBody = function addBody(body) {
 27.7757 +        body._engine = this;
 27.7758 +        if (body.isBody) {
 27.7759 +            this._bodies.push(body);
 27.7760 +            this._hasBodies = true;
 27.7761 +        }
 27.7762 +        else this._particles.push(body);
 27.7763 +        return body;
 27.7764 +    };
 27.7765 +
 27.7766 +    /**
 27.7767 +     * Remove a body from the engine. Detaches body from all forces and
 27.7768 +     * constraints.
 27.7769 +     *
 27.7770 +     * @method removeBody
 27.7771 +     * @param body {Body}
 27.7772 +     */
 27.7773 +    PhysicsEngine.prototype.removeBody = function removeBody(body) {
 27.7774 +        var array = (body.isBody) ? this._bodies : this._particles;
 27.7775 +        var index = array.indexOf(body);
 27.7776 +        if (index > -1) {
 27.7777 +            for (var i = 0; i < Object.keys(this._agents).length; i++) this.detachFrom(i, body);
 27.7778 +            array.splice(index,1);
 27.7779 +        }
 27.7780 +        if (this.getBodies().length === 0) this._hasBodies = false;
 27.7781 +    };
 27.7782 +
 27.7783 +    function _mapAgentArray(agent) {
 27.7784 +        if (agent.applyForce)      return this._forces;
 27.7785 +        if (agent.applyConstraint) return this._constraints;
 27.7786 +    }
 27.7787 +
 27.7788 +    function _attachOne(agent, targets, source) {
 27.7789 +        if (targets === undefined) targets = this.getParticlesAndBodies();
 27.7790 +        if (!(targets instanceof Array)) targets = [targets];
 27.7791 +
 27.7792 +        this._agents[this._currAgentId] = {
 27.7793 +            agent   : agent,
 27.7794 +            targets : targets,
 27.7795 +            source  : source
 27.7796 +        };
 27.7797 +
 27.7798 +        _mapAgentArray.call(this, agent).push(this._currAgentId);
 27.7799 +        return this._currAgentId++;
 27.7800 +    }
 27.7801 +
 27.7802 +    /**
 27.7803 +     * Attaches a force or constraint to a Body. Returns an AgentId of the
 27.7804 +     * attached agent which can be used to detach the agent.
 27.7805 +     *
 27.7806 +     * @method attach
 27.7807 +     * @param agent {Agent|Array.Agent} A force, constraint, or array of them.
 27.7808 +     * @param [targets=All] {Body|Array.Body} The Body or Bodies affected by the agent
 27.7809 +     * @param [source] {Body} The source of the agent
 27.7810 +     * @return AgentId {Number}
 27.7811 +     */
 27.7812 +    PhysicsEngine.prototype.attach = function attach(agents, targets, source) {
 27.7813 +        if (agents instanceof Array) {
 27.7814 +            var agentIDs = [];
 27.7815 +            for (var i = 0; i < agents.length; i++)
 27.7816 +                agentIDs[i] = _attachOne.call(this, agents[i], targets, source);
 27.7817 +            return agentIDs;
 27.7818 +        }
 27.7819 +        else return _attachOne.call(this, agents, targets, source);
 27.7820 +    };
 27.7821 +
 27.7822 +    /**
 27.7823 +     * Append a body to the targets of a previously defined physics agent.
 27.7824 +     *
 27.7825 +     * @method attachTo
 27.7826 +     * @param agentID {AgentId} The agentId of a previously defined agent
 27.7827 +     * @param target {Body} The Body affected by the agent
 27.7828 +     */
 27.7829 +    PhysicsEngine.prototype.attachTo = function attachTo(agentID, target) {
 27.7830 +        _getBoundAgent.call(this, agentID).targets.push(target);
 27.7831 +    };
 27.7832 +
 27.7833 +    /**
 27.7834 +     * Undoes PhysicsEngine.attach. Removes an agent and its associated
 27.7835 +     * effect on its affected Bodies.
 27.7836 +     *
 27.7837 +     * @method detach
 27.7838 +     * @param agentID {AgentId} The agentId of a previously defined agent
 27.7839 +     */
 27.7840 +    PhysicsEngine.prototype.detach = function detach(id) {
 27.7841 +        // detach from forces/constraints array
 27.7842 +        var agent = this.getAgent(id);
 27.7843 +        var agentArray = _mapAgentArray.call(this, agent);
 27.7844 +        var index = agentArray.indexOf(id);
 27.7845 +        agentArray.splice(index,1);
 27.7846 +
 27.7847 +        // detach agents array
 27.7848 +        delete this._agents[id];
 27.7849 +    };
 27.7850 +
 27.7851 +    /**
 27.7852 +     * Remove a single Body from a previously defined agent.
 27.7853 +     *
 27.7854 +     * @method detach
 27.7855 +     * @param agentID {AgentId} The agentId of a previously defined agent
 27.7856 +     * @param target {Body} The body to remove from the agent
 27.7857 +     */
 27.7858 +    PhysicsEngine.prototype.detachFrom = function detachFrom(id, target) {
 27.7859 +        var boundAgent = _getBoundAgent.call(this, id);
 27.7860 +        if (boundAgent.source === target) this.detach(id);
 27.7861 +        else {
 27.7862 +            var targets = boundAgent.targets;
 27.7863 +            var index = targets.indexOf(target);
 27.7864 +            if (index > -1) targets.splice(index,1);
 27.7865 +        }
 27.7866 +    };
 27.7867 +
 27.7868 +    /**
 27.7869 +     * A convenience method to give the Physics Engine a clean slate of
 27.7870 +     * agents. Preserves all added Body objects.
 27.7871 +     *
 27.7872 +     * @method detachAll
 27.7873 +     */
 27.7874 +    PhysicsEngine.prototype.detachAll = function detachAll() {
 27.7875 +        this._agents        = {};
 27.7876 +        this._forces        = [];
 27.7877 +        this._constraints   = [];
 27.7878 +        this._currAgentId   = 0;
 27.7879 +    };
 27.7880 +
 27.7881 +    function _getBoundAgent(id) {
 27.7882 +        return this._agents[id];
 27.7883 +    }
 27.7884 +
 27.7885 +    /**
 27.7886 +     * Returns the corresponding agent given its agentId.
 27.7887 +     *
 27.7888 +     * @method getAgent
 27.7889 +     * @param id {AgentId}
 27.7890 +     */
 27.7891 +    PhysicsEngine.prototype.getAgent = function getAgent(id) {
 27.7892 +        return _getBoundAgent.call(this, id).agent;
 27.7893 +    };
 27.7894 +
 27.7895 +    /**
 27.7896 +     * Returns all particles that are currently managed by the Physics Engine.
 27.7897 +     *
 27.7898 +     * @method getParticles
 27.7899 +     * @return particles {Array.Particles}
 27.7900 +     */
 27.7901 +    PhysicsEngine.prototype.getParticles = function getParticles() {
 27.7902 +        return this._particles;
 27.7903 +    };
 27.7904 +
 27.7905 +    /**
 27.7906 +     * Returns all bodies, except particles, that are currently managed by the Physics Engine.
 27.7907 +     *
 27.7908 +     * @method getBodies
 27.7909 +     * @return bodies {Array.Bodies}
 27.7910 +     */
 27.7911 +    PhysicsEngine.prototype.getBodies = function getBodies() {
 27.7912 +        return this._bodies;
 27.7913 +    };
 27.7914 +
 27.7915 +    /**
 27.7916 +     * Returns all bodies that are currently managed by the Physics Engine.
 27.7917 +     *
 27.7918 +     * @method getBodies
 27.7919 +     * @return bodies {Array.Bodies}
 27.7920 +     */
 27.7921 +    PhysicsEngine.prototype.getParticlesAndBodies = function getParticlesAndBodies() {
 27.7922 +        return this.getParticles().concat(this.getBodies());
 27.7923 +    };
 27.7924 +
 27.7925 +    /**
 27.7926 +     * Iterates over every Particle and applies a function whose first
 27.7927 +     * argument is the Particle
 27.7928 +     *
 27.7929 +     * @method forEachParticle
 27.7930 +     * @param fn {Function} Function to iterate over
 27.7931 +     * @param [dt] {Number} Delta time
 27.7932 +     */
 27.7933 +    PhysicsEngine.prototype.forEachParticle = function forEachParticle(fn, dt) {
 27.7934 +        var particles = this.getParticles();
 27.7935 +        for (var index = 0, len = particles.length; index < len; index++)
 27.7936 +            fn.call(this, particles[index], dt);
 27.7937 +    };
 27.7938 +
 27.7939 +    /**
 27.7940 +     * Iterates over every Body that isn't a Particle and applies
 27.7941 +     * a function whose first argument is the Body
 27.7942 +     *
 27.7943 +     * @method forEachBody
 27.7944 +     * @param fn {Function} Function to iterate over
 27.7945 +     * @param [dt] {Number} Delta time
 27.7946 +     */
 27.7947 +    PhysicsEngine.prototype.forEachBody = function forEachBody(fn, dt) {
 27.7948 +        if (!this._hasBodies) return;
 27.7949 +        var bodies = this.getBodies();
 27.7950 +        for (var index = 0, len = bodies.length; index < len; index++)
 27.7951 +            fn.call(this, bodies[index], dt);
 27.7952 +    };
 27.7953 +
 27.7954 +    /**
 27.7955 +     * Iterates over every Body and applies a function whose first
 27.7956 +     * argument is the Body
 27.7957 +     *
 27.7958 +     * @method forEach
 27.7959 +     * @param fn {Function} Function to iterate over
 27.7960 +     * @param [dt] {Number} Delta time
 27.7961 +     */
 27.7962 +    PhysicsEngine.prototype.forEach = function forEach(fn, dt) {
 27.7963 +        this.forEachParticle(fn, dt);
 27.7964 +        this.forEachBody(fn, dt);
 27.7965 +    };
 27.7966 +
 27.7967 +    function _updateForce(index) {
 27.7968 +        var boundAgent = _getBoundAgent.call(this, this._forces[index]);
 27.7969 +        boundAgent.agent.applyForce(boundAgent.targets, boundAgent.source);
 27.7970 +    }
 27.7971 +
 27.7972 +    function _updateForces() {
 27.7973 +        for (var index = this._forces.length - 1; index > -1; index--)
 27.7974 +            _updateForce.call(this, index);
 27.7975 +    }
 27.7976 +
 27.7977 +    function _updateConstraint(index, dt) {
 27.7978 +        var boundAgent = this._agents[this._constraints[index]];
 27.7979 +        return boundAgent.agent.applyConstraint(boundAgent.targets, boundAgent.source, dt);
 27.7980 +    }
 27.7981 +
 27.7982 +    function _updateConstraints(dt) {
 27.7983 +        var iteration = 0;
 27.7984 +        while (iteration < this.options.constraintSteps) {
 27.7985 +            for (var index = this._constraints.length - 1; index > -1; index--)
 27.7986 +                _updateConstraint.call(this, index, dt);
 27.7987 +            iteration++;
 27.7988 +        }
 27.7989 +    }
 27.7990 +
 27.7991 +    function _updateVelocities(particle, dt) {
 27.7992 +        particle.integrateVelocity(dt);
 27.7993 +    }
 27.7994 +
 27.7995 +    function _updateAngularVelocities(body, dt) {
 27.7996 +        body.integrateAngularMomentum(dt);
 27.7997 +        body.updateAngularVelocity();
 27.7998 +    }
 27.7999 +
 27.8000 +    function _updateOrientations(body, dt) {
 27.8001 +        body.integrateOrientation(dt);
 27.8002 +    }
 27.8003 +
 27.8004 +    function _updatePositions(particle, dt) {
 27.8005 +        particle.integratePosition(dt);
 27.8006 +        particle.emit('update', particle);
 27.8007 +    }
 27.8008 +
 27.8009 +    function _integrate(dt) {
 27.8010 +        _updateForces.call(this, dt);
 27.8011 +        this.forEach(_updateVelocities, dt);
 27.8012 +        this.forEachBody(_updateAngularVelocities, dt);
 27.8013 +        _updateConstraints.call(this, dt);
 27.8014 +        this.forEachBody(_updateOrientations, dt);
 27.8015 +        this.forEach(_updatePositions, dt);
 27.8016 +    }
 27.8017 +
 27.8018 +    function _getEnergyParticles() {
 27.8019 +        var energy = 0.0;
 27.8020 +        var particleEnergy = 0.0;
 27.8021 +        this.forEach(function(particle) {
 27.8022 +            particleEnergy = particle.getEnergy();
 27.8023 +            energy += particleEnergy;
 27.8024 +            if (particleEnergy < particle.sleepTolerance) particle.sleep();
 27.8025 +        });
 27.8026 +        return energy;
 27.8027 +    }
 27.8028 +
 27.8029 +    function _getEnergyForces() {
 27.8030 +        var energy = 0;
 27.8031 +        for (var index = this._forces.length - 1; index > -1; index--)
 27.8032 +            energy += this._forces[index].getEnergy() || 0.0;
 27.8033 +        return energy;
 27.8034 +    }
 27.8035 +
 27.8036 +    function _getEnergyConstraints() {
 27.8037 +        var energy = 0;
 27.8038 +        for (var index = this._constraints.length - 1; index > -1; index--)
 27.8039 +            energy += this._constraints[index].getEnergy() || 0.0;
 27.8040 +        return energy;
 27.8041 +    }
 27.8042 +
 27.8043 +    /**
 27.8044 +     * Calculates the kinetic energy of all Body objects and potential energy
 27.8045 +     * of all attached agents.
 27.8046 +     *
 27.8047 +     * TODO: implement.
 27.8048 +     * @method getEnergy
 27.8049 +     * @return energy {Number}
 27.8050 +     */
 27.8051 +    PhysicsEngine.prototype.getEnergy = function getEnergy() {
 27.8052 +        return _getEnergyParticles.call(this) + _getEnergyForces.call(this) + _getEnergyConstraints.call(this);
 27.8053 +    };
 27.8054 +
 27.8055 +    /**
 27.8056 +     * Updates all Body objects managed by the physics engine over the
 27.8057 +     * time duration since the last time step was called.
 27.8058 +     *
 27.8059 +     * @method step
 27.8060 +     */
 27.8061 +    PhysicsEngine.prototype.step = function step() {
 27.8062 +//        if (this.getEnergy() < this.options.sleepTolerance) {
 27.8063 +//            this.sleep();
 27.8064 +//            return;
 27.8065 +//        };
 27.8066 +
 27.8067 +        //set current frame's time
 27.8068 +        var currTime = now();
 27.8069 +
 27.8070 +        //milliseconds elapsed since last frame
 27.8071 +        var dtFrame = currTime - this._prevTime;
 27.8072 +
 27.8073 +        this._prevTime = currTime;
 27.8074 +
 27.8075 +        if (dtFrame < MIN_TIME_STEP) return;
 27.8076 +        if (dtFrame > MAX_TIME_STEP) dtFrame = MAX_TIME_STEP;
 27.8077 +
 27.8078 +        //robust integration
 27.8079 +//        this._buffer += dtFrame;
 27.8080 +//        while (this._buffer > this._timestep){
 27.8081 +//            _integrate.call(this, this._timestep);
 27.8082 +//            this._buffer -= this._timestep;
 27.8083 +//        };
 27.8084 +//        _integrate.call(this, this._buffer);
 27.8085 +//        this._buffer = 0.0;
 27.8086 +        _integrate.call(this, TIMESTEP);
 27.8087 +
 27.8088 +//        this.emit('update', this);
 27.8089 +    };
 27.8090 +
 27.8091 +    /**
 27.8092 +     * Tells whether the Physics Engine is sleeping or awake.
 27.8093 +     * @method isSleeping
 27.8094 +     * @return {Boolean}
 27.8095 +     */
 27.8096 +    PhysicsEngine.prototype.isSleeping = function isSleeping() {
 27.8097 +        return this._isSleeping;
 27.8098 +    };
 27.8099 +
 27.8100 +    /**
 27.8101 +     * Stops the Physics Engine from updating. Emits an 'end' event.
 27.8102 +     * @method sleep
 27.8103 +     */
 27.8104 +    PhysicsEngine.prototype.sleep = function sleep() {
 27.8105 +        this.emit('end', this);
 27.8106 +        this._isSleeping = true;
 27.8107 +    };
 27.8108 +
 27.8109 +    /**
 27.8110 +     * Starts the Physics Engine from updating. Emits an 'start' event.
 27.8111 +     * @method wake
 27.8112 +     */
 27.8113 +    PhysicsEngine.prototype.wake = function wake() {
 27.8114 +        this._prevTime = now();
 27.8115 +        this.emit('start', this);
 27.8116 +        this._isSleeping = false;
 27.8117 +    };
 27.8118 +
 27.8119 +    PhysicsEngine.prototype.emit = function emit(type, data) {
 27.8120 +        if (this._eventHandler === null) return;
 27.8121 +        this._eventHandler.emit(type, data);
 27.8122 +    };
 27.8123 +
 27.8124 +    PhysicsEngine.prototype.on = function on(event, fn) {
 27.8125 +        if (this._eventHandler === null) this._eventHandler = new EventHandler();
 27.8126 +        this._eventHandler.on(event, fn);
 27.8127 +    };
 27.8128 +
 27.8129 +    module.exports = PhysicsEngine;
 27.8130 +});
 27.8131 +
 27.8132 +define('famous/inputs/Accumulator',['require','exports','module','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) {
 27.8133 +    var EventHandler = require('famous/core/EventHandler');
 27.8134 +    var Transitionable = require('famous/transitions/Transitionable');
 27.8135 +
 27.8136 +    /**
 27.8137 +     * Accumulates differentials of event sources that emit a `delta`
 27.8138 +     *  attribute taking a Number or Array of Number types. The accumulated
 27.8139 +     *  value is stored in a getter/setter.
 27.8140 +     *
 27.8141 +     * @class Accumulator
 27.8142 +     * @constructor
 27.8143 +     * @param value {Number|Array|Transitionable}   Initializing value
 27.8144 +     * @param [eventName='update'] {String}         Name of update event
 27.8145 +     */
 27.8146 +    function Accumulator(value, eventName) {
 27.8147 +        if (eventName === undefined) eventName = 'update';
 27.8148 +
 27.8149 +        this._state = (value && value.get && value.set)
 27.8150 +            ? value
 27.8151 +            : new Transitionable(value || 0);
 27.8152 +
 27.8153 +        this._eventInput = new EventHandler();
 27.8154 +        EventHandler.setInputHandler(this, this._eventInput);
 27.8155 +
 27.8156 +        this._eventInput.on(eventName, _handleUpdate.bind(this));
 27.8157 +    }
 27.8158 +
 27.8159 +    function _handleUpdate(data) {
 27.8160 +        var delta = data.delta;
 27.8161 +        var state = this.get();
 27.8162 +
 27.8163 +        if (delta.constructor === state.constructor){
 27.8164 +            var newState = (delta instanceof Array)
 27.8165 +                ? [state[0] + delta[0], state[1] + delta[1]]
 27.8166 +                : state + delta;
 27.8167 +            this.set(newState);
 27.8168 +        }
 27.8169 +    }
 27.8170 +
 27.8171 +    /**
 27.8172 +     * Basic getter
 27.8173 +     *
 27.8174 +     * @method get
 27.8175 +     * @return {Number|Array} current value
 27.8176 +     */
 27.8177 +    Accumulator.prototype.get = function get() {
 27.8178 +        return this._state.get();
 27.8179 +    };
 27.8180 +
 27.8181 +    /**
 27.8182 +     * Basic setter
 27.8183 +     *
 27.8184 +     * @method set
 27.8185 +     * @param value {Number|Array} new value
 27.8186 +     */
 27.8187 +    Accumulator.prototype.set = function set(value) {
 27.8188 +        this._state.set(value);
 27.8189 +    };
 27.8190 +
 27.8191 +    module.exports = Accumulator;
 27.8192 +});
 27.8193 +
 27.8194 +define('famous/inputs/DesktopEmulationMode',['require','exports','module'],function(require, exports, module) {
 27.8195 +    var hasTouch = 'ontouchstart' in window;
 27.8196 +
 27.8197 +    function kill(type) {
 27.8198 +        window.addEventListener(type, function(event) {
 27.8199 +            event.stopPropagation();
 27.8200 +            return false;
 27.8201 +        }, true);
 27.8202 +    }
 27.8203 +
 27.8204 +    if (hasTouch) {
 27.8205 +        kill('mousedown');
 27.8206 +        kill('mousemove');
 27.8207 +        kill('mouseup');
 27.8208 +        kill('mouseleave');
 27.8209 +    }
 27.8210 +});
 27.8211 +
 27.8212 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8213 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8214 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8215 + *
 27.8216 + * Owner: mark@famo.us
 27.8217 + * @license MPL 2.0
 27.8218 + * @copyright Famous Industries, Inc. 2014
 27.8219 + */
 27.8220 +
 27.8221 +define('famous/inputs/FastClick',['require','exports','module'],function(require, exports, module) {
 27.8222 +    /**
 27.8223 +     * FastClick is an override shim which maps event pairs of
 27.8224 +     *   'touchstart' and 'touchend' which differ by less than a certain
 27.8225 +     *   threshold to the 'click' event.
 27.8226 +     *   This is used to speed up clicks on some browsers.
 27.8227 +     */
 27.8228 +    if (!window.CustomEvent) return;
 27.8229 +    var clickThreshold = 300;
 27.8230 +    var clickWindow = 500;
 27.8231 +    var potentialClicks = {};
 27.8232 +    var recentlyDispatched = {};
 27.8233 +    var _now = Date.now;
 27.8234 +
 27.8235 +    window.addEventListener('touchstart', function(event) {
 27.8236 +        var timestamp = _now();
 27.8237 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8238 +            var touch = event.changedTouches[i];
 27.8239 +            potentialClicks[touch.identifier] = timestamp;
 27.8240 +        }
 27.8241 +    });
 27.8242 +
 27.8243 +    window.addEventListener('touchmove', function(event) {
 27.8244 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8245 +            var touch = event.changedTouches[i];
 27.8246 +            delete potentialClicks[touch.identifier];
 27.8247 +        }
 27.8248 +    });
 27.8249 +
 27.8250 +    window.addEventListener('touchend', function(event) {
 27.8251 +        var currTime = _now();
 27.8252 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8253 +            var touch = event.changedTouches[i];
 27.8254 +            var startTime = potentialClicks[touch.identifier];
 27.8255 +            if (startTime && currTime - startTime < clickThreshold) {
 27.8256 +                var clickEvt = new window.CustomEvent('click', {
 27.8257 +                    'bubbles': true,
 27.8258 +                    'details': touch
 27.8259 +                });
 27.8260 +                recentlyDispatched[currTime] = event;
 27.8261 +                event.target.dispatchEvent(clickEvt);
 27.8262 +            }
 27.8263 +            delete potentialClicks[touch.identifier];
 27.8264 +        }
 27.8265 +    });
 27.8266 +
 27.8267 +    window.addEventListener('click', function(event) {
 27.8268 +        var currTime = _now();
 27.8269 +        for (var i in recentlyDispatched) {
 27.8270 +            var previousEvent = recentlyDispatched[i];
 27.8271 +            if (currTime - i < clickWindow) {
 27.8272 +                if (event instanceof window.MouseEvent && event.target === previousEvent.target) event.stopPropagation();
 27.8273 +            }
 27.8274 +            else delete recentlyDispatched[i];
 27.8275 +        }
 27.8276 +    }, true);
 27.8277 +});
 27.8278 +
 27.8279 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8280 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8281 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8282 + *
 27.8283 + * Owner: mark@famo.us
 27.8284 + * @license MPL 2.0
 27.8285 + * @copyright Famous Industries, Inc. 2014
 27.8286 + */
 27.8287 +
 27.8288 +define('famous/inputs/TwoFingerSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.8289 +    var EventHandler = require('famous/core/EventHandler');
 27.8290 +
 27.8291 +    /**
 27.8292 +     * Helper to PinchSync, RotateSync, and ScaleSync.  Generalized handling of
 27.8293 +     *   two-finger touch events.
 27.8294 +     *   This class is meant to be overridden and not used directly.
 27.8295 +     *
 27.8296 +     * @class TwoFingerSync
 27.8297 +     * @constructor
 27.8298 +     */
 27.8299 +    function TwoFingerSync() {
 27.8300 +        this._eventInput = new EventHandler();
 27.8301 +        this._eventOutput = new EventHandler();
 27.8302 +
 27.8303 +        EventHandler.setInputHandler(this, this._eventInput);
 27.8304 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.8305 +
 27.8306 +        this.touchAEnabled = false;
 27.8307 +        this.touchAId = 0;
 27.8308 +        this.posA = null;
 27.8309 +        this.timestampA = 0;
 27.8310 +        this.touchBEnabled = false;
 27.8311 +        this.touchBId = 0;
 27.8312 +        this.posB = null;
 27.8313 +        this.timestampB = 0;
 27.8314 +
 27.8315 +        this._eventInput.on('touchstart', this.handleStart.bind(this));
 27.8316 +        this._eventInput.on('touchmove', this.handleMove.bind(this));
 27.8317 +        this._eventInput.on('touchend', this.handleEnd.bind(this));
 27.8318 +        this._eventInput.on('touchcancel', this.handleEnd.bind(this));
 27.8319 +    }
 27.8320 +
 27.8321 +    TwoFingerSync.calculateAngle = function(posA, posB) {
 27.8322 +        var diffX = posB[0] - posA[0];
 27.8323 +        var diffY = posB[1] - posA[1];
 27.8324 +        return Math.atan2(diffY, diffX);
 27.8325 +    };
 27.8326 +
 27.8327 +    TwoFingerSync.calculateDistance = function(posA, posB) {
 27.8328 +        var diffX = posB[0] - posA[0];
 27.8329 +        var diffY = posB[1] - posA[1];
 27.8330 +        return Math.sqrt(diffX * diffX + diffY * diffY);
 27.8331 +    };
 27.8332 +
 27.8333 +    TwoFingerSync.calculateCenter = function(posA, posB) {
 27.8334 +        return [(posA[0] + posB[0]) / 2.0, (posA[1] + posB[1]) / 2.0];
 27.8335 +    };
 27.8336 +
 27.8337 +    var _now = Date.now;
 27.8338 +
 27.8339 +    // private
 27.8340 +    TwoFingerSync.prototype.handleStart = function handleStart(event) {
 27.8341 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8342 +            var touch = event.changedTouches[i];
 27.8343 +            if (!this.touchAEnabled) {
 27.8344 +                this.touchAId = touch.identifier;
 27.8345 +                this.touchAEnabled = true;
 27.8346 +                this.posA = [touch.pageX, touch.pageY];
 27.8347 +                this.timestampA = _now();
 27.8348 +            }
 27.8349 +            else if (!this.touchBEnabled) {
 27.8350 +                this.touchBId = touch.identifier;
 27.8351 +                this.touchBEnabled = true;
 27.8352 +                this.posB = [touch.pageX, touch.pageY];
 27.8353 +                this.timestampB = _now();
 27.8354 +                this._startUpdate(event);
 27.8355 +            }
 27.8356 +        }
 27.8357 +    };
 27.8358 +
 27.8359 +    // private
 27.8360 +    TwoFingerSync.prototype.handleMove = function handleMove(event) {
 27.8361 +        if (!(this.touchAEnabled && this.touchBEnabled)) return;
 27.8362 +        var prevTimeA = this.timestampA;
 27.8363 +        var prevTimeB = this.timestampB;
 27.8364 +        var diffTime;
 27.8365 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8366 +            var touch = event.changedTouches[i];
 27.8367 +            if (touch.identifier === this.touchAId) {
 27.8368 +                this.posA = [touch.pageX, touch.pageY];
 27.8369 +                this.timestampA = _now();
 27.8370 +                diffTime = this.timestampA - prevTimeA;
 27.8371 +            }
 27.8372 +            else if (touch.identifier === this.touchBId) {
 27.8373 +                this.posB = [touch.pageX, touch.pageY];
 27.8374 +                this.timestampB = _now();
 27.8375 +                diffTime = this.timestampB - prevTimeB;
 27.8376 +            }
 27.8377 +        }
 27.8378 +        if (diffTime) this._moveUpdate(diffTime);
 27.8379 +    };
 27.8380 +
 27.8381 +    // private
 27.8382 +    TwoFingerSync.prototype.handleEnd = function handleEnd(event) {
 27.8383 +        for (var i = 0; i < event.changedTouches.length; i++) {
 27.8384 +            var touch = event.changedTouches[i];
 27.8385 +            if (touch.identifier === this.touchAId || touch.identifier === this.touchBId) {
 27.8386 +                if (this.touchAEnabled && this.touchBEnabled) {
 27.8387 +                    this._eventOutput.emit('end', {
 27.8388 +                        touches : [this.touchAId, this.touchBId],
 27.8389 +                        angle   : this._angle
 27.8390 +                    });
 27.8391 +                }
 27.8392 +                this.touchAEnabled = false;
 27.8393 +                this.touchAId = 0;
 27.8394 +                this.touchBEnabled = false;
 27.8395 +                this.touchBId = 0;
 27.8396 +            }
 27.8397 +        }
 27.8398 +    };
 27.8399 +
 27.8400 +    module.exports = TwoFingerSync;
 27.8401 +});
 27.8402 +
 27.8403 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8404 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8405 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8406 + *
 27.8407 + * Owner: mark@famo.us
 27.8408 + * @license MPL 2.0
 27.8409 + * @copyright Famous Industries, Inc. 2014
 27.8410 + */
 27.8411 +
 27.8412 +define('famous/inputs/PinchSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 27.8413 +    var TwoFingerSync = require('./TwoFingerSync');
 27.8414 +
 27.8415 +    /**
 27.8416 +     * Handles piped in two-finger touch events to change position via pinching / expanding.
 27.8417 +     *   Emits 'start', 'update' and 'end' events with
 27.8418 +     *   position, velocity, touch ids, and distance between fingers.
 27.8419 +     *
 27.8420 +     * @class PinchSync
 27.8421 +     * @extends TwoFingerSync
 27.8422 +     * @constructor
 27.8423 +     * @param {Object} options default options overrides
 27.8424 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8425 +     */
 27.8426 +    function PinchSync(options) {
 27.8427 +        TwoFingerSync.call(this);
 27.8428 +
 27.8429 +        this.options = Object.create(PinchSync.DEFAULT_OPTIONS);
 27.8430 +        if (options) this.setOptions(options);
 27.8431 +
 27.8432 +        this._displacement = 0;
 27.8433 +        this._previousDistance = 0;
 27.8434 +    }
 27.8435 +
 27.8436 +    PinchSync.prototype = Object.create(TwoFingerSync.prototype);
 27.8437 +    PinchSync.prototype.constructor = PinchSync;
 27.8438 +
 27.8439 +    PinchSync.DEFAULT_OPTIONS = {
 27.8440 +        scale : 1
 27.8441 +    };
 27.8442 +
 27.8443 +    PinchSync.prototype._startUpdate = function _startUpdate(event) {
 27.8444 +        this._previousDistance = TwoFingerSync.calculateDistance(this.posA, this.posB);
 27.8445 +        this._displacement = 0;
 27.8446 +
 27.8447 +        this._eventOutput.emit('start', {
 27.8448 +            count: event.touches.length,
 27.8449 +            touches: [this.touchAId, this.touchBId],
 27.8450 +            distance: this._dist,
 27.8451 +            center: TwoFingerSync.calculateCenter(this.posA, this.posB)
 27.8452 +        });
 27.8453 +    };
 27.8454 +
 27.8455 +    PinchSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 27.8456 +        var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 27.8457 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 27.8458 +
 27.8459 +        var scale = this.options.scale;
 27.8460 +        var delta = scale * (currDist - this._previousDistance);
 27.8461 +        var velocity = delta / diffTime;
 27.8462 +
 27.8463 +        this._previousDistance = currDist;
 27.8464 +        this._displacement += delta;
 27.8465 +
 27.8466 +        this._eventOutput.emit('update', {
 27.8467 +            delta : delta,
 27.8468 +            velocity: velocity,
 27.8469 +            distance: currDist,
 27.8470 +            displacement: this._displacement,
 27.8471 +            center: center,
 27.8472 +            touches: [this.touchAId, this.touchBId]
 27.8473 +        });
 27.8474 +    };
 27.8475 +
 27.8476 +    /**
 27.8477 +     * Return entire options dictionary, including defaults.
 27.8478 +     *
 27.8479 +     * @method getOptions
 27.8480 +     * @return {Object} configuration options
 27.8481 +     */
 27.8482 +    PinchSync.prototype.getOptions = function getOptions() {
 27.8483 +        return this.options;
 27.8484 +    };
 27.8485 +
 27.8486 +    /**
 27.8487 +     * Set internal options, overriding any default options
 27.8488 +     *
 27.8489 +     * @method setOptions
 27.8490 +     *
 27.8491 +     * @param {Object} [options] overrides of default options
 27.8492 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8493 +     */
 27.8494 +    PinchSync.prototype.setOptions = function setOptions(options) {
 27.8495 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.8496 +    };
 27.8497 +
 27.8498 +    module.exports = PinchSync;
 27.8499 +});
 27.8500 +
 27.8501 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8502 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8503 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8504 + *
 27.8505 + * Owner: mark@famo.us
 27.8506 + * @license MPL 2.0
 27.8507 + * @copyright Famous Industries, Inc. 2014
 27.8508 + */
 27.8509 +
 27.8510 +define('famous/inputs/RotateSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 27.8511 +    var TwoFingerSync = require('./TwoFingerSync');
 27.8512 +
 27.8513 +    /**
 27.8514 +     * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding.
 27.8515 +     *   Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, and angle.
 27.8516 +     *   Useful for determining a rotation factor from initial two-finger touch.
 27.8517 +     *
 27.8518 +     * @class RotateSync
 27.8519 +     * @extends TwoFingerSync
 27.8520 +     * @constructor
 27.8521 +     * @param {Object} options default options overrides
 27.8522 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8523 +     */
 27.8524 +    function RotateSync(options) {
 27.8525 +        TwoFingerSync.call(this);
 27.8526 +
 27.8527 +        this.options = Object.create(RotateSync.DEFAULT_OPTIONS);
 27.8528 +        if (options) this.setOptions(options);
 27.8529 +
 27.8530 +        this._angle = 0;
 27.8531 +        this._previousAngle = 0;
 27.8532 +    }
 27.8533 +
 27.8534 +    RotateSync.prototype = Object.create(TwoFingerSync.prototype);
 27.8535 +    RotateSync.prototype.constructor = RotateSync;
 27.8536 +
 27.8537 +    RotateSync.DEFAULT_OPTIONS = {
 27.8538 +        scale : 1
 27.8539 +    };
 27.8540 +
 27.8541 +    RotateSync.prototype._startUpdate = function _startUpdate(event) {
 27.8542 +        this._angle = 0;
 27.8543 +        this._previousAngle = TwoFingerSync.calculateAngle(this.posA, this.posB);
 27.8544 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 27.8545 +        this._eventOutput.emit('start', {
 27.8546 +            count: event.touches.length,
 27.8547 +            angle: this._angle,
 27.8548 +            center: center,
 27.8549 +            touches: [this.touchAId, this.touchBId]
 27.8550 +        });
 27.8551 +    };
 27.8552 +
 27.8553 +    RotateSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 27.8554 +        var scale = this.options.scale;
 27.8555 +
 27.8556 +        var currAngle = TwoFingerSync.calculateAngle(this.posA, this.posB);
 27.8557 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 27.8558 +
 27.8559 +        var diffTheta = scale * (currAngle - this._previousAngle);
 27.8560 +        var velTheta = diffTheta / diffTime;
 27.8561 +
 27.8562 +        this._angle += diffTheta;
 27.8563 +
 27.8564 +        this._eventOutput.emit('update', {
 27.8565 +            delta : diffTheta,
 27.8566 +            velocity: velTheta,
 27.8567 +            angle: this._angle,
 27.8568 +            center: center,
 27.8569 +            touches: [this.touchAId, this.touchBId]
 27.8570 +        });
 27.8571 +
 27.8572 +        this._previousAngle = currAngle;
 27.8573 +    };
 27.8574 +
 27.8575 +    /**
 27.8576 +     * Return entire options dictionary, including defaults.
 27.8577 +     *
 27.8578 +     * @method getOptions
 27.8579 +     * @return {Object} configuration options
 27.8580 +     */
 27.8581 +    RotateSync.prototype.getOptions = function getOptions() {
 27.8582 +        return this.options;
 27.8583 +    };
 27.8584 +
 27.8585 +    /**
 27.8586 +     * Set internal options, overriding any default options
 27.8587 +     *
 27.8588 +     * @method setOptions
 27.8589 +     *
 27.8590 +     * @param {Object} [options] overrides of default options
 27.8591 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8592 +     */
 27.8593 +    RotateSync.prototype.setOptions = function setOptions(options) {
 27.8594 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.8595 +    };
 27.8596 +
 27.8597 +    module.exports = RotateSync;
 27.8598 +});
 27.8599 +
 27.8600 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8601 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8602 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8603 + *
 27.8604 + * Owner: mark@famo.us
 27.8605 + * @license MPL 2.0
 27.8606 + * @copyright Famous Industries, Inc. 2014
 27.8607 + */
 27.8608 +
 27.8609 +define('famous/inputs/ScaleSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 27.8610 +    var TwoFingerSync = require('./TwoFingerSync');
 27.8611 +
 27.8612 +    /**
 27.8613 +     * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding.
 27.8614 +     *   Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, distance, and scale factor.
 27.8615 +     *   Useful for determining a scaling factor from initial two-finger touch.
 27.8616 +     *
 27.8617 +     * @class ScaleSync
 27.8618 +     * @extends TwoFingerSync
 27.8619 +     * @constructor
 27.8620 +     * @param {Object} options default options overrides
 27.8621 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8622 +     */
 27.8623 +    function ScaleSync(options) {
 27.8624 +        TwoFingerSync.call(this);
 27.8625 +
 27.8626 +        this.options = Object.create(ScaleSync.DEFAULT_OPTIONS);
 27.8627 +        if (options) this.setOptions(options);
 27.8628 +
 27.8629 +        this._scaleFactor = 1;
 27.8630 +        this._startDist = 0;
 27.8631 +        this._eventInput.on('pipe', _reset.bind(this));
 27.8632 +    }
 27.8633 +
 27.8634 +    ScaleSync.prototype = Object.create(TwoFingerSync.prototype);
 27.8635 +    ScaleSync.prototype.constructor = ScaleSync;
 27.8636 +
 27.8637 +    ScaleSync.DEFAULT_OPTIONS = {
 27.8638 +        scale : 1
 27.8639 +    };
 27.8640 +
 27.8641 +    function _reset() {
 27.8642 +        this.touchAId = undefined;
 27.8643 +        this.touchBId = undefined;
 27.8644 +    }
 27.8645 +
 27.8646 +    // handles initial touch of two fingers
 27.8647 +    ScaleSync.prototype._startUpdate = function _startUpdate(event) {
 27.8648 +        this._scaleFactor = 1;
 27.8649 +        this._startDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 27.8650 +        this._eventOutput.emit('start', {
 27.8651 +            count: event.touches.length,
 27.8652 +            touches: [this.touchAId, this.touchBId],
 27.8653 +            distance: this._startDist,
 27.8654 +            center: TwoFingerSync.calculateCenter(this.posA, this.posB)
 27.8655 +        });
 27.8656 +    };
 27.8657 +
 27.8658 +    // handles movement of two fingers
 27.8659 +    ScaleSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 27.8660 +        var scale = this.options.scale;
 27.8661 +
 27.8662 +        var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 27.8663 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 27.8664 +
 27.8665 +        var delta = (currDist - this._startDist) / this._startDist;
 27.8666 +        var newScaleFactor = Math.max(1 + scale * delta, 0);
 27.8667 +        var veloScale = (newScaleFactor - this._scaleFactor) / diffTime;
 27.8668 +
 27.8669 +        this._eventOutput.emit('update', {
 27.8670 +            delta : delta,
 27.8671 +            scale: newScaleFactor,
 27.8672 +            velocity: veloScale,
 27.8673 +            distance: currDist,
 27.8674 +            center : center,
 27.8675 +            touches: [this.touchAId, this.touchBId]
 27.8676 +        });
 27.8677 +
 27.8678 +        this._scaleFactor = newScaleFactor;
 27.8679 +    };
 27.8680 +
 27.8681 +    /**
 27.8682 +     * Return entire options dictionary, including defaults.
 27.8683 +     *
 27.8684 +     * @method getOptions
 27.8685 +     * @return {Object} configuration options
 27.8686 +     */
 27.8687 +    ScaleSync.prototype.getOptions = function getOptions() {
 27.8688 +        return this.options;
 27.8689 +    };
 27.8690 +
 27.8691 +    /**
 27.8692 +     * Set internal options, overriding any default options
 27.8693 +     *
 27.8694 +     * @method setOptions
 27.8695 +     *
 27.8696 +     * @param {Object} [options] overrides of default options
 27.8697 +     * @param {Number} [options.scale] scale velocity by this factor
 27.8698 +     */
 27.8699 +    ScaleSync.prototype.setOptions = function setOptions(options) {
 27.8700 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.8701 +    };
 27.8702 +
 27.8703 +    module.exports = ScaleSync;
 27.8704 +});
 27.8705 +
 27.8706 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8707 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8708 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8709 + *
 27.8710 + * Owner: mark@famo.us
 27.8711 + * @license MPL 2.0
 27.8712 + * @copyright Famous Industries, Inc. 2014
 27.8713 + */
 27.8714 +
 27.8715 +define('famous/inputs/ScrollSync',['require','exports','module','famous/core/EventHandler','famous/core/Engine'],function(require, exports, module) {
 27.8716 +    var EventHandler = require('famous/core/EventHandler');
 27.8717 +    var Engine = require('famous/core/Engine');
 27.8718 +
 27.8719 +    /**
 27.8720 +     * Handles piped in mousewheel events.
 27.8721 +     *   Emits 'start', 'update', and 'end' events with payloads including:
 27.8722 +     *   delta: change since last position,
 27.8723 +     *   position: accumulated deltas,
 27.8724 +     *   velocity: speed of change in pixels per ms,
 27.8725 +     *   slip: true (unused).
 27.8726 +     *
 27.8727 +     *   Can be used as delegate of GenericSync.
 27.8728 +     *
 27.8729 +     * @class ScrollSync
 27.8730 +     * @constructor
 27.8731 +     * @param {Object} [options] overrides of default options
 27.8732 +     * @param {Number} [options.direction] Pay attention to x changes (ScrollSync.DIRECTION_X),
 27.8733 +     *   y changes (ScrollSync.DIRECTION_Y) or both (undefined)
 27.8734 +     * @param {Number} [options.minimumEndSpeed] End speed calculation floors at this number, in pixels per ms
 27.8735 +     * @param {boolean} [options.rails] whether to snap position calculations to nearest axis
 27.8736 +     * @param {Number | Array.Number} [options.scale] scale outputs in by scalar or pair of scalars
 27.8737 +     * @param {Number} [options.stallTime] reset time for velocity calculation in ms
 27.8738 +     */
 27.8739 +    function ScrollSync(options) {
 27.8740 +        this.options = Object.create(ScrollSync.DEFAULT_OPTIONS);
 27.8741 +        if (options) this.setOptions(options);
 27.8742 +
 27.8743 +        this._payload = {
 27.8744 +            delta    : null,
 27.8745 +            position : null,
 27.8746 +            velocity : null,
 27.8747 +            slip     : true
 27.8748 +        };
 27.8749 +
 27.8750 +        this._eventInput = new EventHandler();
 27.8751 +        this._eventOutput = new EventHandler();
 27.8752 +
 27.8753 +        EventHandler.setInputHandler(this, this._eventInput);
 27.8754 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.8755 +
 27.8756 +        this._position = (this.options.direction === undefined) ? [0,0] : 0;
 27.8757 +        this._prevTime = undefined;
 27.8758 +        this._prevVel = undefined;
 27.8759 +        this._eventInput.on('mousewheel', _handleMove.bind(this));
 27.8760 +        this._eventInput.on('wheel', _handleMove.bind(this));
 27.8761 +        this._inProgress = false;
 27.8762 +        this._loopBound = false;
 27.8763 +    }
 27.8764 +
 27.8765 +    ScrollSync.DEFAULT_OPTIONS = {
 27.8766 +        direction: undefined,
 27.8767 +        minimumEndSpeed: Infinity,
 27.8768 +        rails: false,
 27.8769 +        scale: 1,
 27.8770 +        stallTime: 50,
 27.8771 +        lineHeight: 40
 27.8772 +    };
 27.8773 +
 27.8774 +    ScrollSync.DIRECTION_X = 0;
 27.8775 +    ScrollSync.DIRECTION_Y = 1;
 27.8776 +
 27.8777 +    var MINIMUM_TICK_TIME = 8;
 27.8778 +
 27.8779 +    var _now = Date.now;
 27.8780 +
 27.8781 +    function _newFrame() {
 27.8782 +        if (this._inProgress && (_now() - this._prevTime) > this.options.stallTime) {
 27.8783 +            this._position = (this.options.direction === undefined) ? [0,0] : 0;
 27.8784 +            this._inProgress = false;
 27.8785 +
 27.8786 +            var finalVel = (Math.abs(this._prevVel) >= this.options.minimumEndSpeed)
 27.8787 +                ? this._prevVel
 27.8788 +                : 0;
 27.8789 +
 27.8790 +            var payload = this._payload;
 27.8791 +            payload.position = this._position;
 27.8792 +            payload.velocity = finalVel;
 27.8793 +            payload.slip = true;
 27.8794 +
 27.8795 +            this._eventOutput.emit('end', payload);
 27.8796 +        }
 27.8797 +    }
 27.8798 +
 27.8799 +    function _handleMove(event) {
 27.8800 +        event.preventDefault();
 27.8801 +
 27.8802 +        if (!this._inProgress) {
 27.8803 +            this._inProgress = true;
 27.8804 +
 27.8805 +            payload = this._payload;
 27.8806 +            payload.slip = true;
 27.8807 +            payload.position = this._position;
 27.8808 +            payload.clientX = event.clientX;
 27.8809 +            payload.clientY = event.clientY;
 27.8810 +            payload.offsetX = event.offsetX;
 27.8811 +            payload.offsetY = event.offsetY;
 27.8812 +            this._eventOutput.emit('start', payload);
 27.8813 +            if (!this._loopBound) {
 27.8814 +                Engine.on('prerender', _newFrame.bind(this));
 27.8815 +                this._loopBound = true;
 27.8816 +            }
 27.8817 +        }
 27.8818 +
 27.8819 +        var currTime = _now();
 27.8820 +        var prevTime = this._prevTime || currTime;
 27.8821 +
 27.8822 +        var diffX = (event.wheelDeltaX !== undefined) ? event.wheelDeltaX : -event.deltaX;
 27.8823 +        var diffY = (event.wheelDeltaY !== undefined) ? event.wheelDeltaY : -event.deltaY;
 27.8824 +
 27.8825 +        if (event.deltaMode === 1) { // units in lines, not pixels
 27.8826 +            diffX *= this.options.lineHeight;
 27.8827 +            diffY *= this.options.lineHeight;
 27.8828 +        }
 27.8829 +
 27.8830 +        if (this.options.rails) {
 27.8831 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 27.8832 +            else diffX = 0;
 27.8833 +        }
 27.8834 +
 27.8835 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time
 27.8836 +
 27.8837 +        var velX = diffX / diffTime;
 27.8838 +        var velY = diffY / diffTime;
 27.8839 +
 27.8840 +        var scale = this.options.scale;
 27.8841 +        var nextVel;
 27.8842 +        var nextDelta;
 27.8843 +
 27.8844 +        if (this.options.direction === ScrollSync.DIRECTION_X) {
 27.8845 +            nextDelta = scale * diffX;
 27.8846 +            nextVel = scale * velX;
 27.8847 +            this._position += nextDelta;
 27.8848 +        }
 27.8849 +        else if (this.options.direction === ScrollSync.DIRECTION_Y) {
 27.8850 +            nextDelta = scale * diffY;
 27.8851 +            nextVel = scale * velY;
 27.8852 +            this._position += nextDelta;
 27.8853 +        }
 27.8854 +        else {
 27.8855 +            nextDelta = [scale * diffX, scale * diffY];
 27.8856 +            nextVel = [scale * velX, scale * velY];
 27.8857 +            this._position[0] += nextDelta[0];
 27.8858 +            this._position[1] += nextDelta[1];
 27.8859 +        }
 27.8860 +
 27.8861 +        var payload = this._payload;
 27.8862 +        payload.delta    = nextDelta;
 27.8863 +        payload.velocity = nextVel;
 27.8864 +        payload.position = this._position;
 27.8865 +        payload.slip     = true;
 27.8866 +
 27.8867 +        this._eventOutput.emit('update', payload);
 27.8868 +
 27.8869 +        this._prevTime = currTime;
 27.8870 +        this._prevVel = nextVel;
 27.8871 +    }
 27.8872 +
 27.8873 +    /**
 27.8874 +     * Return entire options dictionary, including defaults.
 27.8875 +     *
 27.8876 +     * @method getOptions
 27.8877 +     * @return {Object} configuration options
 27.8878 +     */
 27.8879 +    ScrollSync.prototype.getOptions = function getOptions() {
 27.8880 +        return this.options;
 27.8881 +    };
 27.8882 +
 27.8883 +    /**
 27.8884 +     * Set internal options, overriding any default options
 27.8885 +     *
 27.8886 +     * @method setOptions
 27.8887 +     *
 27.8888 +     * @param {Object} [options] overrides of default options
 27.8889 +     * @param {Number} [options.minimimEndSpeed] If final velocity smaller than this, round down to 0.
 27.8890 +     * @param {Number} [options.stallTime] ms of non-motion before 'end' emitted
 27.8891 +     * @param {Number} [options.rails] whether to constrain to nearest axis.
 27.8892 +     * @param {Number} [options.direction] ScrollSync.DIRECTION_X, DIRECTION_Y -
 27.8893 +     *    pay attention to one specific direction.
 27.8894 +     * @param {Number} [options.scale] constant factor to scale velocity output
 27.8895 +     */
 27.8896 +    ScrollSync.prototype.setOptions = function setOptions(options) {
 27.8897 +        if (options.direction !== undefined) this.options.direction = options.direction;
 27.8898 +        if (options.minimumEndSpeed !== undefined) this.options.minimumEndSpeed = options.minimumEndSpeed;
 27.8899 +        if (options.rails !== undefined) this.options.rails = options.rails;
 27.8900 +        if (options.scale !== undefined) this.options.scale = options.scale;
 27.8901 +        if (options.stallTime !== undefined) this.options.stallTime = options.stallTime;
 27.8902 +    };
 27.8903 +
 27.8904 +    module.exports = ScrollSync;
 27.8905 +});
 27.8906 +
 27.8907 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8908 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8909 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8910 + *
 27.8911 + * Owner: david@famo.us
 27.8912 + * @license MPL 2.0
 27.8913 + * @copyright Famous Industries, Inc. 2014
 27.8914 + */
 27.8915 +
 27.8916 +define('famous/transitions/CachedMap',['require','exports','module'],function(require, exports, module) {
 27.8917 +    /**
 27.8918 +     * A simple in-memory object cache.  Used as a helper for Views with
 27.8919 +     * provider functions.
 27.8920 +     * @class CachedMap
 27.8921 +     * @constructor
 27.8922 +     */
 27.8923 +    function CachedMap(mappingFunction) {
 27.8924 +        this._map = mappingFunction || null;
 27.8925 +        this._cachedOutput = null;
 27.8926 +        this._cachedInput = Number.NaN; //never valid as input
 27.8927 +    }
 27.8928 +
 27.8929 +    /**
 27.8930 +     * Creates a mapping function with a cache.
 27.8931 +     * This is the main entrypoint for this object.
 27.8932 +     * @static
 27.8933 +     * @method create
 27.8934 +     * @param {function} mappingFunction mapping
 27.8935 +     * @return {function} memoized mapping function
 27.8936 +     */
 27.8937 +    CachedMap.create = function create(mappingFunction) {
 27.8938 +        var instance = new CachedMap(mappingFunction);
 27.8939 +        return instance.get.bind(instance);
 27.8940 +    };
 27.8941 +
 27.8942 +    /**
 27.8943 +     * Retrieve items from cache or from mapping functin.
 27.8944 +     *
 27.8945 +     * @method get
 27.8946 +     * @param {Object} input input key
 27.8947 +     */
 27.8948 +    CachedMap.prototype.get = function get(input) {
 27.8949 +        if (input !== this._cachedInput) {
 27.8950 +            this._cachedInput = input;
 27.8951 +            this._cachedOutput = this._map(input);
 27.8952 +        }
 27.8953 +        return this._cachedOutput;
 27.8954 +    };
 27.8955 +
 27.8956 +    module.exports = CachedMap;
 27.8957 +});
 27.8958 +
 27.8959 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.8960 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.8961 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.8962 + *
 27.8963 + * Owner: david@famo.us
 27.8964 + * @license MPL 2.0
 27.8965 + * @copyright Famous Industries, Inc. 2014
 27.8966 + */
 27.8967 +
 27.8968 +define('famous/transitions/Easing',['require','exports','module'],function(require, exports, module) {
 27.8969 +
 27.8970 +    /*
 27.8971 +     * A library of curves which map an animation explicitly as a function of time.
 27.8972 +     *
 27.8973 +     * @class Easing
 27.8974 +     */
 27.8975 +    var Easing = {
 27.8976 +
 27.8977 +        /**
 27.8978 +         * @property inQuad
 27.8979 +         * @static
 27.8980 +         */
 27.8981 +        inQuad: function(t) {
 27.8982 +            return t*t;
 27.8983 +        },
 27.8984 +
 27.8985 +        /**
 27.8986 +         * @property outQuad
 27.8987 +         * @static
 27.8988 +         */
 27.8989 +        outQuad: function(t) {
 27.8990 +            return -(t-=1)*t+1;
 27.8991 +        },
 27.8992 +
 27.8993 +        /**
 27.8994 +         * @property inOutQuad
 27.8995 +         * @static
 27.8996 +         */
 27.8997 +        inOutQuad: function(t) {
 27.8998 +            if ((t/=.5) < 1) return .5*t*t;
 27.8999 +            return -.5*((--t)*(t-2) - 1);
 27.9000 +        },
 27.9001 +
 27.9002 +        /**
 27.9003 +         * @property inCubic
 27.9004 +         * @static
 27.9005 +         */
 27.9006 +        inCubic: function(t) {
 27.9007 +            return t*t*t;
 27.9008 +        },
 27.9009 +
 27.9010 +        /**
 27.9011 +         * @property outCubic
 27.9012 +         * @static
 27.9013 +         */
 27.9014 +        outCubic: function(t) {
 27.9015 +            return ((--t)*t*t + 1);
 27.9016 +        },
 27.9017 +
 27.9018 +        /**
 27.9019 +         * @property inOutCubic
 27.9020 +         * @static
 27.9021 +         */
 27.9022 +        inOutCubic: function(t) {
 27.9023 +            if ((t/=.5) < 1) return .5*t*t*t;
 27.9024 +            return .5*((t-=2)*t*t + 2);
 27.9025 +        },
 27.9026 +
 27.9027 +        /**
 27.9028 +         * @property inQuart
 27.9029 +         * @static
 27.9030 +         */
 27.9031 +        inQuart: function(t) {
 27.9032 +            return t*t*t*t;
 27.9033 +        },
 27.9034 +
 27.9035 +        /**
 27.9036 +         * @property outQuart
 27.9037 +         * @static
 27.9038 +         */
 27.9039 +        outQuart: function(t) {
 27.9040 +            return -((--t)*t*t*t - 1);
 27.9041 +        },
 27.9042 +
 27.9043 +        /**
 27.9044 +         * @property inOutQuart
 27.9045 +         * @static
 27.9046 +         */
 27.9047 +        inOutQuart: function(t) {
 27.9048 +            if ((t/=.5) < 1) return .5*t*t*t*t;
 27.9049 +            return -.5 * ((t-=2)*t*t*t - 2);
 27.9050 +        },
 27.9051 +
 27.9052 +        /**
 27.9053 +         * @property inQuint
 27.9054 +         * @static
 27.9055 +         */
 27.9056 +        inQuint: function(t) {
 27.9057 +            return t*t*t*t*t;
 27.9058 +        },
 27.9059 +
 27.9060 +        /**
 27.9061 +         * @property outQuint
 27.9062 +         * @static
 27.9063 +         */
 27.9064 +        outQuint: function(t) {
 27.9065 +            return ((--t)*t*t*t*t + 1);
 27.9066 +        },
 27.9067 +
 27.9068 +        /**
 27.9069 +         * @property inOutQuint
 27.9070 +         * @static
 27.9071 +         */
 27.9072 +        inOutQuint: function(t) {
 27.9073 +            if ((t/=.5) < 1) return .5*t*t*t*t*t;
 27.9074 +            return .5*((t-=2)*t*t*t*t + 2);
 27.9075 +        },
 27.9076 +
 27.9077 +        /**
 27.9078 +         * @property inSine
 27.9079 +         * @static
 27.9080 +         */
 27.9081 +        inSine: function(t) {
 27.9082 +            return -1.0*Math.cos(t * (Math.PI/2)) + 1.0;
 27.9083 +        },
 27.9084 +
 27.9085 +        /**
 27.9086 +         * @property outSine
 27.9087 +         * @static
 27.9088 +         */
 27.9089 +        outSine: function(t) {
 27.9090 +            return Math.sin(t * (Math.PI/2));
 27.9091 +        },
 27.9092 +
 27.9093 +        /**
 27.9094 +         * @property inOutSine
 27.9095 +         * @static
 27.9096 +         */
 27.9097 +        inOutSine: function(t) {
 27.9098 +            return -.5*(Math.cos(Math.PI*t) - 1);
 27.9099 +        },
 27.9100 +
 27.9101 +        /**
 27.9102 +         * @property inExpo
 27.9103 +         * @static
 27.9104 +         */
 27.9105 +        inExpo: function(t) {
 27.9106 +            return (t===0) ? 0.0 : Math.pow(2, 10 * (t - 1));
 27.9107 +        },
 27.9108 +
 27.9109 +        /**
 27.9110 +         * @property outExpo
 27.9111 +         * @static
 27.9112 +         */
 27.9113 +        outExpo: function(t) {
 27.9114 +            return (t===1.0) ? 1.0 : (-Math.pow(2, -10 * t) + 1);
 27.9115 +        },
 27.9116 +
 27.9117 +        /**
 27.9118 +         * @property inOutExpo
 27.9119 +         * @static
 27.9120 +         */
 27.9121 +        inOutExpo: function(t) {
 27.9122 +            if (t===0) return 0.0;
 27.9123 +            if (t===1.0) return 1.0;
 27.9124 +            if ((t/=.5) < 1) return .5 * Math.pow(2, 10 * (t - 1));
 27.9125 +            return .5 * (-Math.pow(2, -10 * --t) + 2);
 27.9126 +        },
 27.9127 +
 27.9128 +        /**
 27.9129 +         * @property inCirc
 27.9130 +         * @static
 27.9131 +         */
 27.9132 +        inCirc: function(t) {
 27.9133 +            return -(Math.sqrt(1 - t*t) - 1);
 27.9134 +        },
 27.9135 +
 27.9136 +        /**
 27.9137 +         * @property outCirc
 27.9138 +         * @static
 27.9139 +         */
 27.9140 +        outCirc: function(t) {
 27.9141 +            return Math.sqrt(1 - (--t)*t);
 27.9142 +        },
 27.9143 +
 27.9144 +        /**
 27.9145 +         * @property inOutCirc
 27.9146 +         * @static
 27.9147 +         */
 27.9148 +        inOutCirc: function(t) {
 27.9149 +            if ((t/=.5) < 1) return -.5 * (Math.sqrt(1 - t*t) - 1);
 27.9150 +            return .5 * (Math.sqrt(1 - (t-=2)*t) + 1);
 27.9151 +        },
 27.9152 +
 27.9153 +        /**
 27.9154 +         * @property inElastic
 27.9155 +         * @static
 27.9156 +         */
 27.9157 +        inElastic: function(t) {
 27.9158 +            var s=1.70158;var p=0;var a=1.0;
 27.9159 +            if (t===0) return 0.0;  if (t===1) return 1.0;  if (!p) p=.3;
 27.9160 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 27.9161 +            return -(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/ p));
 27.9162 +        },
 27.9163 +
 27.9164 +        /**
 27.9165 +         * @property outElastic
 27.9166 +         * @static
 27.9167 +         */
 27.9168 +        outElastic: function(t) {
 27.9169 +            var s=1.70158;var p=0;var a=1.0;
 27.9170 +            if (t===0) return 0.0;  if (t===1) return 1.0;  if (!p) p=.3;
 27.9171 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 27.9172 +            return a*Math.pow(2,-10*t) * Math.sin((t-s)*(2*Math.PI)/p) + 1.0;
 27.9173 +        },
 27.9174 +
 27.9175 +        /**
 27.9176 +         * @property inOutElastic
 27.9177 +         * @static
 27.9178 +         */
 27.9179 +        inOutElastic: function(t) {
 27.9180 +            var s=1.70158;var p=0;var a=1.0;
 27.9181 +            if (t===0) return 0.0;  if ((t/=.5)===2) return 1.0;  if (!p) p=(.3*1.5);
 27.9182 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 27.9183 +            if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p));
 27.9184 +            return a*Math.pow(2,-10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)*.5 + 1.0;
 27.9185 +        },
 27.9186 +
 27.9187 +        /**
 27.9188 +         * @property inBack
 27.9189 +         * @static
 27.9190 +         */
 27.9191 +        inBack: function(t, s) {
 27.9192 +            if (s === undefined) s = 1.70158;
 27.9193 +            return t*t*((s+1)*t - s);
 27.9194 +        },
 27.9195 +
 27.9196 +        /**
 27.9197 +         * @property outBack
 27.9198 +         * @static
 27.9199 +         */
 27.9200 +        outBack: function(t, s) {
 27.9201 +            if (s === undefined) s = 1.70158;
 27.9202 +            return ((--t)*t*((s+1)*t + s) + 1);
 27.9203 +        },
 27.9204 +
 27.9205 +        /**
 27.9206 +         * @property inOutBack
 27.9207 +         * @static
 27.9208 +         */
 27.9209 +        inOutBack: function(t, s) {
 27.9210 +            if (s === undefined) s = 1.70158;
 27.9211 +            if ((t/=.5) < 1) return .5*(t*t*(((s*=(1.525))+1)*t - s));
 27.9212 +            return .5*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2);
 27.9213 +        },
 27.9214 +
 27.9215 +        /**
 27.9216 +         * @property inBounce
 27.9217 +         * @static
 27.9218 +         */
 27.9219 +        inBounce: function(t) {
 27.9220 +            return 1.0 - Easing.outBounce(1.0-t);
 27.9221 +        },
 27.9222 +
 27.9223 +        /**
 27.9224 +         * @property outBounce
 27.9225 +         * @static
 27.9226 +         */
 27.9227 +        outBounce: function(t) {
 27.9228 +            if (t < (1/2.75)) {
 27.9229 +                return (7.5625*t*t);
 27.9230 +            } else if (t < (2/2.75)) {
 27.9231 +                return (7.5625*(t-=(1.5/2.75))*t + .75);
 27.9232 +            } else if (t < (2.5/2.75)) {
 27.9233 +                return (7.5625*(t-=(2.25/2.75))*t + .9375);
 27.9234 +            } else {
 27.9235 +                return (7.5625*(t-=(2.625/2.75))*t + .984375);
 27.9236 +            }
 27.9237 +        },
 27.9238 +
 27.9239 +        /**
 27.9240 +         * @property inOutBounce
 27.9241 +         * @static
 27.9242 +         */
 27.9243 +        inOutBounce: function(t) {
 27.9244 +            if (t < .5) return Easing.inBounce(t*2) * .5;
 27.9245 +            return Easing.outBounce(t*2-1.0) * .5 + .5;
 27.9246 +        }
 27.9247 +    };
 27.9248 +
 27.9249 +    module.exports = Easing;
 27.9250 +});
 27.9251 +
 27.9252 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.9253 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.9254 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.9255 + *
 27.9256 + * Owner: david@famo.us
 27.9257 + * @license MPL 2.0
 27.9258 + * @copyright Famous Industries, Inc. 2014
 27.9259 + */
 27.9260 +
 27.9261 +define('famous/physics/integrators/SymplecticEuler',['require','exports','module','famous/core/OptionsManager'],function(require, exports, module) {
 27.9262 +    var OptionsManager = require('famous/core/OptionsManager');
 27.9263 +
 27.9264 +    /**
 27.9265 +     * Ordinary Differential Equation (ODE) Integrator.
 27.9266 +     * Manages updating a physics body's state over time.
 27.9267 +     *
 27.9268 +     *  p = position, v = velocity, m = mass, f = force, dt = change in time
 27.9269 +     *
 27.9270 +     *      v <- v + dt * f / m
 27.9271 +     *      p <- p + dt * v
 27.9272 +     *
 27.9273 +     *  q = orientation, w = angular velocity, L = angular momentum
 27.9274 +     *
 27.9275 +     *      L <- L + dt * t
 27.9276 +     *      q <- q + dt/2 * q * w
 27.9277 +     *
 27.9278 +     * @class SymplecticEuler
 27.9279 +     * @constructor
 27.9280 +     * @param {Object} options Options to set
 27.9281 +     */
 27.9282 +    function SymplecticEuler(options) {
 27.9283 +        this.options = Object.create(SymplecticEuler.DEFAULT_OPTIONS);
 27.9284 +        this._optionsManager = new OptionsManager(this.options);
 27.9285 +
 27.9286 +        if (options) this.setOptions(options);
 27.9287 +    }
 27.9288 +
 27.9289 +    /**
 27.9290 +     * @property SymplecticEuler.DEFAULT_OPTIONS
 27.9291 +     * @type Object
 27.9292 +     * @protected
 27.9293 +     * @static
 27.9294 +     */
 27.9295 +    SymplecticEuler.DEFAULT_OPTIONS = {
 27.9296 +
 27.9297 +        /**
 27.9298 +         * The maximum velocity of a physics body
 27.9299 +         *      Range : [0, Infinity]
 27.9300 +         * @attribute velocityCap
 27.9301 +         * @type Number
 27.9302 +         */
 27.9303 +
 27.9304 +        velocityCap : undefined,
 27.9305 +
 27.9306 +        /**
 27.9307 +         * The maximum angular velocity of a physics body
 27.9308 +         *      Range : [0, Infinity]
 27.9309 +         * @attribute angularVelocityCap
 27.9310 +         * @type Number
 27.9311 +         */
 27.9312 +        angularVelocityCap : undefined
 27.9313 +    };
 27.9314 +
 27.9315 +    /*
 27.9316 +     * Setter for options
 27.9317 +     *
 27.9318 +     * @method setOptions
 27.9319 +     * @param {Object} options
 27.9320 +     */
 27.9321 +    SymplecticEuler.prototype.setOptions = function setOptions(options) {
 27.9322 +        this._optionsManager.patch(options);
 27.9323 +    };
 27.9324 +
 27.9325 +    /*
 27.9326 +     * Getter for options
 27.9327 +     *
 27.9328 +     * @method getOptions
 27.9329 +     * @return {Object} options
 27.9330 +     */
 27.9331 +    SymplecticEuler.prototype.getOptions = function getOptions() {
 27.9332 +        return this._optionsManager.value();
 27.9333 +    };
 27.9334 +
 27.9335 +    /*
 27.9336 +     * Updates the velocity of a physics body from its accumulated force.
 27.9337 +     *      v <- v + dt * f / m
 27.9338 +     *
 27.9339 +     * @method integrateVelocity
 27.9340 +     * @param {Body} physics body
 27.9341 +     * @param {Number} dt delta time
 27.9342 +     */
 27.9343 +    SymplecticEuler.prototype.integrateVelocity = function integrateVelocity(body, dt) {
 27.9344 +        var v = body.velocity;
 27.9345 +        var w = body.inverseMass;
 27.9346 +        var f = body.force;
 27.9347 +
 27.9348 +        if (f.isZero()) return;
 27.9349 +
 27.9350 +        v.add(f.mult(dt * w)).put(v);
 27.9351 +        f.clear();
 27.9352 +    };
 27.9353 +
 27.9354 +    /*
 27.9355 +     * Updates the position of a physics body from its velocity.
 27.9356 +     *      p <- p + dt * v
 27.9357 +     *
 27.9358 +     * @method integratePosition
 27.9359 +     * @param {Body} physics body
 27.9360 +     * @param {Number} dt delta time
 27.9361 +     */
 27.9362 +    SymplecticEuler.prototype.integratePosition = function integratePosition(body, dt) {
 27.9363 +        var p = body.position;
 27.9364 +        var v = body.velocity;
 27.9365 +
 27.9366 +        if (this.options.velocityCap) v.cap(this.options.velocityCap).put(v);
 27.9367 +        p.add(v.mult(dt)).put(p);
 27.9368 +    };
 27.9369 +
 27.9370 +    /*
 27.9371 +     * Updates the angular momentum of a physics body from its accumuled torque.
 27.9372 +     *      L <- L + dt * t
 27.9373 +     *
 27.9374 +     * @method integrateAngularMomentum
 27.9375 +     * @param {Body} physics body (except a particle)
 27.9376 +     * @param {Number} dt delta time
 27.9377 +     */
 27.9378 +    SymplecticEuler.prototype.integrateAngularMomentum = function integrateAngularMomentum(body, dt) {
 27.9379 +        var L = body.angularMomentum;
 27.9380 +        var t = body.torque;
 27.9381 +
 27.9382 +        if (t.isZero()) return;
 27.9383 +
 27.9384 +        if (this.options.angularVelocityCap) t.cap(this.options.angularVelocityCap).put(t);
 27.9385 +        L.add(t.mult(dt)).put(L);
 27.9386 +        t.clear();
 27.9387 +    };
 27.9388 +
 27.9389 +    /*
 27.9390 +     * Updates the orientation of a physics body from its angular velocity.
 27.9391 +     *      q <- q + dt/2 * q * w
 27.9392 +     *
 27.9393 +     * @method integrateOrientation
 27.9394 +     * @param {Body} physics body (except a particle)
 27.9395 +     * @param {Number} dt delta time
 27.9396 +     */
 27.9397 +    SymplecticEuler.prototype.integrateOrientation = function integrateOrientation(body, dt) {
 27.9398 +        var q = body.orientation;
 27.9399 +        var w = body.angularVelocity;
 27.9400 +
 27.9401 +        if (w.isZero()) return;
 27.9402 +        q.add(q.multiply(w).scalarMultiply(0.5 * dt)).put(q);
 27.9403 +//        q.normalize.put(q);
 27.9404 +    };
 27.9405 +
 27.9406 +    module.exports = SymplecticEuler;
 27.9407 +});
 27.9408 +
 27.9409 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.9410 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.9411 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.9412 + *
 27.9413 + * Owner: david@famo.us
 27.9414 + * @license MPL 2.0
 27.9415 + * @copyright Famous Industries, Inc. 2014
 27.9416 + */
 27.9417 +
 27.9418 +define('famous/physics/bodies/Particle',['require','exports','module','famous/math/Vector','famous/core/Transform','famous/core/EventHandler','../integrators/SymplecticEuler'],function(require, exports, module) {
 27.9419 +    var Vector = require('famous/math/Vector');
 27.9420 +    var Transform = require('famous/core/Transform');
 27.9421 +    var EventHandler = require('famous/core/EventHandler');
 27.9422 +    var Integrator = require('../integrators/SymplecticEuler');
 27.9423 +
 27.9424 +    /**
 27.9425 +     * A point body that is controlled by the Physics Engine. A particle has
 27.9426 +     *   position and velocity states that are updated by the Physics Engine.
 27.9427 +     *   Ultimately, a particle is a _special type of modifier, and can be added to
 27.9428 +     *   the Famous render tree like any other modifier.
 27.9429 +     *
 27.9430 +     * @constructor
 27.9431 +     * @class Particle
 27.9432 +     * @uses EventHandler
 27.9433 +     * @uses Modifier
 27.9434 +     * @extensionfor Body
 27.9435 +     * @param {Options} [options] An object of configurable options.
 27.9436 +     * @param {Array} [options.position] The position of the particle.
 27.9437 +     * @param {Array} [options.velocity] The velocity of the particle.
 27.9438 +     * @param {Number} [options.mass] The mass of the particle.
 27.9439 +     * @param {Hexadecimal} [options.axis] The axis a particle can move along. Can be bitwise ORed e.g., Particle.AXES.X, Particle.AXES.X | Particle.AXES.Y
 27.9440 +     *
 27.9441 +     */
 27.9442 +     function Particle(options) {
 27.9443 +        options = options || {};
 27.9444 +
 27.9445 +        // registers
 27.9446 +        this.position = new Vector();
 27.9447 +        this.velocity = new Vector();
 27.9448 +        this.force    = new Vector();
 27.9449 +
 27.9450 +        var defaults  = Particle.DEFAULT_OPTIONS;
 27.9451 +
 27.9452 +        // set vectors
 27.9453 +        this.setPosition(options.position || defaults.position);
 27.9454 +        this.setVelocity(options.velocity || defaults.velocity);
 27.9455 +        this.force.set(options.force || [0,0,0]);
 27.9456 +
 27.9457 +        // set scalars
 27.9458 +        this.mass = (options.mass !== undefined)
 27.9459 +            ? options.mass
 27.9460 +            : defaults.mass;
 27.9461 +
 27.9462 +        this.axis = (options.axis !== undefined)
 27.9463 +            ? options.axis
 27.9464 +            : defaults.axis;
 27.9465 +
 27.9466 +        this.inverseMass = 1 / this.mass;
 27.9467 +
 27.9468 +        // state variables
 27.9469 +        this._isSleeping     = false;
 27.9470 +        this._engine         = null;
 27.9471 +        this._eventOutput    = null;
 27.9472 +        this._positionGetter = null;
 27.9473 +
 27.9474 +        this.transform = Transform.identity.slice();
 27.9475 +
 27.9476 +        // cached _spec
 27.9477 +        this._spec = {
 27.9478 +            transform : this.transform,
 27.9479 +            target    : null
 27.9480 +        };
 27.9481 +    }
 27.9482 +
 27.9483 +    Particle.DEFAULT_OPTIONS = {
 27.9484 +        position : [0,0,0],
 27.9485 +        velocity : [0,0,0],
 27.9486 +        mass : 1,
 27.9487 +        axis : undefined
 27.9488 +    };
 27.9489 +
 27.9490 +    /**
 27.9491 +     * Kinetic energy threshold needed to update the body
 27.9492 +     *
 27.9493 +     * @property SLEEP_TOLERANCE
 27.9494 +     * @type Number
 27.9495 +     * @static
 27.9496 +     * @default 1e-7
 27.9497 +     */
 27.9498 +    Particle.SLEEP_TOLERANCE = 1e-7;
 27.9499 +
 27.9500 +    /**
 27.9501 +     * Axes by which a body can translate
 27.9502 +     *
 27.9503 +     * @property AXES
 27.9504 +     * @type Hexadecimal
 27.9505 +     * @static
 27.9506 +     * @default 1e-7
 27.9507 +     */
 27.9508 +    Particle.AXES = {
 27.9509 +        X : 0x00, // hexadecimal for 0
 27.9510 +        Y : 0x01, // hexadecimal for 1
 27.9511 +        Z : 0x02  // hexadecimal for 2
 27.9512 +    };
 27.9513 +
 27.9514 +    // Integrator for updating the particle's state
 27.9515 +    // TODO: make this a singleton
 27.9516 +    Particle.INTEGRATOR = new Integrator();
 27.9517 +
 27.9518 +    //Catalogue of outputted events
 27.9519 +    var _events = {
 27.9520 +        start  : 'start',
 27.9521 +        update : 'update',
 27.9522 +        end    : 'end'
 27.9523 +    };
 27.9524 +
 27.9525 +    // Cached timing function
 27.9526 +    var now = (function() {
 27.9527 +        return Date.now;
 27.9528 +    })();
 27.9529 +
 27.9530 +    /**
 27.9531 +     * Stops the particle from updating
 27.9532 +     * @method sleep
 27.9533 +     */
 27.9534 +    Particle.prototype.sleep = function sleep() {
 27.9535 +        if (this._isSleeping) return;
 27.9536 +        this.emit(_events.end, this);
 27.9537 +        this._isSleeping = true;
 27.9538 +    };
 27.9539 +
 27.9540 +    /**
 27.9541 +     * Starts the particle update
 27.9542 +     * @method wake
 27.9543 +     */
 27.9544 +    Particle.prototype.wake = function wake() {
 27.9545 +        if (!this._isSleeping) return;
 27.9546 +        this.emit(_events.start, this);
 27.9547 +        this._isSleeping = false;
 27.9548 +        this._prevTime = now();
 27.9549 +    };
 27.9550 +
 27.9551 +    /**
 27.9552 +     * @attribute isBody
 27.9553 +     * @type Boolean
 27.9554 +     * @static
 27.9555 +     */
 27.9556 +    Particle.prototype.isBody = false;
 27.9557 +
 27.9558 +    /**
 27.9559 +     * Basic setter for position
 27.9560 +     * @method getPosition
 27.9561 +     * @param position {Array|Vector}
 27.9562 +     */
 27.9563 +    Particle.prototype.setPosition = function setPosition(position) {
 27.9564 +        this.position.set(position);
 27.9565 +    };
 27.9566 +
 27.9567 +    /**
 27.9568 +     * 1-dimensional setter for position
 27.9569 +     * @method setPosition1D
 27.9570 +     * @param value {Number}
 27.9571 +     */
 27.9572 +    Particle.prototype.setPosition1D = function setPosition1D(x) {
 27.9573 +        this.position.x = x;
 27.9574 +    };
 27.9575 +
 27.9576 +    /**
 27.9577 +     * Basic getter function for position
 27.9578 +     * @method getPosition
 27.9579 +     * @return position {Array}
 27.9580 +     */
 27.9581 +    Particle.prototype.getPosition = function getPosition() {
 27.9582 +        if (this._positionGetter instanceof Function)
 27.9583 +            this.setPosition(this._positionGetter());
 27.9584 +
 27.9585 +        this._engine.step();
 27.9586 +
 27.9587 +        return this.position.get();
 27.9588 +    };
 27.9589 +
 27.9590 +    /**
 27.9591 +     * 1-dimensional getter for position
 27.9592 +     * @method getPosition1D
 27.9593 +     * @return value {Number}
 27.9594 +     */
 27.9595 +    Particle.prototype.getPosition1D = function getPosition1D() {
 27.9596 +        this._engine.step();
 27.9597 +        return this.position.x;
 27.9598 +    };
 27.9599 +
 27.9600 +    /**
 27.9601 +     * Defines the position from outside the Physics Engine
 27.9602 +     * @method positionFrom
 27.9603 +     * @param positionGetter {Function}
 27.9604 +     */
 27.9605 +    Particle.prototype.positionFrom = function positionFrom(positionGetter) {
 27.9606 +        this._positionGetter = positionGetter;
 27.9607 +    };
 27.9608 +
 27.9609 +    /**
 27.9610 +     * Basic setter function for velocity Vector
 27.9611 +     * @method setVelocity
 27.9612 +     * @function
 27.9613 +     */
 27.9614 +    Particle.prototype.setVelocity = function setVelocity(velocity) {
 27.9615 +        this.velocity.set(velocity);
 27.9616 +        this.wake();
 27.9617 +    };
 27.9618 +
 27.9619 +    /**
 27.9620 +     * 1-dimensional setter for velocity
 27.9621 +     * @method setVelocity1D
 27.9622 +     * @param velocity {Number}
 27.9623 +     */
 27.9624 +    Particle.prototype.setVelocity1D = function setVelocity1D(x) {
 27.9625 +        this.velocity.x = x;
 27.9626 +        this.wake();
 27.9627 +    };
 27.9628 +
 27.9629 +    /**
 27.9630 +     * Basic getter function for velocity Vector
 27.9631 +     * @method getVelocity
 27.9632 +     * @return velocity {Array}
 27.9633 +     */
 27.9634 +    Particle.prototype.getVelocity = function getVelocity() {
 27.9635 +        return this.velocity.get();
 27.9636 +    };
 27.9637 +
 27.9638 +    /**
 27.9639 +     * 1-dimensional getter for velocity
 27.9640 +     * @method getVelocity1D
 27.9641 +     * @return velocity {Number}
 27.9642 +     */
 27.9643 +    Particle.prototype.getVelocity1D = function getVelocity1D() {
 27.9644 +        return this.velocity.x;
 27.9645 +    };
 27.9646 +
 27.9647 +    /**
 27.9648 +     * Basic setter function for mass quantity
 27.9649 +     * @method setMass
 27.9650 +     * @param mass {Number} mass
 27.9651 +     */
 27.9652 +    Particle.prototype.setMass = function setMass(mass) {
 27.9653 +        this.mass = mass;
 27.9654 +        this.inverseMass = 1 / mass;
 27.9655 +    };
 27.9656 +
 27.9657 +    /**
 27.9658 +     * Basic getter function for mass quantity
 27.9659 +     * @method getMass
 27.9660 +     * @return mass {Number}
 27.9661 +     */
 27.9662 +    Particle.prototype.getMass = function getMass() {
 27.9663 +        return this.mass;
 27.9664 +    };
 27.9665 +
 27.9666 +    /**
 27.9667 +     * Reset position and velocity
 27.9668 +     * @method reset
 27.9669 +     * @param position {Array|Vector}
 27.9670 +     * @param velocity {Array|Vector}
 27.9671 +     */
 27.9672 +    Particle.prototype.reset = function reset(position, velocity) {
 27.9673 +        this.setPosition(position || [0,0,0]);
 27.9674 +        this.setVelocity(velocity || [0,0,0]);
 27.9675 +    };
 27.9676 +
 27.9677 +    /**
 27.9678 +     * Add force vector to existing internal force Vector
 27.9679 +     * @method applyForce
 27.9680 +     * @param force {Vector}
 27.9681 +     */
 27.9682 +    Particle.prototype.applyForce = function applyForce(force) {
 27.9683 +        if (force.isZero()) return;
 27.9684 +        this.force.add(force).put(this.force);
 27.9685 +        this.wake();
 27.9686 +    };
 27.9687 +
 27.9688 +    /**
 27.9689 +     * Add impulse (change in velocity) Vector to this Vector's velocity.
 27.9690 +     * @method applyImpulse
 27.9691 +     * @param impulse {Vector}
 27.9692 +     */
 27.9693 +    Particle.prototype.applyImpulse = function applyImpulse(impulse) {
 27.9694 +        if (impulse.isZero()) return;
 27.9695 +        var velocity = this.velocity;
 27.9696 +        velocity.add(impulse.mult(this.inverseMass)).put(velocity);
 27.9697 +    };
 27.9698 +
 27.9699 +    /**
 27.9700 +     * Update a particle's velocity from its force accumulator
 27.9701 +     * @method integrateVelocity
 27.9702 +     * @param dt {Number} Time differential
 27.9703 +     */
 27.9704 +    Particle.prototype.integrateVelocity = function integrateVelocity(dt) {
 27.9705 +        Particle.INTEGRATOR.integrateVelocity(this, dt);
 27.9706 +    };
 27.9707 +
 27.9708 +    /**
 27.9709 +     * Update a particle's position from its velocity
 27.9710 +     * @method integratePosition
 27.9711 +     * @param dt {Number} Time differential
 27.9712 +     */
 27.9713 +    Particle.prototype.integratePosition = function integratePosition(dt) {
 27.9714 +        Particle.INTEGRATOR.integratePosition(this, dt);
 27.9715 +    };
 27.9716 +
 27.9717 +    /**
 27.9718 +     * Update the position and velocity of the particle
 27.9719 +     * @method _integrate
 27.9720 +     * @protected
 27.9721 +     * @param dt {Number} Time differential
 27.9722 +     */
 27.9723 +    Particle.prototype._integrate = function _integrate(dt) {
 27.9724 +        this.integrateVelocity(dt);
 27.9725 +        this.integratePosition(dt);
 27.9726 +    };
 27.9727 +
 27.9728 +    /**
 27.9729 +     * Get kinetic energy of the particle.
 27.9730 +     * @method getEnergy
 27.9731 +     * @function
 27.9732 +     */
 27.9733 +    Particle.prototype.getEnergy = function getEnergy() {
 27.9734 +        return 0.5 * this.mass * this.velocity.normSquared();
 27.9735 +    };
 27.9736 +
 27.9737 +    /**
 27.9738 +     * Generate transform from the current position state
 27.9739 +     * @method getTransform
 27.9740 +     * @return Transform {Transform}
 27.9741 +     */
 27.9742 +    Particle.prototype.getTransform = function getTransform() {
 27.9743 +        this._engine.step();
 27.9744 +
 27.9745 +        var position = this.position;
 27.9746 +        var axis = this.axis;
 27.9747 +        var transform = this.transform;
 27.9748 +
 27.9749 +        if (axis !== undefined) {
 27.9750 +            if (axis & ~Particle.AXES.X) {
 27.9751 +                position.x = 0;
 27.9752 +            }
 27.9753 +            if (axis & ~Particle.AXES.Y) {
 27.9754 +                position.y = 0;
 27.9755 +            }
 27.9756 +            if (axis & ~Particle.AXES.Z) {
 27.9757 +                position.z = 0;
 27.9758 +            }
 27.9759 +        }
 27.9760 +
 27.9761 +        transform[12] = position.x;
 27.9762 +        transform[13] = position.y;
 27.9763 +        transform[14] = position.z;
 27.9764 +
 27.9765 +        return transform;
 27.9766 +    };
 27.9767 +
 27.9768 +    /**
 27.9769 +     * The modify interface of a Modifier
 27.9770 +     * @method modify
 27.9771 +     * @param target {Spec}
 27.9772 +     * @return Spec {Spec}
 27.9773 +     */
 27.9774 +    Particle.prototype.modify = function modify(target) {
 27.9775 +        var _spec = this._spec;
 27.9776 +        _spec.transform = this.getTransform();
 27.9777 +        _spec.target = target;
 27.9778 +        return _spec;
 27.9779 +    };
 27.9780 +
 27.9781 +    // private
 27.9782 +    function _createEventOutput() {
 27.9783 +        this._eventOutput = new EventHandler();
 27.9784 +        this._eventOutput.bindThis(this);
 27.9785 +        //overrides on/removeListener/pipe/unpipe methods
 27.9786 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.9787 +    }
 27.9788 +
 27.9789 +    Particle.prototype.emit = function emit(type, data) {
 27.9790 +        if (!this._eventOutput) return;
 27.9791 +        this._eventOutput.emit(type, data);
 27.9792 +    };
 27.9793 +
 27.9794 +    Particle.prototype.on = function on() {
 27.9795 +        _createEventOutput.call(this);
 27.9796 +        return this.on.apply(this, arguments);
 27.9797 +    };
 27.9798 +    Particle.prototype.removeListener = function removeListener() {
 27.9799 +        _createEventOutput.call(this);
 27.9800 +        return this.removeListener.apply(this, arguments);
 27.9801 +    };
 27.9802 +    Particle.prototype.pipe = function pipe() {
 27.9803 +        _createEventOutput.call(this);
 27.9804 +        return this.pipe.apply(this, arguments);
 27.9805 +    };
 27.9806 +    Particle.prototype.unpipe = function unpipe() {
 27.9807 +        _createEventOutput.call(this);
 27.9808 +        return this.unpipe.apply(this, arguments);
 27.9809 +    };
 27.9810 +
 27.9811 +    module.exports = Particle;
 27.9812 +});
 27.9813 +
 27.9814 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.9815 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.9816 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.9817 + *
 27.9818 + * Owner: david@famo.us
 27.9819 + * @license MPL 2.0
 27.9820 + * @copyright Famous Industries, Inc. 2014
 27.9821 + */
 27.9822 +
 27.9823 +define('famous/physics/constraints/Constraint',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 27.9824 +    var EventHandler = require('famous/core/EventHandler');
 27.9825 +
 27.9826 +    /**
 27.9827 +     *  Allows for two circular bodies to collide and bounce off each other.
 27.9828 +     *
 27.9829 +     *  @class Constraint
 27.9830 +     *  @constructor
 27.9831 +     *  @uses EventHandler
 27.9832 +     *  @param options {Object}
 27.9833 +     */
 27.9834 +    function Constraint() {
 27.9835 +        this.options = this.options || {};
 27.9836 +        this._energy = 0.0;
 27.9837 +        this._eventOutput = null;
 27.9838 +    }
 27.9839 +
 27.9840 +    /*
 27.9841 +     * Setter for options.
 27.9842 +     *
 27.9843 +     * @method setOptions
 27.9844 +     * @param options {Objects}
 27.9845 +     */
 27.9846 +    Constraint.prototype.setOptions = function setOptions(options) {
 27.9847 +        for (var key in options) this.options[key] = options[key];
 27.9848 +    };
 27.9849 +
 27.9850 +    /**
 27.9851 +     * Adds an impulse to a physics body's velocity due to the constraint
 27.9852 +     *
 27.9853 +     * @method applyConstraint
 27.9854 +     */
 27.9855 +    Constraint.prototype.applyConstraint = function applyConstraint() {};
 27.9856 +
 27.9857 +    /**
 27.9858 +     * Getter for energy
 27.9859 +     *
 27.9860 +     * @method getEnergy
 27.9861 +     * @return energy {Number}
 27.9862 +     */
 27.9863 +    Constraint.prototype.getEnergy = function getEnergy() {
 27.9864 +        return this._energy;
 27.9865 +    };
 27.9866 +
 27.9867 +    /**
 27.9868 +     * Setter for energy
 27.9869 +     *
 27.9870 +     * @method setEnergy
 27.9871 +     * @param energy {Number}
 27.9872 +     */
 27.9873 +    Constraint.prototype.setEnergy = function setEnergy(energy) {
 27.9874 +        this._energy = energy;
 27.9875 +    };
 27.9876 +
 27.9877 +    function _createEventOutput() {
 27.9878 +        this._eventOutput = new EventHandler();
 27.9879 +        this._eventOutput.bindThis(this);
 27.9880 +        EventHandler.setOutputHandler(this, this._eventOutput);
 27.9881 +    }
 27.9882 +
 27.9883 +    Constraint.prototype.on = function on() {
 27.9884 +        _createEventOutput.call(this);
 27.9885 +        return this.on.apply(this, arguments);
 27.9886 +    };
 27.9887 +    Constraint.prototype.addListener = function addListener() {
 27.9888 +        _createEventOutput.call(this);
 27.9889 +        return this.addListener.apply(this, arguments);
 27.9890 +    };
 27.9891 +    Constraint.prototype.pipe = function pipe() {
 27.9892 +        _createEventOutput.call(this);
 27.9893 +        return this.pipe.apply(this, arguments);
 27.9894 +    };
 27.9895 +    Constraint.prototype.removeListener = function removeListener() {
 27.9896 +        return this.removeListener.apply(this, arguments);
 27.9897 +    };
 27.9898 +    Constraint.prototype.unpipe = function unpipe() {
 27.9899 +        return this.unpipe.apply(this, arguments);
 27.9900 +    };
 27.9901 +
 27.9902 +    module.exports = Constraint;
 27.9903 +});
 27.9904 +
 27.9905 +/* This Source Code Form is subject to the terms of the Mozilla Public
 27.9906 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 27.9907 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 27.9908 + *
 27.9909 + * Owner: david@famo.us
 27.9910 + * @license MPL 2.0
 27.9911 + * @copyright Famous Industries, Inc. 2014
 27.9912 + */
 27.9913 +
 27.9914 +define('famous/physics/constraints/Snap',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
 27.9915 +    var Constraint = require('./Constraint');
 27.9916 +    var Vector = require('famous/math/Vector');
 27.9917 +
 27.9918 +    /**
 27.9919 +     *  A spring constraint is like a spring force, except that it is always
 27.9920 +     *    numerically stable (even for low periods), at the expense of introducing
 27.9921 +     *    damping (even with dampingRatio set to 0).
 27.9922 +     *
 27.9923 +     *    Use this if you need fast spring-like behavior, e.g., snapping
 27.9924 +     *
 27.9925 +     *  @class Snap
 27.9926 +     *  @constructor
 27.9927 +     *  @extends Constraint
 27.9928 +     *  @param {Options} [options] An object of configurable options.
 27.9929 +     *  @param {Number} [options.period] The amount of time in milliseconds taken for one complete oscillation when there is no damping. Range : [150, Infinity]
 27.9930 +     *  @param {Number} [options.dampingRatio] Additional damping of the spring. Range : [0, 1]. At 0 this spring will still be damped, at 1 the spring will be critically damped (the spring will never oscillate)
 27.9931 +     *  @param {Number} [options.length] The rest length of the spring. Range: [0, Infinity].
 27.9932 +     *  @param {Array} [options.anchor] The location of the spring's anchor, if not another physics body.
 27.9933 +     *
 27.9934 +     */
 27.9935 +    function Snap(options) {
 27.9936 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
 27.9937 +        if (options) this.setOptions(options);
 27.9938 +
 27.9939 +        //registers
 27.9940 +        this.pDiff  = new Vector();
 27.9941 +        this.vDiff  = new Vector();
 27.9942 +        this.impulse1 = new Vector();
 27.9943 +        this.impulse2 = new Vector();
 27.9944 +
 27.9945 +        Constraint.call(this);
 27.9946 +    }
 27.9947 +
 27.9948 +    Snap.prototype = Object.create(Constraint.prototype);
 27.9949 +    Snap.prototype.constructor = Snap;
 27.9950 +
 27.9951 +    Snap.DEFAULT_OPTIONS = {
 27.9952 +        period        : 300,
 27.9953 +        dampingRatio : 0.1,
 27.9954 +        length : 0,
 27.9955 +        anchor : undefined
 27.9956 +    };
 27.9957 +
 27.9958 +    /** const */ var pi = Math.PI;
 27.9959 +
 27.9960 +    function _calcEnergy(impulse, disp, dt) {
 27.9961 +        return Math.abs(impulse.dot(disp)/dt);
 27.9962 +    }
 27.9963 +
 27.9964 +    /**
 27.9965 +     * Basic options setter
 27.9966 +     *
 27.9967 +     * @method setOptions
 27.9968 +     * @param options {Objects} options
 27.9969 +     */
 27.9970 +    Snap.prototype.setOptions = function setOptions(options) {
 27.9971 +        if (options.anchor !== undefined) {
 27.9972 +            if (options.anchor   instanceof Vector) this.options.anchor = options.anchor;
 27.9973 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
 27.9974 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
 27.9975 +        }
 27.9976 +        if (options.length !== undefined) this.options.length = options.length;
 27.9977 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
 27.9978 +        if (options.period !== undefined) this.options.period = options.period;
 27.9979 +    };
 27.9980 +
 27.9981 +    /**
 27.9982 +     * Set the anchor position
 27.9983 +     *
 27.9984 +     * @method setOptions
 27.9985 +     * @param {Array} v TODO
 27.9986 +     */
 27.9987 +
 27.9988 +    Snap.prototype.setAnchor = function setAnchor(v) {
 27.9989 +        if (this.options.anchor !== undefined) this.options.anchor = new Vector();
 27.9990 +        this.options.anchor.set(v);
 27.9991 +    };
 27.9992 +
 27.9993 +    /**
 27.9994 +     * Calculates energy of spring
 27.9995 +     *
 27.9996 +     * @method getEnergy
 27.9997 +     * @param {Object} target TODO
 27.9998 +     * @param {Object} source TODO
 27.9999 +     * @return energy {Number}
27.10000 +     */
27.10001 +    Snap.prototype.getEnergy = function getEnergy(target, source) {
27.10002 +        var options     = this.options;
27.10003 +        var restLength  = options.length;
27.10004 +        var anchor      = options.anchor || source.position;
27.10005 +        var strength    = Math.pow(2 * pi / options.period, 2);
27.10006 +
27.10007 +        var dist = anchor.sub(target.position).norm() - restLength;
27.10008 +
27.10009 +        return 0.5 * strength * dist * dist;
27.10010 +    };
27.10011 +
27.10012 +    /**
27.10013 +     * Adds a spring impulse to a physics body's velocity due to the constraint
27.10014 +     *
27.10015 +     * @method applyConstraint
27.10016 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
27.10017 +     * @param source {Body}         The source of the constraint
27.10018 +     * @param dt {Number}           Delta time
27.10019 +     */
27.10020 +    Snap.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.10021 +        var options         = this.options;
27.10022 +        var pDiff        = this.pDiff;
27.10023 +        var vDiff        = this.vDiff;
27.10024 +        var impulse1     = this.impulse1;
27.10025 +        var impulse2     = this.impulse2;
27.10026 +        var length       = options.length;
27.10027 +        var anchor       = options.anchor || source.position;
27.10028 +        var period       = options.period;
27.10029 +        var dampingRatio = options.dampingRatio;
27.10030 +
27.10031 +        for (var i = 0; i < targets.length ; i++) {
27.10032 +            var target = targets[i];
27.10033 +
27.10034 +            var p1 = target.position;
27.10035 +            var v1 = target.velocity;
27.10036 +            var m1 = target.mass;
27.10037 +            var w1 = target.inverseMass;
27.10038 +
27.10039 +            pDiff.set(p1.sub(anchor));
27.10040 +            var dist = pDiff.norm() - length;
27.10041 +            var effMass;
27.10042 +
27.10043 +            if (source) {
27.10044 +                var w2 = source.inverseMass;
27.10045 +                var v2 = source.velocity;
27.10046 +                vDiff.set(v1.sub(v2));
27.10047 +                effMass = 1/(w1 + w2);
27.10048 +            }
27.10049 +            else {
27.10050 +                vDiff.set(v1);
27.10051 +                effMass = m1;
27.10052 +            }
27.10053 +
27.10054 +            var gamma;
27.10055 +            var beta;
27.10056 +
27.10057 +            if (this.options.period === 0) {
27.10058 +                gamma = 0;
27.10059 +                beta = 1;
27.10060 +            }
27.10061 +            else {
27.10062 +                var k = 4 * effMass * pi * pi / (period * period);
27.10063 +                var c = 4 * effMass * pi * dampingRatio / period;
27.10064 +
27.10065 +                beta  = dt * k / (c + dt * k);
27.10066 +                gamma = 1 / (c + dt*k);
27.10067 +            }
27.10068 +
27.10069 +            var antiDrift = beta/dt * dist;
27.10070 +            pDiff.normalize(-antiDrift)
27.10071 +                .sub(vDiff)
27.10072 +                .mult(dt / (gamma + dt/effMass))
27.10073 +                .put(impulse1);
27.10074 +
27.10075 +            // var n = new Vector();
27.10076 +            // n.set(pDiff.normalize());
27.10077 +            // var lambda = -(n.dot(vDiff) + antiDrift) / (gamma + dt/effMass);
27.10078 +            // impulse2.set(n.mult(dt*lambda));
27.10079 +
27.10080 +            target.applyImpulse(impulse1);
27.10081 +
27.10082 +            if (source) {
27.10083 +                impulse1.mult(-1).put(impulse2);
27.10084 +                source.applyImpulse(impulse2);
27.10085 +            }
27.10086 +
27.10087 +            this.setEnergy(_calcEnergy(impulse1, pDiff, dt));
27.10088 +        }
27.10089 +    };
27.10090 +
27.10091 +    module.exports = Snap;
27.10092 +});
27.10093 +
27.10094 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.10095 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.10096 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.10097 + *
27.10098 + * Owner: david@famo.us
27.10099 + * @license MPL 2.0
27.10100 + * @copyright Famous Industries, Inc. 2014
27.10101 + */
27.10102 +
27.10103 +define('famous/transitions/SnapTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/constraints/Snap','famous/math/Vector'],function(require, exports, module) {
27.10104 +    var PE = require('famous/physics/PhysicsEngine');
27.10105 +    var Particle = require('famous/physics/bodies/Particle');
27.10106 +    var Spring = require('famous/physics/constraints/Snap');
27.10107 +    var Vector = require('famous/math/Vector');
27.10108 +
27.10109 +    /**
27.10110 +     * SnapTransition is a method of transitioning between two values (numbers,
27.10111 +     * or arrays of numbers). It is similar to SpringTransition except
27.10112 +     * the transition can be much faster and always has a damping effect.
27.10113 +     *
27.10114 +     * @class SnapTransition
27.10115 +     * @constructor
27.10116 +     *
27.10117 +     * @param [state=0] {Number|Array} Initial state
27.10118 +     */
27.10119 +    function SnapTransition(state) {
27.10120 +        state = state || 0;
27.10121 +
27.10122 +        this.endState  = new Vector(state);
27.10123 +        this.initState = new Vector();
27.10124 +
27.10125 +        this._dimensions       = 1;
27.10126 +        this._restTolerance    = 1e-10;
27.10127 +        this._absRestTolerance = this._restTolerance;
27.10128 +        this._callback         = undefined;
27.10129 +
27.10130 +        this.PE       = new PE();
27.10131 +        this.particle = new Particle();
27.10132 +        this.spring   = new Spring({anchor : this.endState});
27.10133 +
27.10134 +        this.PE.addBody(this.particle);
27.10135 +        this.PE.attach(this.spring, this.particle);
27.10136 +    }
27.10137 +
27.10138 +    SnapTransition.SUPPORTS_MULTIPLE = 3;
27.10139 +
27.10140 +    /**
27.10141 +     * @property SnapTransition.DEFAULT_OPTIONS
27.10142 +     * @type Object
27.10143 +     * @protected
27.10144 +     * @static
27.10145 +     */
27.10146 +    SnapTransition.DEFAULT_OPTIONS = {
27.10147 +
27.10148 +        /**
27.10149 +         * The amount of time in milliseconds taken for one complete oscillation
27.10150 +         * when there is no damping
27.10151 +         *    Range : [0, Infinity]
27.10152 +         *
27.10153 +         * @attribute period
27.10154 +         * @type Number
27.10155 +         * @default 100
27.10156 +         */
27.10157 +        period : 100,
27.10158 +
27.10159 +        /**
27.10160 +         * The damping of the snap.
27.10161 +         *    Range : [0, 1]
27.10162 +         *
27.10163 +         * @attribute dampingRatio
27.10164 +         * @type Number
27.10165 +         * @default 0.2
27.10166 +         */
27.10167 +        dampingRatio : 0.2,
27.10168 +
27.10169 +        /**
27.10170 +         * The initial velocity of the transition.
27.10171 +         *
27.10172 +         * @attribute velocity
27.10173 +         * @type Number|Array
27.10174 +         * @default 0
27.10175 +         */
27.10176 +        velocity : 0
27.10177 +    };
27.10178 +
27.10179 +    function _getEnergy() {
27.10180 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
27.10181 +    }
27.10182 +
27.10183 +    function _setAbsoluteRestTolerance() {
27.10184 +        var distance = this.endState.sub(this.initState).normSquared();
27.10185 +        this._absRestTolerance = (distance === 0)
27.10186 +            ? this._restTolerance
27.10187 +            : this._restTolerance * distance;
27.10188 +    }
27.10189 +
27.10190 +    function _setTarget(target) {
27.10191 +        this.endState.set(target);
27.10192 +        _setAbsoluteRestTolerance.call(this);
27.10193 +    }
27.10194 +
27.10195 +    function _wake() {
27.10196 +        this.PE.wake();
27.10197 +    }
27.10198 +
27.10199 +    function _sleep() {
27.10200 +        this.PE.sleep();
27.10201 +    }
27.10202 +
27.10203 +    function _setParticlePosition(p) {
27.10204 +        this.particle.position.set(p);
27.10205 +    }
27.10206 +
27.10207 +    function _setParticleVelocity(v) {
27.10208 +        this.particle.velocity.set(v);
27.10209 +    }
27.10210 +
27.10211 +    function _getParticlePosition() {
27.10212 +        return (this._dimensions === 0)
27.10213 +            ? this.particle.getPosition1D()
27.10214 +            : this.particle.getPosition();
27.10215 +    }
27.10216 +
27.10217 +    function _getParticleVelocity() {
27.10218 +        return (this._dimensions === 0)
27.10219 +            ? this.particle.getVelocity1D()
27.10220 +            : this.particle.getVelocity();
27.10221 +    }
27.10222 +
27.10223 +    function _setCallback(callback) {
27.10224 +        this._callback = callback;
27.10225 +    }
27.10226 +
27.10227 +    function _setupDefinition(definition) {
27.10228 +        var defaults = SnapTransition.DEFAULT_OPTIONS;
27.10229 +        if (definition.period === undefined)       definition.period       = defaults.period;
27.10230 +        if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio;
27.10231 +        if (definition.velocity === undefined)     definition.velocity     = defaults.velocity;
27.10232 +
27.10233 +        //setup spring
27.10234 +        this.spring.setOptions({
27.10235 +            period       : definition.period,
27.10236 +            dampingRatio : definition.dampingRatio
27.10237 +        });
27.10238 +
27.10239 +        //setup particle
27.10240 +        _setParticleVelocity.call(this, definition.velocity);
27.10241 +    }
27.10242 +
27.10243 +    function _update() {
27.10244 +        if (this.PE.isSleeping()) {
27.10245 +            if (this._callback) {
27.10246 +                var cb = this._callback;
27.10247 +                this._callback = undefined;
27.10248 +                cb();
27.10249 +            }
27.10250 +            return;
27.10251 +        }
27.10252 +
27.10253 +        if (_getEnergy.call(this) < this._absRestTolerance) {
27.10254 +            _setParticlePosition.call(this, this.endState);
27.10255 +            _setParticleVelocity.call(this, [0,0,0]);
27.10256 +            _sleep.call(this);
27.10257 +        }
27.10258 +    }
27.10259 +
27.10260 +    /**
27.10261 +     * Resets the state and velocity
27.10262 +     *
27.10263 +     * @method reset
27.10264 +     *
27.10265 +     * @param state {Number|Array}      State
27.10266 +     * @param [velocity] {Number|Array} Velocity
27.10267 +     */
27.10268 +    SnapTransition.prototype.reset = function reset(state, velocity) {
27.10269 +        this._dimensions = (state instanceof Array)
27.10270 +            ? state.length
27.10271 +            : 0;
27.10272 +
27.10273 +        this.initState.set(state);
27.10274 +        _setParticlePosition.call(this, state);
27.10275 +        _setTarget.call(this, state);
27.10276 +        if (velocity) _setParticleVelocity.call(this, velocity);
27.10277 +        _setCallback.call(this, undefined);
27.10278 +    };
27.10279 +
27.10280 +    /**
27.10281 +     * Getter for velocity
27.10282 +     *
27.10283 +     * @method getVelocity
27.10284 +     *
27.10285 +     * @return velocity {Number|Array}
27.10286 +     */
27.10287 +    SnapTransition.prototype.getVelocity = function getVelocity() {
27.10288 +        return _getParticleVelocity.call(this);
27.10289 +    };
27.10290 +
27.10291 +    /**
27.10292 +     * Setter for velocity
27.10293 +     *
27.10294 +     * @method setVelocity
27.10295 +     *
27.10296 +     * @return velocity {Number|Array}
27.10297 +     */
27.10298 +    SnapTransition.prototype.setVelocity = function setVelocity(velocity) {
27.10299 +        this.call(this, _setParticleVelocity(velocity));
27.10300 +    };
27.10301 +
27.10302 +    /**
27.10303 +     * Detects whether a transition is in progress
27.10304 +     *
27.10305 +     * @method isActive
27.10306 +     *
27.10307 +     * @return {Boolean}
27.10308 +     */
27.10309 +    SnapTransition.prototype.isActive = function isActive() {
27.10310 +        return !this.PE.isSleeping();
27.10311 +    };
27.10312 +
27.10313 +    /**
27.10314 +     * Halt the transition
27.10315 +     *
27.10316 +     * @method halt
27.10317 +     */
27.10318 +    SnapTransition.prototype.halt = function halt() {
27.10319 +        this.set(this.get());
27.10320 +    };
27.10321 +
27.10322 +    /**
27.10323 +     * Get the current position of the transition
27.10324 +s     *
27.10325 +     * @method get
27.10326 +     *
27.10327 +     * @return state {Number|Array}
27.10328 +     */
27.10329 +    SnapTransition.prototype.get = function get() {
27.10330 +        _update.call(this);
27.10331 +        return _getParticlePosition.call(this);
27.10332 +    };
27.10333 +
27.10334 +    /**
27.10335 +     * Set the end position and transition, with optional callback on completion.
27.10336 +     *
27.10337 +     * @method set
27.10338 +     *
27.10339 +     * @param state {Number|Array}      Final state
27.10340 +     * @param [definition] {Object}     Transition definition
27.10341 +     * @param [callback] {Function}     Callback
27.10342 +     */
27.10343 +    SnapTransition.prototype.set = function set(state, definition, callback) {
27.10344 +        if (!definition) {
27.10345 +            this.reset(state);
27.10346 +            if (callback) callback();
27.10347 +            return;
27.10348 +        }
27.10349 +
27.10350 +        this._dimensions = (state instanceof Array)
27.10351 +            ? state.length
27.10352 +            : 0;
27.10353 +
27.10354 +        _wake.call(this);
27.10355 +        _setupDefinition.call(this, definition);
27.10356 +        _setTarget.call(this, state);
27.10357 +        _setCallback.call(this, callback);
27.10358 +    };
27.10359 +
27.10360 +    module.exports = SnapTransition;
27.10361 +});
27.10362 +
27.10363 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.10364 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.10365 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.10366 + *
27.10367 + * Owner: david@famo.us
27.10368 + * @license MPL 2.0
27.10369 + * @copyright Famous Industries, Inc. 2014
27.10370 + */
27.10371 +
27.10372 +define('famous/physics/forces/Force',['require','exports','module','famous/math/Vector','famous/core/EventHandler'],function(require, exports, module) {
27.10373 +    var Vector = require('famous/math/Vector');
27.10374 +    var EventHandler = require('famous/core/EventHandler');
27.10375 +
27.10376 +    /**
27.10377 +     * Force base class.
27.10378 +     *
27.10379 +     * @class Force
27.10380 +     * @uses EventHandler
27.10381 +     * @constructor
27.10382 +     */
27.10383 +    function Force(force) {
27.10384 +        this.force = new Vector(force);
27.10385 +        this._energy = 0.0;
27.10386 +        this._eventOutput = null;
27.10387 +    }
27.10388 +
27.10389 +    /**
27.10390 +     * Basic setter for options
27.10391 +     *
27.10392 +     * @method setOptions
27.10393 +     * @param options {Objects}
27.10394 +     */
27.10395 +    Force.prototype.setOptions = function setOptions(options) {
27.10396 +        for (var key in options) this.options[key] = options[key];
27.10397 +    };
27.10398 +
27.10399 +    /**
27.10400 +     * Adds a force to a physics body's force accumulator.
27.10401 +     *
27.10402 +     * @method applyForce
27.10403 +     * @param body {Body}
27.10404 +     */
27.10405 +    Force.prototype.applyForce = function applyForce(body) {
27.10406 +        body.applyForce(this.force);
27.10407 +    };
27.10408 +
27.10409 +    /**
27.10410 +     * Getter for a force's potential energy.
27.10411 +     *
27.10412 +     * @method getEnergy
27.10413 +     * @return energy {Number}
27.10414 +     */
27.10415 +    Force.prototype.getEnergy = function getEnergy() {
27.10416 +        return this._energy;
27.10417 +    };
27.10418 +
27.10419 +    /*
27.10420 +     * Setter for a force's potential energy.
27.10421 +     *
27.10422 +     * @method setEnergy
27.10423 +     * @param energy {Number}
27.10424 +     */
27.10425 +    Force.prototype.setEnergy = function setEnergy(energy) {
27.10426 +        this._energy = energy;
27.10427 +    };
27.10428 +
27.10429 +    function _createEventOutput() {
27.10430 +        this._eventOutput = new EventHandler();
27.10431 +        this._eventOutput.bindThis(this);
27.10432 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.10433 +    }
27.10434 +
27.10435 +    Force.prototype.on = function on() {
27.10436 +        _createEventOutput.call(this);
27.10437 +        return this.on.apply(this, arguments);
27.10438 +    };
27.10439 +    Force.prototype.addListener = function addListener() {
27.10440 +        _createEventOutput.call(this);
27.10441 +        return this.addListener.apply(this, arguments);
27.10442 +    };
27.10443 +    Force.prototype.pipe = function pipe() {
27.10444 +        _createEventOutput.call(this);
27.10445 +        return this.pipe.apply(this, arguments);
27.10446 +    };
27.10447 +    Force.prototype.removeListener = function removeListener() {
27.10448 +        return this.removeListener.apply(this, arguments);
27.10449 +    };
27.10450 +    Force.prototype.unpipe = function unpipe() {
27.10451 +        return this.unpipe.apply(this, arguments);
27.10452 +    };
27.10453 +
27.10454 +    module.exports = Force;
27.10455 +});
27.10456 +
27.10457 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.10458 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.10459 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.10460 + *
27.10461 + * Owner: david@famo.us
27.10462 + * @license MPL 2.0
27.10463 + * @copyright Famous Industries, Inc. 2014
27.10464 + */
27.10465 +
27.10466 +define('famous/physics/forces/Spring',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
27.10467 +    var Force = require('./Force');
27.10468 +    var Vector = require('famous/math/Vector');
27.10469 +
27.10470 +    /**
27.10471 +     *  A force that moves a physics body to a location with a spring motion.
27.10472 +     *    The body can be moved to another physics body, or an anchor point.
27.10473 +     *
27.10474 +     *  @class Spring
27.10475 +     *  @constructor
27.10476 +     *  @extends Force
27.10477 +     *  @param {Object} options options to set on drag
27.10478 +     */
27.10479 +    function Spring(options) {
27.10480 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
27.10481 +        if (options) this.setOptions(options);
27.10482 +
27.10483 +        //registers
27.10484 +        this.disp = new Vector(0,0,0);
27.10485 +
27.10486 +        _init.call(this);
27.10487 +        Force.call(this);
27.10488 +    }
27.10489 +
27.10490 +    Spring.prototype = Object.create(Force.prototype);
27.10491 +    Spring.prototype.constructor = Spring;
27.10492 +
27.10493 +    /** @const */ var pi = Math.PI;
27.10494 +
27.10495 +    /**
27.10496 +     * @property Spring.FORCE_FUNCTIONS
27.10497 +     * @type Object
27.10498 +     * @protected
27.10499 +     * @static
27.10500 +     */
27.10501 +    Spring.FORCE_FUNCTIONS = {
27.10502 +
27.10503 +        /**
27.10504 +         * A FENE (Finitely Extensible Nonlinear Elastic) spring force
27.10505 +         *      see: http://en.wikipedia.org/wiki/FENE
27.10506 +         * @attribute FENE
27.10507 +         * @type Function
27.10508 +         * @param {Number} dist current distance target is from source body
27.10509 +         * @param {Number} rMax maximum range of influence
27.10510 +         * @return {Number} unscaled force
27.10511 +         */
27.10512 +        FENE : function(dist, rMax) {
27.10513 +            var rMaxSmall = rMax * .99;
27.10514 +            var r = Math.max(Math.min(dist, rMaxSmall), -rMaxSmall);
27.10515 +            return r / (1 - r * r/(rMax * rMax));
27.10516 +        },
27.10517 +
27.10518 +        /**
27.10519 +         * A Hookean spring force, linear in the displacement
27.10520 +         *      see: http://en.wikipedia.org/wiki/FENE
27.10521 +         * @attribute FENE
27.10522 +         * @type Function
27.10523 +         * @param {Number} dist current distance target is from source body
27.10524 +         * @return {Number} unscaled force
27.10525 +         */
27.10526 +        HOOK : function(dist) {
27.10527 +            return dist;
27.10528 +        }
27.10529 +    };
27.10530 +
27.10531 +    /**
27.10532 +     * @property Spring.DEFAULT_OPTIONS
27.10533 +     * @type Object
27.10534 +     * @protected
27.10535 +     * @static
27.10536 +     */
27.10537 +    Spring.DEFAULT_OPTIONS = {
27.10538 +
27.10539 +        /**
27.10540 +         * The amount of time in milliseconds taken for one complete oscillation
27.10541 +         * when there is no damping
27.10542 +         *    Range : [150, Infinity]
27.10543 +         * @attribute period
27.10544 +         * @type Number
27.10545 +         * @default 300
27.10546 +         */
27.10547 +        period        : 300,
27.10548 +
27.10549 +        /**
27.10550 +         * The damping of the spring.
27.10551 +         *    Range : [0, 1]
27.10552 +         *    0 = no damping, and the spring will oscillate forever
27.10553 +         *    1 = critically damped (the spring will never oscillate)
27.10554 +         * @attribute dampingRatio
27.10555 +         * @type Number
27.10556 +         * @default 0.1
27.10557 +         */
27.10558 +        dampingRatio : 0.1,
27.10559 +
27.10560 +        /**
27.10561 +         * The rest length of the spring
27.10562 +         *    Range : [0, Infinity]
27.10563 +         * @attribute length
27.10564 +         * @type Number
27.10565 +         * @default 0
27.10566 +         */
27.10567 +        length : 0,
27.10568 +
27.10569 +        /**
27.10570 +         * The maximum length of the spring (for a FENE spring)
27.10571 +         *    Range : [0, Infinity]
27.10572 +         * @attribute length
27.10573 +         * @type Number
27.10574 +         * @default Infinity
27.10575 +         */
27.10576 +        maxLength : Infinity,
27.10577 +
27.10578 +        /**
27.10579 +         * The location of the spring's anchor, if not another physics body
27.10580 +         *
27.10581 +         * @attribute anchor
27.10582 +         * @type Array
27.10583 +         * @optional
27.10584 +         */
27.10585 +        anchor : undefined,
27.10586 +
27.10587 +        /**
27.10588 +         * The type of spring force
27.10589 +         * @attribute forceFunction
27.10590 +         * @type Function
27.10591 +         */
27.10592 +        forceFunction : Spring.FORCE_FUNCTIONS.HOOK
27.10593 +    };
27.10594 +
27.10595 +    function _setForceFunction(fn) {
27.10596 +        this.forceFunction = fn;
27.10597 +    }
27.10598 +
27.10599 +    function _calcStiffness() {
27.10600 +        var options = this.options;
27.10601 +        options.stiffness = Math.pow(2 * pi / options.period, 2);
27.10602 +    }
27.10603 +
27.10604 +    function _calcDamping() {
27.10605 +        var options = this.options;
27.10606 +        options.damping = 4 * pi * options.dampingRatio / options.period;
27.10607 +    }
27.10608 +
27.10609 +    function _calcEnergy(strength, dist) {
27.10610 +        return 0.5 * strength * dist * dist;
27.10611 +    }
27.10612 +
27.10613 +    function _init() {
27.10614 +        _setForceFunction.call(this, this.options.forceFunction);
27.10615 +        _calcStiffness.call(this);
27.10616 +        _calcDamping.call(this);
27.10617 +    }
27.10618 +
27.10619 +    /**
27.10620 +     * Basic options setter
27.10621 +     *
27.10622 +     * @method setOptions
27.10623 +     * @param options {Objects}
27.10624 +     */
27.10625 +    Spring.prototype.setOptions = function setOptions(options) {
27.10626 +        if (options.anchor !== undefined) {
27.10627 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
27.10628 +            if (options.anchor   instanceof Vector)  this.options.anchor = options.anchor;
27.10629 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
27.10630 +        }
27.10631 +        if (options.period !== undefined) this.options.period = options.period;
27.10632 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
27.10633 +        if (options.length !== undefined) this.options.length = options.length;
27.10634 +        if (options.forceFunction !== undefined) this.options.forceFunction = options.forceFunction;
27.10635 +        if (options.maxLength !== undefined) this.options.maxLength = options.maxLength;
27.10636 +
27.10637 +        _init.call(this);
27.10638 +    };
27.10639 +
27.10640 +    /**
27.10641 +     * Adds a spring force to a physics body's force accumulator.
27.10642 +     *
27.10643 +     * @method applyForce
27.10644 +     * @param targets {Array.Body} Array of bodies to apply force to.
27.10645 +     */
27.10646 +    Spring.prototype.applyForce = function applyForce(targets, source) {
27.10647 +        var force        = this.force;
27.10648 +        var disp         = this.disp;
27.10649 +        var options      = this.options;
27.10650 +
27.10651 +        var stiffness    = options.stiffness;
27.10652 +        var damping      = options.damping;
27.10653 +        var restLength   = options.length;
27.10654 +        var lMax         = options.maxLength;
27.10655 +        var anchor       = options.anchor || source.position;
27.10656 +
27.10657 +        for (var i = 0; i < targets.length; i++) {
27.10658 +            var target = targets[i];
27.10659 +            var p2 = target.position;
27.10660 +            var v2 = target.velocity;
27.10661 +
27.10662 +            anchor.sub(p2).put(disp);
27.10663 +            var dist = disp.norm() - restLength;
27.10664 +
27.10665 +            if (dist === 0) return;
27.10666 +
27.10667 +            //if dampingRatio specified, then override strength and damping
27.10668 +            var m      = target.mass;
27.10669 +            stiffness *= m;
27.10670 +            damping   *= m;
27.10671 +
27.10672 +            disp.normalize(stiffness * this.forceFunction(dist, lMax))
27.10673 +                .put(force);
27.10674 +
27.10675 +            if (damping)
27.10676 +                if (source) force.add(v2.sub(source.velocity).mult(-damping)).put(force);
27.10677 +                else force.add(v2.mult(-damping)).put(force);
27.10678 +
27.10679 +            target.applyForce(force);
27.10680 +            if (source) source.applyForce(force.mult(-1));
27.10681 +
27.10682 +            this.setEnergy(_calcEnergy(stiffness, dist));
27.10683 +        }
27.10684 +    };
27.10685 +
27.10686 +    /**
27.10687 +     * Calculates the potential energy of the spring.
27.10688 +     *
27.10689 +     * @method getEnergy
27.10690 +     * @param target {Body}     The physics body attached to the spring
27.10691 +     * @return energy {Number}
27.10692 +     */
27.10693 +    Spring.prototype.getEnergy = function getEnergy(target) {
27.10694 +        var options        = this.options;
27.10695 +        var restLength  = options.length;
27.10696 +        var anchor      = options.anchor;
27.10697 +        var strength    = options.stiffness;
27.10698 +
27.10699 +        var dist = anchor.sub(target.position).norm() - restLength;
27.10700 +        return 0.5 * strength * dist * dist;
27.10701 +    };
27.10702 +
27.10703 +    /**
27.10704 +     * Sets the anchor to a new position
27.10705 +     *
27.10706 +     * @method setAnchor
27.10707 +     * @param anchor {Array}    New anchor of the spring
27.10708 +     */
27.10709 +    Spring.prototype.setAnchor = function setAnchor(anchor) {
27.10710 +        if (!this.options.anchor) this.options.anchor = new Vector();
27.10711 +        this.options.anchor.set(anchor);
27.10712 +    };
27.10713 +
27.10714 +    module.exports = Spring;
27.10715 +});
27.10716 +
27.10717 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.10718 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.10719 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.10720 + *
27.10721 + * Owner: david@famo.us
27.10722 + * @license MPL 2.0
27.10723 + * @copyright Famous Industries, Inc. 2014
27.10724 + */
27.10725 +
27.10726 +/*global console*/
27.10727 +
27.10728 +define('famous/transitions/SpringTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/math/Vector'],function(require, exports, module) {
27.10729 +    var PE = require('famous/physics/PhysicsEngine');
27.10730 +    var Particle = require('famous/physics/bodies/Particle');
27.10731 +    var Spring = require('famous/physics/forces/Spring');
27.10732 +    var Vector = require('famous/math/Vector');
27.10733 +
27.10734 +    /**
27.10735 +     * SpringTransition is a method of transitioning between two values (numbers,
27.10736 +     * or arrays of numbers) with a bounce. The transition will overshoot the target
27.10737 +     * state depending on the parameters of the transition.
27.10738 +     *
27.10739 +     * @class SpringTransition
27.10740 +     * @constructor
27.10741 +     *
27.10742 +     * @param {Number|Array} [state=0] Initial state
27.10743 +     */
27.10744 +    function SpringTransition(state) {
27.10745 +        state = state || 0;
27.10746 +        this.endState  = new Vector(state);
27.10747 +        this.initState = new Vector();
27.10748 +
27.10749 +        this._dimensions       = undefined;
27.10750 +        this._restTolerance    = 1e-10;
27.10751 +        this._absRestTolerance = this._restTolerance;
27.10752 +        this._callback         = undefined;
27.10753 +
27.10754 +        this.PE       = new PE();
27.10755 +        this.spring   = new Spring({anchor : this.endState});
27.10756 +        this.particle = new Particle();
27.10757 +
27.10758 +        this.PE.addBody(this.particle);
27.10759 +        this.PE.attach(this.spring, this.particle);
27.10760 +    }
27.10761 +
27.10762 +    SpringTransition.SUPPORTS_MULTIPLE = 3;
27.10763 +
27.10764 +    /**
27.10765 +     * @property SpringTransition.DEFAULT_OPTIONS
27.10766 +     * @type Object
27.10767 +     * @protected
27.10768 +     * @static
27.10769 +     */
27.10770 +    SpringTransition.DEFAULT_OPTIONS = {
27.10771 +
27.10772 +        /**
27.10773 +         * The amount of time in milliseconds taken for one complete oscillation
27.10774 +         * when there is no damping
27.10775 +         *    Range : [0, Infinity]
27.10776 +         *
27.10777 +         * @attribute period
27.10778 +         * @type Number
27.10779 +         * @default 300
27.10780 +         */
27.10781 +        period : 300,
27.10782 +
27.10783 +        /**
27.10784 +         * The damping of the snap.
27.10785 +         *    Range : [0, 1]
27.10786 +         *    0 = no damping, and the spring will oscillate forever
27.10787 +         *    1 = critically damped (the spring will never oscillate)
27.10788 +         *
27.10789 +         * @attribute dampingRatio
27.10790 +         * @type Number
27.10791 +         * @default 0.5
27.10792 +         */
27.10793 +        dampingRatio : 0.5,
27.10794 +
27.10795 +        /**
27.10796 +         * The initial velocity of the transition.
27.10797 +         *
27.10798 +         * @attribute velocity
27.10799 +         * @type Number|Array
27.10800 +         * @default 0
27.10801 +         */
27.10802 +        velocity : 0
27.10803 +    };
27.10804 +
27.10805 +    function _getEnergy() {
27.10806 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
27.10807 +    }
27.10808 +
27.10809 +    function _setParticlePosition(p) {
27.10810 +        this.particle.setPosition(p);
27.10811 +    }
27.10812 +
27.10813 +    function _setParticleVelocity(v) {
27.10814 +        this.particle.setVelocity(v);
27.10815 +    }
27.10816 +
27.10817 +    function _getParticlePosition() {
27.10818 +        return (this._dimensions === 0)
27.10819 +            ? this.particle.getPosition1D()
27.10820 +            : this.particle.getPosition();
27.10821 +    }
27.10822 +
27.10823 +    function _getParticleVelocity() {
27.10824 +        return (this._dimensions === 0)
27.10825 +            ? this.particle.getVelocity1D()
27.10826 +            : this.particle.getVelocity();
27.10827 +    }
27.10828 +
27.10829 +    function _setCallback(callback) {
27.10830 +        this._callback = callback;
27.10831 +    }
27.10832 +
27.10833 +    function _wake() {
27.10834 +        this.PE.wake();
27.10835 +    }
27.10836 +
27.10837 +    function _sleep() {
27.10838 +        this.PE.sleep();
27.10839 +    }
27.10840 +
27.10841 +    function _update() {
27.10842 +        if (this.PE.isSleeping()) {
27.10843 +            if (this._callback) {
27.10844 +                var cb = this._callback;
27.10845 +                this._callback = undefined;
27.10846 +                cb();
27.10847 +            }
27.10848 +            return;
27.10849 +        }
27.10850 +
27.10851 +        if (_getEnergy.call(this) < this._absRestTolerance) {
27.10852 +            _setParticlePosition.call(this, this.endState);
27.10853 +            _setParticleVelocity.call(this, [0,0,0]);
27.10854 +            _sleep.call(this);
27.10855 +        }
27.10856 +    }
27.10857 +
27.10858 +    function _setupDefinition(definition) {
27.10859 +        // TODO fix no-console error
27.10860 +        /* eslint no-console: 0 */
27.10861 +        var defaults = SpringTransition.DEFAULT_OPTIONS;
27.10862 +        if (definition.period === undefined)       definition.period       = defaults.period;
27.10863 +        if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio;
27.10864 +        if (definition.velocity === undefined)     definition.velocity     = defaults.velocity;
27.10865 +
27.10866 +        if (definition.period < 150) {
27.10867 +            definition.period = 150;
27.10868 +            console.warn('The period of a SpringTransition is capped at 150 ms. Use a SnapTransition for faster transitions');
27.10869 +        }
27.10870 +
27.10871 +        //setup spring
27.10872 +        this.spring.setOptions({
27.10873 +            period       : definition.period,
27.10874 +            dampingRatio : definition.dampingRatio
27.10875 +        });
27.10876 +
27.10877 +        //setup particle
27.10878 +        _setParticleVelocity.call(this, definition.velocity);
27.10879 +    }
27.10880 +
27.10881 +    function _setAbsoluteRestTolerance() {
27.10882 +        var distance = this.endState.sub(this.initState).normSquared();
27.10883 +        this._absRestTolerance = (distance === 0)
27.10884 +            ? this._restTolerance
27.10885 +            : this._restTolerance * distance;
27.10886 +    }
27.10887 +
27.10888 +    function _setTarget(target) {
27.10889 +        this.endState.set(target);
27.10890 +        _setAbsoluteRestTolerance.call(this);
27.10891 +    }
27.10892 +
27.10893 +    /**
27.10894 +     * Resets the position and velocity
27.10895 +     *
27.10896 +     * @method reset
27.10897 +     *
27.10898 +     * @param {Number|Array.Number} pos positional state
27.10899 +     * @param {Number|Array} vel velocity
27.10900 +     */
27.10901 +    SpringTransition.prototype.reset = function reset(pos, vel) {
27.10902 +        this._dimensions = (pos instanceof Array)
27.10903 +            ? pos.length
27.10904 +            : 0;
27.10905 +
27.10906 +        this.initState.set(pos);
27.10907 +        _setParticlePosition.call(this, pos);
27.10908 +        _setTarget.call(this, pos);
27.10909 +        if (vel) _setParticleVelocity.call(this, vel);
27.10910 +        _setCallback.call(this, undefined);
27.10911 +    };
27.10912 +
27.10913 +    /**
27.10914 +     * Getter for velocity
27.10915 +     *
27.10916 +     * @method getVelocity
27.10917 +     *
27.10918 +     * @return {Number|Array} velocity
27.10919 +     */
27.10920 +    SpringTransition.prototype.getVelocity = function getVelocity() {
27.10921 +        return _getParticleVelocity.call(this);
27.10922 +    };
27.10923 +
27.10924 +    /**
27.10925 +     * Setter for velocity
27.10926 +     *
27.10927 +     * @method setVelocity
27.10928 +     *
27.10929 +     * @return {Number|Array} velocity
27.10930 +     */
27.10931 +    SpringTransition.prototype.setVelocity = function setVelocity(v) {
27.10932 +        this.call(this, _setParticleVelocity(v));
27.10933 +    };
27.10934 +
27.10935 +    /**
27.10936 +     * Detects whether a transition is in progress
27.10937 +     *
27.10938 +     * @method isActive
27.10939 +     *
27.10940 +     * @return {Boolean}
27.10941 +     */
27.10942 +    SpringTransition.prototype.isActive = function isActive() {
27.10943 +        return !this.PE.isSleeping();
27.10944 +    };
27.10945 +
27.10946 +    /**
27.10947 +     * Halt the transition
27.10948 +     *
27.10949 +     * @method halt
27.10950 +     */
27.10951 +    SpringTransition.prototype.halt = function halt() {
27.10952 +        this.set(this.get());
27.10953 +    };
27.10954 +
27.10955 +    /**
27.10956 +     * Get the current position of the transition
27.10957 +     *
27.10958 +     * @method get
27.10959 +     *
27.10960 +     * @return {Number|Array} state
27.10961 +     */
27.10962 +    SpringTransition.prototype.get = function get() {
27.10963 +        _update.call(this);
27.10964 +        return _getParticlePosition.call(this);
27.10965 +    };
27.10966 +
27.10967 +    /**
27.10968 +     * Set the end position and transition, with optional callback on completion.
27.10969 +     *
27.10970 +     * @method set
27.10971 +     *
27.10972 +     * @param  {Number|Array} endState Final state
27.10973 +     * @param {Object}  definition  Transition definition
27.10974 +     * @param  {Function} callback Callback
27.10975 +     */
27.10976 +    SpringTransition.prototype.set = function set(endState, definition, callback) {
27.10977 +        if (!definition) {
27.10978 +            this.reset(endState);
27.10979 +            if (callback) callback();
27.10980 +            return;
27.10981 +        }
27.10982 +
27.10983 +        this._dimensions = (endState instanceof Array)
27.10984 +            ? endState.length
27.10985 +            : 0;
27.10986 +
27.10987 +        _wake.call(this);
27.10988 +        _setupDefinition.call(this, definition);
27.10989 +        _setTarget.call(this, endState);
27.10990 +        _setCallback.call(this, callback);
27.10991 +    };
27.10992 +
27.10993 +    module.exports = SpringTransition;
27.10994 +});
27.10995 +
27.10996 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.10997 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.10998 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.10999 + *
27.11000 + * Owner: david@famo.us
27.11001 + * @license MPL 2.0
27.11002 + * @copyright Famous Industries, Inc. 2014
27.11003 + */
27.11004 +
27.11005 +define('famous/physics/constraints/Wall',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
27.11006 +    var Constraint = require('./Constraint');
27.11007 +    var Vector = require('famous/math/Vector');
27.11008 +
27.11009 +    /**
27.11010 +     *  A wall describes an infinite two-dimensional plane that physics bodies
27.11011 +     *    can collide with. To define a wall, you must give it a distance (from
27.11012 +     *    the center of the physics engine's origin, and a normal defining the plane
27.11013 +     *    of the wall.
27.11014 +     *
27.11015 +     *    (wall)
27.11016 +     *      |
27.11017 +     *      | (normal)     (origin)
27.11018 +     *      | --->            *
27.11019 +     *      |
27.11020 +     *      |    (distance)
27.11021 +     *      ...................
27.11022 +     *            (100px)
27.11023 +     *
27.11024 +     *      e.g., Wall({normal : [1,0,0], distance : 100})
27.11025 +     *      would be a wall 100 pixels to the left, whose normal points right
27.11026 +     *
27.11027 +     *  @class Wall
27.11028 +     *  @constructor
27.11029 +     *  @extends Constraint
27.11030 +     *  @param {Options} [options] An object of configurable options.
27.11031 +     *  @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic). Range : [0, 1]
27.11032 +     *  @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
27.11033 +     *  @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers.
27.11034 +     *  @param {Array} [options.normal] The normal direction to the wall.
27.11035 +     *  @param {Number} [options.distance] The distance from the origin that the wall is placed.
27.11036 +     *  @param {onContact} [options.onContact] How to handle collision against the wall.
27.11037 +     *
27.11038 +     */
27.11039 +    function Wall(options) {
27.11040 +        this.options = Object.create(Wall.DEFAULT_OPTIONS);
27.11041 +        if (options) this.setOptions(options);
27.11042 +
27.11043 +        //registers
27.11044 +        this.diff = new Vector();
27.11045 +        this.impulse = new Vector();
27.11046 +
27.11047 +        Constraint.call(this);
27.11048 +    }
27.11049 +
27.11050 +    Wall.prototype = Object.create(Constraint.prototype);
27.11051 +    Wall.prototype.constructor = Wall;
27.11052 +
27.11053 +    /**
27.11054 +     * @property Wall.ON_CONTACT
27.11055 +     * @type Object
27.11056 +     * @protected
27.11057 +     * @static
27.11058 +     */
27.11059 +    Wall.ON_CONTACT = {
27.11060 +
27.11061 +        /**
27.11062 +         * Physical bodies bounce off the wall
27.11063 +         * @attribute REFLECT
27.11064 +         */
27.11065 +        REFLECT : 0,
27.11066 +
27.11067 +        /**
27.11068 +         * Physical bodies are unaffected. Usecase is to fire events on contact.
27.11069 +         * @attribute SILENT
27.11070 +         */
27.11071 +        SILENT : 1
27.11072 +    };
27.11073 +
27.11074 +    Wall.DEFAULT_OPTIONS = {
27.11075 +        restitution : 0.5,
27.11076 +        drift : 0.5,
27.11077 +        slop : 0,
27.11078 +        normal : [1, 0, 0],
27.11079 +        distance : 0,
27.11080 +        onContact : Wall.ON_CONTACT.REFLECT
27.11081 +    };
27.11082 +
27.11083 +    /*
27.11084 +     * Setter for options.
27.11085 +     *
27.11086 +     * @method setOptions
27.11087 +     * @param options {Objects}
27.11088 +     */
27.11089 +    Wall.prototype.setOptions = function setOptions(options) {
27.11090 +        if (options.normal !== undefined) {
27.11091 +            if (options.normal instanceof Vector) this.options.normal = options.normal.clone();
27.11092 +            if (options.normal instanceof Array)  this.options.normal = new Vector(options.normal);
27.11093 +        }
27.11094 +        if (options.restitution !== undefined) this.options.restitution = options.restitution;
27.11095 +        if (options.drift !== undefined) this.options.drift = options.drift;
27.11096 +        if (options.slop !== undefined) this.options.slop = options.slop;
27.11097 +        if (options.distance !== undefined) this.options.distance = options.distance;
27.11098 +        if (options.onContact !== undefined) this.options.onContact = options.onContact;
27.11099 +    };
27.11100 +
27.11101 +    function _getNormalVelocity(n, v) {
27.11102 +        return v.dot(n);
27.11103 +    }
27.11104 +
27.11105 +    function _getDistanceFromOrigin(p) {
27.11106 +        var n = this.options.normal;
27.11107 +        var d = this.options.distance;
27.11108 +        return p.dot(n) + d;
27.11109 +    }
27.11110 +
27.11111 +    function _onEnter(particle, overlap, dt) {
27.11112 +        var p = particle.position;
27.11113 +        var v = particle.velocity;
27.11114 +        var m = particle.mass;
27.11115 +        var n = this.options.normal;
27.11116 +        var action = this.options.onContact;
27.11117 +        var restitution = this.options.restitution;
27.11118 +        var impulse = this.impulse;
27.11119 +
27.11120 +        var drift = this.options.drift;
27.11121 +        var slop = -this.options.slop;
27.11122 +        var gamma = 0;
27.11123 +
27.11124 +        if (this._eventOutput) {
27.11125 +            var data = {particle : particle, wall : this, overlap : overlap, normal : n};
27.11126 +            this._eventOutput.emit('preCollision', data);
27.11127 +            this._eventOutput.emit('collision', data);
27.11128 +        }
27.11129 +
27.11130 +        switch (action) {
27.11131 +            case Wall.ON_CONTACT.REFLECT:
27.11132 +                var lambda = (overlap < slop)
27.11133 +                    ? -((1 + restitution) * n.dot(v) + drift / dt * (overlap - slop)) / (m * dt + gamma)
27.11134 +                    : -((1 + restitution) * n.dot(v)) / (m * dt + gamma);
27.11135 +
27.11136 +                impulse.set(n.mult(dt * lambda));
27.11137 +                particle.applyImpulse(impulse);
27.11138 +                particle.setPosition(p.add(n.mult(-overlap)));
27.11139 +                break;
27.11140 +        }
27.11141 +
27.11142 +        if (this._eventOutput) this._eventOutput.emit('postCollision', data);
27.11143 +    }
27.11144 +
27.11145 +    function _onExit(particle, overlap, dt) {
27.11146 +        var action = this.options.onContact;
27.11147 +        var p = particle.position;
27.11148 +        var n = this.options.normal;
27.11149 +
27.11150 +        if (action === Wall.ON_CONTACT.REFLECT) {
27.11151 +            particle.setPosition(p.add(n.mult(-overlap)));
27.11152 +        }
27.11153 +    }
27.11154 +
27.11155 +    /**
27.11156 +     * Adds an impulse to a physics body's velocity due to the wall constraint
27.11157 +     *
27.11158 +     * @method applyConstraint
27.11159 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
27.11160 +     * @param source {Body}         The source of the constraint
27.11161 +     * @param dt {Number}           Delta time
27.11162 +     */
27.11163 +    Wall.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.11164 +        var n = this.options.normal;
27.11165 +
27.11166 +        for (var i = 0; i < targets.length; i++) {
27.11167 +            var particle = targets[i];
27.11168 +            var p = particle.position;
27.11169 +            var v = particle.velocity;
27.11170 +            var r = particle.radius || 0;
27.11171 +
27.11172 +            var overlap = _getDistanceFromOrigin.call(this, p.add(n.mult(-r)));
27.11173 +            var nv = _getNormalVelocity.call(this, n, v);
27.11174 +
27.11175 +            if (overlap <= 0) {
27.11176 +                if (nv < 0) _onEnter.call(this, particle, overlap, dt);
27.11177 +                else _onExit.call(this, particle, overlap, dt);
27.11178 +            }
27.11179 +        }
27.11180 +    };
27.11181 +
27.11182 +    module.exports = Wall;
27.11183 +});
27.11184 +
27.11185 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11186 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11187 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11188 + *
27.11189 + * Owner: david@famo.us
27.11190 + * @license MPL 2.0
27.11191 + * @copyright Famous Industries, Inc. 2014
27.11192 + */
27.11193 +
27.11194 +define('famous/transitions/WallTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/physics/constraints/Wall','famous/math/Vector'],function(require, exports, module) {
27.11195 +    var PE = require('famous/physics/PhysicsEngine');
27.11196 +    var Particle = require('famous/physics/bodies/Particle');
27.11197 +    var Spring = require('famous/physics/forces/Spring');
27.11198 +    var Wall = require('famous/physics/constraints/Wall');
27.11199 +    var Vector = require('famous/math/Vector');
27.11200 +
27.11201 +    /**
27.11202 +     * WallTransition is a method of transitioning between two values (numbers,
27.11203 +     *   or arrays of numbers) with a bounce. Unlike a SpringTransition
27.11204 +     *   The transition will not overshoot the target, but bounce back against it.
27.11205 +     *   The behavior of the bounce is specified by the transition options.
27.11206 +     *
27.11207 +     * @class WallTransition
27.11208 +     * @constructor
27.11209 +     *
27.11210 +     * @param {Number|Array} [state=0] Initial state
27.11211 +     */
27.11212 +    function WallTransition(state) {
27.11213 +        state = state || 0;
27.11214 +
27.11215 +        this.endState  = new Vector(state);
27.11216 +        this.initState = new Vector();
27.11217 +
27.11218 +        this.spring = new Spring({anchor : this.endState});
27.11219 +        this.wall   = new Wall();
27.11220 +
27.11221 +        this._restTolerance = 1e-10;
27.11222 +        this._dimensions = 1;
27.11223 +        this._absRestTolerance = this._restTolerance;
27.11224 +        this._callback = undefined;
27.11225 +
27.11226 +        this.PE = new PE();
27.11227 +        this.particle = new Particle();
27.11228 +
27.11229 +        this.PE.addBody(this.particle);
27.11230 +        this.PE.attach([this.wall, this.spring], this.particle);
27.11231 +    }
27.11232 +
27.11233 +    WallTransition.SUPPORTS_MULTIPLE = 3;
27.11234 +
27.11235 +    /**
27.11236 +     * @property WallTransition.DEFAULT_OPTIONS
27.11237 +     * @type Object
27.11238 +     * @protected
27.11239 +     * @static
27.11240 +     */
27.11241 +    WallTransition.DEFAULT_OPTIONS = {
27.11242 +
27.11243 +        /**
27.11244 +         * The amount of time in milliseconds taken for one complete oscillation
27.11245 +         * when there is no damping
27.11246 +         *    Range : [0, Infinity]
27.11247 +         *
27.11248 +         * @attribute period
27.11249 +         * @type Number
27.11250 +         * @default 300
27.11251 +         */
27.11252 +        period : 300,
27.11253 +
27.11254 +        /**
27.11255 +         * The damping of the snap.
27.11256 +         *    Range : [0, 1]
27.11257 +         *    0 = no damping, and the spring will oscillate forever
27.11258 +         *    1 = critically damped (the spring will never oscillate)
27.11259 +         *
27.11260 +         * @attribute dampingRatio
27.11261 +         * @type Number
27.11262 +         * @default 0.5
27.11263 +         */
27.11264 +        dampingRatio : 0.5,
27.11265 +
27.11266 +        /**
27.11267 +         * The initial velocity of the transition.
27.11268 +         *
27.11269 +         * @attribute velocity
27.11270 +         * @type Number|Array
27.11271 +         * @default 0
27.11272 +         */
27.11273 +        velocity : 0,
27.11274 +
27.11275 +        /**
27.11276 +         * The percentage of momentum transferred to the wall
27.11277 +         *
27.11278 +         * @attribute restitution
27.11279 +         * @type Number
27.11280 +         * @default 0.5
27.11281 +         */
27.11282 +        resitution : 0.5
27.11283 +    };
27.11284 +
27.11285 +    function _getEnergy() {
27.11286 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
27.11287 +    }
27.11288 +
27.11289 +    function _setAbsoluteRestTolerance() {
27.11290 +        var distance = this.endState.sub(this.initState).normSquared();
27.11291 +        this._absRestTolerance = (distance === 0)
27.11292 +            ? this._restTolerance
27.11293 +            : this._restTolerance * distance;
27.11294 +    }
27.11295 +
27.11296 +    function _wake() {
27.11297 +        this.PE.wake();
27.11298 +    }
27.11299 +
27.11300 +    function _sleep() {
27.11301 +        this.PE.sleep();
27.11302 +    }
27.11303 +
27.11304 +    function _setTarget(target) {
27.11305 +        this.endState.set(target);
27.11306 +
27.11307 +        var dist = this.endState.sub(this.initState).norm();
27.11308 +
27.11309 +        this.wall.setOptions({
27.11310 +            distance : this.endState.norm(),
27.11311 +            normal : (dist === 0)
27.11312 +                ? this.particle.velocity.normalize(-1)
27.11313 +                : this.endState.sub(this.initState).normalize(-1)
27.11314 +        });
27.11315 +
27.11316 +        _setAbsoluteRestTolerance.call(this);
27.11317 +    }
27.11318 +
27.11319 +    function _setParticlePosition(p) {
27.11320 +        this.particle.position.set(p);
27.11321 +    }
27.11322 +
27.11323 +    function _setParticleVelocity(v) {
27.11324 +        this.particle.velocity.set(v);
27.11325 +    }
27.11326 +
27.11327 +    function _getParticlePosition() {
27.11328 +        return (this._dimensions === 0)
27.11329 +            ? this.particle.getPosition1D()
27.11330 +            : this.particle.getPosition();
27.11331 +    }
27.11332 +
27.11333 +    function _getParticleVelocity() {
27.11334 +        return (this._dimensions === 0)
27.11335 +            ? this.particle.getVelocity1D()
27.11336 +            : this.particle.getVelocity();
27.11337 +    }
27.11338 +
27.11339 +    function _setCallback(callback) {
27.11340 +        this._callback = callback;
27.11341 +    }
27.11342 +
27.11343 +    function _update() {
27.11344 +        if (this.PE.isSleeping()) {
27.11345 +            if (this._callback) {
27.11346 +                var cb = this._callback;
27.11347 +                this._callback = undefined;
27.11348 +                cb();
27.11349 +            }
27.11350 +            return;
27.11351 +        }
27.11352 +        var energy = _getEnergy.call(this);
27.11353 +        if (energy < this._absRestTolerance) {
27.11354 +            _sleep.call(this);
27.11355 +            _setParticlePosition.call(this, this.endState);
27.11356 +            _setParticleVelocity.call(this, [0,0,0]);
27.11357 +        }
27.11358 +    }
27.11359 +
27.11360 +    function _setupDefinition(def) {
27.11361 +        var defaults = WallTransition.DEFAULT_OPTIONS;
27.11362 +        if (def.period === undefined) def.period = defaults.period;
27.11363 +        if (def.dampingRatio === undefined) def.dampingRatio = defaults.dampingRatio;
27.11364 +        if (def.velocity === undefined) def.velocity = defaults.velocity;
27.11365 +        if (def.restitution === undefined) def.restitution = defaults.restitution;
27.11366 +
27.11367 +        //setup spring
27.11368 +        this.spring.setOptions({
27.11369 +            period : def.period,
27.11370 +            dampingRatio : def.dampingRatio
27.11371 +        });
27.11372 +
27.11373 +        //setup wall
27.11374 +        this.wall.setOptions({
27.11375 +            restitution : def.restitution
27.11376 +        });
27.11377 +
27.11378 +        //setup particle
27.11379 +        _setParticleVelocity.call(this, def.velocity);
27.11380 +    }
27.11381 +
27.11382 +    /**
27.11383 +     * Resets the state and velocity
27.11384 +     *
27.11385 +     * @method reset
27.11386 +     *
27.11387 +     * @param {Number|Array}  state     State
27.11388 +     * @param  {Number|Array} [velocity] Velocity
27.11389 +     */
27.11390 +    WallTransition.prototype.reset = function reset(state, velocity) {
27.11391 +        this._dimensions = (state instanceof Array)
27.11392 +            ? state.length
27.11393 +            : 0;
27.11394 +
27.11395 +        this.initState.set(state);
27.11396 +        _setParticlePosition.call(this, state);
27.11397 +        if (velocity) _setParticleVelocity.call(this, velocity);
27.11398 +        _setTarget.call(this, state);
27.11399 +        _setCallback.call(this, undefined);
27.11400 +    };
27.11401 +
27.11402 +    /**
27.11403 +     * Getter for velocity
27.11404 +     *
27.11405 +     * @method getVelocity
27.11406 +     *
27.11407 +     * @return velocity {Number|Array}
27.11408 +     */
27.11409 +    WallTransition.prototype.getVelocity = function getVelocity() {
27.11410 +        return _getParticleVelocity.call(this);
27.11411 +    };
27.11412 +
27.11413 +    /**
27.11414 +     * Setter for velocity
27.11415 +     *
27.11416 +     * @method setVelocity
27.11417 +     *
27.11418 +     * @return velocity {Number|Array}
27.11419 +     */
27.11420 +    WallTransition.prototype.setVelocity = function setVelocity(velocity) {
27.11421 +        this.call(this, _setParticleVelocity(velocity));
27.11422 +    };
27.11423 +
27.11424 +    /**
27.11425 +     * Detects whether a transition is in progress
27.11426 +     *
27.11427 +     * @method isActive
27.11428 +     *
27.11429 +     * @return {Boolean}
27.11430 +     */
27.11431 +    WallTransition.prototype.isActive = function isActive() {
27.11432 +        return !this.PE.isSleeping();
27.11433 +    };
27.11434 +
27.11435 +    /**
27.11436 +     * Halt the transition
27.11437 +     *
27.11438 +     * @method halt
27.11439 +     */
27.11440 +    WallTransition.prototype.halt = function halt() {
27.11441 +        this.set(this.get());
27.11442 +    };
27.11443 +
27.11444 +    /**
27.11445 +     * Getter
27.11446 +     *
27.11447 +     * @method get
27.11448 +     *
27.11449 +     * @return state {Number|Array}
27.11450 +     */
27.11451 +    WallTransition.prototype.get = function get() {
27.11452 +        _update.call(this);
27.11453 +        return _getParticlePosition.call(this);
27.11454 +    };
27.11455 +
27.11456 +    /**
27.11457 +     * Set the end position and transition, with optional callback on completion.
27.11458 +     *
27.11459 +     * @method set
27.11460 +     *
27.11461 +     * @param state {Number|Array}      Final state
27.11462 +     * @param [definition] {Object}     Transition definition
27.11463 +     * @param [callback] {Function}     Callback
27.11464 +     */
27.11465 +    WallTransition.prototype.set = function set(state, definition, callback) {
27.11466 +        if (!definition) {
27.11467 +            this.reset(state);
27.11468 +            if (callback) callback();
27.11469 +            return;
27.11470 +        }
27.11471 +
27.11472 +        this._dimensions = (state instanceof Array)
27.11473 +            ? state.length
27.11474 +            : 0;
27.11475 +
27.11476 +        _wake.call(this);
27.11477 +        _setupDefinition.call(this, definition);
27.11478 +        _setTarget.call(this, state);
27.11479 +        _setCallback.call(this, callback);
27.11480 +    };
27.11481 +
27.11482 +    module.exports = WallTransition;
27.11483 +});
27.11484 +
27.11485 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11486 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11487 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11488 + *
27.11489 + * Owner: mark@famo.us
27.11490 + * @license MPL 2.0
27.11491 + * @copyright Famous Industries, Inc. 2014
27.11492 + */
27.11493 +
27.11494 +define('famous/surfaces/CanvasSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
27.11495 +    var Surface = require('famous/core/Surface');
27.11496 +
27.11497 +    /**
27.11498 +     * A surface containing an HTML5 Canvas element.
27.11499 +     *   This extends the Surface class.
27.11500 +     *
27.11501 +     * @class CanvasSurface
27.11502 +     * @extends Surface
27.11503 +     * @constructor
27.11504 +     * @param {Object} [options] overrides of default options
27.11505 +     * @param {Array.Number} [options.canvasSize] [width, height] for document element
27.11506 +     */
27.11507 +    function CanvasSurface(options) {
27.11508 +        if (options && options.canvasSize) this._canvasSize = options.canvasSize;
27.11509 +        Surface.apply(this, arguments);
27.11510 +        if (!this._canvasSize) this._canvasSize = this.getSize();
27.11511 +        this._backBuffer = document.createElement('canvas');
27.11512 +        if (this._canvasSize) {
27.11513 +            this._backBuffer.width = this._canvasSize[0];
27.11514 +            this._backBuffer.height = this._canvasSize[1];
27.11515 +        }
27.11516 +        this._contextId = undefined;
27.11517 +    }
27.11518 +
27.11519 +    CanvasSurface.prototype = Object.create(Surface.prototype);
27.11520 +    CanvasSurface.prototype.constructor = CanvasSurface;
27.11521 +    CanvasSurface.prototype.elementType = 'canvas';
27.11522 +    CanvasSurface.prototype.elementClass = 'famous-surface';
27.11523 +
27.11524 +    /**
27.11525 +     * Set inner document content.  Note that this is a noop for CanvasSurface.
27.11526 +     *
27.11527 +     * @method setContent
27.11528 +     *
27.11529 +     */
27.11530 +    CanvasSurface.prototype.setContent = function setContent() {};
27.11531 +
27.11532 +    /**
27.11533 +     * Place the document element this component manages into the document.
27.11534 +     *    This will draw the content to the document.
27.11535 +     *
27.11536 +     * @private
27.11537 +     * @method deploy
27.11538 +     * @param {Node} target document parent of this container
27.11539 +     */
27.11540 +    CanvasSurface.prototype.deploy = function deploy(target) {
27.11541 +        if (this._canvasSize) {
27.11542 +            target.width = this._canvasSize[0];
27.11543 +            target.height = this._canvasSize[1];
27.11544 +        }
27.11545 +        if (this._contextId === '2d') {
27.11546 +            target.getContext(this._contextId).drawImage(this._backBuffer, 0, 0);
27.11547 +            this._backBuffer.width = 0;
27.11548 +            this._backBuffer.height = 0;
27.11549 +        }
27.11550 +    };
27.11551 +
27.11552 +    /**
27.11553 +     * Remove this component and contained content from the document
27.11554 +     *
27.11555 +     * @private
27.11556 +     * @method recall
27.11557 +     *
27.11558 +     * @param {Node} target node to which the component was deployed
27.11559 +     */
27.11560 +    CanvasSurface.prototype.recall = function recall(target) {
27.11561 +        var size = this.getSize();
27.11562 +
27.11563 +        this._backBuffer.width = target.width;
27.11564 +        this._backBuffer.height = target.height;
27.11565 +
27.11566 +        if (this._contextId === '2d') {
27.11567 +            this._backBuffer.getContext(this._contextId).drawImage(target, 0, 0);
27.11568 +            target.width = 0;
27.11569 +            target.height = 0;
27.11570 +        }
27.11571 +    };
27.11572 +
27.11573 +    /**
27.11574 +     * Returns the canvas element's context
27.11575 +     *
27.11576 +     * @method getContext
27.11577 +     * @param {string} contextId context identifier
27.11578 +     */
27.11579 +    CanvasSurface.prototype.getContext = function getContext(contextId) {
27.11580 +        this._contextId = contextId;
27.11581 +        return this._currTarget ? this._currTarget.getContext(contextId) : this._backBuffer.getContext(contextId);
27.11582 +    };
27.11583 +
27.11584 +    /**
27.11585 +     *  Set the size of the surface and canvas element.
27.11586 +     *
27.11587 +     *  @method setSize
27.11588 +     *  @param {Array.number} size [width, height] of surface
27.11589 +     *  @param {Array.number} canvasSize [width, height] of canvas surface
27.11590 +     */
27.11591 +    CanvasSurface.prototype.setSize = function setSize(size, canvasSize) {
27.11592 +        Surface.prototype.setSize.apply(this, arguments);
27.11593 +        if (canvasSize) this._canvasSize = [canvasSize[0], canvasSize[1]];
27.11594 +        if (this._currTarget) {
27.11595 +            this._currTarget.width = this._canvasSize[0];
27.11596 +            this._currTarget.height = this._canvasSize[1];
27.11597 +        }
27.11598 +    };
27.11599 +
27.11600 +    module.exports = CanvasSurface;
27.11601 +});
27.11602 +
27.11603 +
27.11604 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11605 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11606 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11607 + *
27.11608 + * Owner: mark@famo.us
27.11609 + * @license MPL 2.0
27.11610 + * @copyright Famous Industries, Inc. 2014
27.11611 + */
27.11612 +
27.11613 +define('famous/surfaces/ContainerSurface',['require','exports','module','famous/core/Surface','famous/core/Context'],function(require, exports, module) {
27.11614 +    var Surface = require('famous/core/Surface');
27.11615 +    var Context = require('famous/core/Context');
27.11616 +
27.11617 +    /**
27.11618 +     * ContainerSurface is an object designed to contain surfaces and
27.11619 +     *   set properties to be applied to all of them at once.
27.11620 +     *   This extends the Surface class.
27.11621 +     *   A container surface will enforce these properties on the
27.11622 +     *   surfaces it contains:
27.11623 +     *
27.11624 +     *   size (clips contained surfaces to its own width and height);
27.11625 +     *
27.11626 +     *   origin;
27.11627 +     *
27.11628 +     *   its own opacity and transform, which will be automatically
27.11629 +     *   applied to  all Surfaces contained directly and indirectly.
27.11630 +     *
27.11631 +     * @class ContainerSurface
27.11632 +     * @extends Surface
27.11633 +     * @constructor
27.11634 +     * @param {Array.Number} [options.size] [width, height] in pixels
27.11635 +     * @param {Array.string} [options.classes] CSS classes to set on all inner content
27.11636 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
27.11637 +     * @param {string} [options.content] inner (HTML) content of surface (should not be used)
27.11638 +     */
27.11639 +    function ContainerSurface(options) {
27.11640 +        Surface.call(this, options);
27.11641 +        this._container = document.createElement('div');
27.11642 +        this._container.classList.add('famous-group');
27.11643 +        this._container.classList.add('famous-container-group');
27.11644 +        this._shouldRecalculateSize = false;
27.11645 +        this.context = new Context(this._container);
27.11646 +        this.setContent(this._container);
27.11647 +    }
27.11648 +
27.11649 +    ContainerSurface.prototype = Object.create(Surface.prototype);
27.11650 +    ContainerSurface.prototype.constructor = ContainerSurface;
27.11651 +    ContainerSurface.prototype.elementType = 'div';
27.11652 +    ContainerSurface.prototype.elementClass = 'famous-surface';
27.11653 +
27.11654 +    /**
27.11655 +     * Add renderables to this object's render tree
27.11656 +     *
27.11657 +     * @method add
27.11658 +     *
27.11659 +     * @param {Object} obj renderable object
27.11660 +     * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode
27.11661 +     */
27.11662 +    ContainerSurface.prototype.add = function add() {
27.11663 +        return this.context.add.apply(this.context, arguments);
27.11664 +    };
27.11665 +
27.11666 +    /**
27.11667 +     * Return spec for this surface.  Note: Can result in a size recalculation.
27.11668 +     *
27.11669 +     * @private
27.11670 +     * @method render
27.11671 +     *
27.11672 +     * @return {Object} render spec for this surface (spec id)
27.11673 +     */
27.11674 +    ContainerSurface.prototype.render = function render() {
27.11675 +        if (this._sizeDirty) this._shouldRecalculateSize = true;
27.11676 +        return Surface.prototype.render.apply(this, arguments);
27.11677 +    };
27.11678 +
27.11679 +    /**
27.11680 +     * Place the document element this component manages into the document.
27.11681 +     *
27.11682 +     * @private
27.11683 +     * @method deploy
27.11684 +     * @param {Node} target document parent of this container
27.11685 +     */
27.11686 +    ContainerSurface.prototype.deploy = function deploy() {
27.11687 +        this._shouldRecalculateSize = true;
27.11688 +        return Surface.prototype.deploy.apply(this, arguments);
27.11689 +    };
27.11690 +
27.11691 +    /**
27.11692 +     * Apply changes from this component to the corresponding document element.
27.11693 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.11694 +     * and matrix transforms.
27.11695 +     *
27.11696 +     * @private
27.11697 +     * @method commit
27.11698 +     * @param {Context} context commit context
27.11699 +     * @param {Transform} transform unused TODO
27.11700 +     * @param {Number} opacity  unused TODO
27.11701 +     * @param {Array.Number} origin unused TODO
27.11702 +     * @param {Array.Number} size unused TODO
27.11703 +     * @return {undefined} TODO returns an undefined value
27.11704 +     */
27.11705 +    ContainerSurface.prototype.commit = function commit(context, transform, opacity, origin, size) {
27.11706 +        var previousSize = this._size ? [this._size[0], this._size[1]] : null;
27.11707 +        var result = Surface.prototype.commit.apply(this, arguments);
27.11708 +        if (this._shouldRecalculateSize || (previousSize && (this._size[0] !== previousSize[0] || this._size[1] !== previousSize[1]))) {
27.11709 +            this.context.setSize();
27.11710 +            this._shouldRecalculateSize = false;
27.11711 +        }
27.11712 +        this.context.update();
27.11713 +        return result;
27.11714 +    };
27.11715 +
27.11716 +    module.exports = ContainerSurface;
27.11717 +});
27.11718 +
27.11719 +define('famous/surfaces/FormContainerSurface',['require','exports','module','./ContainerSurface'],function(require, exports, module) {
27.11720 +    var ContainerSurface = require('./ContainerSurface');
27.11721 +
27.11722 +    function FormContainerSurface(options) {
27.11723 +        if (options) this._method = options.method || '';
27.11724 +        ContainerSurface.apply(this, arguments);
27.11725 +    }
27.11726 +
27.11727 +    FormContainerSurface.prototype = Object.create(ContainerSurface.prototype);
27.11728 +    FormContainerSurface.prototype.constructor = FormContainerSurface;
27.11729 +
27.11730 +    FormContainerSurface.prototype.elementType = 'form';
27.11731 +
27.11732 +    FormContainerSurface.prototype.deploy = function deploy(target) {
27.11733 +        if (this._method) target.method = this._method;
27.11734 +        return ContainerSurface.prototype.deploy.apply(this, arguments);
27.11735 +    };
27.11736 +
27.11737 +    module.exports = FormContainerSurface;
27.11738 +});
27.11739 +
27.11740 +
27.11741 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11742 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11743 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11744 + *
27.11745 + * Owner: mark@famo.us
27.11746 + * @license MPL 2.0
27.11747 + * @copyright Famous Industries, Inc. 2014
27.11748 + */
27.11749 +
27.11750 +define('famous/surfaces/ImageSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
27.11751 +    var Surface = require('famous/core/Surface');
27.11752 +
27.11753 +    /**
27.11754 +     * A surface containing image content.
27.11755 +     *   This extends the Surface class.
27.11756 +     *
27.11757 +     * @class ImageSurface
27.11758 +     *
27.11759 +     * @extends Surface
27.11760 +     * @constructor
27.11761 +     * @param {Object} [options] overrides of default options
27.11762 +     */
27.11763 +    function ImageSurface(options) {
27.11764 +        this._imageUrl = undefined;
27.11765 +        Surface.apply(this, arguments);
27.11766 +    }
27.11767 +
27.11768 +    ImageSurface.prototype = Object.create(Surface.prototype);
27.11769 +    ImageSurface.prototype.constructor = ImageSurface;
27.11770 +    ImageSurface.prototype.elementType = 'img';
27.11771 +    ImageSurface.prototype.elementClass = 'famous-surface';
27.11772 +
27.11773 +    /**
27.11774 +     * Set content URL.  This will cause a re-rendering.
27.11775 +     * @method setContent
27.11776 +     * @param {string} imageUrl
27.11777 +     */
27.11778 +    ImageSurface.prototype.setContent = function setContent(imageUrl) {
27.11779 +        this._imageUrl = imageUrl;
27.11780 +        this._contentDirty = true;
27.11781 +    };
27.11782 +
27.11783 +    /**
27.11784 +     * Place the document element that this component manages into the document.
27.11785 +     *
27.11786 +     * @private
27.11787 +     * @method deploy
27.11788 +     * @param {Node} target document parent of this container
27.11789 +     */
27.11790 +    ImageSurface.prototype.deploy = function deploy(target) {
27.11791 +        target.src = this._imageUrl || '';
27.11792 +    };
27.11793 +
27.11794 +    /**
27.11795 +     * Remove this component and contained content from the document
27.11796 +     *
27.11797 +     * @private
27.11798 +     * @method recall
27.11799 +     *
27.11800 +     * @param {Node} target node to which the component was deployed
27.11801 +     */
27.11802 +    ImageSurface.prototype.recall = function recall(target) {
27.11803 +        target.src = '';
27.11804 +    };
27.11805 +
27.11806 +    module.exports = ImageSurface;
27.11807 +});
27.11808 +
27.11809 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11810 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11811 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11812 + *
27.11813 + * Owner: mark@famo.us
27.11814 + * @license MPL 2.0
27.11815 + * @copyright Famous Industries, Inc. 2014
27.11816 + */
27.11817 +
27.11818 +define('famous/surfaces/InputSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
27.11819 +    var Surface = require('famous/core/Surface');
27.11820 +
27.11821 +    /**
27.11822 +     * A Famo.us surface in the form of an HTML input element.
27.11823 +     *   This extends the Surface class.
27.11824 +     *
27.11825 +     * @class InputSurface
27.11826 +     * @extends Surface
27.11827 +     * @constructor
27.11828 +     * @param {Object} [options] overrides of default options
27.11829 +     * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an <input> element
27.11830 +     * @param {string} [options.type] specifies the type of element to display (e.g. 'datetime', 'text', 'button', etc.)
27.11831 +     * @param {string} [options.value] value of text
27.11832 +     */
27.11833 +    function InputSurface(options) {
27.11834 +        this._placeholder = options.placeholder || '';
27.11835 +        this._value       = options.value || '';
27.11836 +        this._type        = options.type || 'text';
27.11837 +        this._name        = options.name || '';
27.11838 +
27.11839 +        Surface.apply(this, arguments);
27.11840 +
27.11841 +        this.on('click', this.focus.bind(this));
27.11842 +        window.addEventListener('click', function(event) {
27.11843 +            if (event.target !== this._currTarget) this.blur();
27.11844 +        }.bind(this));
27.11845 +    }
27.11846 +    InputSurface.prototype = Object.create(Surface.prototype);
27.11847 +    InputSurface.prototype.constructor = InputSurface;
27.11848 +
27.11849 +    InputSurface.prototype.elementType = 'input';
27.11850 +    InputSurface.prototype.elementClass = 'famous-surface';
27.11851 +
27.11852 +    /**
27.11853 +     * Set placeholder text.  Note: Triggers a repaint.
27.11854 +     *
27.11855 +     * @method setPlaceholder
27.11856 +     * @param {string} str Value to set the placeholder to.
27.11857 +     * @return {InputSurface} this, allowing method chaining.
27.11858 +     */
27.11859 +    InputSurface.prototype.setPlaceholder = function setPlaceholder(str) {
27.11860 +        this._placeholder = str;
27.11861 +        this._contentDirty = true;
27.11862 +        return this;
27.11863 +    };
27.11864 +
27.11865 +    /**
27.11866 +     * Focus on the current input, pulling up the keyboard on mobile.
27.11867 +     *
27.11868 +     * @method focus
27.11869 +     * @return {InputSurface} this, allowing method chaining.
27.11870 +     */
27.11871 +    InputSurface.prototype.focus = function focus() {
27.11872 +        if (this._currTarget) this._currTarget.focus();
27.11873 +        return this;
27.11874 +    };
27.11875 +
27.11876 +    /**
27.11877 +     * Blur the current input, hiding the keyboard on mobile.
27.11878 +     *
27.11879 +     * @method blur
27.11880 +     * @return {InputSurface} this, allowing method chaining.
27.11881 +     */
27.11882 +    InputSurface.prototype.blur = function blur() {
27.11883 +        if (this._currTarget) this._currTarget.blur();
27.11884 +        return this;
27.11885 +    };
27.11886 +
27.11887 +    /**
27.11888 +     * Set the placeholder conent.
27.11889 +     *   Note: Triggers a repaint next tick.
27.11890 +     *
27.11891 +     * @method setValue
27.11892 +     * @param {string} str Value to set the main input value to.
27.11893 +     * @return {InputSurface} this, allowing method chaining.
27.11894 +     */
27.11895 +    InputSurface.prototype.setValue = function setValue(str) {
27.11896 +        this._value = str;
27.11897 +        this._contentDirty = true;
27.11898 +        return this;
27.11899 +    };
27.11900 +
27.11901 +    /**
27.11902 +     * Set the type of element to display conent.
27.11903 +     *   Note: Triggers a repaint next tick.
27.11904 +     *
27.11905 +     * @method setType
27.11906 +     * @param {string} str type of the input surface (e.g. 'button', 'text')
27.11907 +     * @return {InputSurface} this, allowing method chaining.
27.11908 +     */
27.11909 +    InputSurface.prototype.setType = function setType(str) {
27.11910 +        this._type = str;
27.11911 +        this._contentDirty = true;
27.11912 +        return this;
27.11913 +    };
27.11914 +
27.11915 +    /**
27.11916 +     * Get the value of the inner content of the element (e.g. the entered text)
27.11917 +     *
27.11918 +     * @method getValue
27.11919 +     * @return {string} value of element
27.11920 +     */
27.11921 +    InputSurface.prototype.getValue = function getValue() {
27.11922 +        if (this._currTarget) {
27.11923 +            return this._currTarget.value;
27.11924 +        }
27.11925 +        else {
27.11926 +            return this._value;
27.11927 +        }
27.11928 +    };
27.11929 +
27.11930 +    /**
27.11931 +     * Set the name attribute of the element.
27.11932 +     *   Note: Triggers a repaint next tick.
27.11933 +     *
27.11934 +     * @method setName
27.11935 +     * @param {string} str element name
27.11936 +     * @return {InputSurface} this, allowing method chaining.
27.11937 +     */
27.11938 +    InputSurface.prototype.setName = function setName(str) {
27.11939 +        this._name = str;
27.11940 +        this._contentDirty = true;
27.11941 +        return this;
27.11942 +    };
27.11943 +
27.11944 +    /**
27.11945 +     * Get the name attribute of the element.
27.11946 +     *
27.11947 +     * @method getName
27.11948 +     * @return {string} name of element
27.11949 +     */
27.11950 +    InputSurface.prototype.getName = function getName() {
27.11951 +        return this._name;
27.11952 +    };
27.11953 +
27.11954 +    /**
27.11955 +     * Place the document element this component manages into the document.
27.11956 +     *
27.11957 +     * @private
27.11958 +     * @method deploy
27.11959 +     * @param {Node} target document parent of this container
27.11960 +     */
27.11961 +    InputSurface.prototype.deploy = function deploy(target) {
27.11962 +        if (this._placeholder !== '') target.placeholder = this._placeholder;
27.11963 +        target.value = this._value;
27.11964 +        target.type = this._type;
27.11965 +        target.name = this._name;
27.11966 +    };
27.11967 +
27.11968 +    module.exports = InputSurface;
27.11969 +});
27.11970 +
27.11971 +define('famous/surfaces/SubmitInputSurface',['require','exports','module','./InputSurface'],function(require, exports, module) {
27.11972 +    var InputSurface = require('./InputSurface');
27.11973 +
27.11974 +    function SubmitInputSurface(options) {
27.11975 +        InputSurface.apply(this, arguments);
27.11976 +        this._type = 'submit';
27.11977 +        if (options && options.onClick) this.setOnClick(options.onClick);
27.11978 +    }
27.11979 +
27.11980 +    SubmitInputSurface.prototype = Object.create(InputSurface.prototype);
27.11981 +    SubmitInputSurface.prototype.constructor = SubmitInputSurface;
27.11982 +
27.11983 +    SubmitInputSurface.prototype.setOnClick = function(onClick) {
27.11984 +        this.onClick = onClick;
27.11985 +    };
27.11986 +
27.11987 +    SubmitInputSurface.prototype.deploy = function deploy(target) {
27.11988 +        if (this.onclick) target.onClick = this.onClick;
27.11989 +        InputSurface.prototype.deploy.apply(this, arguments);
27.11990 +    };
27.11991 +
27.11992 +    module.exports = SubmitInputSurface;
27.11993 +});
27.11994 +
27.11995 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.11996 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.11997 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.11998 + *
27.11999 + * Owner: mark@famo.us
27.12000 + * @license MPL 2.0
27.12001 + * @copyright Famous Industries, Inc. 2014
27.12002 + */
27.12003 +
27.12004 +define('famous/surfaces/TextareaSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
27.12005 +    var Surface = require('famous/core/Surface');
27.12006 +
27.12007 +    /**
27.12008 +     * A Famo.us surface in the form of an HTML textarea element.
27.12009 +     *   This extends the Surface class.
27.12010 +     *
27.12011 +     * @class TextareaSurface
27.12012 +     * @extends Surface
27.12013 +     * @constructor
27.12014 +     * @param {Object} [options] overrides of default options
27.12015 +     * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an textarea element
27.12016 +     * @param {string} [options.value] value of text
27.12017 +     * @param {string} [options.name] specifies the name of textarea
27.12018 +     * @param {string} [options.wrap] specify 'hard' or 'soft' wrap for textarea
27.12019 +     * @param {number} [options.cols] number of columns in textarea
27.12020 +     * @param {number} [options.rows] number of rows in textarea
27.12021 +     */
27.12022 +    function TextareaSurface(options) {
27.12023 +        this._placeholder = options.placeholder || '';
27.12024 +        this._value       = options.value || '';
27.12025 +        this._name        = options.name || '';
27.12026 +        this._wrap        = options.wrap || '';
27.12027 +        this._cols        = options.cols || '';
27.12028 +        this._rows        = options.rows || '';
27.12029 +
27.12030 +        Surface.apply(this, arguments);
27.12031 +        this.on('click', this.focus.bind(this));
27.12032 +    }
27.12033 +    TextareaSurface.prototype = Object.create(Surface.prototype);
27.12034 +    TextareaSurface.prototype.constructor = TextareaSurface;
27.12035 +
27.12036 +    TextareaSurface.prototype.elementType = 'textarea';
27.12037 +    TextareaSurface.prototype.elementClass = 'famous-surface';
27.12038 +
27.12039 +    /**
27.12040 +     * Set placeholder text.  Note: Triggers a repaint.
27.12041 +     *
27.12042 +     * @method setPlaceholder
27.12043 +     * @param {string} str Value to set the placeholder to.
27.12044 +     * @return {TextareaSurface} this, allowing method chaining.
27.12045 +     */
27.12046 +    TextareaSurface.prototype.setPlaceholder = function setPlaceholder(str) {
27.12047 +        this._placeholder = str;
27.12048 +        this._contentDirty = true;
27.12049 +        return this;
27.12050 +    };
27.12051 +
27.12052 +    /**
27.12053 +     * Focus on the current input, pulling up the keyboard on mobile.
27.12054 +     *
27.12055 +     * @method focus
27.12056 +     * @return {TextareaSurface} this, allowing method chaining.
27.12057 +     */
27.12058 +    TextareaSurface.prototype.focus = function focus() {
27.12059 +        if (this._currTarget) this._currTarget.focus();
27.12060 +        return this;
27.12061 +    };
27.12062 +
27.12063 +    /**
27.12064 +     * Blur the current input, hiding the keyboard on mobile.
27.12065 +     *
27.12066 +     * @method focus
27.12067 +     * @return {TextareaSurface} this, allowing method chaining.
27.12068 +     */
27.12069 +    TextareaSurface.prototype.blur = function blur() {
27.12070 +        if (this._currTarget) this._currTarget.blur();
27.12071 +        return this;
27.12072 +    };
27.12073 +
27.12074 +    /**
27.12075 +     * Set the value of textarea.
27.12076 +     *   Note: Triggers a repaint next tick.
27.12077 +     *
27.12078 +     * @method setValue
27.12079 +     * @param {string} str Value to set the main textarea value to.
27.12080 +     * @return {TextareaSurface} this, allowing method chaining.
27.12081 +     */
27.12082 +    TextareaSurface.prototype.setValue = function setValue(str) {
27.12083 +        this._value = str;
27.12084 +        this._contentDirty = true;
27.12085 +        return this;
27.12086 +    };
27.12087 +
27.12088 +    /**
27.12089 +     * Get the value of the inner content of the textarea (e.g. the entered text)
27.12090 +     *
27.12091 +     * @method getValue
27.12092 +     * @return {string} value of element
27.12093 +     */
27.12094 +    TextareaSurface.prototype.getValue = function getValue() {
27.12095 +        if (this._currTarget) {
27.12096 +            return this._currTarget.value;
27.12097 +        }
27.12098 +        else {
27.12099 +            return this._value;
27.12100 +        }
27.12101 +    };
27.12102 +
27.12103 +    /**
27.12104 +     * Set the name attribute of the element.
27.12105 +     *   Note: Triggers a repaint next tick.
27.12106 +     *
27.12107 +     * @method setName
27.12108 +     * @param {string} str element name
27.12109 +     * @return {TextareaSurface} this, allowing method chaining.
27.12110 +     */
27.12111 +    TextareaSurface.prototype.setName = function setName(str) {
27.12112 +        this._name = str;
27.12113 +        this._contentDirty = true;
27.12114 +        return this;
27.12115 +    };
27.12116 +
27.12117 +    /**
27.12118 +     * Get the name attribute of the element.
27.12119 +     *
27.12120 +     * @method getName
27.12121 +     * @return {string} name of element
27.12122 +     */
27.12123 +    TextareaSurface.prototype.getName = function getName() {
27.12124 +        return this._name;
27.12125 +    };
27.12126 +
27.12127 +    /**
27.12128 +     * Set the wrap of textarea.
27.12129 +     *   Note: Triggers a repaint next tick.
27.12130 +     *
27.12131 +     * @method setWrap
27.12132 +     * @param {string} str wrap of the textarea surface (e.g. 'soft', 'hard')
27.12133 +     * @return {TextareaSurface} this, allowing method chaining.
27.12134 +     */
27.12135 +    TextareaSurface.prototype.setWrap = function setWrap(str) {
27.12136 +        this._wrap = str;
27.12137 +        this._contentDirty = true;
27.12138 +        return this;
27.12139 +    };
27.12140 +
27.12141 +    /**
27.12142 +     * Set the number of columns visible in the textarea.
27.12143 +     *   Note: Overridden by surface size; set width to true. (eg. size: [true, *])
27.12144 +     *         Triggers a repaint next tick.
27.12145 +     *
27.12146 +     * @method setColumns
27.12147 +     * @param {number} num columns in textarea surface
27.12148 +     * @return {TextareaSurface} this, allowing method chaining.
27.12149 +     */
27.12150 +    TextareaSurface.prototype.setColumns = function setColumns(num) {
27.12151 +        this._cols = num;
27.12152 +        this._contentDirty = true;
27.12153 +        return this;
27.12154 +    };
27.12155 +
27.12156 +    /**
27.12157 +     * Set the number of rows visible in the textarea.
27.12158 +     *   Note: Overridden by surface size; set height to true. (eg. size: [*, true])
27.12159 +     *         Triggers a repaint next tick.
27.12160 +     *
27.12161 +     * @method setRows
27.12162 +     * @param {number} num rows in textarea surface
27.12163 +     * @return {TextareaSurface} this, allowing method chaining.
27.12164 +     */
27.12165 +    TextareaSurface.prototype.setRows = function setRows(num) {
27.12166 +        this._rows = num;
27.12167 +        this._contentDirty = true;
27.12168 +        return this;
27.12169 +    };
27.12170 +
27.12171 +    /**
27.12172 +     * Place the document element this component manages into the document.
27.12173 +     *
27.12174 +     * @private
27.12175 +     * @method deploy
27.12176 +     * @param {Node} target document parent of this container
27.12177 +     */
27.12178 +    TextareaSurface.prototype.deploy = function deploy(target) {
27.12179 +        if (this._placeholder !== '') target.placeholder = this._placeholder;
27.12180 +        if (this._value !== '') target.value = this._value;
27.12181 +        if (this._name !== '') target.name = this._name;
27.12182 +        if (this._wrap !== '') target.wrap = this._wrap;
27.12183 +        if (this._cols !== '') target.cols = this._cols;
27.12184 +        if (this._rows !== '') target.rows = this._rows;
27.12185 +    };
27.12186 +
27.12187 +    module.exports = TextareaSurface;
27.12188 +});
27.12189 +
27.12190 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12191 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12192 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12193 + *
27.12194 + * Owner: mark@famo.us
27.12195 + * @license MPL 2.0
27.12196 + * @copyright Famous Industries, Inc. 2014
27.12197 + */
27.12198 +
27.12199 +define('famous/surfaces/VideoSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
27.12200 +    var Surface = require('famous/core/Surface');
27.12201 +
27.12202 +    /**
27.12203 +     * Creates a famous surface containing video content. Currently adding
27.12204 +     *   controls and manipulating the video are not supported through the
27.12205 +     *   surface interface, but can be accomplished via standard JavaScript
27.12206 +     *   manipulation of the video DOM element.
27.12207 +     *   This extends the Surface class.
27.12208 +     *
27.12209 +     * @class VideoSurface
27.12210 +     * @extends Surface
27.12211 +     * @constructor
27.12212 +     * @param {Object} [options] default option overrides
27.12213 +     * @param {Array.Number} [options.size] [width, height] in pixels
27.12214 +     * @param {Array.string} [options.classes] CSS classes to set on inner content
27.12215 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
27.12216 +     * @param {string} [options.content] inner (HTML) content of surface
27.12217 +     * @param {boolean} [options.autoplay] autoplay
27.12218 +     */
27.12219 +    function VideoSurface(options) {
27.12220 +        this._videoUrl = undefined;
27.12221 +        this.options = Object.create(VideoSurface.DEFAULT_OPTIONS);
27.12222 +        if (options) this.setOptions(options);
27.12223 +
27.12224 +        Surface.apply(this, arguments);
27.12225 +    }
27.12226 +    VideoSurface.prototype = Object.create(Surface.prototype);
27.12227 +    VideoSurface.prototype.constructor = VideoSurface;
27.12228 +
27.12229 +    VideoSurface.DEFAULT_OPTIONS = {
27.12230 +        autoplay: false
27.12231 +    };
27.12232 +
27.12233 +    VideoSurface.prototype.elementType = 'video';
27.12234 +    VideoSurface.prototype.elementClass = 'famous-surface';
27.12235 +
27.12236 +    /**
27.12237 +     * Set internal options, overriding any default options
27.12238 +     *
27.12239 +     * @method setOptions
27.12240 +     *
27.12241 +     * @param {Object} [options] overrides of default options
27.12242 +     * @param {Boolean} [options.autoplay] HTML autoplay
27.12243 +     */
27.12244 +    VideoSurface.prototype.setOptions = function setOptions(options) {
27.12245 +        for (var key in VideoSurface.DEFAULT_OPTIONS) {
27.12246 +            if (options[key] !== undefined) this.options[key] = options[key];
27.12247 +        }
27.12248 +    };
27.12249 +
27.12250 +    /**
27.12251 +     * Set url of the video.
27.12252 +     *
27.12253 +     * @method setContent
27.12254 +     * @param {string} videoUrl URL
27.12255 +     */
27.12256 +    VideoSurface.prototype.setContent = function setContent(videoUrl) {
27.12257 +        this._videoUrl = videoUrl;
27.12258 +        this._contentDirty = true;
27.12259 +    };
27.12260 +
27.12261 +    /**
27.12262 +     * Place the document element this component manages into the document.
27.12263 +     *   Note: In the case of VideoSurface, simply changes the options on the target.
27.12264 +     *
27.12265 +     * @private
27.12266 +     * @method deploy
27.12267 +     * @param {Node} target document parent of this container
27.12268 +     */
27.12269 +    VideoSurface.prototype.deploy = function deploy(target) {
27.12270 +        target.src = this._videoUrl;
27.12271 +        target.autoplay = this.options.autoplay;
27.12272 +    };
27.12273 +
27.12274 +    /**
27.12275 +     * Remove this component and contained content from the document.
27.12276 +     *   Note: This doesn't actually remove the <video> element from the
27.12277 +     *   document.
27.12278 +     * @private
27.12279 +     * @method recall
27.12280 +     *
27.12281 +     * @param {Node} target node to which the component was deployed
27.12282 +     */
27.12283 +    VideoSurface.prototype.recall = function recall(target) {
27.12284 +        target.src = '';
27.12285 +    };
27.12286 +
27.12287 +    module.exports = VideoSurface;
27.12288 +});
27.12289 +
27.12290 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12291 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12292 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12293 + *
27.12294 + * Owner: mark@famo.us
27.12295 + * @license MPL 2.0
27.12296 + * @copyright Famous Industries, Inc. 2014
27.12297 + */
27.12298 +
27.12299 +define('famous/utilities/KeyCodes',['require','exports','module'],function(require, exports, module) {
27.12300 +
27.12301 +    /**
27.12302 +     * Collection to map keyboard codes in plain english
27.12303 +     *
27.12304 +     * @class KeyCodes
27.12305 +     * @static
27.12306 +     */
27.12307 +    var KeyCodes = {
27.12308 +        0 : 48,
27.12309 +        1 : 49,
27.12310 +        2 : 50,
27.12311 +        3 : 51,
27.12312 +        4 : 52,
27.12313 +        5 : 53,
27.12314 +        6 : 54,
27.12315 +        7 : 55,
27.12316 +        8 : 56,
27.12317 +        9 : 57,
27.12318 +        a : 97,
27.12319 +        b : 98,
27.12320 +        c : 99,
27.12321 +        d : 100,
27.12322 +        e : 101,
27.12323 +        f : 102,
27.12324 +        g : 103,
27.12325 +        h : 104,
27.12326 +        i : 105,
27.12327 +        j : 106,
27.12328 +        k : 107,
27.12329 +        l : 108,
27.12330 +        m : 109,
27.12331 +        n : 110,
27.12332 +        o : 111,
27.12333 +        p : 112,
27.12334 +        q : 113,
27.12335 +        r : 114,
27.12336 +        s : 115,
27.12337 +        t : 116,
27.12338 +        u : 117,
27.12339 +        v : 118,
27.12340 +        w : 119,
27.12341 +        x : 120,
27.12342 +        y : 121,
27.12343 +        z : 122,
27.12344 +        A : 65,
27.12345 +        B : 66,
27.12346 +        C : 67,
27.12347 +        D : 68,
27.12348 +        E : 69,
27.12349 +        F : 70,
27.12350 +        G : 71,
27.12351 +        H : 72,
27.12352 +        I : 73,
27.12353 +        J : 74,
27.12354 +        K : 75,
27.12355 +        L : 76,
27.12356 +        M : 77,
27.12357 +        N : 78,
27.12358 +        O : 79,
27.12359 +        P : 80,
27.12360 +        Q : 81,
27.12361 +        R : 82,
27.12362 +        S : 83,
27.12363 +        T : 84,
27.12364 +        U : 85,
27.12365 +        V : 86,
27.12366 +        W : 87,
27.12367 +        X : 88,
27.12368 +        Y : 89,
27.12369 +        Z : 90,
27.12370 +        ENTER : 13,
27.12371 +        LEFT_ARROW: 37,
27.12372 +        RIGHT_ARROW: 39,
27.12373 +        UP_ARROW: 38,
27.12374 +        DOWN_ARROW: 40,
27.12375 +        SPACE: 32,
27.12376 +        SHIFT: 16,
27.12377 +        TAB: 9
27.12378 +    };
27.12379 +
27.12380 +    module.exports = KeyCodes;
27.12381 +});
27.12382 +
27.12383 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12384 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12385 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12386 + *
27.12387 + * Owner: mark@famo.us
27.12388 + * @license MPL 2.0
27.12389 + * @copyright Famous Industries, Inc. 2014
27.12390 + */
27.12391 +// TODO fix func-style
27.12392 +/*eslint func-style: [0, "declaration"] */
27.12393 +
27.12394 +define('famous/utilities/Timer',['require','exports','module','famous/core/Engine'],function(require, exports, module) {
27.12395 +    /**
27.12396 +     * An internal library to reproduce javascript time-based scheduling.
27.12397 +     *   Using standard javascript setTimeout methods can have a negative performance impact
27.12398 +     *   when combined with the Famous rendering process, so instead require Timer and call
27.12399 +     *   Timer.setTimeout, Timer.setInterval, etc.
27.12400 +     *
27.12401 +     * @class Timer
27.12402 +     * @constructor
27.12403 +     */
27.12404 +    var FamousEngine = require('famous/core/Engine');
27.12405 +
27.12406 +    var _event  = 'prerender';
27.12407 +
27.12408 +    var getTime = (window.performance) ?
27.12409 +        function() {
27.12410 +            return window.performance.now();
27.12411 +        }
27.12412 +        : function() {
27.12413 +            return Date.now();
27.12414 +        };
27.12415 +
27.12416 +    /**
27.12417 +     * Add a function to be run on every prerender
27.12418 +     *
27.12419 +     * @method addTimerFunction
27.12420 +     *
27.12421 +     * @param {function} fn function to be run every prerender
27.12422 +     *
27.12423 +     * @return {function} function passed in as parameter
27.12424 +     */
27.12425 +    function addTimerFunction(fn) {
27.12426 +        FamousEngine.on(_event, fn);
27.12427 +        return fn;
27.12428 +    }
27.12429 +
27.12430 +    /**
27.12431 +     * Wraps a function to be invoked after a certain amount of time.
27.12432 +     *  After a set duration has passed, it executes the function and
27.12433 +     *  removes it as a listener to 'prerender'.
27.12434 +     *
27.12435 +     * @method setTimeout
27.12436 +     *
27.12437 +     * @param {function} fn function to be run after a specified duration
27.12438 +     * @param {number} duration milliseconds from now to execute the function
27.12439 +     *
27.12440 +     * @return {function} function passed in as parameter
27.12441 +     */
27.12442 +    function setTimeout(fn, duration) {
27.12443 +        var t = getTime();
27.12444 +        var callback = function() {
27.12445 +            var t2 = getTime();
27.12446 +            if (t2 - t >= duration) {
27.12447 +                fn.apply(this, arguments);
27.12448 +                FamousEngine.removeListener(_event, callback);
27.12449 +            }
27.12450 +        };
27.12451 +        return addTimerFunction(callback);
27.12452 +    }
27.12453 +
27.12454 +    /**
27.12455 +     * Wraps a function to be invoked after a certain amount of time.
27.12456 +     *  After a set duration has passed, it executes the function and
27.12457 +     *  resets the execution time.
27.12458 +     *
27.12459 +     * @method setInterval
27.12460 +     *
27.12461 +     * @param {function} fn function to be run after a specified duration
27.12462 +     * @param {number} duration interval to execute function in milliseconds
27.12463 +     *
27.12464 +     * @return {function} function passed in as parameter
27.12465 +     */
27.12466 +    function setInterval(fn, duration) {
27.12467 +        var t = getTime();
27.12468 +        var callback = function() {
27.12469 +            var t2 = getTime();
27.12470 +            if (t2 - t >= duration) {
27.12471 +                fn.apply(this, arguments);
27.12472 +                t = getTime();
27.12473 +            }
27.12474 +        };
27.12475 +        return addTimerFunction(callback);
27.12476 +    }
27.12477 +
27.12478 +    /**
27.12479 +     * Wraps a function to be invoked after a certain amount of prerender ticks.
27.12480 +     *  Similar use to setTimeout but tied to the engine's run speed.
27.12481 +     *
27.12482 +     * @method after
27.12483 +     *
27.12484 +     * @param {function} fn function to be run after a specified amount of ticks
27.12485 +     * @param {number} numTicks number of prerender frames to wait
27.12486 +     *
27.12487 +     * @return {function} function passed in as parameter
27.12488 +     */
27.12489 +    function after(fn, numTicks) {
27.12490 +        if (numTicks === undefined) return undefined;
27.12491 +        var callback = function() {
27.12492 +            numTicks--;
27.12493 +            if (numTicks <= 0) { //in case numTicks is fraction or negative
27.12494 +                fn.apply(this, arguments);
27.12495 +                clear(callback);
27.12496 +            }
27.12497 +        };
27.12498 +        return addTimerFunction(callback);
27.12499 +    }
27.12500 +
27.12501 +    /**
27.12502 +     * Wraps a function to be continually invoked after a certain amount of prerender ticks.
27.12503 +     *  Similar use to setInterval but tied to the engine's run speed.
27.12504 +     *
27.12505 +     * @method every
27.12506 +     *
27.12507 +     * @param {function} fn function to be run after a specified amount of ticks
27.12508 +     * @param {number} numTicks number of prerender frames to wait
27.12509 +     *
27.12510 +     * @return {function} function passed in as parameter
27.12511 +     */
27.12512 +    function every(fn, numTicks) {
27.12513 +        numTicks = numTicks || 1;
27.12514 +        var initial = numTicks;
27.12515 +        var callback = function() {
27.12516 +            numTicks--;
27.12517 +            if (numTicks <= 0) { //in case numTicks is fraction or negative
27.12518 +                fn.apply(this, arguments);
27.12519 +                numTicks = initial;
27.12520 +            }
27.12521 +        };
27.12522 +        return addTimerFunction(callback);
27.12523 +    }
27.12524 +
27.12525 +    /**
27.12526 +     * Remove a function that gets called every prerender
27.12527 +     *
27.12528 +     * @method clear
27.12529 +     *
27.12530 +     * @param {function} fn event linstener
27.12531 +     */
27.12532 +    function clear(fn) {
27.12533 +        FamousEngine.removeListener(_event, fn);
27.12534 +    }
27.12535 +
27.12536 +    /**
27.12537 +     * Executes a function after a certain amount of time. Makes sure
27.12538 +     *  the function is not run multiple times.
27.12539 +     *
27.12540 +     * @method debounce
27.12541 +     *
27.12542 +     * @param {function} func function to run after certain amount of time
27.12543 +     * @param {number} wait amount of time
27.12544 +     *
27.12545 +     * @return {function} function that is not able to debounce
27.12546 +     */
27.12547 +    function debounce(func, wait) {
27.12548 +        var timeout;
27.12549 +        var ctx;
27.12550 +        var timestamp;
27.12551 +        var result;
27.12552 +        var args;
27.12553 +        return function() {
27.12554 +            ctx = this;
27.12555 +            args = arguments;
27.12556 +            timestamp = getTime();
27.12557 +
27.12558 +            var fn = function() {
27.12559 +                var last = getTime - timestamp;
27.12560 +
27.12561 +                if (last < wait) {
27.12562 +                    timeout = setTimeout(fn, wait - last);
27.12563 +                } else {
27.12564 +                    timeout = null;
27.12565 +                    result = func.apply(ctx, args);
27.12566 +                }
27.12567 +            };
27.12568 +
27.12569 +            clear(timeout);
27.12570 +            timeout = setTimeout(fn, wait);
27.12571 +
27.12572 +            return result;
27.12573 +        };
27.12574 +    }
27.12575 +
27.12576 +    module.exports = {
27.12577 +        setTimeout : setTimeout,
27.12578 +        setInterval : setInterval,
27.12579 +        debounce : debounce,
27.12580 +        after : after,
27.12581 +        every : every,
27.12582 +        clear : clear
27.12583 +    };
27.12584 +
27.12585 +});
27.12586 +
27.12587 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12588 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12589 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12590 + *
27.12591 + * Owner: mike@famo.us
27.12592 + * @license MPL 2.0
27.12593 + * @copyright Famous Industries, Inc. 2014
27.12594 + */
27.12595 +
27.12596 +define('famous/views/ContextualView',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/EventHandler','famous/core/OptionsManager'],function(require, exports, module) {
27.12597 +    var Entity = require('famous/core/Entity');
27.12598 +    var Transform = require('famous/core/Transform');
27.12599 +    var EventHandler = require('famous/core/EventHandler');
27.12600 +    var OptionsManager = require('famous/core/OptionsManager');
27.12601 +
27.12602 +    /**
27.12603 +     * ContextualView is an interface for creating views that need to
27.12604 +     *   be aware of their parent's transform, size, and/or origin.
27.12605 +     *   Consists of a OptionsManager paired with an input EventHandler
27.12606 +     *   and an output EventHandler. Meant to be extended by the developer.
27.12607 +     * @class ContextualView
27.12608 +     * @constructor
27.12609 +     * @param {Options} [options] An object of configurable options.
27.12610 +     */
27.12611 +    function ContextualView(options) {
27.12612 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS || ContextualView.DEFAULT_OPTIONS);
27.12613 +        this._optionsManager = new OptionsManager(this.options);
27.12614 +        if (options) this.setOptions(options);
27.12615 +
27.12616 +        this._eventInput = new EventHandler();
27.12617 +        this._eventOutput = new EventHandler();
27.12618 +        EventHandler.setInputHandler(this, this._eventInput);
27.12619 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.12620 +
27.12621 +        this._id = Entity.register(this);
27.12622 +    }
27.12623 +
27.12624 +    ContextualView.DEFAULT_OPTIONS = {};
27.12625 +
27.12626 +    /**
27.12627 +     * Patches the ContextualLayout instance's options with the passed-in ones.
27.12628 +     *
27.12629 +     * @method setOptions
27.12630 +     * @param {Options} options An object of configurable options for the ContextualLayout instance.
27.12631 +     */
27.12632 +    ContextualView.prototype.setOptions = function setOptions(options) {
27.12633 +        return this._optionsManager.setOptions(options);
27.12634 +    };
27.12635 +
27.12636 +    /**
27.12637 +     * Returns ContextualLayout instance's options.
27.12638 +     *
27.12639 +     * @method setOptions
27.12640 +     * @return {Options} options The instance's object of configurable options.
27.12641 +     */
27.12642 +    ContextualView.prototype.getOptions = function getOptions() {
27.12643 +        return this._optionsManager.getOptions();
27.12644 +    };
27.12645 +
27.12646 +    /**
27.12647 +     * Return the registers Entity id for the ContextualView.
27.12648 +     *
27.12649 +     * @private
27.12650 +     * @method render
27.12651 +     * @return {Number} Registered Entity id
27.12652 +     */
27.12653 +    ContextualView.prototype.render = function render() {
27.12654 +        return this._id;
27.12655 +    };
27.12656 +
27.12657 +    /**
27.12658 +     * Apply changes from this component to the corresponding document element.
27.12659 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.12660 +     * and matrix transforms.
27.12661 +     *
27.12662 +     * @private
27.12663 +     * @method commit
27.12664 +     * @param {Context} context commit context
27.12665 +     */
27.12666 +    ContextualView.prototype.commit = function commit(context) {};
27.12667 +
27.12668 +    module.exports = ContextualView;
27.12669 +});
27.12670 +
27.12671 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12672 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12673 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12674 + *
27.12675 + * Owner: felix@famo.us
27.12676 + * @license MPL 2.0
27.12677 + * @copyright Famous Industries, Inc. 2014
27.12678 + */
27.12679 +
27.12680 +define('famous/views/SequentialLayout',['require','exports','module','famous/core/OptionsManager','famous/core/Transform','famous/core/ViewSequence','famous/utilities/Utility'],function(require, exports, module) {
27.12681 +    var OptionsManager = require('famous/core/OptionsManager');
27.12682 +    var Transform = require('famous/core/Transform');
27.12683 +    var ViewSequence = require('famous/core/ViewSequence');
27.12684 +    var Utility = require('famous/utilities/Utility');
27.12685 +
27.12686 +    /**
27.12687 +     * SequentialLayout will lay out a collection of renderables sequentially in the specified direction.
27.12688 +     * @class SequentialLayout
27.12689 +     * @constructor
27.12690 +     * @param {Options} [options] An object of configurable options.
27.12691 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
27.12692 +     * module, this option will lay out the SequentialLayout instance's renderables either horizontally
27.12693 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
27.12694 +     * to just use integers as well.
27.12695 +     * @param {Array.Number} [options.defaultItemSize=[50, 50]] In the case where a renderable layed out
27.12696 +     * under SequentialLayout's control doesen't have a getSize method, SequentialLayout will assign it
27.12697 +     * this default size. (Commonly a case with Views).
27.12698 +     */
27.12699 +    function SequentialLayout(options) {
27.12700 +        this._items = null;
27.12701 +        this._size = null;
27.12702 +        this._outputFunction = SequentialLayout.DEFAULT_OUTPUT_FUNCTION;
27.12703 +
27.12704 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
27.12705 +        this.optionsManager = new OptionsManager(this.options);
27.12706 +
27.12707 +        this._itemsCache = [];
27.12708 +        this._outputCache = {
27.12709 +            size: null,
27.12710 +            target: this._itemsCache
27.12711 +        };
27.12712 +
27.12713 +        if (options) this.setOptions(options);
27.12714 +    }
27.12715 +
27.12716 +    SequentialLayout.DEFAULT_OPTIONS = {
27.12717 +        direction: Utility.Direction.Y,
27.12718 +        itemSpacing: 0,
27.12719 +        defaultItemSize: [50, 50]
27.12720 +    };
27.12721 +
27.12722 +    SequentialLayout.DEFAULT_OUTPUT_FUNCTION = function DEFAULT_OUTPUT_FUNCTION(input, offset, index) {
27.12723 +        var transform = (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset);
27.12724 +        return {
27.12725 +            transform: transform,
27.12726 +            target: input.render()
27.12727 +        };
27.12728 +    };
27.12729 +
27.12730 +    /**
27.12731 +     * Returns the width and the height of the SequentialLayout instance.
27.12732 +     *
27.12733 +     * @method getSize
27.12734 +     * @return {Array} A two value array of the SequentialLayout instance's current width and height (in that order).
27.12735 +     */
27.12736 +    SequentialLayout.prototype.getSize = function getSize() {
27.12737 +        if (!this._size) this.render(); // hack size in
27.12738 +        return this._size;
27.12739 +    };
27.12740 +
27.12741 +    /**
27.12742 +     * Sets the collection of renderables under the SequentialLayout instance's control.
27.12743 +     *
27.12744 +     * @method sequenceFrom
27.12745 +     * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence.
27.12746 +     * @chainable
27.12747 +     */
27.12748 +    SequentialLayout.prototype.sequenceFrom = function sequenceFrom(items) {
27.12749 +        if (items instanceof Array) items = new ViewSequence(items);
27.12750 +        this._items = items;
27.12751 +        return this;
27.12752 +    };
27.12753 +
27.12754 +    /**
27.12755 +     * Patches the SequentialLayout instance's options with the passed-in ones.
27.12756 +     *
27.12757 +     * @method setOptions
27.12758 +     * @param {Options} options An object of configurable options for the SequentialLayout instance.
27.12759 +     * @chainable
27.12760 +     */
27.12761 +    SequentialLayout.prototype.setOptions = function setOptions(options) {
27.12762 +        this.optionsManager.setOptions.apply(this.optionsManager, arguments);
27.12763 +        return this;
27.12764 +    };
27.12765 +
27.12766 +    /**
27.12767 +     * setOutputFunction is used to apply a user-defined output transform on each processed renderable.
27.12768 +     *  For a good example, check out SequentialLayout's own DEFAULT_OUTPUT_FUNCTION in the code.
27.12769 +     *
27.12770 +     * @method setOutputFunction
27.12771 +     * @param {Function} outputFunction An output processer for each renderable in the SequentialLayout
27.12772 +     * instance.
27.12773 +     * @chainable
27.12774 +     */
27.12775 +    SequentialLayout.prototype.setOutputFunction = function setOutputFunction(outputFunction) {
27.12776 +        this._outputFunction = outputFunction;
27.12777 +        return this;
27.12778 +    };
27.12779 +
27.12780 +    /**
27.12781 +     * Generate a render spec from the contents of this component.
27.12782 +     *
27.12783 +     * @private
27.12784 +     * @method render
27.12785 +     * @return {number} Render spec for this component
27.12786 +     */
27.12787 +    SequentialLayout.prototype.render = function render() {
27.12788 +        var length = 0;
27.12789 +        var girth = 0;
27.12790 +
27.12791 +        var lengthDim = (this.options.direction === Utility.Direction.X) ? 0 : 1;
27.12792 +        var girthDim = (this.options.direction === Utility.Direction.X) ? 1 : 0;
27.12793 +
27.12794 +        var currentNode = this._items;
27.12795 +        var result = this._itemsCache;
27.12796 +        var i = 0;
27.12797 +        while (currentNode) {
27.12798 +            var item = currentNode.get();
27.12799 +            if (!item) break;
27.12800 +
27.12801 +            var itemSize;
27.12802 +            if (item && item.getSize) itemSize = item.getSize();
27.12803 +            if (!itemSize) itemSize = this.options.defaultItemSize;
27.12804 +            if (itemSize[girthDim] !== true) girth = Math.max(girth, itemSize[girthDim]);
27.12805 +
27.12806 +            var output = this._outputFunction.call(this, item, length, i);
27.12807 +            result[i] = output;
27.12808 +
27.12809 +            if (itemSize[lengthDim] && (itemSize[lengthDim] !== true)) length += itemSize[lengthDim] + this.options.itemSpacing;
27.12810 +            currentNode = currentNode.getNext();
27.12811 +            i++;
27.12812 +        }
27.12813 +        this._itemsCache.splice(i);
27.12814 +
27.12815 +        if (!girth) girth = undefined;
27.12816 +
27.12817 +        if (!this._size) this._size = [0, 0];
27.12818 +        this._size[lengthDim] = length - this.options.itemSpacing; // account for last itemSpacing
27.12819 +        this._size[girthDim] = girth;
27.12820 +
27.12821 +        this._outputCache.size = this.getSize();
27.12822 +        return this._outputCache;
27.12823 +    };
27.12824 +
27.12825 +    module.exports = SequentialLayout;
27.12826 +});
27.12827 +
27.12828 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12829 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12830 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12831 + *
27.12832 + * Owner: felix@famo.us
27.12833 + * @license MPL 2.0
27.12834 + * @copyright Famous Industries, Inc. 2014
27.12835 + */
27.12836 +
27.12837 +define('famous/views/Deck',['require','exports','module','famous/core/Transform','famous/core/OptionsManager','famous/transitions/Transitionable','famous/utilities/Utility','./SequentialLayout'],function(require, exports, module) {
27.12838 +    var Transform = require('famous/core/Transform');
27.12839 +    var OptionsManager = require('famous/core/OptionsManager');
27.12840 +    var Transitionable = require('famous/transitions/Transitionable');
27.12841 +    var Utility = require('famous/utilities/Utility');
27.12842 +    var SequentialLayout = require('./SequentialLayout');
27.12843 +
27.12844 +    /**
27.12845 +     * A Sequential Layout that can be opened and closed with animations.
27.12846 +     *
27.12847 +     *   Takes the same options as SequentialLayout
27.12848 +     *   as well as options for the open/close transition
27.12849 +     *   and the rotation you want your Deck instance to layout in.
27.12850 +     *
27.12851 +     * @class Deck
27.12852 +     * @constructor
27.12853 +     * @extends SequentialLayout
27.12854 +     *
27.12855 +     * @param {Options} [options] An object of configurable options
27.12856 +     * @param {Transition} [options.transition={duration: 500, curve: 'easeOutBounce'}
27.12857 +     *   The transition that executes upon opening or closing your deck instance.
27.12858 +     * @param {Number} [stackRotation=0] The amount of rotation applied to the propogation
27.12859 +     *   of the Deck instance's stack of renderables.
27.12860 +     * @param {Object} [options.transition] A transition object for changing between states.
27.12861 +     * @param {Number} [options.direction] axis of expansion (Utility.Direction.X or .Y)
27.12862 +     */
27.12863 +    function Deck(options) {
27.12864 +        SequentialLayout.apply(this, arguments);
27.12865 +        this.state = new Transitionable(0);
27.12866 +        this._isOpen = false;
27.12867 +
27.12868 +        this.setOutputFunction(function(input, offset, index) {
27.12869 +            var state = _getState.call(this);
27.12870 +            var positionMatrix = (this.options.direction === Utility.Direction.X) ?
27.12871 +                Transform.translate(state * offset, 0, 0.001 * (state - 1) * offset) :
27.12872 +                Transform.translate(0, state * offset, 0.001 * (state - 1) * offset);
27.12873 +            var output = input.render();
27.12874 +            if (this.options.stackRotation) {
27.12875 +                var amount = this.options.stackRotation * index * (1 - state);
27.12876 +                output = {
27.12877 +                    transform: Transform.rotateZ(amount),
27.12878 +                    origin: [0.5, 0.5],
27.12879 +                    target: output
27.12880 +                };
27.12881 +            }
27.12882 +            return {
27.12883 +                transform: positionMatrix,
27.12884 +                size: input.getSize(),
27.12885 +                target: output
27.12886 +            };
27.12887 +        });
27.12888 +    }
27.12889 +    Deck.prototype = Object.create(SequentialLayout.prototype);
27.12890 +    Deck.prototype.constructor = Deck;
27.12891 +
27.12892 +    Deck.DEFAULT_OPTIONS = OptionsManager.patch(SequentialLayout.DEFAULT_OPTIONS, {
27.12893 +        transition: {
27.12894 +            curve: 'easeOutBounce',
27.12895 +            duration: 500
27.12896 +        },
27.12897 +        stackRotation: 0
27.12898 +    });
27.12899 +
27.12900 +    /**
27.12901 +     * Returns the width and the height of the Deck instance.
27.12902 +     *
27.12903 +     * @method getSize
27.12904 +     * @return {Array} A two value array of Deck's current width and height (in that order).
27.12905 +     *   Scales as Deck opens and closes.
27.12906 +     */
27.12907 +    Deck.prototype.getSize = function getSize() {
27.12908 +        var originalSize = SequentialLayout.prototype.getSize.apply(this, arguments);
27.12909 +        var firstSize = this._items ? this._items.get().getSize() : [0, 0];
27.12910 +        if (!firstSize) firstSize = [0, 0];
27.12911 +        var state = _getState.call(this);
27.12912 +        var invState = 1 - state;
27.12913 +        return [firstSize[0] * invState + originalSize[0] * state, firstSize[1] * invState + originalSize[1] * state];
27.12914 +    };
27.12915 +
27.12916 +    function _getState(returnFinal) {
27.12917 +        if (returnFinal) return this._isOpen ? 1 : 0;
27.12918 +        else return this.state.get();
27.12919 +    }
27.12920 +
27.12921 +    function _setState(pos, transition, callback) {
27.12922 +        this.state.halt();
27.12923 +        this.state.set(pos, transition, callback);
27.12924 +    }
27.12925 +
27.12926 +    /**
27.12927 +     * An accesor method to find out if the messaged Deck instance is open or closed.
27.12928 +     *
27.12929 +     * @method isOpen
27.12930 +     * @return {Boolean} Returns true if the instance is open or false if it's closed.
27.12931 +     */
27.12932 +    Deck.prototype.isOpen = function isOpen() {
27.12933 +        return this._isOpen;
27.12934 +    };
27.12935 +
27.12936 +    /**
27.12937 +     * Sets the Deck instance to an open state.
27.12938 +     *
27.12939 +     * @method open
27.12940 +     * @param {function} [callback] Executes after transitioning to a fully open state.
27.12941 +     */
27.12942 +    Deck.prototype.open = function open(callback) {
27.12943 +        this._isOpen = true;
27.12944 +       _setState.call(this, 1, this.options.transition, callback);
27.12945 +    };
27.12946 +
27.12947 +    /**
27.12948 +     * Sets the Deck instance to an open state.
27.12949 +     *
27.12950 +     * @method close
27.12951 +     * @param {function} [callback] Executes after transitioning to a fully closed state.
27.12952 +     */
27.12953 +    Deck.prototype.close = function close(callback) {
27.12954 +        this._isOpen = false;
27.12955 +        _setState.call(this, 0, this.options.transition, callback);
27.12956 +    };
27.12957 +
27.12958 +    /**
27.12959 +     * Sets the Deck instance from its current state to the opposite state.
27.12960 +     *
27.12961 +     * @method close
27.12962 +     * @param {function} [callback] Executes after transitioning to the toggled state.
27.12963 +     */
27.12964 +    Deck.prototype.toggle = function toggle(callback) {
27.12965 +        if (this._isOpen) this.close(callback);
27.12966 +        else this.open(callback);
27.12967 +    };
27.12968 +
27.12969 +    module.exports = Deck;
27.12970 +});
27.12971 +
27.12972 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.12973 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.12974 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.12975 + *
27.12976 + * Owner: felix@famo.us
27.12977 + * @license MPL 2.0
27.12978 + * @copyright Famous Industries, Inc. 2014
27.12979 + */
27.12980 +
27.12981 +define('famous/views/RenderController',['require','exports','module','famous/core/Modifier','famous/core/RenderNode','famous/core/Transform','famous/transitions/Transitionable','famous/core/View'],function(require, exports, module) {
27.12982 +    var Modifier = require('famous/core/Modifier');
27.12983 +    var RenderNode = require('famous/core/RenderNode');
27.12984 +    var Transform = require('famous/core/Transform');
27.12985 +    var Transitionable = require('famous/transitions/Transitionable');
27.12986 +    var View = require('famous/core/View');
27.12987 +
27.12988 +    /**
27.12989 +     * A dynamic view that can show or hide different renerables with transitions.
27.12990 +     * @class RenderController
27.12991 +     * @constructor
27.12992 +     * @param {Options} [options] An object of configurable options.
27.12993 +     * @param {Transition} [inTransition=true] The transition in charge of showing a renderable.
27.12994 +     * @param {Transition} [outTransition=true]  The transition in charge of removing your previous renderable when
27.12995 +     * you show a new one, or hiding your current renderable.
27.12996 +     * @param {Boolean} [overlap=true] When showing a new renderable, overlap determines if the
27.12997 +      out transition of the old one executes concurrently with the in transition of the new one,
27.12998 +       or synchronously beforehand.
27.12999 +     */
27.13000 +    function RenderController(options) {
27.13001 +        View.apply(this, arguments);
27.13002 +
27.13003 +        this._showing = -1;
27.13004 +        this._outgoingRenderables = [];
27.13005 +        this._nextRenderable = null;
27.13006 +
27.13007 +        this._renderables = [];
27.13008 +        this._nodes = [];
27.13009 +        this._modifiers = [];
27.13010 +        this._states = [];
27.13011 +
27.13012 +        this.inTransformMap = RenderController.DefaultMap.transform;
27.13013 +        this.inOpacityMap = RenderController.DefaultMap.opacity;
27.13014 +        this.inOriginMap = RenderController.DefaultMap.origin;
27.13015 +        this.outTransformMap = RenderController.DefaultMap.transform;
27.13016 +        this.outOpacityMap = RenderController.DefaultMap.opacity;
27.13017 +        this.outOriginMap = RenderController.DefaultMap.origin;
27.13018 +
27.13019 +        this._output = [];
27.13020 +    }
27.13021 +    RenderController.prototype = Object.create(View.prototype);
27.13022 +    RenderController.prototype.constructor = RenderController;
27.13023 +
27.13024 +    RenderController.DEFAULT_OPTIONS = {
27.13025 +        inTransition: true,
27.13026 +        outTransition: true,
27.13027 +        overlap: true
27.13028 +    };
27.13029 +
27.13030 +    RenderController.DefaultMap = {
27.13031 +        transform: function() {
27.13032 +            return Transform.identity;
27.13033 +        },
27.13034 +        opacity: function(progress) {
27.13035 +            return progress;
27.13036 +        },
27.13037 +        origin: null
27.13038 +    };
27.13039 +
27.13040 +    function _mappedState(map, state) {
27.13041 +        return map(state.get());
27.13042 +    }
27.13043 +
27.13044 +    /**
27.13045 +     * As your RenderController shows a new renderable, it executes a transition in. This transition in
27.13046 +     *  will affect a default interior state and modify it as you bring renderables in and out. However, if you want to control
27.13047 +     *  the transform, opacity, and origin state yourself, you may call certain methods (such as inTransformFrom) to obtain state from an outside source,
27.13048 +     *  that may either be a function or a Famous transitionable. inTransformFrom sets the accessor for the state of
27.13049 +     *  the transform used in transitioning in renderables.
27.13050 +     *
27.13051 +     * @method inTransformFrom
27.13052 +     * @param {Function|Transitionable} transform  A function that returns a transform from outside closure, or a
27.13053 +     * a transitionable that manages a full transform (a sixteen value array).
27.13054 +     * @chainable
27.13055 +     */
27.13056 +    RenderController.prototype.inTransformFrom = function inTransformFrom(transform) {
27.13057 +        if (transform instanceof Function) this.inTransformMap = transform;
27.13058 +        else if (transform && transform.get) this.inTransformMap = transform.get.bind(transform);
27.13059 +        else throw new Error('inTransformFrom takes only function or getter object');
27.13060 +        //TODO: tween transition
27.13061 +        return this;
27.13062 +    };
27.13063 +
27.13064 +    /**
27.13065 +     * inOpacityFrom sets the accessor for the state of the opacity used in transitioning in renderables.
27.13066 +     * @method inOpacityFrom
27.13067 +     * @param {Function|Transitionable} opacity  A function that returns an opacity from outside closure, or a
27.13068 +     * a transitionable that manages opacity (a number between zero and one).
27.13069 +     * @chainable
27.13070 +     */
27.13071 +    RenderController.prototype.inOpacityFrom = function inOpacityFrom(opacity) {
27.13072 +        if (opacity instanceof Function) this.inOpacityMap = opacity;
27.13073 +        else if (opacity && opacity.get) this.inOpacityMap = opacity.get.bind(opacity);
27.13074 +        else throw new Error('inOpacityFrom takes only function or getter object');
27.13075 +        //TODO: tween opacity
27.13076 +        return this;
27.13077 +    };
27.13078 +
27.13079 +    /**
27.13080 +     * inOriginFrom sets the accessor for the state of the origin used in transitioning in renderables.
27.13081 +     * @method inOriginFrom
27.13082 +     * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a
27.13083 +     * a transitionable that manages origin (a two value array of numbers between zero and one).
27.13084 +     * @chainable
27.13085 +     */
27.13086 +    RenderController.prototype.inOriginFrom = function inOriginFrom(origin) {
27.13087 +        if (origin instanceof Function) this.inOriginMap = origin;
27.13088 +        else if (origin && origin.get) this.inOriginMap = origin.get.bind(origin);
27.13089 +        else throw new Error('inOriginFrom takes only function or getter object');
27.13090 +        //TODO: tween origin
27.13091 +        return this;
27.13092 +    };
27.13093 +
27.13094 +    /**
27.13095 +     * outTransformFrom sets the accessor for the state of the transform used in transitioning out renderables.
27.13096 +     * @method show
27.13097 +     * @param {Function|Transitionable} transform  A function that returns a transform from outside closure, or a
27.13098 +     * a transitionable that manages a full transform (a sixteen value array).
27.13099 +     * @chainable
27.13100 +     */
27.13101 +    RenderController.prototype.outTransformFrom = function outTransformFrom(transform) {
27.13102 +        if (transform instanceof Function) this.outTransformMap = transform;
27.13103 +        else if (transform && transform.get) this.outTransformMap = transform.get.bind(transform);
27.13104 +        else throw new Error('inTransformFrom takes only function or getter object');
27.13105 +        //TODO: tween transition
27.13106 +        return this;
27.13107 +    };
27.13108 +
27.13109 +    /**
27.13110 +     * outOpacityFrom sets the accessor for the state of the opacity used in transitioning out renderables.
27.13111 +     * @method inOpacityFrom
27.13112 +     * @param {Function|Transitionable} opacity  A function that returns an opacity from outside closure, or a
27.13113 +     * a transitionable that manages opacity (a number between zero and one).
27.13114 +     * @chainable
27.13115 +     */
27.13116 +    RenderController.prototype.outOpacityFrom = function outOpacityFrom(opacity) {
27.13117 +        if (opacity instanceof Function) this.outOpacityMap = opacity;
27.13118 +        else if (opacity && opacity.get) this.outOpacityMap = opacity.get.bind(opacity);
27.13119 +        else throw new Error('inOpacityFrom takes only function or getter object');
27.13120 +        //TODO: tween opacity
27.13121 +        return this;
27.13122 +    };
27.13123 +
27.13124 +    /**
27.13125 +     * outOriginFrom sets the accessor for the state of the origin used in transitioning out renderables.
27.13126 +     * @method inOriginFrom
27.13127 +     * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a
27.13128 +     * a transitionable that manages origin (a two value array of numbers between zero and one).
27.13129 +     * @chainable
27.13130 +     */
27.13131 +    RenderController.prototype.outOriginFrom = function outOriginFrom(origin) {
27.13132 +        if (origin instanceof Function) this.outOriginMap = origin;
27.13133 +        else if (origin && origin.get) this.outOriginMap = origin.get.bind(origin);
27.13134 +        else throw new Error('inOriginFrom takes only function or getter object');
27.13135 +        //TODO: tween origin
27.13136 +        return this;
27.13137 +    };
27.13138 +
27.13139 +    /**
27.13140 +     * Show displays the targeted renderable with a transition and an optional callback to
27.13141 +     * execute afterwards.
27.13142 +     * @method show
27.13143 +     * @param {Object} renderable The renderable you want to show.
27.13144 +     * @param {Transition} [transition] Overwrites the default transition in to display the
27.13145 +     * passed-in renderable.
27.13146 +     * @param {function} [callback] Executes after transitioning in the renderable.
27.13147 +     * @chainable
27.13148 +     */
27.13149 +    RenderController.prototype.show = function show(renderable, transition, callback) {
27.13150 +        if (!renderable) {
27.13151 +            return this.hide(callback);
27.13152 +        }
27.13153 +
27.13154 +        if (transition instanceof Function) {
27.13155 +            callback = transition;
27.13156 +            transition = null;
27.13157 +        }
27.13158 +
27.13159 +        if (this._showing >= 0) {
27.13160 +            if (this.options.overlap) this.hide();
27.13161 +            else {
27.13162 +                if (this._nextRenderable) {
27.13163 +                    this._nextRenderable = renderable;
27.13164 +                }
27.13165 +                else {
27.13166 +                    this._nextRenderable = renderable;
27.13167 +                    this.hide(function() {
27.13168 +                        if (this._nextRenderable === renderable) this.show(this._nextRenderable, callback);
27.13169 +                        this._nextRenderable = null;
27.13170 +                    });
27.13171 +                }
27.13172 +                return undefined;
27.13173 +            }
27.13174 +        }
27.13175 +
27.13176 +        var state = null;
27.13177 +
27.13178 +        // check to see if we should restore
27.13179 +        var renderableIndex = this._renderables.indexOf(renderable);
27.13180 +        if (renderableIndex >= 0) {
27.13181 +            this._showing = renderableIndex;
27.13182 +            state = this._states[renderableIndex];
27.13183 +            state.halt();
27.13184 +
27.13185 +            var outgoingIndex = this._outgoingRenderables.indexOf(renderable);
27.13186 +            if (outgoingIndex >= 0) this._outgoingRenderables.splice(outgoingIndex, 1);
27.13187 +        }
27.13188 +        else {
27.13189 +            state = new Transitionable(0);
27.13190 +
27.13191 +            var modifier = new Modifier({
27.13192 +                transform: this.inTransformMap ? _mappedState.bind(this, this.inTransformMap, state) : null,
27.13193 +                opacity: this.inOpacityMap ? _mappedState.bind(this, this.inOpacityMap, state) : null,
27.13194 +                origin: this.inOriginMap ? _mappedState.bind(this, this.inOriginMap, state) : null
27.13195 +            });
27.13196 +            var node = new RenderNode();
27.13197 +            node.add(modifier).add(renderable);
27.13198 +
27.13199 +            this._showing = this._nodes.length;
27.13200 +            this._nodes.push(node);
27.13201 +            this._modifiers.push(modifier);
27.13202 +            this._states.push(state);
27.13203 +            this._renderables.push(renderable);
27.13204 +        }
27.13205 +
27.13206 +        if (!transition) transition = this.options.inTransition;
27.13207 +        state.set(1, transition, callback);
27.13208 +    };
27.13209 +
27.13210 +    /**
27.13211 +     * Hide hides the currently displayed renderable with an out transition.
27.13212 +     * @method hide
27.13213 +     * @param {Transition} [transition] Overwrites the default transition in to hide the
27.13214 +     * currently controlled renderable.
27.13215 +     * @param {function} [callback] Executes after transitioning out the renderable.
27.13216 +     * @chainable
27.13217 +     */
27.13218 +    RenderController.prototype.hide = function hide(transition, callback) {
27.13219 +        if (this._showing < 0) return;
27.13220 +        var index = this._showing;
27.13221 +        this._showing = -1;
27.13222 +
27.13223 +        if (transition instanceof Function) {
27.13224 +            callback = transition;
27.13225 +            transition = undefined;
27.13226 +        }
27.13227 +
27.13228 +        var node = this._nodes[index];
27.13229 +        var modifier = this._modifiers[index];
27.13230 +        var state = this._states[index];
27.13231 +        var renderable = this._renderables[index];
27.13232 +
27.13233 +        modifier.transformFrom(this.outTransformMap ? _mappedState.bind(this, this.outTransformMap, state) : null);
27.13234 +        modifier.opacityFrom(this.outOpacityMap ? _mappedState.bind(this, this.outOpacityMap, state) : null);
27.13235 +        modifier.originFrom(this.outOriginMap ? _mappedState.bind(this, this.outOriginMap, state) : null);
27.13236 +
27.13237 +        if (this._outgoingRenderables.indexOf(renderable) < 0) this._outgoingRenderables.push(renderable);
27.13238 +
27.13239 +        if (!transition) transition = this.options.outTransition;
27.13240 +        state.halt();
27.13241 +        state.set(0, transition, function(node, modifier, state, renderable) {
27.13242 +            if (this._outgoingRenderables.indexOf(renderable) >= 0) {
27.13243 +                var index = this._nodes.indexOf(node);
27.13244 +                this._nodes.splice(index, 1);
27.13245 +                this._modifiers.splice(index, 1);
27.13246 +                this._states.splice(index, 1);
27.13247 +                this._renderables.splice(index, 1);
27.13248 +                this._outgoingRenderables.splice(this._outgoingRenderables.indexOf(renderable), 1);
27.13249 +
27.13250 +                if (this._showing >= index) this._showing--;
27.13251 +            }
27.13252 +            if (callback) callback.call(this);
27.13253 +        }.bind(this, node, modifier, state, renderable));
27.13254 +    };
27.13255 +
27.13256 +    /**
27.13257 +     * Generate a render spec from the contents of this component.
27.13258 +     *
27.13259 +     * @private
27.13260 +     * @method render
27.13261 +     * @return {number} Render spec for this component
27.13262 +     */
27.13263 +    RenderController.prototype.render = function render() {
27.13264 +        var result = this._output;
27.13265 +        if (result.length > this._nodes.length) result.splice(this._nodes.length);
27.13266 +        for (var i = 0; i < this._nodes.length; i++) {
27.13267 +            result[i] = this._nodes[i].render();
27.13268 +        }
27.13269 +        return result;
27.13270 +    };
27.13271 +
27.13272 +    module.exports = RenderController;
27.13273 +});
27.13274 +
27.13275 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.13276 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.13277 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.13278 + *
27.13279 + * Owner: felix@famo.us
27.13280 + * @license MPL 2.0
27.13281 + * @copyright Famous Industries, Inc. 2014
27.13282 + */
27.13283 +
27.13284 +define('famous/views/EdgeSwapper',['require','exports','module','famous/transitions/CachedMap','famous/core/Entity','famous/core/EventHandler','famous/core/Transform','./RenderController'],function(require, exports, module) {
27.13285 +    var CachedMap = require('famous/transitions/CachedMap');
27.13286 +    var Entity = require('famous/core/Entity');
27.13287 +    var EventHandler = require('famous/core/EventHandler');
27.13288 +    var Transform = require('famous/core/Transform');
27.13289 +    var RenderController = require('./RenderController');
27.13290 +
27.13291 +    /**
27.13292 +     * Container which handles swapping renderables from the edge of its parent context.
27.13293 +     * @class EdgeSwapper
27.13294 +     * @constructor
27.13295 +     * @param {Options} [options] An object of configurable options.
27.13296 +     *   Takes the same options as RenderController.
27.13297 +     * @uses RenderController
27.13298 +     */
27.13299 +    function EdgeSwapper(options) {
27.13300 +        this._currentTarget = null;
27.13301 +        this._size = [undefined, undefined];
27.13302 +
27.13303 +        this._controller = new RenderController(options);
27.13304 +        this._controller.inTransformFrom(CachedMap.create(_transformMap.bind(this, 0.0001)));
27.13305 +        this._controller.outTransformFrom(CachedMap.create(_transformMap.bind(this, -0.0001)));
27.13306 +
27.13307 +        this._eventInput = new EventHandler();
27.13308 +        EventHandler.setInputHandler(this, this._eventInput);
27.13309 +
27.13310 +        this._entityId = Entity.register(this);
27.13311 +        if (options) this.setOptions(options);
27.13312 +    }
27.13313 +
27.13314 +    function _transformMap(zMax, progress) {
27.13315 +        return Transform.translate(this._size[0] * (1 - progress), 0, zMax * (1 - progress));
27.13316 +    }
27.13317 +
27.13318 +    /**
27.13319 +     * Displays the passed-in content with the EdgeSwapper instance's default transition.
27.13320 +     *
27.13321 +     * @method show
27.13322 +     * @param {Object} content The renderable you want to display.
27.13323 +     */
27.13324 +    EdgeSwapper.prototype.show = function show(content) {
27.13325 +        // stop sending input to old target
27.13326 +        if (this._currentTarget) this._eventInput.unpipe(this._currentTarget);
27.13327 +
27.13328 +        this._currentTarget = content;
27.13329 +
27.13330 +        // start sending input to new target
27.13331 +        if (this._currentTarget && this._currentTarget.trigger) this._eventInput.pipe(this._currentTarget);
27.13332 +
27.13333 +        this._controller.show.apply(this._controller, arguments);
27.13334 +    };
27.13335 +
27.13336 +    /**
27.13337 +     * Patches the EdgeSwapper instance's options with the passed-in ones.
27.13338 +     *
27.13339 +     * @method setOptions
27.13340 +     * @param {Options} options An object of configurable options for the Edgeswapper instance.
27.13341 +     */
27.13342 +    EdgeSwapper.prototype.setOptions = function setOptions(options) {
27.13343 +        this._controller.setOptions(options);
27.13344 +    };
27.13345 +
27.13346 +    /**
27.13347 +     * Generate a render spec from the contents of this component.
27.13348 +     *
27.13349 +     * @private
27.13350 +     * @method render
27.13351 +     * @return {number} Render spec for this component
27.13352 +     */
27.13353 +    EdgeSwapper.prototype.render = function render() {
27.13354 +        return this._entityId;
27.13355 +    };
27.13356 +
27.13357 +    /**
27.13358 +     * Apply changes from this component to the corresponding document element.
27.13359 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.13360 +     * and matrix transforms.
27.13361 +     *
27.13362 +     * @private
27.13363 +     * @method commit
27.13364 +     * @param {Context} context commit context
27.13365 +     */
27.13366 +    EdgeSwapper.prototype.commit = function commit(context) {
27.13367 +        this._size[0] = context.size[0];
27.13368 +        this._size[1] = context.size[1];
27.13369 +
27.13370 +        return {
27.13371 +            transform: context.transform,
27.13372 +            opacity: context.opacity,
27.13373 +            origin: context.origin,
27.13374 +            size: context.size,
27.13375 +            target: this._controller.render()
27.13376 +        };
27.13377 +    };
27.13378 +
27.13379 +    module.exports = EdgeSwapper;
27.13380 +});
27.13381 +
27.13382 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.13383 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.13384 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.13385 + *
27.13386 + * Owner: mike@famo.us
27.13387 + * @license MPL 2.0
27.13388 + * @copyright Famous Industries, Inc. 2014
27.13389 + */
27.13390 +
27.13391 +define('famous/views/FlexibleLayout',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/OptionsManager','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) {
27.13392 +    var Entity = require('famous/core/Entity');
27.13393 +    var Transform = require('famous/core/Transform');
27.13394 +    var OptionsManager = require('famous/core/OptionsManager');
27.13395 +    var EventHandler = require('famous/core/EventHandler');
27.13396 +    var Transitionable = require('famous/transitions/Transitionable');
27.13397 +
27.13398 +    /**
27.13399 +     * A layout which divides a context into sections based on a proportion
27.13400 +     *   of the total sum of ratios.  FlexibleLayout can either lay renderables
27.13401 +     *   out vertically or horizontally.
27.13402 +     * @class FlexibleLayout
27.13403 +     * @constructor
27.13404 +     * @param {Options} [options] An object of configurable options.
27.13405 +     * @param {Number} [options.direction=0] Direction the FlexibleLayout instance should lay out renderables.
27.13406 +     * @param {Transition} [options.transition=false] The transiton that controls the FlexibleLayout instance's reflow.
27.13407 +     * @param {Ratios} [options.ratios=[]] The proportions for the renderables to maintain
27.13408 +     */
27.13409 +    function FlexibleLayout(options) {
27.13410 +        this.options = Object.create(FlexibleLayout.DEFAULT_OPTIONS);
27.13411 +        this.optionsManager = new OptionsManager(this.options);
27.13412 +        if (options) this.setOptions(options);
27.13413 +
27.13414 +        this.id = Entity.register(this);
27.13415 +
27.13416 +        this._ratios = new Transitionable(this.options.ratios);
27.13417 +        this._nodes = [];
27.13418 +
27.13419 +        this._cachedDirection = null;
27.13420 +        this._cachedTotalLength = false;
27.13421 +        this._cachedLengths = [];
27.13422 +        this._cachedTransforms = null;
27.13423 +        this._ratiosDirty = false;
27.13424 +
27.13425 +        this._eventOutput = new EventHandler();
27.13426 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.13427 +    }
27.13428 +
27.13429 +    FlexibleLayout.DIRECTION_X = 0;
27.13430 +    FlexibleLayout.DIRECTION_Y = 1;
27.13431 +
27.13432 +    FlexibleLayout.DEFAULT_OPTIONS = {
27.13433 +        direction: FlexibleLayout.DIRECTION_X,
27.13434 +        transition: false,
27.13435 +        ratios : []
27.13436 +    };
27.13437 +
27.13438 +    function _reflow(ratios, length, direction) {
27.13439 +        var currTransform;
27.13440 +        var translation = 0;
27.13441 +        var flexLength = length;
27.13442 +        var ratioSum = 0;
27.13443 +        var ratio;
27.13444 +        var node;
27.13445 +        var i;
27.13446 +
27.13447 +        this._cachedLengths = [];
27.13448 +        this._cachedTransforms = [];
27.13449 +
27.13450 +        for (i = 0; i < ratios.length; i++){
27.13451 +            ratio = ratios[i];
27.13452 +            node = this._nodes[i];
27.13453 +
27.13454 +            if (typeof ratio !== 'number')
27.13455 +                flexLength -= node.getSize()[direction] || 0;
27.13456 +            else
27.13457 +                ratioSum += ratio;
27.13458 +        }
27.13459 +
27.13460 +        for (i = 0; i < ratios.length; i++) {
27.13461 +            node = this._nodes[i];
27.13462 +            ratio = ratios[i];
27.13463 +
27.13464 +            length = (typeof ratio === 'number')
27.13465 +                ? flexLength * ratio / ratioSum
27.13466 +                : node.getSize()[direction];
27.13467 +
27.13468 +            currTransform = (direction === FlexibleLayout.DIRECTION_X)
27.13469 +                ? Transform.translate(translation, 0, 0)
27.13470 +                : Transform.translate(0, translation, 0);
27.13471 +
27.13472 +            this._cachedTransforms.push(currTransform);
27.13473 +            this._cachedLengths.push(length);
27.13474 +
27.13475 +            translation += length;
27.13476 +        }
27.13477 +    }
27.13478 +
27.13479 +    /**
27.13480 +     * Generate a render spec from the contents of this component.
27.13481 +     *
27.13482 +     * @private
27.13483 +     * @method render
27.13484 +     * @return {Object} Render spec for this component
27.13485 +     */
27.13486 +    FlexibleLayout.prototype.render = function render() {
27.13487 +        return this.id;
27.13488 +    };
27.13489 +
27.13490 +    /**
27.13491 +     * Patches the FlexibleLayouts instance's options with the passed-in ones.
27.13492 +     *
27.13493 +     * @method setOptions
27.13494 +     * @param {Options} options An object of configurable options for the FlexibleLayout instance.
27.13495 +     */
27.13496 +    FlexibleLayout.prototype.setOptions = function setOptions(options) {
27.13497 +        this.optionsManager.setOptions(options);
27.13498 +    };
27.13499 +
27.13500 +    /**
27.13501 +     * Sets the collection of renderables under the FlexibleLayout instance's control.  Also sets
27.13502 +     * the associated ratio values for sizing the renderables if given.
27.13503 +     *
27.13504 +     * @method sequenceFrom
27.13505 +     * @param {Array} sequence An array of renderables.
27.13506 +     */
27.13507 +    FlexibleLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
27.13508 +        this._nodes = sequence;
27.13509 +
27.13510 +        if (this._ratios.get().length === 0) {
27.13511 +            var ratios = [];
27.13512 +            for (var i = 0; i < this._nodes.length; i++) ratios.push(1);
27.13513 +            this.setRatios(ratios);
27.13514 +        }
27.13515 +    };
27.13516 +
27.13517 +    /**
27.13518 +     * Sets the associated ratio values for sizing the renderables.
27.13519 +     *
27.13520 +     * @method setRatios
27.13521 +     * @param {Array} ratios Array of ratios corresponding to the percentage sizes each renderable should be
27.13522 +     */
27.13523 +    FlexibleLayout.prototype.setRatios = function setRatios(ratios, transition, callback) {
27.13524 +        if (transition === undefined) transition = this.options.transition;
27.13525 +        var currRatios = this._ratios;
27.13526 +        if (currRatios.get().length === 0) transition = undefined;
27.13527 +        if (currRatios.isActive()) currRatios.halt();
27.13528 +        currRatios.set(ratios, transition, callback);
27.13529 +        this._ratiosDirty = true;
27.13530 +    };
27.13531 +
27.13532 +    /**
27.13533 +     * Apply changes from this component to the corresponding document element.
27.13534 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.13535 +     * and matrix transforms.
27.13536 +     *
27.13537 +     * @private
27.13538 +     * @method commit
27.13539 +     * @param {Context} context commit context
27.13540 +     */
27.13541 +    FlexibleLayout.prototype.commit = function commit(context) {
27.13542 +        var parentSize = context.size;
27.13543 +        var parentTransform = context.transform;
27.13544 +        var parentOrigin = context.origin;
27.13545 +
27.13546 +        var ratios = this._ratios.get();
27.13547 +        var direction = this.options.direction;
27.13548 +        var length = parentSize[direction];
27.13549 +        var size;
27.13550 +
27.13551 +        if (length !== this._cachedTotalLength || this._ratiosDirty || this._ratios.isActive() || direction !== this._cachedDirection) {
27.13552 +            _reflow.call(this, ratios, length, direction);
27.13553 +
27.13554 +            if (length !== this._cachedTotalLength) this._cachedTotalLength = length;
27.13555 +            if (direction !== this._cachedDirection) this._cachedDirection = direction;
27.13556 +            if (this._ratiosDirty) this._ratiosDirty = false;
27.13557 +        }
27.13558 +
27.13559 +        var result = [];
27.13560 +        for (var i = 0; i < ratios.length; i++) {
27.13561 +            size = [undefined, undefined];
27.13562 +            length = this._cachedLengths[i];
27.13563 +            size[direction] = length;
27.13564 +            result.push({
27.13565 +                transform : this._cachedTransforms[i],
27.13566 +                size: size,
27.13567 +                target : this._nodes[i].render()
27.13568 +            });
27.13569 +        }
27.13570 +
27.13571 +        if (parentSize && (parentOrigin[0] !== 0 && parentOrigin[1] !== 0))
27.13572 +            parentTransform = Transform.moveThen([-parentSize[0]*parentOrigin[0], -parentSize[1]*parentOrigin[1], 0], parentTransform);
27.13573 +
27.13574 +        return {
27.13575 +            transform: parentTransform,
27.13576 +            size: parentSize,
27.13577 +            target: result
27.13578 +        };
27.13579 +    };
27.13580 +
27.13581 +    module.exports = FlexibleLayout;
27.13582 +});
27.13583 +
27.13584 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.13585 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.13586 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.13587 + *
27.13588 + * Owner: felix@famo.us
27.13589 + * @license MPL 2.0
27.13590 + * @copyright Famous Industries, Inc. 2014
27.13591 + */
27.13592 +
27.13593 +define('famous/views/Flipper',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/RenderNode','famous/core/OptionsManager'],function(require, exports, module) {
27.13594 +    var Transform = require('famous/core/Transform');
27.13595 +    var Transitionable = require('famous/transitions/Transitionable');
27.13596 +    var RenderNode = require('famous/core/RenderNode');
27.13597 +    var OptionsManager = require('famous/core/OptionsManager');
27.13598 +
27.13599 +    /**
27.13600 +     * Allows you to link two renderables as front and back sides that can be
27.13601 +     *  'flipped' back and forth along a chosen axis. Rendering optimizations are
27.13602 +     *  automatically handled.
27.13603 +     *
27.13604 +     * @class Flipper
27.13605 +     * @constructor
27.13606 +     * @param {Options} [options] An object of options.
27.13607 +     * @param {Transition} [options.transition=true] The transition executed when flipping your Flipper instance.
27.13608 +     */
27.13609 +    function Flipper(options) {
27.13610 +        this.options = Object.create(Flipper.DEFAULT_OPTIONS);
27.13611 +        this._optionsManager = new OptionsManager(this.options);
27.13612 +        if (options) this.setOptions(options);
27.13613 +
27.13614 +        this.angle = new Transitionable(0);
27.13615 +
27.13616 +        this.frontNode = undefined;
27.13617 +        this.backNode = undefined;
27.13618 +
27.13619 +        this.flipped = false;
27.13620 +    }
27.13621 +
27.13622 +    Flipper.DIRECTION_X = 0;
27.13623 +    Flipper.DIRECTION_Y = 1;
27.13624 +
27.13625 +    var SEPERATION_LENGTH = 1;
27.13626 +
27.13627 +    Flipper.DEFAULT_OPTIONS = {
27.13628 +        transition: true,
27.13629 +        direction: Flipper.DIRECTION_X
27.13630 +    };
27.13631 +
27.13632 +    /**
27.13633 +     * Toggles the rotation between the front and back renderables
27.13634 +     *
27.13635 +     * @method flip
27.13636 +     * @param {Object} [transition] Transition definition
27.13637 +     * @param {Function} [callback] Callback
27.13638 +     */
27.13639 +    Flipper.prototype.flip = function flip(transition, callback) {
27.13640 +        var angle = this.flipped ? 0 : Math.PI;
27.13641 +        this.setAngle(angle, transition, callback);
27.13642 +        this.flipped = !this.flipped;
27.13643 +    };
27.13644 +
27.13645 +    /**
27.13646 +     * Basic setter to the angle
27.13647 +     *
27.13648 +     * @method setAngle
27.13649 +     * @param {Number} angle
27.13650 +     * @param {Object} [transition] Transition definition
27.13651 +     * @param {Function} [callback] Callback
27.13652 +     */
27.13653 +    Flipper.prototype.setAngle = function setAngle(angle, transition, callback) {
27.13654 +        if (transition === undefined) transition = this.options.transition;
27.13655 +        if (this.angle.isActive()) this.angle.halt();
27.13656 +        this.angle.set(angle, transition, callback);
27.13657 +    };
27.13658 +
27.13659 +    /**
27.13660 +     * Patches the Flipper instance's options with the passed-in ones.
27.13661 +     *
27.13662 +     * @method setOptions
27.13663 +     * @param {Options} options An object of configurable options for the Flipper instance.
27.13664 +     */
27.13665 +    Flipper.prototype.setOptions = function setOptions(options) {
27.13666 +        return this._optionsManager.setOptions(options);
27.13667 +    };
27.13668 +
27.13669 +    /**
27.13670 +     * Adds the passed-in renderable to the view associated with the 'front' of the Flipper instance.
27.13671 +     *
27.13672 +     * @method setFront
27.13673 +     * @chainable
27.13674 +     * @param {Object} node The renderable you want to add to the front.
27.13675 +     */
27.13676 +    Flipper.prototype.setFront = function setFront(node) {
27.13677 +        this.frontNode = node;
27.13678 +    };
27.13679 +
27.13680 +    /**
27.13681 +     * Adds the passed-in renderable to the view associated with the 'back' of the Flipper instance.
27.13682 +     *
27.13683 +     * @method setBack
27.13684 +     * @chainable
27.13685 +     * @param {Object} node The renderable you want to add to the back.
27.13686 +     */
27.13687 +    Flipper.prototype.setBack = function setBack(node) {
27.13688 +        this.backNode = node;
27.13689 +    };
27.13690 +
27.13691 +    /**
27.13692 +     * Generate a render spec from the contents of this component.
27.13693 +     *
27.13694 +     * @private
27.13695 +     * @method render
27.13696 +     * @return {Number} Render spec for this component
27.13697 +     */
27.13698 +    Flipper.prototype.render = function render() {
27.13699 +        var angle = this.angle.get();
27.13700 +
27.13701 +        var frontTransform;
27.13702 +        var backTransform;
27.13703 +
27.13704 +        if (this.options.direction === Flipper.DIRECTION_X) {
27.13705 +            frontTransform = Transform.rotateY(angle);
27.13706 +            backTransform = Transform.rotateY(angle + Math.PI);
27.13707 +        }
27.13708 +        else {
27.13709 +            frontTransform = Transform.rotateX(angle);
27.13710 +            backTransform = Transform.rotateX(angle + Math.PI);
27.13711 +        }
27.13712 +
27.13713 +        var result = [];
27.13714 +        if (this.frontNode){
27.13715 +            result.push({
27.13716 +                transform: frontTransform,
27.13717 +                target: this.frontNode.render()
27.13718 +            });
27.13719 +        }
27.13720 +
27.13721 +        if (this.backNode){
27.13722 +            result.push({
27.13723 +                transform: Transform.moveThen([0, 0, SEPERATION_LENGTH], backTransform),
27.13724 +                target: this.backNode.render()
27.13725 +            });
27.13726 +        }
27.13727 +
27.13728 +        return result;
27.13729 +    };
27.13730 +
27.13731 +    module.exports = Flipper;
27.13732 +});
27.13733 +
27.13734 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.13735 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.13736 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.13737 + *
27.13738 + * Owner: felix@famo.us
27.13739 + * @license MPL 2.0
27.13740 + * @copyright Famous Industries, Inc. 2014
27.13741 + */
27.13742 +
27.13743 +define('famous/views/GridLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/ViewSequence','famous/core/EventHandler','famous/core/Modifier','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
27.13744 +    var Entity = require('famous/core/Entity');
27.13745 +    var RenderNode = require('famous/core/RenderNode');
27.13746 +    var Transform = require('famous/core/Transform');
27.13747 +    var ViewSequence = require('famous/core/ViewSequence');
27.13748 +    var EventHandler = require('famous/core/EventHandler');
27.13749 +    var Modifier = require('famous/core/Modifier');
27.13750 +    var OptionsManager = require('famous/core/OptionsManager');
27.13751 +    var Transitionable = require('famous/transitions/Transitionable');
27.13752 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
27.13753 +
27.13754 +    /**
27.13755 +     * A layout which divides a context into several evenly-sized grid cells.
27.13756 +     *   If dimensions are provided, the grid is evenly subdivided with children
27.13757 +     *   cells representing their own context, otherwise the cellSize property is used to compute
27.13758 +     *   dimensions so that items of cellSize will fit.
27.13759 +     * @class GridLayout
27.13760 +     * @constructor
27.13761 +     * @param {Options} [options] An object of configurable options.
27.13762 +     * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns
27.13763 +     * and rows in your Gridlayout instance.
27.13764 +     * @param {Array.Number} [options.cellSize=[250, 250]]  A two-value array which specifies the width and height
27.13765 +     * of each cell in your Gridlayout instance.
27.13766 +     * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow.
27.13767 +     */
27.13768 +    function GridLayout(options) {
27.13769 +        this.options = Object.create(GridLayout.DEFAULT_OPTIONS);
27.13770 +        this.optionsManager = new OptionsManager(this.options);
27.13771 +        if (options) this.setOptions(options);
27.13772 +
27.13773 +        this.id = Entity.register(this);
27.13774 +
27.13775 +        this._modifiers = [];
27.13776 +        this._states = [];
27.13777 +        this._contextSizeCache = [0, 0];
27.13778 +        this._dimensionsCache = [0, 0];
27.13779 +        this._activeCount = 0;
27.13780 +
27.13781 +        this._eventOutput = new EventHandler();
27.13782 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.13783 +    }
27.13784 +
27.13785 +    function _reflow(size, cols, rows) {
27.13786 +        var usableSize = [size[0], size[1]];
27.13787 +        usableSize[0] -= this.options.gutterSize[0] * (cols - 1);
27.13788 +        usableSize[1] -= this.options.gutterSize[1] * (rows - 1);
27.13789 +
27.13790 +        var rowSize = Math.round(usableSize[1] / rows);
27.13791 +        var colSize = Math.round(usableSize[0] / cols);
27.13792 +
27.13793 +        var currY = 0;
27.13794 +        var currX;
27.13795 +        var currIndex = 0;
27.13796 +        for (var i = 0; i < rows; i++) {
27.13797 +            currX = 0;
27.13798 +            for (var j = 0; j < cols; j++) {
27.13799 +                if (this._modifiers[currIndex] === undefined) {
27.13800 +                    _createModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1);
27.13801 +                }
27.13802 +                else {
27.13803 +                    _animateModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1);
27.13804 +                }
27.13805 +
27.13806 +                currIndex++;
27.13807 +                currX += colSize + this.options.gutterSize[0];
27.13808 +            }
27.13809 +
27.13810 +            currY += rowSize + this.options.gutterSize[1];
27.13811 +        }
27.13812 +
27.13813 +        this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]];
27.13814 +        this._contextSizeCache = [size[0], size[1]];
27.13815 +
27.13816 +        this._activeCount = rows * cols;
27.13817 +
27.13818 +        for (i = this._activeCount ; i < this._modifiers.length; i++) _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0);
27.13819 +
27.13820 +        this._eventOutput.emit('reflow');
27.13821 +    }
27.13822 +
27.13823 +    function _createModifier(index, size, position, opacity) {
27.13824 +        var transitionItem = {
27.13825 +            transform: new TransitionableTransform(Transform.translate.apply(null, position)),
27.13826 +            opacity: new Transitionable(opacity),
27.13827 +            size: new Transitionable(size)
27.13828 +        };
27.13829 +
27.13830 +        var modifier = new Modifier({
27.13831 +            transform: transitionItem.transform,
27.13832 +            opacity: transitionItem.opacity,
27.13833 +            size: transitionItem.size
27.13834 +        });
27.13835 +
27.13836 +        this._states[index] = transitionItem;
27.13837 +        this._modifiers[index] = modifier;
27.13838 +
27.13839 +    }
27.13840 +
27.13841 +    function _animateModifier(index, size, position, opacity) {
27.13842 +        var currState = this._states[index];
27.13843 +
27.13844 +        var currSize = currState.size;
27.13845 +        var currOpacity = currState.opacity;
27.13846 +        var currTransform = currState.transform;
27.13847 +
27.13848 +        var transition = this.options.transition;
27.13849 +
27.13850 +        currTransform.halt();
27.13851 +        currOpacity.halt();
27.13852 +        currSize.halt();
27.13853 +
27.13854 +        currTransform.setTranslate(position, transition);
27.13855 +        currSize.set(size, transition);
27.13856 +        currOpacity.set(opacity, transition);
27.13857 +    }
27.13858 +
27.13859 +    GridLayout.DEFAULT_OPTIONS = {
27.13860 +        dimensions: [1, 1],
27.13861 +        transition: false,
27.13862 +        gutterSize: [0, 0]
27.13863 +    };
27.13864 +
27.13865 +    /**
27.13866 +     * Generate a render spec from the contents of this component.
27.13867 +     *
27.13868 +     * @private
27.13869 +     * @method render
27.13870 +     * @return {Object} Render spec for this component
27.13871 +     */
27.13872 +    GridLayout.prototype.render = function render() {
27.13873 +        return this.id;
27.13874 +    };
27.13875 +
27.13876 +    /**
27.13877 +     * Patches the GridLayout instance's options with the passed-in ones.
27.13878 +     *
27.13879 +     * @method setOptions
27.13880 +     * @param {Options} options An object of configurable options for the GridLayout instance.
27.13881 +     */
27.13882 +    GridLayout.prototype.setOptions = function setOptions(options) {
27.13883 +        return this.optionsManager.setOptions(options);
27.13884 +    };
27.13885 +
27.13886 +    /**
27.13887 +     * Sets the collection of renderables under the Gridlayout instance's control.
27.13888 +     *
27.13889 +     * @method sequenceFrom
27.13890 +     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence.
27.13891 +     */
27.13892 +    GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
27.13893 +        if (sequence instanceof Array) sequence = new ViewSequence(sequence);
27.13894 +        this.sequence = sequence;
27.13895 +    };
27.13896 +
27.13897 +    /**
27.13898 +     * Apply changes from this component to the corresponding document element.
27.13899 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.13900 +     * and matrix transforms.
27.13901 +     *
27.13902 +     * @private
27.13903 +     * @method commit
27.13904 +     * @param {Context} context commit context
27.13905 +     */
27.13906 +    GridLayout.prototype.commit = function commit(context) {
27.13907 +        var transform = context.transform;
27.13908 +        var opacity = context.opacity;
27.13909 +        var origin = context.origin;
27.13910 +        var size = context.size;
27.13911 +
27.13912 +        var cols = this.options.dimensions[0];
27.13913 +        var rows = this.options.dimensions[1];
27.13914 +
27.13915 +        if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) {
27.13916 +            _reflow.call(this, size, cols, rows);
27.13917 +        }
27.13918 +
27.13919 +        var sequence = this.sequence;
27.13920 +        var result = [];
27.13921 +        var currIndex = 0;
27.13922 +        while (sequence && (currIndex < this._modifiers.length)) {
27.13923 +            var item = sequence.get();
27.13924 +            var modifier = this._modifiers[currIndex];
27.13925 +            if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) {
27.13926 +                this._modifiers.splice(currIndex, 1);
27.13927 +                this._states.splice(currIndex, 1);
27.13928 +            }
27.13929 +            if (item) {
27.13930 +                result.push(
27.13931 +                    modifier.modify({
27.13932 +                        origin: origin,
27.13933 +                        target: item.render()
27.13934 +                    })
27.13935 +                );
27.13936 +            }
27.13937 +            sequence = sequence.getNext();
27.13938 +            currIndex++;
27.13939 +        }
27.13940 +
27.13941 +        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
27.13942 +        return {
27.13943 +            transform: transform,
27.13944 +            opacity: opacity,
27.13945 +            size: size,
27.13946 +            target: result
27.13947 +        };
27.13948 +    };
27.13949 +
27.13950 +    module.exports = GridLayout;
27.13951 +});
27.13952 +
27.13953 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.13954 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.13955 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.13956 + *
27.13957 + * Owner: felix@famo.us
27.13958 + * @license MPL 2.0
27.13959 + * @copyright Famous Industries, Inc. 2014
27.13960 + */
27.13961 +
27.13962 +define('famous/views/HeaderFooterLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/OptionsManager'],function(require, exports, module) {
27.13963 +    var Entity = require('famous/core/Entity');
27.13964 +    var RenderNode = require('famous/core/RenderNode');
27.13965 +    var Transform = require('famous/core/Transform');
27.13966 +    var OptionsManager = require('famous/core/OptionsManager');
27.13967 +
27.13968 +    /**
27.13969 +     * A layout which will arrange three renderables into a header and footer area of defined size,
27.13970 +      and a content area of flexible size.
27.13971 +     * @class HeaderFooterLayout
27.13972 +     * @constructor
27.13973 +     * @param {Options} [options] An object of configurable options.
27.13974 +     * @param {Number} [options.direction=HeaderFooterLayout.DIRECTION_Y] A direction of HeaderFooterLayout.DIRECTION_X
27.13975 +     * lays your HeaderFooterLayout instance horizontally, and a direction of HeaderFooterLayout.DIRECTION_Y
27.13976 +     * lays it out vertically.
27.13977 +     * @param {Number} [options.headerSize=undefined]  The amount of pixels allocated to the header node
27.13978 +     * in the HeaderFooterLayout instance's direction.
27.13979 +     * @param {Number} [options.footerSize=undefined] The amount of pixels allocated to the footer node
27.13980 +     * in the HeaderFooterLayout instance's direction.
27.13981 +     */
27.13982 +    function HeaderFooterLayout(options) {
27.13983 +        this.options = Object.create(HeaderFooterLayout.DEFAULT_OPTIONS);
27.13984 +        this._optionsManager = new OptionsManager(this.options);
27.13985 +        if (options) this.setOptions(options);
27.13986 +
27.13987 +        this._entityId = Entity.register(this);
27.13988 +
27.13989 +        this.header = new RenderNode();
27.13990 +        this.footer = new RenderNode();
27.13991 +        this.content = new RenderNode();
27.13992 +    }
27.13993 +
27.13994 +    /**
27.13995 +     *  When used as a value for your HeaderFooterLayout's direction option, causes it to lay out horizontally.
27.13996 +     *
27.13997 +     *  @attribute DIRECTION_X
27.13998 +     *  @type Number
27.13999 +     *  @static
27.14000 +     *  @default 0
27.14001 +     *  @protected
27.14002 +     */
27.14003 +    HeaderFooterLayout.DIRECTION_X = 0;
27.14004 +
27.14005 +    /**
27.14006 +     *  When used as a value for your HeaderFooterLayout's direction option, causes it to lay out vertically.
27.14007 +     *
27.14008 +     *  @attribute DIRECTION_Y
27.14009 +     *  @type Number
27.14010 +     *  @static
27.14011 +     *  @default 1
27.14012 +     *  @protected
27.14013 +     */
27.14014 +    HeaderFooterLayout.DIRECTION_Y = 1;
27.14015 +
27.14016 +    HeaderFooterLayout.DEFAULT_OPTIONS = {
27.14017 +        direction: HeaderFooterLayout.DIRECTION_Y,
27.14018 +        headerSize: undefined,
27.14019 +        footerSize: undefined,
27.14020 +        defaultHeaderSize: 0,
27.14021 +        defaultFooterSize: 0
27.14022 +    };
27.14023 +
27.14024 +    /**
27.14025 +     * Generate a render spec from the contents of this component.
27.14026 +     *
27.14027 +     * @private
27.14028 +     * @method render
27.14029 +     * @return {Object} Render spec for this component
27.14030 +     */
27.14031 +    HeaderFooterLayout.prototype.render = function render() {
27.14032 +        return this._entityId;
27.14033 +    };
27.14034 +
27.14035 +    /**
27.14036 +     * Patches the HeaderFooterLayout instance's options with the passed-in ones.
27.14037 +     *
27.14038 +     * @method setOptions
27.14039 +     * @param {Options} options An object of configurable options for the HeaderFooterLayout instance.
27.14040 +     */
27.14041 +    HeaderFooterLayout.prototype.setOptions = function setOptions(options) {
27.14042 +        return this._optionsManager.setOptions(options);
27.14043 +    };
27.14044 +
27.14045 +    function _resolveNodeSize(node, defaultSize) {
27.14046 +        var nodeSize = node.getSize();
27.14047 +        return nodeSize ? nodeSize[this.options.direction] : defaultSize;
27.14048 +    }
27.14049 +
27.14050 +    function _outputTransform(offset) {
27.14051 +        if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return Transform.translate(offset, 0, 0);
27.14052 +        else return Transform.translate(0, offset, 0);
27.14053 +    }
27.14054 +
27.14055 +    function _finalSize(directionSize, size) {
27.14056 +        if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return [directionSize, size[1]];
27.14057 +        else return [size[0], directionSize];
27.14058 +    }
27.14059 +
27.14060 +    /**
27.14061 +     * Apply changes from this component to the corresponding document element.
27.14062 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.14063 +     * and matrix transforms.
27.14064 +     *
27.14065 +     * @private
27.14066 +     * @method commit
27.14067 +     * @param {Context} context commit context
27.14068 +     */
27.14069 +    HeaderFooterLayout.prototype.commit = function commit(context) {
27.14070 +        var transform = context.transform;
27.14071 +        var origin = context.origin;
27.14072 +        var size = context.size;
27.14073 +        var opacity = context.opacity;
27.14074 +
27.14075 +        var headerSize = (this.options.headerSize !== undefined) ? this.options.headerSize : _resolveNodeSize.call(this, this.header, this.options.defaultHeaderSize);
27.14076 +        var footerSize = (this.options.footerSize !== undefined) ? this.options.footerSize : _resolveNodeSize.call(this, this.footer, this.options.defaultFooterSize);
27.14077 +        var contentSize = size[this.options.direction] - headerSize - footerSize;
27.14078 +
27.14079 +        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
27.14080 +
27.14081 +        var result = [
27.14082 +            {
27.14083 +                size: _finalSize.call(this, headerSize, size),
27.14084 +                target: this.header.render()
27.14085 +            },
27.14086 +            {
27.14087 +                transform: _outputTransform.call(this, headerSize),
27.14088 +                size: _finalSize.call(this, contentSize, size),
27.14089 +                target: this.content.render()
27.14090 +            },
27.14091 +            {
27.14092 +                transform: _outputTransform.call(this, headerSize + contentSize),
27.14093 +                size: _finalSize.call(this, footerSize, size),
27.14094 +                target: this.footer.render()
27.14095 +            }
27.14096 +        ];
27.14097 +
27.14098 +        return {
27.14099 +            transform: transform,
27.14100 +            opacity: opacity,
27.14101 +            size: size,
27.14102 +            target: result
27.14103 +        };
27.14104 +    };
27.14105 +
27.14106 +    module.exports = HeaderFooterLayout;
27.14107 +});
27.14108 +
27.14109 +define('famous/views/Lightbox',['require','exports','module','famous/core/Transform','famous/core/Modifier','famous/core/RenderNode','famous/utilities/Utility','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
27.14110 +    var Transform = require('famous/core/Transform');
27.14111 +    var Modifier = require('famous/core/Modifier');
27.14112 +    var RenderNode = require('famous/core/RenderNode');
27.14113 +    var Utility = require('famous/utilities/Utility');
27.14114 +    var OptionsManager = require('famous/core/OptionsManager');
27.14115 +    var Transitionable = require('famous/transitions/Transitionable');
27.14116 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
27.14117 +
27.14118 +    /**
27.14119 +     * Lightbox, using transitions, shows and hides different renderables. Lightbox can essentially be
27.14120 +     * thought of as RenderController with a stateful implementation and interface.
27.14121 +     *
27.14122 +     * @class Lightbox
27.14123 +     * @constructor
27.14124 +     * @param {Options} [options] An object of configurable options.
27.14125 +     * @param {Transform} [options.inTransform] The transform at the start of transitioning in a shown renderable.
27.14126 +     * @param {Transform} [options.outTransform] The transform at the end of transitioning out a renderable.
27.14127 +     * @param {Transform} [options.showTransform] The transform applied to your shown renderable in its state of equilibrium.
27.14128 +     * @param {Number} [options.inOpacity] A number between one and zero that defines the state of a shown renderables opacity upon initially
27.14129 +     * being transitioned in.
27.14130 +     * @param {Number} [options.outOpacity] A number between one and zero that defines the state of a shown renderables opacity upon being
27.14131 +     * fully transitioned out.
27.14132 +     * @param {Number} [options.showOpacity] A number between one and zero that defines the state of a shown renderables opacity
27.14133 +     * once succesfully transitioned in.
27.14134 +     * @param {Array<Number>} [options.inOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables
27.14135 +     * origin upon intially being transitioned in.
27.14136 +     * @param {Array<Number>} [options.outOrigin] A two value array of numbers between one and zero that defines the state of a shown renderable
27.14137 +     * once fully hidden.
27.14138 +     * @param {Array<Number>} [options.showOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables
27.14139 +     * origin upon succesfully being shown.
27.14140 +     * @param {Transition} [options.inTransition=true] The transition in charge of showing a renderable.
27.14141 +     * @param {Transition} [options.outTransition=true]  The transition in charge of removing your previous renderable when
27.14142 +     * you show a new one, or hiding your current renderable.
27.14143 +     * @param {Boolean} [options.overlap=false] When showing a new renderable, overlap determines if the
27.14144 +     *   out transition of the old one executes concurrently with the in transition of the new one,
27.14145 +      *  or synchronously beforehand.
27.14146 +     */
27.14147 +    function Lightbox(options) {
27.14148 +        this.options = Object.create(Lightbox.DEFAULT_OPTIONS);
27.14149 +        this._optionsManager = new OptionsManager(this.options);
27.14150 +
27.14151 +        if (options) this.setOptions(options);
27.14152 +
27.14153 +        this._showing = false;
27.14154 +        this.nodes = [];
27.14155 +        this.transforms = [];
27.14156 +        this.states = [];
27.14157 +    }
27.14158 +
27.14159 +    Lightbox.DEFAULT_OPTIONS = {
27.14160 +        inTransform: Transform.scale(0.001, 0.001, 0.001),
27.14161 +        inOpacity: 0,
27.14162 +        inOrigin: [0.5, 0.5],
27.14163 +        outTransform: Transform.scale(0.001, 0.001, 0.001),
27.14164 +        outOpacity: 0,
27.14165 +        outOrigin: [0.5, 0.5],
27.14166 +        showTransform: Transform.identity,
27.14167 +        showOpacity: 1,
27.14168 +        showOrigin: [0.5, 0.5],
27.14169 +        inTransition: true,
27.14170 +        outTransition: true,
27.14171 +        overlap: false
27.14172 +    };
27.14173 +
27.14174 +    /**
27.14175 +     * Patches the Lightbox instance's options with the passed-in ones.
27.14176 +     *
27.14177 +     * @method setOptions
27.14178 +     * @param {Options} options An object of configurable options for the Lightbox instance.
27.14179 +     */
27.14180 +    Lightbox.prototype.setOptions = function setOptions(options) {
27.14181 +        return this._optionsManager.setOptions(options);
27.14182 +    };
27.14183 +
27.14184 +   /**
27.14185 +     * Show displays the targeted renderable with a transition and an optional callback to
27.14186 +     *  execute afterwards.
27.14187 +     * @method show
27.14188 +     * @param {Object} renderable The renderable you want to show.
27.14189 +     * @param {Transition} [transition] Overwrites the default transition in to display the
27.14190 +     * passed-in renderable.
27.14191 +     * @param {function} [callback] Executes after transitioning in the renderable.
27.14192 +     */
27.14193 +    Lightbox.prototype.show = function show(renderable, transition, callback) {
27.14194 +        if (!renderable) {
27.14195 +            return this.hide(callback);
27.14196 +        }
27.14197 +
27.14198 +        if (transition instanceof Function) {
27.14199 +            callback = transition;
27.14200 +            transition = undefined;
27.14201 +        }
27.14202 +
27.14203 +        if (this._showing) {
27.14204 +            if (this.options.overlap) this.hide();
27.14205 +            else {
27.14206 +                return this.hide(this.show.bind(this, renderable, transition, callback));
27.14207 +            }
27.14208 +        }
27.14209 +        this._showing = true;
27.14210 +
27.14211 +        var stateItem = {
27.14212 +            transform: new TransitionableTransform(this.options.inTransform),
27.14213 +            origin: new Transitionable(this.options.inOrigin),
27.14214 +            opacity: new Transitionable(this.options.inOpacity)
27.14215 +        };
27.14216 +
27.14217 +        var transform = new Modifier({
27.14218 +            transform: stateItem.transform,
27.14219 +            opacity: stateItem.opacity,
27.14220 +            origin: stateItem.origin
27.14221 +        });
27.14222 +        var node = new RenderNode();
27.14223 +        node.add(transform).add(renderable);
27.14224 +        this.nodes.push(node);
27.14225 +        this.states.push(stateItem);
27.14226 +        this.transforms.push(transform);
27.14227 +
27.14228 +        var _cb = callback ? Utility.after(3, callback) : undefined;
27.14229 +
27.14230 +        if (!transition) transition = this.options.inTransition;
27.14231 +        stateItem.transform.set(this.options.showTransform, transition, _cb);
27.14232 +        stateItem.opacity.set(this.options.showOpacity, transition, _cb);
27.14233 +        stateItem.origin.set(this.options.showOrigin, transition, _cb);
27.14234 +    };
27.14235 +
27.14236 +    /**
27.14237 +     * Hide hides the currently displayed renderable with an out transition.
27.14238 +     * @method hide
27.14239 +     * @param {Transition} [transition] Overwrites the default transition in to hide the
27.14240 +     * currently controlled renderable.
27.14241 +     * @param {function} [callback] Executes after transitioning out the renderable.
27.14242 +     */
27.14243 +    Lightbox.prototype.hide = function hide(transition, callback) {
27.14244 +        if (!this._showing) return;
27.14245 +        this._showing = false;
27.14246 +
27.14247 +        if (transition instanceof Function) {
27.14248 +            callback = transition;
27.14249 +            transition = undefined;
27.14250 +        }
27.14251 +
27.14252 +        var node = this.nodes[this.nodes.length - 1];
27.14253 +        var transform = this.transforms[this.transforms.length - 1];
27.14254 +        var stateItem = this.states[this.states.length - 1];
27.14255 +        var _cb = Utility.after(3, function() {
27.14256 +            this.nodes.splice(this.nodes.indexOf(node), 1);
27.14257 +            this.states.splice(this.states.indexOf(stateItem), 1);
27.14258 +            this.transforms.splice(this.transforms.indexOf(transform), 1);
27.14259 +            if (callback) callback.call(this);
27.14260 +        }.bind(this));
27.14261 +
27.14262 +        if (!transition) transition = this.options.outTransition;
27.14263 +        stateItem.transform.set(this.options.outTransform, transition, _cb);
27.14264 +        stateItem.opacity.set(this.options.outOpacity, transition, _cb);
27.14265 +        stateItem.origin.set(this.options.outOrigin, transition, _cb);
27.14266 +    };
27.14267 +
27.14268 +    /**
27.14269 +     * Generate a render spec from the contents of this component.
27.14270 +     *
27.14271 +     * @private
27.14272 +     * @method render
27.14273 +     * @return {number} Render spec for this component
27.14274 +     */
27.14275 +    Lightbox.prototype.render = function render() {
27.14276 +        var result = [];
27.14277 +        for (var i = 0; i < this.nodes.length; i++) {
27.14278 +            result.push(this.nodes[i].render());
27.14279 +        }
27.14280 +        return result;
27.14281 +    };
27.14282 +
27.14283 +    module.exports = Lightbox;
27.14284 +});
27.14285 +
27.14286 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.14287 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.14288 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.14289 + *
27.14290 + * Owner: david@famo.us
27.14291 + * @license MPL 2.0
27.14292 + * @copyright Famous Industries, Inc. 2014
27.14293 + */
27.14294 +
27.14295 +define('famous/physics/forces/Drag',['require','exports','module','./Force'],function(require, exports, module) {
27.14296 +    var Force = require('./Force');
27.14297 +
27.14298 +    /**
27.14299 +     * Drag is a force that opposes velocity. Attach it to the physics engine
27.14300 +     * to slow down a physics body in motion.
27.14301 +     *
27.14302 +     * @class Drag
27.14303 +     * @constructor
27.14304 +     * @extends Force
27.14305 +     * @param {Object} options options to set on drag
27.14306 +     */
27.14307 +    function Drag(options) {
27.14308 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
27.14309 +        if (options) this.setOptions(options);
27.14310 +
27.14311 +        Force.call(this);
27.14312 +    }
27.14313 +
27.14314 +    Drag.prototype = Object.create(Force.prototype);
27.14315 +    Drag.prototype.constructor = Drag;
27.14316 +
27.14317 +    /**
27.14318 +     * @property Drag.FORCE_FUNCTIONS
27.14319 +     * @type Object
27.14320 +     * @protected
27.14321 +     * @static
27.14322 +     */
27.14323 +    Drag.FORCE_FUNCTIONS = {
27.14324 +
27.14325 +        /**
27.14326 +         * A drag force proportional to the velocity
27.14327 +         * @attribute LINEAR
27.14328 +         * @type Function
27.14329 +         * @param {Vector} velocity
27.14330 +         * @return {Vector} drag force
27.14331 +         */
27.14332 +        LINEAR : function(velocity) {
27.14333 +            return velocity;
27.14334 +        },
27.14335 +
27.14336 +        /**
27.14337 +         * A drag force proportional to the square of the velocity
27.14338 +         * @attribute QUADRATIC
27.14339 +         * @type Function
27.14340 +         * @param {Vector} velocity
27.14341 +         * @return {Vector} drag force
27.14342 +         */
27.14343 +        QUADRATIC : function(velocity) {
27.14344 +            return velocity.mult(velocity.norm());
27.14345 +        }
27.14346 +    };
27.14347 +
27.14348 +    /**
27.14349 +     * @property Drag.DEFAULT_OPTIONS
27.14350 +     * @type Object
27.14351 +     * @protected
27.14352 +     * @static
27.14353 +     */
27.14354 +    Drag.DEFAULT_OPTIONS = {
27.14355 +
27.14356 +        /**
27.14357 +         * The strength of the force
27.14358 +         *    Range : [0, 0.1]
27.14359 +         * @attribute strength
27.14360 +         * @type Number
27.14361 +         * @default 0.01
27.14362 +         */
27.14363 +        strength : 0.01,
27.14364 +
27.14365 +        /**
27.14366 +         * The type of opposing force
27.14367 +         * @attribute forceFunction
27.14368 +         * @type Function
27.14369 +         */
27.14370 +        forceFunction : Drag.FORCE_FUNCTIONS.LINEAR
27.14371 +    };
27.14372 +
27.14373 +    /**
27.14374 +     * Adds a drag force to a physics body's force accumulator.
27.14375 +     *
27.14376 +     * @method applyForce
27.14377 +     * @param targets {Array.Body} Array of bodies to apply drag force to.
27.14378 +     */
27.14379 +    Drag.prototype.applyForce = function applyForce(targets) {
27.14380 +        var strength        = this.options.strength;
27.14381 +        var forceFunction   = this.options.forceFunction;
27.14382 +        var force           = this.force;
27.14383 +        for (var index = 0; index < targets.length; index++) {
27.14384 +            var particle = targets[index];
27.14385 +            forceFunction(particle.velocity).mult(-strength).put(force);
27.14386 +            particle.applyForce(force);
27.14387 +        }
27.14388 +    };
27.14389 +
27.14390 +    /**
27.14391 +     * Basic options setter
27.14392 +     *
27.14393 +     * @method setOptions
27.14394 +     * @param {Objects} options
27.14395 +     */
27.14396 +    Drag.prototype.setOptions = function setOptions(options) {
27.14397 +        for (var key in options) this.options[key] = options[key];
27.14398 +    };
27.14399 +
27.14400 +    module.exports = Drag;
27.14401 +});
27.14402 +
27.14403 +define('famous/views/Scroller',['require','exports','module','famous/core/Entity','famous/core/Group','famous/core/OptionsManager','famous/core/Transform','famous/utilities/Utility','famous/core/ViewSequence','famous/core/EventHandler'],function(require, exports, module) {
27.14404 +    var Entity = require('famous/core/Entity');
27.14405 +    var Group = require('famous/core/Group');
27.14406 +    var OptionsManager = require('famous/core/OptionsManager');
27.14407 +    var Transform = require('famous/core/Transform');
27.14408 +    var Utility = require('famous/utilities/Utility');
27.14409 +    var ViewSequence = require('famous/core/ViewSequence');
27.14410 +    var EventHandler = require('famous/core/EventHandler');
27.14411 +
27.14412 +    /**
27.14413 +     * Scroller lays out a collection of renderables, and will browse through them based on
27.14414 +     * accessed position. Scroller also broadcasts an 'edgeHit' event, with a position property of the location of the edge,
27.14415 +     * when you've hit the 'edges' of it's renderable collection.
27.14416 +     * @class Scroller
27.14417 +     * @constructor
27.14418 +      * @event error
27.14419 +     * @param {Options} [options] An object of configurable options.
27.14420 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
27.14421 +     * module, this option will lay out the Scroller instance's renderables either horizontally
27.14422 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
27.14423 +     * to just use integers as well.
27.14424 +     * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scroller will display content in.
27.14425 +     * @param {Number} [margin=undefined] The size of the area (in pixels) that Scroller will process renderables' associated calculations in.
27.14426 +     */
27.14427 +    function Scroller(options) {
27.14428 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
27.14429 +        this._optionsManager = new OptionsManager(this.options);
27.14430 +        if (options) this._optionsManager.setOptions(options);
27.14431 +
27.14432 +        this._node = null;
27.14433 +        this._position = 0;
27.14434 +
27.14435 +        // used for shifting nodes
27.14436 +        this._positionOffset = 0;
27.14437 +
27.14438 +        this._positionGetter = null;
27.14439 +        this._outputFunction = null;
27.14440 +        this._masterOutputFunction = null;
27.14441 +        this.outputFrom();
27.14442 +
27.14443 +        this._onEdge = 0; // -1 for top, 1 for bottom
27.14444 +
27.14445 +        this.group = new Group();
27.14446 +        this.group.add({render: _innerRender.bind(this)});
27.14447 +
27.14448 +        this._entityId = Entity.register(this);
27.14449 +        this._size = [undefined, undefined];
27.14450 +        this._contextSize = [undefined, undefined];
27.14451 +
27.14452 +        this._eventInput = new EventHandler();
27.14453 +        this._eventOutput = new EventHandler();
27.14454 +
27.14455 +        EventHandler.setInputHandler(this, this._eventInput);
27.14456 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.14457 +    }
27.14458 +
27.14459 +    Scroller.DEFAULT_OPTIONS = {
27.14460 +        direction: Utility.Direction.Y,
27.14461 +        margin: 0,
27.14462 +        clipSize: undefined,
27.14463 +        groupScroll: false
27.14464 +    };
27.14465 +
27.14466 +    function _sizeForDir(size) {
27.14467 +        if (!size) size = this._contextSize;
27.14468 +        var dimension = (this.options.direction === Utility.Direction.X) ? 0 : 1;
27.14469 +        return (size[dimension] === undefined) ? this._contextSize[dimension] : size[dimension];
27.14470 +    }
27.14471 +
27.14472 +    function _output(node, offset, target) {
27.14473 +        var size = node.getSize ? node.getSize() : this._contextSize;
27.14474 +        var transform = this._outputFunction(offset);
27.14475 +        target.push({transform: transform, target: node.render()});
27.14476 +        return _sizeForDir.call(this, size);
27.14477 +    }
27.14478 +
27.14479 +    function _getClipSize() {
27.14480 +        if (this.options.clipSize) return this.options.clipSize;
27.14481 +        else return _sizeForDir.call(this, this._contextSize);
27.14482 +    }
27.14483 +
27.14484 +    /**
27.14485 +     * Patches the Scroller instance's options with the passed-in ones.
27.14486 +     * @method setOptions
27.14487 +     * @param {Options} options An object of configurable options for the Scroller instance.
27.14488 +     */
27.14489 +    Scroller.prototype.setOptions = function setOptions(options) {
27.14490 +        this._optionsManager.setOptions(options);
27.14491 +
27.14492 +        if (this.options.groupScroll) {
27.14493 +          this.group.pipe(this._eventOutput);
27.14494 +        }
27.14495 +        else {
27.14496 +          this.group.unpipe(this._eventOutput);
27.14497 +        }
27.14498 +    };
27.14499 +
27.14500 +    /**
27.14501 +     * Tells you if the Scroller instance is on an edge.
27.14502 +     * @method onEdge
27.14503 +     * @return {Boolean} Whether the Scroller instance is on an edge or not.
27.14504 +     */
27.14505 +    Scroller.prototype.onEdge = function onEdge() {
27.14506 +        return this._onEdge;
27.14507 +    };
27.14508 +
27.14509 +    /**
27.14510 +     * Allows you to overwrite the way Scroller lays out it's renderables. Scroller will
27.14511 +     * pass an offset into the function. By default the Scroller instance just translates each node
27.14512 +     * in it's direction by the passed-in offset.
27.14513 +     * Scroller will translate each renderable down
27.14514 +     * @method outputFrom
27.14515 +     * @param {Function} fn A function that takes an offset and returns a transform.
27.14516 +     * @param {Function} [masterFn]
27.14517 +     */
27.14518 +    Scroller.prototype.outputFrom = function outputFrom(fn, masterFn) {
27.14519 +        if (!fn) {
27.14520 +            fn = function(offset) {
27.14521 +                return (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset);
27.14522 +            }.bind(this);
27.14523 +            if (!masterFn) masterFn = fn;
27.14524 +        }
27.14525 +        this._outputFunction = fn;
27.14526 +        this._masterOutputFunction = masterFn ? masterFn : function(offset) {
27.14527 +            return Transform.inverse(fn(-offset));
27.14528 +        };
27.14529 +    };
27.14530 +
27.14531 +    /**
27.14532 +     * The Scroller instance's method for reading from an external position. Scroller uses
27.14533 +     * the external position to actually scroll through it's renderables.
27.14534 +     * @method positionFrom
27.14535 +     * @param {Getter} position Can be either a function that returns a position,
27.14536 +     * or an object with a get method that returns a position.
27.14537 +     */
27.14538 +    Scroller.prototype.positionFrom = function positionFrom(position) {
27.14539 +        if (position instanceof Function) this._positionGetter = position;
27.14540 +        else if (position && position.get) this._positionGetter = position.get.bind(position);
27.14541 +        else {
27.14542 +            this._positionGetter = null;
27.14543 +            this._position = position;
27.14544 +        }
27.14545 +        if (this._positionGetter) this._position = this._positionGetter.call(this);
27.14546 +    };
27.14547 +
27.14548 +    /**
27.14549 +     * Sets the collection of renderables under the Scroller instance's control.
27.14550 +     *
27.14551 +     * @method sequenceFrom
27.14552 +     * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence.
27.14553 +     * @chainable
27.14554 +     */
27.14555 +    Scroller.prototype.sequenceFrom = function sequenceFrom(node) {
27.14556 +        if (node instanceof Array) node = new ViewSequence({array: node});
27.14557 +        this._node = node;
27.14558 +        this._positionOffset = 0;
27.14559 +    };
27.14560 +
27.14561 +    /**
27.14562 +     * Returns the width and the height of the Scroller instance.
27.14563 +     *
27.14564 +     * @method getSize
27.14565 +     * @return {Array} A two value array of the Scroller instance's current width and height (in that order).
27.14566 +     */
27.14567 +    Scroller.prototype.getSize = function getSize(actual) {
27.14568 +        return actual ? this._contextSize : this._size;
27.14569 +    };
27.14570 +
27.14571 +    /**
27.14572 +     * Generate a render spec from the contents of this component.
27.14573 +     *
27.14574 +     * @private
27.14575 +     * @method render
27.14576 +     * @return {number} Render spec for this component
27.14577 +     */
27.14578 +    Scroller.prototype.render = function render() {
27.14579 +        if (!this._node) return null;
27.14580 +        if (this._positionGetter) this._position = this._positionGetter.call(this);
27.14581 +        return this._entityId;
27.14582 +    };
27.14583 +
27.14584 +    /**
27.14585 +     * Apply changes from this component to the corresponding document element.
27.14586 +     * This includes changes to classes, styles, size, content, opacity, origin,
27.14587 +     * and matrix transforms.
27.14588 +     *
27.14589 +     * @private
27.14590 +     * @method commit
27.14591 +     * @param {Context} context commit context
27.14592 +     */
27.14593 +    Scroller.prototype.commit = function commit(context) {
27.14594 +        var transform = context.transform;
27.14595 +        var opacity = context.opacity;
27.14596 +        var origin = context.origin;
27.14597 +        var size = context.size;
27.14598 +
27.14599 +        // reset edge detection on size change
27.14600 +        if (!this.options.clipSize && (size[0] !== this._contextSize[0] || size[1] !== this._contextSize[1])) {
27.14601 +            this._onEdge = 0;
27.14602 +            this._contextSize[0] = size[0];
27.14603 +            this._contextSize[1] = size[1];
27.14604 +
27.14605 +            if (this.options.direction === Utility.Direction.X) {
27.14606 +                this._size[0] = _getClipSize.call(this);
27.14607 +                this._size[1] = undefined;
27.14608 +            }
27.14609 +            else {
27.14610 +                this._size[0] = undefined;
27.14611 +                this._size[1] = _getClipSize.call(this);
27.14612 +            }
27.14613 +        }
27.14614 +
27.14615 +        var scrollTransform = this._masterOutputFunction(-this._position);
27.14616 +
27.14617 +        return {
27.14618 +            transform: Transform.multiply(transform, scrollTransform),
27.14619 +            size: size,
27.14620 +            opacity: opacity,
27.14621 +            origin: origin,
27.14622 +            target: this.group.render()
27.14623 +        };
27.14624 +    };
27.14625 +
27.14626 +    function _normalizeState() {
27.14627 +        var nodeSize = _sizeForDir.call(this, this._node.getSize());
27.14628 +        var nextNode = this._node && this._node.getNext ? this._node.getNext() : null;
27.14629 +        while (nextNode && this._position + this._positionOffset >= nodeSize) {
27.14630 +            this._positionOffset -= nodeSize;
27.14631 +            this._node = nextNode;
27.14632 +            nodeSize = _sizeForDir.call(this, this._node.getSize());
27.14633 +            nextNode = this._node && this._node.getNext ? this._node.getNext() : null;
27.14634 +        }
27.14635 +        var prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null;
27.14636 +        while (prevNode && this._position + this._positionOffset < 0) {
27.14637 +            var prevNodeSize = _sizeForDir.call(this, prevNode.getSize());
27.14638 +            this._positionOffset += prevNodeSize;
27.14639 +            this._node = prevNode;
27.14640 +            prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null;
27.14641 +        }
27.14642 +    }
27.14643 +
27.14644 +    function _innerRender() {
27.14645 +        var size = null;
27.14646 +        var position = this._position;
27.14647 +        var result = [];
27.14648 +
27.14649 +        this._onEdge = 0;
27.14650 +
27.14651 +        var offset = -this._positionOffset;
27.14652 +        var clipSize = _getClipSize.call(this);
27.14653 +        var currNode = this._node;
27.14654 +        while (currNode && offset - position < clipSize + this.options.margin) {
27.14655 +            offset += _output.call(this, currNode, offset, result);
27.14656 +            currNode = currNode.getNext ? currNode.getNext() : null;
27.14657 +        }
27.14658 +
27.14659 +        var sizeNode = this._node;
27.14660 +        var nodesSize = _sizeForDir.call(this, sizeNode.getSize());
27.14661 +        if (offset < clipSize) {
27.14662 +            while (sizeNode && nodesSize < clipSize) {
27.14663 +                sizeNode = sizeNode.getPrevious();
27.14664 +                if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize());
27.14665 +            }
27.14666 +            sizeNode = this._node;
27.14667 +            while (sizeNode && nodesSize < clipSize) {
27.14668 +                sizeNode = sizeNode.getNext();
27.14669 +                if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize());
27.14670 +            }
27.14671 +        }
27.14672 +
27.14673 +        var edgeSize = (nodesSize !== undefined && nodesSize < clipSize) ? nodesSize : clipSize;
27.14674 +
27.14675 +        if (!currNode && offset - position <= edgeSize) {
27.14676 +            this._onEdge = 1;
27.14677 +            this._eventOutput.emit('edgeHit', {
27.14678 +                position: offset - edgeSize
27.14679 +            });
27.14680 +        }
27.14681 +        else if (!this._node.getPrevious() && position <= 0) {
27.14682 +            this._onEdge = -1;
27.14683 +            this._eventOutput.emit('edgeHit', {
27.14684 +                position: 0
27.14685 +            });
27.14686 +        }
27.14687 +
27.14688 +        // backwards
27.14689 +        currNode = (this._node && this._node.getPrevious) ? this._node.getPrevious() : null;
27.14690 +        offset = -this._positionOffset;
27.14691 +        if (currNode) {
27.14692 +            size = currNode.getSize ? currNode.getSize() : this._contextSize;
27.14693 +            offset -= _sizeForDir.call(this, size);
27.14694 +        }
27.14695 +
27.14696 +        while (currNode && ((offset - position) > -(_getClipSize.call(this) + this.options.margin))) {
27.14697 +            _output.call(this, currNode, offset, result);
27.14698 +            currNode = currNode.getPrevious ? currNode.getPrevious() : null;
27.14699 +            if (currNode) {
27.14700 +                size = currNode.getSize ? currNode.getSize() : this._contextSize;
27.14701 +                offset -= _sizeForDir.call(this, size);
27.14702 +            }
27.14703 +        }
27.14704 +
27.14705 +        _normalizeState.call(this);
27.14706 +        return result;
27.14707 +    }
27.14708 +
27.14709 +    module.exports = Scroller;
27.14710 +});
27.14711 +
27.14712 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.14713 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.14714 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.14715 + *
27.14716 + * Owner: felix@famo.us
27.14717 + * @license MPL 2.0
27.14718 + * @copyright Famous Industries, Inc. 2014
27.14719 + */
27.14720 +
27.14721 +define('famous/views/Scrollview',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Drag','famous/physics/forces/Spring','famous/core/EventHandler','famous/core/OptionsManager','famous/core/ViewSequence','famous/views/Scroller','famous/utilities/Utility','famous/inputs/GenericSync','famous/inputs/ScrollSync','famous/inputs/TouchSync'],function(require, exports, module) {
27.14722 +    var PhysicsEngine = require('famous/physics/PhysicsEngine');
27.14723 +    var Particle = require('famous/physics/bodies/Particle');
27.14724 +    var Drag = require('famous/physics/forces/Drag');
27.14725 +    var Spring = require('famous/physics/forces/Spring');
27.14726 +
27.14727 +    var EventHandler = require('famous/core/EventHandler');
27.14728 +    var OptionsManager = require('famous/core/OptionsManager');
27.14729 +    var ViewSequence = require('famous/core/ViewSequence');
27.14730 +    var Scroller = require('famous/views/Scroller');
27.14731 +    var Utility = require('famous/utilities/Utility');
27.14732 +
27.14733 +    var GenericSync = require('famous/inputs/GenericSync');
27.14734 +    var ScrollSync = require('famous/inputs/ScrollSync');
27.14735 +    var TouchSync = require('famous/inputs/TouchSync');
27.14736 +    GenericSync.register({scroll : ScrollSync, touch : TouchSync});
27.14737 +
27.14738 +    /**
27.14739 +     * Scrollview will lay out a collection of renderables sequentially in the specified direction, and will
27.14740 +     * allow you to scroll through them with mousewheel or touch events.
27.14741 +     * @class Scrollview
27.14742 +     * @constructor
27.14743 +     * @param {Options} [options] An object of configurable options.
27.14744 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
27.14745 +     * module, this option will lay out the Scrollview instance's renderables either horizontally
27.14746 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
27.14747 +     * to just use integers as well.
27.14748 +     * @param {Boolean} [options.rails=true] When true, Scrollview's genericSync will only process input in it's primary access.
27.14749 +     * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scrollview will display content in.
27.14750 +     * @param {Number} [margin=undefined] The size of the area (in pixels) that Scrollview will process renderables' associated calculations in.
27.14751 +     * @param {Number} [friction=0.001] Input resistance proportional to the velocity of the input.
27.14752 +     * Controls the feel of the Scrollview instance at low velocities.
27.14753 +     * @param {Number} [drag=0.0001] Input resistance proportional to the square of the velocity of the input.
27.14754 +     * Affects Scrollview instance more prominently at high velocities.
27.14755 +     * @param {Number} [edgeGrip=0.5] A coefficient for resistance against after-touch momentum.
27.14756 +     * @param {Number} [egePeriod=300] Sets the period on the spring that handles the physics associated
27.14757 +     * with hitting the end of a scrollview.
27.14758 +     * @param {Number} [edgeDamp=1] Sets the damping on the spring that handles the physics associated
27.14759 +     * with hitting the end of a scrollview.
27.14760 +     * @param {Boolean} [paginated=false] A paginated scrollview will scroll through items discretely
27.14761 +     * rather than continously.
27.14762 +     * @param {Number} [pagePeriod=500] Sets the period on the spring that handles the physics associated
27.14763 +     * with pagination.
27.14764 +     * @param {Number} [pageDamp=0.8] Sets the damping on the spring that handles the physics associated
27.14765 +     * with pagination.
27.14766 +     * @param {Number} [pageStopSpeed=Infinity] The threshold for determining the amount of velocity
27.14767 +     * required to trigger pagination. The lower the threshold, the easier it is to scroll continuosly.
27.14768 +     * @param {Number} [pageSwitchSpeed=1] The threshold for momentum-based velocity pagination.
27.14769 +     * @param {Number} [speedLimit=10] The highest scrolling speed you can reach.
27.14770 +     */
27.14771 +    function Scrollview(options) {
27.14772 +        this.options = Object.create(Scrollview.DEFAULT_OPTIONS);
27.14773 +        this._optionsManager = new OptionsManager(this.options);
27.14774 +
27.14775 +        this._node = null;
27.14776 +
27.14777 +        this._physicsEngine = new PhysicsEngine();
27.14778 +        this._particle = new Particle();
27.14779 +        this._physicsEngine.addBody(this._particle);
27.14780 +
27.14781 +        this.spring = new Spring({anchor: [0, 0, 0]});
27.14782 +
27.14783 +        this.drag = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.QUADRATIC});
27.14784 +        this.friction = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.LINEAR});
27.14785 +
27.14786 +        this.sync = new GenericSync(['scroll', 'touch'], {direction : this.options.direction});
27.14787 +
27.14788 +        this._eventInput = new EventHandler();
27.14789 +        this._eventOutput = new EventHandler();
27.14790 +
27.14791 +        this._eventInput.pipe(this.sync);
27.14792 +        this.sync.pipe(this._eventInput);
27.14793 +
27.14794 +        EventHandler.setInputHandler(this, this._eventInput);
27.14795 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.14796 +
27.14797 +        this._touchCount = 0;
27.14798 +        this._springState = 0;
27.14799 +        this._onEdge = 0; // -1 for top, 1 for bottom
27.14800 +        this._pageSpringPosition = 0;
27.14801 +        this._edgeSpringPosition = 0;
27.14802 +        this._touchVelocity = undefined;
27.14803 +        this._earlyEnd = false;
27.14804 +        this._needsPaginationCheck = false;
27.14805 +
27.14806 +        this._scroller = new Scroller();
27.14807 +        this._scroller.positionFrom(this.getPosition.bind(this));
27.14808 +
27.14809 +        this.setOptions(options);
27.14810 +
27.14811 +        _bindEvents.call(this);
27.14812 +    }
27.14813 +
27.14814 +    /** @const */
27.14815 +    var TOLERANCE = 0.5;
27.14816 +
27.14817 +    Scrollview.DEFAULT_OPTIONS = {
27.14818 +        direction: Utility.Direction.Y,
27.14819 +        rails: true,
27.14820 +        friction: 0.001,
27.14821 +        drag: 0.0001,
27.14822 +        edgeGrip: 0.5,
27.14823 +        edgePeriod: 300,
27.14824 +        edgeDamp: 1,
27.14825 +        margin: 1000,       // mostly safe
27.14826 +        paginated: false,
27.14827 +        pagePeriod: 500,
27.14828 +        pageDamp: 0.8,
27.14829 +        pageStopSpeed: 10,
27.14830 +        pageSwitchSpeed: 0.5,
27.14831 +        speedLimit: 10,
27.14832 +        groupScroll: false
27.14833 +    };
27.14834 +
27.14835 +    /** @enum */
27.14836 +    var SpringStates = {
27.14837 +        NONE: 0,
27.14838 +        EDGE: 1,
27.14839 +        PAGE: 2
27.14840 +    };
27.14841 +
27.14842 +    function _handleStart(event) {
27.14843 +        this._touchCount = event.count;
27.14844 +        if (event.count === undefined) this._touchCount = 1;
27.14845 +
27.14846 +        _detachAgents.call(this);
27.14847 +        this.setVelocity(0);
27.14848 +        this._touchVelocity = 0;
27.14849 +        this._earlyEnd = false;
27.14850 +    }
27.14851 +
27.14852 +    function _handleMove(event) {
27.14853 +        var velocity = -event.velocity;
27.14854 +        var delta = -event.delta;
27.14855 +
27.14856 +        if (this._onEdge && event.slip) {
27.14857 +            if ((velocity < 0 && this._onEdge < 0) || (velocity > 0 && this._onEdge > 0)) {
27.14858 +                if (!this._earlyEnd) {
27.14859 +                    _handleEnd.call(this, event);
27.14860 +                    this._earlyEnd = true;
27.14861 +                }
27.14862 +            }
27.14863 +            else if (this._earlyEnd && (Math.abs(velocity) > Math.abs(this.getVelocity()))) {
27.14864 +                _handleStart.call(this, event);
27.14865 +            }
27.14866 +        }
27.14867 +        if (this._earlyEnd) return;
27.14868 +        this._touchVelocity = velocity;
27.14869 +
27.14870 +        if (event.slip) this.setVelocity(velocity);
27.14871 +        else this.setPosition(this.getPosition() + delta);
27.14872 +    }
27.14873 +
27.14874 +    function _handleEnd(event) {
27.14875 +        this._touchCount = event.count || 0;
27.14876 +        if (!this._touchCount) {
27.14877 +            _detachAgents.call(this);
27.14878 +            if (this._onEdge) _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE);
27.14879 +            _attachAgents.call(this);
27.14880 +            var velocity = -event.velocity;
27.14881 +            var speedLimit = this.options.speedLimit;
27.14882 +            if (event.slip) speedLimit *= this.options.edgeGrip;
27.14883 +            if (velocity < -speedLimit) velocity = -speedLimit;
27.14884 +            else if (velocity > speedLimit) velocity = speedLimit;
27.14885 +            this.setVelocity(velocity);
27.14886 +            this._touchVelocity = undefined;
27.14887 +            this._needsPaginationCheck = true;
27.14888 +        }
27.14889 +    }
27.14890 +
27.14891 +    function _bindEvents() {
27.14892 +        this._eventInput.bindThis(this);
27.14893 +        this._eventInput.on('start', _handleStart);
27.14894 +        this._eventInput.on('update', _handleMove);
27.14895 +        this._eventInput.on('end', _handleEnd);
27.14896 +
27.14897 +        this._scroller.on('edgeHit', function(data) {
27.14898 +            this._edgeSpringPosition = data.position;
27.14899 +        }.bind(this));
27.14900 +    }
27.14901 +
27.14902 +    function _attachAgents() {
27.14903 +        if (this._springState) this._physicsEngine.attach([this.spring], this._particle);
27.14904 +        else this._physicsEngine.attach([this.drag, this.friction], this._particle);
27.14905 +    }
27.14906 +
27.14907 +    function _detachAgents() {
27.14908 +        this._springState = SpringStates.NONE;
27.14909 +        this._physicsEngine.detachAll();
27.14910 +    }
27.14911 +
27.14912 +    function _nodeSizeForDirection(node) {
27.14913 +        var direction = this.options.direction;
27.14914 +        var nodeSize = (node.getSize() || this._scroller.getSize())[direction];
27.14915 +        if (!nodeSize) nodeSize = this._scroller.getSize()[direction];
27.14916 +        return nodeSize;
27.14917 +    }
27.14918 +
27.14919 +    function _handleEdge(edgeDetected) {
27.14920 +        if (!this._onEdge && edgeDetected) {
27.14921 +            this.sync.setOptions({scale: this.options.edgeGrip});
27.14922 +            if (!this._touchCount && this._springState !== SpringStates.EDGE) {
27.14923 +                _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE);
27.14924 +            }
27.14925 +        }
27.14926 +        else if (this._onEdge && !edgeDetected) {
27.14927 +            this.sync.setOptions({scale: 1});
27.14928 +            if (this._springState && Math.abs(this.getVelocity()) < 0.001) {
27.14929 +                // reset agents, detaching the spring
27.14930 +                _detachAgents.call(this);
27.14931 +                _attachAgents.call(this);
27.14932 +            }
27.14933 +        }
27.14934 +        this._onEdge = edgeDetected;
27.14935 +    }
27.14936 +
27.14937 +    function _handlePagination() {
27.14938 +        if (!this._needsPaginationCheck) return;
27.14939 +
27.14940 +        if (this._touchCount) return;
27.14941 +        if (this._springState === SpringStates.EDGE) return;
27.14942 +
27.14943 +        var velocity = this.getVelocity();
27.14944 +        if (Math.abs(velocity) >= this.options.pageStopSpeed) return;
27.14945 +
27.14946 +        var position = this.getPosition();
27.14947 +        var velocitySwitch = Math.abs(velocity) > this.options.pageSwitchSpeed;
27.14948 +
27.14949 +        // parameters to determine when to switch
27.14950 +        var nodeSize = _nodeSizeForDirection.call(this, this._node);
27.14951 +        var positionNext = position > 0.5 * nodeSize;
27.14952 +        var velocityNext = velocity > 0;
27.14953 +
27.14954 +        if ((positionNext && !velocitySwitch) || (velocitySwitch && velocityNext)) this.goToNextPage();
27.14955 +        else _setSpring.call(this, 0, SpringStates.PAGE);
27.14956 +
27.14957 +        this._needsPaginationCheck = false;
27.14958 +    }
27.14959 +
27.14960 +    function _setSpring(position, springState) {
27.14961 +        var springOptions;
27.14962 +        if (springState === SpringStates.EDGE) {
27.14963 +            this._edgeSpringPosition = position;
27.14964 +            springOptions = {
27.14965 +                anchor: [this._edgeSpringPosition, 0, 0],
27.14966 +                period: this.options.edgePeriod,
27.14967 +                dampingRatio: this.options.edgeDamp
27.14968 +            };
27.14969 +        }
27.14970 +        else if (springState === SpringStates.PAGE) {
27.14971 +            this._pageSpringPosition = position;
27.14972 +            springOptions = {
27.14973 +                anchor: [this._pageSpringPosition, 0, 0],
27.14974 +                period: this.options.pagePeriod,
27.14975 +                dampingRatio: this.options.pageDamp
27.14976 +            };
27.14977 +        }
27.14978 +
27.14979 +        this.spring.setOptions(springOptions);
27.14980 +        if (springState && !this._springState) {
27.14981 +            _detachAgents.call(this);
27.14982 +            this._springState = springState;
27.14983 +            _attachAgents.call(this);
27.14984 +        }
27.14985 +        this._springState = springState;
27.14986 +    }
27.14987 +
27.14988 +    function _normalizeState() {
27.14989 +        var position = this.getPosition();
27.14990 +        var nodeSize = _nodeSizeForDirection.call(this, this._node);
27.14991 +        var nextNode = this._node.getNext();
27.14992 +
27.14993 +        while (position > nodeSize + TOLERANCE && nextNode) {
27.14994 +            _shiftOrigin.call(this, -nodeSize);
27.14995 +            position -= nodeSize;
27.14996 +            this._scroller.sequenceFrom(nextNode);
27.14997 +            this._node = nextNode;
27.14998 +            nextNode = this._node.getNext();
27.14999 +            nodeSize = _nodeSizeForDirection.call(this, this._node);
27.15000 +        }
27.15001 +
27.15002 +        var previousNode = this._node.getPrevious();
27.15003 +        var previousNodeSize;
27.15004 +
27.15005 +        while (position < -TOLERANCE && previousNode) {
27.15006 +            previousNodeSize = _nodeSizeForDirection.call(this, previousNode);
27.15007 +            this._scroller.sequenceFrom(previousNode);
27.15008 +            this._node = previousNode;
27.15009 +            _shiftOrigin.call(this, previousNodeSize);
27.15010 +            position += previousNodeSize;
27.15011 +            previousNode = this._node.getPrevious();
27.15012 +        }
27.15013 +    }
27.15014 +
27.15015 +    function _shiftOrigin(amount) {
27.15016 +        this._edgeSpringPosition += amount;
27.15017 +        this._pageSpringPosition += amount;
27.15018 +        this.setPosition(this.getPosition() + amount);
27.15019 +        if (this._springState === SpringStates.EDGE) {
27.15020 +            this.spring.setOptions({anchor: [this._edgeSpringPosition, 0, 0]});
27.15021 +        }
27.15022 +        else if (this._springState === SpringStates.PAGE) {
27.15023 +            this.spring.setOptions({anchor: [this._pageSpringPosition, 0, 0]});
27.15024 +        }
27.15025 +    }
27.15026 +
27.15027 +    Scrollview.prototype.outputFrom = function outputFrom() {
27.15028 +        return this._scroller.outputFrom.apply(this._scroller, arguments);
27.15029 +    };
27.15030 +
27.15031 +    /**
27.15032 +     * Returns the position associated with the Scrollview instance's current node
27.15033 +     *  (generally the node currently at the top).
27.15034 +     * @method getPosition
27.15035 +     * @param {number} [node] If specified, returns the position of the node at that index in the
27.15036 +     * Scrollview instance's currently managed collection.
27.15037 +     * @return {number} The position of either the specified node, or the Scrollview's current Node,
27.15038 +     * in pixels translated.
27.15039 +     */
27.15040 +    Scrollview.prototype.getPosition = function getPosition() {
27.15041 +        return this._particle.getPosition1D();
27.15042 +    };
27.15043 +
27.15044 +    /**
27.15045 +     * Sets position of the physics particle that controls Scrollview instance's "position"
27.15046 +     * @method setPosition
27.15047 +     * @param {number} x The amount of pixels you want your scrollview to progress by.
27.15048 +     */
27.15049 +    Scrollview.prototype.setPosition = function setPosition(x) {
27.15050 +        this._particle.setPosition1D(x);
27.15051 +    };
27.15052 +
27.15053 +    /**
27.15054 +     * Returns the Scrollview instance's velocity.
27.15055 +     * @method getVelocity
27.15056 +     * @return {Number} The velocity.
27.15057 +     */
27.15058 +
27.15059 +    Scrollview.prototype.getVelocity = function getVelocity() {
27.15060 +        return this._touchCount ? this._touchVelocity : this._particle.getVelocity1D();
27.15061 +    };
27.15062 +
27.15063 +    /**
27.15064 +     * Sets the Scrollview instance's velocity. Until affected by input or another call of setVelocity
27.15065 +     *  the Scrollview instance will scroll at the passed-in velocity.
27.15066 +     * @method setVelocity
27.15067 +     * @param {number} v The magnitude of the velocity.
27.15068 +     */
27.15069 +    Scrollview.prototype.setVelocity = function setVelocity(v) {
27.15070 +        this._particle.setVelocity1D(v);
27.15071 +    };
27.15072 +
27.15073 +    /**
27.15074 +     * Patches the Scrollview instance's options with the passed-in ones.
27.15075 +     * @method setOptions
27.15076 +     * @param {Options} options An object of configurable options for the Scrollview instance.
27.15077 +     */
27.15078 +    Scrollview.prototype.setOptions = function setOptions(options) {
27.15079 +        if (options) {
27.15080 +            if (options.direction !== undefined) {
27.15081 +                if (options.direction === 'x') options.direction = Utility.Direction.X;
27.15082 +                else if (options.direction === 'y') options.direction = Utility.Direction.Y;
27.15083 +            }
27.15084 +
27.15085 +            this._scroller.setOptions(options);
27.15086 +            this._optionsManager.setOptions(options);
27.15087 +        }
27.15088 +
27.15089 +        this._scroller.setOptions(this.options);
27.15090 +        if (this.options.groupScroll)
27.15091 +            this._scroller.pipe(this._eventInput);
27.15092 +        else
27.15093 +            this._scroller.unpipe(this._eventInput);
27.15094 +
27.15095 +        this.drag.setOptions({strength: this.options.drag});
27.15096 +        this.friction.setOptions({strength: this.options.friction});
27.15097 +
27.15098 +        this.spring.setOptions({
27.15099 +            period: this.options.edgePeriod,
27.15100 +            dampingRatio: this.options.edgeDamp
27.15101 +        });
27.15102 +
27.15103 +        this.sync.setOptions({
27.15104 +            rails: this.options.rails,
27.15105 +            direction: (this.options.direction === Utility.Direction.X) ? GenericSync.DIRECTION_X : GenericSync.DIRECTION_Y
27.15106 +        });
27.15107 +    };
27.15108 +
27.15109 +    /**
27.15110 +     * goToPreviousPage paginates your Scrollview instance backwards by one item.
27.15111 +     * @method goToPreviousPage
27.15112 +     * @return {ViewSequence} The previous node.
27.15113 +     */
27.15114 +    Scrollview.prototype.goToPreviousPage = function goToPreviousPage() {
27.15115 +        if (!this._node) return null;
27.15116 +        var previousNode = this._node.getPrevious();
27.15117 +        if (previousNode) {
27.15118 +            var currentPosition = this.getPosition();
27.15119 +            var previousNodeSize = _nodeSizeForDirection.call(this, previousNode);
27.15120 +            this._scroller.sequenceFrom(previousNode);
27.15121 +            this._node = previousNode;
27.15122 +            var previousSpringPosition = (currentPosition < TOLERANCE) ? -previousNodeSize : 0;
27.15123 +            _setSpring.call(this, previousSpringPosition, SpringStates.PAGE);
27.15124 +            _shiftOrigin.call(this, previousNodeSize);
27.15125 +        }
27.15126 +        this._eventOutput.emit('pageChange', {direction: -1});
27.15127 +        return previousNode;
27.15128 +    };
27.15129 +
27.15130 +    /**
27.15131 +     * goToNextPage paginates your Scrollview instance forwards by one item.
27.15132 +     * @method goToNextPage
27.15133 +     * @return {ViewSequence} The next node.
27.15134 +     */
27.15135 +    Scrollview.prototype.goToNextPage = function goToNextPage() {
27.15136 +        if (!this._node) return null;
27.15137 +        var nextNode = this._node.getNext();
27.15138 +        if (nextNode) {
27.15139 +            var currentPosition = this.getPosition();
27.15140 +            var currentNodeSize = _nodeSizeForDirection.call(this, this._node);
27.15141 +            var nextNodeSize = _nodeSizeForDirection.call(this, nextNode);
27.15142 +            this._scroller.sequenceFrom(nextNode);
27.15143 +            this._node = nextNode;
27.15144 +            var nextSpringPosition = (currentPosition > currentNodeSize - TOLERANCE) ? currentNodeSize + nextNodeSize : currentNodeSize;
27.15145 +            _setSpring.call(this, nextSpringPosition, SpringStates.PAGE);
27.15146 +            _shiftOrigin.call(this, -currentNodeSize);
27.15147 +        }
27.15148 +        this._eventOutput.emit('pageChange', {direction: 1});
27.15149 +        return nextNode;
27.15150 +    };
27.15151 +
27.15152 +    /**
27.15153 +     * Sets the collection of renderables under the Scrollview instance's control, by
27.15154 +     *  setting its current node to the passed in ViewSequence. If you
27.15155 +     *  pass in an array, the Scrollview instance will set its node as a ViewSequence instantiated with
27.15156 +     *  the passed-in array.
27.15157 +     *
27.15158 +     * @method sequenceFrom
27.15159 +     * @param {Array|ViewSequence} node Either an array of renderables or a Famous viewSequence.
27.15160 +     */
27.15161 +    Scrollview.prototype.sequenceFrom = function sequenceFrom(node) {
27.15162 +        if (node instanceof Array) node = new ViewSequence({array: node});
27.15163 +        this._node = node;
27.15164 +        return this._scroller.sequenceFrom(node);
27.15165 +    };
27.15166 +
27.15167 +    /**
27.15168 +     * Returns the width and the height of the Scrollview instance.
27.15169 +     *
27.15170 +     * @method getSize
27.15171 +     * @return {Array} A two value array of the Scrollview instance's current width and height (in that order).
27.15172 +     */
27.15173 +    Scrollview.prototype.getSize = function getSize() {
27.15174 +        return this._scroller.getSize.apply(this._scroller, arguments);
27.15175 +    };
27.15176 +
27.15177 +    /**
27.15178 +     * Generate a render spec from the contents of this component.
27.15179 +     *
27.15180 +     * @private
27.15181 +     * @method render
27.15182 +     * @return {number} Render spec for this component
27.15183 +     */
27.15184 +    Scrollview.prototype.render = function render() {
27.15185 +        if (!this._node) return null;
27.15186 +
27.15187 +        _normalizeState.call(this);
27.15188 +        _handleEdge.call(this, this._scroller.onEdge());
27.15189 +        if (this.options.paginated) _handlePagination.call(this);
27.15190 +
27.15191 +        return this._scroller.render();
27.15192 +    };
27.15193 +
27.15194 +    module.exports = Scrollview;
27.15195 +});
27.15196 +
27.15197 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15198 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15199 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15200 + *
27.15201 + * Owner: felix@famo.us
27.15202 + * @license MPL 2.0
27.15203 + * @copyright Famous Industries, Inc. 2014
27.15204 + */
27.15205 +
27.15206 +define('famous/views/ScrollContainer',['require','exports','module','famous/surfaces/ContainerSurface','famous/core/EventHandler','./Scrollview','famous/utilities/Utility','famous/core/OptionsManager'],function(require, exports, module) {
27.15207 +    var ContainerSurface = require('famous/surfaces/ContainerSurface');
27.15208 +    var EventHandler = require('famous/core/EventHandler');
27.15209 +    var Scrollview = require('./Scrollview');
27.15210 +    var Utility = require('famous/utilities/Utility');
27.15211 +    var OptionsManager = require('famous/core/OptionsManager');
27.15212 +
27.15213 +    /**
27.15214 +     * A Container surface with a scrollview automatically added. The convenience of ScrollContainer lies in
27.15215 +     * being able to clip out portions of the associated scrollview that lie outside the bounding surface,
27.15216 +     * and in being able to move the scrollview more easily by applying modifiers to the parent container
27.15217 +     * surface.
27.15218 +     * @class ScrollContainer
27.15219 +     * @constructor
27.15220 +     * @param {Options} [options] An object of configurable options.
27.15221 +     * @param {Options} [options.container=undefined] Options for the ScrollContainer instance's surface.
27.15222 +     * @param {Options} [options.scrollview={direction:Utility.Direction.X}]  Options for the ScrollContainer instance's scrollview.
27.15223 +     */
27.15224 +    function ScrollContainer(options) {
27.15225 +        this.options = Object.create(ScrollContainer.DEFAULT_OPTIONS);
27.15226 +        this._optionsManager = new OptionsManager(this.options);
27.15227 +
27.15228 +        if (options) this.setOptions(options);
27.15229 +
27.15230 +        this.container = new ContainerSurface(this.options.container);
27.15231 +        this.scrollview = new Scrollview(this.options.scrollview);
27.15232 +
27.15233 +        this.container.add(this.scrollview);
27.15234 +
27.15235 +        EventHandler.setInputHandler(this, this.scrollview);
27.15236 +        EventHandler.setOutputHandler(this, this.scrollview);
27.15237 +        this.scrollview.subscribe(this.container);
27.15238 +    }
27.15239 +
27.15240 +    ScrollContainer.DEFAULT_OPTIONS = {
27.15241 +        container: {
27.15242 +            properties: {overflow : 'hidden'}
27.15243 +        },
27.15244 +        scrollview: {direction: Utility.Direction.X}
27.15245 +    };
27.15246 +
27.15247 +    /**
27.15248 +     * Patches the ScrollContainer instance's options with the passed-in ones.
27.15249 +     *
27.15250 +     * @method setOptions
27.15251 +     * @param {Options} options An object of configurable options for the ScrollContainer instance.
27.15252 +     */
27.15253 +    ScrollContainer.prototype.setOptions = function setOptions(options) {
27.15254 +        return this._optionsManager.setOptions(options);
27.15255 +    };
27.15256 +
27.15257 +    /**
27.15258 +     * Sets the collection of renderables under the ScrollContainer instance scrollview's control.
27.15259 +     *
27.15260 +     * @method sequenceFrom
27.15261 +     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous ViewSequence.
27.15262 +     */
27.15263 +    ScrollContainer.prototype.sequenceFrom = function sequenceFrom() {
27.15264 +        return this.scrollview.sequenceFrom.apply(this.scrollview, arguments);
27.15265 +    };
27.15266 +
27.15267 +    /**
27.15268 +     * Generate a render spec from the contents of this component.
27.15269 +     *
27.15270 +     * @private
27.15271 +     * @method render
27.15272 +     * @return {number} Render spec for this component
27.15273 +     */
27.15274 +    ScrollContainer.prototype.render = function render() {
27.15275 +        return this.container.render.apply(this.container, arguments);
27.15276 +    };
27.15277 +
27.15278 +    module.exports = ScrollContainer;
27.15279 +});
27.15280 +
27.15281 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15282 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15283 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15284 + *
27.15285 + * Owner: mark@famo.us
27.15286 + * @license MPL 2.0
27.15287 + * @copyright Famous Industries, Inc. 2014
27.15288 + */
27.15289 +
27.15290 +define('famous/widgets/NavigationBar',['require','exports','module','famous/core/Scene','famous/core/Surface','famous/core/Transform','famous/core/View'],function(require, exports, module) {
27.15291 +    var Scene = require('famous/core/Scene');
27.15292 +    var Surface = require('famous/core/Surface');
27.15293 +    var Transform = require('famous/core/Transform');
27.15294 +    var View = require('famous/core/View');
27.15295 +
27.15296 +    /**
27.15297 +     * A view for displaying the title of the current page
27.15298 +     *  as well as icons for navigating backwards and opening
27.15299 +     *  further options
27.15300 +     *
27.15301 +     * @class NavigationBar
27.15302 +     * @extends View
27.15303 +     * @constructor
27.15304 +     *
27.15305 +     * @param {object} [options] overrides of default options
27.15306 +     * @param {Array.number} [options.size=(undefined,0.5)] Size of the navigation bar and it's componenets.
27.15307 +     * @param {Array.string} [options.backClasses=(back)] CSS Classes attached to back of Navigation.
27.15308 +     * @param {String} [options.backContent=(&#x25c0;)] Content of the back button.
27.15309 +     * @param {Array.string} [options.classes=(navigation)] CSS Classes attached to the surfaces.
27.15310 +     * @param {String} [options.content] Content to pass into title bar.
27.15311 +     * @param {Array.string} [options.classes=(more)] CSS Classes attached to the More surface.
27.15312 +     * @param {String} [options.moreContent=(&#x271a;)] Content of the more button.
27.15313 +     */
27.15314 +    function NavigationBar(options) {
27.15315 +        View.apply(this, arguments);
27.15316 +
27.15317 +        this.title = new Surface({
27.15318 +            classes: this.options.classes,
27.15319 +            content: this.options.content
27.15320 +        });
27.15321 +
27.15322 +        this.back = new Surface({
27.15323 +            size: [this.options.size[1], this.options.size[1]],
27.15324 +            classes: this.options.classes,
27.15325 +            content: this.options.backContent
27.15326 +        });
27.15327 +        this.back.on('click', function() {
27.15328 +            this._eventOutput.emit('back', {});
27.15329 +        }.bind(this));
27.15330 +
27.15331 +        this.more = new Surface({
27.15332 +            size: [this.options.size[1], this.options.size[1]],
27.15333 +            classes: this.options.classes,
27.15334 +            content: this.options.moreContent
27.15335 +        });
27.15336 +        this.more.on('click', function() {
27.15337 +            this._eventOutput.emit('more', {});
27.15338 +        }.bind(this));
27.15339 +
27.15340 +        this.layout = new Scene({
27.15341 +            id: 'master',
27.15342 +            size: this.options.size,
27.15343 +            target: [
27.15344 +                {
27.15345 +                    transform: Transform.inFront,
27.15346 +                    origin: [0, 0.5],
27.15347 +                    target: this.back
27.15348 +                },
27.15349 +                {
27.15350 +                    origin: [0.5, 0.5],
27.15351 +                    target: this.title
27.15352 +                },
27.15353 +                {
27.15354 +                    transform: Transform.inFront,
27.15355 +                    origin: [1, 0.5],
27.15356 +                    target: this.more
27.15357 +                }
27.15358 +            ]
27.15359 +        });
27.15360 +
27.15361 +        this._add(this.layout);
27.15362 +
27.15363 +        this._optionsManager.on('change', function(event) {
27.15364 +            var key = event.id;
27.15365 +            var data = event.value;
27.15366 +            if (key === 'size') {
27.15367 +                this.layout.id.master.setSize(data);
27.15368 +                this.title.setSize(data);
27.15369 +                this.back.setSize([data[1], data[1]]);
27.15370 +                this.more.setSize([data[1], data[1]]);
27.15371 +            }
27.15372 +            else if (key === 'backClasses') {
27.15373 +                this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)});
27.15374 +            }
27.15375 +            else if (key === 'backContent') {
27.15376 +                this.back.setContent(this.options.backContent);
27.15377 +            }
27.15378 +            else if (key === 'classes') {
27.15379 +                this.title.setOptions({classes: this.options.classes});
27.15380 +                this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)});
27.15381 +                this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)});
27.15382 +            }
27.15383 +            else if (key === 'content') {
27.15384 +                this.setContent(this.options.content);
27.15385 +            }
27.15386 +            else if (key === 'moreClasses') {
27.15387 +                this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)});
27.15388 +            }
27.15389 +            else if (key === 'moreContent') {
27.15390 +                this.more.setContent(this.options.content);
27.15391 +            }
27.15392 +        }.bind(this));
27.15393 +    }
27.15394 +
27.15395 +    NavigationBar.prototype = Object.create(View.prototype);
27.15396 +    NavigationBar.prototype.constructor = NavigationBar;
27.15397 +
27.15398 +    NavigationBar.DEFAULT_OPTIONS = {
27.15399 +        size: [undefined, 50],
27.15400 +        backClasses: ['back'],
27.15401 +        backContent: '&#x25c0;',
27.15402 +        classes: ['navigation'],
27.15403 +        content: '',
27.15404 +        moreClasses: ['more'],
27.15405 +        moreContent: '&#x271a;'
27.15406 +    };
27.15407 +
27.15408 +    /**
27.15409 +     * Set the title of the NavigationBar
27.15410 +     *
27.15411 +     * @method setContent
27.15412 +     *
27.15413 +     * @param {object} content JSON object containing title information
27.15414 +     *
27.15415 +     * @return {undefined}
27.15416 +     */
27.15417 +    NavigationBar.prototype.setContent = function setContent(content) {
27.15418 +        return this.title.setContent(content);
27.15419 +    };
27.15420 +
27.15421 +    module.exports = NavigationBar;
27.15422 +});
27.15423 +
27.15424 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15425 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15426 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15427 + *
27.15428 + * Owner: mark@famo.us
27.15429 + * @license MPL 2.0
27.15430 + * @copyright Famous Industries, Inc. 2014
27.15431 + */
27.15432 +
27.15433 +define('famous/widgets/Slider',['require','exports','module','famous/core/Surface','famous/surfaces/CanvasSurface','famous/core/Transform','famous/core/EventHandler','famous/math/Utilities','famous/core/OptionsManager','famous/inputs/MouseSync','famous/inputs/TouchSync','famous/inputs/GenericSync'],function(require, exports, module) {
27.15434 +    var Surface = require('famous/core/Surface');
27.15435 +    var CanvasSurface = require('famous/surfaces/CanvasSurface');
27.15436 +    var Transform = require('famous/core/Transform');
27.15437 +    var EventHandler = require('famous/core/EventHandler');
27.15438 +    var Utilities = require('famous/math/Utilities');
27.15439 +    var OptionsManager = require('famous/core/OptionsManager');
27.15440 +
27.15441 +    var MouseSync = require('famous/inputs/MouseSync');
27.15442 +    var TouchSync = require('famous/inputs/TouchSync');
27.15443 +    var GenericSync = require('famous/inputs/GenericSync');
27.15444 +
27.15445 +    GenericSync.register({
27.15446 +        mouse : MouseSync,
27.15447 +        touch : TouchSync
27.15448 +    });
27.15449 +
27.15450 +    /** @constructor */
27.15451 +    function Slider(options) {
27.15452 +        this.options = Object.create(Slider.DEFAULT_OPTIONS);
27.15453 +        this.optionsManager = new OptionsManager(this.options);
27.15454 +        if (options) this.setOptions(options);
27.15455 +
27.15456 +        this.indicator = new CanvasSurface({
27.15457 +            size: this.options.indicatorSize,
27.15458 +            classes : ['slider-back']
27.15459 +        });
27.15460 +
27.15461 +        this.label = new Surface({
27.15462 +            size: this.options.labelSize,
27.15463 +            content: this.options.label,
27.15464 +            properties : {pointerEvents : 'none'},
27.15465 +            classes: ['slider-label']
27.15466 +        });
27.15467 +
27.15468 +        this.eventOutput = new EventHandler();
27.15469 +        this.eventInput = new EventHandler();
27.15470 +        EventHandler.setInputHandler(this, this.eventInput);
27.15471 +        EventHandler.setOutputHandler(this, this.eventOutput);
27.15472 +
27.15473 +        var scale = (this.options.range[1] - this.options.range[0]) / this.options.indicatorSize[0];
27.15474 +
27.15475 +        this.sync = new GenericSync(
27.15476 +            ['mouse', 'touch'],
27.15477 +            {
27.15478 +                scale : scale,
27.15479 +                direction : GenericSync.DIRECTION_X
27.15480 +            }
27.15481 +        );
27.15482 +
27.15483 +        this.indicator.pipe(this.sync);
27.15484 +        this.sync.pipe(this);
27.15485 +
27.15486 +        this.eventInput.on('update', function(data) {
27.15487 +            this.set(data.position);
27.15488 +        }.bind(this));
27.15489 +
27.15490 +        this._drawPos = 0;
27.15491 +        _updateLabel.call(this);
27.15492 +    }
27.15493 +
27.15494 +    Slider.DEFAULT_OPTIONS = {
27.15495 +        size: [200, 60],
27.15496 +        indicatorSize: [200, 30],
27.15497 +        labelSize: [200, 30],
27.15498 +        range: [0, 1],
27.15499 +        precision: 2,
27.15500 +        value: 0,
27.15501 +        label: '',
27.15502 +        fillColor: 'rgba(170, 170, 170, 1)'
27.15503 +    };
27.15504 +
27.15505 +    function _updateLabel() {
27.15506 +        this.label.setContent(this.options.label + '<span style="float: right">' + this.get().toFixed(this.options.precision) + '</span>');
27.15507 +    }
27.15508 +
27.15509 +    Slider.prototype.setOptions = function setOptions(options) {
27.15510 +        return this.optionsManager.setOptions(options);
27.15511 +    };
27.15512 +
27.15513 +    Slider.prototype.get = function get() {
27.15514 +        return this.options.value;
27.15515 +    };
27.15516 +
27.15517 +    Slider.prototype.set = function set(value) {
27.15518 +        if (value === this.options.value) return;
27.15519 +        this.options.value = Utilities.clamp(value, this.options.range);
27.15520 +        _updateLabel.call(this);
27.15521 +        this.eventOutput.emit('change', {value: value});
27.15522 +    };
27.15523 +
27.15524 +    Slider.prototype.getSize = function getSize() {
27.15525 +        return this.options.size;
27.15526 +    };
27.15527 +
27.15528 +    Slider.prototype.render = function render() {
27.15529 +        var range = this.options.range;
27.15530 +        var fillSize = Math.floor(((this.get() - range[0]) / (range[1] - range[0])) * this.options.indicatorSize[0]);
27.15531 +
27.15532 +        if (fillSize < this._drawPos) {
27.15533 +            this.indicator.getContext('2d').clearRect(fillSize, 0, this._drawPos - fillSize + 1, this.options.indicatorSize[1]);
27.15534 +        }
27.15535 +        else if (fillSize > this._drawPos) {
27.15536 +            var ctx = this.indicator.getContext('2d');
27.15537 +            ctx.fillStyle = this.options.fillColor;
27.15538 +            ctx.fillRect(this._drawPos-1, 0, fillSize - this._drawPos+1, this.options.indicatorSize[1]);
27.15539 +        }
27.15540 +        this._drawPos = fillSize;
27.15541 +
27.15542 +        return {
27.15543 +            size: this.options.size,
27.15544 +            target: [
27.15545 +                {
27.15546 +                    origin: [0, 0],
27.15547 +                    target: this.indicator.render()
27.15548 +                },
27.15549 +                {
27.15550 +                    transform: Transform.translate(0, 0, 1),
27.15551 +                    origin: [0, 0],
27.15552 +                    target: this.label.render()
27.15553 +                }
27.15554 +            ]
27.15555 +        };
27.15556 +    };
27.15557 +
27.15558 +    module.exports = Slider;
27.15559 +});
27.15560 +
27.15561 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15562 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15563 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15564 + *
27.15565 + * Owner: mark@famo.us
27.15566 + * @license MPL 2.0
27.15567 + * @copyright Famous Industries, Inc. 2014
27.15568 + */
27.15569 +
27.15570 +define('famous/widgets/ToggleButton',['require','exports','module','famous/core/Surface','famous/core/EventHandler','famous/views/RenderController'],function(require, exports, module) {
27.15571 +    var Surface = require('famous/core/Surface');
27.15572 +    var EventHandler = require('famous/core/EventHandler');
27.15573 +    var RenderController = require('famous/views/RenderController');
27.15574 +
27.15575 +    /**
27.15576 +     * A view for transitioning between two surfaces based
27.15577 +     *  on a 'on' and 'off' state
27.15578 +     *
27.15579 +     * @class TabBar
27.15580 +     * @extends View
27.15581 +     * @constructor
27.15582 +     *
27.15583 +     * @param {object} options overrides of default options
27.15584 +     */
27.15585 +    function ToggleButton(options) {
27.15586 +        this.options = {
27.15587 +            content: '',
27.15588 +            offClasses: ['off'],
27.15589 +            onClasses: ['on'],
27.15590 +            size: undefined,
27.15591 +            outTransition: {curve: 'easeInOut', duration: 300},
27.15592 +            inTransition: {curve: 'easeInOut', duration: 300},
27.15593 +            toggleMode: ToggleButton.TOGGLE,
27.15594 +            crossfade: true
27.15595 +        };
27.15596 +
27.15597 +        this._eventOutput = new EventHandler();
27.15598 +        EventHandler.setOutputHandler(this, this._eventOutput);
27.15599 +
27.15600 +        this.offSurface = new Surface();
27.15601 +        this.offSurface.on('click', function() {
27.15602 +            if (this.options.toggleMode !== ToggleButton.OFF) this.select();
27.15603 +        }.bind(this));
27.15604 +        this.offSurface.pipe(this._eventOutput);
27.15605 +
27.15606 +        this.onSurface = new Surface();
27.15607 +        this.onSurface.on('click', function() {
27.15608 +            if (this.options.toggleMode !== ToggleButton.ON) this.deselect();
27.15609 +        }.bind(this));
27.15610 +        this.onSurface.pipe(this._eventOutput);
27.15611 +
27.15612 +        this.arbiter = new RenderController({
27.15613 +            overlap : this.options.crossfade
27.15614 +        });
27.15615 +
27.15616 +        this.deselect();
27.15617 +
27.15618 +        if (options) this.setOptions(options);
27.15619 +    }
27.15620 +
27.15621 +    ToggleButton.OFF = 0;
27.15622 +    ToggleButton.ON = 1;
27.15623 +    ToggleButton.TOGGLE = 2;
27.15624 +
27.15625 +    /**
27.15626 +     * Transition towards the 'on' state and dispatch an event to
27.15627 +     *  listeners to announce it was selected
27.15628 +     *
27.15629 +     * @method select
27.15630 +     */
27.15631 +    ToggleButton.prototype.select = function select() {
27.15632 +        this.selected = true;
27.15633 +        this.arbiter.show(this.onSurface, this.options.inTransition);
27.15634 +//        this.arbiter.setMode(ToggleButton.ON, this.options.inTransition);
27.15635 +        this._eventOutput.emit('select');
27.15636 +    };
27.15637 +
27.15638 +    /**
27.15639 +     * Transition towards the 'off' state and dispatch an event to
27.15640 +     *  listeners to announce it was deselected
27.15641 +     *
27.15642 +     * @method deselect
27.15643 +     */
27.15644 +    ToggleButton.prototype.deselect = function deselect() {
27.15645 +        this.selected = false;
27.15646 +        this.arbiter.show(this.offSurface, this.options.outTransition);
27.15647 +        this._eventOutput.emit('deselect');
27.15648 +    };
27.15649 +
27.15650 +    /**
27.15651 +     * Return the state of the button
27.15652 +     *
27.15653 +     * @method isSelected
27.15654 +     *
27.15655 +     * @return {boolean} selected state
27.15656 +     */
27.15657 +    ToggleButton.prototype.isSelected = function isSelected() {
27.15658 +        return this.selected;
27.15659 +    };
27.15660 +
27.15661 +    /**
27.15662 +     * Override the current options
27.15663 +     *
27.15664 +     * @method setOptions
27.15665 +     *
27.15666 +     * @param {object} options JSON
27.15667 +     */
27.15668 +    ToggleButton.prototype.setOptions = function setOptions(options) {
27.15669 +        if (options.content !== undefined) {
27.15670 +            this.options.content = options.content;
27.15671 +            this.offSurface.setContent(this.options.content);
27.15672 +            this.onSurface.setContent(this.options.content);
27.15673 +        }
27.15674 +        if (options.offClasses) {
27.15675 +            this.options.offClasses = options.offClasses;
27.15676 +            this.offSurface.setClasses(this.options.offClasses);
27.15677 +        }
27.15678 +        if (options.onClasses) {
27.15679 +            this.options.onClasses = options.onClasses;
27.15680 +            this.onSurface.setClasses(this.options.onClasses);
27.15681 +        }
27.15682 +        if (options.size !== undefined) {
27.15683 +            this.options.size = options.size;
27.15684 +            this.onSurface.setSize(this.options.size);
27.15685 +            this.offSurface.setSize(this.options.size);
27.15686 +        }
27.15687 +        if (options.toggleMode !== undefined) this.options.toggleMode = options.toggleMode;
27.15688 +        if (options.outTransition !== undefined) this.options.outTransition = options.outTransition;
27.15689 +        if (options.inTransition !== undefined) this.options.inTransition = options.inTransition;
27.15690 +        if (options.crossfade !== undefined) {
27.15691 +            this.options.crossfade = options.crossfade;
27.15692 +            this.arbiter.setOptions({overlap: this.options.crossfade});
27.15693 +        }
27.15694 +    };
27.15695 +
27.15696 +    /**
27.15697 +     * Return the size defined in the options object
27.15698 +     *
27.15699 +     * @method getSize
27.15700 +     *
27.15701 +     * @return {array} two element array [height, width]
27.15702 +     */
27.15703 +    ToggleButton.prototype.getSize = function getSize() {
27.15704 +        return this.options.size;
27.15705 +    };
27.15706 +
27.15707 +    /**
27.15708 +     * Generate a render spec from the contents of this component.
27.15709 +     *
27.15710 +     * @private
27.15711 +     * @method render
27.15712 +     * @return {number} Render spec for this component
27.15713 +     */
27.15714 +    ToggleButton.prototype.render = function render() {
27.15715 +        return this.arbiter.render();
27.15716 +    };
27.15717 +
27.15718 +    module.exports = ToggleButton;
27.15719 +});
27.15720 +
27.15721 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15722 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15723 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15724 + *
27.15725 + * Owner: mark@famo.us
27.15726 + * @license MPL 2.0
27.15727 + * @copyright Famous Industries, Inc. 2014
27.15728 + */
27.15729 +
27.15730 +define('famous/widgets/TabBar',['require','exports','module','famous/utilities/Utility','famous/core/View','famous/views/GridLayout','./ToggleButton'],function(require, exports, module) {
27.15731 +    var Utility = require('famous/utilities/Utility');
27.15732 +    var View = require('famous/core/View');
27.15733 +    var GridLayout = require('famous/views/GridLayout');
27.15734 +    var ToggleButton = require('./ToggleButton');
27.15735 +
27.15736 +    /**
27.15737 +     * A view for displaying various tabs that dispatch events
27.15738 +     *  based on the id of the button that was clicked
27.15739 +     *
27.15740 +     * @class TabBar
27.15741 +     * @extends View
27.15742 +     * @constructor
27.15743 +     *
27.15744 +     * @param {object} options overrides of default options
27.15745 +     */
27.15746 +    function TabBar(options) {
27.15747 +        View.apply(this, arguments);
27.15748 +
27.15749 +        this.layout = new GridLayout();
27.15750 +        this.buttons = [];
27.15751 +        this._buttonIds = {};
27.15752 +        this._buttonCallbacks = {};
27.15753 +
27.15754 +        this.layout.sequenceFrom(this.buttons);
27.15755 +        this._add(this.layout);
27.15756 +
27.15757 +        this._optionsManager.on('change', _updateOptions.bind(this));
27.15758 +    }
27.15759 +
27.15760 +    TabBar.prototype = Object.create(View.prototype);
27.15761 +    TabBar.prototype.constructor = TabBar;
27.15762 +
27.15763 +    TabBar.DEFAULT_OPTIONS = {
27.15764 +        sections: [],
27.15765 +        widget: ToggleButton,
27.15766 +        size: [undefined, 50],
27.15767 +        direction: Utility.Direction.X,
27.15768 +        buttons: {
27.15769 +            toggleMode: ToggleButton.ON
27.15770 +        }
27.15771 +    };
27.15772 +
27.15773 +    /**
27.15774 +     * Update the options for all components of the view
27.15775 +     *
27.15776 +     * @method _updateOptions
27.15777 +     *
27.15778 +     * @param {object} data component options
27.15779 +     */
27.15780 +    function _updateOptions(data) {
27.15781 +        var id = data.id;
27.15782 +        var value = data.value;
27.15783 +
27.15784 +        if (id === 'direction') {
27.15785 +            this.layout.setOptions({dimensions: _resolveGridDimensions.call(this.buttons.length, this.options.direction)});
27.15786 +        }
27.15787 +        else if (id === 'buttons') {
27.15788 +            for (var i in this.buttons) {
27.15789 +                this.buttons[i].setOptions(value);
27.15790 +            }
27.15791 +        }
27.15792 +        else if (id === 'sections') {
27.15793 +            for (var sectionId in this.options.sections) {
27.15794 +                this.defineSection(sectionId, this.options.sections[sectionId]);
27.15795 +            }
27.15796 +        }
27.15797 +    }
27.15798 +
27.15799 +    /**
27.15800 +     * Return an array of the proper dimensions for the tabs
27.15801 +     *
27.15802 +     * @method _resolveGridDimensions
27.15803 +     *
27.15804 +     * @param {number} count number of buttons
27.15805 +     * @param {number} direction direction of the layout
27.15806 +     *
27.15807 +     * @return {array} the dimensions of the tab section
27.15808 +     */
27.15809 +    function _resolveGridDimensions(count, direction) {
27.15810 +        if (direction === Utility.Direction.X) return [count, 1];
27.15811 +        else return [1, count];
27.15812 +    }
27.15813 +
27.15814 +    /**
27.15815 +     * Create a new button with the specified id.  If one already exists with
27.15816 +     *  that id, unbind all listeners.
27.15817 +     *
27.15818 +     * @method defineSection
27.15819 +     *
27.15820 +     * @param {string} id name of the button
27.15821 +     * @param {object} content data for the creation of a new ToggleButton
27.15822 +     */
27.15823 +    TabBar.prototype.defineSection = function defineSection(id, content) {
27.15824 +        var button;
27.15825 +        var i = this._buttonIds[id];
27.15826 +
27.15827 +        if (i === undefined) {
27.15828 +            i = this.buttons.length;
27.15829 +            this._buttonIds[id] = i;
27.15830 +            var widget = this.options.widget;
27.15831 +            button = new widget();
27.15832 +            this.buttons[i] = button;
27.15833 +            this.layout.setOptions({dimensions: _resolveGridDimensions(this.buttons.length, this.options.direction)});
27.15834 +        }
27.15835 +        else {
27.15836 +            button = this.buttons[i];
27.15837 +            button.unbind('select', this._buttonCallbacks[id]);
27.15838 +        }
27.15839 +
27.15840 +        if (this.options.buttons) button.setOptions(this.options.buttons);
27.15841 +        button.setOptions(content);
27.15842 +
27.15843 +        this._buttonCallbacks[id] = this.select.bind(this, id);
27.15844 +        button.on('select', this._buttonCallbacks[id]);
27.15845 +    };
27.15846 +
27.15847 +    /**
27.15848 +     * Select a particular button and dispatch the id of the selection
27.15849 +     *  to any listeners.  Deselect all others
27.15850 +     *
27.15851 +     * @method select
27.15852 +     *
27.15853 +     * @param {string} id button id
27.15854 +     */
27.15855 +    TabBar.prototype.select = function select(id) {
27.15856 +        var btn = this._buttonIds[id];
27.15857 +        // this prevents event loop
27.15858 +        if (this.buttons[btn] && this.buttons[btn].isSelected()) {
27.15859 +            this._eventOutput.emit('select', {id: id});
27.15860 +        }
27.15861 +        else if (this.buttons[btn]) {
27.15862 +            this.buttons[btn].select();
27.15863 +        }
27.15864 +
27.15865 +        for (var i = 0; i < this.buttons.length; i++) {
27.15866 +            if (i !== btn) this.buttons[i].deselect();
27.15867 +        }
27.15868 +    };
27.15869 +
27.15870 +    module.exports = TabBar;
27.15871 +});
27.15872 +
27.15873 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.15874 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.15875 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.15876 + *
27.15877 + * Owner: david@famo.us
27.15878 + * @license MPL 2.0
27.15879 + * @copyright Famous Industries, Inc. 2014
27.15880 + */
27.15881 +
27.15882 +define('famous/physics/bodies/Body',['require','exports','module','./Particle','famous/core/Transform','famous/math/Vector','famous/math/Quaternion','famous/math/Matrix'],function(require, exports, module) {
27.15883 +    var Particle = require('./Particle');
27.15884 +    var Transform = require('famous/core/Transform');
27.15885 +    var Vector = require('famous/math/Vector');
27.15886 +    var Quaternion = require('famous/math/Quaternion');
27.15887 +    var Matrix = require('famous/math/Matrix');
27.15888 +
27.15889 +    /**
27.15890 +     * A unit controlled by the physics engine which extends the zero-dimensional
27.15891 +     * Particle to include geometry. In addition to maintaining the state
27.15892 +     * of a Particle its state includes orientation, angular velocity
27.15893 +     * and angular momentum and responds to torque forces.
27.15894 +     *
27.15895 +     * @class Body
27.15896 +     * @extends Particle
27.15897 +     * @constructor
27.15898 +     */
27.15899 +    function Body(options) {
27.15900 +        Particle.call(this, options);
27.15901 +        options = options || {};
27.15902 +
27.15903 +        this.orientation     = new Quaternion();
27.15904 +        this.angularVelocity = new Vector();
27.15905 +        this.angularMomentum = new Vector();
27.15906 +        this.torque          = new Vector();
27.15907 +
27.15908 +        if (options.orientation)     this.orientation.set(options.orientation);
27.15909 +        if (options.angularVelocity) this.angularVelocity.set(options.angularVelocity);
27.15910 +        if (options.angularMomentum) this.angularMomentum.set(options.angularMomentum);
27.15911 +        if (options.torque)          this.torque.set(options.torque);
27.15912 +
27.15913 +        this.setMomentsOfInertia();
27.15914 +
27.15915 +        this.angularVelocity.w = 0;        //quaternify the angular velocity
27.15916 +
27.15917 +        //registers
27.15918 +        this.pWorld = new Vector();        //placeholder for world space position
27.15919 +    }
27.15920 +
27.15921 +    Body.DEFAULT_OPTIONS = Particle.DEFAULT_OPTIONS;
27.15922 +    Body.DEFAULT_OPTIONS.orientation = [0,0,0,1];
27.15923 +    Body.DEFAULT_OPTIONS.angularVelocity = [0,0,0];
27.15924 +
27.15925 +    Body.AXES = Particle.AXES;
27.15926 +    Body.SLEEP_TOLERANCE = Particle.SLEEP_TOLERANCE;
27.15927 +    Body.INTEGRATOR = Particle.INTEGRATOR;
27.15928 +
27.15929 +    Body.prototype = Object.create(Particle.prototype);
27.15930 +    Body.prototype.constructor = Body;
27.15931 +
27.15932 +    Body.prototype.isBody = true;
27.15933 +
27.15934 +    Body.prototype.setMass = function setMass() {
27.15935 +        Particle.prototype.setMass.apply(this, arguments);
27.15936 +        this.setMomentsOfInertia();
27.15937 +    };
27.15938 +
27.15939 +    /**
27.15940 +     * Setter for moment of inertia, which is necessary to give proper
27.15941 +     * angular inertia depending on the geometry of the body.
27.15942 +     *
27.15943 +     * @method setMomentsOfInertia
27.15944 +     */
27.15945 +    Body.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
27.15946 +        this.inertia = new Matrix();
27.15947 +        this.inverseInertia = new Matrix();
27.15948 +    };
27.15949 +
27.15950 +    /**
27.15951 +     * Update the angular velocity from the angular momentum state.
27.15952 +     *
27.15953 +     * @method updateAngularVelocity
27.15954 +     */
27.15955 +    Body.prototype.updateAngularVelocity = function updateAngularVelocity() {
27.15956 +        this.angularVelocity.set(this.inverseInertia.vectorMultiply(this.angularMomentum));
27.15957 +    };
27.15958 +
27.15959 +    /**
27.15960 +     * Determine world coordinates from the local coordinate system. Useful
27.15961 +     * if the Body has rotated in space.
27.15962 +     *
27.15963 +     * @method toWorldCoordinates
27.15964 +     * @param localPosition {Vector} local coordinate vector
27.15965 +     * @return global coordinate vector {Vector}
27.15966 +     */
27.15967 +    Body.prototype.toWorldCoordinates = function toWorldCoordinates(localPosition) {
27.15968 +        return this.pWorld.set(this.orientation.rotateVector(localPosition));
27.15969 +    };
27.15970 +
27.15971 +    /**
27.15972 +     * Calculates the kinetic and intertial energy of a body.
27.15973 +     *
27.15974 +     * @method getEnergy
27.15975 +     * @return energy {Number}
27.15976 +     */
27.15977 +    Body.prototype.getEnergy = function getEnergy() {
27.15978 +        return Particle.prototype.getEnergy.call(this)
27.15979 +            + 0.5 * this.inertia.vectorMultiply(this.angularVelocity).dot(this.angularVelocity);
27.15980 +    };
27.15981 +
27.15982 +    /**
27.15983 +     * Extends Particle.reset to reset orientation, angular velocity
27.15984 +     * and angular momentum.
27.15985 +     *
27.15986 +     * @method reset
27.15987 +     * @param [p] {Array|Vector} position
27.15988 +     * @param [v] {Array|Vector} velocity
27.15989 +     * @param [q] {Array|Quaternion} orientation
27.15990 +     * @param [L] {Array|Vector} angular momentum
27.15991 +     */
27.15992 +    Body.prototype.reset = function reset(p, v, q, L) {
27.15993 +        Particle.prototype.reset.call(this, p, v);
27.15994 +        this.angularVelocity.clear();
27.15995 +        this.setOrientation(q || [1,0,0,0]);
27.15996 +        this.setAngularMomentum(L || [0,0,0]);
27.15997 +    };
27.15998 +
27.15999 +    /**
27.16000 +     * Setter for orientation
27.16001 +     *
27.16002 +     * @method setOrientation
27.16003 +     * @param q {Array|Quaternion} orientation
27.16004 +     */
27.16005 +    Body.prototype.setOrientation = function setOrientation(q) {
27.16006 +        this.orientation.set(q);
27.16007 +    };
27.16008 +
27.16009 +    /**
27.16010 +     * Setter for angular velocity
27.16011 +     *
27.16012 +     * @method setAngularVelocity
27.16013 +     * @param w {Array|Vector} angular velocity
27.16014 +     */
27.16015 +    Body.prototype.setAngularVelocity = function setAngularVelocity(w) {
27.16016 +        this.wake();
27.16017 +        this.angularVelocity.set(w);
27.16018 +    };
27.16019 +
27.16020 +    /**
27.16021 +     * Setter for angular momentum
27.16022 +     *
27.16023 +     * @method setAngularMomentum
27.16024 +     * @param L {Array|Vector} angular momentum
27.16025 +     */
27.16026 +    Body.prototype.setAngularMomentum = function setAngularMomentum(L) {
27.16027 +        this.wake();
27.16028 +        this.angularMomentum.set(L);
27.16029 +    };
27.16030 +
27.16031 +    /**
27.16032 +     * Extends Particle.applyForce with an optional argument
27.16033 +     * to apply the force at an off-centered location, resulting in a torque.
27.16034 +     *
27.16035 +     * @method applyForce
27.16036 +     * @param force {Vector} force
27.16037 +     * @param [location] {Vector} off-center location on the body
27.16038 +     */
27.16039 +    Body.prototype.applyForce = function applyForce(force, location) {
27.16040 +        Particle.prototype.applyForce.call(this, force);
27.16041 +        if (location !== undefined) this.applyTorque(location.cross(force));
27.16042 +    };
27.16043 +
27.16044 +    /**
27.16045 +     * Applied a torque force to a body, inducing a rotation.
27.16046 +     *
27.16047 +     * @method applyTorque
27.16048 +     * @param torque {Vector} torque
27.16049 +     */
27.16050 +    Body.prototype.applyTorque = function applyTorque(torque) {
27.16051 +        this.wake();
27.16052 +        this.torque.set(this.torque.add(torque));
27.16053 +    };
27.16054 +
27.16055 +    /**
27.16056 +     * Extends Particle.getTransform to include a rotational component
27.16057 +     * derived from the particle's orientation.
27.16058 +     *
27.16059 +     * @method getTransform
27.16060 +     * @return transform {Transform}
27.16061 +     */
27.16062 +    Body.prototype.getTransform = function getTransform() {
27.16063 +        return Transform.thenMove(
27.16064 +            this.orientation.getTransform(),
27.16065 +            Transform.getTranslate(Particle.prototype.getTransform.call(this))
27.16066 +        );
27.16067 +    };
27.16068 +
27.16069 +    /**
27.16070 +     * Extends Particle._integrate to also update the rotational states
27.16071 +     * of the body.
27.16072 +     *
27.16073 +     * @method getTransform
27.16074 +     * @protected
27.16075 +     * @param dt {Number} delta time
27.16076 +     */
27.16077 +    Body.prototype._integrate = function _integrate(dt) {
27.16078 +        Particle.prototype._integrate.call(this, dt);
27.16079 +        this.integrateAngularMomentum(dt);
27.16080 +        this.updateAngularVelocity(dt);
27.16081 +        this.integrateOrientation(dt);
27.16082 +    };
27.16083 +
27.16084 +    /**
27.16085 +     * Updates the angular momentum via the its integrator.
27.16086 +     *
27.16087 +     * @method integrateAngularMomentum
27.16088 +     * @param dt {Number} delta time
27.16089 +     */
27.16090 +    Body.prototype.integrateAngularMomentum = function integrateAngularMomentum(dt) {
27.16091 +        Body.INTEGRATOR.integrateAngularMomentum(this, dt);
27.16092 +    };
27.16093 +
27.16094 +    /**
27.16095 +     * Updates the orientation via the its integrator.
27.16096 +     *
27.16097 +     * @method integrateOrientation
27.16098 +     * @param dt {Number} delta time
27.16099 +     */
27.16100 +    Body.prototype.integrateOrientation = function integrateOrientation(dt) {
27.16101 +        Body.INTEGRATOR.integrateOrientation(this, dt);
27.16102 +    };
27.16103 +
27.16104 +    module.exports = Body;
27.16105 +});
27.16106 +
27.16107 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16108 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16109 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16110 + *
27.16111 + * Owner: david@famo.us
27.16112 + * @license MPL 2.0
27.16113 + * @copyright Famous Industries, Inc. 2014
27.16114 + */
27.16115 +
27.16116 +define('famous/physics/bodies/Circle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) {
27.16117 +    var Body = require('./Body');
27.16118 +    var Matrix = require('famous/math/Matrix');
27.16119 +
27.16120 +    /**
27.16121 +     * Implements a circle, or spherical, geometry for an Body with
27.16122 +     * radius.
27.16123 +     *
27.16124 +     * @class Circle
27.16125 +     * @extends Body
27.16126 +     * @constructor
27.16127 +     */
27.16128 +    function Circle(options) {
27.16129 +        options = options || {};
27.16130 +        this.setRadius(options.radius || 0);
27.16131 +        Body.call(this, options);
27.16132 +    }
27.16133 +
27.16134 +    Circle.prototype = Object.create(Body.prototype);
27.16135 +    Circle.prototype.constructor = Circle;
27.16136 +
27.16137 +    /**
27.16138 +     * Basic setter for radius.
27.16139 +     * @method setRadius
27.16140 +     * @param r {Number} radius
27.16141 +     */
27.16142 +    Circle.prototype.setRadius = function setRadius(r) {
27.16143 +        this.radius = r;
27.16144 +        this.size = [2*this.radius, 2*this.radius];
27.16145 +        this.setMomentsOfInertia();
27.16146 +    };
27.16147 +
27.16148 +    Circle.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
27.16149 +        var m = this.mass;
27.16150 +        var r = this.radius;
27.16151 +
27.16152 +        this.inertia = new Matrix([
27.16153 +            [0.25 * m * r * r, 0, 0],
27.16154 +            [0, 0.25 * m * r * r, 0],
27.16155 +            [0, 0, 0.5 * m * r * r]
27.16156 +        ]);
27.16157 +
27.16158 +        this.inverseInertia = new Matrix([
27.16159 +            [4 / (m * r * r), 0, 0],
27.16160 +            [0, 4 / (m * r * r), 0],
27.16161 +            [0, 0, 2 / (m * r * r)]
27.16162 +        ]);
27.16163 +    };
27.16164 +
27.16165 +    module.exports = Circle;
27.16166 +
27.16167 +});
27.16168 +
27.16169 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16170 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16171 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16172 + *
27.16173 + * Owner: david@famo.us
27.16174 + * @license MPL 2.0
27.16175 + * @copyright Famous Industries, Inc. 2014
27.16176 + */
27.16177 +
27.16178 +define('famous/physics/bodies/Rectangle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) {
27.16179 +    var Body = require('./Body');
27.16180 +    var Matrix = require('famous/math/Matrix');
27.16181 +
27.16182 +    /**
27.16183 +     * Implements a rectangular geometry for an Body with
27.16184 +     * size = [width, height].
27.16185 +     *
27.16186 +     * @class Rectangle
27.16187 +     * @extends Body
27.16188 +     * @constructor
27.16189 +     */
27.16190 +    function Rectangle(options) {
27.16191 +        options = options || {};
27.16192 +        this.size = options.size || [0,0];
27.16193 +        Body.call(this, options);
27.16194 +    }
27.16195 +
27.16196 +    Rectangle.prototype = Object.create(Body.prototype);
27.16197 +    Rectangle.prototype.constructor = Rectangle;
27.16198 +
27.16199 +    /**
27.16200 +     * Basic setter for size.
27.16201 +     * @method setSize
27.16202 +     * @param size {Array} size = [width, height]
27.16203 +     */
27.16204 +    Rectangle.prototype.setSize = function setSize(size) {
27.16205 +        this.size = size;
27.16206 +        this.setMomentsOfInertia();
27.16207 +    };
27.16208 +
27.16209 +    Rectangle.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
27.16210 +        var m = this.mass;
27.16211 +        var w = this.size[0];
27.16212 +        var h = this.size[1];
27.16213 +
27.16214 +        this.inertia = new Matrix([
27.16215 +            [m * h * h / 12, 0, 0],
27.16216 +            [0, m * w * w / 12, 0],
27.16217 +            [0, 0, m * (w * w + h * h) / 12]
27.16218 +        ]);
27.16219 +
27.16220 +        this.inverseInertia = new Matrix([
27.16221 +            [12 / (m * h * h), 0, 0],
27.16222 +            [0, 12 / (m * w * w), 0],
27.16223 +            [0, 0, 12 / (m * (w * w + h * h))]
27.16224 +        ]);
27.16225 +    };
27.16226 +
27.16227 +    module.exports = Rectangle;
27.16228 +
27.16229 +});
27.16230 +
27.16231 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16232 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16233 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16234 + *
27.16235 + * Owner: david@famo.us
27.16236 + * @license MPL 2.0
27.16237 + * @copyright Famous Industries, Inc. 2014
27.16238 + */
27.16239 +
27.16240 +define('famous/physics/constraints/Collision',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
27.16241 +    var Constraint = require('./Constraint');
27.16242 +    var Vector = require('famous/math/Vector');
27.16243 +
27.16244 +    /**
27.16245 +     *  Allows for two circular bodies to collide and bounce off each other.
27.16246 +     *
27.16247 +     *  @class Collision
27.16248 +     *  @constructor
27.16249 +     *  @extends Constraint
27.16250 +     *  @param {Options} [options] An object of configurable options.
27.16251 +     *  @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) Range : [0, 1]
27.16252 +     *  @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
27.16253 +     *  @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers
27.16254 +     *
27.16255 +     */
27.16256 +    function Collision(options) {
27.16257 +        this.options = Object.create(Collision.DEFAULT_OPTIONS);
27.16258 +        if (options) this.setOptions(options);
27.16259 +
27.16260 +        //registers
27.16261 +        this.normal   = new Vector();
27.16262 +        this.pDiff    = new Vector();
27.16263 +        this.vDiff    = new Vector();
27.16264 +        this.impulse1 = new Vector();
27.16265 +        this.impulse2 = new Vector();
27.16266 +
27.16267 +        Constraint.call(this);
27.16268 +    }
27.16269 +
27.16270 +    Collision.prototype = Object.create(Constraint.prototype);
27.16271 +    Collision.prototype.constructor = Collision;
27.16272 +
27.16273 +    Collision.DEFAULT_OPTIONS = {
27.16274 +        restitution : 0.5,
27.16275 +        drift : 0.5,
27.16276 +        slop : 0
27.16277 +    };
27.16278 +
27.16279 +    function _normalVelocity(particle1, particle2) {
27.16280 +        return particle1.velocity.dot(particle2.velocity);
27.16281 +    }
27.16282 +
27.16283 +    /*
27.16284 +     * Setter for options.
27.16285 +     *
27.16286 +     * @method setOptions
27.16287 +     * @param options {Objects}
27.16288 +     */
27.16289 +    Collision.prototype.setOptions = function setOptions(options) {
27.16290 +        for (var key in options) this.options[key] = options[key];
27.16291 +    };
27.16292 +
27.16293 +    /**
27.16294 +     * Adds an impulse to a physics body's velocity due to the constraint
27.16295 +     *
27.16296 +     * @method applyConstraint
27.16297 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
27.16298 +     * @param source {Body}         The source of the constraint
27.16299 +     * @param dt {Number}           Delta time
27.16300 +     */
27.16301 +    Collision.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.16302 +        if (source === undefined) return;
27.16303 +
27.16304 +        var v1 = source.velocity;
27.16305 +        var p1 = source.position;
27.16306 +        var w1 = source.inverseMass;
27.16307 +        var r1 = source.radius;
27.16308 +
27.16309 +        var options = this.options;
27.16310 +        var drift = options.drift;
27.16311 +        var slop = -options.slop;
27.16312 +        var restitution = options.restitution;
27.16313 +
27.16314 +        var n     = this.normal;
27.16315 +        var pDiff = this.pDiff;
27.16316 +        var vDiff = this.vDiff;
27.16317 +        var impulse1 = this.impulse1;
27.16318 +        var impulse2 = this.impulse2;
27.16319 +
27.16320 +        for (var i = 0; i < targets.length; i++) {
27.16321 +            var target = targets[i];
27.16322 +
27.16323 +            if (target === source) continue;
27.16324 +
27.16325 +            var v2 = target.velocity;
27.16326 +            var p2 = target.position;
27.16327 +            var w2 = target.inverseMass;
27.16328 +            var r2 = target.radius;
27.16329 +
27.16330 +            pDiff.set(p2.sub(p1));
27.16331 +            vDiff.set(v2.sub(v1));
27.16332 +
27.16333 +            var dist    = pDiff.norm();
27.16334 +            var overlap = dist - (r1 + r2);
27.16335 +            var effMass = 1/(w1 + w2);
27.16336 +            var gamma   = 0;
27.16337 +
27.16338 +            if (overlap < 0) {
27.16339 +
27.16340 +                n.set(pDiff.normalize());
27.16341 +
27.16342 +                if (this._eventOutput) {
27.16343 +                    var collisionData = {
27.16344 +                        target  : target,
27.16345 +                        source  : source,
27.16346 +                        overlap : overlap,
27.16347 +                        normal  : n
27.16348 +                    };
27.16349 +
27.16350 +                    this._eventOutput.emit('preCollision', collisionData);
27.16351 +                    this._eventOutput.emit('collision', collisionData);
27.16352 +                }
27.16353 +
27.16354 +                var lambda = (overlap <= slop)
27.16355 +                    ? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
27.16356 +                    : ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass);
27.16357 +
27.16358 +                n.mult(dt*lambda).put(impulse1);
27.16359 +                impulse1.mult(-1).put(impulse2);
27.16360 +
27.16361 +                source.applyImpulse(impulse1);
27.16362 +                target.applyImpulse(impulse2);
27.16363 +
27.16364 +                //source.setPosition(p1.add(n.mult(overlap/2)));
27.16365 +                //target.setPosition(p2.sub(n.mult(overlap/2)));
27.16366 +
27.16367 +                if (this._eventOutput) this._eventOutput.emit('postCollision', collisionData);
27.16368 +
27.16369 +            }
27.16370 +        }
27.16371 +    };
27.16372 +
27.16373 +    module.exports = Collision;
27.16374 +});
27.16375 +
27.16376 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16377 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16378 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16379 + *
27.16380 + * Owner: david@famo.us
27.16381 + * @license MPL 2.0
27.16382 + * @copyright Famous Industries, Inc. 2014
27.16383 + */
27.16384 +
27.16385 +define('famous/physics/constraints/Curve',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
27.16386 +    var Constraint = require('./Constraint');
27.16387 +    var Vector = require('famous/math/Vector');
27.16388 +
27.16389 +    /**
27.16390 +     *  A constraint that keeps a physics body on a given implicit curve
27.16391 +     *    regardless of other physical forces are applied to it.
27.16392 +     *
27.16393 +     *    A curve constraint is two surface constraints in disguise, as a curve is
27.16394 +     *    the intersection of two surfaces, and is essentially constrained to both
27.16395 +     *
27.16396 +     *  @class Curve
27.16397 +     *  @constructor
27.16398 +     *  @extends Constraint
27.16399 +     *  @param {Options} [options] An object of configurable options.
27.16400 +     *  @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y - r*r } corresponds to a circle of radius r pixels
27.16401 +     *  @param {Function} [options.plane] An implicitly defined second surface that the body is constrained to
27.16402 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is violated
27.16403 +     *  @param {Number} [options.number] The damping-like reaction when the constraint is violated
27.16404 +     */
27.16405 +    function Curve(options) {
27.16406 +        this.options = Object.create(Curve.DEFAULT_OPTIONS);
27.16407 +        if (options) this.setOptions(options);
27.16408 +
27.16409 +        //registers
27.16410 +        this.J = new Vector();
27.16411 +        this.impulse = new Vector();
27.16412 +
27.16413 +        Constraint.call(this);
27.16414 +    }
27.16415 +
27.16416 +    Curve.prototype = Object.create(Constraint.prototype);
27.16417 +    Curve.prototype.constructor = Curve;
27.16418 +
27.16419 +    /** @const */ var epsilon = 1e-7;
27.16420 +    /** @const */ var pi = Math.PI;
27.16421 +
27.16422 +    Curve.DEFAULT_OPTIONS = {
27.16423 +        equation  : function(x,y,z) {
27.16424 +            return 0;
27.16425 +        },
27.16426 +        plane : function(x,y,z) {
27.16427 +            return z;
27.16428 +        },
27.16429 +        period : 0,
27.16430 +        dampingRatio : 0
27.16431 +    };
27.16432 +
27.16433 +    /**
27.16434 +     * Basic options setter
27.16435 +     *
27.16436 +     * @method setOptions
27.16437 +     * @param options {Objects}
27.16438 +     */
27.16439 +    Curve.prototype.setOptions = function setOptions(options) {
27.16440 +        for (var key in options) this.options[key] = options[key];
27.16441 +    };
27.16442 +
27.16443 +    /**
27.16444 +     * Adds a curve impulse to a physics body.
27.16445 +     *
27.16446 +     * @method applyConstraint
27.16447 +     * @param targets {Array.Body} Array of bodies to apply force to.
27.16448 +     * @param source {Body} Not applicable
27.16449 +     * @param dt {Number} Delta time
27.16450 +     */
27.16451 +    Curve.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.16452 +        var options = this.options;
27.16453 +        var impulse = this.impulse;
27.16454 +        var J = this.J;
27.16455 +
27.16456 +        var f = options.equation;
27.16457 +        var g = options.plane;
27.16458 +        var dampingRatio = options.dampingRatio;
27.16459 +        var period = options.period;
27.16460 +
27.16461 +        for (var i = 0; i < targets.length; i++) {
27.16462 +            var body = targets[i];
27.16463 +
27.16464 +            var v = body.velocity;
27.16465 +            var p = body.position;
27.16466 +            var m = body.mass;
27.16467 +
27.16468 +            var gamma;
27.16469 +            var beta;
27.16470 +
27.16471 +            if (period === 0) {
27.16472 +                gamma = 0;
27.16473 +                beta = 1;
27.16474 +            }
27.16475 +            else {
27.16476 +                var c = 4 * m * pi * dampingRatio / period;
27.16477 +                var k = 4 * m * pi * pi / (period * period);
27.16478 +
27.16479 +                gamma = 1 / (c + dt*k);
27.16480 +                beta  = dt*k / (c + dt*k);
27.16481 +            }
27.16482 +
27.16483 +            var x = p.x;
27.16484 +            var y = p.y;
27.16485 +            var z = p.z;
27.16486 +
27.16487 +            var f0  = f(x, y, z);
27.16488 +            var dfx = (f(x + epsilon, p, p) - f0) / epsilon;
27.16489 +            var dfy = (f(x, y + epsilon, p) - f0) / epsilon;
27.16490 +            var dfz = (f(x, y, p + epsilon) - f0) / epsilon;
27.16491 +
27.16492 +            var g0  = g(x, y, z);
27.16493 +            var dgx = (g(x + epsilon, y, z) - g0) / epsilon;
27.16494 +            var dgy = (g(x, y + epsilon, z) - g0) / epsilon;
27.16495 +            var dgz = (g(x, y, z + epsilon) - g0) / epsilon;
27.16496 +
27.16497 +            J.setXYZ(dfx + dgx, dfy + dgy, dfz + dgz);
27.16498 +
27.16499 +            var antiDrift = beta/dt * (f0 + g0);
27.16500 +            var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m);
27.16501 +
27.16502 +            impulse.set(J.mult(dt*lambda));
27.16503 +            body.applyImpulse(impulse);
27.16504 +        }
27.16505 +    };
27.16506 +
27.16507 +    module.exports = Curve;
27.16508 +});
27.16509 +
27.16510 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16511 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16512 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16513 + *
27.16514 + * Owner: david@famo.us
27.16515 + * @license MPL 2.0
27.16516 + * @copyright Famous Industries, Inc. 2014
27.16517 + */
27.16518 +
27.16519 +define('famous/physics/constraints/Distance',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
27.16520 +    var Constraint = require('./Constraint');
27.16521 +    var Vector = require('famous/math/Vector');
27.16522 +
27.16523 +    /**
27.16524 +     *  A constraint that keeps a physics body a given distance away from a given
27.16525 +     *  anchor, or another attached body.
27.16526 +     *
27.16527 +     *
27.16528 +     *  @class Distance
27.16529 +     *  @constructor
27.16530 +     *  @extends Constraint
27.16531 +     *  @param {Options} [options] An object of configurable options.
27.16532 +     *  @param {Array} [options.anchor] The location of the anchor
27.16533 +     *  @param {Number} [options.length] The amount of distance from the anchor the constraint should enforce
27.16534 +     *  @param {Number} [options.minLength] The minimum distance before the constraint is activated. Use this property for a "rope" effect.
27.16535 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is broken.
27.16536 +     *  @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is broken.
27.16537 +     *
27.16538 +     */
27.16539 +    function Distance(options) {
27.16540 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
27.16541 +        if (options) this.setOptions(options);
27.16542 +
27.16543 +        //registers
27.16544 +        this.impulse  = new Vector();
27.16545 +        this.normal   = new Vector();
27.16546 +        this.diffP    = new Vector();
27.16547 +        this.diffV    = new Vector();
27.16548 +
27.16549 +        Constraint.call(this);
27.16550 +    }
27.16551 +
27.16552 +    Distance.prototype = Object.create(Constraint.prototype);
27.16553 +    Distance.prototype.constructor = Distance;
27.16554 +
27.16555 +    Distance.DEFAULT_OPTIONS = {
27.16556 +        anchor : null,
27.16557 +        length : 0,
27.16558 +        minLength : 0,
27.16559 +        period : 0,
27.16560 +        dampingRatio : 0
27.16561 +    };
27.16562 +
27.16563 +    /** @const */ var pi = Math.PI;
27.16564 +
27.16565 +    /**
27.16566 +     * Basic options setter
27.16567 +     *
27.16568 +     * @method setOptions
27.16569 +     * @param options {Objects}
27.16570 +     */
27.16571 +    Distance.prototype.setOptions = function setOptions(options) {
27.16572 +        if (options.anchor) {
27.16573 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
27.16574 +            if (options.anchor   instanceof Vector)  this.options.anchor = options.anchor;
27.16575 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
27.16576 +        }
27.16577 +        if (options.length !== undefined) this.options.length = options.length;
27.16578 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
27.16579 +        if (options.period !== undefined) this.options.period = options.period;
27.16580 +        if (options.minLength !== undefined) this.options.minLength = options.minLength;
27.16581 +    };
27.16582 +
27.16583 +    function _calcError(impulse, body) {
27.16584 +        return body.mass * impulse.norm();
27.16585 +    }
27.16586 +
27.16587 +    /**
27.16588 +     * Set the anchor position
27.16589 +     *
27.16590 +     * @method setOptions
27.16591 +     * @param anchor {Array}
27.16592 +     */
27.16593 +    Distance.prototype.setAnchor = function setAnchor(anchor) {
27.16594 +        if (!this.options.anchor) this.options.anchor = new Vector();
27.16595 +        this.options.anchor.set(anchor);
27.16596 +    };
27.16597 +
27.16598 +    /**
27.16599 +     * Adds an impulse to a physics body's velocity due to the constraint
27.16600 +     *
27.16601 +     * @method applyConstraint
27.16602 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
27.16603 +     * @param source {Body}         The source of the constraint
27.16604 +     * @param dt {Number}           Delta time
27.16605 +     */
27.16606 +    Distance.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.16607 +        var n        = this.normal;
27.16608 +        var diffP    = this.diffP;
27.16609 +        var diffV    = this.diffV;
27.16610 +        var impulse  = this.impulse;
27.16611 +        var options  = this.options;
27.16612 +
27.16613 +        var dampingRatio = options.dampingRatio;
27.16614 +        var period       = options.period;
27.16615 +        var minLength    = options.minLength;
27.16616 +
27.16617 +        var p2;
27.16618 +        var w2;
27.16619 +
27.16620 +        if (source) {
27.16621 +            var v2 = source.velocity;
27.16622 +            p2 = source.position;
27.16623 +            w2 = source.inverseMass;
27.16624 +        }
27.16625 +        else {
27.16626 +            p2 = this.options.anchor;
27.16627 +            w2 = 0;
27.16628 +        }
27.16629 +
27.16630 +        var length = this.options.length;
27.16631 +
27.16632 +        for (var i = 0; i < targets.length; i++) {
27.16633 +            var body = targets[i];
27.16634 +
27.16635 +            var v1 = body.velocity;
27.16636 +            var p1 = body.position;
27.16637 +            var w1 = body.inverseMass;
27.16638 +
27.16639 +            diffP.set(p1.sub(p2));
27.16640 +            n.set(diffP.normalize());
27.16641 +
27.16642 +            var dist = diffP.norm() - length;
27.16643 +
27.16644 +            //rope effect
27.16645 +            if (Math.abs(dist) < minLength) return;
27.16646 +
27.16647 +            if (source) diffV.set(v1.sub(v2));
27.16648 +            else diffV.set(v1);
27.16649 +
27.16650 +            var effMass = 1 / (w1 + w2);
27.16651 +            var gamma;
27.16652 +            var beta;
27.16653 +
27.16654 +            if (period === 0) {
27.16655 +                gamma = 0;
27.16656 +                beta  = 1;
27.16657 +            }
27.16658 +            else {
27.16659 +                var c = 4 * effMass * pi * dampingRatio / period;
27.16660 +                var k = 4 * effMass * pi * pi / (period * period);
27.16661 +
27.16662 +                gamma = 1 / (c + dt*k);
27.16663 +                beta  = dt*k / (c + dt*k);
27.16664 +            }
27.16665 +
27.16666 +            var antiDrift = beta/dt * dist;
27.16667 +            var lambda    = -(n.dot(diffV) + antiDrift) / (gamma + dt/effMass);
27.16668 +
27.16669 +            impulse.set(n.mult(dt*lambda));
27.16670 +            body.applyImpulse(impulse);
27.16671 +
27.16672 +            if (source) source.applyImpulse(impulse.mult(-1));
27.16673 +        }
27.16674 +    };
27.16675 +
27.16676 +    module.exports = Distance;
27.16677 +});
27.16678 +
27.16679 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16680 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16682 + *
27.16683 + * Owner: david@famo.us
27.16684 + * @license MPL 2.0
27.16685 + * @copyright Famous Industries, Inc. 2014
27.16686 + */
27.16687 +
27.16688 +define('famous/physics/constraints/Surface',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
27.16689 +    var Constraint = require('./Constraint');
27.16690 +    var Vector = require('famous/math/Vector');
27.16691 +
27.16692 +    /**
27.16693 +     *  A constraint that keeps a physics body on a given implicit surface
27.16694 +     *    regardless of other physical forces are applied to it.
27.16695 +     *
27.16696 +     *  @class Surface
27.16697 +     *  @constructor
27.16698 +     *  @extends Constraint
27.16699 +     *  @param {Options} [options] An object of configurable options.
27.16700 +     *  @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y + z*z - r*r } corresponds to a sphere of radius r pixels.
27.16701 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is violated.
27.16702 +     *  @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is violated.
27.16703 +     */
27.16704 +    function Surface(options) {
27.16705 +        this.options = Object.create(Surface.DEFAULT_OPTIONS);
27.16706 +        if (options) this.setOptions(options);
27.16707 +
27.16708 +        this.J = new Vector();
27.16709 +        this.impulse  = new Vector();
27.16710 +
27.16711 +        Constraint.call(this);
27.16712 +    }
27.16713 +
27.16714 +    Surface.prototype = Object.create(Constraint.prototype);
27.16715 +    Surface.prototype.constructor = Surface;
27.16716 +
27.16717 +    Surface.DEFAULT_OPTIONS = {
27.16718 +        equation : undefined,
27.16719 +        period : 0,
27.16720 +        dampingRatio : 0
27.16721 +    };
27.16722 +
27.16723 +    /** @const */ var epsilon = 1e-7;
27.16724 +    /** @const */ var pi = Math.PI;
27.16725 +
27.16726 +    /**
27.16727 +     * Basic options setter
27.16728 +     *
27.16729 +     * @method setOptions
27.16730 +     * @param options {Objects}
27.16731 +     */
27.16732 +    Surface.prototype.setOptions = function setOptions(options) {
27.16733 +        for (var key in options) this.options[key] = options[key];
27.16734 +    };
27.16735 +
27.16736 +    /**
27.16737 +     * Adds a surface impulse to a physics body.
27.16738 +     *
27.16739 +     * @method applyConstraint
27.16740 +     * @param targets {Array.Body} Array of bodies to apply force to.
27.16741 +     * @param source {Body} Not applicable
27.16742 +     * @param dt {Number} Delta time
27.16743 +     */
27.16744 +    Surface.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.16745 +        var impulse = this.impulse;
27.16746 +        var J       = this.J;
27.16747 +        var options = this.options;
27.16748 +
27.16749 +        var f = options.equation;
27.16750 +        var dampingRatio = options.dampingRatio;
27.16751 +        var period = options.period;
27.16752 +
27.16753 +        for (var i = 0; i < targets.length; i++) {
27.16754 +            var particle = targets[i];
27.16755 +
27.16756 +            var v = particle.velocity;
27.16757 +            var p = particle.position;
27.16758 +            var m = particle.mass;
27.16759 +
27.16760 +            var gamma;
27.16761 +            var beta;
27.16762 +
27.16763 +            if (period === 0) {
27.16764 +                gamma = 0;
27.16765 +                beta = 1;
27.16766 +            }
27.16767 +            else {
27.16768 +                var c = 4 * m * pi * dampingRatio / period;
27.16769 +                var k = 4 * m * pi * pi / (period * period);
27.16770 +
27.16771 +                gamma = 1 / (c + dt*k);
27.16772 +                beta  = dt*k / (c + dt*k);
27.16773 +            }
27.16774 +
27.16775 +            var x = p.x;
27.16776 +            var y = p.y;
27.16777 +            var z = p.z;
27.16778 +
27.16779 +            var f0  = f(x, y, z);
27.16780 +            var dfx = (f(x + epsilon, p, p) - f0) / epsilon;
27.16781 +            var dfy = (f(x, y + epsilon, p) - f0) / epsilon;
27.16782 +            var dfz = (f(x, y, p + epsilon) - f0) / epsilon;
27.16783 +            J.setXYZ(dfx, dfy, dfz);
27.16784 +
27.16785 +            var antiDrift = beta/dt * f0;
27.16786 +            var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m);
27.16787 +
27.16788 +            impulse.set(J.mult(dt*lambda));
27.16789 +            particle.applyImpulse(impulse);
27.16790 +        }
27.16791 +    };
27.16792 +
27.16793 +    module.exports = Surface;
27.16794 +});
27.16795 +
27.16796 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.16797 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.16798 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.16799 + *
27.16800 + * Owner: david@famo.us
27.16801 + * @license MPL 2.0
27.16802 + * @copyright Famous Industries, Inc. 2014
27.16803 + */
27.16804 +
27.16805 +define('famous/physics/constraints/Walls',['require','exports','module','./Constraint','./Wall','famous/math/Vector'],function(require, exports, module) {
27.16806 +    var Constraint = require('./Constraint');
27.16807 +    var Wall = require('./Wall');
27.16808 +    var Vector = require('famous/math/Vector');
27.16809 +
27.16810 +    /**
27.16811 +     *  Walls combines one or more Wall primitives and exposes a simple API to
27.16812 +     *  interact with several walls at once. A common use case would be to set up
27.16813 +     *  a bounding box for a physics body, that would collide with each side.
27.16814 +     *
27.16815 +     *  @class Walls
27.16816 +     *  @constructor
27.16817 +     *  @extends Constraint
27.16818 +     *  @uses Wall
27.16819 +     *  @param {Options} [options] An object of configurable options.
27.16820 +     *  @param {Array} [options.sides] An array of sides e.g., [Walls.LEFT, Walls.TOP]
27.16821 +     *  @param {Array} [options.size] The size of the bounding box of the walls.
27.16822 +     *  @param {Array} [options.origin] The center of the wall relative to the size.
27.16823 +     *  @param {Array} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
27.16824 +     *  @param {Array} [options.slop] Amount of penetration in pixels to ignore before collision event triggers.
27.16825 +     *  @param {Array} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) The energy ratio lost in a collision (0 = stick, 1 = elastic)
27.16826 +     *  @param {Array} [options.onContact] How to handle collision against the wall.
27.16827 +     */
27.16828 +    function Walls(options) {
27.16829 +        this.options = Object.create(Walls.DEFAULT_OPTIONS);
27.16830 +        if (options) this.setOptions(options);
27.16831 +        _createComponents.call(this, options.sides || this.options.sides);
27.16832 +
27.16833 +        Constraint.call(this);
27.16834 +    }
27.16835 +
27.16836 +    Walls.prototype = Object.create(Constraint.prototype);
27.16837 +    Walls.prototype.constructor = Walls;
27.16838 +    /**
27.16839 +     * @property Walls.ON_CONTACT
27.16840 +     * @type Object
27.16841 +     * @extends Wall.ON_CONTACT
27.16842 +     * @static
27.16843 +     */
27.16844 +    Walls.ON_CONTACT = Wall.ON_CONTACT;
27.16845 +
27.16846 +    /**
27.16847 +     * An enumeration of common types of walls
27.16848 +     *    LEFT, RIGHT, TOP, BOTTOM, FRONT, BACK
27.16849 +     *    TWO_DIMENSIONAL, THREE_DIMENSIONAL
27.16850 +     *
27.16851 +     * @property Walls.SIDES
27.16852 +     * @type Object
27.16853 +     * @final
27.16854 +     * @static
27.16855 +     */
27.16856 +    Walls.SIDES = {
27.16857 +        LEFT   : 0,
27.16858 +        RIGHT  : 1,
27.16859 +        TOP    : 2,
27.16860 +        BOTTOM : 3,
27.16861 +        FRONT  : 4,
27.16862 +        BACK   : 5,
27.16863 +        TWO_DIMENSIONAL : [0, 1, 2, 3],
27.16864 +        THREE_DIMENSIONAL : [0, 1, 2, 3, 4, 5]
27.16865 +    };
27.16866 +
27.16867 +    Walls.DEFAULT_OPTIONS = {
27.16868 +        sides : Walls.SIDES.TWO_DIMENSIONAL,
27.16869 +        size : [window.innerWidth, window.innerHeight, 0],
27.16870 +        origin : [.5, .5, .5],
27.16871 +        drift : 0.5,
27.16872 +        slop : 0,
27.16873 +        restitution : 0.5,
27.16874 +        onContact : Walls.ON_CONTACT.REFLECT
27.16875 +    };
27.16876 +
27.16877 +    var _SIDE_NORMALS = {
27.16878 +        0 : new Vector(1, 0, 0),
27.16879 +        1 : new Vector(-1, 0, 0),
27.16880 +        2 : new Vector(0, 1, 0),
27.16881 +        3 : new Vector(0,-1, 0),
27.16882 +        4 : new Vector(0, 0, 1),
27.16883 +        5 : new Vector(0, 0,-1)
27.16884 +    };
27.16885 +
27.16886 +    function _getDistance(side, size, origin) {
27.16887 +        var distance;
27.16888 +        var SIDES = Walls.SIDES;
27.16889 +        switch (parseInt(side)) {
27.16890 +            case SIDES.LEFT:
27.16891 +                distance = size[0] * origin[0];
27.16892 +                break;
27.16893 +            case SIDES.TOP:
27.16894 +                distance = size[1] * origin[1];
27.16895 +                break;
27.16896 +            case SIDES.FRONT:
27.16897 +                distance = size[2] * origin[2];
27.16898 +                break;
27.16899 +            case SIDES.RIGHT:
27.16900 +                distance = size[0] * (1 - origin[0]);
27.16901 +                break;
27.16902 +            case SIDES.BOTTOM:
27.16903 +                distance = size[1] * (1 - origin[1]);
27.16904 +                break;
27.16905 +            case SIDES.BACK:
27.16906 +                distance = size[2] * (1 - origin[2]);
27.16907 +                break;
27.16908 +        }
27.16909 +        return distance;
27.16910 +    }
27.16911 +
27.16912 +    /*
27.16913 +     * Setter for options.
27.16914 +     *
27.16915 +     * @method setOptions
27.16916 +     * @param options {Objects}
27.16917 +     */
27.16918 +    Walls.prototype.setOptions = function setOptions(options) {
27.16919 +        var resizeFlag = false;
27.16920 +        if (options.restitution !== undefined) _setOptionsForEach.call(this, {restitution : options.restitution});
27.16921 +        if (options.drift !== undefined) _setOptionsForEach.call(this, {drift : options.drift});
27.16922 +        if (options.slop !== undefined) _setOptionsForEach.call(this, {slop : options.slop});
27.16923 +        if (options.onContact !== undefined) _setOptionsForEach.call(this, {onContact : options.onContact});
27.16924 +        if (options.size !== undefined) resizeFlag = true;
27.16925 +        if (options.sides !== undefined) this.options.sides = options.sides;
27.16926 +        if (options.origin !== undefined) resizeFlag = true;
27.16927 +        if (resizeFlag) this.setSize(options.size, options.origin);
27.16928 +    };
27.16929 +
27.16930 +    function _createComponents(sides) {
27.16931 +        this.components = {};
27.16932 +        var components = this.components;
27.16933 +
27.16934 +        for (var i = 0; i < sides.length; i++) {
27.16935 +            var side = sides[i];
27.16936 +            components[i] = new Wall({
27.16937 +                normal   : _SIDE_NORMALS[side].clone(),
27.16938 +                distance : _getDistance(side, this.options.size, this.options.origin)
27.16939 +            });
27.16940 +        }
27.16941 +    }
27.16942 +
27.16943 +    /*
27.16944 +     * Setter for size.
27.16945 +     *
27.16946 +     * @method setOptions
27.16947 +     * @param options {Objects}
27.16948 +     */
27.16949 +    Walls.prototype.setSize = function setSize(size, origin) {
27.16950 +        origin = origin || this.options.origin;
27.16951 +        if (origin.length < 3) origin[2] = 0.5;
27.16952 +
27.16953 +        this.forEach(function(wall, side) {
27.16954 +            var d = _getDistance(side, size, origin);
27.16955 +            wall.setOptions({distance : d});
27.16956 +        });
27.16957 +
27.16958 +        this.options.size   = size;
27.16959 +        this.options.origin = origin;
27.16960 +    };
27.16961 +
27.16962 +    function _setOptionsForEach(options) {
27.16963 +        this.forEach(function(wall) {
27.16964 +            wall.setOptions(options);
27.16965 +        });
27.16966 +        for (var key in options) this.options[key] = options[key];
27.16967 +    }
27.16968 +
27.16969 +    /**
27.16970 +     * Adds an impulse to a physics body's velocity due to the walls constraint
27.16971 +     *
27.16972 +     * @method applyConstraint
27.16973 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
27.16974 +     * @param source {Body}         The source of the constraint
27.16975 +     * @param dt {Number}           Delta time
27.16976 +     */
27.16977 +    Walls.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
27.16978 +        this.forEach(function(wall) {
27.16979 +            wall.applyConstraint(targets, source, dt);
27.16980 +        });
27.16981 +    };
27.16982 +
27.16983 +    /**
27.16984 +     * Apply a method to each wall making up the walls
27.16985 +     *
27.16986 +     * @method applyConstraint
27.16987 +     * @param fn {Function}  Function that takes in a wall as its first parameter
27.16988 +     */
27.16989 +    Walls.prototype.forEach = function forEach(fn) {
27.16990 +        for (var key in this.sides) fn(this.sides[key], key);
27.16991 +    };
27.16992 +
27.16993 +    /**
27.16994 +     * Rotates the walls by an angle in the XY-plane
27.16995 +     *
27.16996 +     * @method applyConstraint
27.16997 +     * @param angle {Function}
27.16998 +     */
27.16999 +    Walls.prototype.rotateZ = function rotateZ(angle) {
27.17000 +        this.forEach(function(wall) {
27.17001 +            var n = wall.options.normal;
27.17002 +            n.rotateZ(angle).put(n);
27.17003 +        });
27.17004 +    };
27.17005 +
27.17006 +    /**
27.17007 +     * Rotates the walls by an angle in the YZ-plane
27.17008 +     *
27.17009 +     * @method applyConstraint
27.17010 +     * @param angle {Function}
27.17011 +     */
27.17012 +    Walls.prototype.rotateX = function rotateX(angle) {
27.17013 +        this.forEach(function(wall) {
27.17014 +            var n = wall.options.normal;
27.17015 +            n.rotateX(angle).put(n);
27.17016 +        });
27.17017 +    };
27.17018 +
27.17019 +    /**
27.17020 +     * Rotates the walls by an angle in the XZ-plane
27.17021 +     *
27.17022 +     * @method applyConstraint
27.17023 +     * @param angle {Function}
27.17024 +     */
27.17025 +    Walls.prototype.rotateY = function rotateY(angle) {
27.17026 +        this.forEach(function(wall) {
27.17027 +            var n = wall.options.normal;
27.17028 +            n.rotateY(angle).put(n);
27.17029 +        });
27.17030 +    };
27.17031 +
27.17032 +    module.exports = Walls;
27.17033 +});
27.17034 +
27.17035 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.17036 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.17037 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.17038 + *
27.17039 + * Owner: david@famo.us
27.17040 + * @license MPL 2.0
27.17041 + * @copyright Famous Industries, Inc. 2014
27.17042 + */
27.17043 +
27.17044 +//TODO: test options manager
27.17045 +define('famous/physics/forces/Repulsion',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
27.17046 +    var Force = require('./Force');
27.17047 +    var Vector = require('famous/math/Vector');
27.17048 +
27.17049 +    /**
27.17050 +     *  Repulsion is a force that repels (attracts) bodies away (towards)
27.17051 +     *    each other. A repulsion of negative strength is attractive.
27.17052 +     *
27.17053 +     *  @class Repulsion
27.17054 +     *  @constructor
27.17055 +     *  @extends Force
27.17056 +     *  @param {Object} options overwrites default options
27.17057 +     */
27.17058 +    function Repulsion(options) {
27.17059 +        this.options = Object.create(Repulsion.DEFAULT_OPTIONS);
27.17060 +        if (options) this.setOptions(options);
27.17061 +
27.17062 +        //registers
27.17063 +        this.disp  = new Vector();
27.17064 +
27.17065 +        Force.call(this);
27.17066 +    }
27.17067 +
27.17068 +    Repulsion.prototype = Object.create(Force.prototype);
27.17069 +    Repulsion.prototype.constructor = Repulsion;
27.17070 +    /**
27.17071 +     * @property Repulsion.DECAY_FUNCTIONS
27.17072 +     * @type Object
27.17073 +     * @protected
27.17074 +     * @static
27.17075 +     */
27.17076 +    Repulsion.DECAY_FUNCTIONS = {
27.17077 +
27.17078 +        /**
27.17079 +         * A linear decay function
27.17080 +         * @attribute LINEAR
27.17081 +         * @type Function
27.17082 +         * @param {Number} r distance from the source body
27.17083 +         * @param {Number} cutoff the effective radius of influence
27.17084 +         */
27.17085 +        LINEAR : function(r, cutoff) {
27.17086 +            return Math.max(1 - (1 / cutoff) * r, 0);
27.17087 +        },
27.17088 +
27.17089 +        /**
27.17090 +         * A Morse potential decay function (http://en.wikipedia.org/wiki/Morse_potential)
27.17091 +         * @attribute MORSE
27.17092 +         * @type Function
27.17093 +         * @param {Number} r distance from the source body
27.17094 +         * @param {Number} cutoff the minimum radius of influence
27.17095 +         */
27.17096 +        MORSE : function(r, cutoff) {
27.17097 +            var r0 = (cutoff === 0) ? 100 : cutoff;
27.17098 +            var rShifted = r + r0 * (1 - Math.log(2)); //shift by x-intercept
27.17099 +            return Math.max(1 - Math.pow(1 - Math.exp(rShifted/r0 - 1), 2), 0);
27.17100 +        },
27.17101 +
27.17102 +        /**
27.17103 +         * An inverse distance decay function
27.17104 +         * @attribute INVERSE
27.17105 +         * @type Function
27.17106 +         * @param {Number} r distance from the source body
27.17107 +         * @param {Number} cutoff a distance shift to avoid singularities
27.17108 +         */
27.17109 +        INVERSE : function(r, cutoff) {
27.17110 +            return 1 / (1 - cutoff + r);
27.17111 +        },
27.17112 +
27.17113 +        /**
27.17114 +         * An inverse squared distance decay function
27.17115 +         * @attribute INVERSE
27.17116 +         * @type Function
27.17117 +         * @param {Number} r distance from the source body
27.17118 +         * @param {Number} cutoff a distance shift to avoid singularities
27.17119 +         */
27.17120 +        GRAVITY : function(r, cutoff) {
27.17121 +            return 1 / (1 - cutoff + r*r);
27.17122 +        }
27.17123 +    };
27.17124 +
27.17125 +    /**
27.17126 +     * @property Repulsion.DEFAULT_OPTIONS
27.17127 +     * @type Object
27.17128 +     * @protected
27.17129 +     * @static
27.17130 +     */
27.17131 +    Repulsion.DEFAULT_OPTIONS = {
27.17132 +
27.17133 +        /**
27.17134 +         * The strength of the force
27.17135 +         *    Range : [0, 100]
27.17136 +         * @attribute strength
27.17137 +         * @type Number
27.17138 +         * @default 1
27.17139 +         */
27.17140 +        strength : 1,
27.17141 +
27.17142 +        /**
27.17143 +         * The location of the force, if not another physics body
27.17144 +         *
27.17145 +         * @attribute anchor
27.17146 +         * @type Number
27.17147 +         * @default 0.01
27.17148 +         * @optional
27.17149 +         */
27.17150 +        anchor : undefined,
27.17151 +
27.17152 +        /**
27.17153 +         * The range of the repulsive force
27.17154 +         * @attribute radii
27.17155 +         * @type Array
27.17156 +         * @default [0, Infinity]
27.17157 +         */
27.17158 +        range : [0, Infinity],
27.17159 +
27.17160 +        /**
27.17161 +         * A normalization for the force to avoid singularities at the origin
27.17162 +         * @attribute cutoff
27.17163 +         * @type Number
27.17164 +         * @default 0
27.17165 +         */
27.17166 +        cutoff : 0,
27.17167 +
27.17168 +        /**
27.17169 +         * The maximum magnitude of the force
27.17170 +         *    Range : [0, Infinity]
27.17171 +         * @attribute cap
27.17172 +         * @type Number
27.17173 +         * @default Infinity
27.17174 +         */
27.17175 +        cap : Infinity,
27.17176 +
27.17177 +        /**
27.17178 +         * The type of decay the repulsive force should have
27.17179 +         * @attribute decayFunction
27.17180 +         * @type Function
27.17181 +         */
27.17182 +        decayFunction : Repulsion.DECAY_FUNCTIONS.GRAVITY
27.17183 +    };
27.17184 +
27.17185 +    /*
27.17186 +     * Setter for options.
27.17187 +     *
27.17188 +     * @method setOptions
27.17189 +     * @param {Objects} options
27.17190 +     */
27.17191 +    Repulsion.prototype.setOptions = function setOptions(options) {
27.17192 +        if (options.anchor !== undefined) {
27.17193 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
27.17194 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
27.17195 +            delete options.anchor;
27.17196 +        }
27.17197 +        for (var key in options) this.options[key] = options[key];
27.17198 +    };
27.17199 +
27.17200 +    /**
27.17201 +     * Adds a drag force to a physics body's force accumulator.
27.17202 +     *
27.17203 +     * @method applyForce
27.17204 +     * @param targets {Array.Body}  Array of bodies to apply force to
27.17205 +     * @param source {Body}         The source of the force
27.17206 +     */
27.17207 +    Repulsion.prototype.applyForce = function applyForce(targets, source) {
27.17208 +        var options     = this.options;
27.17209 +        var force       = this.force;
27.17210 +        var disp        = this.disp;
27.17211 +
27.17212 +        var strength    = options.strength;
27.17213 +        var anchor      = options.anchor || source.position;
27.17214 +        var cap         = options.cap;
27.17215 +        var cutoff      = options.cutoff;
27.17216 +        var rMin        = options.range[0];
27.17217 +        var rMax        = options.range[1];
27.17218 +        var decayFn     = options.decayFunction;
27.17219 +
27.17220 +        if (strength === 0) return;
27.17221 +
27.17222 +        for (var index in targets) {
27.17223 +            var particle = targets[index];
27.17224 +
27.17225 +            if (particle === source) continue;
27.17226 +
27.17227 +            var m1 = particle.mass;
27.17228 +            var p1 = particle.position;
27.17229 +
27.17230 +            disp.set(p1.sub(anchor));
27.17231 +            var r = disp.norm();
27.17232 +
27.17233 +            if (r < rMax && r > rMin) {
27.17234 +                force.set(disp.normalize(strength * m1 * decayFn(r, cutoff)).cap(cap));
27.17235 +                particle.applyForce(force);
27.17236 +            }
27.17237 +        }
27.17238 +
27.17239 +    };
27.17240 +
27.17241 +    module.exports = Repulsion;
27.17242 +});
27.17243 +
27.17244 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.17245 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.17246 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.17247 + *
27.17248 + * Owner: david@famo.us
27.17249 + * @license MPL 2.0
27.17250 + * @copyright Famous Industries, Inc. 2014
27.17251 + */
27.17252 +
27.17253 +define('famous/physics/forces/RotationalDrag',['require','exports','module','./Drag'],function(require, exports, module) {
27.17254 +    var Drag = require('./Drag');
27.17255 +
27.17256 +    /**
27.17257 +     * Rotational drag is a force that opposes angular velocity.
27.17258 +     *   Attach it to a physics body to slow down its rotation.
27.17259 +     *
27.17260 +     * @class RotationalDrag
27.17261 +     * @constructor
27.17262 +     * @extends Force
27.17263 +     * @param {Object} options options to set on drag
27.17264 +     */
27.17265 +    function RotationalDrag(options) {
27.17266 +        Drag.call(this, options);
27.17267 +    }
27.17268 +
27.17269 +    RotationalDrag.prototype = Object.create(Drag.prototype);
27.17270 +    RotationalDrag.prototype.constructor = RotationalDrag;
27.17271 +
27.17272 +    RotationalDrag.DEFAULT_OPTIONS = Drag.DEFAULT_OPTIONS;
27.17273 +    RotationalDrag.FORCE_FUNCTIONS = Drag.FORCE_FUNCTIONS;
27.17274 +
27.17275 +    /**
27.17276 +     * @property Repulsion.FORCE_FUNCTIONS
27.17277 +     * @type Object
27.17278 +     * @protected
27.17279 +     * @static
27.17280 +     */
27.17281 +    RotationalDrag.FORCE_FUNCTIONS = {
27.17282 +
27.17283 +        /**
27.17284 +         * A drag force proprtional to the angular velocity
27.17285 +         * @attribute LINEAR
27.17286 +         * @type Function
27.17287 +         * @param {Vector} angularVelocity
27.17288 +         * @return {Vector} drag force
27.17289 +         */
27.17290 +        LINEAR : function(angularVelocity) {
27.17291 +            return angularVelocity;
27.17292 +        },
27.17293 +
27.17294 +        /**
27.17295 +         * A drag force proprtional to the square of the angular velocity
27.17296 +         * @attribute QUADRATIC
27.17297 +         * @type Function
27.17298 +         * @param {Vector} angularVelocity
27.17299 +         * @return {Vector} drag force
27.17300 +         */
27.17301 +        QUADRATIC : function(angularVelocity) {
27.17302 +            return angularVelocity.mult(angularVelocity.norm());
27.17303 +        }
27.17304 +    };
27.17305 +
27.17306 +    /**
27.17307 +     * Adds a rotational drag force to a physics body's torque accumulator.
27.17308 +     *
27.17309 +     * @method applyForce
27.17310 +     * @param targets {Array.Body} Array of bodies to apply drag force to.
27.17311 +     */
27.17312 +    RotationalDrag.prototype.applyForce = function applyForce(targets) {
27.17313 +        var strength       = this.options.strength;
27.17314 +        var forceFunction  = this.options.forceFunction;
27.17315 +        var force          = this.force;
27.17316 +
27.17317 +        //TODO: rotational drag as function of inertia
27.17318 +        for (var index = 0; index < targets.length; index++) {
27.17319 +            var particle = targets[index];
27.17320 +            forceFunction(particle.angularVelocity).mult(-100*strength).put(force);
27.17321 +            particle.applyTorque(force);
27.17322 +        }
27.17323 +    };
27.17324 +
27.17325 +    /*
27.17326 +     * Setter for options.
27.17327 +     *
27.17328 +     * @method setOptions
27.17329 +     * @param {Objects} options
27.17330 +     */
27.17331 +    RotationalDrag.prototype.setOptions = function setOptions(options) {
27.17332 +        for (var key in options) this.options[key] = options[key];
27.17333 +    };
27.17334 +
27.17335 +    module.exports = RotationalDrag;
27.17336 +});
27.17337 +
27.17338 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.17339 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.17340 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.17341 + *
27.17342 + * Owner: david@famo.us
27.17343 + * @license MPL 2.0
27.17344 + * @copyright Famous Industries, Inc. 2014
27.17345 + */
27.17346 +
27.17347 +//TODO: test inheritance
27.17348 +define('famous/physics/forces/RotationalSpring',['require','exports','module','./Spring'],function(require, exports, module) {
27.17349 +    var Spring = require('./Spring');
27.17350 +
27.17351 +    /**
27.17352 +     *  A force that rotates a physics body back to target Euler angles.
27.17353 +     *  Just as a spring translates a body to a particular X, Y, Z, location,
27.17354 +     *  a rotational spring rotates a body to a particular X, Y, Z Euler angle.
27.17355 +     *      Note: there is no physical agent that does this in the "real world"
27.17356 +     *
27.17357 +     *  @class RotationalSpring
27.17358 +     *  @constructor
27.17359 +     *  @extends Spring
27.17360 +     *  @param {Object} options options to set on drag
27.17361 +     */
27.17362 +    function RotationalSpring(options) {
27.17363 +        Spring.call(this, options);
27.17364 +    }
27.17365 +
27.17366 +    RotationalSpring.prototype = Object.create(Spring.prototype);
27.17367 +    RotationalSpring.prototype.constructor = RotationalSpring;
27.17368 +
27.17369 +    RotationalSpring.DEFAULT_OPTIONS = Spring.DEFAULT_OPTIONS;
27.17370 +    RotationalSpring.FORCE_FUNCTIONS = Spring.FORCE_FUNCTIONS;
27.17371 +
27.17372 +    /**
27.17373 +     * Adds a torque force to a physics body's torque accumulator.
27.17374 +     *
27.17375 +     * @method applyForce
27.17376 +     * @param targets {Array.Body} Array of bodies to apply torque to.
27.17377 +     */
27.17378 +    RotationalSpring.prototype.applyForce = function applyForce(targets) {
27.17379 +        var force        = this.force;
27.17380 +        var options      = this.options;
27.17381 +        var disp         = this.disp;
27.17382 +
27.17383 +        var stiffness    = options.stiffness;
27.17384 +        var damping      = options.damping;
27.17385 +        var restLength   = options.length;
27.17386 +        var anchor       = options.anchor;
27.17387 +
27.17388 +        for (var i = 0; i < targets.length; i++) {
27.17389 +            var target = targets[i];
27.17390 +
27.17391 +            disp.set(anchor.sub(target.orientation));
27.17392 +            var dist = disp.norm() - restLength;
27.17393 +
27.17394 +            if (dist === 0) return;
27.17395 +
27.17396 +            //if dampingRatio specified, then override strength and damping
27.17397 +            var m      = target.mass;
27.17398 +            stiffness *= m;
27.17399 +            damping   *= m;
27.17400 +
27.17401 +            force.set(disp.normalize(stiffness * this.forceFunction(dist, this.options.lMax)));
27.17402 +
27.17403 +            if (damping) force.set(force.add(target.angularVelocity.mult(-damping)));
27.17404 +
27.17405 +            target.applyTorque(force);
27.17406 +        }
27.17407 +    };
27.17408 +
27.17409 +    /**
27.17410 +     * Calculates the potential energy of the rotational spring.
27.17411 +     *
27.17412 +     * @method getEnergy
27.17413 +     * @param {Body} target The physics body attached to the spring
27.17414 +     */
27.17415 +    RotationalSpring.prototype.getEnergy = function getEnergy(target) {
27.17416 +        var options     = this.options;
27.17417 +        var restLength  = options.length;
27.17418 +        var anchor      = options.anchor;
27.17419 +        var strength    = options.stiffness;
27.17420 +
27.17421 +        var dist = anchor.sub(target.orientation).norm() - restLength;
27.17422 +        return 0.5 * strength * dist * dist;
27.17423 +    };
27.17424 +
27.17425 +    module.exports = RotationalSpring;
27.17426 +});
27.17427 +
27.17428 +/* This Source Code Form is subject to the terms of the Mozilla Public
27.17429 + * License, v. 2.0. If a copy of the MPL was not distributed with this
27.17430 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27.17431 + *
27.17432 + * Owner: david@famo.us
27.17433 + * @license MPL 2.0
27.17434 + * @copyright Famous Industries, Inc. 2014
27.17435 + */
27.17436 +
27.17437 +define('famous/physics/forces/VectorField',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
27.17438 +    var Force = require('./Force');
27.17439 +    var Vector = require('famous/math/Vector');
27.17440 +
27.17441 +    /**
27.17442 +     *  A force that moves a physics body to a location with a spring motion.
27.17443 +     *    The body can be moved to another physics body, or an anchor point.
27.17444 +     *
27.17445 +     *  @class VectorField
27.17446 +     *  @constructor
27.17447 +     *  @extends Force
27.17448 +     *  @param {Object} options options to set on drag
27.17449 +     */
27.17450 +    function VectorField(options) {
27.17451 +        this.options = Object.create(VectorField.DEFAULT_OPTIONS);
27.17452 +        if (options) this.setOptions(options);
27.17453 +
27.17454 +        _setFieldOptions.call(this, this.options.field);
27.17455 +        Force.call(this);
27.17456 +
27.17457 +        //registers
27.17458 +        this.evaluation = new Vector(0,0,0);
27.17459 +    }
27.17460 +
27.17461 +    VectorField.prototype = Object.create(Force.prototype);
27.17462 +    VectorField.prototype.constructor = VectorField;
27.17463 +
27.17464 +    /**
27.17465 +     * @property Spring.FORCE_FUNCTIONS
27.17466 +     * @type Object
27.17467 +     * @protected
27.17468 +     * @static
27.17469 +     */
27.17470 +    VectorField.FIELDS = {
27.17471 +        /**
27.17472 +         * Constant force, e.g., gravity
27.17473 +         * @attribute CONSTANT
27.17474 +         * @type Function
27.17475 +         * @param v {Vector}        Current position of physics body
27.17476 +         * @param options {Object}  The direction of the force
27.17477 +         *      Pass a {direction : Vector} into the VectorField options
27.17478 +         * @return {Number} unscaled force
27.17479 +         */
27.17480 +        CONSTANT : function(v, options) {
27.17481 +            return v.set(options.direction);
27.17482 +        },
27.17483 +
27.17484 +        /**
27.17485 +         * Linear force
27.17486 +         * @attribute LINEAR
27.17487 +         * @type Function
27.17488 +         * @param v {Vector} Current position of physics body
27.17489 +         * @return {Number} unscaled force
27.17490 +         */
27.17491 +        LINEAR : function(v) {
27.17492 +            return v;
27.17493 +        },
27.17494 +
27.17495 +        /**
27.17496 +         * Radial force, e.g., Hookean spring
27.17497 +         * @attribute RADIAL
27.17498 +         * @type Function
27.17499 +         * @param v {Vector} Current position of physics body
27.17500 +         * @return {Number} unscaled force
27.17501 +         */
27.17502 +        RADIAL : function(v) {
27.17503 +            return v.set(v.mult(-1, v));
27.17504 +        },
27.17505 +
27.17506 +        /**
27.17507 +         * Spherical force
27.17508 +         * @attribute SPHERE_ATTRACTOR
27.17509 +         * @type Function
27.17510 +         * @param v {Vector}        Current position of physics body
27.17511 +         * @param options {Object}  An object with the radius of the sphere
27.17512 +         *      Pass a {radius : Number} into the VectorField options
27.17513 +         * @return {Number} unscaled force
27.17514 +         */
27.17515 +        SPHERE_ATTRACTOR : function(v, options) {
27.17516 +            return v.set(v.mult((options.radius - v.norm()) / v.norm()));
27.17517 +        },
27.17518 +
27.17519 +        /**
27.17520 +         * Point attractor force, e.g., Hookean spring with an anchor
27.17521 +         * @attribute POINT_ATTRACTOR
27.17522 +         * @type Function
27.17523 +         * @param v {Vector}        Current position of physics body
27.17524 +         * @param options {Object}  And object with the position of the attractor
27.17525 +         *      Pass a {position : Vector} into the VectorField options
27.17526 +         * @return {Number} unscaled force
27.17527 +         */
27.17528 +        POINT_ATTRACTOR : function(v, options) {
27.17529 +            return v.set(options.position.sub(v));
27.17530 +        }
27.17531 +    };
27.17532 +
27.17533 +    /**
27.17534 +     * @property VectorField.DEFAULT_OPTIONS
27.17535 +     * @type Object
27.17536 +     * @protected
27.17537 +     * @static
27.17538 +     */
27.17539 +    VectorField.DEFAULT_OPTIONS = {
27.17540 +
27.17541 +        /**
27.17542 +         * The strength of the force
27.17543 +         *    Range : [0, 10]
27.17544 +         * @attribute strength
27.17545 +         * @type Number
27.17546 +         * @default 1
27.17547 +         */
27.17548 +        strength : 1,
27.17549 +
27.17550 +        /**
27.17551 +         * Type of vectorfield
27.17552 +         *    Range : [0, 100]
27.17553 +         * @attribute field
27.17554 +         * @type Function
27.17555 +         */
27.17556 +        field : VectorField.FIELDS.CONSTANT
27.17557 +    };
27.17558 +
27.17559 +    /**
27.17560 +     * Basic options setter
27.17561 +     *
27.17562 +     * @method setOptions
27.17563 +     * @param {Objects} options
27.17564 +     */
27.17565 +    VectorField.prototype.setOptions = function setOptions(options) {
27.17566 +        for (var key in options) this.options[key] = options[key];
27.17567 +    };
27.17568 +
27.17569 +    function _setFieldOptions(field) {
27.17570 +        var FIELDS = VectorField.FIELDS;
27.17571 +
27.17572 +        switch (field) {
27.17573 +            case FIELDS.CONSTANT:
27.17574 +                if (!this.options.direction) this.options.direction = new Vector(0,1,0);
27.17575 +                break;
27.17576 +            case FIELDS.POINT_ATTRACTOR:
27.17577 +                if (!this.options.position) this.options.position = new Vector(0,0,0);
27.17578 +                break;
27.17579 +            case FIELDS.SPHERE_ATTRACTOR:
27.17580 +                if (!this.options.radius) this.options.radius = 1;
27.17581 +                break;
27.17582 +        }
27.17583 +    }
27.17584 +
27.17585 +    function _evaluate(v) {
27.17586 +        var evaluation = this.evaluation;
27.17587 +        var field = this.options.field;
27.17588 +        evaluation.set(v);
27.17589 +        return field(evaluation, this.options);
27.17590 +    }
27.17591 +
27.17592 +    /**
27.17593 +     * Adds the vectorfield's force to a physics body's force accumulator.
27.17594 +     *
27.17595 +     * @method applyForce
27.17596 +     * @param targets {Array.body} Array of bodies to apply force to.
27.17597 +     */
27.17598 +    VectorField.prototype.applyForce = function applyForce(targets) {
27.17599 +        var force = this.force;
27.17600 +        for (var i = 0; i < targets.length; i++) {
27.17601 +            var particle = targets[i];
27.17602 +            force.set(
27.17603 +                _evaluate.call(this, particle.position)
27.17604 +                .mult(particle.mass * this.options.strength)
27.17605 +            );
27.17606 +            particle.applyForce(force);
27.17607 +        }
27.17608 +    };
27.17609 +
27.17610 +    module.exports = VectorField;
27.17611 +});
27.17612 +
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/famous_styles.css	Sun Jul 06 12:02:12 2014 -0700
    28.3 @@ -0,0 +1,163 @@
    28.4 +body {
    28.5 +  color: #404040;
    28.6 +  background-color: #f2f2f0;
    28.7 +}
    28.8 +
    28.9 +.main {
   28.10 +  background-color: white;
   28.11 +}
   28.12 +
   28.13 +a {
   28.14 +  color: #fa5c4f;
   28.15 +}
   28.16 +
   28.17 +.red {
   28.18 +  color: #fa5c4f;
   28.19 +}
   28.20 +
   28.21 +.light-grey {
   28.22 +  color: #f2f2f0;
   28.23 +}
   28.24 +
   28.25 +.medium-grey {
   28.26 +  color: #878785;
   28.27 +}
   28.28 +
   28.29 +.red-bg {
   28.30 +  color: white;
   28.31 +  background-color: #fa5c4f;
   28.32 +}
   28.33 +
   28.34 +.red-outline {
   28.35 +  border: 2px solid #fa5c4f;
   28.36 +}
   28.37 +
   28.38 +.grey-bg {
   28.39 +  background-color: #404040;
   28.40 +  color: white;
   28.41 +}
   28.42 +
   28.43 +.spacer-line {
   28.44 +  border-top: 1px solid #fa5c4f;
   28.45 +}
   28.46 +
   28.47 +.white-bg {
   28.48 +  background-color: white;
   28.49 +}
   28.50 +
   28.51 +@font-face {
   28.52 +  font-family: "Avenir Next W04 Demi";
   28.53 +  src: url("fonts/7adddd91-84e0-4423-b40e-61945189916d.eot") format("eot"), url("fonts/b0908846-3d5c-4768-af33-5f968b1da156.woff") format("woff"), url("fonts/fe1602be-28ca-467e-9cd3-7bfc586f31bc.ttf") format("truetype");
   28.54 +}
   28.55 +
   28.56 +@font-face {
   28.57 +  font-family: "AvenirNextLTW02-Regular";
   28.58 +  src: url("fonts/7a1b7ae7-5c29-481f-83ac-652e932c5509.eot") format("eot"), url("fonts/3a42a252-67ff-4186-88cf-762f56719ca1.woff") format("woff"), url("fonts/dbc39ae3-2636-4653-a23e-8938bce2cf51.ttf") format("truetype");
   28.59 +}
   28.60 +
   28.61 +input:focus {
   28.62 +  border: 1px solid #fa5c4f;
   28.63 +}
   28.64 +
   28.65 +input:hover {
   28.66 +  border: 1px solid #404040;
   28.67 +}
   28.68 +
   28.69 +input {
   28.70 +  outline: 0px;
   28.71 +  border-radius: 5px;
   28.72 +  border: 1px solid #f2f2f0;
   28.73 +  padding: 18px;
   28.74 +}
   28.75 +
   28.76 +body, input {
   28.77 +  font-family: "AvenirNextLTW02-Regular", sans-serif;
   28.78 +  font-size: 16px;
   28.79 +  line-height: 25px;
   28.80 +}
   28.81 +
   28.82 +h1 {
   28.83 +  font-size: 67px;
   28.84 +  line-height: 109px;
   28.85 +  margin-bottom: 67px;
   28.86 +}
   28.87 +
   28.88 +h2 {
   28.89 +  font-size: 41px;
   28.90 +  line-height: 67px;
   28.91 +  margin-bottom: 41px;
   28.92 +}
   28.93 +
   28.94 +h3 {
   28.95 +  font-size: 25px;
   28.96 +  line-height: 41px;
   28.97 +  margin-bottom: 25px;
   28.98 +}
   28.99 +
  28.100 +h4 {
  28.101 +  font-family: "Avenir Next W04 Demi";
  28.102 +}
  28.103 +
  28.104 +h4, h5, h6, p, li, a {
  28.105 +  font-size: 16px;
  28.106 +  line-height: 25px;
  28.107 +}
  28.108 +
  28.109 +h1, h2, h3, h4, h5, h6 {
  28.110 +  max-width: 845px;
  28.111 +}
  28.112 +
  28.113 +p {
  28.114 +  max-width: 522px;
  28.115 +}
  28.116 +
  28.117 +h5 {
  28.118 +  text-transform: uppercase;
  28.119 +}
  28.120 +
  28.121 +a {
  28.122 +  text-decoration: none;
  28.123 +}
  28.124 +
  28.125 +a:hover {
  28.126 +  text-decoration: underline;
  28.127 +}
  28.128 +
  28.129 +pre {
  28.130 +  font-family: monospace;
  28.131 +  width: 100%;
  28.132 +  background-color: #404040;
  28.133 +  border-radius: 5px;
  28.134 +  padding: 27px 18px;
  28.135 +  overflow-x: scroll;
  28.136 +}
  28.137 +
  28.138 +ul {
  28.139 +  margin-left: 25px;
  28.140 +}
  28.141 +
  28.142 +code {
  28.143 +  width: 100%;
  28.144 +}
  28.145 +
  28.146 +p, pre, ul {
  28.147 +  margin-bottom: 25px;
  28.148 +}
  28.149 +
  28.150 +small {
  28.151 +  font-size: 9px;
  28.152 +  line-height: 9px;
  28.153 +}
  28.154 +
  28.155 +.button {
  28.156 +  padding: 18px;
  28.157 +  border-radius: 3px;
  28.158 +  margin: 29px 0px;
  28.159 +}
  28.160 +
  28.161 +.backface-visible {
  28.162 +  backface-visibility: visible;
  28.163 +  -webkit-backface-visibility: visible;
  28.164 +  -moz-backface-visibility: visible;
  28.165 +  -ms-backface-visibility: visible;
  28.166 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/functionPrototypeBind.js	Sun Jul 06 12:02:12 2014 -0700
    29.3 @@ -0,0 +1,23 @@
    29.4 +if (!Function.prototype.bind) {
    29.5 +    Function.prototype.bind = function (oThis) {
    29.6 +        if (typeof this !== "function") {
    29.7 +            // closest thing possible to the ECMAScript 5 internal IsCallable function
    29.8 +            throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    29.9 +        }
   29.10 +
   29.11 +        var aArgs = Array.prototype.slice.call(arguments, 1), 
   29.12 +        fToBind = this, 
   29.13 +        fNOP = function () {},
   29.14 +        fBound = function () {
   29.15 +            return fToBind.apply(this instanceof fNOP && oThis
   29.16 +                ? this
   29.17 +                : oThis,
   29.18 +                aArgs.concat(Array.prototype.slice.call(arguments)));
   29.19 +        };
   29.20 +
   29.21 +        fNOP.prototype = this.prototype;
   29.22 +        fBound.prototype = new fNOP();
   29.23 +
   29.24 +        return fBound;
   29.25 +    };
   29.26 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/jquery.min.js	Sun Jul 06 12:02:12 2014 -0700
    30.3 @@ -0,0 +1,4 @@
    30.4 +/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
    30.5 +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
    30.6 +if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"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){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
    30.7 +},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
    30.8 \ No newline at end of file
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/requestAnimationFrame.js	Sun Jul 06 12:02:12 2014 -0700
    31.3 @@ -0,0 +1,13 @@
    31.4 +// adds requestAnimationFrame functionality
    31.5 +// Source: http://strd6.com/2011/05/better-window-requestanimationframe-shim/
    31.6 +
    31.7 +window.requestAnimationFrame || (window.requestAnimationFrame = 
    31.8 +  window.webkitRequestAnimationFrame || 
    31.9 +  window.mozRequestAnimationFrame    || 
   31.10 +  window.oRequestAnimationFrame      || 
   31.11 +  window.msRequestAnimationFrame     || 
   31.12 +  function(callback, element) {
   31.13 +    return window.setTimeout(function() {
   31.14 +      callback(+new Date());
   31.15 +  }, 1000 / 60);
   31.16 +});
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/lib/require.js	Sun Jul 06 12:02:12 2014 -0700
    32.3 @@ -0,0 +1,2076 @@
    32.4 +/** vim: et:ts=4:sw=4:sts=4
    32.5 + * @license RequireJS 2.1.14 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
    32.6 + * Available via the MIT or new BSD license.
    32.7 + * see: http://github.com/jrburke/requirejs for details
    32.8 + */
    32.9 +//Not using strict: uneven strict support in browsers, #392, and causes
   32.10 +//problems with requirejs.exec()/transpiler plugins that may not be strict.
   32.11 +/*jslint regexp: true, nomen: true, sloppy: true */
   32.12 +/*global window, navigator, document, importScripts, setTimeout, opera */
   32.13 +
   32.14 +var requirejs, require, define;
   32.15 +(function (global) {
   32.16 +    var req, s, head, baseElement, dataMain, src,
   32.17 +        interactiveScript, currentlyAddingScript, mainScript, subPath,
   32.18 +        version = '2.1.14',
   32.19 +        commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
   32.20 +        cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
   32.21 +        jsSuffixRegExp = /\.js$/,
   32.22 +        currDirRegExp = /^\.\//,
   32.23 +        op = Object.prototype,
   32.24 +        ostring = op.toString,
   32.25 +        hasOwn = op.hasOwnProperty,
   32.26 +        ap = Array.prototype,
   32.27 +        apsp = ap.splice,
   32.28 +        isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
   32.29 +        isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
   32.30 +        //PS3 indicates loaded and complete, but need to wait for complete
   32.31 +        //specifically. Sequence is 'loading', 'loaded', execution,
   32.32 +        // then 'complete'. The UA check is unfortunate, but not sure how
   32.33 +        //to feature test w/o causing perf issues.
   32.34 +        readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
   32.35 +                      /^complete$/ : /^(complete|loaded)$/,
   32.36 +        defContextName = '_',
   32.37 +        //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
   32.38 +        isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
   32.39 +        contexts = {},
   32.40 +        cfg = {},
   32.41 +        globalDefQueue = [],
   32.42 +        useInteractive = false;
   32.43 +
   32.44 +    function isFunction(it) {
   32.45 +        return ostring.call(it) === '[object Function]';
   32.46 +    }
   32.47 +
   32.48 +    function isArray(it) {
   32.49 +        return ostring.call(it) === '[object Array]';
   32.50 +    }
   32.51 +
   32.52 +    /**
   32.53 +     * Helper function for iterating over an array. If the func returns
   32.54 +     * a true value, it will break out of the loop.
   32.55 +     */
   32.56 +    function each(ary, func) {
   32.57 +        if (ary) {
   32.58 +            var i;
   32.59 +            for (i = 0; i < ary.length; i += 1) {
   32.60 +                if (ary[i] && func(ary[i], i, ary)) {
   32.61 +                    break;
   32.62 +                }
   32.63 +            }
   32.64 +        }
   32.65 +    }
   32.66 +
   32.67 +    /**
   32.68 +     * Helper function for iterating over an array backwards. If the func
   32.69 +     * returns a true value, it will break out of the loop.
   32.70 +     */
   32.71 +    function eachReverse(ary, func) {
   32.72 +        if (ary) {
   32.73 +            var i;
   32.74 +            for (i = ary.length - 1; i > -1; i -= 1) {
   32.75 +                if (ary[i] && func(ary[i], i, ary)) {
   32.76 +                    break;
   32.77 +                }
   32.78 +            }
   32.79 +        }
   32.80 +    }
   32.81 +
   32.82 +    function hasProp(obj, prop) {
   32.83 +        return hasOwn.call(obj, prop);
   32.84 +    }
   32.85 +
   32.86 +    function getOwn(obj, prop) {
   32.87 +        return hasProp(obj, prop) && obj[prop];
   32.88 +    }
   32.89 +
   32.90 +    /**
   32.91 +     * Cycles over properties in an object and calls a function for each
   32.92 +     * property value. If the function returns a truthy value, then the
   32.93 +     * iteration is stopped.
   32.94 +     */
   32.95 +    function eachProp(obj, func) {
   32.96 +        var prop;
   32.97 +        for (prop in obj) {
   32.98 +            if (hasProp(obj, prop)) {
   32.99 +                if (func(obj[prop], prop)) {
  32.100 +                    break;
  32.101 +                }
  32.102 +            }
  32.103 +        }
  32.104 +    }
  32.105 +
  32.106 +    /**
  32.107 +     * Simple function to mix in properties from source into target,
  32.108 +     * but only if target does not already have a property of the same name.
  32.109 +     */
  32.110 +    function mixin(target, source, force, deepStringMixin) {
  32.111 +        if (source) {
  32.112 +            eachProp(source, function (value, prop) {
  32.113 +                if (force || !hasProp(target, prop)) {
  32.114 +                    if (deepStringMixin && typeof value === 'object' && value &&
  32.115 +                        !isArray(value) && !isFunction(value) &&
  32.116 +                        !(value instanceof RegExp)) {
  32.117 +
  32.118 +                        if (!target[prop]) {
  32.119 +                            target[prop] = {};
  32.120 +                        }
  32.121 +                        mixin(target[prop], value, force, deepStringMixin);
  32.122 +                    } else {
  32.123 +                        target[prop] = value;
  32.124 +                    }
  32.125 +                }
  32.126 +            });
  32.127 +        }
  32.128 +        return target;
  32.129 +    }
  32.130 +
  32.131 +    //Similar to Function.prototype.bind, but the 'this' object is specified
  32.132 +    //first, since it is easier to read/figure out what 'this' will be.
  32.133 +    function bind(obj, fn) {
  32.134 +        return function () {
  32.135 +            return fn.apply(obj, arguments);
  32.136 +        };
  32.137 +    }
  32.138 +
  32.139 +    function scripts() {
  32.140 +        return document.getElementsByTagName('script');
  32.141 +    }
  32.142 +
  32.143 +    function defaultOnError(err) {
  32.144 +        throw err;
  32.145 +    }
  32.146 +
  32.147 +    //Allow getting a global that is expressed in
  32.148 +    //dot notation, like 'a.b.c'.
  32.149 +    function getGlobal(value) {
  32.150 +        if (!value) {
  32.151 +            return value;
  32.152 +        }
  32.153 +        var g = global;
  32.154 +        each(value.split('.'), function (part) {
  32.155 +            g = g[part];
  32.156 +        });
  32.157 +        return g;
  32.158 +    }
  32.159 +
  32.160 +    /**
  32.161 +     * Constructs an error with a pointer to an URL with more information.
  32.162 +     * @param {String} id the error ID that maps to an ID on a web page.
  32.163 +     * @param {String} message human readable error.
  32.164 +     * @param {Error} [err] the original error, if there is one.
  32.165 +     *
  32.166 +     * @returns {Error}
  32.167 +     */
  32.168 +    function makeError(id, msg, err, requireModules) {
  32.169 +        var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
  32.170 +        e.requireType = id;
  32.171 +        e.requireModules = requireModules;
  32.172 +        if (err) {
  32.173 +            e.originalError = err;
  32.174 +        }
  32.175 +        return e;
  32.176 +    }
  32.177 +
  32.178 +    if (typeof define !== 'undefined') {
  32.179 +        //If a define is already in play via another AMD loader,
  32.180 +        //do not overwrite.
  32.181 +        return;
  32.182 +    }
  32.183 +
  32.184 +    if (typeof requirejs !== 'undefined') {
  32.185 +        if (isFunction(requirejs)) {
  32.186 +            //Do not overwrite an existing requirejs instance.
  32.187 +            return;
  32.188 +        }
  32.189 +        cfg = requirejs;
  32.190 +        requirejs = undefined;
  32.191 +    }
  32.192 +
  32.193 +    //Allow for a require config object
  32.194 +    if (typeof require !== 'undefined' && !isFunction(require)) {
  32.195 +        //assume it is a config object.
  32.196 +        cfg = require;
  32.197 +        require = undefined;
  32.198 +    }
  32.199 +
  32.200 +    function newContext(contextName) {
  32.201 +        var inCheckLoaded, Module, context, handlers,
  32.202 +            checkLoadedTimeoutId,
  32.203 +            config = {
  32.204 +                //Defaults. Do not set a default for map
  32.205 +                //config to speed up normalize(), which
  32.206 +                //will run faster if there is no default.
  32.207 +                waitSeconds: 7,
  32.208 +                baseUrl: './',
  32.209 +                paths: {},
  32.210 +                bundles: {},
  32.211 +                pkgs: {},
  32.212 +                shim: {},
  32.213 +                config: {}
  32.214 +            },
  32.215 +            registry = {},
  32.216 +            //registry of just enabled modules, to speed
  32.217 +            //cycle breaking code when lots of modules
  32.218 +            //are registered, but not activated.
  32.219 +            enabledRegistry = {},
  32.220 +            undefEvents = {},
  32.221 +            defQueue = [],
  32.222 +            defined = {},
  32.223 +            urlFetched = {},
  32.224 +            bundlesMap = {},
  32.225 +            requireCounter = 1,
  32.226 +            unnormalizedCounter = 1;
  32.227 +
  32.228 +        /**
  32.229 +         * Trims the . and .. from an array of path segments.
  32.230 +         * It will keep a leading path segment if a .. will become
  32.231 +         * the first path segment, to help with module name lookups,
  32.232 +         * which act like paths, but can be remapped. But the end result,
  32.233 +         * all paths that use this function should look normalized.
  32.234 +         * NOTE: this method MODIFIES the input array.
  32.235 +         * @param {Array} ary the array of path segments.
  32.236 +         */
  32.237 +        function trimDots(ary) {
  32.238 +            var i, part;
  32.239 +            for (i = 0; i < ary.length; i++) {
  32.240 +                part = ary[i];
  32.241 +                if (part === '.') {
  32.242 +                    ary.splice(i, 1);
  32.243 +                    i -= 1;
  32.244 +                } else if (part === '..') {
  32.245 +                    // If at the start, or previous value is still ..,
  32.246 +                    // keep them so that when converted to a path it may
  32.247 +                    // still work when converted to a path, even though
  32.248 +                    // as an ID it is less than ideal. In larger point
  32.249 +                    // releases, may be better to just kick out an error.
  32.250 +                    if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') {
  32.251 +                        continue;
  32.252 +                    } else if (i > 0) {
  32.253 +                        ary.splice(i - 1, 2);
  32.254 +                        i -= 2;
  32.255 +                    }
  32.256 +                }
  32.257 +            }
  32.258 +        }
  32.259 +
  32.260 +        /**
  32.261 +         * Given a relative module name, like ./something, normalize it to
  32.262 +         * a real name that can be mapped to a path.
  32.263 +         * @param {String} name the relative name
  32.264 +         * @param {String} baseName a real name that the name arg is relative
  32.265 +         * to.
  32.266 +         * @param {Boolean} applyMap apply the map config to the value. Should
  32.267 +         * only be done if this normalization is for a dependency ID.
  32.268 +         * @returns {String} normalized name
  32.269 +         */
  32.270 +        function normalize(name, baseName, applyMap) {
  32.271 +            var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
  32.272 +                foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
  32.273 +                baseParts = (baseName && baseName.split('/')),
  32.274 +                map = config.map,
  32.275 +                starMap = map && map['*'];
  32.276 +
  32.277 +            //Adjust any relative paths.
  32.278 +            if (name) {
  32.279 +                name = name.split('/');
  32.280 +                lastIndex = name.length - 1;
  32.281 +
  32.282 +                // If wanting node ID compatibility, strip .js from end
  32.283 +                // of IDs. Have to do this here, and not in nameToUrl
  32.284 +                // because node allows either .js or non .js to map
  32.285 +                // to same file.
  32.286 +                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
  32.287 +                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
  32.288 +                }
  32.289 +
  32.290 +                // Starts with a '.' so need the baseName
  32.291 +                if (name[0].charAt(0) === '.' && baseParts) {
  32.292 +                    //Convert baseName to array, and lop off the last part,
  32.293 +                    //so that . matches that 'directory' and not name of the baseName's
  32.294 +                    //module. For instance, baseName of 'one/two/three', maps to
  32.295 +                    //'one/two/three.js', but we want the directory, 'one/two' for
  32.296 +                    //this normalization.
  32.297 +                    normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
  32.298 +                    name = normalizedBaseParts.concat(name);
  32.299 +                }
  32.300 +
  32.301 +                trimDots(name);
  32.302 +                name = name.join('/');
  32.303 +            }
  32.304 +
  32.305 +            //Apply map config if available.
  32.306 +            if (applyMap && map && (baseParts || starMap)) {
  32.307 +                nameParts = name.split('/');
  32.308 +
  32.309 +                outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
  32.310 +                    nameSegment = nameParts.slice(0, i).join('/');
  32.311 +
  32.312 +                    if (baseParts) {
  32.313 +                        //Find the longest baseName segment match in the config.
  32.314 +                        //So, do joins on the biggest to smallest lengths of baseParts.
  32.315 +                        for (j = baseParts.length; j > 0; j -= 1) {
  32.316 +                            mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
  32.317 +
  32.318 +                            //baseName segment has config, find if it has one for
  32.319 +                            //this name.
  32.320 +                            if (mapValue) {
  32.321 +                                mapValue = getOwn(mapValue, nameSegment);
  32.322 +                                if (mapValue) {
  32.323 +                                    //Match, update name to the new value.
  32.324 +                                    foundMap = mapValue;
  32.325 +                                    foundI = i;
  32.326 +                                    break outerLoop;
  32.327 +                                }
  32.328 +                            }
  32.329 +                        }
  32.330 +                    }
  32.331 +
  32.332 +                    //Check for a star map match, but just hold on to it,
  32.333 +                    //if there is a shorter segment match later in a matching
  32.334 +                    //config, then favor over this star map.
  32.335 +                    if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
  32.336 +                        foundStarMap = getOwn(starMap, nameSegment);
  32.337 +                        starI = i;
  32.338 +                    }
  32.339 +                }
  32.340 +
  32.341 +                if (!foundMap && foundStarMap) {
  32.342 +                    foundMap = foundStarMap;
  32.343 +                    foundI = starI;
  32.344 +                }
  32.345 +
  32.346 +                if (foundMap) {
  32.347 +                    nameParts.splice(0, foundI, foundMap);
  32.348 +                    name = nameParts.join('/');
  32.349 +                }
  32.350 +            }
  32.351 +
  32.352 +            // If the name points to a package's name, use
  32.353 +            // the package main instead.
  32.354 +            pkgMain = getOwn(config.pkgs, name);
  32.355 +
  32.356 +            return pkgMain ? pkgMain : name;
  32.357 +        }
  32.358 +
  32.359 +        function removeScript(name) {
  32.360 +            if (isBrowser) {
  32.361 +                each(scripts(), function (scriptNode) {
  32.362 +                    if (scriptNode.getAttribute('data-requiremodule') === name &&
  32.363 +                            scriptNode.getAttribute('data-requirecontext') === context.contextName) {
  32.364 +                        scriptNode.parentNode.removeChild(scriptNode);
  32.365 +                        return true;
  32.366 +                    }
  32.367 +                });
  32.368 +            }
  32.369 +        }
  32.370 +
  32.371 +        function hasPathFallback(id) {
  32.372 +            var pathConfig = getOwn(config.paths, id);
  32.373 +            if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
  32.374 +                //Pop off the first array value, since it failed, and
  32.375 +                //retry
  32.376 +                pathConfig.shift();
  32.377 +                context.require.undef(id);
  32.378 +
  32.379 +                //Custom require that does not do map translation, since
  32.380 +                //ID is "absolute", already mapped/resolved.
  32.381 +                context.makeRequire(null, {
  32.382 +                    skipMap: true
  32.383 +                })([id]);
  32.384 +
  32.385 +                return true;
  32.386 +            }
  32.387 +        }
  32.388 +
  32.389 +        //Turns a plugin!resource to [plugin, resource]
  32.390 +        //with the plugin being undefined if the name
  32.391 +        //did not have a plugin prefix.
  32.392 +        function splitPrefix(name) {
  32.393 +            var prefix,
  32.394 +                index = name ? name.indexOf('!') : -1;
  32.395 +            if (index > -1) {
  32.396 +                prefix = name.substring(0, index);
  32.397 +                name = name.substring(index + 1, name.length);
  32.398 +            }
  32.399 +            return [prefix, name];
  32.400 +        }
  32.401 +
  32.402 +        /**
  32.403 +         * Creates a module mapping that includes plugin prefix, module
  32.404 +         * name, and path. If parentModuleMap is provided it will
  32.405 +         * also normalize the name via require.normalize()
  32.406 +         *
  32.407 +         * @param {String} name the module name
  32.408 +         * @param {String} [parentModuleMap] parent module map
  32.409 +         * for the module name, used to resolve relative names.
  32.410 +         * @param {Boolean} isNormalized: is the ID already normalized.
  32.411 +         * This is true if this call is done for a define() module ID.
  32.412 +         * @param {Boolean} applyMap: apply the map config to the ID.
  32.413 +         * Should only be true if this map is for a dependency.
  32.414 +         *
  32.415 +         * @returns {Object}
  32.416 +         */
  32.417 +        function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
  32.418 +            var url, pluginModule, suffix, nameParts,
  32.419 +                prefix = null,
  32.420 +                parentName = parentModuleMap ? parentModuleMap.name : null,
  32.421 +                originalName = name,
  32.422 +                isDefine = true,
  32.423 +                normalizedName = '';
  32.424 +
  32.425 +            //If no name, then it means it is a require call, generate an
  32.426 +            //internal name.
  32.427 +            if (!name) {
  32.428 +                isDefine = false;
  32.429 +                name = '_@r' + (requireCounter += 1);
  32.430 +            }
  32.431 +
  32.432 +            nameParts = splitPrefix(name);
  32.433 +            prefix = nameParts[0];
  32.434 +            name = nameParts[1];
  32.435 +
  32.436 +            if (prefix) {
  32.437 +                prefix = normalize(prefix, parentName, applyMap);
  32.438 +                pluginModule = getOwn(defined, prefix);
  32.439 +            }
  32.440 +
  32.441 +            //Account for relative paths if there is a base name.
  32.442 +            if (name) {
  32.443 +                if (prefix) {
  32.444 +                    if (pluginModule && pluginModule.normalize) {
  32.445 +                        //Plugin is loaded, use its normalize method.
  32.446 +                        normalizedName = pluginModule.normalize(name, function (name) {
  32.447 +                            return normalize(name, parentName, applyMap);
  32.448 +                        });
  32.449 +                    } else {
  32.450 +                        // If nested plugin references, then do not try to
  32.451 +                        // normalize, as it will not normalize correctly. This
  32.452 +                        // places a restriction on resourceIds, and the longer
  32.453 +                        // term solution is not to normalize until plugins are
  32.454 +                        // loaded and all normalizations to allow for async
  32.455 +                        // loading of a loader plugin. But for now, fixes the
  32.456 +                        // common uses. Details in #1131
  32.457 +                        normalizedName = name.indexOf('!') === -1 ?
  32.458 +                                         normalize(name, parentName, applyMap) :
  32.459 +                                         name;
  32.460 +                    }
  32.461 +                } else {
  32.462 +                    //A regular module.
  32.463 +                    normalizedName = normalize(name, parentName, applyMap);
  32.464 +
  32.465 +                    //Normalized name may be a plugin ID due to map config
  32.466 +                    //application in normalize. The map config values must
  32.467 +                    //already be normalized, so do not need to redo that part.
  32.468 +                    nameParts = splitPrefix(normalizedName);
  32.469 +                    prefix = nameParts[0];
  32.470 +                    normalizedName = nameParts[1];
  32.471 +                    isNormalized = true;
  32.472 +
  32.473 +                    url = context.nameToUrl(normalizedName);
  32.474 +                }
  32.475 +            }
  32.476 +
  32.477 +            //If the id is a plugin id that cannot be determined if it needs
  32.478 +            //normalization, stamp it with a unique ID so two matching relative
  32.479 +            //ids that may conflict can be separate.
  32.480 +            suffix = prefix && !pluginModule && !isNormalized ?
  32.481 +                     '_unnormalized' + (unnormalizedCounter += 1) :
  32.482 +                     '';
  32.483 +
  32.484 +            return {
  32.485 +                prefix: prefix,
  32.486 +                name: normalizedName,
  32.487 +                parentMap: parentModuleMap,
  32.488 +                unnormalized: !!suffix,
  32.489 +                url: url,
  32.490 +                originalName: originalName,
  32.491 +                isDefine: isDefine,
  32.492 +                id: (prefix ?
  32.493 +                        prefix + '!' + normalizedName :
  32.494 +                        normalizedName) + suffix
  32.495 +            };
  32.496 +        }
  32.497 +
  32.498 +        function getModule(depMap) {
  32.499 +            var id = depMap.id,
  32.500 +                mod = getOwn(registry, id);
  32.501 +
  32.502 +            if (!mod) {
  32.503 +                mod = registry[id] = new context.Module(depMap);
  32.504 +            }
  32.505 +
  32.506 +            return mod;
  32.507 +        }
  32.508 +
  32.509 +        function on(depMap, name, fn) {
  32.510 +            var id = depMap.id,
  32.511 +                mod = getOwn(registry, id);
  32.512 +
  32.513 +            if (hasProp(defined, id) &&
  32.514 +                    (!mod || mod.defineEmitComplete)) {
  32.515 +                if (name === 'defined') {
  32.516 +                    fn(defined[id]);
  32.517 +                }
  32.518 +            } else {
  32.519 +                mod = getModule(depMap);
  32.520 +                if (mod.error && name === 'error') {
  32.521 +                    fn(mod.error);
  32.522 +                } else {
  32.523 +                    mod.on(name, fn);
  32.524 +                }
  32.525 +            }
  32.526 +        }
  32.527 +
  32.528 +        function onError(err, errback) {
  32.529 +            var ids = err.requireModules,
  32.530 +                notified = false;
  32.531 +
  32.532 +            if (errback) {
  32.533 +                errback(err);
  32.534 +            } else {
  32.535 +                each(ids, function (id) {
  32.536 +                    var mod = getOwn(registry, id);
  32.537 +                    if (mod) {
  32.538 +                        //Set error on module, so it skips timeout checks.
  32.539 +                        mod.error = err;
  32.540 +                        if (mod.events.error) {
  32.541 +                            notified = true;
  32.542 +                            mod.emit('error', err);
  32.543 +                        }
  32.544 +                    }
  32.545 +                });
  32.546 +
  32.547 +                if (!notified) {
  32.548 +                    req.onError(err);
  32.549 +                }
  32.550 +            }
  32.551 +        }
  32.552 +
  32.553 +        /**
  32.554 +         * Internal method to transfer globalQueue items to this context's
  32.555 +         * defQueue.
  32.556 +         */
  32.557 +        function takeGlobalQueue() {
  32.558 +            //Push all the globalDefQueue items into the context's defQueue
  32.559 +            if (globalDefQueue.length) {
  32.560 +                //Array splice in the values since the context code has a
  32.561 +                //local var ref to defQueue, so cannot just reassign the one
  32.562 +                //on context.
  32.563 +                apsp.apply(defQueue,
  32.564 +                           [defQueue.length, 0].concat(globalDefQueue));
  32.565 +                globalDefQueue = [];
  32.566 +            }
  32.567 +        }
  32.568 +
  32.569 +        handlers = {
  32.570 +            'require': function (mod) {
  32.571 +                if (mod.require) {
  32.572 +                    return mod.require;
  32.573 +                } else {
  32.574 +                    return (mod.require = context.makeRequire(mod.map));
  32.575 +                }
  32.576 +            },
  32.577 +            'exports': function (mod) {
  32.578 +                mod.usingExports = true;
  32.579 +                if (mod.map.isDefine) {
  32.580 +                    if (mod.exports) {
  32.581 +                        return (defined[mod.map.id] = mod.exports);
  32.582 +                    } else {
  32.583 +                        return (mod.exports = defined[mod.map.id] = {});
  32.584 +                    }
  32.585 +                }
  32.586 +            },
  32.587 +            'module': function (mod) {
  32.588 +                if (mod.module) {
  32.589 +                    return mod.module;
  32.590 +                } else {
  32.591 +                    return (mod.module = {
  32.592 +                        id: mod.map.id,
  32.593 +                        uri: mod.map.url,
  32.594 +                        config: function () {
  32.595 +                            return  getOwn(config.config, mod.map.id) || {};
  32.596 +                        },
  32.597 +                        exports: mod.exports || (mod.exports = {})
  32.598 +                    });
  32.599 +                }
  32.600 +            }
  32.601 +        };
  32.602 +
  32.603 +        function cleanRegistry(id) {
  32.604 +            //Clean up machinery used for waiting modules.
  32.605 +            delete registry[id];
  32.606 +            delete enabledRegistry[id];
  32.607 +        }
  32.608 +
  32.609 +        function breakCycle(mod, traced, processed) {
  32.610 +            var id = mod.map.id;
  32.611 +
  32.612 +            if (mod.error) {
  32.613 +                mod.emit('error', mod.error);
  32.614 +            } else {
  32.615 +                traced[id] = true;
  32.616 +                each(mod.depMaps, function (depMap, i) {
  32.617 +                    var depId = depMap.id,
  32.618 +                        dep = getOwn(registry, depId);
  32.619 +
  32.620 +                    //Only force things that have not completed
  32.621 +                    //being defined, so still in the registry,
  32.622 +                    //and only if it has not been matched up
  32.623 +                    //in the module already.
  32.624 +                    if (dep && !mod.depMatched[i] && !processed[depId]) {
  32.625 +                        if (getOwn(traced, depId)) {
  32.626 +                            mod.defineDep(i, defined[depId]);
  32.627 +                            mod.check(); //pass false?
  32.628 +                        } else {
  32.629 +                            breakCycle(dep, traced, processed);
  32.630 +                        }
  32.631 +                    }
  32.632 +                });
  32.633 +                processed[id] = true;
  32.634 +            }
  32.635 +        }
  32.636 +
  32.637 +        function checkLoaded() {
  32.638 +            var err, usingPathFallback,
  32.639 +                waitInterval = config.waitSeconds * 1000,
  32.640 +                //It is possible to disable the wait interval by using waitSeconds of 0.
  32.641 +                expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
  32.642 +                noLoads = [],
  32.643 +                reqCalls = [],
  32.644 +                stillLoading = false,
  32.645 +                needCycleCheck = true;
  32.646 +
  32.647 +            //Do not bother if this call was a result of a cycle break.
  32.648 +            if (inCheckLoaded) {
  32.649 +                return;
  32.650 +            }
  32.651 +
  32.652 +            inCheckLoaded = true;
  32.653 +
  32.654 +            //Figure out the state of all the modules.
  32.655 +            eachProp(enabledRegistry, function (mod) {
  32.656 +                var map = mod.map,
  32.657 +                    modId = map.id;
  32.658 +
  32.659 +                //Skip things that are not enabled or in error state.
  32.660 +                if (!mod.enabled) {
  32.661 +                    return;
  32.662 +                }
  32.663 +
  32.664 +                if (!map.isDefine) {
  32.665 +                    reqCalls.push(mod);
  32.666 +                }
  32.667 +
  32.668 +                if (!mod.error) {
  32.669 +                    //If the module should be executed, and it has not
  32.670 +                    //been inited and time is up, remember it.
  32.671 +                    if (!mod.inited && expired) {
  32.672 +                        if (hasPathFallback(modId)) {
  32.673 +                            usingPathFallback = true;
  32.674 +                            stillLoading = true;
  32.675 +                        } else {
  32.676 +                            noLoads.push(modId);
  32.677 +                            removeScript(modId);
  32.678 +                        }
  32.679 +                    } else if (!mod.inited && mod.fetched && map.isDefine) {
  32.680 +                        stillLoading = true;
  32.681 +                        if (!map.prefix) {
  32.682 +                            //No reason to keep looking for unfinished
  32.683 +                            //loading. If the only stillLoading is a
  32.684 +                            //plugin resource though, keep going,
  32.685 +                            //because it may be that a plugin resource
  32.686 +                            //is waiting on a non-plugin cycle.
  32.687 +                            return (needCycleCheck = false);
  32.688 +                        }
  32.689 +                    }
  32.690 +                }
  32.691 +            });
  32.692 +
  32.693 +            if (expired && noLoads.length) {
  32.694 +                //If wait time expired, throw error of unloaded modules.
  32.695 +                err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
  32.696 +                err.contextName = context.contextName;
  32.697 +                return onError(err);
  32.698 +            }
  32.699 +
  32.700 +            //Not expired, check for a cycle.
  32.701 +            if (needCycleCheck) {
  32.702 +                each(reqCalls, function (mod) {
  32.703 +                    breakCycle(mod, {}, {});
  32.704 +                });
  32.705 +            }
  32.706 +
  32.707 +            //If still waiting on loads, and the waiting load is something
  32.708 +            //other than a plugin resource, or there are still outstanding
  32.709 +            //scripts, then just try back later.
  32.710 +            if ((!expired || usingPathFallback) && stillLoading) {
  32.711 +                //Something is still waiting to load. Wait for it, but only
  32.712 +                //if a timeout is not already in effect.
  32.713 +                if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
  32.714 +                    checkLoadedTimeoutId = setTimeout(function () {
  32.715 +                        checkLoadedTimeoutId = 0;
  32.716 +                        checkLoaded();
  32.717 +                    }, 50);
  32.718 +                }
  32.719 +            }
  32.720 +
  32.721 +            inCheckLoaded = false;
  32.722 +        }
  32.723 +
  32.724 +        Module = function (map) {
  32.725 +            this.events = getOwn(undefEvents, map.id) || {};
  32.726 +            this.map = map;
  32.727 +            this.shim = getOwn(config.shim, map.id);
  32.728 +            this.depExports = [];
  32.729 +            this.depMaps = [];
  32.730 +            this.depMatched = [];
  32.731 +            this.pluginMaps = {};
  32.732 +            this.depCount = 0;
  32.733 +
  32.734 +            /* this.exports this.factory
  32.735 +               this.depMaps = [],
  32.736 +               this.enabled, this.fetched
  32.737 +            */
  32.738 +        };
  32.739 +
  32.740 +        Module.prototype = {
  32.741 +            init: function (depMaps, factory, errback, options) {
  32.742 +                options = options || {};
  32.743 +
  32.744 +                //Do not do more inits if already done. Can happen if there
  32.745 +                //are multiple define calls for the same module. That is not
  32.746 +                //a normal, common case, but it is also not unexpected.
  32.747 +                if (this.inited) {
  32.748 +                    return;
  32.749 +                }
  32.750 +
  32.751 +                this.factory = factory;
  32.752 +
  32.753 +                if (errback) {
  32.754 +                    //Register for errors on this module.
  32.755 +                    this.on('error', errback);
  32.756 +                } else if (this.events.error) {
  32.757 +                    //If no errback already, but there are error listeners
  32.758 +                    //on this module, set up an errback to pass to the deps.
  32.759 +                    errback = bind(this, function (err) {
  32.760 +                        this.emit('error', err);
  32.761 +                    });
  32.762 +                }
  32.763 +
  32.764 +                //Do a copy of the dependency array, so that
  32.765 +                //source inputs are not modified. For example
  32.766 +                //"shim" deps are passed in here directly, and
  32.767 +                //doing a direct modification of the depMaps array
  32.768 +                //would affect that config.
  32.769 +                this.depMaps = depMaps && depMaps.slice(0);
  32.770 +
  32.771 +                this.errback = errback;
  32.772 +
  32.773 +                //Indicate this module has be initialized
  32.774 +                this.inited = true;
  32.775 +
  32.776 +                this.ignore = options.ignore;
  32.777 +
  32.778 +                //Could have option to init this module in enabled mode,
  32.779 +                //or could have been previously marked as enabled. However,
  32.780 +                //the dependencies are not known until init is called. So
  32.781 +                //if enabled previously, now trigger dependencies as enabled.
  32.782 +                if (options.enabled || this.enabled) {
  32.783 +                    //Enable this module and dependencies.
  32.784 +                    //Will call this.check()
  32.785 +                    this.enable();
  32.786 +                } else {
  32.787 +                    this.check();
  32.788 +                }
  32.789 +            },
  32.790 +
  32.791 +            defineDep: function (i, depExports) {
  32.792 +                //Because of cycles, defined callback for a given
  32.793 +                //export can be called more than once.
  32.794 +                if (!this.depMatched[i]) {
  32.795 +                    this.depMatched[i] = true;
  32.796 +                    this.depCount -= 1;
  32.797 +                    this.depExports[i] = depExports;
  32.798 +                }
  32.799 +            },
  32.800 +
  32.801 +            fetch: function () {
  32.802 +                if (this.fetched) {
  32.803 +                    return;
  32.804 +                }
  32.805 +                this.fetched = true;
  32.806 +
  32.807 +                context.startTime = (new Date()).getTime();
  32.808 +
  32.809 +                var map = this.map;
  32.810 +
  32.811 +                //If the manager is for a plugin managed resource,
  32.812 +                //ask the plugin to load it now.
  32.813 +                if (this.shim) {
  32.814 +                    context.makeRequire(this.map, {
  32.815 +                        enableBuildCallback: true
  32.816 +                    })(this.shim.deps || [], bind(this, function () {
  32.817 +                        return map.prefix ? this.callPlugin() : this.load();
  32.818 +                    }));
  32.819 +                } else {
  32.820 +                    //Regular dependency.
  32.821 +                    return map.prefix ? this.callPlugin() : this.load();
  32.822 +                }
  32.823 +            },
  32.824 +
  32.825 +            load: function () {
  32.826 +                var url = this.map.url;
  32.827 +
  32.828 +                //Regular dependency.
  32.829 +                if (!urlFetched[url]) {
  32.830 +                    urlFetched[url] = true;
  32.831 +                    context.load(this.map.id, url);
  32.832 +                }
  32.833 +            },
  32.834 +
  32.835 +            /**
  32.836 +             * Checks if the module is ready to define itself, and if so,
  32.837 +             * define it.
  32.838 +             */
  32.839 +            check: function () {
  32.840 +                if (!this.enabled || this.enabling) {
  32.841 +                    return;
  32.842 +                }
  32.843 +
  32.844 +                var err, cjsModule,
  32.845 +                    id = this.map.id,
  32.846 +                    depExports = this.depExports,
  32.847 +                    exports = this.exports,
  32.848 +                    factory = this.factory;
  32.849 +
  32.850 +                if (!this.inited) {
  32.851 +                    this.fetch();
  32.852 +                } else if (this.error) {
  32.853 +                    this.emit('error', this.error);
  32.854 +                } else if (!this.defining) {
  32.855 +                    //The factory could trigger another require call
  32.856 +                    //that would result in checking this module to
  32.857 +                    //define itself again. If already in the process
  32.858 +                    //of doing that, skip this work.
  32.859 +                    this.defining = true;
  32.860 +
  32.861 +                    if (this.depCount < 1 && !this.defined) {
  32.862 +                        if (isFunction(factory)) {
  32.863 +                            //If there is an error listener, favor passing
  32.864 +                            //to that instead of throwing an error. However,
  32.865 +                            //only do it for define()'d  modules. require
  32.866 +                            //errbacks should not be called for failures in
  32.867 +                            //their callbacks (#699). However if a global
  32.868 +                            //onError is set, use that.
  32.869 +                            if ((this.events.error && this.map.isDefine) ||
  32.870 +                                req.onError !== defaultOnError) {
  32.871 +                                try {
  32.872 +                                    exports = context.execCb(id, factory, depExports, exports);
  32.873 +                                } catch (e) {
  32.874 +                                    err = e;
  32.875 +                                }
  32.876 +                            } else {
  32.877 +                                exports = context.execCb(id, factory, depExports, exports);
  32.878 +                            }
  32.879 +
  32.880 +                            // Favor return value over exports. If node/cjs in play,
  32.881 +                            // then will not have a return value anyway. Favor
  32.882 +                            // module.exports assignment over exports object.
  32.883 +                            if (this.map.isDefine && exports === undefined) {
  32.884 +                                cjsModule = this.module;
  32.885 +                                if (cjsModule) {
  32.886 +                                    exports = cjsModule.exports;
  32.887 +                                } else if (this.usingExports) {
  32.888 +                                    //exports already set the defined value.
  32.889 +                                    exports = this.exports;
  32.890 +                                }
  32.891 +                            }
  32.892 +
  32.893 +                            if (err) {
  32.894 +                                err.requireMap = this.map;
  32.895 +                                err.requireModules = this.map.isDefine ? [this.map.id] : null;
  32.896 +                                err.requireType = this.map.isDefine ? 'define' : 'require';
  32.897 +                                return onError((this.error = err));
  32.898 +                            }
  32.899 +
  32.900 +                        } else {
  32.901 +                            //Just a literal value
  32.902 +                            exports = factory;
  32.903 +                        }
  32.904 +
  32.905 +                        this.exports = exports;
  32.906 +
  32.907 +                        if (this.map.isDefine && !this.ignore) {
  32.908 +                            defined[id] = exports;
  32.909 +
  32.910 +                            if (req.onResourceLoad) {
  32.911 +                                req.onResourceLoad(context, this.map, this.depMaps);
  32.912 +                            }
  32.913 +                        }
  32.914 +
  32.915 +                        //Clean up
  32.916 +                        cleanRegistry(id);
  32.917 +
  32.918 +                        this.defined = true;
  32.919 +                    }
  32.920 +
  32.921 +                    //Finished the define stage. Allow calling check again
  32.922 +                    //to allow define notifications below in the case of a
  32.923 +                    //cycle.
  32.924 +                    this.defining = false;
  32.925 +
  32.926 +                    if (this.defined && !this.defineEmitted) {
  32.927 +                        this.defineEmitted = true;
  32.928 +                        this.emit('defined', this.exports);
  32.929 +                        this.defineEmitComplete = true;
  32.930 +                    }
  32.931 +
  32.932 +                }
  32.933 +            },
  32.934 +
  32.935 +            callPlugin: function () {
  32.936 +                var map = this.map,
  32.937 +                    id = map.id,
  32.938 +                    //Map already normalized the prefix.
  32.939 +                    pluginMap = makeModuleMap(map.prefix);
  32.940 +
  32.941 +                //Mark this as a dependency for this plugin, so it
  32.942 +                //can be traced for cycles.
  32.943 +                this.depMaps.push(pluginMap);
  32.944 +
  32.945 +                on(pluginMap, 'defined', bind(this, function (plugin) {
  32.946 +                    var load, normalizedMap, normalizedMod,
  32.947 +                        bundleId = getOwn(bundlesMap, this.map.id),
  32.948 +                        name = this.map.name,
  32.949 +                        parentName = this.map.parentMap ? this.map.parentMap.name : null,
  32.950 +                        localRequire = context.makeRequire(map.parentMap, {
  32.951 +                            enableBuildCallback: true
  32.952 +                        });
  32.953 +
  32.954 +                    //If current map is not normalized, wait for that
  32.955 +                    //normalized name to load instead of continuing.
  32.956 +                    if (this.map.unnormalized) {
  32.957 +                        //Normalize the ID if the plugin allows it.
  32.958 +                        if (plugin.normalize) {
  32.959 +                            name = plugin.normalize(name, function (name) {
  32.960 +                                return normalize(name, parentName, true);
  32.961 +                            }) || '';
  32.962 +                        }
  32.963 +
  32.964 +                        //prefix and name should already be normalized, no need
  32.965 +                        //for applying map config again either.
  32.966 +                        normalizedMap = makeModuleMap(map.prefix + '!' + name,
  32.967 +                                                      this.map.parentMap);
  32.968 +                        on(normalizedMap,
  32.969 +                            'defined', bind(this, function (value) {
  32.970 +                                this.init([], function () { return value; }, null, {
  32.971 +                                    enabled: true,
  32.972 +                                    ignore: true
  32.973 +                                });
  32.974 +                            }));
  32.975 +
  32.976 +                        normalizedMod = getOwn(registry, normalizedMap.id);
  32.977 +                        if (normalizedMod) {
  32.978 +                            //Mark this as a dependency for this plugin, so it
  32.979 +                            //can be traced for cycles.
  32.980 +                            this.depMaps.push(normalizedMap);
  32.981 +
  32.982 +                            if (this.events.error) {
  32.983 +                                normalizedMod.on('error', bind(this, function (err) {
  32.984 +                                    this.emit('error', err);
  32.985 +                                }));
  32.986 +                            }
  32.987 +                            normalizedMod.enable();
  32.988 +                        }
  32.989 +
  32.990 +                        return;
  32.991 +                    }
  32.992 +
  32.993 +                    //If a paths config, then just load that file instead to
  32.994 +                    //resolve the plugin, as it is built into that paths layer.
  32.995 +                    if (bundleId) {
  32.996 +                        this.map.url = context.nameToUrl(bundleId);
  32.997 +                        this.load();
  32.998 +                        return;
  32.999 +                    }
 32.1000 +
 32.1001 +                    load = bind(this, function (value) {
 32.1002 +                        this.init([], function () { return value; }, null, {
 32.1003 +                            enabled: true
 32.1004 +                        });
 32.1005 +                    });
 32.1006 +
 32.1007 +                    load.error = bind(this, function (err) {
 32.1008 +                        this.inited = true;
 32.1009 +                        this.error = err;
 32.1010 +                        err.requireModules = [id];
 32.1011 +
 32.1012 +                        //Remove temp unnormalized modules for this module,
 32.1013 +                        //since they will never be resolved otherwise now.
 32.1014 +                        eachProp(registry, function (mod) {
 32.1015 +                            if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
 32.1016 +                                cleanRegistry(mod.map.id);
 32.1017 +                            }
 32.1018 +                        });
 32.1019 +
 32.1020 +                        onError(err);
 32.1021 +                    });
 32.1022 +
 32.1023 +                    //Allow plugins to load other code without having to know the
 32.1024 +                    //context or how to 'complete' the load.
 32.1025 +                    load.fromText = bind(this, function (text, textAlt) {
 32.1026 +                        /*jslint evil: true */
 32.1027 +                        var moduleName = map.name,
 32.1028 +                            moduleMap = makeModuleMap(moduleName),
 32.1029 +                            hasInteractive = useInteractive;
 32.1030 +
 32.1031 +                        //As of 2.1.0, support just passing the text, to reinforce
 32.1032 +                        //fromText only being called once per resource. Still
 32.1033 +                        //support old style of passing moduleName but discard
 32.1034 +                        //that moduleName in favor of the internal ref.
 32.1035 +                        if (textAlt) {
 32.1036 +                            text = textAlt;
 32.1037 +                        }
 32.1038 +
 32.1039 +                        //Turn off interactive script matching for IE for any define
 32.1040 +                        //calls in the text, then turn it back on at the end.
 32.1041 +                        if (hasInteractive) {
 32.1042 +                            useInteractive = false;
 32.1043 +                        }
 32.1044 +
 32.1045 +                        //Prime the system by creating a module instance for
 32.1046 +                        //it.
 32.1047 +                        getModule(moduleMap);
 32.1048 +
 32.1049 +                        //Transfer any config to this other module.
 32.1050 +                        if (hasProp(config.config, id)) {
 32.1051 +                            config.config[moduleName] = config.config[id];
 32.1052 +                        }
 32.1053 +
 32.1054 +                        try {
 32.1055 +                            req.exec(text);
 32.1056 +                        } catch (e) {
 32.1057 +                            return onError(makeError('fromtexteval',
 32.1058 +                                             'fromText eval for ' + id +
 32.1059 +                                            ' failed: ' + e,
 32.1060 +                                             e,
 32.1061 +                                             [id]));
 32.1062 +                        }
 32.1063 +
 32.1064 +                        if (hasInteractive) {
 32.1065 +                            useInteractive = true;
 32.1066 +                        }
 32.1067 +
 32.1068 +                        //Mark this as a dependency for the plugin
 32.1069 +                        //resource
 32.1070 +                        this.depMaps.push(moduleMap);
 32.1071 +
 32.1072 +                        //Support anonymous modules.
 32.1073 +                        context.completeLoad(moduleName);
 32.1074 +
 32.1075 +                        //Bind the value of that module to the value for this
 32.1076 +                        //resource ID.
 32.1077 +                        localRequire([moduleName], load);
 32.1078 +                    });
 32.1079 +
 32.1080 +                    //Use parentName here since the plugin's name is not reliable,
 32.1081 +                    //could be some weird string with no path that actually wants to
 32.1082 +                    //reference the parentName's path.
 32.1083 +                    plugin.load(map.name, localRequire, load, config);
 32.1084 +                }));
 32.1085 +
 32.1086 +                context.enable(pluginMap, this);
 32.1087 +                this.pluginMaps[pluginMap.id] = pluginMap;
 32.1088 +            },
 32.1089 +
 32.1090 +            enable: function () {
 32.1091 +                enabledRegistry[this.map.id] = this;
 32.1092 +                this.enabled = true;
 32.1093 +
 32.1094 +                //Set flag mentioning that the module is enabling,
 32.1095 +                //so that immediate calls to the defined callbacks
 32.1096 +                //for dependencies do not trigger inadvertent load
 32.1097 +                //with the depCount still being zero.
 32.1098 +                this.enabling = true;
 32.1099 +
 32.1100 +                //Enable each dependency
 32.1101 +                each(this.depMaps, bind(this, function (depMap, i) {
 32.1102 +                    var id, mod, handler;
 32.1103 +
 32.1104 +                    if (typeof depMap === 'string') {
 32.1105 +                        //Dependency needs to be converted to a depMap
 32.1106 +                        //and wired up to this module.
 32.1107 +                        depMap = makeModuleMap(depMap,
 32.1108 +                                               (this.map.isDefine ? this.map : this.map.parentMap),
 32.1109 +                                               false,
 32.1110 +                                               !this.skipMap);
 32.1111 +                        this.depMaps[i] = depMap;
 32.1112 +
 32.1113 +                        handler = getOwn(handlers, depMap.id);
 32.1114 +
 32.1115 +                        if (handler) {
 32.1116 +                            this.depExports[i] = handler(this);
 32.1117 +                            return;
 32.1118 +                        }
 32.1119 +
 32.1120 +                        this.depCount += 1;
 32.1121 +
 32.1122 +                        on(depMap, 'defined', bind(this, function (depExports) {
 32.1123 +                            this.defineDep(i, depExports);
 32.1124 +                            this.check();
 32.1125 +                        }));
 32.1126 +
 32.1127 +                        if (this.errback) {
 32.1128 +                            on(depMap, 'error', bind(this, this.errback));
 32.1129 +                        }
 32.1130 +                    }
 32.1131 +
 32.1132 +                    id = depMap.id;
 32.1133 +                    mod = registry[id];
 32.1134 +
 32.1135 +                    //Skip special modules like 'require', 'exports', 'module'
 32.1136 +                    //Also, don't call enable if it is already enabled,
 32.1137 +                    //important in circular dependency cases.
 32.1138 +                    if (!hasProp(handlers, id) && mod && !mod.enabled) {
 32.1139 +                        context.enable(depMap, this);
 32.1140 +                    }
 32.1141 +                }));
 32.1142 +
 32.1143 +                //Enable each plugin that is used in
 32.1144 +                //a dependency
 32.1145 +                eachProp(this.pluginMaps, bind(this, function (pluginMap) {
 32.1146 +                    var mod = getOwn(registry, pluginMap.id);
 32.1147 +                    if (mod && !mod.enabled) {
 32.1148 +                        context.enable(pluginMap, this);
 32.1149 +                    }
 32.1150 +                }));
 32.1151 +
 32.1152 +                this.enabling = false;
 32.1153 +
 32.1154 +                this.check();
 32.1155 +            },
 32.1156 +
 32.1157 +            on: function (name, cb) {
 32.1158 +                var cbs = this.events[name];
 32.1159 +                if (!cbs) {
 32.1160 +                    cbs = this.events[name] = [];
 32.1161 +                }
 32.1162 +                cbs.push(cb);
 32.1163 +            },
 32.1164 +
 32.1165 +            emit: function (name, evt) {
 32.1166 +                each(this.events[name], function (cb) {
 32.1167 +                    cb(evt);
 32.1168 +                });
 32.1169 +                if (name === 'error') {
 32.1170 +                    //Now that the error handler was triggered, remove
 32.1171 +                    //the listeners, since this broken Module instance
 32.1172 +                    //can stay around for a while in the registry.
 32.1173 +                    delete this.events[name];
 32.1174 +                }
 32.1175 +            }
 32.1176 +        };
 32.1177 +
 32.1178 +        function callGetModule(args) {
 32.1179 +            //Skip modules already defined.
 32.1180 +            if (!hasProp(defined, args[0])) {
 32.1181 +                getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
 32.1182 +            }
 32.1183 +        }
 32.1184 +
 32.1185 +        function removeListener(node, func, name, ieName) {
 32.1186 +            //Favor detachEvent because of IE9
 32.1187 +            //issue, see attachEvent/addEventListener comment elsewhere
 32.1188 +            //in this file.
 32.1189 +            if (node.detachEvent && !isOpera) {
 32.1190 +                //Probably IE. If not it will throw an error, which will be
 32.1191 +                //useful to know.
 32.1192 +                if (ieName) {
 32.1193 +                    node.detachEvent(ieName, func);
 32.1194 +                }
 32.1195 +            } else {
 32.1196 +                node.removeEventListener(name, func, false);
 32.1197 +            }
 32.1198 +        }
 32.1199 +
 32.1200 +        /**
 32.1201 +         * Given an event from a script node, get the requirejs info from it,
 32.1202 +         * and then removes the event listeners on the node.
 32.1203 +         * @param {Event} evt
 32.1204 +         * @returns {Object}
 32.1205 +         */
 32.1206 +        function getScriptData(evt) {
 32.1207 +            //Using currentTarget instead of target for Firefox 2.0's sake. Not
 32.1208 +            //all old browsers will be supported, but this one was easy enough
 32.1209 +            //to support and still makes sense.
 32.1210 +            var node = evt.currentTarget || evt.srcElement;
 32.1211 +
 32.1212 +            //Remove the listeners once here.
 32.1213 +            removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
 32.1214 +            removeListener(node, context.onScriptError, 'error');
 32.1215 +
 32.1216 +            return {
 32.1217 +                node: node,
 32.1218 +                id: node && node.getAttribute('data-requiremodule')
 32.1219 +            };
 32.1220 +        }
 32.1221 +
 32.1222 +        function intakeDefines() {
 32.1223 +            var args;
 32.1224 +
 32.1225 +            //Any defined modules in the global queue, intake them now.
 32.1226 +            takeGlobalQueue();
 32.1227 +
 32.1228 +            //Make sure any remaining defQueue items get properly processed.
 32.1229 +            while (defQueue.length) {
 32.1230 +                args = defQueue.shift();
 32.1231 +                if (args[0] === null) {
 32.1232 +                    return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
 32.1233 +                } else {
 32.1234 +                    //args are id, deps, factory. Should be normalized by the
 32.1235 +                    //define() function.
 32.1236 +                    callGetModule(args);
 32.1237 +                }
 32.1238 +            }
 32.1239 +        }
 32.1240 +
 32.1241 +        context = {
 32.1242 +            config: config,
 32.1243 +            contextName: contextName,
 32.1244 +            registry: registry,
 32.1245 +            defined: defined,
 32.1246 +            urlFetched: urlFetched,
 32.1247 +            defQueue: defQueue,
 32.1248 +            Module: Module,
 32.1249 +            makeModuleMap: makeModuleMap,
 32.1250 +            nextTick: req.nextTick,
 32.1251 +            onError: onError,
 32.1252 +
 32.1253 +            /**
 32.1254 +             * Set a configuration for the context.
 32.1255 +             * @param {Object} cfg config object to integrate.
 32.1256 +             */
 32.1257 +            configure: function (cfg) {
 32.1258 +                //Make sure the baseUrl ends in a slash.
 32.1259 +                if (cfg.baseUrl) {
 32.1260 +                    if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
 32.1261 +                        cfg.baseUrl += '/';
 32.1262 +                    }
 32.1263 +                }
 32.1264 +
 32.1265 +                //Save off the paths since they require special processing,
 32.1266 +                //they are additive.
 32.1267 +                var shim = config.shim,
 32.1268 +                    objs = {
 32.1269 +                        paths: true,
 32.1270 +                        bundles: true,
 32.1271 +                        config: true,
 32.1272 +                        map: true
 32.1273 +                    };
 32.1274 +
 32.1275 +                eachProp(cfg, function (value, prop) {
 32.1276 +                    if (objs[prop]) {
 32.1277 +                        if (!config[prop]) {
 32.1278 +                            config[prop] = {};
 32.1279 +                        }
 32.1280 +                        mixin(config[prop], value, true, true);
 32.1281 +                    } else {
 32.1282 +                        config[prop] = value;
 32.1283 +                    }
 32.1284 +                });
 32.1285 +
 32.1286 +                //Reverse map the bundles
 32.1287 +                if (cfg.bundles) {
 32.1288 +                    eachProp(cfg.bundles, function (value, prop) {
 32.1289 +                        each(value, function (v) {
 32.1290 +                            if (v !== prop) {
 32.1291 +                                bundlesMap[v] = prop;
 32.1292 +                            }
 32.1293 +                        });
 32.1294 +                    });
 32.1295 +                }
 32.1296 +
 32.1297 +                //Merge shim
 32.1298 +                if (cfg.shim) {
 32.1299 +                    eachProp(cfg.shim, function (value, id) {
 32.1300 +                        //Normalize the structure
 32.1301 +                        if (isArray(value)) {
 32.1302 +                            value = {
 32.1303 +                                deps: value
 32.1304 +                            };
 32.1305 +                        }
 32.1306 +                        if ((value.exports || value.init) && !value.exportsFn) {
 32.1307 +                            value.exportsFn = context.makeShimExports(value);
 32.1308 +                        }
 32.1309 +                        shim[id] = value;
 32.1310 +                    });
 32.1311 +                    config.shim = shim;
 32.1312 +                }
 32.1313 +
 32.1314 +                //Adjust packages if necessary.
 32.1315 +                if (cfg.packages) {
 32.1316 +                    each(cfg.packages, function (pkgObj) {
 32.1317 +                        var location, name;
 32.1318 +
 32.1319 +                        pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
 32.1320 +
 32.1321 +                        name = pkgObj.name;
 32.1322 +                        location = pkgObj.location;
 32.1323 +                        if (location) {
 32.1324 +                            config.paths[name] = pkgObj.location;
 32.1325 +                        }
 32.1326 +
 32.1327 +                        //Save pointer to main module ID for pkg name.
 32.1328 +                        //Remove leading dot in main, so main paths are normalized,
 32.1329 +                        //and remove any trailing .js, since different package
 32.1330 +                        //envs have different conventions: some use a module name,
 32.1331 +                        //some use a file name.
 32.1332 +                        config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
 32.1333 +                                     .replace(currDirRegExp, '')
 32.1334 +                                     .replace(jsSuffixRegExp, '');
 32.1335 +                    });
 32.1336 +                }
 32.1337 +
 32.1338 +                //If there are any "waiting to execute" modules in the registry,
 32.1339 +                //update the maps for them, since their info, like URLs to load,
 32.1340 +                //may have changed.
 32.1341 +                eachProp(registry, function (mod, id) {
 32.1342 +                    //If module already has init called, since it is too
 32.1343 +                    //late to modify them, and ignore unnormalized ones
 32.1344 +                    //since they are transient.
 32.1345 +                    if (!mod.inited && !mod.map.unnormalized) {
 32.1346 +                        mod.map = makeModuleMap(id);
 32.1347 +                    }
 32.1348 +                });
 32.1349 +
 32.1350 +                //If a deps array or a config callback is specified, then call
 32.1351 +                //require with those args. This is useful when require is defined as a
 32.1352 +                //config object before require.js is loaded.
 32.1353 +                if (cfg.deps || cfg.callback) {
 32.1354 +                    context.require(cfg.deps || [], cfg.callback);
 32.1355 +                }
 32.1356 +            },
 32.1357 +
 32.1358 +            makeShimExports: function (value) {
 32.1359 +                function fn() {
 32.1360 +                    var ret;
 32.1361 +                    if (value.init) {
 32.1362 +                        ret = value.init.apply(global, arguments);
 32.1363 +                    }
 32.1364 +                    return ret || (value.exports && getGlobal(value.exports));
 32.1365 +                }
 32.1366 +                return fn;
 32.1367 +            },
 32.1368 +
 32.1369 +            makeRequire: function (relMap, options) {
 32.1370 +                options = options || {};
 32.1371 +
 32.1372 +                function localRequire(deps, callback, errback) {
 32.1373 +                    var id, map, requireMod;
 32.1374 +
 32.1375 +                    if (options.enableBuildCallback && callback && isFunction(callback)) {
 32.1376 +                        callback.__requireJsBuild = true;
 32.1377 +                    }
 32.1378 +
 32.1379 +                    if (typeof deps === 'string') {
 32.1380 +                        if (isFunction(callback)) {
 32.1381 +                            //Invalid call
 32.1382 +                            return onError(makeError('requireargs', 'Invalid require call'), errback);
 32.1383 +                        }
 32.1384 +
 32.1385 +                        //If require|exports|module are requested, get the
 32.1386 +                        //value for them from the special handlers. Caveat:
 32.1387 +                        //this only works while module is being defined.
 32.1388 +                        if (relMap && hasProp(handlers, deps)) {
 32.1389 +                            return handlers[deps](registry[relMap.id]);
 32.1390 +                        }
 32.1391 +
 32.1392 +                        //Synchronous access to one module. If require.get is
 32.1393 +                        //available (as in the Node adapter), prefer that.
 32.1394 +                        if (req.get) {
 32.1395 +                            return req.get(context, deps, relMap, localRequire);
 32.1396 +                        }
 32.1397 +
 32.1398 +                        //Normalize module name, if it contains . or ..
 32.1399 +                        map = makeModuleMap(deps, relMap, false, true);
 32.1400 +                        id = map.id;
 32.1401 +
 32.1402 +                        if (!hasProp(defined, id)) {
 32.1403 +                            return onError(makeError('notloaded', 'Module name "' +
 32.1404 +                                        id +
 32.1405 +                                        '" has not been loaded yet for context: ' +
 32.1406 +                                        contextName +
 32.1407 +                                        (relMap ? '' : '. Use require([])')));
 32.1408 +                        }
 32.1409 +                        return defined[id];
 32.1410 +                    }
 32.1411 +
 32.1412 +                    //Grab defines waiting in the global queue.
 32.1413 +                    intakeDefines();
 32.1414 +
 32.1415 +                    //Mark all the dependencies as needing to be loaded.
 32.1416 +                    context.nextTick(function () {
 32.1417 +                        //Some defines could have been added since the
 32.1418 +                        //require call, collect them.
 32.1419 +                        intakeDefines();
 32.1420 +
 32.1421 +                        requireMod = getModule(makeModuleMap(null, relMap));
 32.1422 +
 32.1423 +                        //Store if map config should be applied to this require
 32.1424 +                        //call for dependencies.
 32.1425 +                        requireMod.skipMap = options.skipMap;
 32.1426 +
 32.1427 +                        requireMod.init(deps, callback, errback, {
 32.1428 +                            enabled: true
 32.1429 +                        });
 32.1430 +
 32.1431 +                        checkLoaded();
 32.1432 +                    });
 32.1433 +
 32.1434 +                    return localRequire;
 32.1435 +                }
 32.1436 +
 32.1437 +                mixin(localRequire, {
 32.1438 +                    isBrowser: isBrowser,
 32.1439 +
 32.1440 +                    /**
 32.1441 +                     * Converts a module name + .extension into an URL path.
 32.1442 +                     * *Requires* the use of a module name. It does not support using
 32.1443 +                     * plain URLs like nameToUrl.
 32.1444 +                     */
 32.1445 +                    toUrl: function (moduleNamePlusExt) {
 32.1446 +                        var ext,
 32.1447 +                            index = moduleNamePlusExt.lastIndexOf('.'),
 32.1448 +                            segment = moduleNamePlusExt.split('/')[0],
 32.1449 +                            isRelative = segment === '.' || segment === '..';
 32.1450 +
 32.1451 +                        //Have a file extension alias, and it is not the
 32.1452 +                        //dots from a relative path.
 32.1453 +                        if (index !== -1 && (!isRelative || index > 1)) {
 32.1454 +                            ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
 32.1455 +                            moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
 32.1456 +                        }
 32.1457 +
 32.1458 +                        return context.nameToUrl(normalize(moduleNamePlusExt,
 32.1459 +                                                relMap && relMap.id, true), ext,  true);
 32.1460 +                    },
 32.1461 +
 32.1462 +                    defined: function (id) {
 32.1463 +                        return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
 32.1464 +                    },
 32.1465 +
 32.1466 +                    specified: function (id) {
 32.1467 +                        id = makeModuleMap(id, relMap, false, true).id;
 32.1468 +                        return hasProp(defined, id) || hasProp(registry, id);
 32.1469 +                    }
 32.1470 +                });
 32.1471 +
 32.1472 +                //Only allow undef on top level require calls
 32.1473 +                if (!relMap) {
 32.1474 +                    localRequire.undef = function (id) {
 32.1475 +                        //Bind any waiting define() calls to this context,
 32.1476 +                        //fix for #408
 32.1477 +                        takeGlobalQueue();
 32.1478 +
 32.1479 +                        var map = makeModuleMap(id, relMap, true),
 32.1480 +                            mod = getOwn(registry, id);
 32.1481 +
 32.1482 +                        removeScript(id);
 32.1483 +
 32.1484 +                        delete defined[id];
 32.1485 +                        delete urlFetched[map.url];
 32.1486 +                        delete undefEvents[id];
 32.1487 +
 32.1488 +                        //Clean queued defines too. Go backwards
 32.1489 +                        //in array so that the splices do not
 32.1490 +                        //mess up the iteration.
 32.1491 +                        eachReverse(defQueue, function(args, i) {
 32.1492 +                            if(args[0] === id) {
 32.1493 +                                defQueue.splice(i, 1);
 32.1494 +                            }
 32.1495 +                        });
 32.1496 +
 32.1497 +                        if (mod) {
 32.1498 +                            //Hold on to listeners in case the
 32.1499 +                            //module will be attempted to be reloaded
 32.1500 +                            //using a different config.
 32.1501 +                            if (mod.events.defined) {
 32.1502 +                                undefEvents[id] = mod.events;
 32.1503 +                            }
 32.1504 +
 32.1505 +                            cleanRegistry(id);
 32.1506 +                        }
 32.1507 +                    };
 32.1508 +                }
 32.1509 +
 32.1510 +                return localRequire;
 32.1511 +            },
 32.1512 +
 32.1513 +            /**
 32.1514 +             * Called to enable a module if it is still in the registry
 32.1515 +             * awaiting enablement. A second arg, parent, the parent module,
 32.1516 +             * is passed in for context, when this method is overridden by
 32.1517 +             * the optimizer. Not shown here to keep code compact.
 32.1518 +             */
 32.1519 +            enable: function (depMap) {
 32.1520 +                var mod = getOwn(registry, depMap.id);
 32.1521 +                if (mod) {
 32.1522 +                    getModule(depMap).enable();
 32.1523 +                }
 32.1524 +            },
 32.1525 +
 32.1526 +            /**
 32.1527 +             * Internal method used by environment adapters to complete a load event.
 32.1528 +             * A load event could be a script load or just a load pass from a synchronous
 32.1529 +             * load call.
 32.1530 +             * @param {String} moduleName the name of the module to potentially complete.
 32.1531 +             */
 32.1532 +            completeLoad: function (moduleName) {
 32.1533 +                var found, args, mod,
 32.1534 +                    shim = getOwn(config.shim, moduleName) || {},
 32.1535 +                    shExports = shim.exports;
 32.1536 +
 32.1537 +                takeGlobalQueue();
 32.1538 +
 32.1539 +                while (defQueue.length) {
 32.1540 +                    args = defQueue.shift();
 32.1541 +                    if (args[0] === null) {
 32.1542 +                        args[0] = moduleName;
 32.1543 +                        //If already found an anonymous module and bound it
 32.1544 +                        //to this name, then this is some other anon module
 32.1545 +                        //waiting for its completeLoad to fire.
 32.1546 +                        if (found) {
 32.1547 +                            break;
 32.1548 +                        }
 32.1549 +                        found = true;
 32.1550 +                    } else if (args[0] === moduleName) {
 32.1551 +                        //Found matching define call for this script!
 32.1552 +                        found = true;
 32.1553 +                    }
 32.1554 +
 32.1555 +                    callGetModule(args);
 32.1556 +                }
 32.1557 +
 32.1558 +                //Do this after the cycle of callGetModule in case the result
 32.1559 +                //of those calls/init calls changes the registry.
 32.1560 +                mod = getOwn(registry, moduleName);
 32.1561 +
 32.1562 +                if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
 32.1563 +                    if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
 32.1564 +                        if (hasPathFallback(moduleName)) {
 32.1565 +                            return;
 32.1566 +                        } else {
 32.1567 +                            return onError(makeError('nodefine',
 32.1568 +                                             'No define call for ' + moduleName,
 32.1569 +                                             null,
 32.1570 +                                             [moduleName]));
 32.1571 +                        }
 32.1572 +                    } else {
 32.1573 +                        //A script that does not call define(), so just simulate
 32.1574 +                        //the call for it.
 32.1575 +                        callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
 32.1576 +                    }
 32.1577 +                }
 32.1578 +
 32.1579 +                checkLoaded();
 32.1580 +            },
 32.1581 +
 32.1582 +            /**
 32.1583 +             * Converts a module name to a file path. Supports cases where
 32.1584 +             * moduleName may actually be just an URL.
 32.1585 +             * Note that it **does not** call normalize on the moduleName,
 32.1586 +             * it is assumed to have already been normalized. This is an
 32.1587 +             * internal API, not a public one. Use toUrl for the public API.
 32.1588 +             */
 32.1589 +            nameToUrl: function (moduleName, ext, skipExt) {
 32.1590 +                var paths, syms, i, parentModule, url,
 32.1591 +                    parentPath, bundleId,
 32.1592 +                    pkgMain = getOwn(config.pkgs, moduleName);
 32.1593 +
 32.1594 +                if (pkgMain) {
 32.1595 +                    moduleName = pkgMain;
 32.1596 +                }
 32.1597 +
 32.1598 +                bundleId = getOwn(bundlesMap, moduleName);
 32.1599 +
 32.1600 +                if (bundleId) {
 32.1601 +                    return context.nameToUrl(bundleId, ext, skipExt);
 32.1602 +                }
 32.1603 +
 32.1604 +                //If a colon is in the URL, it indicates a protocol is used and it is just
 32.1605 +                //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
 32.1606 +                //or ends with .js, then assume the user meant to use an url and not a module id.
 32.1607 +                //The slash is important for protocol-less URLs as well as full paths.
 32.1608 +                if (req.jsExtRegExp.test(moduleName)) {
 32.1609 +                    //Just a plain path, not module name lookup, so just return it.
 32.1610 +                    //Add extension if it is included. This is a bit wonky, only non-.js things pass
 32.1611 +                    //an extension, this method probably needs to be reworked.
 32.1612 +                    url = moduleName + (ext || '');
 32.1613 +                } else {
 32.1614 +                    //A module that needs to be converted to a path.
 32.1615 +                    paths = config.paths;
 32.1616 +
 32.1617 +                    syms = moduleName.split('/');
 32.1618 +                    //For each module name segment, see if there is a path
 32.1619 +                    //registered for it. Start with most specific name
 32.1620 +                    //and work up from it.
 32.1621 +                    for (i = syms.length; i > 0; i -= 1) {
 32.1622 +                        parentModule = syms.slice(0, i).join('/');
 32.1623 +
 32.1624 +                        parentPath = getOwn(paths, parentModule);
 32.1625 +                        if (parentPath) {
 32.1626 +                            //If an array, it means there are a few choices,
 32.1627 +                            //Choose the one that is desired
 32.1628 +                            if (isArray(parentPath)) {
 32.1629 +                                parentPath = parentPath[0];
 32.1630 +                            }
 32.1631 +                            syms.splice(0, i, parentPath);
 32.1632 +                            break;
 32.1633 +                        }
 32.1634 +                    }
 32.1635 +
 32.1636 +                    //Join the path parts together, then figure out if baseUrl is needed.
 32.1637 +                    url = syms.join('/');
 32.1638 +                    url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js'));
 32.1639 +                    url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
 32.1640 +                }
 32.1641 +
 32.1642 +                return config.urlArgs ? url +
 32.1643 +                                        ((url.indexOf('?') === -1 ? '?' : '&') +
 32.1644 +                                         config.urlArgs) : url;
 32.1645 +            },
 32.1646 +
 32.1647 +            //Delegates to req.load. Broken out as a separate function to
 32.1648 +            //allow overriding in the optimizer.
 32.1649 +            load: function (id, url) {
 32.1650 +                req.load(context, id, url);
 32.1651 +            },
 32.1652 +
 32.1653 +            /**
 32.1654 +             * Executes a module callback function. Broken out as a separate function
 32.1655 +             * solely to allow the build system to sequence the files in the built
 32.1656 +             * layer in the right sequence.
 32.1657 +             *
 32.1658 +             * @private
 32.1659 +             */
 32.1660 +            execCb: function (name, callback, args, exports) {
 32.1661 +                return callback.apply(exports, args);
 32.1662 +            },
 32.1663 +
 32.1664 +            /**
 32.1665 +             * callback for script loads, used to check status of loading.
 32.1666 +             *
 32.1667 +             * @param {Event} evt the event from the browser for the script
 32.1668 +             * that was loaded.
 32.1669 +             */
 32.1670 +            onScriptLoad: function (evt) {
 32.1671 +                //Using currentTarget instead of target for Firefox 2.0's sake. Not
 32.1672 +                //all old browsers will be supported, but this one was easy enough
 32.1673 +                //to support and still makes sense.
 32.1674 +                if (evt.type === 'load' ||
 32.1675 +                        (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
 32.1676 +                    //Reset interactive script so a script node is not held onto for
 32.1677 +                    //to long.
 32.1678 +                    interactiveScript = null;
 32.1679 +
 32.1680 +                    //Pull out the name of the module and the context.
 32.1681 +                    var data = getScriptData(evt);
 32.1682 +                    context.completeLoad(data.id);
 32.1683 +                }
 32.1684 +            },
 32.1685 +
 32.1686 +            /**
 32.1687 +             * Callback for script errors.
 32.1688 +             */
 32.1689 +            onScriptError: function (evt) {
 32.1690 +                var data = getScriptData(evt);
 32.1691 +                if (!hasPathFallback(data.id)) {
 32.1692 +                    return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
 32.1693 +                }
 32.1694 +            }
 32.1695 +        };
 32.1696 +
 32.1697 +        context.require = context.makeRequire();
 32.1698 +        return context;
 32.1699 +    }
 32.1700 +
 32.1701 +    /**
 32.1702 +     * Main entry point.
 32.1703 +     *
 32.1704 +     * If the only argument to require is a string, then the module that
 32.1705 +     * is represented by that string is fetched for the appropriate context.
 32.1706 +     *
 32.1707 +     * If the first argument is an array, then it will be treated as an array
 32.1708 +     * of dependency string names to fetch. An optional function callback can
 32.1709 +     * be specified to execute when all of those dependencies are available.
 32.1710 +     *
 32.1711 +     * Make a local req variable to help Caja compliance (it assumes things
 32.1712 +     * on a require that are not standardized), and to give a short
 32.1713 +     * name for minification/local scope use.
 32.1714 +     */
 32.1715 +    req = requirejs = function (deps, callback, errback, optional) {
 32.1716 +
 32.1717 +        //Find the right context, use default
 32.1718 +        var context, config,
 32.1719 +            contextName = defContextName;
 32.1720 +
 32.1721 +        // Determine if have config object in the call.
 32.1722 +        if (!isArray(deps) && typeof deps !== 'string') {
 32.1723 +            // deps is a config object
 32.1724 +            config = deps;
 32.1725 +            if (isArray(callback)) {
 32.1726 +                // Adjust args if there are dependencies
 32.1727 +                deps = callback;
 32.1728 +                callback = errback;
 32.1729 +                errback = optional;
 32.1730 +            } else {
 32.1731 +                deps = [];
 32.1732 +            }
 32.1733 +        }
 32.1734 +
 32.1735 +        if (config && config.context) {
 32.1736 +            contextName = config.context;
 32.1737 +        }
 32.1738 +
 32.1739 +        context = getOwn(contexts, contextName);
 32.1740 +        if (!context) {
 32.1741 +            context = contexts[contextName] = req.s.newContext(contextName);
 32.1742 +        }
 32.1743 +
 32.1744 +        if (config) {
 32.1745 +            context.configure(config);
 32.1746 +        }
 32.1747 +
 32.1748 +        return context.require(deps, callback, errback);
 32.1749 +    };
 32.1750 +
 32.1751 +    /**
 32.1752 +     * Support require.config() to make it easier to cooperate with other
 32.1753 +     * AMD loaders on globally agreed names.
 32.1754 +     */
 32.1755 +    req.config = function (config) {
 32.1756 +        return req(config);
 32.1757 +    };
 32.1758 +
 32.1759 +    /**
 32.1760 +     * Execute something after the current tick
 32.1761 +     * of the event loop. Override for other envs
 32.1762 +     * that have a better solution than setTimeout.
 32.1763 +     * @param  {Function} fn function to execute later.
 32.1764 +     */
 32.1765 +    req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
 32.1766 +        setTimeout(fn, 4);
 32.1767 +    } : function (fn) { fn(); };
 32.1768 +
 32.1769 +    /**
 32.1770 +     * Export require as a global, but only if it does not already exist.
 32.1771 +     */
 32.1772 +    if (!require) {
 32.1773 +        require = req;
 32.1774 +    }
 32.1775 +
 32.1776 +    req.version = version;
 32.1777 +
 32.1778 +    //Used to filter out dependencies that are already paths.
 32.1779 +    req.jsExtRegExp = /^\/|:|\?|\.js$/;
 32.1780 +    req.isBrowser = isBrowser;
 32.1781 +    s = req.s = {
 32.1782 +        contexts: contexts,
 32.1783 +        newContext: newContext
 32.1784 +    };
 32.1785 +
 32.1786 +    //Create default context.
 32.1787 +    req({});
 32.1788 +
 32.1789 +    //Exports some context-sensitive methods on global require.
 32.1790 +    each([
 32.1791 +        'toUrl',
 32.1792 +        'undef',
 32.1793 +        'defined',
 32.1794 +        'specified'
 32.1795 +    ], function (prop) {
 32.1796 +        //Reference from contexts instead of early binding to default context,
 32.1797 +        //so that during builds, the latest instance of the default context
 32.1798 +        //with its config gets used.
 32.1799 +        req[prop] = function () {
 32.1800 +            var ctx = contexts[defContextName];
 32.1801 +            return ctx.require[prop].apply(ctx, arguments);
 32.1802 +        };
 32.1803 +    });
 32.1804 +
 32.1805 +    if (isBrowser) {
 32.1806 +        head = s.head = document.getElementsByTagName('head')[0];
 32.1807 +        //If BASE tag is in play, using appendChild is a problem for IE6.
 32.1808 +        //When that browser dies, this can be removed. Details in this jQuery bug:
 32.1809 +        //http://dev.jquery.com/ticket/2709
 32.1810 +        baseElement = document.getElementsByTagName('base')[0];
 32.1811 +        if (baseElement) {
 32.1812 +            head = s.head = baseElement.parentNode;
 32.1813 +        }
 32.1814 +    }
 32.1815 +
 32.1816 +    /**
 32.1817 +     * Any errors that require explicitly generates will be passed to this
 32.1818 +     * function. Intercept/override it if you want custom error handling.
 32.1819 +     * @param {Error} err the error object.
 32.1820 +     */
 32.1821 +    req.onError = defaultOnError;
 32.1822 +
 32.1823 +    /**
 32.1824 +     * Creates the node for the load command. Only used in browser envs.
 32.1825 +     */
 32.1826 +    req.createNode = function (config, moduleName, url) {
 32.1827 +        var node = config.xhtml ?
 32.1828 +                document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
 32.1829 +                document.createElement('script');
 32.1830 +        node.type = config.scriptType || 'text/javascript';
 32.1831 +        node.charset = 'utf-8';
 32.1832 +        node.async = true;
 32.1833 +        return node;
 32.1834 +    };
 32.1835 +
 32.1836 +    /**
 32.1837 +     * Does the request to load a module for the browser case.
 32.1838 +     * Make this a separate function to allow other environments
 32.1839 +     * to override it.
 32.1840 +     *
 32.1841 +     * @param {Object} context the require context to find state.
 32.1842 +     * @param {String} moduleName the name of the module.
 32.1843 +     * @param {Object} url the URL to the module.
 32.1844 +     */
 32.1845 +    req.load = function (context, moduleName, url) {
 32.1846 +        var config = (context && context.config) || {},
 32.1847 +            node;
 32.1848 +        if (isBrowser) {
 32.1849 +            //In the browser so use a script tag
 32.1850 +            node = req.createNode(config, moduleName, url);
 32.1851 +
 32.1852 +            node.setAttribute('data-requirecontext', context.contextName);
 32.1853 +            node.setAttribute('data-requiremodule', moduleName);
 32.1854 +
 32.1855 +            //Set up load listener. Test attachEvent first because IE9 has
 32.1856 +            //a subtle issue in its addEventListener and script onload firings
 32.1857 +            //that do not match the behavior of all other browsers with
 32.1858 +            //addEventListener support, which fire the onload event for a
 32.1859 +            //script right after the script execution. See:
 32.1860 +            //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
 32.1861 +            //UNFORTUNATELY Opera implements attachEvent but does not follow the script
 32.1862 +            //script execution mode.
 32.1863 +            if (node.attachEvent &&
 32.1864 +                    //Check if node.attachEvent is artificially added by custom script or
 32.1865 +                    //natively supported by browser
 32.1866 +                    //read https://github.com/jrburke/requirejs/issues/187
 32.1867 +                    //if we can NOT find [native code] then it must NOT natively supported.
 32.1868 +                    //in IE8, node.attachEvent does not have toString()
 32.1869 +                    //Note the test for "[native code" with no closing brace, see:
 32.1870 +                    //https://github.com/jrburke/requirejs/issues/273
 32.1871 +                    !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
 32.1872 +                    !isOpera) {
 32.1873 +                //Probably IE. IE (at least 6-8) do not fire
 32.1874 +                //script onload right after executing the script, so
 32.1875 +                //we cannot tie the anonymous define call to a name.
 32.1876 +                //However, IE reports the script as being in 'interactive'
 32.1877 +                //readyState at the time of the define call.
 32.1878 +                useInteractive = true;
 32.1879 +
 32.1880 +                node.attachEvent('onreadystatechange', context.onScriptLoad);
 32.1881 +                //It would be great to add an error handler here to catch
 32.1882 +                //404s in IE9+. However, onreadystatechange will fire before
 32.1883 +                //the error handler, so that does not help. If addEventListener
 32.1884 +                //is used, then IE will fire error before load, but we cannot
 32.1885 +                //use that pathway given the connect.microsoft.com issue
 32.1886 +                //mentioned above about not doing the 'script execute,
 32.1887 +                //then fire the script load event listener before execute
 32.1888 +                //next script' that other browsers do.
 32.1889 +                //Best hope: IE10 fixes the issues,
 32.1890 +                //and then destroys all installs of IE 6-9.
 32.1891 +                //node.attachEvent('onerror', context.onScriptError);
 32.1892 +            } else {
 32.1893 +                node.addEventListener('load', context.onScriptLoad, false);
 32.1894 +                node.addEventListener('error', context.onScriptError, false);
 32.1895 +            }
 32.1896 +            node.src = url;
 32.1897 +
 32.1898 +            //For some cache cases in IE 6-8, the script executes before the end
 32.1899 +            //of the appendChild execution, so to tie an anonymous define
 32.1900 +            //call to the module name (which is stored on the node), hold on
 32.1901 +            //to a reference to this node, but clear after the DOM insertion.
 32.1902 +            currentlyAddingScript = node;
 32.1903 +            if (baseElement) {
 32.1904 +                head.insertBefore(node, baseElement);
 32.1905 +            } else {
 32.1906 +                head.appendChild(node);
 32.1907 +            }
 32.1908 +            currentlyAddingScript = null;
 32.1909 +
 32.1910 +            return node;
 32.1911 +        } else if (isWebWorker) {
 32.1912 +            try {
 32.1913 +                //In a web worker, use importScripts. This is not a very
 32.1914 +                //efficient use of importScripts, importScripts will block until
 32.1915 +                //its script is downloaded and evaluated. However, if web workers
 32.1916 +                //are in play, the expectation that a build has been done so that
 32.1917 +                //only one script needs to be loaded anyway. This may need to be
 32.1918 +                //reevaluated if other use cases become common.
 32.1919 +                importScripts(url);
 32.1920 +
 32.1921 +                //Account for anonymous modules
 32.1922 +                context.completeLoad(moduleName);
 32.1923 +            } catch (e) {
 32.1924 +                context.onError(makeError('importscripts',
 32.1925 +                                'importScripts failed for ' +
 32.1926 +                                    moduleName + ' at ' + url,
 32.1927 +                                e,
 32.1928 +                                [moduleName]));
 32.1929 +            }
 32.1930 +        }
 32.1931 +    };
 32.1932 +
 32.1933 +    function getInteractiveScript() {
 32.1934 +        if (interactiveScript && interactiveScript.readyState === 'interactive') {
 32.1935 +            return interactiveScript;
 32.1936 +        }
 32.1937 +
 32.1938 +        eachReverse(scripts(), function (script) {
 32.1939 +            if (script.readyState === 'interactive') {
 32.1940 +                return (interactiveScript = script);
 32.1941 +            }
 32.1942 +        });
 32.1943 +        return interactiveScript;
 32.1944 +    }
 32.1945 +
 32.1946 +    //Look for a data-main script attribute, which could also adjust the baseUrl.
 32.1947 +    if (isBrowser && !cfg.skipDataMain) {
 32.1948 +        //Figure out baseUrl. Get it from the script tag with require.js in it.
 32.1949 +        eachReverse(scripts(), function (script) {
 32.1950 +            //Set the 'head' where we can append children by
 32.1951 +            //using the script's parent.
 32.1952 +            if (!head) {
 32.1953 +                head = script.parentNode;
 32.1954 +            }
 32.1955 +
 32.1956 +            //Look for a data-main attribute to set main script for the page
 32.1957 +            //to load. If it is there, the path to data main becomes the
 32.1958 +            //baseUrl, if it is not already set.
 32.1959 +            dataMain = script.getAttribute('data-main');
 32.1960 +            if (dataMain) {
 32.1961 +                //Preserve dataMain in case it is a path (i.e. contains '?')
 32.1962 +                mainScript = dataMain;
 32.1963 +
 32.1964 +                //Set final baseUrl if there is not already an explicit one.
 32.1965 +                if (!cfg.baseUrl) {
 32.1966 +                    //Pull off the directory of data-main for use as the
 32.1967 +                    //baseUrl.
 32.1968 +                    src = mainScript.split('/');
 32.1969 +                    mainScript = src.pop();
 32.1970 +                    subPath = src.length ? src.join('/')  + '/' : './';
 32.1971 +
 32.1972 +                    cfg.baseUrl = subPath;
 32.1973 +                }
 32.1974 +
 32.1975 +                //Strip off any trailing .js since mainScript is now
 32.1976 +                //like a module name.
 32.1977 +                mainScript = mainScript.replace(jsSuffixRegExp, '');
 32.1978 +
 32.1979 +                 //If mainScript is still a path, fall back to dataMain
 32.1980 +                if (req.jsExtRegExp.test(mainScript)) {
 32.1981 +                    mainScript = dataMain;
 32.1982 +                }
 32.1983 +
 32.1984 +                //Put the data-main script in the files to load.
 32.1985 +                cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
 32.1986 +
 32.1987 +                return true;
 32.1988 +            }
 32.1989 +        });
 32.1990 +    }
 32.1991 +
 32.1992 +    /**
 32.1993 +     * The function that handles definitions of modules. Differs from
 32.1994 +     * require() in that a string for the module should be the first argument,
 32.1995 +     * and the function to execute after dependencies are loaded should
 32.1996 +     * return a value to define the module corresponding to the first argument's
 32.1997 +     * name.
 32.1998 +     */
 32.1999 +    define = function (name, deps, callback) {
 32.2000 +        var node, context;
 32.2001 +
 32.2002 +        //Allow for anonymous modules
 32.2003 +        if (typeof name !== 'string') {
 32.2004 +            //Adjust args appropriately
 32.2005 +            callback = deps;
 32.2006 +            deps = name;
 32.2007 +            name = null;
 32.2008 +        }
 32.2009 +
 32.2010 +        //This module may not have dependencies
 32.2011 +        if (!isArray(deps)) {
 32.2012 +            callback = deps;
 32.2013 +            deps = null;
 32.2014 +        }
 32.2015 +
 32.2016 +        //If no name, and callback is a function, then figure out if it a
 32.2017 +        //CommonJS thing with dependencies.
 32.2018 +        if (!deps && isFunction(callback)) {
 32.2019 +            deps = [];
 32.2020 +            //Remove comments from the callback string,
 32.2021 +            //look for require calls, and pull them into the dependencies,
 32.2022 +            //but only if there are function args.
 32.2023 +            if (callback.length) {
 32.2024 +                callback
 32.2025 +                    .toString()
 32.2026 +                    .replace(commentRegExp, '')
 32.2027 +                    .replace(cjsRequireRegExp, function (match, dep) {
 32.2028 +                        deps.push(dep);
 32.2029 +                    });
 32.2030 +
 32.2031 +                //May be a CommonJS thing even without require calls, but still
 32.2032 +                //could use exports, and module. Avoid doing exports and module
 32.2033 +                //work though if it just needs require.
 32.2034 +                //REQUIRES the function to expect the CommonJS variables in the
 32.2035 +                //order listed below.
 32.2036 +                deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
 32.2037 +            }
 32.2038 +        }
 32.2039 +
 32.2040 +        //If in IE 6-8 and hit an anonymous define() call, do the interactive
 32.2041 +        //work.
 32.2042 +        if (useInteractive) {
 32.2043 +            node = currentlyAddingScript || getInteractiveScript();
 32.2044 +            if (node) {
 32.2045 +                if (!name) {
 32.2046 +                    name = node.getAttribute('data-requiremodule');
 32.2047 +                }
 32.2048 +                context = contexts[node.getAttribute('data-requirecontext')];
 32.2049 +            }
 32.2050 +        }
 32.2051 +
 32.2052 +        //Always save off evaluating the def call until the script onload handler.
 32.2053 +        //This allows multiple modules to be in a file without prematurely
 32.2054 +        //tracing dependencies, and allows for anonymous module support,
 32.2055 +        //where the module name is not known until the script onload event
 32.2056 +        //occurs. If no context, use the global queue, and get it processed
 32.2057 +        //in the onscript load callback.
 32.2058 +        (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
 32.2059 +    };
 32.2060 +
 32.2061 +    define.amd = {
 32.2062 +        jQuery: true
 32.2063 +    };
 32.2064 +
 32.2065 +
 32.2066 +    /**
 32.2067 +     * Executes the text. Normally just uses eval, but can be modified
 32.2068 +     * to use a better, environment-specific call. Only used for transpiling
 32.2069 +     * loader plugins, not for plain JS modules.
 32.2070 +     * @param {String} text the text to execute/evaluate.
 32.2071 +     */
 32.2072 +    req.exec = function (text) {
 32.2073 +        /*jslint evil: true */
 32.2074 +        return eval(text);
 32.2075 +    };
 32.2076 +
 32.2077 +    //Set up with config info.
 32.2078 +    req(cfg);
 32.2079 +}(this));
 32.2080 \ No newline at end of file
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/Display/startUpApp.js	Sun Jul 06 12:02:12 2014 -0700
    33.3 @@ -0,0 +1,16 @@
    33.4 +// For any third party dependencies, like jQuery, place them in the lib folder.
    33.5 +
    33.6 +// Configure loading modules from the lib directory,
    33.7 +// except for 'app' ones, which are in a sibling
    33.8 +// directory.
    33.9 +requirejs.config({
   33.10 +//    baseUrl: 'lib',
   33.11 +    paths: {
   33.12 +        app: './app',
   33.13 +		lib: './lib'
   33.14 +    }
   33.15 +});
   33.16 +
   33.17 +// Start loading the main app file. Put all of
   33.18 +// your application logic in there.
   33.19 +requirejs(['app/POPApp']);
   33.20 \ No newline at end of file
    34.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.odg has changed
    35.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph.pdf has changed
    36.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.odg has changed
    37.1 Binary file 1__Development/0__Code_Dev/Javascript_approach/GabePattern/12_Dc_02___Sample_Prog_to_hand_compile__with_syntax_graph__for_Gabe.pdf has changed
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/GabePattern/GabePattern_data_structs.js	Sun Jul 06 12:02:12 2014 -0700
    38.3 @@ -0,0 +1,438 @@
    38.4 +
    38.5 +var c = document.getElementById("POPCanvas");
    38.6 +var ctx = c.getContext("2d");
    38.7 +var foreGroundFill = "#000000";
    38.8 +var backGroundFill = "#FFFFFF";
    38.9 +ctx.font = "14px Arial";
   38.10 +ctx.fillStyle = foreGroundFill;
   38.11 +var fillText = "Hello World";
   38.12 +ctx.fillText(fillText,10,50);
   38.13 +
   38.14 +alert("hello!");
   38.15 +
   38.16 +ctx.fillStyle = backGroundFill;
   38.17 +ctx.fillText(fillText,10,50);
   38.18 +
   38.19 +//A syntax graph consists of two kinds of nodes: element, port, and property 
   38.20 +//An element node can have sub-elements, and a property node can have
   38.21 +// sub-properties, but a port node may not have sub-ports!
   38.22 +
   38.23 +//this is the top level handle to the syntax graph of the gabe transform rule
   38.24 +var firstGabeTransformRule = {};
   38.25 +
   38.26 +//make a variable that holds an empty element struct.. this var will used
   38.27 +// to build up an element, and then reused to build up other elements 
   38.28 +var tempElem = 
   38.29 + { properties: [],
   38.30 +   portsIn:    [],
   38.31 +   portsOut:   [],
   38.32 +   subElems:   []
   38.33 + };
   38.34 + 
   38.35 +//the root of the Gabe Transform to the temp elem, then build up a property
   38.36 +// to place into the elem.
   38.37 +firstGabeTransformRule.root = tempElem; 
   38.38 +
   38.39 +//build the first property
   38.40 +var tempProperty = 
   38.41 + { propertyName: "TypeOfElement",
   38.42 +   propertyValue: "GabeTransformRule",
   38.43 +   subProperties: []
   38.44 + }
   38.45 + 
   38.46 +//attach it to the root elem
   38.47 +firstGabeTransformRule.root.properties[0] = tempProperty;
   38.48 +
   38.49 +//build and attach the second property
   38.50 +var tempProperty = 
   38.51 + { propertyName: "TypeOfSyntacticStructure",
   38.52 +   propertyValue: "syntacticHierarchy",
   38.53 +   subProperties: []
   38.54 + }
   38.55 +
   38.56 +firstGabeTransformRule.root.properties[1] = tempProperty;
   38.57 +
   38.58 +//now reuse tempElem to make the first sub-element of the root elem 
   38.59 +var tempElem = 
   38.60 + { properties: [],
   38.61 +   portsIn:    [],
   38.62 +   portsOut:   [],
   38.63 +   subElems:   []
   38.64 + }
   38.65 +
   38.66 +firstGabeTransformRule.root.subElems[0] = tempElem;
   38.67 +
   38.68 +var tempProperty = 
   38.69 + { propertyName: "TypeOfElement",
   38.70 +   propertyValue: "GabeQueryPattern",
   38.71 +   subProperties: []
   38.72 + }
   38.73 + 
   38.74 +tempElem.properties[0] = tempProperty;
   38.75 +
   38.76 +var tempProperty =
   38.77 + { propertyName: "TypeOfSyntacticStructure",
   38.78 +   propertyValue: "syntacticHierarchy",
   38.79 +   subProperties: []
   38.80 + }
   38.81 +  
   38.82 +tempElem.properties[1] = tempProperty;
   38.83 +
   38.84 +
   38.85 +//Keep going, building up the graph that was drawn
   38.86 +//make the second sub-element of the root elem, the replacement pattern 
   38.87 +var tempElem = 
   38.88 + { properties: [],
   38.89 +   portsIn:    [],
   38.90 +   portsOut:   [],
   38.91 +   subElems:   []
   38.92 + }
   38.93 +
   38.94 +firstGabeTransformRule.root.subElems[1] = tempElem;
   38.95 +
   38.96 +var tempProperty = 
   38.97 + { propertyName: "TypeOfElement",
   38.98 +   propertyValue: "GabeReplacePattern",
   38.99 +   subProperties: []
  38.100 + }
  38.101 + 
  38.102 +tempElem.properties[0] = tempProperty;
  38.103 +
  38.104 +var tempProperty =
  38.105 + { propertyName: "TypeOfSyntacticStructure",
  38.106 +   propertyValue: "syntacticHierarchy",
  38.107 +   subProperties: []
  38.108 + }
  38.109 +  
  38.110 +tempElem.properties[1] = tempProperty;
  38.111 +
  38.112 +//Now, go back and fill in the rest of the query pattern
  38.113 +//First, add the sub-elements of the query pattern node
  38.114 +var tempElem = 
  38.115 + { properties: [],
  38.116 +   portsIn:    [],
  38.117 +   portsOut:   [],
  38.118 +   subElems:   []
  38.119 + };
  38.120 +
  38.121 +firstGabeTransformRule.root.subElems[0].subElems[0] = tempElem;
  38.122 +
  38.123 +var tempProperty = 
  38.124 + { propertyName: "TypeOfElement",
  38.125 +   propertyValue: "Command",
  38.126 +   subProperties: []
  38.127 + };
  38.128 + 
  38.129 +tempElem.properties[0] = tempProperty;
  38.130 +
  38.131 +var tempProperty =
  38.132 + { propertyName: "CommandID",
  38.133 +   propertyValue: "GabePattPush",
  38.134 +   subProperties: []
  38.135 + };
  38.136 +
  38.137 +tempElem.properties[0].subProperties[0] = tempProperty;
  38.138 +
  38.139 + 
  38.140 +var tempProperty =
  38.141 + { propertyName: "TypeOfSyntacticStructure",
  38.142 +   propertyValue: "syntacticPatternRoot",
  38.143 +   subProperties: []
  38.144 + };
  38.145 +  
  38.146 +tempElem.properties[1] = tempProperty;
  38.147 +
  38.148 +//now add the ports to this Command syntactic pattern
  38.149 +var tempPort =
  38.150 + { element: tempElem,
  38.151 +   properties: [],
  38.152 +   pairedPorts: []
  38.153 + };
  38.154 +
  38.155 +tempElem.portsIn[0] = tempPort;
  38.156 +
  38.157 +//add properties to the port
  38.158 +tempPort.properties[0] =
  38.159 + { propertyName: "TypeOfPort",
  38.160 +   propertyValue: "dataComm",
  38.161 +   subProperties: 
  38.162 +    [{ propertyName: "TypeOfCommData",
  38.163 +      propertyValue: "GabePattStack",
  38.164 +      subProperties: []
  38.165 +    }]
  38.166 + };
  38.167 +
  38.168 +//check that syntax was done correctly..
  38.169 +ctx.fillStyle = foreGroundFill;
  38.170 +fillText = tempPort.properties[0].subProperties[0].propertyName;
  38.171 +
  38.172 +ctx.fillText(fillText,10,50);
  38.173 +
  38.174 +alert("printf!");
  38.175 +
  38.176 +ctx.fillStyle = backGroundFill;
  38.177 +ctx.fillText(fillText,10,50);
  38.178 +
  38.179 +
  38.180 +var tempPort =
  38.181 + { element: tempElem,
  38.182 +   properties: [],
  38.183 +   pairedPorts: []
  38.184 + };
  38.185 +
  38.186 +tempElem.portsIn[1] = tempPort;
  38.187 +
  38.188 +//add properties to the port
  38.189 +tempPort.properties[0] =
  38.190 + { propertyName: "TypeOfPort",
  38.191 +   propertyValue: "dataComm",
  38.192 +   subProperties: 
  38.193 +    [{ propertyName: "TypeOfCommData",
  38.194 +      propertyValue: "float",
  38.195 +      subProperties: []
  38.196 +    }]
  38.197 + };
  38.198 + 
  38.199 +
  38.200 +var tempPort =
  38.201 + { element: tempElem,
  38.202 +   properties: [],
  38.203 +   pairedPorts: []
  38.204 + };
  38.205 +
  38.206 +tempElem.portsOut[0] = tempPort;
  38.207 +
  38.208 +//add properties to the port
  38.209 +tempPort.properties[0] =
  38.210 + { propertyName: "TypeOfPort",
  38.211 +   propertyValue: "dataComm",
  38.212 +   subProperties: 
  38.213 +    [{ propertyName: "TypeOfCommData",
  38.214 +      propertyValue: "GabePattStack",
  38.215 +      subProperties: []
  38.216 +    }]
  38.217 + };
  38.218 +
  38.219 +//First command (push) done!  Now make second command (head)
  38.220 +var tempElem = 
  38.221 + { properties: [],
  38.222 +   portsIn:    [],
  38.223 +   portsOut:   [],
  38.224 +   subElems:   []
  38.225 + };
  38.226 +
  38.227 +firstGabeTransformRule.root.subElems[0].subElems[1] = tempElem;
  38.228 +
  38.229 +//getting tired of the temp this and temp that, just make object directly
  38.230 +tempElem.properties[0] = 
  38.231 + { propertyName: "TypeOfElement",
  38.232 +   propertyValue: "Command",
  38.233 +   subProperties: 
  38.234 +    [{ propertyName: "CommandID",
  38.235 +      propertyValue: "GabePattPop",
  38.236 +      subProperties: []
  38.237 +    }]
  38.238 + };
  38.239 +  
  38.240 +tempElem.properties[1] = 
  38.241 + { propertyName: "TypeOfSyntacticStructure",
  38.242 +   propertyValue: "syntacticPatternRoot",
  38.243 +   subProperties: []
  38.244 + };
  38.245 +
  38.246 +//now add the ports to this Command syntactic pattern
  38.247 +tempElem.portsIn[0] = 
  38.248 + { element: tempElem,
  38.249 +   properties: [],
  38.250 +   pairedPorts: []
  38.251 + };
  38.252 +
  38.253 +//add properties to the port
  38.254 +tempElem.portsIn[0].properties[0] =
  38.255 + { propertyName: "TypeOfPort",
  38.256 +   propertyValue: "dataComm",
  38.257 +   subProperties: 
  38.258 +    [{ propertyName: "TypeOfCommData",
  38.259 +      propertyValue: "GabePattStack",
  38.260 +      subProperties: []
  38.261 +    }]
  38.262 + };
  38.263 +
  38.264 +//next port
  38.265 +tempElem.portsOut[0] = 
  38.266 + { element: tempElem,
  38.267 +   properties: [],
  38.268 +   pairedPorts: []
  38.269 + };
  38.270 +
  38.271 +//add properties to the port
  38.272 +tempElem.portsOut[0].properties[0] =
  38.273 + { propertyName: "TypeOfPort",
  38.274 +   propertyValue: "dataComm",
  38.275 +   subProperties: 
  38.276 +    [{ propertyName: "TypeOfCommData",
  38.277 +      propertyValue: "GabePattStack",
  38.278 +      subProperties: []
  38.279 +    }]
  38.280 + };
  38.281 +
  38.282 +
  38.283 +//next port
  38.284 +tempElem.portsOut[1] = 
  38.285 + { element: tempElem,
  38.286 +   properties: [],
  38.287 +   pairedPorts: []
  38.288 + };
  38.289 +
  38.290 +//add properties to the port
  38.291 +tempElem.portsOut[1].properties[0] =
  38.292 + { propertyName: "TypeOfPort",
  38.293 +   propertyValue: "dataComm",
  38.294 +   subProperties: 
  38.295 +    [{ propertyName: "TypeOfCommData",
  38.296 +      propertyValue: "float",
  38.297 +      subProperties: []
  38.298 +    }]
  38.299 + };
  38.300 +
  38.301 +//now pair the ports to each other
  38.302 +var pushElem = firstGabeTransformRule.root.subElems[0].subElems[0];
  38.303 +var popElem = firstGabeTransformRule.root.subElems[0].subElems[1];
  38.304 +
  38.305 +pushElem.portsOut[0].pairedPorts[0] =
  38.306 +   popElem.portsIn[0];
  38.307 +popElem.portsIn[0].pairedPorts[0] =
  38.308 +   pushElem.portsOut[0];
  38.309 +
  38.310 +//Done with the query pattern!
  38.311 +
  38.312 +//========================================
  38.313 +//Now do the replace pattern
  38.314 +//========================================
  38.315 +var tempElem = 
  38.316 + { properties: [],
  38.317 +   portsIn:    [],
  38.318 +   portsOut:   [],
  38.319 +   subElems:   []
  38.320 + };
  38.321 +
  38.322 +firstGabeTransformRule.root.subElems[1].subElems[0] = tempElem;
  38.323 +
  38.324 +//This is the pass through command element
  38.325 +tempElem.properties[0] = 
  38.326 + { propertyName: "TypeOfElement",
  38.327 +   propertyValue: "Command",
  38.328 +   subProperties: 
  38.329 +    [{ propertyName: "CommandID",
  38.330 +      propertyValue: "GabePassThrough",
  38.331 +      subProperties: []
  38.332 +    }]
  38.333 + };
  38.334 +
  38.335 +tempElem.properties[1] = 
  38.336 + { propertyName: "TypeOfSyntacticStructure",
  38.337 +   propertyValue: "syntacticPatternRoot",
  38.338 +   subProperties: []
  38.339 + };
  38.340 +
  38.341 +//now add the ports to this Command syntactic pattern
  38.342 +tempElem.portsIn[0] = 
  38.343 + { element: tempElem,
  38.344 +   properties: [],
  38.345 +   pairedPorts: []
  38.346 + };
  38.347 +
  38.348 +//add properties to the port
  38.349 +tempElem.portsIn[0].properties[0] =
  38.350 + { propertyName: "TypeOfPort",
  38.351 +   propertyValue: "dataComm",
  38.352 +   subProperties: 
  38.353 +    [{ propertyName: "TypeOfCommData",
  38.354 +      propertyValue: "GabePattStack",
  38.355 +      subProperties: []
  38.356 +    }]
  38.357 + };
  38.358 +
  38.359 +//next port
  38.360 +tempElem.portsIn[1] = 
  38.361 + { element: tempElem,
  38.362 +   properties: [],
  38.363 +   pairedPorts: []
  38.364 + };
  38.365 +
  38.366 +//add properties to the port
  38.367 +tempElem.portsIn[1].properties[0] =
  38.368 + { propertyName: "TypeOfPort",
  38.369 +   propertyValue: "dataComm",
  38.370 +   subProperties: 
  38.371 +    [{ propertyName: "TypeOfCommData",
  38.372 +      propertyValue: "float",
  38.373 +      subProperties: []
  38.374 +    }]
  38.375 + };
  38.376 +
  38.377 +
  38.378 +//next port
  38.379 +tempElem.portsOut[0] = 
  38.380 + { element: tempElem,
  38.381 +   properties: [],
  38.382 +   pairedPorts: []
  38.383 + };
  38.384 +
  38.385 +//add properties to the port
  38.386 +tempElem.portsOut[0].properties[0] =
  38.387 + { propertyName: "TypeOfPort",
  38.388 +   propertyValue: "dataComm",
  38.389 +   subProperties: 
  38.390 +    [{ propertyName: "TypeOfCommData",
  38.391 +      propertyValue: "GabePattStack",
  38.392 +      subProperties: []
  38.393 +    }]
  38.394 + };
  38.395 +
  38.396 +
  38.397 +//next port
  38.398 +tempElem.portsOut[1] = 
  38.399 + { element: tempElem,
  38.400 +   properties: [],
  38.401 +   pairedPorts: []
  38.402 + };
  38.403 +
  38.404 +//add properties to the port
  38.405 +tempElem.portsOut[1].properties[0] =
  38.406 + { propertyName: "TypeOfPort",
  38.407 +   propertyValue: "dataComm",
  38.408 +   subProperties: 
  38.409 +    [{ propertyName: "TypeOfCommData",
  38.410 +      propertyValue: "float",
  38.411 +      subProperties: []
  38.412 +    }]
  38.413 + };
  38.414 +
  38.415 +//no paired ports in this one..  done done!!
  38.416 +
  38.417 +//print a few things, just to make sure the data structs are correctly
  38.418 +// created and can be traversed.
  38.419 +ctx.fillStyle = foreGroundFill;
  38.420 +var passThroughCmd = firstGabeTransformRule.root.subElems[1].subElems[0];
  38.421 +fillText = passThroughCmd.portsOut[1].properties[0].subProperties[0].propertyValue;
  38.422 +
  38.423 +ctx.fillText(fillText,10,50);
  38.424 +
  38.425 +var el2 =  document.createElement("printf")
  38.426 +el2.style.display="block";
  38.427 +el2.style.width="100%";
  38.428 +el2.innerHTML = fillText;
  38.429 +document.body.appendChild(el2);
  38.430 +
  38.431 +alert("printf!");
  38.432 +
  38.433 +ctx.fillStyle = backGroundFill;
  38.434 +ctx.fillText(fillText,10,50);
  38.435 +
  38.436 +document.body.removeChild(el2);
  38.437 +
  38.438 +
  38.439 +
  38.440 +
  38.441 +
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/GabePattern/loadGabePattern.html	Sun Jul 06 12:02:12 2014 -0700
    39.3 @@ -0,0 +1,16 @@
    39.4 +<!DOCTYPE html>
    39.5 +<html>
    39.6 +<body>
    39.7 +
    39.8 +<canvas id="POPCanvas" width="400" height="400" style="border:1px solid #000000;">
    39.9 +Your browser does not support the HTML5 canvas tag.
   39.10 +</canvas>
   39.11 +
   39.12 +
   39.13 +<script src="GabePattern_data_structs.js">
   39.14 +</script>
   39.15 +
   39.16 +</body>
   39.17 +</html>
   39.18 +
   39.19 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/A.svg	Sun Jul 06 12:02:12 2014 -0700
    40.3 @@ -0,0 +1,7 @@
    40.4 +<?xml version="1.0" standalone="no"?>
    40.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    40.6 +  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    40.7 +<svg width="100px" height="100px" viewBox="0 0 200 200"
    40.8 +     xmlns="http://www.w3.org/2000/svg" version="1.1">  
    40.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">A</text>
   40.10 +</svg>
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/B.svg	Sun Jul 06 12:02:12 2014 -0700
    41.3 @@ -0,0 +1,7 @@
    41.4 +<?xml version="1.0" standalone="no"?>
    41.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    41.6 +  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    41.7 +<svg width="100px" height="100px" viewBox="0 0 200 200"
    41.8 +     xmlns="http://www.w3.org/2000/svg" version="1.1">  
    41.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">B</text>
   41.10 +</svg>
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/cubic.svg.xml	Sun Jul 06 12:02:12 2014 -0700
    42.3 @@ -0,0 +1,19 @@
    42.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    42.5 +<?xml-stylesheet href="styles-svg.css" type="text/css"?>
    42.6 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    42.7 +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 499 499" preserveAspectRatio="xMidYMid meet">
    42.8 +	<title>SVG curve</title>
    42.9 +	<desc>example curves in SVG</desc>
   42.10 +	<g id="main">
   42.11 +		<circle id="p1" cx="100" cy="250" r="16" />
   42.12 +		<circle id="p2" cx="400" cy="250" r="16" />
   42.13 +		
   42.14 +		<circle id="c1" cx="100" cy="100" r="8" />
   42.15 +		<circle id="c2" cx="400" cy="100" r="8" />
   42.16 +		
   42.17 +		<line id="l1" x1="100" y1="250" x2="100" y2="100" />
   42.18 +		<line id="l2" x1="400" y1="250" x2="400" y2="100" />
   42.19 +	
   42.20 +		<path id="curve" d="M100,250 C100,100 400,100 400,250" />
   42.21 +	</g>
   42.22 +</svg>
   42.23 \ No newline at end of file
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.html	Sun Jul 06 12:02:12 2014 -0700
    43.3 @@ -0,0 +1,33 @@
    43.4 +<!DOCTYPE html>
    43.5 +<html lang="en">
    43.6 +<head>
    43.7 +<meta charset="UTF-8" />
    43.8 +<title>SVG Cubic B&#233;zier Curve Example</title>
    43.9 +</head>
   43.10 +<link rel="stylesheet" type="text/css" media="all" href="styles.css" />
   43.11 +<body>
   43.12 +
   43.13 +<h1>SVG Cubic B&#233;zier Curve Example</h1>
   43.14 +
   43.15 +<object id="svg" type="image/svg+xml" data="cubic.svg.xml" class="C">Your browser does not support SVG</object>
   43.16 +<pre id="code">code</pre>
   43.17 +
   43.18 +<p>This demonstration shows how cubic b&#233;zier curves can be drawn on an SVG. </p>
   43.19 +
   43.20 +<p>Drag the line ends or the control points to change the curve. Click the curve to toggle the fill.</p>
   43.21 +
   43.22 +<p>For more information, please refer to:<br />
   43.23 +<a href="http://www.sitepoint.com/html5-svg-cubic-curves/">How to Draw Cubic Bezier Curves on HTML5 SVGs</a></p>
   43.24 +
   43.25 +<p>See also:<br />
   43.26 +<a href="http://blogs.sitepoint.com/html5-svg-quadratic-curves/">How to Draw Quadratic B&#233;zier Curves on HTML5 SVGs</a><br />
   43.27 +<a href="http://blogs.sitepoint.com/svg-path-element/">How to Create Complex Paths in SVGs</a></p>
   43.28 +
   43.29 +<h2>Disclaimer</h2>
   43.30 +<p>The code was developed by <a href="http://twitter.com/craigbuckler">Craig Buckler</a> of <a href="http://optimalworks.net/">OptimalWorks.net</a> for <a href="http://sitepoint.com/">SitePoint.com</a>.</p>
   43.31 +
   43.32 +<p>This code can be used without any restrictions but please don't expect 24/7 support! A link back to SitePoint.com is appreciated.</p>
   43.33 +
   43.34 +<script type="text/javascript" src="curves.js"></script>
   43.35 +</body>
   43.36 +</html>
   43.37 \ No newline at end of file
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/curves.js	Sun Jul 06 12:02:12 2014 -0700
    44.3 @@ -0,0 +1,142 @@
    44.4 +/* 
    44.5 + * SVG curve example
    44.6 + *
    44.7 + * By Craig Buckler,		http://twitter.com/craigbuckler
    44.8 + * of OptimalWorks.net		http://optimalworks.net/
    44.9 + * for SitePoint.com		http://sitepoint.com/
   44.10 + * 
   44.11 + * Refer to:
   44.12 + * http://www.sitepoint.com/html5-svg-quadratic-curves/
   44.13 + * http://www.sitepoint.com/html5-svg-cubic-curves/
   44.14 + *
   44.15 + * This code can be used without restrictions.
   44.16 + */
   44.17 +
   44.18 +(function() {
   44.19 +
   44.20 +	var container, svg, cType, code, point = {}, line = {}, fill = false, drag = null, dPoint, maxX, maxY;
   44.21 +
   44.22 +	// define initial points
   44.23 +	function Init() {
   44.24 +
   44.25 +		var c = svg.getElementsByTagName("circle");
   44.26 +		for (var i = 0; i < c.length; i++) {
   44.27 +			point[c[i].getAttributeNS(null,"id")] = {
   44.28 +				x: parseInt(c[i].getAttributeNS(null,"cx"),10),
   44.29 +				y: parseInt(c[i].getAttributeNS(null,"cy"),10)
   44.30 +			};
   44.31 +		}
   44.32 +		
   44.33 +		// lines
   44.34 +		line.l1 = svg.getElementById("l1");
   44.35 +		line.l2 = svg.getElementById("l2");
   44.36 +		line.curve = svg.getElementById("curve");
   44.37 +		
   44.38 +		// code
   44.39 +		code = document.getElementById("code");
   44.40 +	
   44.41 +		// event handlers
   44.42 +		svg.onmousedown = svg.onmousemove = svg.onmouseup = Drag;
   44.43 +		svg.ontouchstart = svg.ontouchmove = svg.ontouchend = Drag;
   44.44 +		
   44.45 +		DrawSVG();
   44.46 +	}
   44.47 +	
   44.48 +	
   44.49 +	// draw curve
   44.50 +	function DrawSVG() {
   44.51 +	
   44.52 +		// control line 1
   44.53 +		line.l1.setAttributeNS(null, "x1", point.p1.x);
   44.54 +		line.l1.setAttributeNS(null, "y1", point.p1.y);
   44.55 +		line.l1.setAttributeNS(null, "x2", point.c1.x);
   44.56 +		line.l1.setAttributeNS(null, "y2", point.c1.y);
   44.57 +		
   44.58 +		// control line 2
   44.59 +		var c2 = (point.c2 ? "c2" : "c1");
   44.60 +		line.l2.setAttributeNS(null, "x1", point.p2.x);
   44.61 +		line.l2.setAttributeNS(null, "y1", point.p2.y);
   44.62 +		line.l2.setAttributeNS(null, "x2", point[c2].x);
   44.63 +		line.l2.setAttributeNS(null, "y2", point[c2].y);
   44.64 +		
   44.65 +		// curve
   44.66 +		var d = 
   44.67 +			"M"+point.p1.x+","+point.p1.y+" "+cType+
   44.68 +			point.c1.x+","+point.c1.y+" "+
   44.69 +			(point.c2 ? point.c2.x+","+point.c2.y+" " : "")+
   44.70 +			point.p2.x+","+point.p2.y+
   44.71 +			(fill ? " Z" : "");
   44.72 +		line.curve.setAttributeNS(null, "d", d);
   44.73 +		
   44.74 +		// show code
   44.75 +		if (code) {
   44.76 +			code.textContent = '<path d="'+d+'" />';
   44.77 +		}
   44.78 +	}
   44.79 +	
   44.80 +	
   44.81 +	// drag event handler
   44.82 +	function Drag(e) {
   44.83 +		
   44.84 +		e.stopPropagation();
   44.85 +		var t = e.target, id = t.id, et = e.type, m = MousePos(e);
   44.86 +	
   44.87 +		// toggle fill class
   44.88 +		if (!drag && et == "mousedown" && id == "curve") {
   44.89 +			fill = !fill;
   44.90 +			t.setAttributeNS(null, "class", (fill ? "fill" : ""));
   44.91 +			DrawSVG();
   44.92 +		}
   44.93 +	
   44.94 +		// start drag
   44.95 +		if (!drag && typeof(point[id]) != "undefined" && (et == "mousedown" || et == "touchstart")) {
   44.96 +			drag = t;
   44.97 +			dPoint = m;
   44.98 +		}
   44.99 +		
  44.100 +		// drag
  44.101 +		if (drag && (et == "mousemove" || et == "touchmove")) {
  44.102 +			id = drag.id;
  44.103 +			point[id].x += m.x - dPoint.x;
  44.104 +			point[id].y += m.y - dPoint.y;
  44.105 +			dPoint = m;
  44.106 +			drag.setAttributeNS(null, "cx", point[id].x);
  44.107 +			drag.setAttributeNS(null, "cy", point[id].y);
  44.108 +			DrawSVG();
  44.109 +		}
  44.110 +		
  44.111 +		// stop drag
  44.112 +		if (drag && (et == "mouseup" || et == "touchend")) {
  44.113 +			drag = null;
  44.114 +		}
  44.115 +	
  44.116 +	}
  44.117 +
  44.118 +	
  44.119 +	// mouse position
  44.120 +	function MousePos(event) {
  44.121 +		return {
  44.122 +			x: Math.max(0, Math.min(maxX, event.pageX)),
  44.123 +			y: Math.max(0, Math.min(maxY, event.pageY))
  44.124 +		}
  44.125 +	}
  44.126 +	
  44.127 +	
  44.128 +	// start
  44.129 +	window.onload = function() {
  44.130 +		container = document.getElementById("svg");
  44.131 +		if (container) {
  44.132 +			cType = container.className;
  44.133 +			maxX = container.offsetWidth-1;
  44.134 +			maxY = container.offsetHeight-1;
  44.135 +			svg = container.contentDocument;
  44.136 +			Init();
  44.137 +		}
  44.138 +	}
  44.139 +	
  44.140 +})();
  44.141 +
  44.142 + 
  44.143 +
  44.144 +
  44.145 +
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles-svg.css	Sun Jul 06 12:02:12 2014 -0700
    45.3 @@ -0,0 +1,34 @@
    45.4 +/* SVG styles */
    45.5 +path
    45.6 +{
    45.7 +	stroke-width: 8;
    45.8 +	stroke: #000;
    45.9 +	stroke-linecap: round;
   45.10 +	fill: none;
   45.11 +}
   45.12 +
   45.13 +path.fill
   45.14 +{
   45.15 +	fill: #3ff;
   45.16 +}
   45.17 +
   45.18 +circle
   45.19 +{
   45.20 +	stroke-width: 2;
   45.21 +	stroke: #c00;
   45.22 +	fill: #fff;
   45.23 +}
   45.24 +
   45.25 +circle:hover
   45.26 +{
   45.27 +	fill: #c00;
   45.28 +	cursor: move;
   45.29 +}
   45.30 +
   45.31 +line
   45.32 +{
   45.33 +	stroke-width: 1;
   45.34 +	stroke: #999;
   45.35 +	stroke-linecap: round;
   45.36 +	stroke-dasharray: 5,3;
   45.37 +}
   45.38 \ No newline at end of file
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/bezier/styles.css	Sun Jul 06 12:02:12 2014 -0700
    46.3 @@ -0,0 +1,53 @@
    46.4 +/* CSS */
    46.5 +body
    46.6 +{
    46.7 +	font-family: arial, helvetica, sans-serif;
    46.8 +	font-size: 85%;
    46.9 +	margin: 10px 15px;
   46.10 +	color: #333;
   46.11 +	background-color: #ddd;
   46.12 +}
   46.13 +
   46.14 +h1
   46.15 +{
   46.16 +	font-size: 1.6em;
   46.17 +	font-weight: normal;
   46.18 +	margin: 0 0 0.3em 0;
   46.19 +}
   46.20 +
   46.21 +h2
   46.22 +{
   46.23 +	font-size: 1.4em;
   46.24 +	font-weight: normal;
   46.25 +	margin: 1.5em 0 0 0;
   46.26 +}
   46.27 +
   46.28 +p
   46.29 +{
   46.30 +	margin: 1em 0;
   46.31 +}
   46.32 +
   46.33 +#svg
   46.34 +{
   46.35 +	display: inline;
   46.36 +	float: left;
   46.37 +	width: 500px;
   46.38 +	height: 500px;
   46.39 +	margin: 0 10px 10px 0;
   46.40 +	background-color: #fff;
   46.41 +}
   46.42 +
   46.43 +#code
   46.44 +{
   46.45 +	display: block;
   46.46 +	width: auto;
   46.47 +	height: 4em;
   46.48 +	font-family: monospace;
   46.49 +	font-size: 1.2em;
   46.50 +	padding: 2px 4px;
   46.51 +	margin: 0;
   46.52 +	color: #555;
   46.53 +	background-color: #eee;
   46.54 +	border: 1px solid #999;
   46.55 +	overflow: auto;
   46.56 +}
   46.57 \ No newline at end of file
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/box.svg	Sun Jul 06 12:02:12 2014 -0700
    47.3 @@ -0,0 +1,8 @@
    47.4 +<?xml version="1.0" standalone="no"?>
    47.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    47.6 +  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    47.7 +<svg width="400" height="400" viewBox="0 0 400 400"
    47.8 +     xmlns="http://www.w3.org/2000/svg" version="1.1">  
    47.9 +<rect x="10" y="10" width="380" height="380" 
   47.10 +fill="white" stroke="black" stroke-width="10"  />
   47.11 +</svg>
   47.12 \ No newline at end of file
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/inkscape_sigma.svg	Sun Jul 06 12:02:12 2014 -0700
    48.3 @@ -0,0 +1,70 @@
    48.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    48.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    48.6 +
    48.7 +<svg
    48.8 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    48.9 +   xmlns:cc="http://creativecommons.org/ns#"
   48.10 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   48.11 +   xmlns:svg="http://www.w3.org/2000/svg"
   48.12 +   xmlns="http://www.w3.org/2000/svg"
   48.13 +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   48.14 +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   48.15 +   width="744.09448819"
   48.16 +   height="1052.3622047"
   48.17 +   id="svg2"
   48.18 +   version="1.1"
   48.19 +   inkscape:version="0.48.2 r9819"
   48.20 +   sodipodi:docname="New document 1">
   48.21 +  <defs
   48.22 +     id="defs4" />
   48.23 +  <sodipodi:namedview
   48.24 +     id="base"
   48.25 +     pagecolor="#ffffff"
   48.26 +     bordercolor="#666666"
   48.27 +     borderopacity="1.0"
   48.28 +     inkscape:pageopacity="0.0"
   48.29 +     inkscape:pageshadow="2"
   48.30 +     inkscape:zoom="0.82"
   48.31 +     inkscape:cx="375"
   48.32 +     inkscape:cy="878.31441"
   48.33 +     inkscape:document-units="px"
   48.34 +     inkscape:current-layer="layer1"
   48.35 +     showgrid="false"
   48.36 +     inkscape:window-width="1063"
   48.37 +     inkscape:window-height="832"
   48.38 +     inkscape:window-x="125"
   48.39 +     inkscape:window-y="0"
   48.40 +     inkscape:window-maximized="0" />
   48.41 +  <metadata
   48.42 +     id="metadata7">
   48.43 +    <rdf:RDF>
   48.44 +      <cc:Work
   48.45 +         rdf:about="">
   48.46 +        <dc:format>image/svg+xml</dc:format>
   48.47 +        <dc:type
   48.48 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   48.49 +        <dc:title></dc:title>
   48.50 +      </cc:Work>
   48.51 +    </rdf:RDF>
   48.52 +  </metadata>
   48.53 +  <g
   48.54 +     inkscape:label="Layer 1"
   48.55 +     inkscape:groupmode="layer"
   48.56 +     id="layer1">
   48.57 +    <g
   48.58 +       id="g3759">
   48.59 +      <path
   48.60 +         sodipodi:nodetypes="ccc"
   48.61 +         inkscape:connector-curvature="0"
   48.62 +         id="path2985"
   48.63 +         d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806"
   48.64 +         style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
   48.65 +      <path
   48.66 +         style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
   48.67 +         d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806"
   48.68 +         id="path3757"
   48.69 +         inkscape:connector-curvature="0"
   48.70 +         sodipodi:nodetypes="ccc" />
   48.71 +    </g>
   48.72 +  </g>
   48.73 +</svg>
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/plus.svg	Sun Jul 06 12:02:12 2014 -0700
    49.3 @@ -0,0 +1,7 @@
    49.4 +<?xml version="1.0" standalone="no"?>
    49.5 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    49.6 +  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    49.7 +<svg width="100px" height="100px" viewBox="0 0 200 200"
    49.8 +     xmlns="http://www.w3.org/2000/svg" version="1.1">  
    49.9 +<text x="50" y="50" font-size="20" font-family="Arial Sans" fill="red" text-anchor="end">+</text>
   49.10 +</svg>
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/SVG_shapes/sigma.svg	Sun Jul 06 12:02:12 2014 -0700
    50.3 @@ -0,0 +1,42 @@
    50.4 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    50.5 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    50.6 +
    50.7 +<svg
    50.8 +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    50.9 +   xmlns:cc="http://creativecommons.org/ns#"
   50.10 +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   50.11 +   xmlns:svg="http://www.w3.org/2000/svg"
   50.12 +   xmlns="http://www.w3.org/2000/svg"
   50.13 +   version="1.1"
   50.14 +   width="744.09448"
   50.15 +   height="1052.3622"
   50.16 +   id="svg2">
   50.17 +  <defs
   50.18 +     id="defs4" />
   50.19 +  <metadata
   50.20 +     id="metadata7">
   50.21 +    <rdf:RDF>
   50.22 +      <cc:Work
   50.23 +         rdf:about="">
   50.24 +        <dc:format>image/svg+xml</dc:format>
   50.25 +        <dc:type
   50.26 +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
   50.27 +        <dc:title></dc:title>
   50.28 +      </cc:Work>
   50.29 +    </rdf:RDF>
   50.30 +  </metadata>
   50.31 +  <g
   50.32 +     id="layer1">
   50.33 +    <g
   50.34 +       id="g3759">
   50.35 +      <path
   50.36 +         d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806"
   50.37 +         id="path2985"
   50.38 +         style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
   50.39 +      <path
   50.40 +         d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806"
   50.41 +         id="path3757"
   50.42 +         style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
   50.43 +    </g>
   50.44 +  </g>
   50.45 +</svg>
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/ToDos__14_Jy_02.txt	Sun Jul 06 12:02:12 2014 -0700
    51.3 @@ -0,0 +1,173 @@
    51.4 +
    51.5 +#-] Create skeleton of system
    51.6 +#- -] create an app module that acts as test scaffolding
    51.7 +#- -] create a Display module and a visualizer module
    51.8 +#- -] in the app, create the display and visualizer and connect them
    51.9 +#- -] in the app, create the GabePattern syntax graph inside the srcHolder, and set that to be what gets visualized.
   51.10 +#- -] in app, trigger the visualizer to generate a view hierarchy and send it to the display, which in turn triggers display to generate famous render tree.
   51.11 +
   51.12 +//====== Visualizer ======
   51.13 +//=
   51.14 +//========================
   51.15 +-] make a function that accepts a native syntax graph and builds a view hierarchy from it, then hands that view hierarchy data structure to the Display
   51.16 +#- -] First, make the prototype, with skeleton of internal structure
   51.17 +- -] second, do by-hand code that creates the view hierarchy of the two-box visualization of part of the syntax graph of the GabePattern example
   51.18 +
   51.19 +
   51.20 +//====== Display ======
   51.21 +//=
   51.22 +//========================
   51.23 +-] make a function that accepts a view hierarchy data structure and builds a famous render tree from that
   51.24 +#- -] first, make the prototype and skeleton of internal structure
   51.25 +
   51.26 +
   51.27 +=====================
   51.28 +# -] So, the task at hand is to draw a single syntax graph element, by using famous.  After that, add transforms that change the size.. then ones that shift positions.. and so on, go from there..  until have a syntax graph drawn.  
   51.29 +# - -] Try taking an SVG representation of the round-cornered box and converting that to whatever famous takes as its native vector graphic/drawing format.  Saw a googled thing about a converter from svg to something famous understood, like some form of opengl or something.
   51.30 +
   51.31 +# -] Get SVG working with famous -- draw the sigma example, hard-coding it, with SVG copied from inkscape output.
   51.32 +
   51.33 +#-] Q: how to remove a node from the render tree?  Or from a context surface?
   51.34 +-[] A: CAN'T!!!!!  Have to regenerate the whole damn thing!
   51.35 +
   51.36 +#-] Get famous working without a net connection -- download whatever URLs that the page references, so are local files.
   51.37 +
   51.38 +-] Get famous fonts -- download to local somehow..
   51.39 +
   51.40 +#-] Figure out how that other graph drawing thing made the curvy arrow-lines between nodes..
   51.41 +
   51.42 +#-] Get bezier curves in SVG working on syntax graph page, going between text surface and middle of target box side, with control points set to mix x of one end point with y of other end point
   51.43 +
   51.44 +XXX -] Next, draw two element nodes, complete with properties and ports, with linked ports -- so know correct code, that is known to work. [-] don't need to go this far, all the essential elements have been hit.
   51.45 +
   51.46 +#-] Look back at Java stuff, see what were doing for structure sent from visualizer to Display
   51.47 +[-] Were also doing a hierarchy of bounding boxes
   51.48 +[-] Were parsing the syntax graph -- generate a bounding box and visual contents for each kind of element in the syntax graph
   51.49 +
   51.50 +-] Next, define a data structure for the visual elements.
   51.51 +- -] within it is the information needed to construct the graph that have drawn
   51.52 +- -] see below for visual element design.. and #look back over java version..
   51.53 +
   51.54 +-] Next, take the syntax graph for the GabePatterns, create the visual elements to represent that.
   51.55 +
   51.56 +-] Next, write the Display object to receive the visual elements, and then create the famous objects from it, which end up painting the syntax graph elements as seen in the PDF.
   51.57 +
   51.58 +-] Next, create the visual element objects for the rest of the syntax graph, and have them all draw to the screen, using famous.
   51.59 +
   51.60 +-] Make a Display object, which contains the code wrote above.
   51.61 +
   51.62 +-] Have the Display object receive the visual element object, and proceed to draw it to the screen using famous.  Choose a protocol for handing visual element objects to the Display and triggering the Display to render them via famous.
   51.63 +
   51.64 +-] Make the visual elements for a graph of 5 nodes.  hand them to the display.
   51.65 +
   51.66 +-] Make a "change" visual element.  Have the display modify its famous structure according to the change visual element.
   51.67 +
   51.68 +
   51.69 +-] Separately, the task is to construct a visual hierarchy structure inside the visualizer..  then to convert that into visual elements..  then to receive those elements in the famous display, and reconstruct a famous structure from the stream of visual elements.
   51.70 +
   51.71 +-] Create a source holder object.. just a simple thing, as a place holder
   51.72 +
   51.73 +-] dump the syntax graph wrote for Gabe out to a JSON file
   51.74 +
   51.75 +-] have the source holder object load the JSON in, and convert to the javascript objects wrote for Gabe
   51.76 +
   51.77 +-] Then, make a new object, just one syntax graph element, as above.  Send it to a JSON file.  Have the source holder read it in and convert to javascript object.
   51.78 +
   51.79 +-] make a visualizer object inside the source holder
   51.80 +
   51.81 +-] give the visualizer access to the data structure inside the holder, which is the syntax graph
   51.82 +
   51.83 +-] have the visualizer build its own data structure?  Or augment the existing one with new stuff?  Add a visualizer field to all of the syntax graph nodes?  Make it an array, one spot for each visualizer added to the source holder?
   51.84 +
   51.85 +-] Go with augment for now, even though feels like it's mixing things dangerously..  it, on the other hand, puts the visualization right into the data visualized, so keeps the two in sync -- no danger of something modifying the data behind the back of the visualizer..
   51.86 +
   51.87 +-] make the augmentation for the one syntax graph element created above.
   51.88 +
   51.89 +-] have the visualizer generate a visual element object from that simple graph.
   51.90 +
   51.91 +-] have the visualizer send that visual element to the display created above, which 
   51.92 +
   51.93 +-] Draw the visual hierarchy structure, which is separate from the syntax graph data.  Perhaps make them both the same data structures, just add visual objects as properties (which are ignored by everything thing else, like the compiler)
   51.94 +
   51.95 +-] The javascript structure of linked objects will be internal to the source holder.  The visualizer will take that and construct stream of visual elements from it.  The modifier will directly modify it.  The holder will also have a serialized version of the data structure -- which is JSON format.  The data structure will be made such that can use the JSON tools to directly turn it into JSON, save that to a file, then later read the file back, and use the JSON tool to parse the JSON back into the javascript linked objects.
   51.96 +
   51.97 +-] The modifier will attach additional objects and properties, which are used to manage interaction with something that is editing the source..  for example, an insertion point is maintained, and highlight markings, and selection markings.  (maybe multiple selections, and even browse through previous selections, and fork off one)
   51.98 +
   51.99 +-] The modifier will notify the visualizer of what changed, each time it does a change.  The visualizer can then decide what needs to be re-sent to the display, and can decide new visual placements of things, if needed..
  51.100 +
  51.101 +
  51.102 +==============================================
  51.103 +=
  51.104 +=
  51.105 +==============================================
  51.106 +So, question..  what do display list elements look like?  Does visualizer produce the layout, for example, specify a bounding box and position for each element, including text, lines, etc?  Does it produce the bezier curves in SVG that connect syntax graph elements?
  51.107 +
  51.108 +Or, does it send something with fewer details?  Let the Display calculate exact placement of visual elements?
  51.109 +
  51.110 +What about pan and zoom?  Does Visualizer handle that, or Display..  pan means moving some elements out of the painted canvas and moving others in..  zoom does too, in addition to calculating new transforms for each element painted..  So, if Display does this, then it must either have all the visual elements in it, or else it much send a request to Visualizer that triggers sending what's needed..
  51.111 +
  51.112 +Soooo..  make a two-way path between Display and Visualizer, in order to handle pan, zoom, 3D rotates, and so forth?
  51.113 +
  51.114 +Orrrr..  leave that to the MVDM loop..  the pan/zoom/rotate gestures go into the command-maker, and thence into the visualizer, which then sends view update..
  51.115 +
  51.116 +sooo..  this view update stuff..  does Display keep a full representation of the visual elements, and then translate that into Famo.us elements?  Or, does it keep, say, a current visualizer list..  where visualizer updates simply modify the previous list sent..  then Display translates the updated list into Famo.us elements..  given that Famo.us doesn't support removing render tree elements, that might be a good approach..  and it simplifies the thing about how to figure out what a visualizer update is and what to do with it inside the Display.
  51.117 +
  51.118 +Okay.. now..  just need to figure out what the Visualizer actually sends..  how much detail..
  51.119 +
  51.120 +You know what?  I don't want to think about it!  Just going to do something, see what happens, and then can modify later..  probably will never get modified, these choices have a way of sticking, due to momentum of volume of work and low improvement in changing..  but, don't want to stall myself, need to keep moving..
  51.121 +
  51.122 +sooooo...  something has to calculate placement of bounding boxes, and calculate translations and sizing..  and move things in and out based on zoom, pan, rotate..  and trigger redraws and resends of display data for graphs and calculation results..  seems like if put placement and transform calcs inside Display then are making the Display an active thing, giving it intelligence and control..  then, run into problems when have a view that is composed of pieces from many different holders and different processors..  for example, displaying a worksheet, where the worksheet itself is in a holder that generates a view, and locations on the worksheet are calculated by live processors, and locations are graphs which are generated by graphing processors that take calculations from other processors..  want the worksheet holder to handle generating the view, and collecting the data from the other processors..  don't want the Display to have any kind of intelligence related to this!  
  51.123 +
  51.124 +Hmmm..  so, if the worksheet holder is doing all of the collecting of data and triggering re-calcs, and melding together into a view..  then Display is simply passively painting that and collecting gestures that it sends back..  the holder then knows what to do with the gestures performed upon view elements..  
  51.125 +
  51.126 +So that means that the Display should not be calculating pan and zoom and rotate!!  Those are responses to gestures, and those trigger behaviors from the visualizer (which may, in turn, have to trigger behaviors from other processors in order to get updated calcs to put into the view)
  51.127 +
  51.128 +Got it, so as tempting as it is to peel off such gestures in the Display and build intelligence into there..  it will cause problems..  so best to have all the visual related processing be done inside the visualizers..  
  51.129 +
  51.130 +so..  means the visualizer should send out things pretty close to renderable..
  51.131 +
  51.132 +Now.  The question comes up..  what format?  Does the visualizer send out SVG?  Is that universal enough?  Will that cause problems with non-browser based approaches?  If not SVG, then what?  Will need to represent paths..  does visualizer calculate Bezier curves and send those?  Or does it just say "here are end points, connect these with a smooth path"?  Does the visualizer calculate how to route arcs within a graph around the other nodes in an optimal way?  If the user supplies helpers by moving things, does the Display remember that, or the Visualizer?  
  51.133 +
  51.134 +Ahhhh..  okay..  if what the user to be able to affect the visual arrangement, then need to remember the gestures they give that are related to visual arrangement..  for example, they grab bezier control points and move them, in order to affect a curve, or add new points within a path in order to route it..  those things have to be remembered!  The Display has no place to store such things!!
  51.135 +
  51.136 +Right..  that means that the holder must store info related to viewing the holder contents!  sooooo..  the visualizer must be the thing that generates any details that a person may want to adjust.
  51.137 +
  51.138 +Right.  Any visual arrangement that a person might want to adjust must be stored inside the holder, and so the visualizer must be the thing that generates that level of detail.  Right.  Got it.
  51.139 +
  51.140 +So.  Yes.  That means that the visualizer must send out bounding boxes, translations, sizing, path points, control points, and so forth.  So.  Yes.  SVG is looking like a good way to go..  has to be something!  Can invent my own equivalent, which specifies paths, shapes, widths, and so forth..  but what is the gain?  The only potential is sending in binary, to save the overhead of SVG's text embodiment.  The savings worth the effort?  NO!
  51.141 +
  51.142 +Okay then.  SVG.  That is the visualizer's format for POP.  Or perhaps it just sends the values that go into the SVG?  The Display does the final conversion to text-based SVG format?  Hmmmm, what about custom syntax, which is SVG from the programmer?  Just send indication of SVG elements, together with the values?  Maybe enums for the SVG indicators, or something..
  51.143 +
  51.144 +Now.  Question is, how much effort?  Is it more effort to send a representation, then construct text-repr inside Display?  Or more effort to construct SVG text in visualizer and send it ready-made?
  51.145 +
  51.146 +Seems easier to just construct SVG text inside visualizer and send that.. 
  51.147 +
  51.148 +Heck, if send representation, then are already forcing SVG!  It doesn't constrain the Display if send the text form..  the display is just as free to convert the binary form to something else as it is to convert the text form to something else..  so if Display is not browser, and doesn't have SVG drawing primitives, it has to do the extra step of parsing SVG in order to extract the values from the text, and then generate whatever internal form it has, such as calculating paths or even pixels itself..  the extraction from text does not seem like a terribly large burden compared to the rest.
  51.149 +
  51.150 +Buuuut..  don't really care!  Going to generate text form inside visualizer, because, why not?  Then the Display only translates displayList elements into its internal thing that paints.  In the case of browser, Display translates display list into famo.us elements, placing the SVG verbatim onto famous surfaces, and makes the SVG bounding box the same as the famous surface size.
  51.151 +
  51.152 +In fact, display list is going to represent almost verbatim what a Famo.us render tree will look like!  It is a fairly universal declaration..  hierarchy of local visual contexts, with relationship among those contexts, including relative placement in 3D space and relative sizing from one to another.
  51.153 +
  51.154 +Alright, getting to it now..  display list will be a serialization of a hierarchy..  The top of the hierarchy is the view painted onto.  The Display tells the visualizer what the pixel dimensions are of the view.  The visualizer makes that the top level bounding box.  It then inserts bounding boxes within that, and inserts bounding boxes within those, and so forth down.  Each bounding box is either a hierarchy element, relationship element, or a painted element.  Hierarchy elements simply state what elements are included, and give their own bounding box.  Relationship elements are attached by the parent hierarchy element.  For example, it is the job of the parent to make sure all the children fit inside its bounding box.  The bounding box may be 2D or 3D.  A parent ensures the fit by attaching relationships to the children elements.  The relationships can be translations or scalings or rotations.. or actually any arbitrary 3D transform.  A hierarchy element knows nothing of the context in which it fits, so it has no way of attaching relationships to itself!  Each hierarchy element is responsible for ensuring that all descendants fit within its bounding box.  Any relationship attached to a hierarchy element is transitively applied to all descendants of the hierarchy element.  For example, if one is rotated in 3D, then it, together with all its contents, is rotated as a unit.  Each descendant maintains the same relationship to its parent as before..  but the entire bundle has been rotated as a unit!
  51.155 +
  51.156 +Great..  so that is the display list..  it is a serialization of that hierarchy.  A display update then assumes a given hierarchy, and says "change this relationship between this parent and this child" or "remove this parent and all descendants" etc..  in effect, it specifies a change to the hierarchical structure..
  51.157 +
  51.158 +Sooooo..  means that have two copies of the view hierarchy..  one inside the visualizer, which is serialized, and another inside the Display, which is translated into Display-local elements that are then painted.
  51.159 +
  51.160 +Not the most efficient..  hurts me..  but, well, what are you going to do?  What's better?  Need the flexibility of having the visualizer control all changes to the view hierarchy.. and need the visualizer to calculate all placement and path details so that user changes can be remembered inside the holder (without something clunky like "save this view modification info as a black box and hand it to the Display, which knows what it means" yuck, just begging for loss of sync when move from one Display to another or even upgrade the Display!)..  
  51.161 +
  51.162 +so, then, there's no way around having the visualizer internally represent the bounding box hierarchy as it constructs the details.  Thennnnn..  something must translate that representation into the internal Display representation!  The Display could have any native form internally..  canvas with paths drawn upon it, Java 2D, even just pixels, with all the code in between..  well, in effect, every Display ends up being everything between that hierarchy and on down to pixels!!
  51.163 +
  51.164 +So, could just hand the data structure from visualizer to the Display..?  This is fine if both are inside same hardware, sharing memory..  but need a serialization if Display has separate memory..  which it will if the src holder is on a server and the display is a browser on a client!
  51.165 +
  51.166 +Hmmm..  what about just handing the data structure to the Display for now..  can always add the serialization later, it's not functional!  :-)  Ahhh, yes.. less work.  Good.  Okay, will do that.  save serialization for later.  For now, in javascript, will build a src holder that saves syntax graph natively in JSON, as an internal data structure of the form made for GabePatterns.  The visualizer in the src holder will generate a view hierarchy from that data structure.  It will save any view related data within the syntax graph data structure as extra properties added to the nodes.  The visualizer will then hand a reference to the view hierarchy directly to the display object.  The display object will then generate famous elements from the view hierarcy elements.  View updates will simply be the visualizer changing the view hierarchy then calling the display with a reference to the changed hierarchy.
  51.167 +
  51.168 +Done.  Make it so.
  51.169 +
  51.170 +BTW, thinking to introduce another component, which is a helper, that maybe takes some higher level view form and generates the view hierarchy from that..  this will ease the burden on developers who make custom syntax.. it will act as a library for them, essentially..  (and, of course, there will be a serializer that turns a view hierarchy into a stream of visual objects sent to the Display, which will reconstruct the view hierarchy then translate that into into elements that it paints.. for now, that serializer is just JSON!  It has provision to translate javascript objects into text form, and then on the other side parse that text form to reproduce the javascript objects.. might need extra logic in order to recreate the links among parents and children.. not sure whether JSON can go deep that way..).
  51.171 +
  51.172 +
  51.173 + 
  51.174 +
  51.175 +
  51.176 +
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/copy_of_famous_univ_example_code.js	Sun Jul 06 12:02:12 2014 -0700
    52.3 @@ -0,0 +1,94 @@
    52.4 +var Engine        = require('famous/core/Engine');
    52.5 +var Surface       = require('famous/core/Surface');
    52.6 +var Transform     = require('famous/core/Transform');
    52.7 +var StateModifier = require('famous/modifiers/StateModifier');
    52.8 +var Easing        = require('famous/transitions/Easing');
    52.9 +var Lightbox      = require('famous/views/Lightbox');
   52.10 +var ImageSurface  = require('famous/surfaces/ImageSurface');
   52.11 +var DeviceView    = require('./DeviceView');
   52.12 +
   52.13 +var mainContext = Engine.createContext();
   52.14 +
   52.15 +var device, lightbox;
   52.16 +var slides = [];
   52.17 +var index = 0;
   52.18 +var arrowMod;
   52.19 +
   52.20 +var lightboxOptions = {
   52.21 +  inOpacity: 1,
   52.22 +  outOpacity: 1,
   52.23 +  inTransform: Transform.translate(320,0, 0),
   52.24 +  outTransform: Transform.translate(-320, 0, 1),
   52.25 +  inTransition: { duration: 400, curve: Easing.outBack },
   52.26 +  outTransition: { duration: 150, curve: Easing.easeOut }
   52.27 +};
   52.28 +
   52.29 +createDevice();
   52.30 +createSlides();
   52.31 +createLightbox();
   52.32 +
   52.33 +function createDevice() {
   52.34 +  var deviceOptions = {
   52.35 +    type: 'iphone',
   52.36 +    height: window.innerHeight - 100
   52.37 +  };
   52.38 +
   52.39 +  device = new DeviceView(deviceOptions);
   52.40 +
   52.41 +  var deviceModifier = new StateModifier({
   52.42 +    size: device.getSize(),
   52.43 +    origin: [0.5, 0.5]
   52.44 +  });
   52.45 +
   52.46 +  mainContext.add(deviceModifier).add(device);
   52.47 +}
   52.48 +
   52.49 +function createSlides() {
   52.50 +  var slideContent = [
   52.51 +    '<svg width="100" height="80"><rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">',
   52.52 +    '<img src="http://launch.famo.us/fu-assets/hello/slide1.png" width="100%">',
   52.53 +    '<img src="http://launch.famo.us/fu-assets/hello/slide2.png" width="100%">',
   52.54 +    '<img src="http://launch.famo.us/fu-assets/hello/slide3.png" width="100%">'];
   52.55 +    
   52.56 +  var background = new Surface({
   52.57 +    properties: {
   52.58 +      backgroundColor: '#FA5C4F'
   52.59 +    }
   52.60 +  });
   52.61 +
   52.62 +  device.add(background);
   52.63 +
   52.64 +  for (var i = 0; i < slideContent.length; i++) {
   52.65 +    var slide = new Surface({
   52.66 +      content: slideContent[i],
   52.67 +      properties: {
   52.68 +        color: 'white',
   52.69 +        lineHeight: '200%',
   52.70 +        textAlign: 'center',
   52.71 +        fontSize: '36px',
   52.72 +        cursor: 'pointer'
   52.73 +      }
   52.74 +    });
   52.75 +    
   52.76 +    slide.on('click', showNextSlide);
   52.77 +
   52.78 +    slides.push(slide);
   52.79 +  }
   52.80 +}
   52.81 +
   52.82 +function createLightbox() {
   52.83 +  lightbox = new Lightbox(lightboxOptions);
   52.84 +  device.add(lightbox);
   52.85 +  lightbox.show(slides[0]);
   52.86 +}
   52.87 +
   52.88 +function showNextSlide() {
   52.89 +  index++;
   52.90 +  if(slides[index]) lightbox.show(slides[index]);
   52.91 +
   52.92 +  if(index === 1) {
   52.93 +    GlobalEvents.trigger('pointToButton', 'fullscreen');
   52.94 +  }
   52.95 +}
   52.96 +
   52.97 +GlobalEvents.trigger('hideArrowOnToggle')
   52.98 \ No newline at end of file
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/famous_learning.js	Sun Jul 06 12:02:12 2014 -0700
    53.3 @@ -0,0 +1,143 @@
    53.4 +
    53.5 +
    53.6 +define(function(require, exports, module) {
    53.7 +    var Engine           = require("famous/core/Engine");
    53.8 +    var Surface          = require("famous/core/Surface");
    53.9 +    var Modifier         = require("famous/core/Modifier");
   53.10 +    var Transform = require('famous/core/Transform');
   53.11 +    var StateModifier = require('famous/modifiers/StateModifier');
   53.12 +    var ContainerSurface = require("famous/surfaces/ContainerSurface");
   53.13 +    var Scrollview       = require("famous/views/Scrollview");
   53.14 +
   53.15 +    var mainContext = Engine.createContext();
   53.16 +	
   53.17 +	var boxSVG = '<svg width="100" height="80"> <rect x="30" y="10" rx="20" ry="20" width="50" height="50" style="fill:red;stroke:black;stroke-width:3;opacity:0.5">';
   53.18 +	var mySurface = new Surface({
   53.19 +	  size: [100, 100],
   53.20 +      content: boxSVG,
   53.21 +      properties: {
   53.22 +        color: 'white',
   53.23 +        lineHeight: '200%',
   53.24 +        textAlign: 'center',
   53.25 +        fontSize: '36px',
   53.26 +        cursor: 'pointer'
   53.27 +     }
   53.28 +	});
   53.29 +	var mySurface2 = new Surface({
   53.30 +	  size: [100, 100],
   53.31 +      content: boxSVG,
   53.32 +      properties: {
   53.33 +        color: 'white',
   53.34 +        lineHeight: '200%',
   53.35 +        textAlign: 'center',
   53.36 +        fontSize: '36px',
   53.37 +        cursor: 'pointer'
   53.38 +     }
   53.39 +	});
   53.40 +	var sigmaSVG = '<svg width="744.09448" height="1052.3622" id="svg2"> <g id="g3759"> <path  d="m 188.70968,122.10412 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,31.81771 -0.47557,0.69813 38.70968,32.25806" id="path2985" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 188.70968,184.36218 c -46.7742,0 -48.3871,0 -48.3871,0 39.47543,-31.81771 -0.47557,-0.69813 38.70968,-32.25806" id="path3757" style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> </g> </svg>';
   53.41 +	var sigmaSurf = new Surface({
   53.42 +	  size: [100, 100],
   53.43 +      content: sigmaSVG,
   53.44 +      properties: {
   53.45 +        color: 'black',
   53.46 +        lineHeight: '200%',
   53.47 +        textAlign: 'center',
   53.48 +        fontSize: '36px',
   53.49 +        cursor: 'pointer'
   53.50 +     }
   53.51 +	});
   53.52 +
   53.53 +	var moveModifier1 = new StateModifier({
   53.54 +        transform: Transform.translate(250, 100, 0)
   53.55 +    });
   53.56 +	var moveModifier2 = new StateModifier({
   53.57 +        transform: Transform.translate(350, 150, 0)
   53.58 +    });
   53.59 +	var rotateModifier = new StateModifier({
   53.60 +		transform: Transform.rotateZ(Math.PI/4)
   53.61 +	});
   53.62 +
   53.63 +//the origin is the point inside the child, relative to the child's
   53.64 +// internal axes, at which the child will be pinned inside its parent.
   53.65 +//The align is the point inside the parent, relative to the parent's axes,
   53.66 +// at which the origins of children will be pinned.
   53.67 +//The origin is also the point about which rotations are performed
   53.68 +	var moveRelativeModifier = new StateModifier({
   53.69 +      size: [20, 20],
   53.70 +      align: [0.5,0],
   53.71 +      origin: [0.5,0]
   53.72 +    });
   53.73 +	var moveRelativeModifier2 = new StateModifier({
   53.74 +      size: [20, 20],
   53.75 +      align: [0.5,0],
   53.76 +      origin: [0.5,0]
   53.77 +    });
   53.78 +
   53.79 +	var moveModifier2 = new StateModifier({
   53.80 +        transform: Transform.translate(350, 150, 0)
   53.81 +    });
   53.82 +	
   53.83 +    var scaleMod = new StateModifier({
   53.84 +        transform: Transform.scale(0.5, 0.5, 1)
   53.85 +    });
   53.86 +
   53.87 +
   53.88 +//can make a tree inside the context -- so, can have a transform applied
   53.89 +// to multiple children..  do so by making a var that holds the transform
   53.90 +// node, then add to that variable multiple times.
   53.91 +//Note, though that a given surface object will only render once!  Have to
   53.92 +// clone it if want multiple versions to be drawn.
   53.93 +//Same goes for modifiers -- cannot put same modifier object at multiple 
   53.94 +// places within tree -- it will only render children of ONE of those places!
   53.95 +   var node = mainContext.add(rotateModifier);
   53.96 +   node.add(moveModifier2).add(moveRelativeModifier).add(mySurface);
   53.97 +   node.add(moveModifier1).add(scaleMod).add(mySurface2);
   53.98 +   mainContext.add(moveRelativeModifier2).add(sigmaSurf);
   53.99 +
  53.100 +	//========== copy-pasted scrollview example stuff below this ==========
  53.101 +	var container = new ContainerSurface(
  53.102 +	 {
  53.103 +		size: [400, 400],
  53.104 +		properties: 
  53.105 +		 {
  53.106 +			overflow: 'hidden'
  53.107 +		 }
  53.108 +	 });
  53.109 +	
  53.110 +	var surfaces = [];
  53.111 +	//create a thing that is able to transition between surfaces.. the 
  53.112 +	// surface that transitions in is the new one that is seeable on screen.
  53.113 +	var scrollview = new Scrollview();
  53.114 +	
  53.115 +	//create the renderable surfaces, each is capable of being seeable on screen
  53.116 +	var temp;
  53.117 +	for (var i = 0; i < 5; i++) {
  53.118 +		temp = new Surface({
  53.119 +			size: [undefined, 50],
  53.120 +			content: 'I am surface: ' + (i + 1),
  53.121 +			classes: ['red-bg'],
  53.122 +			properties: {
  53.123 +				textAlign: 'center',
  53.124 +				lineHeight: '50px'
  53.125 +			}
  53.126 +		});
  53.127 +
  53.128 +		//put the surface into the scrollview management element
  53.129 +		temp.pipe(scrollview);
  53.130 +		//put the surface into an array of surfaces, for bookkeeping
  53.131 +		surfaces.push(temp);
  53.132 +	}
  53.133 +
  53.134 +	//The scrollview is now loaded up with all the surfaces, so tell it how
  53.135 +	// want it to transition between the different surfaces
  53.136 +	scrollview.sequenceFrom(surfaces);
  53.137 +	
  53.138 +	//add the scrollview to the container..  the container defines size and
  53.139 +	// some other properties..
  53.140 +	container.add(scrollview);
  53.141 +
  53.142 +	//make the container viewable, and hence the scrollview, hence whatever 
  53.143 +	// surface is loaded as the top in the scrollview
  53.144 +	mainContext.add(new Modifier({origin: [.5, .5]})).add(container);
  53.145 +
  53.146 +});
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning.js	Sun Jul 06 12:02:12 2014 -0700
    54.3 @@ -0,0 +1,144 @@
    54.4 +
    54.5 +//load in the famous stuff -- so far only figured out how to do it via html tag..
    54.6 +
    54.7 +document.write('<script type="text/javascript"> require(["famous_learning"]);</script>');
    54.8 +//document.write('<script type="text/javascript"> require(["draw_svg_example"]);</script>');
    54.9 +//=========================
   54.10 +
   54.11 +var el =  document.createElement("h1")
   54.12 +el.id="title";
   54.13 +el.innerHTML = "Some title";
   54.14 +document.body.appendChild(el);
   54.15 +
   54.16 +var el2 =  document.createElement("span")
   54.17 +el2.style.display="block";
   54.18 +el2.style.width="100%";
   54.19 +el2.innerHTML = "Some arb text";
   54.20 +document.body.appendChild(el2);
   54.21 +
   54.22 +function appendHtml(el, str) {
   54.23 +  var div = document.createElement('div');
   54.24 +  div.innerHTML = str;
   54.25 +  while (div.children.length > 0) {
   54.26 +      if ( div.children[0].tagName == 'LINK' ) {
   54.27 +          // Create an actual link element to append later
   54.28 +          style = document.createElement('link');
   54.29 +          style.href = div.children[0].href;
   54.30 +          // append your other things like rel, type, etc
   54.31 +          el.appendChild(style);
   54.32 +      }
   54.33 +      el.appendChild(div.children[0]);
   54.34 +  }
   54.35 +}
   54.36 +
   54.37 +var c = document.getElementById("myCanvas");
   54.38 +var ctx = c.getContext("2d");
   54.39 +ctx.fillStyle = "#FF0000";
   54.40 +ctx.fillRect(0,0,150,75);
   54.41 +
   54.42 +var c = document.getElementById("myCanvas");
   54.43 +var ctx = c.getContext("2d");
   54.44 +ctx.moveTo(0,0);
   54.45 +ctx.lineTo(200,100);
   54.46 +ctx.stroke();
   54.47 +
   54.48 +var c = document.getElementById("myCanvas");
   54.49 +var ctx = c.getContext("2d");
   54.50 +ctx.beginPath();
   54.51 +ctx.arc(95,50,40,0,Math.PI);
   54.52 +ctx.stroke();
   54.53 +
   54.54 +var c = document.getElementById("myCanvas");
   54.55 +var ctx = c.getContext("2d");
   54.56 +ctx.font = "30px Arial";
   54.57 +ctx.fillStyle = "#000000";
   54.58 +ctx.fillText("Hello World",10,50);
   54.59 +
   54.60 +ctx.fillStyle = "#FF0000";
   54.61 +ctx.fillText("Hello World",10,50);
   54.62 +
   54.63 +var c = document.getElementById("myCanvas");
   54.64 +var ctx = c.getContext("2d");
   54.65 +ctx.font = "30px Arial";
   54.66 +ctx.fillStyle = "#000000";
   54.67 +ctx.strokeText("Hello World",10,90);
   54.68 +
   54.69 +var c = document.getElementById("POPCanvas");
   54.70 +var ctx = c.getContext("2d");
   54.71 +ctx.font = "30px Arial";
   54.72 +ctx.fillStyle = "#000000";
   54.73 +ctx.strokeText("Hello POP!",10,90);
   54.74 +
   54.75 +//A syntax graph consists of two kinds of elements, plus a list of properties attached to each element
   54.76 +
   54.77 +//var surname = prompt('Greetings friend, may I enquire as to your surname?');
   54.78 +
   54.79 +var i = 1;
   54.80 +while (i < 2) {
   54.81 +//    alert(i);
   54.82 +    i = i + 1;
   54.83 +}
   54.84 +
   54.85 +for (var i = 1; i < 2; i++) {
   54.86 +//    alert(i);
   54.87 +}
   54.88 +
   54.89 +var add = function (a, b) {
   54.90 +    return a + b;
   54.91 +};
   54.92 +
   54.93 +
   54.94 +var result = add(1, 2); // result is now 3
   54.95 +
   54.96 +
   54.97 +var jedi = {
   54.98 +    name: "Yoda",
   54.99 +    age: 899,
  54.100 +    talk: function () { alert("another... Sky... walker..."); }
  54.101 +};
  54.102 +
  54.103 +var dog = {};
  54.104 +
  54.105 +dog.bark = function () { alert("Woof!"); };
  54.106 +
  54.107 +var helloFrom = function (personName) {
  54.108 +    return "Hello from " + personName;
  54.109 +}
  54.110 +
  54.111 +var people = ['Tom', 'Yoda', 'Ron'];
  54.112 +
  54.113 +people.push('Bob');
  54.114 +people.push('Dr Evil');
  54.115 +
  54.116 +people.pop();
  54.117 +
  54.118 +for (var i=0; i < people.length; i++) {
  54.119 +    var greeting = helloFrom(people[i]);
  54.120 +//    alert(greeting);
  54.121 +}
  54.122 +
  54.123 +var person = {
  54.124 +    age: 122
  54.125 +};
  54.126 +
  54.127 +person.name = {
  54.128 +    first: "Jeanne",
  54.129 +    last: "Calment"
  54.130 +};
  54.131 +
  54.132 +var properties = [];
  54.133 +
  54.134 +var exampleSyntaxGraph = {};
  54.135 +
  54.136 +exampleSyntaxGraph.root = 
  54.137 + { properties: {},
  54.138 +   linksIn:    {},
  54.139 +   linksOut:   {},
  54.140 +   subElems:   {}
  54.141 + };
  54.142 +
  54.143 +exampleSyntaxGraph.root.properties.propertyName = "ElementType";exampleSyntaxGraph.root.properties.propertyValue = "Command";
  54.144 +exampleSyntaxGraph.root.properties.propertyName = "ElementType";
  54.145 +
  54.146 +
  54.147 +
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learningLoadPage.html	Sun Jul 06 12:02:12 2014 -0700
    55.3 @@ -0,0 +1,53 @@
    55.4 +<!DOCTYPE html>
    55.5 +<html>
    55.6 +    <head>
    55.7 +        <title>famo.us App</title>
    55.8 +        <meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
    55.9 +        <meta name="mobile-web-app-capable" content="yes" />
   55.10 +        <meta name="apple-mobile-web-app-capable" content="yes" />
   55.11 +        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
   55.12 +
   55.13 +        <!-- shims for backwards compatibility -->
   55.14 +        <script type="text/javascript" src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
   55.15 +        <script type="text/javascript" src="http://code.famo.us/lib/classList.js"></script>
   55.16 +        <script type="text/javascript" src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
   55.17 +
   55.18 +        <!-- module loader -->
   55.19 +        <script type="text/javascript" src="http://code.famo.us/lib/require.js"></script>
   55.20 +
   55.21 +        <!-- famous -->
   55.22 +        <link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.2/famous.css" />
   55.23 +        <script type="text/javascript" src="http://code.famo.us/famous/0.2/famous.js"></script>
   55.24 +		
   55.25 +<!-- the famous stylesheet messes up text fonts, but the famous surfaces don't paint their background properly without the famous CSS.. -->
   55.26 +        <link rel="stylesheet" type="text/css" href="http://code.famo.us/assets/famous_styles.css" />
   55.27 +		
   55.28 +        <!-- load D3, to play around with also! -->
   55.29 +		<!--script type="text/javascript" src="d3/d3.v3.js"></script-->
   55.30 +		
   55.31 +    </head>
   55.32 +
   55.33 +<!--
   55.34 +<script src="terminal.js">
   55.35 +</script>
   55.36 +<body onload="window.start('terminal');">
   55.37 +
   55.38 +<div id="loader">...</div>
   55.39 +-->
   55.40 +<body>
   55.41 +<canvas id="myCanvas" width="200" height="200" style="border:1px solid #000000;">
   55.42 +Your browser does not support the HTML5 canvas tag.
   55.43 +</canvas>
   55.44 +
   55.45 +<canvas id="POPCanvas" width="200" height="100" style="border:1px solid #000000;">
   55.46 +</canvas>
   55.47 +
   55.48 +<!--script type="text/javascript">require(['famous_surface_example']);</script-->
   55.49 +
   55.50 +<script src="epocritesPuzzle.js">
   55.51 +</script>
   55.52 +
   55.53 +</body>
   55.54 +</html>
   55.55 +
   55.56 +
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/learning_scripts/learning_text_bounding_box.js	Sun Jul 06 12:02:12 2014 -0700
    56.3 @@ -0,0 +1,83 @@
    56.4 +
    56.5 +	//Do this part once, of creating a DOM element and adding it to document
    56.6 +	var el1 =  document.createElement("div");
    56.7 +	document.body.appendChild(el1); //only need to append once then reuse
    56.8 +	
    56.9 +	//now set the SVG text string -- from this point down can be repeated 
   56.10 +	// for multiple strings without removing or re-adding the element, nor
   56.11 +	// fiddling with the DOM
   56.12 +	var text1_1_1_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText1">' + text1_1_1.content + '</text> </svg>';
   56.13 +	//note the id is inside the text element! Also the fill and stroke are
   56.14 +	// null so nothing paints
   56.15 +	el1.innerHTML = text1_1_1_SVG; 
   56.16 +
   56.17 +	//get the element -- this seems to be what triggers the bounding box calc
   56.18 +	var test = document.getElementById("svgText1"); //use ID of the text elem
   56.19 +
   56.20 +	//get the box, take the values out of it, and display them
   56.21 +    var rect = test.getBoundingClientRect();
   56.22 +	var str = "";
   56.23 +	for (i in rect) { //a trick for getting all the attributes of the object
   56.24 +		str += i + " = " + rect[i] + "  ";
   56.25 +	}
   56.26 +	console.log("svgText1: " + str);
   56.27 +		
   56.28 +	var el2 =  document.createElement("span");
   56.29 +	el2.style.display="block";
   56.30 +	el2.id="testing123";
   56.31 +	el2.style.width="10%";
   56.32 +	el2.innerHTML = text1_1_1.content;
   56.33 +	document.body.appendChild(el2);
   56.34 +	console.log("testing123 class " + el2.className);
   56.35 +	
   56.36 +	
   56.37 +	var test = document.getElementById("test12");
   56.38 +    var rect = test.getBoundingClientRect();
   56.39 +	var str = "";
   56.40 +	for (i in rect) {
   56.41 +		str += i + " = " + rect[i] + "<br>";
   56.42 +	}
   56.43 +	console.log("test12: " + str);
   56.44 +
   56.45 +//	var svgTextElem = new SVGTextElement();
   56.46 +	
   56.47 +	var elem = document.getElementById("svg_text");
   56.48 +	var foo = elem.getBBox();
   56.49 +	console.log("svg_text getBBox: " + foo.width);
   56.50 +//	console.log("svg_text computed: " + elem.getComputedTextLength());
   56.51 +	console.log("svg_text foo: " + elem.childNodes[1].className);
   56.52 +	console.log("svg_text class: " + elem.className);
   56.53 +	
   56.54 +	
   56.55 +	var f = document.getElementById("svg_text").getClientRects();
   56.56 +	console.log("svg_text getClientRects: " + f[0].width);
   56.57 +	
   56.58 +	var rect = document.getElementById("testing123").getBoundingClientRect();
   56.59 +	console.log("getBoundingClientRect: " + rect.width);
   56.60 +	
   56.61 +	function getText1_1_1() {
   56.62 +	}
   56.63 +	var text1_1_2 = new Surface({
   56.64 +	  size: [true, true],
   56.65 +      content: "portsIn",
   56.66 +      properties: {
   56.67 +        color: 'black',
   56.68 +        textAlign: 'left',
   56.69 +        fontSize: '11px',
   56.70 +        cursor: 'pointer'
   56.71 +      }
   56.72 +	});
   56.73 +//	document.body.removeChild(el1);
   56.74 +	var text1_1_2_SVG = '<svg> <text id="svgText2" x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none">' + text1_1_2.content + '</text> </svg>';
   56.75 +	el1.innerHTML = text1_1_2_SVG;
   56.76 +//	document.body.appendChild(el1);
   56.77 +	
   56.78 +	var test = document.getElementById("svgText2");
   56.79 +    var rect = test.getBoundingClientRect();
   56.80 +	var str = "";
   56.81 +	for (i in rect) {
   56.82 +		str += i + " = " + rect[i] + "<br>";
   56.83 +	}
   56.84 +	console.log("svgText2: " + str);
   56.85 +	console.log("svgText2: " + test.getComputedTextLength());
   56.86 +	
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/classList.js	Sun Jul 06 12:02:12 2014 -0700
    57.3 @@ -0,0 +1,138 @@
    57.4 +
    57.5 +/*
    57.6 + * classList.js: Cross-browser full element.classList implementation.
    57.7 + * 2011-06-15
    57.8 + *
    57.9 + * By Eli Grey, http://eligrey.com
   57.10 + * Public Domain.
   57.11 + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
   57.12 + */
   57.13 +
   57.14 +/*global self, document, DOMException */
   57.15 +
   57.16 +/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
   57.17 +
   57.18 +if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
   57.19 +
   57.20 +(function (view) {
   57.21 +
   57.22 +"use strict";
   57.23 +
   57.24 +var
   57.25 +	  classListProp = "classList"
   57.26 +	, protoProp = "prototype"
   57.27 +	, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
   57.28 +	, objCtr = Object
   57.29 +	, strTrim = String[protoProp].trim || function () {
   57.30 +		return this.replace(/^\s+|\s+$/g, "");
   57.31 +	}
   57.32 +	, arrIndexOf = Array[protoProp].indexOf || function (item) {
   57.33 +		var
   57.34 +			  i = 0
   57.35 +			, len = this.length
   57.36 +		;
   57.37 +		for (; i < len; i++) {
   57.38 +			if (i in this && this[i] === item) {
   57.39 +				return i;
   57.40 +			}
   57.41 +		}
   57.42 +		return -1;
   57.43 +	}
   57.44 +	// Vendors: please allow content code to instantiate DOMExceptions
   57.45 +	, DOMEx = function (type, message) {
   57.46 +		this.name = type;
   57.47 +		this.code = DOMException[type];
   57.48 +		this.message = message;
   57.49 +	}
   57.50 +	, checkTokenAndGetIndex = function (classList, token) {
   57.51 +		if (token === "") {
   57.52 +			throw new DOMEx(
   57.53 +				  "SYNTAX_ERR"
   57.54 +				, "An invalid or illegal string was specified"
   57.55 +			);
   57.56 +		}
   57.57 +		if (/\s/.test(token)) {
   57.58 +			throw new DOMEx(
   57.59 +				  "INVALID_CHARACTER_ERR"
   57.60 +				, "String contains an invalid character"
   57.61 +			);
   57.62 +		}
   57.63 +		return arrIndexOf.call(classList, token);
   57.64 +	}
   57.65 +	, ClassList = function (elem) {
   57.66 +		var
   57.67 +			  trimmedClasses = strTrim.call(elem.className)
   57.68 +			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
   57.69 +			, i = 0
   57.70 +			, len = classes.length
   57.71 +		;
   57.72 +		for (; i < len; i++) {
   57.73 +			this.push(classes[i]);
   57.74 +		}
   57.75 +		this._updateClassName = function () {
   57.76 +			elem.className = this.toString();
   57.77 +		};
   57.78 +	}
   57.79 +	, classListProto = ClassList[protoProp] = []
   57.80 +	, classListGetter = function () {
   57.81 +		return new ClassList(this);
   57.82 +	}
   57.83 +;
   57.84 +// Most DOMException implementations don't allow calling DOMException's toString()
   57.85 +// on non-DOMExceptions. Error's toString() is sufficient here.
   57.86 +DOMEx[protoProp] = Error[protoProp];
   57.87 +classListProto.item = function (i) {
   57.88 +	return this[i] || null;
   57.89 +};
   57.90 +classListProto.contains = function (token) {
   57.91 +	token += "";
   57.92 +	return checkTokenAndGetIndex(this, token) !== -1;
   57.93 +};
   57.94 +classListProto.add = function (token) {
   57.95 +	token += "";
   57.96 +	if (checkTokenAndGetIndex(this, token) === -1) {
   57.97 +		this.push(token);
   57.98 +		this._updateClassName();
   57.99 +	}
  57.100 +};
  57.101 +classListProto.remove = function (token) {
  57.102 +	token += "";
  57.103 +	var index = checkTokenAndGetIndex(this, token);
  57.104 +	if (index !== -1) {
  57.105 +		this.splice(index, 1);
  57.106 +		this._updateClassName();
  57.107 +	}
  57.108 +};
  57.109 +classListProto.toggle = function (token) {
  57.110 +	token += "";
  57.111 +	if (checkTokenAndGetIndex(this, token) === -1) {
  57.112 +		this.add(token);
  57.113 +	} else {
  57.114 +		this.remove(token);
  57.115 +	}
  57.116 +};
  57.117 +classListProto.toString = function () {
  57.118 +	return this.join(" ");
  57.119 +};
  57.120 +
  57.121 +if (objCtr.defineProperty) {
  57.122 +	var classListPropDesc = {
  57.123 +		  get: classListGetter
  57.124 +		, enumerable: true
  57.125 +		, configurable: true
  57.126 +	};
  57.127 +	try {
  57.128 +		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  57.129 +	} catch (ex) { // IE 8 doesn't support enumerable:true
  57.130 +		if (ex.number === -0x7FF5EC54) {
  57.131 +			classListPropDesc.enumerable = false;
  57.132 +			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  57.133 +		}
  57.134 +	}
  57.135 +} else if (objCtr[protoProp].__defineGetter__) {
  57.136 +	elemCtrProto.__defineGetter__(classListProp, classListGetter);
  57.137 +}
  57.138 +
  57.139 +}(self));
  57.140 +
  57.141 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous.css	Sun Jul 06 12:02:12 2014 -0700
    58.3 @@ -0,0 +1,77 @@
    58.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
    58.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
    58.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    58.7 + *
    58.8 + * Owner: mark@famo.us
    58.9 + * @license MPL 2.0
   58.10 + * @copyright Famous Industries, Inc. 2014
   58.11 + */
   58.12 +
   58.13 +
   58.14 +html {
   58.15 +    width: 100%;
   58.16 +    height: 100%;
   58.17 +    margin: 0px;
   58.18 +    padding: 0px;
   58.19 +    overflow: hidden;
   58.20 +    -webkit-transform-style: preserve-3d;
   58.21 +    transform-style: preserve-3d;
   58.22 +}
   58.23 +
   58.24 +body {
   58.25 +    position: absolute;
   58.26 +    width: 100%;
   58.27 +    height: 100%;
   58.28 +    margin: 0px;
   58.29 +    padding: 0px;
   58.30 +    -webkit-transform-style: preserve-3d;
   58.31 +    transform-style: preserve-3d;
   58.32 +    -webkit-font-smoothing: antialiased;
   58.33 +    -webkit-tap-highlight-color: transparent;
   58.34 +    -webkit-perspective: 0;
   58.35 +    perspective: none;
   58.36 +    overflow: hidden;
   58.37 +}
   58.38 +
   58.39 +.famous-container, .famous-group {
   58.40 +    position: absolute;
   58.41 +    top: 0px;
   58.42 +    left: 0px;
   58.43 +    bottom: 0px;
   58.44 +    right: 0px;
   58.45 +    overflow: visible;
   58.46 +    -webkit-transform-style: preserve-3d;
   58.47 +    transform-style: preserve-3d;
   58.48 +    -webkit-backface-visibility: visible;
   58.49 +    backface-visibility: visible;
   58.50 +    pointer-events: none;
   58.51 +}
   58.52 +
   58.53 +.famous-group {
   58.54 +    width: 0px;
   58.55 +    height: 0px;
   58.56 +    margin: 0px;
   58.57 +    padding: 0px;
   58.58 +    -webkit-transform-style: preserve-3d;
   58.59 +    transform-style: preserve-3d;
   58.60 +}
   58.61 +
   58.62 +.famous-surface {
   58.63 +    position: absolute;
   58.64 +    -webkit-transform-origin: center center;
   58.65 +    transform-origin: center center;
   58.66 +    -webkit-backface-visibility: hidden;
   58.67 +    backface-visibility: hidden;
   58.68 +    -webkit-transform-style: flat;
   58.69 +    transform-style: preserve-3d; /* performance */
   58.70 +    -webkit-box-sizing: border-box;
   58.71 +    -moz-box-sizing: border-box;
   58.72 +    -webkit-tap-highlight-color: transparent;
   58.73 +    pointer-events: auto;
   58.74 +}
   58.75 +
   58.76 +.famous-container-group {
   58.77 +    position: relative;
   58.78 +    width: 100%;
   58.79 +    height: 100%;
   58.80 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous.js	Sun Jul 06 12:02:12 2014 -0700
    59.3 @@ -0,0 +1,17609 @@
    59.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
    59.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
    59.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    59.7 + *
    59.8 + * Owner: mark@famo.us
    59.9 + * @license MPL 2.0
   59.10 + * @copyright Famous Industries, Inc. 2014
   59.11 + */
   59.12 +
   59.13 +define('famous/core/Entity',['require','exports','module'],function(require, exports, module) {
   59.14 +    /**
   59.15 +     * A singleton that maintains a global registry of Surfaces.
   59.16 +     *   Private.
   59.17 +     *
   59.18 +     * @private
   59.19 +     * @static
   59.20 +     * @class Entity
   59.21 +     */
   59.22 +
   59.23 +    var entities = [];
   59.24 +
   59.25 +    /**
   59.26 +     * Get entity from global index.
   59.27 +     *
   59.28 +     * @private
   59.29 +     * @method get
   59.30 +     * @param {Number} id entity reigstration id
   59.31 +     * @return {Surface} entity in the global index
   59.32 +     */
   59.33 +    function get(id) {
   59.34 +        return entities[id];
   59.35 +    }
   59.36 +
   59.37 +    /**
   59.38 +     * Overwrite entity in the global index
   59.39 +     *
   59.40 +     * @private
   59.41 +     * @method set
   59.42 +     * @param {Number} id entity reigstration id
   59.43 +     * @return {Surface} entity to add to the global index
   59.44 +     */
   59.45 +    function set(id, entity) {
   59.46 +        entities[id] = entity;
   59.47 +    }
   59.48 +
   59.49 +    /**
   59.50 +     * Add entity to global index
   59.51 +     *
   59.52 +     * @private
   59.53 +     * @method register
   59.54 +     * @param {Surface} entity to add to global index
   59.55 +     * @return {Number} new id
   59.56 +     */
   59.57 +    function register(entity) {
   59.58 +        var id = entities.length;
   59.59 +        set(id, entity);
   59.60 +        return id;
   59.61 +    }
   59.62 +
   59.63 +    /**
   59.64 +     * Remove entity from global index
   59.65 +     *
   59.66 +     * @private
   59.67 +     * @method unregister
   59.68 +     * @param {Number} id entity reigstration id
   59.69 +     */
   59.70 +    function unregister(id) {
   59.71 +        set(id, null);
   59.72 +    }
   59.73 +
   59.74 +    module.exports = {
   59.75 +        register: register,
   59.76 +        unregister: unregister,
   59.77 +        get: get,
   59.78 +        set: set
   59.79 +    };
   59.80 +});
   59.81 +
   59.82 +/* This Source Code Form is subject to the terms of the Mozilla Public
   59.83 + * License, v. 2.0. If a copy of the MPL was not distributed with this
   59.84 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   59.85 + *
   59.86 + * Owner: mark@famo.us
   59.87 + * @license MPL 2.0
   59.88 + * @copyright Famous Industries, Inc. 2014
   59.89 + */
   59.90 +
   59.91 +define('famous/core/Transform',['require','exports','module'],function(require, exports, module) {
   59.92 +
   59.93 +    /**
   59.94 +     *  A high-performance static matrix math library used to calculate
   59.95 +     *    affine transforms on surfaces and other renderables.
   59.96 +     *    Famo.us uses 4x4 matrices corresponding directly to
   59.97 +     *    WebKit matrices (column-major order).
   59.98 +     *
   59.99 +     *    The internal "type" of a Matrix is a 16-long float array in
  59.100 +     *    row-major order, with:
  59.101 +     *    elements [0],[1],[2],[4],[5],[6],[8],[9],[10] forming the 3x3
  59.102 +     *          transformation matrix;
  59.103 +     *    elements [12], [13], [14] corresponding to the t_x, t_y, t_z
  59.104 +     *           translation;
  59.105 +     *    elements [3], [7], [11] set to 0;
  59.106 +     *    element [15] set to 1.
  59.107 +     *    All methods are static.
  59.108 +     *
  59.109 +     * @static
  59.110 +     *
  59.111 +     * @class Transform
  59.112 +     */
  59.113 +    var Transform = {};
  59.114 +
  59.115 +    // WARNING: these matrices correspond to WebKit matrices, which are
  59.116 +    //    transposed from their math counterparts
  59.117 +    Transform.precision = 1e-6;
  59.118 +    Transform.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  59.119 +
  59.120 +    /**
  59.121 +     * Multiply two or more Transform matrix types to return a Transform matrix.
  59.122 +     *
  59.123 +     * @method multiply4x4
  59.124 +     * @static
  59.125 +     * @param {Transform} a left Transform
  59.126 +     * @param {Transform} b right Transform
  59.127 +     * @return {Transform}
  59.128 +     */
  59.129 +    Transform.multiply4x4 = function multiply4x4(a, b) {
  59.130 +        return [
  59.131 +            a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
  59.132 +            a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
  59.133 +            a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
  59.134 +            a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
  59.135 +            a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
  59.136 +            a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
  59.137 +            a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
  59.138 +            a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
  59.139 +            a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
  59.140 +            a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
  59.141 +            a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
  59.142 +            a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
  59.143 +            a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
  59.144 +            a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
  59.145 +            a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
  59.146 +            a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]
  59.147 +        ];
  59.148 +    };
  59.149 +
  59.150 +    /**
  59.151 +     * Fast-multiply two or more Transform matrix types to return a
  59.152 +     *    Matrix, assuming bottom row on each is [0 0 0 1].
  59.153 +     *
  59.154 +     * @method multiply
  59.155 +     * @static
  59.156 +     * @param {Transform} a left Transform
  59.157 +     * @param {Transform} b right Transform
  59.158 +     * @return {Transform}
  59.159 +     */
  59.160 +    Transform.multiply = function multiply(a, b) {
  59.161 +        return [
  59.162 +            a[0] * b[0] + a[4] * b[1] + a[8] * b[2],
  59.163 +            a[1] * b[0] + a[5] * b[1] + a[9] * b[2],
  59.164 +            a[2] * b[0] + a[6] * b[1] + a[10] * b[2],
  59.165 +            0,
  59.166 +            a[0] * b[4] + a[4] * b[5] + a[8] * b[6],
  59.167 +            a[1] * b[4] + a[5] * b[5] + a[9] * b[6],
  59.168 +            a[2] * b[4] + a[6] * b[5] + a[10] * b[6],
  59.169 +            0,
  59.170 +            a[0] * b[8] + a[4] * b[9] + a[8] * b[10],
  59.171 +            a[1] * b[8] + a[5] * b[9] + a[9] * b[10],
  59.172 +            a[2] * b[8] + a[6] * b[9] + a[10] * b[10],
  59.173 +            0,
  59.174 +            a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12],
  59.175 +            a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13],
  59.176 +            a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14],
  59.177 +            1
  59.178 +        ];
  59.179 +    };
  59.180 +
  59.181 +    /**
  59.182 +     * Return a Transform translated by additional amounts in each
  59.183 +     *    dimension. This is equivalent to the result of
  59.184 +     *
  59.185 +     *    Transform.multiply(Matrix.translate(t[0], t[1], t[2]), m).
  59.186 +     *
  59.187 +     * @method thenMove
  59.188 +     * @static
  59.189 +     * @param {Transform} m a Transform
  59.190 +     * @param {Array.Number} t floats delta vector of length 2 or 3
  59.191 +     * @return {Transform}
  59.192 +     */
  59.193 +    Transform.thenMove = function thenMove(m, t) {
  59.194 +        if (!t[2]) t[2] = 0;
  59.195 +        return [m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, m[12] + t[0], m[13] + t[1], m[14] + t[2], 1];
  59.196 +    };
  59.197 +
  59.198 +    /**
  59.199 +     * Return a Transform atrix which represents the result of a transform matrix
  59.200 +     *    applied after a move. This is faster than the equivalent multiply.
  59.201 +     *    This is equivalent to the result of:
  59.202 +     *
  59.203 +     *    Transform.multiply(m, Transform.translate(t[0], t[1], t[2])).
  59.204 +     *
  59.205 +     * @method moveThen
  59.206 +     * @static
  59.207 +     * @param {Array.Number} v vector representing initial movement
  59.208 +     * @param {Transform} m matrix to apply afterwards
  59.209 +     * @return {Transform} the resulting matrix
  59.210 +     */
  59.211 +    Transform.moveThen = function moveThen(v, m) {
  59.212 +        if (!v[2]) v[2] = 0;
  59.213 +        var t0 = v[0] * m[0] + v[1] * m[4] + v[2] * m[8];
  59.214 +        var t1 = v[0] * m[1] + v[1] * m[5] + v[2] * m[9];
  59.215 +        var t2 = v[0] * m[2] + v[1] * m[6] + v[2] * m[10];
  59.216 +        return Transform.thenMove(m, [t0, t1, t2]);
  59.217 +    };
  59.218 +
  59.219 +    /**
  59.220 +     * Return a Transform which represents a translation by specified
  59.221 +     *    amounts in each dimension.
  59.222 +     *
  59.223 +     * @method translate
  59.224 +     * @static
  59.225 +     * @param {Number} x x translation
  59.226 +     * @param {Number} y y translation
  59.227 +     * @param {Number} z z translation
  59.228 +     * @return {Transform}
  59.229 +     */
  59.230 +    Transform.translate = function translate(x, y, z) {
  59.231 +        if (z === undefined) z = 0;
  59.232 +        return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
  59.233 +    };
  59.234 +
  59.235 +    /**
  59.236 +     * Return a Transform scaled by a vector in each
  59.237 +     *    dimension. This is a more performant equivalent to the result of
  59.238 +     *
  59.239 +     *    Transform.multiply(Transform.scale(s[0], s[1], s[2]), m).
  59.240 +     *
  59.241 +     * @method thenScale
  59.242 +     * @static
  59.243 +     * @param {Transform} m a matrix
  59.244 +     * @param {Array.Number} s delta vector (array of floats &&
  59.245 +     *    array.length == 3)
  59.246 +     * @return {Transform}
  59.247 +     */
  59.248 +    Transform.thenScale = function thenScale(m, s) {
  59.249 +        return [
  59.250 +            s[0] * m[0], s[1] * m[1], s[2] * m[2], 0,
  59.251 +            s[0] * m[4], s[1] * m[5], s[2] * m[6], 0,
  59.252 +            s[0] * m[8], s[1] * m[9], s[2] * m[10], 0,
  59.253 +            s[0] * m[12], s[1] * m[13], s[2] * m[14], 1
  59.254 +        ];
  59.255 +    };
  59.256 +
  59.257 +    /**
  59.258 +     * Return a Transform which represents a scale by specified amounts
  59.259 +     *    in each dimension.
  59.260 +     *
  59.261 +     * @method scale
  59.262 +     * @static
  59.263 +     * @param {Number} x x scale factor
  59.264 +     * @param {Number} y y scale factor
  59.265 +     * @param {Number} z z scale factor
  59.266 +     * @return {Transform}
  59.267 +     */
  59.268 +    Transform.scale = function scale(x, y, z) {
  59.269 +        if (z === undefined) z = 1;
  59.270 +        return [x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1];
  59.271 +    };
  59.272 +
  59.273 +    /**
  59.274 +     * Return a Transform which represents a clockwise
  59.275 +     *    rotation around the x axis.
  59.276 +     *
  59.277 +     * @method rotateX
  59.278 +     * @static
  59.279 +     * @param {Number} theta radians
  59.280 +     * @return {Transform}
  59.281 +     */
  59.282 +    Transform.rotateX = function rotateX(theta) {
  59.283 +        var cosTheta = Math.cos(theta);
  59.284 +        var sinTheta = Math.sin(theta);
  59.285 +        return [1, 0, 0, 0, 0, cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1];
  59.286 +    };
  59.287 +
  59.288 +    /**
  59.289 +     * Return a Transform which represents a clockwise
  59.290 +     *    rotation around the y axis.
  59.291 +     *
  59.292 +     * @method rotateY
  59.293 +     * @static
  59.294 +     * @param {Number} theta radians
  59.295 +     * @return {Transform}
  59.296 +     */
  59.297 +    Transform.rotateY = function rotateY(theta) {
  59.298 +        var cosTheta = Math.cos(theta);
  59.299 +        var sinTheta = Math.sin(theta);
  59.300 +        return [cosTheta, 0, -sinTheta, 0, 0, 1, 0, 0, sinTheta, 0, cosTheta, 0, 0, 0, 0, 1];
  59.301 +    };
  59.302 +
  59.303 +    /**
  59.304 +     * Return a Transform which represents a clockwise
  59.305 +     *    rotation around the z axis.
  59.306 +     *
  59.307 +     * @method rotateZ
  59.308 +     * @static
  59.309 +     * @param {Number} theta radians
  59.310 +     * @return {Transform}
  59.311 +     */
  59.312 +    Transform.rotateZ = function rotateZ(theta) {
  59.313 +        var cosTheta = Math.cos(theta);
  59.314 +        var sinTheta = Math.sin(theta);
  59.315 +        return [cosTheta, sinTheta, 0, 0, -sinTheta, cosTheta, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  59.316 +    };
  59.317 +
  59.318 +    /**
  59.319 +     * Return a Transform which represents composed clockwise
  59.320 +     *    rotations along each of the axes. Equivalent to the result of
  59.321 +     *    Matrix.multiply(rotateX(phi), rotateY(theta), rotateZ(psi)).
  59.322 +     *
  59.323 +     * @method rotate
  59.324 +     * @static
  59.325 +     * @param {Number} phi radians to rotate about the positive x axis
  59.326 +     * @param {Number} theta radians to rotate about the positive y axis
  59.327 +     * @param {Number} psi radians to rotate about the positive z axis
  59.328 +     * @return {Transform}
  59.329 +     */
  59.330 +    Transform.rotate = function rotate(phi, theta, psi) {
  59.331 +        var cosPhi = Math.cos(phi);
  59.332 +        var sinPhi = Math.sin(phi);
  59.333 +        var cosTheta = Math.cos(theta);
  59.334 +        var sinTheta = Math.sin(theta);
  59.335 +        var cosPsi = Math.cos(psi);
  59.336 +        var sinPsi = Math.sin(psi);
  59.337 +        var result = [
  59.338 +            cosTheta * cosPsi,
  59.339 +            cosPhi * sinPsi + sinPhi * sinTheta * cosPsi,
  59.340 +            sinPhi * sinPsi - cosPhi * sinTheta * cosPsi,
  59.341 +            0,
  59.342 +            -cosTheta * sinPsi,
  59.343 +            cosPhi * cosPsi - sinPhi * sinTheta * sinPsi,
  59.344 +            sinPhi * cosPsi + cosPhi * sinTheta * sinPsi,
  59.345 +            0,
  59.346 +            sinTheta,
  59.347 +            -sinPhi * cosTheta,
  59.348 +            cosPhi * cosTheta,
  59.349 +            0,
  59.350 +            0, 0, 0, 1
  59.351 +        ];
  59.352 +        return result;
  59.353 +    };
  59.354 +
  59.355 +    /**
  59.356 +     * Return a Transform which represents an axis-angle rotation
  59.357 +     *
  59.358 +     * @method rotateAxis
  59.359 +     * @static
  59.360 +     * @param {Array.Number} v unit vector representing the axis to rotate about
  59.361 +     * @param {Number} theta radians to rotate clockwise about the axis
  59.362 +     * @return {Transform}
  59.363 +     */
  59.364 +    Transform.rotateAxis = function rotateAxis(v, theta) {
  59.365 +        var sinTheta = Math.sin(theta);
  59.366 +        var cosTheta = Math.cos(theta);
  59.367 +        var verTheta = 1 - cosTheta; // versine of theta
  59.368 +
  59.369 +        var xxV = v[0] * v[0] * verTheta;
  59.370 +        var xyV = v[0] * v[1] * verTheta;
  59.371 +        var xzV = v[0] * v[2] * verTheta;
  59.372 +        var yyV = v[1] * v[1] * verTheta;
  59.373 +        var yzV = v[1] * v[2] * verTheta;
  59.374 +        var zzV = v[2] * v[2] * verTheta;
  59.375 +        var xs = v[0] * sinTheta;
  59.376 +        var ys = v[1] * sinTheta;
  59.377 +        var zs = v[2] * sinTheta;
  59.378 +
  59.379 +        var result = [
  59.380 +            xxV + cosTheta, xyV + zs, xzV - ys, 0,
  59.381 +            xyV - zs, yyV + cosTheta, yzV + xs, 0,
  59.382 +            xzV + ys, yzV - xs, zzV + cosTheta, 0,
  59.383 +            0, 0, 0, 1
  59.384 +        ];
  59.385 +        return result;
  59.386 +    };
  59.387 +
  59.388 +    /**
  59.389 +     * Return a Transform which represents a transform matrix applied about
  59.390 +     * a separate origin point.
  59.391 +     *
  59.392 +     * @method aboutOrigin
  59.393 +     * @static
  59.394 +     * @param {Array.Number} v origin point to apply matrix
  59.395 +     * @param {Transform} m matrix to apply
  59.396 +     * @return {Transform}
  59.397 +     */
  59.398 +    Transform.aboutOrigin = function aboutOrigin(v, m) {
  59.399 +        var t0 = v[0] - (v[0] * m[0] + v[1] * m[4] + v[2] * m[8]);
  59.400 +        var t1 = v[1] - (v[0] * m[1] + v[1] * m[5] + v[2] * m[9]);
  59.401 +        var t2 = v[2] - (v[0] * m[2] + v[1] * m[6] + v[2] * m[10]);
  59.402 +        return Transform.thenMove(m, [t0, t1, t2]);
  59.403 +    };
  59.404 +
  59.405 +    /**
  59.406 +     * Return a Transform representation of a skew transformation
  59.407 +     *
  59.408 +     * @method skew
  59.409 +     * @static
  59.410 +     * @param {Number} phi scale factor skew in the x axis
  59.411 +     * @param {Number} theta scale factor skew in the y axis
  59.412 +     * @param {Number} psi scale factor skew in the z axis
  59.413 +     * @return {Transform}
  59.414 +     */
  59.415 +    Transform.skew = function skew(phi, theta, psi) {
  59.416 +        return [1, 0, 0, 0, Math.tan(psi), 1, 0, 0, Math.tan(theta), Math.tan(phi), 1, 0, 0, 0, 0, 1];
  59.417 +    };
  59.418 +
  59.419 +    /**
  59.420 +     * Return a Transform representation of a skew in the x-direction
  59.421 +     *
  59.422 +     * @method skewX
  59.423 +     * @static
  59.424 +     * @param {Number} angle the angle between the top and left sides
  59.425 +     * @return {Transform}
  59.426 +     */
  59.427 +    Transform.skewX = function skewX(angle) {
  59.428 +        return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  59.429 +    };
  59.430 +
  59.431 +    /**
  59.432 +     * Return a Transform representation of a skew in the y-direction
  59.433 +     *
  59.434 +     * @method skewY
  59.435 +     * @static
  59.436 +     * @param {Number} angle the angle between the top and right sides
  59.437 +     * @return {Transform}
  59.438 +     */
  59.439 +    Transform.skewY = function skewY(angle) {
  59.440 +        return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  59.441 +    };
  59.442 +
  59.443 +    /**
  59.444 +     * Returns a perspective Transform matrix
  59.445 +     *
  59.446 +     * @method perspective
  59.447 +     * @static
  59.448 +     * @param {Number} focusZ z position of focal point
  59.449 +     * @return {Transform}
  59.450 +     */
  59.451 +    Transform.perspective = function perspective(focusZ) {
  59.452 +        return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1 / focusZ, 0, 0, 0, 1];
  59.453 +    };
  59.454 +
  59.455 +    /**
  59.456 +     * Return translation vector component of given Transform
  59.457 +     *
  59.458 +     * @method getTranslate
  59.459 +     * @static
  59.460 +     * @param {Transform} m Transform
  59.461 +     * @return {Array.Number} the translation vector [t_x, t_y, t_z]
  59.462 +     */
  59.463 +    Transform.getTranslate = function getTranslate(m) {
  59.464 +        return [m[12], m[13], m[14]];
  59.465 +    };
  59.466 +
  59.467 +    /**
  59.468 +     * Return inverse affine transform for given Transform.
  59.469 +     *   Note: This assumes m[3] = m[7] = m[11] = 0, and m[15] = 1.
  59.470 +     *   Will provide incorrect results if not invertible or preconditions not met.
  59.471 +     *
  59.472 +     * @method inverse
  59.473 +     * @static
  59.474 +     * @param {Transform} m Transform
  59.475 +     * @return {Transform}
  59.476 +     */
  59.477 +    Transform.inverse = function inverse(m) {
  59.478 +        // only need to consider 3x3 section for affine
  59.479 +        var c0 = m[5] * m[10] - m[6] * m[9];
  59.480 +        var c1 = m[4] * m[10] - m[6] * m[8];
  59.481 +        var c2 = m[4] * m[9] - m[5] * m[8];
  59.482 +        var c4 = m[1] * m[10] - m[2] * m[9];
  59.483 +        var c5 = m[0] * m[10] - m[2] * m[8];
  59.484 +        var c6 = m[0] * m[9] - m[1] * m[8];
  59.485 +        var c8 = m[1] * m[6] - m[2] * m[5];
  59.486 +        var c9 = m[0] * m[6] - m[2] * m[4];
  59.487 +        var c10 = m[0] * m[5] - m[1] * m[4];
  59.488 +        var detM = m[0] * c0 - m[1] * c1 + m[2] * c2;
  59.489 +        var invD = 1 / detM;
  59.490 +        var result = [
  59.491 +            invD * c0, -invD * c4, invD * c8, 0,
  59.492 +            -invD * c1, invD * c5, -invD * c9, 0,
  59.493 +            invD * c2, -invD * c6, invD * c10, 0,
  59.494 +            0, 0, 0, 1
  59.495 +        ];
  59.496 +        result[12] = -m[12] * result[0] - m[13] * result[4] - m[14] * result[8];
  59.497 +        result[13] = -m[12] * result[1] - m[13] * result[5] - m[14] * result[9];
  59.498 +        result[14] = -m[12] * result[2] - m[13] * result[6] - m[14] * result[10];
  59.499 +        return result;
  59.500 +    };
  59.501 +
  59.502 +    /**
  59.503 +     * Returns the transpose of a 4x4 matrix
  59.504 +     *
  59.505 +     * @method transpose
  59.506 +     * @static
  59.507 +     * @param {Transform} m matrix
  59.508 +     * @return {Transform} the resulting transposed matrix
  59.509 +     */
  59.510 +    Transform.transpose = function transpose(m) {
  59.511 +        return [m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]];
  59.512 +    };
  59.513 +
  59.514 +    function _normSquared(v) {
  59.515 +        return (v.length === 2) ? v[0] * v[0] + v[1] * v[1] : v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
  59.516 +    }
  59.517 +    function _norm(v) {
  59.518 +        return Math.sqrt(_normSquared(v));
  59.519 +    }
  59.520 +    function _sign(n) {
  59.521 +        return (n < 0) ? -1 : 1;
  59.522 +    }
  59.523 +
  59.524 +    /**
  59.525 +     * Decompose Transform into separate .translate, .rotate, .scale,
  59.526 +     *    and .skew components.
  59.527 +     *
  59.528 +     * @method interpret
  59.529 +     * @static
  59.530 +     * @param {Transform} M transform matrix
  59.531 +     * @return {Object} matrix spec object with component matrices .translate,
  59.532 +     *    .rotate, .scale, .skew
  59.533 +     */
  59.534 +    Transform.interpret = function interpret(M) {
  59.535 +
  59.536 +        // QR decomposition via Householder reflections
  59.537 +        //FIRST ITERATION
  59.538 +
  59.539 +        //default Q1 to the identity matrix;
  59.540 +        var x = [M[0], M[1], M[2]];                // first column vector
  59.541 +        var sgn = _sign(x[0]);                     // sign of first component of x (for stability)
  59.542 +        var xNorm = _norm(x);                      // norm of first column vector
  59.543 +        var v = [x[0] + sgn * xNorm, x[1], x[2]];  // v = x + sign(x[0])|x|e1
  59.544 +        var mult = 2 / _normSquared(v);            // mult = 2/v'v
  59.545 +
  59.546 +        //bail out if our Matrix is singular
  59.547 +        if (mult >= Infinity) {
  59.548 +            return {translate: Transform.getTranslate(M), rotate: [0, 0, 0], scale: [0, 0, 0], skew: [0, 0, 0]};
  59.549 +        }
  59.550 +
  59.551 +        //evaluate Q1 = I - 2vv'/v'v
  59.552 +        var Q1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
  59.553 +
  59.554 +        //diagonals
  59.555 +        Q1[0]  = 1 - mult * v[0] * v[0];    // 0,0 entry
  59.556 +        Q1[5]  = 1 - mult * v[1] * v[1];    // 1,1 entry
  59.557 +        Q1[10] = 1 - mult * v[2] * v[2];    // 2,2 entry
  59.558 +
  59.559 +        //upper diagonal
  59.560 +        Q1[1] = -mult * v[0] * v[1];        // 0,1 entry
  59.561 +        Q1[2] = -mult * v[0] * v[2];        // 0,2 entry
  59.562 +        Q1[6] = -mult * v[1] * v[2];        // 1,2 entry
  59.563 +
  59.564 +        //lower diagonal
  59.565 +        Q1[4] = Q1[1];                      // 1,0 entry
  59.566 +        Q1[8] = Q1[2];                      // 2,0 entry
  59.567 +        Q1[9] = Q1[6];                      // 2,1 entry
  59.568 +
  59.569 +        //reduce first column of M
  59.570 +        var MQ1 = Transform.multiply(Q1, M);
  59.571 +
  59.572 +        //SECOND ITERATION on (1,1) minor
  59.573 +        var x2 = [MQ1[5], MQ1[6]];
  59.574 +        var sgn2 = _sign(x2[0]);                    // sign of first component of x (for stability)
  59.575 +        var x2Norm = _norm(x2);                     // norm of first column vector
  59.576 +        var v2 = [x2[0] + sgn2 * x2Norm, x2[1]];    // v = x + sign(x[0])|x|e1
  59.577 +        var mult2 = 2 / _normSquared(v2);           // mult = 2/v'v
  59.578 +
  59.579 +        //evaluate Q2 = I - 2vv'/v'v
  59.580 +        var Q2 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
  59.581 +
  59.582 +        //diagonal
  59.583 +        Q2[5]  = 1 - mult2 * v2[0] * v2[0]; // 1,1 entry
  59.584 +        Q2[10] = 1 - mult2 * v2[1] * v2[1]; // 2,2 entry
  59.585 +
  59.586 +        //off diagonals
  59.587 +        Q2[6] = -mult2 * v2[0] * v2[1];     // 2,1 entry
  59.588 +        Q2[9] = Q2[6];                      // 1,2 entry
  59.589 +
  59.590 +        //calc QR decomposition. Q = Q1*Q2, R = Q'*M
  59.591 +        var Q = Transform.multiply(Q2, Q1);      //note: really Q transpose
  59.592 +        var R = Transform.multiply(Q, M);
  59.593 +
  59.594 +        //remove negative scaling
  59.595 +        var remover = Transform.scale(R[0] < 0 ? -1 : 1, R[5] < 0 ? -1 : 1, R[10] < 0 ? -1 : 1);
  59.596 +        R = Transform.multiply(R, remover);
  59.597 +        Q = Transform.multiply(remover, Q);
  59.598 +
  59.599 +        //decompose into rotate/scale/skew matrices
  59.600 +        var result = {};
  59.601 +        result.translate = Transform.getTranslate(M);
  59.602 +        result.rotate = [Math.atan2(-Q[6], Q[10]), Math.asin(Q[2]), Math.atan2(-Q[1], Q[0])];
  59.603 +        if (!result.rotate[0]) {
  59.604 +            result.rotate[0] = 0;
  59.605 +            result.rotate[2] = Math.atan2(Q[4], Q[5]);
  59.606 +        }
  59.607 +        result.scale = [R[0], R[5], R[10]];
  59.608 +        result.skew = [Math.atan2(R[9], result.scale[2]), Math.atan2(R[8], result.scale[2]), Math.atan2(R[4], result.scale[0])];
  59.609 +
  59.610 +        //double rotation workaround
  59.611 +        if (Math.abs(result.rotate[0]) + Math.abs(result.rotate[2]) > 1.5 * Math.PI) {
  59.612 +            result.rotate[1] = Math.PI - result.rotate[1];
  59.613 +            if (result.rotate[1] > Math.PI) result.rotate[1] -= 2 * Math.PI;
  59.614 +            if (result.rotate[1] < -Math.PI) result.rotate[1] += 2 * Math.PI;
  59.615 +            if (result.rotate[0] < 0) result.rotate[0] += Math.PI;
  59.616 +            else result.rotate[0] -= Math.PI;
  59.617 +            if (result.rotate[2] < 0) result.rotate[2] += Math.PI;
  59.618 +            else result.rotate[2] -= Math.PI;
  59.619 +        }
  59.620 +
  59.621 +        return result;
  59.622 +    };
  59.623 +
  59.624 +    /**
  59.625 +     * Weighted average between two matrices by averaging their
  59.626 +     *     translation, rotation, scale, skew components.
  59.627 +     *     f(M1,M2,t) = (1 - t) * M1 + t * M2
  59.628 +     *
  59.629 +     * @method average
  59.630 +     * @static
  59.631 +     * @param {Transform} M1 f(M1,M2,0) = M1
  59.632 +     * @param {Transform} M2 f(M1,M2,1) = M2
  59.633 +     * @param {Number} t
  59.634 +     * @return {Transform}
  59.635 +     */
  59.636 +    Transform.average = function average(M1, M2, t) {
  59.637 +        t = (t === undefined) ? 0.5 : t;
  59.638 +        var specM1 = Transform.interpret(M1);
  59.639 +        var specM2 = Transform.interpret(M2);
  59.640 +
  59.641 +        var specAvg = {
  59.642 +            translate: [0, 0, 0],
  59.643 +            rotate: [0, 0, 0],
  59.644 +            scale: [0, 0, 0],
  59.645 +            skew: [0, 0, 0]
  59.646 +        };
  59.647 +
  59.648 +        for (var i = 0; i < 3; i++) {
  59.649 +            specAvg.translate[i] = (1 - t) * specM1.translate[i] + t * specM2.translate[i];
  59.650 +            specAvg.rotate[i] = (1 - t) * specM1.rotate[i] + t * specM2.rotate[i];
  59.651 +            specAvg.scale[i] = (1 - t) * specM1.scale[i] + t * specM2.scale[i];
  59.652 +            specAvg.skew[i] = (1 - t) * specM1.skew[i] + t * specM2.skew[i];
  59.653 +        }
  59.654 +        return Transform.build(specAvg);
  59.655 +    };
  59.656 +
  59.657 +    /**
  59.658 +     * Compose .translate, .rotate, .scale, .skew components into
  59.659 +     * Transform matrix
  59.660 +     *
  59.661 +     * @method build
  59.662 +     * @static
  59.663 +     * @param {matrixSpec} spec object with component matrices .translate,
  59.664 +     *    .rotate, .scale, .skew
  59.665 +     * @return {Transform} composed transform
  59.666 +     */
  59.667 +    Transform.build = function build(spec) {
  59.668 +        var scaleMatrix = Transform.scale(spec.scale[0], spec.scale[1], spec.scale[2]);
  59.669 +        var skewMatrix = Transform.skew(spec.skew[0], spec.skew[1], spec.skew[2]);
  59.670 +        var rotateMatrix = Transform.rotate(spec.rotate[0], spec.rotate[1], spec.rotate[2]);
  59.671 +        return Transform.thenMove(Transform.multiply(Transform.multiply(rotateMatrix, skewMatrix), scaleMatrix), spec.translate);
  59.672 +    };
  59.673 +
  59.674 +    /**
  59.675 +     * Determine if two Transforms are component-wise equal
  59.676 +     *   Warning: breaks on perspective Transforms
  59.677 +     *
  59.678 +     * @method equals
  59.679 +     * @static
  59.680 +     * @param {Transform} a matrix
  59.681 +     * @param {Transform} b matrix
  59.682 +     * @return {boolean}
  59.683 +     */
  59.684 +    Transform.equals = function equals(a, b) {
  59.685 +        return !Transform.notEquals(a, b);
  59.686 +    };
  59.687 +
  59.688 +    /**
  59.689 +     * Determine if two Transforms are component-wise unequal
  59.690 +     *   Warning: breaks on perspective Transforms
  59.691 +     *
  59.692 +     * @method notEquals
  59.693 +     * @static
  59.694 +     * @param {Transform} a matrix
  59.695 +     * @param {Transform} b matrix
  59.696 +     * @return {boolean}
  59.697 +     */
  59.698 +    Transform.notEquals = function notEquals(a, b) {
  59.699 +        if (a === b) return false;
  59.700 +
  59.701 +        // shortci
  59.702 +        return !(a && b) ||
  59.703 +            a[12] !== b[12] || a[13] !== b[13] || a[14] !== b[14] ||
  59.704 +            a[0] !== b[0] || a[1] !== b[1] || a[2] !== b[2] ||
  59.705 +            a[4] !== b[4] || a[5] !== b[5] || a[6] !== b[6] ||
  59.706 +            a[8] !== b[8] || a[9] !== b[9] || a[10] !== b[10];
  59.707 +    };
  59.708 +
  59.709 +    /**
  59.710 +     * Constrain angle-trio components to range of [-pi, pi).
  59.711 +     *
  59.712 +     * @method normalizeRotation
  59.713 +     * @static
  59.714 +     * @param {Array.Number} rotation phi, theta, psi (array of floats
  59.715 +     *    && array.length == 3)
  59.716 +     * @return {Array.Number} new phi, theta, psi triplet
  59.717 +     *    (array of floats && array.length == 3)
  59.718 +     */
  59.719 +    Transform.normalizeRotation = function normalizeRotation(rotation) {
  59.720 +        var result = rotation.slice(0);
  59.721 +        if (result[0] === Math.PI * 0.5 || result[0] === -Math.PI * 0.5) {
  59.722 +            result[0] = -result[0];
  59.723 +            result[1] = Math.PI - result[1];
  59.724 +            result[2] -= Math.PI;
  59.725 +        }
  59.726 +        if (result[0] > Math.PI * 0.5) {
  59.727 +            result[0] = result[0] - Math.PI;
  59.728 +            result[1] = Math.PI - result[1];
  59.729 +            result[2] -= Math.PI;
  59.730 +        }
  59.731 +        if (result[0] < -Math.PI * 0.5) {
  59.732 +            result[0] = result[0] + Math.PI;
  59.733 +            result[1] = -Math.PI - result[1];
  59.734 +            result[2] -= Math.PI;
  59.735 +        }
  59.736 +        while (result[1] < -Math.PI) result[1] += 2 * Math.PI;
  59.737 +        while (result[1] >= Math.PI) result[1] -= 2 * Math.PI;
  59.738 +        while (result[2] < -Math.PI) result[2] += 2 * Math.PI;
  59.739 +        while (result[2] >= Math.PI) result[2] -= 2 * Math.PI;
  59.740 +        return result;
  59.741 +    };
  59.742 +
  59.743 +    /**
  59.744 +     * (Property) Array defining a translation forward in z by 1
  59.745 +     *
  59.746 +     * @property {array} inFront
  59.747 +     * @static
  59.748 +     * @final
  59.749 +     */
  59.750 +    Transform.inFront = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1e-3, 1];
  59.751 +
  59.752 +    /**
  59.753 +     * (Property) Array defining a translation backwards in z by 1
  59.754 +     *
  59.755 +     * @property {array} behind
  59.756 +     * @static
  59.757 +     * @final
  59.758 +     */
  59.759 +    Transform.behind = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1e-3, 1];
  59.760 +
  59.761 +    module.exports = Transform;
  59.762 +});
  59.763 +
  59.764 +
  59.765 +/* This Source Code Form is subject to the terms of the Mozilla Public
  59.766 + * License, v. 2.0. If a copy of the MPL was not distributed with this
  59.767 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  59.768 + *
  59.769 + * Owner: mark@famo.us
  59.770 + * @license MPL 2.0
  59.771 + * @copyright Famous Industries, Inc. 2014
  59.772 + */
  59.773 +
  59.774 +define('famous/core/SpecParser',['require','exports','module','./Transform'],function(require, exports, module) {
  59.775 +    var Transform = require('./Transform');
  59.776 +
  59.777 +    /**
  59.778 +     *
  59.779 +     * This object translates the rendering instructions ("render specs")
  59.780 +     *   that renderable components generate into document update
  59.781 +     *   instructions ("update specs").  Private.
  59.782 +     *
  59.783 +     * @private
  59.784 +     * @class SpecParser
  59.785 +     * @constructor
  59.786 +     */
  59.787 +    function SpecParser() {
  59.788 +        this.result = {};
  59.789 +    }
  59.790 +    SpecParser._instance = new SpecParser();
  59.791 +
  59.792 +    /**
  59.793 +     * Convert a render spec coming from the context's render chain to an
  59.794 +     *    update spec for the update chain. This is the only major entry point
  59.795 +     *    for a consumer of this class.
  59.796 +     *
  59.797 +     * @method parse
  59.798 +     * @static
  59.799 +     * @private
  59.800 +     *
  59.801 +     * @param {renderSpec} spec input render spec
  59.802 +     * @param {Object} context context to do the parse in
  59.803 +     * @return {Object} the resulting update spec (if no callback
  59.804 +     *   specified, else none)
  59.805 +     */
  59.806 +    SpecParser.parse = function parse(spec, context) {
  59.807 +        return SpecParser._instance.parse(spec, context);
  59.808 +    };
  59.809 +
  59.810 +    /**
  59.811 +     * Convert a renderSpec coming from the context's render chain to an update
  59.812 +     *    spec for the update chain. This is the only major entrypoint for a
  59.813 +     *    consumer of this class.
  59.814 +     *
  59.815 +     * @method parse
  59.816 +     *
  59.817 +     * @private
  59.818 +     * @param {renderSpec} spec input render spec
  59.819 +     * @param {Context} context
  59.820 +     * @return {updateSpec} the resulting update spec
  59.821 +     */
  59.822 +    SpecParser.prototype.parse = function parse(spec, context) {
  59.823 +        this.reset();
  59.824 +        this._parseSpec(spec, context, Transform.identity);
  59.825 +        return this.result;
  59.826 +    };
  59.827 +
  59.828 +    /**
  59.829 +     * Prepare SpecParser for re-use (or first use) by setting internal state
  59.830 +     *  to blank.
  59.831 +     *
  59.832 +     * @private
  59.833 +     * @method reset
  59.834 +     */
  59.835 +    SpecParser.prototype.reset = function reset() {
  59.836 +        this.result = {};
  59.837 +    };
  59.838 +
  59.839 +    // Multiply matrix M by vector v
  59.840 +    function _vecInContext(v, m) {
  59.841 +        return [
  59.842 +            v[0] * m[0] + v[1] * m[4] + v[2] * m[8],
  59.843 +            v[0] * m[1] + v[1] * m[5] + v[2] * m[9],
  59.844 +            v[0] * m[2] + v[1] * m[6] + v[2] * m[10]
  59.845 +        ];
  59.846 +    }
  59.847 +
  59.848 +    var _originZeroZero = [0, 0];
  59.849 +
  59.850 +    // From the provided renderSpec tree, recursively compose opacities,
  59.851 +    //    origins, transforms, and sizes corresponding to each surface id from
  59.852 +    //    the provided renderSpec tree structure. On completion, those
  59.853 +    //    properties of 'this' object should be ready to use to build an
  59.854 +    //    updateSpec.
  59.855 +    SpecParser.prototype._parseSpec = function _parseSpec(spec, parentContext, sizeContext) {
  59.856 +        var id;
  59.857 +        var target;
  59.858 +        var transform;
  59.859 +        var opacity;
  59.860 +        var origin;
  59.861 +        var align;
  59.862 +        var size;
  59.863 +
  59.864 +        if (typeof spec === 'number') {
  59.865 +            id = spec;
  59.866 +            transform = parentContext.transform;
  59.867 +            align = parentContext.align || parentContext.origin;
  59.868 +            if (parentContext.size && align && (align[0] || align[1])) {
  59.869 +                var alignAdjust = [align[0] * parentContext.size[0], align[1] * parentContext.size[1], 0];
  59.870 +                transform = Transform.thenMove(transform, _vecInContext(alignAdjust, sizeContext));
  59.871 +            }
  59.872 +            this.result[id] = {
  59.873 +                transform: transform,
  59.874 +                opacity: parentContext.opacity,
  59.875 +                origin: parentContext.origin || _originZeroZero,
  59.876 +                align: parentContext.align || parentContext.origin || _originZeroZero,
  59.877 +                size: parentContext.size
  59.878 +            };
  59.879 +        }
  59.880 +        else if (!spec) { // placed here so 0 will be cached earlier
  59.881 +            return;
  59.882 +        }
  59.883 +        else if (spec instanceof Array) {
  59.884 +            for (var i = 0; i < spec.length; i++) {
  59.885 +                this._parseSpec(spec[i], parentContext, sizeContext);
  59.886 +            }
  59.887 +        }
  59.888 +        else {
  59.889 +            target = spec.target;
  59.890 +            transform = parentContext.transform;
  59.891 +            opacity = parentContext.opacity;
  59.892 +            origin = parentContext.origin;
  59.893 +            align = parentContext.align;
  59.894 +            size = parentContext.size;
  59.895 +            var nextSizeContext = sizeContext;
  59.896 +
  59.897 +            if (spec.opacity !== undefined) opacity = parentContext.opacity * spec.opacity;
  59.898 +            if (spec.transform) transform = Transform.multiply(parentContext.transform, spec.transform);
  59.899 +            if (spec.origin) {
  59.900 +                origin = spec.origin;
  59.901 +                nextSizeContext = parentContext.transform;
  59.902 +            }
  59.903 +            if (spec.align) align = spec.align;
  59.904 +            if (spec.size) {
  59.905 +                var parentSize = parentContext.size;
  59.906 +                size = [
  59.907 +                    spec.size[0] !== undefined ? spec.size[0] : parentSize[0],
  59.908 +                    spec.size[1] !== undefined ? spec.size[1] : parentSize[1]
  59.909 +                ];
  59.910 +                if (parentSize) {
  59.911 +                    if (!align) align = origin;
  59.912 +                    if (align && (align[0] || align[1])) transform = Transform.thenMove(transform, _vecInContext([align[0] * parentSize[0], align[1] * parentSize[1], 0], sizeContext));
  59.913 +                    if (origin && (origin[0] || origin[1])) transform = Transform.moveThen([-origin[0] * size[0], -origin[1] * size[1], 0], transform);
  59.914 +                }
  59.915 +                nextSizeContext = parentContext.transform;
  59.916 +                origin = null;
  59.917 +                align = null;
  59.918 +            }
  59.919 +
  59.920 +            this._parseSpec(target, {
  59.921 +                transform: transform,
  59.922 +                opacity: opacity,
  59.923 +                origin: origin,
  59.924 +                align: align,
  59.925 +                size: size
  59.926 +            }, nextSizeContext);
  59.927 +        }
  59.928 +    };
  59.929 +
  59.930 +    module.exports = SpecParser;
  59.931 +});
  59.932 +
  59.933 +/* This Source Code Form is subject to the terms of the Mozilla Public
  59.934 + * License, v. 2.0. If a copy of the MPL was not distributed with this
  59.935 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  59.936 + *
  59.937 + * Owner: mark@famo.us
  59.938 + * @license MPL 2.0
  59.939 + * @copyright Famous Industries, Inc. 2014
  59.940 + */
  59.941 +
  59.942 +define('famous/core/RenderNode',['require','exports','module','./Entity','./SpecParser'],function(require, exports, module) {
  59.943 +    var Entity = require('./Entity');
  59.944 +    var SpecParser = require('./SpecParser');
  59.945 +
  59.946 +    /**
  59.947 +     * A wrapper for inserting a renderable component (like a Modifer or
  59.948 +     *   Surface) into the render tree.
  59.949 +     *
  59.950 +     * @class RenderNode
  59.951 +     * @constructor
  59.952 +     *
  59.953 +     * @param {Object} object Target renderable component
  59.954 +     */
  59.955 +    function RenderNode(object) {
  59.956 +        this._object = null;
  59.957 +        this._child = null;
  59.958 +        this._hasMultipleChildren = false;
  59.959 +        this._isRenderable = false;
  59.960 +        this._isModifier = false;
  59.961 +
  59.962 +        this._resultCache = {};
  59.963 +        this._prevResults = {};
  59.964 +
  59.965 +        this._childResult = null;
  59.966 +
  59.967 +        if (object) this.set(object);
  59.968 +    }
  59.969 +
  59.970 +    /**
  59.971 +     * Append a renderable to the list of this node's children.
  59.972 +     *   This produces a new RenderNode in the tree.
  59.973 +     *   Note: Does not double-wrap if child is a RenderNode already.
  59.974 +     *
  59.975 +     * @method add
  59.976 +     * @param {Object} child renderable object
  59.977 +     * @return {RenderNode} new render node wrapping child
  59.978 +     */
  59.979 +    RenderNode.prototype.add = function add(child) {
  59.980 +        var childNode = (child instanceof RenderNode) ? child : new RenderNode(child);
  59.981 +        if (this._child instanceof Array) this._child.push(childNode);
  59.982 +        else if (this._child) {
  59.983 +            this._child = [this._child, childNode];
  59.984 +            this._hasMultipleChildren = true;
  59.985 +            this._childResult = []; // to be used later
  59.986 +        }
  59.987 +        else this._child = childNode;
  59.988 +
  59.989 +        return childNode;
  59.990 +    };
  59.991 +
  59.992 +    /**
  59.993 +     * Return the single wrapped object.  Returns null if this node has multiple child nodes.
  59.994 +     *
  59.995 +     * @method get
  59.996 +     *
  59.997 +     * @return {Ojbect} contained renderable object
  59.998 +     */
  59.999 +    RenderNode.prototype.get = function get() {
 59.1000 +        return this._object || (this._hasMultipleChildren ? null : (this._child ? this._child.get() : null));
 59.1001 +    };
 59.1002 +
 59.1003 +    /**
 59.1004 +     * Overwrite the list of children to contain the single provided object
 59.1005 +     *
 59.1006 +     * @method set
 59.1007 +     * @param {Object} child renderable object
 59.1008 +     * @return {RenderNode} this render node, or child if it is a RenderNode
 59.1009 +     */
 59.1010 +    RenderNode.prototype.set = function set(child) {
 59.1011 +        this._childResult = null;
 59.1012 +        this._hasMultipleChildren = false;
 59.1013 +        this._isRenderable = child.render ? true : false;
 59.1014 +        this._isModifier = child.modify ? true : false;
 59.1015 +        this._object = child;
 59.1016 +        this._child = null;
 59.1017 +        if (child instanceof RenderNode) return child;
 59.1018 +        else return this;
 59.1019 +    };
 59.1020 +
 59.1021 +    /**
 59.1022 +     * Get render size of contained object.
 59.1023 +     *
 59.1024 +     * @method getSize
 59.1025 +     * @return {Array.Number} size of this or size of single child.
 59.1026 +     */
 59.1027 +    RenderNode.prototype.getSize = function getSize() {
 59.1028 +        var result = null;
 59.1029 +        var target = this.get();
 59.1030 +        if (target && target.getSize) result = target.getSize();
 59.1031 +        if (!result && this._child && this._child.getSize) result = this._child.getSize();
 59.1032 +        return result;
 59.1033 +    };
 59.1034 +
 59.1035 +    // apply results of rendering this subtree to the document
 59.1036 +    function _applyCommit(spec, context, cacheStorage) {
 59.1037 +        var result = SpecParser.parse(spec, context);
 59.1038 +        var keys = Object.keys(result);
 59.1039 +        for (var i = 0; i < keys.length; i++) {
 59.1040 +            var id = keys[i];
 59.1041 +            var childNode = Entity.get(id);
 59.1042 +            var commitParams = result[id];
 59.1043 +            commitParams.allocator = context.allocator;
 59.1044 +            var commitResult = childNode.commit(commitParams);
 59.1045 +            if (commitResult) _applyCommit(commitResult, context, cacheStorage);
 59.1046 +            else cacheStorage[id] = commitParams;
 59.1047 +        }
 59.1048 +    }
 59.1049 +
 59.1050 +    /**
 59.1051 +     * Commit the content change from this node to the document.
 59.1052 +     *
 59.1053 +     * @private
 59.1054 +     * @method commit
 59.1055 +     * @param {Context} context render context
 59.1056 +     */
 59.1057 +    RenderNode.prototype.commit = function commit(context) {
 59.1058 +        // free up some divs from the last loop
 59.1059 +        var prevKeys = Object.keys(this._prevResults);
 59.1060 +        for (var i = 0; i < prevKeys.length; i++) {
 59.1061 +            var id = prevKeys[i];
 59.1062 +            if (this._resultCache[id] === undefined) {
 59.1063 +                var object = Entity.get(id);
 59.1064 +                if (object.cleanup) object.cleanup(context.allocator);
 59.1065 +            }
 59.1066 +        }
 59.1067 +
 59.1068 +        this._prevResults = this._resultCache;
 59.1069 +        this._resultCache = {};
 59.1070 +        _applyCommit(this.render(), context, this._resultCache);
 59.1071 +    };
 59.1072 +
 59.1073 +    /**
 59.1074 +     * Generate a render spec from the contents of the wrapped component.
 59.1075 +     *
 59.1076 +     * @private
 59.1077 +     * @method render
 59.1078 +     *
 59.1079 +     * @return {Object} render specification for the component subtree
 59.1080 +     *    only under this node.
 59.1081 +     */
 59.1082 +    RenderNode.prototype.render = function render() {
 59.1083 +        if (this._isRenderable) return this._object.render();
 59.1084 +
 59.1085 +        var result = null;
 59.1086 +        if (this._hasMultipleChildren) {
 59.1087 +            result = this._childResult;
 59.1088 +            var children = this._child;
 59.1089 +            for (var i = 0; i < children.length; i++) {
 59.1090 +                result[i] = children[i].render();
 59.1091 +            }
 59.1092 +        }
 59.1093 +        else if (this._child) result = this._child.render();
 59.1094 +
 59.1095 +        return this._isModifier ? this._object.modify(result) : result;
 59.1096 +    };
 59.1097 +
 59.1098 +    module.exports = RenderNode;
 59.1099 +});
 59.1100 +
 59.1101 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1102 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1103 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1104 + *
 59.1105 + * Owner: mark@famo.us
 59.1106 + * @license MPL 2.0
 59.1107 + * @copyright Famous Industries, Inc. 2014
 59.1108 + */
 59.1109 +
 59.1110 +define('famous/core/EventEmitter',['require','exports','module'],function(require, exports, module) {
 59.1111 +    /**
 59.1112 +     * EventEmitter represents a channel for events.
 59.1113 +     *
 59.1114 +     * @class EventEmitter
 59.1115 +     * @constructor
 59.1116 +     */
 59.1117 +    function EventEmitter() {
 59.1118 +        this.listeners = {};
 59.1119 +        this._owner = this;
 59.1120 +    }
 59.1121 +
 59.1122 +    /**
 59.1123 +     * Trigger an event, sending to all downstream handlers
 59.1124 +     *   listening for provided 'type' key.
 59.1125 +     *
 59.1126 +     * @method emit
 59.1127 +     *
 59.1128 +     * @param {string} type event type key (for example, 'click')
 59.1129 +     * @param {Object} event event data
 59.1130 +     * @return {EventHandler} this
 59.1131 +     */
 59.1132 +    EventEmitter.prototype.emit = function emit(type, event) {
 59.1133 +        var handlers = this.listeners[type];
 59.1134 +        if (handlers) {
 59.1135 +            for (var i = 0; i < handlers.length; i++) {
 59.1136 +                handlers[i].call(this._owner, event);
 59.1137 +            }
 59.1138 +        }
 59.1139 +        return this;
 59.1140 +    };
 59.1141 +
 59.1142 +    /**
 59.1143 +     * Bind a callback function to an event type handled by this object.
 59.1144 +     *
 59.1145 +     * @method "on"
 59.1146 +     *
 59.1147 +     * @param {string} type event type key (for example, 'click')
 59.1148 +     * @param {function(string, Object)} handler callback
 59.1149 +     * @return {EventHandler} this
 59.1150 +     */
 59.1151 +   EventEmitter.prototype.on = function on(type, handler) {
 59.1152 +        if (!(type in this.listeners)) this.listeners[type] = [];
 59.1153 +        var index = this.listeners[type].indexOf(handler);
 59.1154 +        if (index < 0) this.listeners[type].push(handler);
 59.1155 +        return this;
 59.1156 +    };
 59.1157 +
 59.1158 +    /**
 59.1159 +     * Alias for "on".
 59.1160 +     * @method addListener
 59.1161 +     */
 59.1162 +    EventEmitter.prototype.addListener = EventEmitter.prototype.on;
 59.1163 +
 59.1164 +   /**
 59.1165 +     * Unbind an event by type and handler.
 59.1166 +     *   This undoes the work of "on".
 59.1167 +     *
 59.1168 +     * @method removeListener
 59.1169 +     *
 59.1170 +     * @param {string} type event type key (for example, 'click')
 59.1171 +     * @param {function} handler function object to remove
 59.1172 +     * @return {EventEmitter} this
 59.1173 +     */
 59.1174 +    EventEmitter.prototype.removeListener = function removeListener(type, handler) {
 59.1175 +        var index = this.listeners[type].indexOf(handler);
 59.1176 +        if (index >= 0) this.listeners[type].splice(index, 1);
 59.1177 +        return this;
 59.1178 +    };
 59.1179 +
 59.1180 +    /**
 59.1181 +     * Call event handlers with this set to owner.
 59.1182 +     *
 59.1183 +     * @method bindThis
 59.1184 +     *
 59.1185 +     * @param {Object} owner object this EventEmitter belongs to
 59.1186 +     */
 59.1187 +    EventEmitter.prototype.bindThis = function bindThis(owner) {
 59.1188 +        this._owner = owner;
 59.1189 +    };
 59.1190 +
 59.1191 +    module.exports = EventEmitter;
 59.1192 +});
 59.1193 +
 59.1194 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1195 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1196 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1197 + *
 59.1198 + * Owner: mark@famo.us
 59.1199 + * @license MPL 2.0
 59.1200 + * @copyright Famous Industries, Inc. 2014
 59.1201 + */
 59.1202 +
 59.1203 +define('famous/core/EventHandler',['require','exports','module','./EventEmitter'],function(require, exports, module) {
 59.1204 +    var EventEmitter = require('./EventEmitter');
 59.1205 +
 59.1206 +    /**
 59.1207 +     * EventHandler forwards received events to a set of provided callback functions.
 59.1208 +     * It allows events to be captured, processed, and optionally piped through to other event handlers.
 59.1209 +     *
 59.1210 +     * @class EventHandler
 59.1211 +     * @extends EventEmitter
 59.1212 +     * @constructor
 59.1213 +     */
 59.1214 +    function EventHandler() {
 59.1215 +        EventEmitter.apply(this, arguments);
 59.1216 +
 59.1217 +        this.downstream = []; // downstream event handlers
 59.1218 +        this.downstreamFn = []; // downstream functions
 59.1219 +
 59.1220 +        this.upstream = []; // upstream event handlers
 59.1221 +        this.upstreamListeners = {}; // upstream listeners
 59.1222 +    }
 59.1223 +    EventHandler.prototype = Object.create(EventEmitter.prototype);
 59.1224 +    EventHandler.prototype.constructor = EventHandler;
 59.1225 +
 59.1226 +    /**
 59.1227 +     * Assign an event handler to receive an object's input events.
 59.1228 +     *
 59.1229 +     * @method setInputHandler
 59.1230 +     * @static
 59.1231 +     *
 59.1232 +     * @param {Object} object object to mix trigger, subscribe, and unsubscribe functions into
 59.1233 +     * @param {EventHandler} handler assigned event handler
 59.1234 +     */
 59.1235 +    EventHandler.setInputHandler = function setInputHandler(object, handler) {
 59.1236 +        object.trigger = handler.trigger.bind(handler);
 59.1237 +        if (handler.subscribe && handler.unsubscribe) {
 59.1238 +            object.subscribe = handler.subscribe.bind(handler);
 59.1239 +            object.unsubscribe = handler.unsubscribe.bind(handler);
 59.1240 +        }
 59.1241 +    };
 59.1242 +
 59.1243 +    /**
 59.1244 +     * Assign an event handler to receive an object's output events.
 59.1245 +     *
 59.1246 +     * @method setOutputHandler
 59.1247 +     * @static
 59.1248 +     *
 59.1249 +     * @param {Object} object object to mix pipe, unpipe, on, addListener, and removeListener functions into
 59.1250 +     * @param {EventHandler} handler assigned event handler
 59.1251 +     */
 59.1252 +    EventHandler.setOutputHandler = function setOutputHandler(object, handler) {
 59.1253 +        if (handler instanceof EventHandler) handler.bindThis(object);
 59.1254 +        object.pipe = handler.pipe.bind(handler);
 59.1255 +        object.unpipe = handler.unpipe.bind(handler);
 59.1256 +        object.on = handler.on.bind(handler);
 59.1257 +        object.addListener = object.on;
 59.1258 +        object.removeListener = handler.removeListener.bind(handler);
 59.1259 +    };
 59.1260 +
 59.1261 +    /**
 59.1262 +     * Trigger an event, sending to all downstream handlers
 59.1263 +     *   listening for provided 'type' key.
 59.1264 +     *
 59.1265 +     * @method emit
 59.1266 +     *
 59.1267 +     * @param {string} type event type key (for example, 'click')
 59.1268 +     * @param {Object} event event data
 59.1269 +     * @return {EventHandler} this
 59.1270 +     */
 59.1271 +    EventHandler.prototype.emit = function emit(type, event) {
 59.1272 +        EventEmitter.prototype.emit.apply(this, arguments);
 59.1273 +        var i = 0;
 59.1274 +        for (i = 0; i < this.downstream.length; i++) {
 59.1275 +            if (this.downstream[i].trigger) this.downstream[i].trigger(type, event);
 59.1276 +        }
 59.1277 +        for (i = 0; i < this.downstreamFn.length; i++) {
 59.1278 +            this.downstreamFn[i](type, event);
 59.1279 +        }
 59.1280 +        return this;
 59.1281 +    };
 59.1282 +
 59.1283 +    /**
 59.1284 +     * Alias for emit
 59.1285 +     * @method addListener
 59.1286 +     */
 59.1287 +    EventHandler.prototype.trigger = EventHandler.prototype.emit;
 59.1288 +
 59.1289 +    /**
 59.1290 +     * Add event handler object to set of downstream handlers.
 59.1291 +     *
 59.1292 +     * @method pipe
 59.1293 +     *
 59.1294 +     * @param {EventHandler} target event handler target object
 59.1295 +     * @return {EventHandler} passed event handler
 59.1296 +     */
 59.1297 +    EventHandler.prototype.pipe = function pipe(target) {
 59.1298 +        if (target.subscribe instanceof Function) return target.subscribe(this);
 59.1299 +
 59.1300 +        var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream;
 59.1301 +        var index = downstreamCtx.indexOf(target);
 59.1302 +        if (index < 0) downstreamCtx.push(target);
 59.1303 +
 59.1304 +        if (target instanceof Function) target('pipe', null);
 59.1305 +        else if (target.trigger) target.trigger('pipe', null);
 59.1306 +
 59.1307 +        return target;
 59.1308 +    };
 59.1309 +
 59.1310 +    /**
 59.1311 +     * Remove handler object from set of downstream handlers.
 59.1312 +     *   Undoes work of "pipe".
 59.1313 +     *
 59.1314 +     * @method unpipe
 59.1315 +     *
 59.1316 +     * @param {EventHandler} target target handler object
 59.1317 +     * @return {EventHandler} provided target
 59.1318 +     */
 59.1319 +    EventHandler.prototype.unpipe = function unpipe(target) {
 59.1320 +        if (target.unsubscribe instanceof Function) return target.unsubscribe(this);
 59.1321 +
 59.1322 +        var downstreamCtx = (target instanceof Function) ? this.downstreamFn : this.downstream;
 59.1323 +        var index = downstreamCtx.indexOf(target);
 59.1324 +        if (index >= 0) {
 59.1325 +            downstreamCtx.splice(index, 1);
 59.1326 +            if (target instanceof Function) target('unpipe', null);
 59.1327 +            else if (target.trigger) target.trigger('unpipe', null);
 59.1328 +            return target;
 59.1329 +        }
 59.1330 +        else return false;
 59.1331 +    };
 59.1332 +
 59.1333 +    /**
 59.1334 +     * Bind a callback function to an event type handled by this object.
 59.1335 +     *
 59.1336 +     * @method "on"
 59.1337 +     *
 59.1338 +     * @param {string} type event type key (for example, 'click')
 59.1339 +     * @param {function(string, Object)} handler callback
 59.1340 +     * @return {EventHandler} this
 59.1341 +     */
 59.1342 +    EventHandler.prototype.on = function on(type, handler) {
 59.1343 +        EventEmitter.prototype.on.apply(this, arguments);
 59.1344 +        if (!(type in this.upstreamListeners)) {
 59.1345 +            var upstreamListener = this.trigger.bind(this, type);
 59.1346 +            this.upstreamListeners[type] = upstreamListener;
 59.1347 +            for (var i = 0; i < this.upstream.length; i++) {
 59.1348 +                this.upstream[i].on(type, upstreamListener);
 59.1349 +            }
 59.1350 +        }
 59.1351 +        return this;
 59.1352 +    };
 59.1353 +
 59.1354 +    /**
 59.1355 +     * Alias for "on"
 59.1356 +     * @method addListener
 59.1357 +     */
 59.1358 +    EventHandler.prototype.addListener = EventHandler.prototype.on;
 59.1359 +
 59.1360 +    /**
 59.1361 +     * Listen for events from an upstream event handler.
 59.1362 +     *
 59.1363 +     * @method subscribe
 59.1364 +     *
 59.1365 +     * @param {EventEmitter} source source emitter object
 59.1366 +     * @return {EventHandler} this
 59.1367 +     */
 59.1368 +    EventHandler.prototype.subscribe = function subscribe(source) {
 59.1369 +        var index = this.upstream.indexOf(source);
 59.1370 +        if (index < 0) {
 59.1371 +            this.upstream.push(source);
 59.1372 +            for (var type in this.upstreamListeners) {
 59.1373 +                source.on(type, this.upstreamListeners[type]);
 59.1374 +            }
 59.1375 +        }
 59.1376 +        return this;
 59.1377 +    };
 59.1378 +
 59.1379 +    /**
 59.1380 +     * Stop listening to events from an upstream event handler.
 59.1381 +     *
 59.1382 +     * @method unsubscribe
 59.1383 +     *
 59.1384 +     * @param {EventEmitter} source source emitter object
 59.1385 +     * @return {EventHandler} this
 59.1386 +     */
 59.1387 +    EventHandler.prototype.unsubscribe = function unsubscribe(source) {
 59.1388 +        var index = this.upstream.indexOf(source);
 59.1389 +        if (index >= 0) {
 59.1390 +            this.upstream.splice(index, 1);
 59.1391 +            for (var type in this.upstreamListeners) {
 59.1392 +                source.removeListener(type, this.upstreamListeners[type]);
 59.1393 +            }
 59.1394 +        }
 59.1395 +        return this;
 59.1396 +    };
 59.1397 +
 59.1398 +    module.exports = EventHandler;
 59.1399 +});
 59.1400 +
 59.1401 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1402 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1403 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1404 + *
 59.1405 + * Owner: mark@famo.us
 59.1406 + * @license MPL 2.0
 59.1407 + * @copyright Famous Industries, Inc. 2014
 59.1408 + */
 59.1409 +
 59.1410 +define('famous/core/ElementAllocator',['require','exports','module'],function(require, exports, module) {
 59.1411 +
 59.1412 +    /**
 59.1413 +     * Internal helper object to Context that handles the process of
 59.1414 +     *   creating and allocating DOM elements within a managed div.
 59.1415 +     *   Private.
 59.1416 +     *
 59.1417 +     * @class ElementAllocator
 59.1418 +     * @constructor
 59.1419 +     * @private
 59.1420 +     * @param {Node} container document element in which Famo.us content will be inserted
 59.1421 +     */
 59.1422 +    function ElementAllocator(container) {
 59.1423 +        if (!container) container = document.createDocumentFragment();
 59.1424 +        this.container = container;
 59.1425 +        this.detachedNodes = {};
 59.1426 +        this.nodeCount = 0;
 59.1427 +    }
 59.1428 +
 59.1429 +    /**
 59.1430 +     * Move the document elements from their original container to a new one.
 59.1431 +     *
 59.1432 +     * @private
 59.1433 +     * @method migrate
 59.1434 +     *
 59.1435 +     * @param {Node} container document element to which Famo.us content will be migrated
 59.1436 +     */
 59.1437 +    ElementAllocator.prototype.migrate = function migrate(container) {
 59.1438 +        var oldContainer = this.container;
 59.1439 +        if (container === oldContainer) return;
 59.1440 +
 59.1441 +        if (oldContainer instanceof DocumentFragment) {
 59.1442 +            container.appendChild(oldContainer);
 59.1443 +        }
 59.1444 +        else {
 59.1445 +            while (oldContainer.hasChildNodes()) {
 59.1446 +                container.appendChild(oldContainer.removeChild(oldContainer.firstChild));
 59.1447 +            }
 59.1448 +        }
 59.1449 +
 59.1450 +        this.container = container;
 59.1451 +    };
 59.1452 +
 59.1453 +    /**
 59.1454 +     * Allocate an element of specified type from the pool.
 59.1455 +     *
 59.1456 +     * @private
 59.1457 +     * @method allocate
 59.1458 +     *
 59.1459 +     * @param {string} type type of element, e.g. 'div'
 59.1460 +     * @return {Node} allocated document element
 59.1461 +     */
 59.1462 +    ElementAllocator.prototype.allocate = function allocate(type) {
 59.1463 +        type = type.toLowerCase();
 59.1464 +        if (!(type in this.detachedNodes)) this.detachedNodes[type] = [];
 59.1465 +        var nodeStore = this.detachedNodes[type];
 59.1466 +        var result;
 59.1467 +        if (nodeStore.length > 0) {
 59.1468 +            result = nodeStore.pop();
 59.1469 +        }
 59.1470 +        else {
 59.1471 +            result = document.createElement(type);
 59.1472 +            this.container.appendChild(result);
 59.1473 +        }
 59.1474 +        this.nodeCount++;
 59.1475 +        return result;
 59.1476 +    };
 59.1477 +
 59.1478 +    /**
 59.1479 +     * De-allocate an element of specified type to the pool.
 59.1480 +     *
 59.1481 +     * @private
 59.1482 +     * @method deallocate
 59.1483 +     *
 59.1484 +     * @param {Node} element document element to deallocate
 59.1485 +     */
 59.1486 +    ElementAllocator.prototype.deallocate = function deallocate(element) {
 59.1487 +        var nodeType = element.nodeName.toLowerCase();
 59.1488 +        var nodeStore = this.detachedNodes[nodeType];
 59.1489 +        nodeStore.push(element);
 59.1490 +        this.nodeCount--;
 59.1491 +    };
 59.1492 +
 59.1493 +    /**
 59.1494 +     * Get count of total allocated nodes in the document.
 59.1495 +     *
 59.1496 +     * @private
 59.1497 +     * @method getNodeCount
 59.1498 +     *
 59.1499 +     * @return {Number} total node count
 59.1500 +     */
 59.1501 +    ElementAllocator.prototype.getNodeCount = function getNodeCount() {
 59.1502 +        return this.nodeCount;
 59.1503 +    };
 59.1504 +
 59.1505 +    module.exports = ElementAllocator;
 59.1506 +});
 59.1507 +
 59.1508 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1509 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1510 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1511 + *
 59.1512 + * Owner: mark@famo.us
 59.1513 + * @license MPL 2.0
 59.1514 + * @copyright Famous Industries, Inc. 2014
 59.1515 + */
 59.1516 +
 59.1517 +define('famous/utilities/Utility',['require','exports','module'],function(require, exports, module) {
 59.1518 +    /**
 59.1519 +     * This namespace holds standalone functionality.
 59.1520 +     *  Currently includes name mapping for transition curves,
 59.1521 +     *  name mapping for origin pairs, and the after() function.
 59.1522 +     *
 59.1523 +     * @class Utility
 59.1524 +     * @static
 59.1525 +     */
 59.1526 +    var Utility = {};
 59.1527 +
 59.1528 +    /**
 59.1529 +     * Table of direction array positions
 59.1530 +     *
 59.1531 +     * @property {object} Direction
 59.1532 +     * @final
 59.1533 +     */
 59.1534 +    Utility.Direction = {
 59.1535 +        X: 0,
 59.1536 +        Y: 1,
 59.1537 +        Z: 2
 59.1538 +    };
 59.1539 +
 59.1540 +    /**
 59.1541 +     * Return wrapper around callback function. Once the wrapper is called N
 59.1542 +     *   times, invoke the callback function. Arguments and scope preserved.
 59.1543 +     *
 59.1544 +     * @method after
 59.1545 +     *
 59.1546 +     * @param {number} count number of calls before callback function invoked
 59.1547 +     * @param {Function} callback wrapped callback function
 59.1548 +     *
 59.1549 +     * @return {function} wrapped callback with coundown feature
 59.1550 +     */
 59.1551 +    Utility.after = function after(count, callback) {
 59.1552 +        var counter = count;
 59.1553 +        return function() {
 59.1554 +            counter--;
 59.1555 +            if (counter === 0) callback.apply(this, arguments);
 59.1556 +        };
 59.1557 +    };
 59.1558 +
 59.1559 +    /**
 59.1560 +     * Load a URL and return its contents in a callback
 59.1561 +     *
 59.1562 +     * @method loadURL
 59.1563 +     *
 59.1564 +     * @param {string} url URL of object
 59.1565 +     * @param {function} callback callback to dispatch with content
 59.1566 +     */
 59.1567 +    Utility.loadURL = function loadURL(url, callback) {
 59.1568 +        var xhr = new XMLHttpRequest();
 59.1569 +        xhr.onreadystatechange = function onreadystatechange() {
 59.1570 +            if (this.readyState === 4) {
 59.1571 +                if (callback) callback(this.responseText);
 59.1572 +            }
 59.1573 +        };
 59.1574 +        xhr.open('GET', url);
 59.1575 +        xhr.send();
 59.1576 +    };
 59.1577 +
 59.1578 +    /**
 59.1579 +     * Create a document fragment from a string of HTML
 59.1580 +     *
 59.1581 +     * @method createDocumentFragmentFromHTML
 59.1582 +     *
 59.1583 +     * @param {string} html HTML to convert to DocumentFragment
 59.1584 +     *
 59.1585 +     * @return {DocumentFragment} DocumentFragment representing input HTML
 59.1586 +     */
 59.1587 +    Utility.createDocumentFragmentFromHTML = function createDocumentFragmentFromHTML(html) {
 59.1588 +        var element = document.createElement('div');
 59.1589 +        element.innerHTML = html;
 59.1590 +        var result = document.createDocumentFragment();
 59.1591 +        while (element.hasChildNodes()) result.appendChild(element.firstChild);
 59.1592 +        return result;
 59.1593 +    };
 59.1594 +
 59.1595 +    module.exports = Utility;
 59.1596 +});
 59.1597 +
 59.1598 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1599 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1600 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1601 + *
 59.1602 + * Owner: david@famo.us
 59.1603 + * @license MPL 2.0
 59.1604 + * @copyright Famous Industries, Inc. 2014
 59.1605 + */
 59.1606 +
 59.1607 +define('famous/transitions/MultipleTransition',['require','exports','module','famous/utilities/Utility'],function(require, exports, module) {
 59.1608 +    var Utility = require('famous/utilities/Utility');
 59.1609 +
 59.1610 +    /**
 59.1611 +     * Transition meta-method to support transitioning multiple
 59.1612 +     *   values with scalar-only methods.
 59.1613 +     *
 59.1614 +     *
 59.1615 +     * @class MultipleTransition
 59.1616 +     * @constructor
 59.1617 +     *
 59.1618 +     * @param {Object} method Transionable class to multiplex
 59.1619 +     */
 59.1620 +    function MultipleTransition(method) {
 59.1621 +        this.method = method;
 59.1622 +        this._instances = [];
 59.1623 +        this.state = [];
 59.1624 +    }
 59.1625 +
 59.1626 +    MultipleTransition.SUPPORTS_MULTIPLE = true;
 59.1627 +
 59.1628 +    /**
 59.1629 +     * Get the state of each transition.
 59.1630 +     *
 59.1631 +     * @method get
 59.1632 +     *
 59.1633 +     * @return state {Number|Array} state array
 59.1634 +     */
 59.1635 +    MultipleTransition.prototype.get = function get() {
 59.1636 +        for (var i = 0; i < this._instances.length; i++) {
 59.1637 +            this.state[i] = this._instances[i].get();
 59.1638 +        }
 59.1639 +        return this.state;
 59.1640 +    };
 59.1641 +
 59.1642 +    /**
 59.1643 +     * Set the end states with a shared transition, with optional callback.
 59.1644 +     *
 59.1645 +     * @method set
 59.1646 +     *
 59.1647 +     * @param {Number|Array} endState Final State.  Use a multi-element argument for multiple transitions.
 59.1648 +     * @param {Object} transition Transition definition, shared among all instances
 59.1649 +     * @param {Function} callback called when all endStates have been reached.
 59.1650 +     */
 59.1651 +    MultipleTransition.prototype.set = function set(endState, transition, callback) {
 59.1652 +        var _allCallback = Utility.after(endState.length, callback);
 59.1653 +        for (var i = 0; i < endState.length; i++) {
 59.1654 +            if (!this._instances[i]) this._instances[i] = new (this.method)();
 59.1655 +            this._instances[i].set(endState[i], transition, _allCallback);
 59.1656 +        }
 59.1657 +    };
 59.1658 +
 59.1659 +    /**
 59.1660 +     * Reset all transitions to start state.
 59.1661 +     *
 59.1662 +     * @method reset
 59.1663 +     *
 59.1664 +     * @param  {Number|Array} startState Start state
 59.1665 +     */
 59.1666 +    MultipleTransition.prototype.reset = function reset(startState) {
 59.1667 +        for (var i = 0; i < startState.length; i++) {
 59.1668 +            if (!this._instances[i]) this._instances[i] = new (this.method)();
 59.1669 +            this._instances[i].reset(startState[i]);
 59.1670 +        }
 59.1671 +    };
 59.1672 +
 59.1673 +    module.exports = MultipleTransition;
 59.1674 +});
 59.1675 +
 59.1676 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.1677 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.1678 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.1679 + *
 59.1680 + * Owner: david@famo.us
 59.1681 + * @license MPL 2.0
 59.1682 + * @copyright Famous Industries, Inc. 2014
 59.1683 + */
 59.1684 +
 59.1685 +define('famous/transitions/TweenTransition',['require','exports','module'],function(require, exports, module) {
 59.1686 +
 59.1687 +    /**
 59.1688 +     *
 59.1689 +     * A state maintainer for a smooth transition between
 59.1690 +     *    numerically-specified states.  Example numeric states include floats or
 59.1691 +     *    Transfornm objects.
 59.1692 +     *
 59.1693 +     *    An initial state is set with the constructor or set(startValue). A
 59.1694 +     *    corresponding end state and transition are set with set(endValue,
 59.1695 +     *    transition). Subsequent calls to set(endValue, transition) begin at
 59.1696 +     *    the last state. Calls to get(timestamp) provide the _interpolated state
 59.1697 +     *    along the way.
 59.1698 +     *
 59.1699 +     *   Note that there is no event loop here - calls to get() are the only way
 59.1700 +     *    to find out state projected to the current (or provided) time and are
 59.1701 +     *    the only way to trigger callbacks. Usually this kind of object would
 59.1702 +     *    be part of the render() path of a visible component.
 59.1703 +     *
 59.1704 +     * @class TweenTransition
 59.1705 +     * @constructor
 59.1706 +     *
 59.1707 +     * @param {Object} options TODO
 59.1708 +     *    beginning state
 59.1709 +     */
 59.1710 +    function TweenTransition(options) {
 59.1711 +        this.options = Object.create(TweenTransition.DEFAULT_OPTIONS);
 59.1712 +        if (options) this.setOptions(options);
 59.1713 +
 59.1714 +        this._startTime = 0;
 59.1715 +        this._startValue = 0;
 59.1716 +        this._updateTime = 0;
 59.1717 +        this._endValue = 0;
 59.1718 +        this._curve = undefined;
 59.1719 +        this._duration = 0;
 59.1720 +        this._active = false;
 59.1721 +        this._callback = undefined;
 59.1722 +        this.state = 0;
 59.1723 +        this.velocity = undefined;
 59.1724 +    }
 59.1725 +
 59.1726 +    /**
 59.1727 +     * Transition curves mapping independent variable t from domain [0,1] to a
 59.1728 +     *    range within [0,1]. Includes functions 'linear', 'easeIn', 'easeOut',
 59.1729 +     *    'easeInOut', 'easeOutBounce', 'spring'.
 59.1730 +     *
 59.1731 +     * @property {object} Curve
 59.1732 +     * @final
 59.1733 +     */
 59.1734 +    TweenTransition.Curves = {
 59.1735 +        linear: function(t) {
 59.1736 +            return t;
 59.1737 +        },
 59.1738 +        easeIn: function(t) {
 59.1739 +            return t*t;
 59.1740 +        },
 59.1741 +        easeOut: function(t) {
 59.1742 +            return t*(2-t);
 59.1743 +        },
 59.1744 +        easeInOut: function(t) {
 59.1745 +            if (t <= 0.5) return 2*t*t;
 59.1746 +            else return -2*t*t + 4*t - 1;
 59.1747 +        },
 59.1748 +        easeOutBounce: function(t) {
 59.1749 +            return t*(3 - 2*t);
 59.1750 +        },
 59.1751 +        spring: function(t) {
 59.1752 +            return (1 - t) * Math.sin(6 * Math.PI * t) + t;
 59.1753 +        }
 59.1754 +    };
 59.1755 +
 59.1756 +    TweenTransition.SUPPORTS_MULTIPLE = true;
 59.1757 +    TweenTransition.DEFAULT_OPTIONS = {
 59.1758 +        curve: TweenTransition.Curves.linear,
 59.1759 +        duration: 500,
 59.1760 +        speed: 0 /* considered only if positive */
 59.1761 +    };
 59.1762 +
 59.1763 +    var registeredCurves = {};
 59.1764 +
 59.1765 +    /**
 59.1766 +     * Add "unit" curve to internal dictionary of registered curves.
 59.1767 +     *
 59.1768 +     * @method registerCurve
 59.1769 +     *
 59.1770 +     * @static
 59.1771 +     *
 59.1772 +     * @param {string} curveName dictionary key
 59.1773 +     * @param {unitCurve} curve function of one numeric variable mapping [0,1]
 59.1774 +     *    to range inside [0,1]
 59.1775 +     * @return {boolean} false if key is taken, else true
 59.1776 +     */
 59.1777 +    TweenTransition.registerCurve = function registerCurve(curveName, curve) {
 59.1778 +        if (!registeredCurves[curveName]) {
 59.1779 +            registeredCurves[curveName] = curve;
 59.1780 +            return true;
 59.1781 +        }
 59.1782 +        else {
 59.1783 +            return false;
 59.1784 +        }
 59.1785 +    };
 59.1786 +
 59.1787 +    /**
 59.1788 +     * Remove object with key "curveName" from internal dictionary of registered
 59.1789 +     *    curves.
 59.1790 +     *
 59.1791 +     * @method unregisterCurve
 59.1792 +     *
 59.1793 +     * @static
 59.1794 +     *
 59.1795 +     * @param {string} curveName dictionary key
 59.1796 +     * @return {boolean} false if key has no dictionary value
 59.1797 +     */
 59.1798 +    TweenTransition.unregisterCurve = function unregisterCurve(curveName) {
 59.1799 +        if (registeredCurves[curveName]) {
 59.1800 +            delete registeredCurves[curveName];
 59.1801 +            return true;
 59.1802 +        }
 59.1803 +        else {
 59.1804 +            return false;
 59.1805 +        }
 59.1806 +    };
 59.1807 +
 59.1808 +    /**
 59.1809 +     * Retrieve function with key "curveName" from internal dictionary of
 59.1810 +     *    registered curves. Default curves are defined in the
 59.1811 +     *    TweenTransition.Curves array, where the values represent
 59.1812 +     *    unitCurve functions.
 59.1813 +     *
 59.1814 +     * @method getCurve
 59.1815 +     *
 59.1816 +     * @static
 59.1817 +     *
 59.1818 +     * @param {string} curveName dictionary key
 59.1819 +     * @return {unitCurve} curve function of one numeric variable mapping [0,1]
 59.1820 +     *    to range inside [0,1]
 59.1821 +     */
 59.1822 +    TweenTransition.getCurve = function getCurve(curveName) {
 59.1823 +        var curve = registeredCurves[curveName];
 59.1824 +        if (curve !== undefined) return curve;
 59.1825 +        else throw new Error('curve not registered');
 59.1826 +    };
 59.1827 +
 59.1828 +    /**
 59.1829 +     * Retrieve all available curves.
 59.1830 +     *
 59.1831 +     * @method getCurves
 59.1832 +     *
 59.1833 +     * @static
 59.1834 +     *
 59.1835 +     * @return {object} curve functions of one numeric variable mapping [0,1]
 59.1836 +     *    to range inside [0,1]
 59.1837 +     */
 59.1838 +    TweenTransition.getCurves = function getCurves() {
 59.1839 +        return registeredCurves;
 59.1840 +    };
 59.1841 +
 59.1842 +     // Interpolate: If a linear function f(0) = a, f(1) = b, then return f(t)
 59.1843 +    function _interpolate(a, b, t) {
 59.1844 +        return ((1 - t) * a) + (t * b);
 59.1845 +    }
 59.1846 +
 59.1847 +    function _clone(obj) {
 59.1848 +        if (obj instanceof Object) {
 59.1849 +            if (obj instanceof Array) return obj.slice(0);
 59.1850 +            else return Object.create(obj);
 59.1851 +        }
 59.1852 +        else return obj;
 59.1853 +    }
 59.1854 +
 59.1855 +    // Fill in missing properties in "transition" with those in defaultTransition, and
 59.1856 +    //   convert internal named curve to function object, returning as new
 59.1857 +    //   object.
 59.1858 +    function _normalize(transition, defaultTransition) {
 59.1859 +        var result = {curve: defaultTransition.curve};
 59.1860 +        if (defaultTransition.duration) result.duration = defaultTransition.duration;
 59.1861 +        if (defaultTransition.speed) result.speed = defaultTransition.speed;
 59.1862 +        if (transition instanceof Object) {
 59.1863 +            if (transition.duration !== undefined) result.duration = transition.duration;
 59.1864 +            if (transition.curve) result.curve = transition.curve;
 59.1865 +            if (transition.speed) result.speed = transition.speed;
 59.1866 +        }
 59.1867 +        if (typeof result.curve === 'string') result.curve = TweenTransition.getCurve(result.curve);
 59.1868 +        return result;
 59.1869 +    }
 59.1870 +
 59.1871 +    /**
 59.1872 +     * Set internal options, overriding any default options.
 59.1873 +     *
 59.1874 +     * @method setOptions
 59.1875 +     *
 59.1876 +     *
 59.1877 +     * @param {Object} options options object
 59.1878 +     * @param {Object} [options.curve] function mapping [0,1] to [0,1] or identifier
 59.1879 +     * @param {Number} [options.duration] duration in ms
 59.1880 +     * @param {Number} [options.speed] speed in pixels per ms
 59.1881 +     */
 59.1882 +    TweenTransition.prototype.setOptions = function setOptions(options) {
 59.1883 +        if (options.curve !== undefined) this.options.curve = options.curve;
 59.1884 +        if (options.duration !== undefined) this.options.duration = options.duration;
 59.1885 +        if (options.speed !== undefined) this.options.speed = options.speed;
 59.1886 +    };
 59.1887 +
 59.1888 +    /**
 59.1889 +     * Add transition to end state to the queue of pending transitions. Special
 59.1890 +     *    Use: calling without a transition resets the object to that state with
 59.1891 +     *    no pending actions
 59.1892 +     *
 59.1893 +     * @method set
 59.1894 +     *
 59.1895 +     *
 59.1896 +     * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endValue
 59.1897 +     *    end state to which we _interpolate
 59.1898 +     * @param {transition=} transition object of type {duration: number, curve:
 59.1899 +     *    f[0,1] -> [0,1] or name}. If transition is omitted, change will be
 59.1900 +     *    instantaneous.
 59.1901 +     * @param {function()=} callback Zero-argument function to call on observed
 59.1902 +     *    completion (t=1)
 59.1903 +     */
 59.1904 +    TweenTransition.prototype.set = function set(endValue, transition, callback) {
 59.1905 +        if (!transition) {
 59.1906 +            this.reset(endValue);
 59.1907 +            if (callback) callback();
 59.1908 +            return;
 59.1909 +        }
 59.1910 +
 59.1911 +        this._startValue = _clone(this.get());
 59.1912 +        transition = _normalize(transition, this.options);
 59.1913 +        if (transition.speed) {
 59.1914 +            var startValue = this._startValue;
 59.1915 +            if (startValue instanceof Object) {
 59.1916 +                var variance = 0;
 59.1917 +                for (var i in startValue) variance += (endValue[i] - startValue[i]) * (endValue[i] - startValue[i]);
 59.1918 +                transition.duration = Math.sqrt(variance) / transition.speed;
 59.1919 +            }
 59.1920 +            else {
 59.1921 +                transition.duration = Math.abs(endValue - startValue) / transition.speed;
 59.1922 +            }
 59.1923 +        }
 59.1924 +
 59.1925 +        this._startTime = Date.now();
 59.1926 +        this._endValue = _clone(endValue);
 59.1927 +        this._startVelocity = _clone(transition.velocity);
 59.1928 +        this._duration = transition.duration;
 59.1929 +        this._curve = transition.curve;
 59.1930 +        this._active = true;
 59.1931 +        this._callback = callback;
 59.1932 +    };
 59.1933 +
 59.1934 +    /**
 59.1935 +     * Cancel all transitions and reset to a stable state
 59.1936 +     *
 59.1937 +     * @method reset
 59.1938 +     *
 59.1939 +     * @param {number|Array.Number|Object.<number, number>} startValue
 59.1940 +     *    starting state
 59.1941 +     * @param {number} startVelocity
 59.1942 +     *    starting velocity
 59.1943 +     */
 59.1944 +    TweenTransition.prototype.reset = function reset(startValue, startVelocity) {
 59.1945 +        if (this._callback) {
 59.1946 +            var callback = this._callback;
 59.1947 +            this._callback = undefined;
 59.1948 +            callback();
 59.1949 +        }
 59.1950 +        this.state = _clone(startValue);
 59.1951 +        this.velocity = _clone(startVelocity);
 59.1952 +        this._startTime = 0;
 59.1953 +        this._duration = 0;
 59.1954 +        this._updateTime = 0;
 59.1955 +        this._startValue = this.state;
 59.1956 +        this._startVelocity = this.velocity;
 59.1957 +        this._endValue = this.state;
 59.1958 +        this._active = false;
 59.1959 +    };
 59.1960 +
 59.1961 +    /**
 59.1962 +     * Get current velocity
 59.1963 +     *
 59.1964 +     * @method getVelocity
 59.1965 +     *
 59.1966 +     * @returns {Number} velocity
 59.1967 +     */
 59.1968 +    TweenTransition.prototype.getVelocity = function getVelocity() {
 59.1969 +        return this.velocity;
 59.1970 +    };
 59.1971 +
 59.1972 +    /**
 59.1973 +     * Get interpolated state of current action at provided time. If the last
 59.1974 +     *    action has completed, invoke its callback.
 59.1975 +     *
 59.1976 +     * @method get
 59.1977 +     *
 59.1978 +     *
 59.1979 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 59.1980 +     *    time. If omitted, use current time. (Unix epoch time)
 59.1981 +     * @return {number|Object.<number|string, number>} beginning state
 59.1982 +     *    _interpolated to this point in time.
 59.1983 +     */
 59.1984 +    TweenTransition.prototype.get = function get(timestamp) {
 59.1985 +        this.update(timestamp);
 59.1986 +        return this.state;
 59.1987 +    };
 59.1988 +
 59.1989 +    function _calculateVelocity(current, start, curve, duration, t) {
 59.1990 +        var velocity;
 59.1991 +        var eps = 1e-7;
 59.1992 +        var speed = (curve(t) - curve(t - eps)) / eps;
 59.1993 +        if (current instanceof Array) {
 59.1994 +            velocity = [];
 59.1995 +            for (var i = 0; i < current.length; i++){
 59.1996 +                if (typeof current[i] === 'number')
 59.1997 +                    velocity[i] = speed * (current[i] - start[i]) / duration;
 59.1998 +                else
 59.1999 +                    velocity[i] = 0;
 59.2000 +            }
 59.2001 +
 59.2002 +        }
 59.2003 +        else velocity = speed * (current - start) / duration;
 59.2004 +        return velocity;
 59.2005 +    }
 59.2006 +
 59.2007 +    function _calculateState(start, end, t) {
 59.2008 +        var state;
 59.2009 +        if (start instanceof Array) {
 59.2010 +            state = [];
 59.2011 +            for (var i = 0; i < start.length; i++) {
 59.2012 +                if (typeof start[i] === 'number')
 59.2013 +                    state[i] = _interpolate(start[i], end[i], t);
 59.2014 +                else
 59.2015 +                    state[i] = start[i];
 59.2016 +            }
 59.2017 +        }
 59.2018 +        else state = _interpolate(start, end, t);
 59.2019 +        return state;
 59.2020 +    }
 59.2021 +
 59.2022 +    /**
 59.2023 +     * Update internal state to the provided timestamp. This may invoke the last
 59.2024 +     *    callback and begin a new action.
 59.2025 +     *
 59.2026 +     * @method update
 59.2027 +     *
 59.2028 +     *
 59.2029 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 59.2030 +     *    time. If omitted, use current time. (Unix epoch time)
 59.2031 +     */
 59.2032 +    TweenTransition.prototype.update = function update(timestamp) {
 59.2033 +        if (!this._active) {
 59.2034 +            if (this._callback) {
 59.2035 +                var callback = this._callback;
 59.2036 +                this._callback = undefined;
 59.2037 +                callback();
 59.2038 +            }
 59.2039 +            return;
 59.2040 +        }
 59.2041 +
 59.2042 +        if (!timestamp) timestamp = Date.now();
 59.2043 +        if (this._updateTime >= timestamp) return;
 59.2044 +        this._updateTime = timestamp;
 59.2045 +
 59.2046 +        var timeSinceStart = timestamp - this._startTime;
 59.2047 +        if (timeSinceStart >= this._duration) {
 59.2048 +            this.state = this._endValue;
 59.2049 +            this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, 1);
 59.2050 +            this._active = false;
 59.2051 +        }
 59.2052 +        else if (timeSinceStart < 0) {
 59.2053 +            this.state = this._startValue;
 59.2054 +            this.velocity = this._startVelocity;
 59.2055 +        }
 59.2056 +        else {
 59.2057 +            var t = timeSinceStart / this._duration;
 59.2058 +            this.state = _calculateState(this._startValue, this._endValue, this._curve(t));
 59.2059 +            this.velocity = _calculateVelocity(this.state, this._startValue, this._curve, this._duration, t);
 59.2060 +        }
 59.2061 +    };
 59.2062 +
 59.2063 +    /**
 59.2064 +     * Is there at least one action pending completion?
 59.2065 +     *
 59.2066 +     * @method isActive
 59.2067 +     *
 59.2068 +     *
 59.2069 +     * @return {boolean}
 59.2070 +     */
 59.2071 +    TweenTransition.prototype.isActive = function isActive() {
 59.2072 +        return this._active;
 59.2073 +    };
 59.2074 +
 59.2075 +    /**
 59.2076 +     * Halt transition at current state and erase all pending actions.
 59.2077 +     *
 59.2078 +     * @method halt
 59.2079 +     *
 59.2080 +     */
 59.2081 +    TweenTransition.prototype.halt = function halt() {
 59.2082 +        this.reset(this.get());
 59.2083 +    };
 59.2084 +
 59.2085 +    // Register all the default curves
 59.2086 +    TweenTransition.registerCurve('linear', TweenTransition.Curves.linear);
 59.2087 +    TweenTransition.registerCurve('easeIn', TweenTransition.Curves.easeIn);
 59.2088 +    TweenTransition.registerCurve('easeOut', TweenTransition.Curves.easeOut);
 59.2089 +    TweenTransition.registerCurve('easeInOut', TweenTransition.Curves.easeInOut);
 59.2090 +    TweenTransition.registerCurve('easeOutBounce', TweenTransition.Curves.easeOutBounce);
 59.2091 +    TweenTransition.registerCurve('spring', TweenTransition.Curves.spring);
 59.2092 +
 59.2093 +    TweenTransition.customCurve = function customCurve(v1, v2) {
 59.2094 +        v1 = v1 || 0; v2 = v2 || 0;
 59.2095 +        return function(t) {
 59.2096 +            return v1*t + (-2*v1 - v2 + 3)*t*t + (v1 + v2 - 2)*t*t*t;
 59.2097 +        };
 59.2098 +    };
 59.2099 +
 59.2100 +    module.exports = TweenTransition;
 59.2101 +});
 59.2102 +
 59.2103 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.2104 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.2105 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.2106 + *
 59.2107 + * Owner: david@famo.us
 59.2108 + * @license MPL 2.0
 59.2109 + * @copyright Famous Industries, Inc. 2014
 59.2110 + */
 59.2111 +
 59.2112 +define('famous/transitions/Transitionable',['require','exports','module','./MultipleTransition','./TweenTransition'],function(require, exports, module) {
 59.2113 +    var MultipleTransition = require('./MultipleTransition');
 59.2114 +    var TweenTransition = require('./TweenTransition');
 59.2115 +
 59.2116 +    /**
 59.2117 +     * A state maintainer for a smooth transition between
 59.2118 +     *    numerically-specified states. Example numeric states include floats or
 59.2119 +     *    Transform objects.
 59.2120 +     *
 59.2121 +     * An initial state is set with the constructor or set(startState). A
 59.2122 +     *    corresponding end state and transition are set with set(endState,
 59.2123 +     *    transition). Subsequent calls to set(endState, transition) begin at
 59.2124 +     *    the last state. Calls to get(timestamp) provide the interpolated state
 59.2125 +     *    along the way.
 59.2126 +     *
 59.2127 +     * Note that there is no event loop here - calls to get() are the only way
 59.2128 +     *    to find state projected to the current (or provided) time and are
 59.2129 +     *    the only way to trigger callbacks. Usually this kind of object would
 59.2130 +     *    be part of the render() path of a visible component.
 59.2131 +     *
 59.2132 +     * @class Transitionable
 59.2133 +     * @constructor
 59.2134 +     * @param {number|Array.Number|Object.<number|string, number>} start
 59.2135 +     *    beginning state
 59.2136 +     */
 59.2137 +    function Transitionable(start) {
 59.2138 +        this.currentAction = null;
 59.2139 +        this.actionQueue = [];
 59.2140 +        this.callbackQueue = [];
 59.2141 +
 59.2142 +        this.state = 0;
 59.2143 +        this.velocity = undefined;
 59.2144 +        this._callback = undefined;
 59.2145 +        this._engineInstance = null;
 59.2146 +        this._currentMethod = null;
 59.2147 +
 59.2148 +        this.set(start);
 59.2149 +    }
 59.2150 +
 59.2151 +    var transitionMethods = {};
 59.2152 +
 59.2153 +    Transitionable.registerMethod = function registerMethod(name, engineClass) {
 59.2154 +        if (!(name in transitionMethods)) {
 59.2155 +            transitionMethods[name] = engineClass;
 59.2156 +            return true;
 59.2157 +        }
 59.2158 +        else return false;
 59.2159 +    };
 59.2160 +
 59.2161 +    Transitionable.unregisterMethod = function unregisterMethod(name) {
 59.2162 +        if (name in transitionMethods) {
 59.2163 +            delete transitionMethods[name];
 59.2164 +            return true;
 59.2165 +        }
 59.2166 +        else return false;
 59.2167 +    };
 59.2168 +
 59.2169 +    function _loadNext() {
 59.2170 +        if (this._callback) {
 59.2171 +            var callback = this._callback;
 59.2172 +            this._callback = undefined;
 59.2173 +            callback();
 59.2174 +        }
 59.2175 +        if (this.actionQueue.length <= 0) {
 59.2176 +            this.set(this.get()); // no update required
 59.2177 +            return;
 59.2178 +        }
 59.2179 +        this.currentAction = this.actionQueue.shift();
 59.2180 +        this._callback = this.callbackQueue.shift();
 59.2181 +
 59.2182 +        var method = null;
 59.2183 +        var endValue = this.currentAction[0];
 59.2184 +        var transition = this.currentAction[1];
 59.2185 +        if (transition instanceof Object && transition.method) {
 59.2186 +            method = transition.method;
 59.2187 +            if (typeof method === 'string') method = transitionMethods[method];
 59.2188 +        }
 59.2189 +        else {
 59.2190 +            method = TweenTransition;
 59.2191 +        }
 59.2192 +
 59.2193 +        if (this._currentMethod !== method) {
 59.2194 +            if (!(endValue instanceof Object) || method.SUPPORTS_MULTIPLE === true || endValue.length <= method.SUPPORTS_MULTIPLE) {
 59.2195 +                this._engineInstance = new method();
 59.2196 +            }
 59.2197 +            else {
 59.2198 +                this._engineInstance = new MultipleTransition(method);
 59.2199 +            }
 59.2200 +            this._currentMethod = method;
 59.2201 +        }
 59.2202 +
 59.2203 +        this._engineInstance.reset(this.state, this.velocity);
 59.2204 +        if (this.velocity !== undefined) transition.velocity = this.velocity;
 59.2205 +        this._engineInstance.set(endValue, transition, _loadNext.bind(this));
 59.2206 +    }
 59.2207 +
 59.2208 +    /**
 59.2209 +     * Add transition to end state to the queue of pending transitions. Special
 59.2210 +     *    Use: calling without a transition resets the object to that state with
 59.2211 +     *    no pending actions
 59.2212 +     *
 59.2213 +     * @method set
 59.2214 +     *
 59.2215 +     * @param {number|FamousMatrix|Array.Number|Object.<number, number>} endState
 59.2216 +     *    end state to which we interpolate
 59.2217 +     * @param {transition=} transition object of type {duration: number, curve:
 59.2218 +     *    f[0,1] -> [0,1] or name}. If transition is omitted, change will be
 59.2219 +     *    instantaneous.
 59.2220 +     * @param {function()=} callback Zero-argument function to call on observed
 59.2221 +     *    completion (t=1)
 59.2222 +     */
 59.2223 +    Transitionable.prototype.set = function set(endState, transition, callback) {
 59.2224 +        if (!transition) {
 59.2225 +            this.reset(endState);
 59.2226 +            if (callback) callback();
 59.2227 +            return this;
 59.2228 +        }
 59.2229 +
 59.2230 +        var action = [endState, transition];
 59.2231 +        this.actionQueue.push(action);
 59.2232 +        this.callbackQueue.push(callback);
 59.2233 +        if (!this.currentAction) _loadNext.call(this);
 59.2234 +        return this;
 59.2235 +    };
 59.2236 +
 59.2237 +    /**
 59.2238 +     * Cancel all transitions and reset to a stable state
 59.2239 +     *
 59.2240 +     * @method reset
 59.2241 +     *
 59.2242 +     * @param {number|Array.Number|Object.<number, number>} startState
 59.2243 +     *    stable state to set to
 59.2244 +     */
 59.2245 +    Transitionable.prototype.reset = function reset(startState, startVelocity) {
 59.2246 +        this._currentMethod = null;
 59.2247 +        this._engineInstance = null;
 59.2248 +        this._callback = undefined;
 59.2249 +        this.state = startState;
 59.2250 +        this.velocity = startVelocity;
 59.2251 +        this.currentAction = null;
 59.2252 +        this.actionQueue = [];
 59.2253 +        this.callbackQueue = [];
 59.2254 +    };
 59.2255 +
 59.2256 +    /**
 59.2257 +     * Add delay action to the pending action queue queue.
 59.2258 +     *
 59.2259 +     * @method delay
 59.2260 +     *
 59.2261 +     * @param {number} duration delay time (ms)
 59.2262 +     * @param {function} callback Zero-argument function to call on observed
 59.2263 +     *    completion (t=1)
 59.2264 +     */
 59.2265 +    Transitionable.prototype.delay = function delay(duration, callback) {
 59.2266 +        this.set(this.get(), {duration: duration,
 59.2267 +            curve: function() {
 59.2268 +                return 0;
 59.2269 +            }},
 59.2270 +            callback
 59.2271 +        );
 59.2272 +    };
 59.2273 +
 59.2274 +    /**
 59.2275 +     * Get interpolated state of current action at provided time. If the last
 59.2276 +     *    action has completed, invoke its callback.
 59.2277 +     *
 59.2278 +     * @method get
 59.2279 +     *
 59.2280 +     * @param {number=} timestamp Evaluate the curve at a normalized version of this
 59.2281 +     *    time. If omitted, use current time. (Unix epoch time)
 59.2282 +     * @return {number|Object.<number|string, number>} beginning state
 59.2283 +     *    interpolated to this point in time.
 59.2284 +     */
 59.2285 +    Transitionable.prototype.get = function get(timestamp) {
 59.2286 +        if (this._engineInstance) {
 59.2287 +            if (this._engineInstance.getVelocity)
 59.2288 +                this.velocity = this._engineInstance.getVelocity();
 59.2289 +            this.state = this._engineInstance.get(timestamp);
 59.2290 +        }
 59.2291 +        return this.state;
 59.2292 +    };
 59.2293 +
 59.2294 +    /**
 59.2295 +     * Is there at least one action pending completion?
 59.2296 +     *
 59.2297 +     * @method isActive
 59.2298 +     *
 59.2299 +     * @return {boolean}
 59.2300 +     */
 59.2301 +    Transitionable.prototype.isActive = function isActive() {
 59.2302 +        return !!this.currentAction;
 59.2303 +    };
 59.2304 +
 59.2305 +    /**
 59.2306 +     * Halt transition at current state and erase all pending actions.
 59.2307 +     *
 59.2308 +     * @method halt
 59.2309 +     */
 59.2310 +    Transitionable.prototype.halt = function halt() {
 59.2311 +        this.set(this.get());
 59.2312 +    };
 59.2313 +
 59.2314 +    module.exports = Transitionable;
 59.2315 +});
 59.2316 +
 59.2317 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.2318 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.2319 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.2320 + *
 59.2321 + * Owner: mark@famo.us
 59.2322 + * @license MPL 2.0
 59.2323 + * @copyright Famous Industries, Inc. 2014
 59.2324 + */
 59.2325 +
 59.2326 +define('famous/core/Context',['require','exports','module','./RenderNode','./EventHandler','./ElementAllocator','./Transform','famous/transitions/Transitionable'],function(require, exports, module) {
 59.2327 +    var RenderNode = require('./RenderNode');
 59.2328 +    var EventHandler = require('./EventHandler');
 59.2329 +    var ElementAllocator = require('./ElementAllocator');
 59.2330 +    var Transform = require('./Transform');
 59.2331 +    var Transitionable = require('famous/transitions/Transitionable');
 59.2332 +
 59.2333 +    var _originZeroZero = [0, 0];
 59.2334 +
 59.2335 +    function _getElementSize(element) {
 59.2336 +        return [element.clientWidth, element.clientHeight];
 59.2337 +    }
 59.2338 +
 59.2339 +    /**
 59.2340 +     * The top-level container for a Famous-renderable piece of the document.
 59.2341 +     *   It is directly updated by the process-wide Engine object, and manages one
 59.2342 +     *   render tree root, which can contain other renderables.
 59.2343 +     *
 59.2344 +     * @class Context
 59.2345 +     * @constructor
 59.2346 +     * @private
 59.2347 +     * @param {Node} container Element in which content will be inserted
 59.2348 +     */
 59.2349 +    function Context(container) {
 59.2350 +        this.container = container;
 59.2351 +        this._allocator = new ElementAllocator(container);
 59.2352 +
 59.2353 +        this._node = new RenderNode();
 59.2354 +        this._eventOutput = new EventHandler();
 59.2355 +        this._size = _getElementSize(this.container);
 59.2356 +
 59.2357 +        this._perspectiveState = new Transitionable(0);
 59.2358 +        this._perspective = undefined;
 59.2359 +
 59.2360 +        this._nodeContext = {
 59.2361 +            allocator: this._allocator,
 59.2362 +            transform: Transform.identity,
 59.2363 +            opacity: 1,
 59.2364 +            origin: _originZeroZero,
 59.2365 +            align: null,
 59.2366 +            size: this._size
 59.2367 +        };
 59.2368 +
 59.2369 +        this._eventOutput.on('resize', function() {
 59.2370 +            this.setSize(_getElementSize(this.container));
 59.2371 +        }.bind(this));
 59.2372 +
 59.2373 +    }
 59.2374 +
 59.2375 +    // Note: Unused
 59.2376 +    Context.prototype.getAllocator = function getAllocator() {
 59.2377 +        return this._allocator;
 59.2378 +    };
 59.2379 +
 59.2380 +    /**
 59.2381 +     * Add renderables to this Context's render tree.
 59.2382 +     *
 59.2383 +     * @method add
 59.2384 +     *
 59.2385 +     * @param {Object} obj renderable object
 59.2386 +     * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode
 59.2387 +     */
 59.2388 +    Context.prototype.add = function add(obj) {
 59.2389 +        return this._node.add(obj);
 59.2390 +    };
 59.2391 +
 59.2392 +    /**
 59.2393 +     * Move this Context to another containing document element.
 59.2394 +     *
 59.2395 +     * @method migrate
 59.2396 +     *
 59.2397 +     * @param {Node} container Element to which content will be migrated
 59.2398 +     */
 59.2399 +    Context.prototype.migrate = function migrate(container) {
 59.2400 +        if (container === this.container) return;
 59.2401 +        this.container = container;
 59.2402 +        this._allocator.migrate(container);
 59.2403 +    };
 59.2404 +
 59.2405 +    /**
 59.2406 +     * Gets viewport size for Context.
 59.2407 +     *
 59.2408 +     * @method getSize
 59.2409 +     *
 59.2410 +     * @return {Array.Number} viewport size as [width, height]
 59.2411 +     */
 59.2412 +    Context.prototype.getSize = function getSize() {
 59.2413 +        return this._size;
 59.2414 +    };
 59.2415 +
 59.2416 +    /**
 59.2417 +     * Sets viewport size for Context.
 59.2418 +     *
 59.2419 +     * @method setSize
 59.2420 +     *
 59.2421 +     * @param {Array.Number} size [width, height].  If unspecified, use size of root document element.
 59.2422 +     */
 59.2423 +    Context.prototype.setSize = function setSize(size) {
 59.2424 +        if (!size) size = _getElementSize(this.container);
 59.2425 +        this._size[0] = size[0];
 59.2426 +        this._size[1] = size[1];
 59.2427 +    };
 59.2428 +
 59.2429 +    /**
 59.2430 +     * Commit this Context's content changes to the document.
 59.2431 +     *
 59.2432 +     * @private
 59.2433 +     * @method update
 59.2434 +     * @param {Object} contextParameters engine commit specification
 59.2435 +     */
 59.2436 +    Context.prototype.update = function update(contextParameters) {
 59.2437 +        if (contextParameters) {
 59.2438 +            if (contextParameters.transform) this._nodeContext.transform = contextParameters.transform;
 59.2439 +            if (contextParameters.opacity) this._nodeContext.opacity = contextParameters.opacity;
 59.2440 +            if (contextParameters.origin) this._nodeContext.origin = contextParameters.origin;
 59.2441 +            if (contextParameters.align) this._nodeContext.align = contextParameters.align;
 59.2442 +            if (contextParameters.size) this._nodeContext.size = contextParameters.size;
 59.2443 +        }
 59.2444 +        var perspective = this._perspectiveState.get();
 59.2445 +        if (perspective !== this._perspective) {
 59.2446 +            this.container.style.perspective = perspective ? perspective.toFixed() + 'px' : '';
 59.2447 +            this.container.style.webkitPerspective = perspective ? perspective.toFixed() : '';
 59.2448 +            this._perspective = perspective;
 59.2449 +        }
 59.2450 +
 59.2451 +        this._node.commit(this._nodeContext);
 59.2452 +    };
 59.2453 +
 59.2454 +    /**
 59.2455 +     * Get current perspective of this context in pixels.
 59.2456 +     *
 59.2457 +     * @method getPerspective
 59.2458 +     * @return {Number} depth perspective in pixels
 59.2459 +     */
 59.2460 +    Context.prototype.getPerspective = function getPerspective() {
 59.2461 +        return this._perspectiveState.get();
 59.2462 +    };
 59.2463 +
 59.2464 +    /**
 59.2465 +     * Set current perspective of this context in pixels.
 59.2466 +     *
 59.2467 +     * @method setPerspective
 59.2468 +     * @param {Number} perspective in pixels
 59.2469 +     * @param {Object} [transition] Transitionable object for applying the change
 59.2470 +     * @param {function(Object)} callback function called on completion of transition
 59.2471 +     */
 59.2472 +    Context.prototype.setPerspective = function setPerspective(perspective, transition, callback) {
 59.2473 +        return this._perspectiveState.set(perspective, transition, callback);
 59.2474 +    };
 59.2475 +
 59.2476 +    /**
 59.2477 +     * Trigger an event, sending to all downstream handlers
 59.2478 +     *   listening for provided 'type' key.
 59.2479 +     *
 59.2480 +     * @method emit
 59.2481 +     *
 59.2482 +     * @param {string} type event type key (for example, 'click')
 59.2483 +     * @param {Object} event event data
 59.2484 +     * @return {EventHandler} this
 59.2485 +     */
 59.2486 +    Context.prototype.emit = function emit(type, event) {
 59.2487 +        return this._eventOutput.emit(type, event);
 59.2488 +    };
 59.2489 +
 59.2490 +    /**
 59.2491 +     * Bind a callback function to an event type handled by this object.
 59.2492 +     *
 59.2493 +     * @method "on"
 59.2494 +     *
 59.2495 +     * @param {string} type event type key (for example, 'click')
 59.2496 +     * @param {function(string, Object)} handler callback
 59.2497 +     * @return {EventHandler} this
 59.2498 +     */
 59.2499 +    Context.prototype.on = function on(type, handler) {
 59.2500 +        return this._eventOutput.on(type, handler);
 59.2501 +    };
 59.2502 +
 59.2503 +    /**
 59.2504 +     * Unbind an event by type and handler.
 59.2505 +     *   This undoes the work of "on".
 59.2506 +     *
 59.2507 +     * @method removeListener
 59.2508 +     *
 59.2509 +     * @param {string} type event type key (for example, 'click')
 59.2510 +     * @param {function} handler function object to remove
 59.2511 +     * @return {EventHandler} internal event handler object (for chaining)
 59.2512 +     */
 59.2513 +    Context.prototype.removeListener = function removeListener(type, handler) {
 59.2514 +        return this._eventOutput.removeListener(type, handler);
 59.2515 +    };
 59.2516 +
 59.2517 +    /**
 59.2518 +     * Add event handler object to set of downstream handlers.
 59.2519 +     *
 59.2520 +     * @method pipe
 59.2521 +     *
 59.2522 +     * @param {EventHandler} target event handler target object
 59.2523 +     * @return {EventHandler} passed event handler
 59.2524 +     */
 59.2525 +    Context.prototype.pipe = function pipe(target) {
 59.2526 +        return this._eventOutput.pipe(target);
 59.2527 +    };
 59.2528 +
 59.2529 +    /**
 59.2530 +     * Remove handler object from set of downstream handlers.
 59.2531 +     *   Undoes work of "pipe".
 59.2532 +     *
 59.2533 +     * @method unpipe
 59.2534 +     *
 59.2535 +     * @param {EventHandler} target target handler object
 59.2536 +     * @return {EventHandler} provided target
 59.2537 +     */
 59.2538 +    Context.prototype.unpipe = function unpipe(target) {
 59.2539 +        return this._eventOutput.unpipe(target);
 59.2540 +    };
 59.2541 +
 59.2542 +    module.exports = Context;
 59.2543 +});
 59.2544 +
 59.2545 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.2546 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.2547 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.2548 + *
 59.2549 + * Owner: mark@famo.us
 59.2550 + * @license MPL 2.0
 59.2551 + * @copyright Famous Industries, Inc. 2014
 59.2552 + */
 59.2553 +
 59.2554 +define('famous/core/OptionsManager',['require','exports','module','./EventHandler'],function(require, exports, module) {
 59.2555 +    var EventHandler = require('./EventHandler');
 59.2556 +
 59.2557 +    /**
 59.2558 +     *  A collection of methods for setting options which can be extended
 59.2559 +     *  onto other classes.
 59.2560 +     *
 59.2561 +     *
 59.2562 +     *  **** WARNING ****
 59.2563 +     *  You can only pass through objects that will compile into valid JSON.
 59.2564 +     *
 59.2565 +     *  Valid options:
 59.2566 +     *      Strings,
 59.2567 +     *      Arrays,
 59.2568 +     *      Objects,
 59.2569 +     *      Numbers,
 59.2570 +     *      Nested Objects,
 59.2571 +     *      Nested Arrays.
 59.2572 +     *
 59.2573 +     *    This excludes:
 59.2574 +     *        Document Fragments,
 59.2575 +     *        Functions
 59.2576 +     * @class OptionsManager
 59.2577 +     * @constructor
 59.2578 +     * @param {Object} value options dictionary
 59.2579 +     */
 59.2580 +    function OptionsManager(value) {
 59.2581 +        this._value = value;
 59.2582 +        this.eventOutput = null;
 59.2583 +    }
 59.2584 +
 59.2585 +    /**
 59.2586 +     * Create options manager from source dictionary with arguments overriden by patch dictionary.
 59.2587 +     *
 59.2588 +     * @static
 59.2589 +     * @method OptionsManager.patch
 59.2590 +     *
 59.2591 +     * @param {Object} source source arguments
 59.2592 +     * @param {...Object} data argument additions and overwrites
 59.2593 +     * @return {Object} source object
 59.2594 +     */
 59.2595 +    OptionsManager.patch = function patchObject(source, data) {
 59.2596 +        var manager = new OptionsManager(source);
 59.2597 +        for (var i = 1; i < arguments.length; i++) manager.patch(arguments[i]);
 59.2598 +        return source;
 59.2599 +    };
 59.2600 +
 59.2601 +    function _createEventOutput() {
 59.2602 +        this.eventOutput = new EventHandler();
 59.2603 +        this.eventOutput.bindThis(this);
 59.2604 +        EventHandler.setOutputHandler(this, this.eventOutput);
 59.2605 +    }
 59.2606 +
 59.2607 +    /**
 59.2608 +     * Create OptionsManager from source with arguments overriden by patches.
 59.2609 +     *   Triggers 'change' event on this object's event handler if the state of
 59.2610 +     *   the OptionsManager changes as a result.
 59.2611 +     *
 59.2612 +     * @method patch
 59.2613 +     *
 59.2614 +     * @param {...Object} arguments list of patch objects
 59.2615 +     * @return {OptionsManager} this
 59.2616 +     */
 59.2617 +    OptionsManager.prototype.patch = function patch() {
 59.2618 +        var myState = this._value;
 59.2619 +        for (var i = 0; i < arguments.length; i++) {
 59.2620 +            var data = arguments[i];
 59.2621 +            for (var k in data) {
 59.2622 +                if ((k in myState) && (data[k] && data[k].constructor === Object) && (myState[k] && myState[k].constructor === Object)) {
 59.2623 +                    if (!myState.hasOwnProperty(k)) myState[k] = Object.create(myState[k]);
 59.2624 +                    this.key(k).patch(data[k]);
 59.2625 +                    if (this.eventOutput) this.eventOutput.emit('change', {id: k, value: this.key(k).value()});
 59.2626 +                }
 59.2627 +                else this.set(k, data[k]);
 59.2628 +            }
 59.2629 +        }
 59.2630 +        return this;
 59.2631 +    };
 59.2632 +
 59.2633 +    /**
 59.2634 +     * Alias for patch
 59.2635 +     *
 59.2636 +     * @method setOptions
 59.2637 +     *
 59.2638 +     */
 59.2639 +    OptionsManager.prototype.setOptions = OptionsManager.prototype.patch;
 59.2640 +
 59.2641 +    /**
 59.2642 +     * Return OptionsManager based on sub-object retrieved by key
 59.2643 +     *
 59.2644 +     * @method key
 59.2645 +     *
 59.2646 +     * @param {string} identifier key
 59.2647 +     * @return {OptionsManager} new options manager with the value
 59.2648 +     */
 59.2649 +    OptionsManager.prototype.key = function key(identifier) {
 59.2650 +        var result = new OptionsManager(this._value[identifier]);
 59.2651 +        if (!(result._value instanceof Object) || result._value instanceof Array) result._value = {};
 59.2652 +        return result;
 59.2653 +    };
 59.2654 +
 59.2655 +    /**
 59.2656 +     * Look up value by key
 59.2657 +     * @method get
 59.2658 +     *
 59.2659 +     * @param {string} key key
 59.2660 +     * @return {Object} associated object
 59.2661 +     */
 59.2662 +    OptionsManager.prototype.get = function get(key) {
 59.2663 +        return this._value[key];
 59.2664 +    };
 59.2665 +
 59.2666 +    /**
 59.2667 +     * Alias for get
 59.2668 +     * @method getOptions
 59.2669 +     */
 59.2670 +    OptionsManager.prototype.getOptions = OptionsManager.prototype.get;
 59.2671 +
 59.2672 +    /**
 59.2673 +     * Set key to value.  Outputs 'change' event if a value is overwritten.
 59.2674 +     *
 59.2675 +     * @method set
 59.2676 +     *
 59.2677 +     * @param {string} key key string
 59.2678 +     * @param {Object} value value object
 59.2679 +     * @return {OptionsManager} new options manager based on the value object
 59.2680 +     */
 59.2681 +    OptionsManager.prototype.set = function set(key, value) {
 59.2682 +        var originalValue = this.get(key);
 59.2683 +        this._value[key] = value;
 59.2684 +        if (this.eventOutput && value !== originalValue) this.eventOutput.emit('change', {id: key, value: value});
 59.2685 +        return this;
 59.2686 +    };
 59.2687 +
 59.2688 +    /**
 59.2689 +     * Return entire object contents of this OptionsManager.
 59.2690 +     *
 59.2691 +     * @method value
 59.2692 +     *
 59.2693 +     * @return {Object} current state of options
 59.2694 +     */
 59.2695 +    OptionsManager.prototype.value = function value() {
 59.2696 +        return this._value;
 59.2697 +    };
 59.2698 +
 59.2699 +    /**
 59.2700 +     * Bind a callback function to an event type handled by this object.
 59.2701 +     *
 59.2702 +     * @method "on"
 59.2703 +     *
 59.2704 +     * @param {string} type event type key (for example, 'change')
 59.2705 +     * @param {function(string, Object)} handler callback
 59.2706 +     * @return {EventHandler} this
 59.2707 +     */
 59.2708 +    OptionsManager.prototype.on = function on() {
 59.2709 +        _createEventOutput.call(this);
 59.2710 +        return this.on.apply(this, arguments);
 59.2711 +    };
 59.2712 +
 59.2713 +    /**
 59.2714 +     * Unbind an event by type and handler.
 59.2715 +     *   This undoes the work of "on".
 59.2716 +     *
 59.2717 +     * @method removeListener
 59.2718 +     *
 59.2719 +     * @param {string} type event type key (for example, 'change')
 59.2720 +     * @param {function} handler function object to remove
 59.2721 +     * @return {EventHandler} internal event handler object (for chaining)
 59.2722 +     */
 59.2723 +    OptionsManager.prototype.removeListener = function removeListener() {
 59.2724 +        _createEventOutput.call(this);
 59.2725 +        return this.removeListener.apply(this, arguments);
 59.2726 +    };
 59.2727 +
 59.2728 +    /**
 59.2729 +     * Add event handler object to set of downstream handlers.
 59.2730 +     *
 59.2731 +     * @method pipe
 59.2732 +     *
 59.2733 +     * @param {EventHandler} target event handler target object
 59.2734 +     * @return {EventHandler} passed event handler
 59.2735 +     */
 59.2736 +    OptionsManager.prototype.pipe = function pipe() {
 59.2737 +        _createEventOutput.call(this);
 59.2738 +        return this.pipe.apply(this, arguments);
 59.2739 +    };
 59.2740 +
 59.2741 +    /**
 59.2742 +     * Remove handler object from set of downstream handlers.
 59.2743 +     * Undoes work of "pipe"
 59.2744 +     *
 59.2745 +     * @method unpipe
 59.2746 +     *
 59.2747 +     * @param {EventHandler} target target handler object
 59.2748 +     * @return {EventHandler} provided target
 59.2749 +     */
 59.2750 +    OptionsManager.prototype.unpipe = function unpipe() {
 59.2751 +        _createEventOutput.call(this);
 59.2752 +        return this.unpipe.apply(this, arguments);
 59.2753 +    };
 59.2754 +
 59.2755 +    module.exports = OptionsManager;
 59.2756 +});
 59.2757 +
 59.2758 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.2759 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.2760 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.2761 + *
 59.2762 + * Owner: mark@famo.us
 59.2763 + * @license MPL 2.0
 59.2764 + * @copyright Famous Industries, Inc. 2014
 59.2765 + */
 59.2766 +
 59.2767 +define('famous/core/Engine',['require','exports','module','./Context','./EventHandler','./OptionsManager'],function(require, exports, module) {
 59.2768 +
 59.2769 +    /**
 59.2770 +     * The singleton object initiated upon process
 59.2771 +     *   startup which manages all active Context instances, runs
 59.2772 +     *   the render dispatch loop, and acts as a listener and dispatcher
 59.2773 +     *   for events.  All methods are therefore static.
 59.2774 +     *
 59.2775 +     *   On static initialization, window.requestAnimationFrame is called with
 59.2776 +     *     the event loop function.
 59.2777 +     *
 59.2778 +     *   Note: Any window in which Engine runs will prevent default
 59.2779 +     *     scrolling behavior on the 'touchmove' event.
 59.2780 +     *
 59.2781 +     * @static
 59.2782 +     * @class Engine
 59.2783 +     */
 59.2784 +    var Context = require('./Context');
 59.2785 +    var EventHandler = require('./EventHandler');
 59.2786 +    var OptionsManager = require('./OptionsManager');
 59.2787 +
 59.2788 +    var Engine = {};
 59.2789 +
 59.2790 +    var contexts = [];
 59.2791 +    var nextTickQueue = [];
 59.2792 +    var deferQueue = [];
 59.2793 +
 59.2794 +    var lastTime = Date.now();
 59.2795 +    var frameTime;
 59.2796 +    var frameTimeLimit;
 59.2797 +    var loopEnabled = true;
 59.2798 +    var eventForwarders = {};
 59.2799 +    var eventHandler = new EventHandler();
 59.2800 +
 59.2801 +    var options = {
 59.2802 +        containerType: 'div',
 59.2803 +        containerClass: 'famous-container',
 59.2804 +        fpsCap: undefined,
 59.2805 +        runLoop: true
 59.2806 +    };
 59.2807 +    var optionsManager = new OptionsManager(options);
 59.2808 +
 59.2809 +    /** @const */
 59.2810 +    var MAX_DEFER_FRAME_TIME = 10;
 59.2811 +
 59.2812 +    /**
 59.2813 +     * Inside requestAnimationFrame loop, step() is called, which:
 59.2814 +     *   calculates current FPS (throttling loop if it is over limit set in setFPSCap),
 59.2815 +     *   emits dataless 'prerender' event on start of loop,
 59.2816 +     *   calls in order any one-shot functions registered by nextTick on last loop,
 59.2817 +     *   calls Context.update on all Context objects registered,
 59.2818 +     *   and emits dataless 'postrender' event on end of loop.
 59.2819 +     *
 59.2820 +     * @static
 59.2821 +     * @private
 59.2822 +     * @method step
 59.2823 +     */
 59.2824 +    Engine.step = function step() {
 59.2825 +        var currentTime = Date.now();
 59.2826 +
 59.2827 +        // skip frame if we're over our framerate cap
 59.2828 +        if (frameTimeLimit && currentTime - lastTime < frameTimeLimit) return;
 59.2829 +
 59.2830 +        var i = 0;
 59.2831 +
 59.2832 +        frameTime = currentTime - lastTime;
 59.2833 +        lastTime = currentTime;
 59.2834 +
 59.2835 +        eventHandler.emit('prerender');
 59.2836 +
 59.2837 +        // empty the queue
 59.2838 +        for (i = 0; i < nextTickQueue.length; i++) nextTickQueue[i].call(this);
 59.2839 +        nextTickQueue.splice(0);
 59.2840 +
 59.2841 +        // limit total execution time for deferrable functions
 59.2842 +        while (deferQueue.length && (Date.now() - currentTime) < MAX_DEFER_FRAME_TIME) {
 59.2843 +            deferQueue.shift().call(this);
 59.2844 +        }
 59.2845 +
 59.2846 +        for (i = 0; i < contexts.length; i++) contexts[i].update();
 59.2847 +
 59.2848 +        eventHandler.emit('postrender');
 59.2849 +    };
 59.2850 +
 59.2851 +    // engage requestAnimationFrame
 59.2852 +    function loop() {
 59.2853 +        if (options.runLoop) {
 59.2854 +            Engine.step();
 59.2855 +            requestAnimationFrame(loop);
 59.2856 +        }
 59.2857 +        else loopEnabled = false;
 59.2858 +    }
 59.2859 +    requestAnimationFrame(loop);
 59.2860 +
 59.2861 +    //
 59.2862 +    // Upon main document window resize (unless on an "input" HTML element):
 59.2863 +    //   scroll to the top left corner of the window,
 59.2864 +    //   and for each managed Context: emit the 'resize' event and update its size.
 59.2865 +    // @param {Object=} event document event
 59.2866 +    //
 59.2867 +    function handleResize(event) {
 59.2868 +        for (var i = 0; i < contexts.length; i++) {
 59.2869 +            contexts[i].emit('resize');
 59.2870 +        }
 59.2871 +        eventHandler.emit('resize');
 59.2872 +    }
 59.2873 +    window.addEventListener('resize', handleResize, false);
 59.2874 +    handleResize();
 59.2875 +
 59.2876 +    // prevent scrolling via browser
 59.2877 +    window.addEventListener('touchmove', function(event) {
 59.2878 +        event.preventDefault();
 59.2879 +    }, true);
 59.2880 +
 59.2881 +    /**
 59.2882 +     * Add event handler object to set of downstream handlers.
 59.2883 +     *
 59.2884 +     * @method pipe
 59.2885 +     *
 59.2886 +     * @param {EventHandler} target event handler target object
 59.2887 +     * @return {EventHandler} passed event handler
 59.2888 +     */
 59.2889 +    Engine.pipe = function pipe(target) {
 59.2890 +        if (target.subscribe instanceof Function) return target.subscribe(Engine);
 59.2891 +        else return eventHandler.pipe(target);
 59.2892 +    };
 59.2893 +
 59.2894 +    /**
 59.2895 +     * Remove handler object from set of downstream handlers.
 59.2896 +     *   Undoes work of "pipe".
 59.2897 +     *
 59.2898 +     * @method unpipe
 59.2899 +     *
 59.2900 +     * @param {EventHandler} target target handler object
 59.2901 +     * @return {EventHandler} provided target
 59.2902 +     */
 59.2903 +    Engine.unpipe = function unpipe(target) {
 59.2904 +        if (target.unsubscribe instanceof Function) return target.unsubscribe(Engine);
 59.2905 +        else return eventHandler.unpipe(target);
 59.2906 +    };
 59.2907 +
 59.2908 +    /**
 59.2909 +     * Bind a callback function to an event type handled by this object.
 59.2910 +     *
 59.2911 +     * @static
 59.2912 +     * @method "on"
 59.2913 +     *
 59.2914 +     * @param {string} type event type key (for example, 'click')
 59.2915 +     * @param {function(string, Object)} handler callback
 59.2916 +     * @return {EventHandler} this
 59.2917 +     */
 59.2918 +    Engine.on = function on(type, handler) {
 59.2919 +        if (!(type in eventForwarders)) {
 59.2920 +            eventForwarders[type] = eventHandler.emit.bind(eventHandler, type);
 59.2921 +            if (document.body) {
 59.2922 +                document.body.addEventListener(type, eventForwarders[type]);
 59.2923 +            }
 59.2924 +            else {
 59.2925 +                Engine.nextTick(function(type, forwarder) {
 59.2926 +                    document.body.addEventListener(type, forwarder);
 59.2927 +                }.bind(this, type, eventForwarders[type]));
 59.2928 +            }
 59.2929 +        }
 59.2930 +        return eventHandler.on(type, handler);
 59.2931 +    };
 59.2932 +
 59.2933 +    /**
 59.2934 +     * Trigger an event, sending to all downstream handlers
 59.2935 +     *   listening for provided 'type' key.
 59.2936 +     *
 59.2937 +     * @method emit
 59.2938 +     *
 59.2939 +     * @param {string} type event type key (for example, 'click')
 59.2940 +     * @param {Object} event event data
 59.2941 +     * @return {EventHandler} this
 59.2942 +     */
 59.2943 +    Engine.emit = function emit(type, event) {
 59.2944 +        return eventHandler.emit(type, event);
 59.2945 +    };
 59.2946 +
 59.2947 +    /**
 59.2948 +     * Unbind an event by type and handler.
 59.2949 +     *   This undoes the work of "on".
 59.2950 +     *
 59.2951 +     * @static
 59.2952 +     * @method removeListener
 59.2953 +     *
 59.2954 +     * @param {string} type event type key (for example, 'click')
 59.2955 +     * @param {function} handler function object to remove
 59.2956 +     * @return {EventHandler} internal event handler object (for chaining)
 59.2957 +     */
 59.2958 +    Engine.removeListener = function removeListener(type, handler) {
 59.2959 +        return eventHandler.removeListener(type, handler);
 59.2960 +    };
 59.2961 +
 59.2962 +    /**
 59.2963 +     * Return the current calculated frames per second of the Engine.
 59.2964 +     *
 59.2965 +     * @static
 59.2966 +     * @method getFPS
 59.2967 +     *
 59.2968 +     * @return {Number} calculated fps
 59.2969 +     */
 59.2970 +    Engine.getFPS = function getFPS() {
 59.2971 +        return 1000 / frameTime;
 59.2972 +    };
 59.2973 +
 59.2974 +    /**
 59.2975 +     * Set the maximum fps at which the system should run. If internal render
 59.2976 +     *    loop is called at a greater frequency than this FPSCap, Engine will
 59.2977 +     *    throttle render and update until this rate is achieved.
 59.2978 +     *
 59.2979 +     * @static
 59.2980 +     * @method setFPSCap
 59.2981 +     *
 59.2982 +     * @param {Number} fps maximum frames per second
 59.2983 +     */
 59.2984 +    Engine.setFPSCap = function setFPSCap(fps) {
 59.2985 +        frameTimeLimit = Math.floor(1000 / fps);
 59.2986 +    };
 59.2987 +
 59.2988 +    /**
 59.2989 +     * Return engine options.
 59.2990 +     *
 59.2991 +     * @static
 59.2992 +     * @method getOptions
 59.2993 +     * @param {string} key
 59.2994 +     * @return {Object} engine options
 59.2995 +     */
 59.2996 +    Engine.getOptions = function getOptions() {
 59.2997 +        return optionsManager.getOptions.apply(optionsManager, arguments);
 59.2998 +    };
 59.2999 +
 59.3000 +    /**
 59.3001 +     * Set engine options
 59.3002 +     *
 59.3003 +     * @static
 59.3004 +     * @method setOptions
 59.3005 +     *
 59.3006 +     * @param {Object} [options] overrides of default options
 59.3007 +     * @param {Number} [options.fpsCap]  maximum fps at which the system should run
 59.3008 +     * @param {boolean} [options.runLoop=true] whether the run loop should continue
 59.3009 +     * @param {string} [options.containerType="div"] type of container element.  Defaults to 'div'.
 59.3010 +     * @param {string} [options.containerClass="famous-container"] type of container element.  Defaults to 'famous-container'.
 59.3011 +     */
 59.3012 +    Engine.setOptions = function setOptions(options) {
 59.3013 +        return optionsManager.setOptions.apply(optionsManager, arguments);
 59.3014 +    };
 59.3015 +
 59.3016 +    /**
 59.3017 +     * Creates a new Context for rendering and event handling with
 59.3018 +     *    provided document element as top of each tree. This will be tracked by the
 59.3019 +     *    process-wide Engine.
 59.3020 +     *
 59.3021 +     * @static
 59.3022 +     * @method createContext
 59.3023 +     *
 59.3024 +     * @param {Node} el will be top of Famo.us document element tree
 59.3025 +     * @return {Context} new Context within el
 59.3026 +     */
 59.3027 +    Engine.createContext = function createContext(el) {
 59.3028 +        var needMountContainer = false;
 59.3029 +        if (!el) {
 59.3030 +            el = document.createElement(options.containerType);
 59.3031 +            el.classList.add(options.containerClass);
 59.3032 +            needMountContainer = true;
 59.3033 +        }
 59.3034 +        var context = new Context(el);
 59.3035 +        Engine.registerContext(context);
 59.3036 +        if (needMountContainer) {
 59.3037 +            Engine.nextTick(function(context, el) {
 59.3038 +                document.body.appendChild(el);
 59.3039 +                context.emit('resize');
 59.3040 +            }.bind(this, context, el));
 59.3041 +        }
 59.3042 +        return context;
 59.3043 +    };
 59.3044 +
 59.3045 +    /**
 59.3046 +     * Registers an existing context to be updated within the run loop.
 59.3047 +     *
 59.3048 +     * @static
 59.3049 +     * @method registerContext
 59.3050 +     *
 59.3051 +     * @param {Context} context Context to register
 59.3052 +     * @return {FamousContext} provided context
 59.3053 +     */
 59.3054 +    Engine.registerContext = function registerContext(context) {
 59.3055 +        contexts.push(context);
 59.3056 +        return context;
 59.3057 +    };
 59.3058 +
 59.3059 +    /**
 59.3060 +     * Queue a function to be executed on the next tick of the
 59.3061 +     *    Engine.
 59.3062 +     *
 59.3063 +     * @static
 59.3064 +     * @method nextTick
 59.3065 +     *
 59.3066 +     * @param {function(Object)} fn function accepting window object
 59.3067 +     */
 59.3068 +    Engine.nextTick = function nextTick(fn) {
 59.3069 +        nextTickQueue.push(fn);
 59.3070 +    };
 59.3071 +
 59.3072 +    /**
 59.3073 +     * Queue a function to be executed sometime soon, at a time that is
 59.3074 +     *    unlikely to affect frame rate.
 59.3075 +     *
 59.3076 +     * @static
 59.3077 +     * @method defer
 59.3078 +     *
 59.3079 +     * @param {Function} fn
 59.3080 +     */
 59.3081 +    Engine.defer = function defer(fn) {
 59.3082 +        deferQueue.push(fn);
 59.3083 +    };
 59.3084 +
 59.3085 +    optionsManager.on('change', function(data) {
 59.3086 +        if (data.id === 'fpsCap') Engine.setFPSCap(data.value);
 59.3087 +        else if (data.id === 'runLoop') {
 59.3088 +            // kick off the loop only if it was stopped
 59.3089 +            if (!loopEnabled && data.value) {
 59.3090 +                loopEnabled = true;
 59.3091 +                requestAnimationFrame(loop);
 59.3092 +            }
 59.3093 +        }
 59.3094 +    });
 59.3095 +
 59.3096 +    module.exports = Engine;
 59.3097 +});
 59.3098 +
 59.3099 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.3100 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.3101 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.3102 + *
 59.3103 + * Owner: mark@famo.us
 59.3104 + * @license MPL 2.0
 59.3105 + * @copyright Famous Industries, Inc. 2014
 59.3106 + */
 59.3107 +
 59.3108 +define('famous/core/Surface',['require','exports','module','./Entity','./EventHandler','./Transform'],function(require, exports, module) {
 59.3109 +    var Entity = require('./Entity');
 59.3110 +    var EventHandler = require('./EventHandler');
 59.3111 +    var Transform = require('./Transform');
 59.3112 +
 59.3113 +    var devicePixelRatio = window.devicePixelRatio || 1;
 59.3114 +    var usePrefix = document.createElement('div').style.webkitTransform !== undefined;
 59.3115 +
 59.3116 +    /**
 59.3117 +     * A base class for viewable content and event
 59.3118 +     *   targets inside a Famo.us application, containing a renderable document
 59.3119 +     *   fragment. Like an HTML div, it can accept internal markup,
 59.3120 +     *   properties, classes, and handle events.
 59.3121 +     *
 59.3122 +     * @class Surface
 59.3123 +     * @constructor
 59.3124 +     *
 59.3125 +     * @param {Object} [options] default option overrides
 59.3126 +     * @param {Array.Number} [options.size] [width, height] in pixels
 59.3127 +     * @param {Array.string} [options.classes] CSS classes to set on inner content
 59.3128 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
 59.3129 +     * @param {string} [options.content] inner (HTML) content of surface
 59.3130 +     */
 59.3131 +    function Surface(options) {
 59.3132 +        this.options = {};
 59.3133 +
 59.3134 +        this.properties = {};
 59.3135 +        this.content = '';
 59.3136 +        this.classList = [];
 59.3137 +        this.size = null;
 59.3138 +
 59.3139 +        this._classesDirty = true;
 59.3140 +        this._stylesDirty = true;
 59.3141 +        this._sizeDirty = true;
 59.3142 +        this._contentDirty = true;
 59.3143 +
 59.3144 +        this._dirtyClasses = [];
 59.3145 +
 59.3146 +        this._matrix = null;
 59.3147 +        this._opacity = 1;
 59.3148 +        this._origin = null;
 59.3149 +        this._size = null;
 59.3150 +
 59.3151 +        /** @ignore */
 59.3152 +        this.eventForwarder = function eventForwarder(event) {
 59.3153 +            this.emit(event.type, event);
 59.3154 +        }.bind(this);
 59.3155 +        this.eventHandler = new EventHandler();
 59.3156 +        this.eventHandler.bindThis(this);
 59.3157 +
 59.3158 +        this.id = Entity.register(this);
 59.3159 +
 59.3160 +        if (options) this.setOptions(options);
 59.3161 +
 59.3162 +        this._currTarget = null;
 59.3163 +    }
 59.3164 +    Surface.prototype.elementType = 'div';
 59.3165 +    Surface.prototype.elementClass = 'famous-surface';
 59.3166 +
 59.3167 +    /**
 59.3168 +     * Bind a callback function to an event type handled by this object.
 59.3169 +     *
 59.3170 +     * @method "on"
 59.3171 +     *
 59.3172 +     * @param {string} type event type key (for example, 'click')
 59.3173 +     * @param {function(string, Object)} fn handler callback
 59.3174 +     * @return {EventHandler} this
 59.3175 +     */
 59.3176 +    Surface.prototype.on = function on(type, fn) {
 59.3177 +        if (this._currTarget) this._currTarget.addEventListener(type, this.eventForwarder);
 59.3178 +        this.eventHandler.on(type, fn);
 59.3179 +    };
 59.3180 +
 59.3181 +    /**
 59.3182 +     * Unbind an event by type and handler.
 59.3183 +     *   This undoes the work of "on"
 59.3184 +     *
 59.3185 +     * @method removeListener
 59.3186 +     * @param {string} type event type key (for example, 'click')
 59.3187 +     * @param {function(string, Object)} fn handler
 59.3188 +     */
 59.3189 +    Surface.prototype.removeListener = function removeListener(type, fn) {
 59.3190 +        this.eventHandler.removeListener(type, fn);
 59.3191 +    };
 59.3192 +
 59.3193 +    /**
 59.3194 +     * Trigger an event, sending to all downstream handlers
 59.3195 +     *   listening for provided 'type' key.
 59.3196 +     *
 59.3197 +     * @method emit
 59.3198 +     *
 59.3199 +     * @param {string} type event type key (for example, 'click')
 59.3200 +     * @param {Object} [event] event data
 59.3201 +     * @return {EventHandler} this
 59.3202 +     */
 59.3203 +    Surface.prototype.emit = function emit(type, event) {
 59.3204 +        if (event && !event.origin) event.origin = this;
 59.3205 +        var handled = this.eventHandler.emit(type, event);
 59.3206 +        if (handled && event && event.stopPropagation) event.stopPropagation();
 59.3207 +        return handled;
 59.3208 +    };
 59.3209 +
 59.3210 +    /**
 59.3211 +     * Add event handler object to set of downstream handlers.
 59.3212 +     *
 59.3213 +     * @method pipe
 59.3214 +     *
 59.3215 +     * @param {EventHandler} target event handler target object
 59.3216 +     * @return {EventHandler} passed event handler
 59.3217 +     */
 59.3218 +    Surface.prototype.pipe = function pipe(target) {
 59.3219 +        return this.eventHandler.pipe(target);
 59.3220 +    };
 59.3221 +
 59.3222 +    /**
 59.3223 +     * Remove handler object from set of downstream handlers.
 59.3224 +     *   Undoes work of "pipe"
 59.3225 +     *
 59.3226 +     * @method unpipe
 59.3227 +     *
 59.3228 +     * @param {EventHandler} target target handler object
 59.3229 +     * @return {EventHandler} provided target
 59.3230 +     */
 59.3231 +    Surface.prototype.unpipe = function unpipe(target) {
 59.3232 +        return this.eventHandler.unpipe(target);
 59.3233 +    };
 59.3234 +
 59.3235 +    /**
 59.3236 +     * Return spec for this surface. Note that for a base surface, this is
 59.3237 +     *    simply an id.
 59.3238 +     *
 59.3239 +     * @method render
 59.3240 +     * @private
 59.3241 +     * @return {Object} render spec for this surface (spec id)
 59.3242 +     */
 59.3243 +    Surface.prototype.render = function render() {
 59.3244 +        return this.id;
 59.3245 +    };
 59.3246 +
 59.3247 +    /**
 59.3248 +     * Set CSS-style properties on this Surface. Note that this will cause
 59.3249 +     *    dirtying and thus re-rendering, even if values do not change.
 59.3250 +     *
 59.3251 +     * @method setProperties
 59.3252 +     * @param {Object} properties property dictionary of "key" => "value"
 59.3253 +     */
 59.3254 +    Surface.prototype.setProperties = function setProperties(properties) {
 59.3255 +        for (var n in properties) {
 59.3256 +            this.properties[n] = properties[n];
 59.3257 +        }
 59.3258 +        this._stylesDirty = true;
 59.3259 +    };
 59.3260 +
 59.3261 +    /**
 59.3262 +     * Get CSS-style properties on this Surface.
 59.3263 +     *
 59.3264 +     * @method getProperties
 59.3265 +     *
 59.3266 +     * @return {Object} Dictionary of this Surface's properties.
 59.3267 +     */
 59.3268 +    Surface.prototype.getProperties = function getProperties() {
 59.3269 +        return this.properties;
 59.3270 +    };
 59.3271 +
 59.3272 +    /**
 59.3273 +     * Add CSS-style class to the list of classes on this Surface. Note
 59.3274 +     *   this will map directly to the HTML property of the actual
 59.3275 +     *   corresponding rendered <div>.
 59.3276 +     *
 59.3277 +     * @method addClass
 59.3278 +     * @param {string} className name of class to add
 59.3279 +     */
 59.3280 +    Surface.prototype.addClass = function addClass(className) {
 59.3281 +        if (this.classList.indexOf(className) < 0) {
 59.3282 +            this.classList.push(className);
 59.3283 +            this._classesDirty = true;
 59.3284 +        }
 59.3285 +    };
 59.3286 +
 59.3287 +    /**
 59.3288 +     * Remove CSS-style class from the list of classes on this Surface.
 59.3289 +     *   Note this will map directly to the HTML property of the actual
 59.3290 +     *   corresponding rendered <div>.
 59.3291 +     *
 59.3292 +     * @method removeClass
 59.3293 +     * @param {string} className name of class to remove
 59.3294 +     */
 59.3295 +    Surface.prototype.removeClass = function removeClass(className) {
 59.3296 +        var i = this.classList.indexOf(className);
 59.3297 +        if (i >= 0) {
 59.3298 +            this._dirtyClasses.push(this.classList.splice(i, 1)[0]);
 59.3299 +            this._classesDirty = true;
 59.3300 +        }
 59.3301 +    };
 59.3302 +
 59.3303 +    /**
 59.3304 +     * Reset class list to provided dictionary.
 59.3305 +     * @method setClasses
 59.3306 +     * @param {Array.string} classList
 59.3307 +     */
 59.3308 +    Surface.prototype.setClasses = function setClasses(classList) {
 59.3309 +        var i = 0;
 59.3310 +        var removal = [];
 59.3311 +        for (i = 0; i < this.classList.length; i++) {
 59.3312 +            if (classList.indexOf(this.classList[i]) < 0) removal.push(this.classList[i]);
 59.3313 +        }
 59.3314 +        for (i = 0; i < removal.length; i++) this.removeClass(removal[i]);
 59.3315 +        // duplicates are already checked by addClass()
 59.3316 +        for (i = 0; i < classList.length; i++) this.addClass(classList[i]);
 59.3317 +    };
 59.3318 +
 59.3319 +    /**
 59.3320 +     * Get array of CSS-style classes attached to this div.
 59.3321 +     *
 59.3322 +     * @method getClasslist
 59.3323 +     * @return {Array.string} array of class names
 59.3324 +     */
 59.3325 +    Surface.prototype.getClassList = function getClassList() {
 59.3326 +        return this.classList;
 59.3327 +    };
 59.3328 +
 59.3329 +    /**
 59.3330 +     * Set or overwrite inner (HTML) content of this surface. Note that this
 59.3331 +     *    causes a re-rendering if the content has changed.
 59.3332 +     *
 59.3333 +     * @method setContent
 59.3334 +     * @param {string|Document Fragment} content HTML content
 59.3335 +     */
 59.3336 +    Surface.prototype.setContent = function setContent(content) {
 59.3337 +        if (this.content !== content) {
 59.3338 +            this.content = content;
 59.3339 +            this._contentDirty = true;
 59.3340 +        }
 59.3341 +    };
 59.3342 +
 59.3343 +    /**
 59.3344 +     * Return inner (HTML) content of this surface.
 59.3345 +     *
 59.3346 +     * @method getContent
 59.3347 +     *
 59.3348 +     * @return {string} inner (HTML) content
 59.3349 +     */
 59.3350 +    Surface.prototype.getContent = function getContent() {
 59.3351 +        return this.content;
 59.3352 +    };
 59.3353 +
 59.3354 +    /**
 59.3355 +     * Set options for this surface
 59.3356 +     *
 59.3357 +     * @method setOptions
 59.3358 +     * @param {Object} [options] overrides for default options.  See constructor.
 59.3359 +     */
 59.3360 +    Surface.prototype.setOptions = function setOptions(options) {
 59.3361 +        if (options.size) this.setSize(options.size);
 59.3362 +        if (options.classes) this.setClasses(options.classes);
 59.3363 +        if (options.properties) this.setProperties(options.properties);
 59.3364 +        if (options.content) this.setContent(options.content);
 59.3365 +    };
 59.3366 +
 59.3367 +    //  Attach Famous event handling to document events emanating from target
 59.3368 +    //    document element.  This occurs just after deployment to the document.
 59.3369 +    //    Calling this enables methods like #on and #pipe.
 59.3370 +    function _addEventListeners(target) {
 59.3371 +        for (var i in this.eventHandler.listeners) {
 59.3372 +            target.addEventListener(i, this.eventForwarder);
 59.3373 +        }
 59.3374 +    }
 59.3375 +
 59.3376 +    //  Detach Famous event handling from document events emanating from target
 59.3377 +    //  document element.  This occurs just before recall from the document.
 59.3378 +    function _removeEventListeners(target) {
 59.3379 +        for (var i in this.eventHandler.listeners) {
 59.3380 +            target.removeEventListener(i, this.eventForwarder);
 59.3381 +        }
 59.3382 +    }
 59.3383 +
 59.3384 +     //  Apply to document all changes from removeClass() since last setup().
 59.3385 +    function _cleanupClasses(target) {
 59.3386 +        for (var i = 0; i < this._dirtyClasses.length; i++) target.classList.remove(this._dirtyClasses[i]);
 59.3387 +        this._dirtyClasses = [];
 59.3388 +    }
 59.3389 +
 59.3390 +    // Apply values of all Famous-managed styles to the document element.
 59.3391 +    //  These will be deployed to the document on call to #setup().
 59.3392 +    function _applyStyles(target) {
 59.3393 +        for (var n in this.properties) {
 59.3394 +            target.style[n] = this.properties[n];
 59.3395 +        }
 59.3396 +    }
 59.3397 +
 59.3398 +    // Clear all Famous-managed styles from the document element.
 59.3399 +    // These will be deployed to the document on call to #setup().
 59.3400 +    function _cleanupStyles(target) {
 59.3401 +        for (var n in this.properties) {
 59.3402 +            target.style[n] = '';
 59.3403 +        }
 59.3404 +    }
 59.3405 +
 59.3406 +    /**
 59.3407 +     * Return a Matrix's webkit css representation to be used with the
 59.3408 +     *    CSS3 -webkit-transform style.
 59.3409 +     *    Example: -webkit-transform: matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,716,243,0,1)
 59.3410 +     *
 59.3411 +     * @method _formatCSSTransform
 59.3412 +     * @private
 59.3413 +     * @param {FamousMatrix} m matrix
 59.3414 +     * @return {string} matrix3d CSS style representation of the transform
 59.3415 +     */
 59.3416 +    function _formatCSSTransform(m) {
 59.3417 +        m[12] = Math.round(m[12] * devicePixelRatio) / devicePixelRatio;
 59.3418 +        m[13] = Math.round(m[13] * devicePixelRatio) / devicePixelRatio;
 59.3419 +
 59.3420 +        var result = 'matrix3d(';
 59.3421 +        for (var i = 0; i < 15; i++) {
 59.3422 +            result += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ',';
 59.3423 +        }
 59.3424 +        result += m[15] + ')';
 59.3425 +        return result;
 59.3426 +    }
 59.3427 +
 59.3428 +    /**
 59.3429 +     * Directly apply given FamousMatrix to the document element as the
 59.3430 +     *   appropriate webkit CSS style.
 59.3431 +     *
 59.3432 +     * @method setMatrix
 59.3433 +     *
 59.3434 +     * @static
 59.3435 +     * @private
 59.3436 +     * @param {Element} element document element
 59.3437 +     * @param {FamousMatrix} matrix
 59.3438 +     */
 59.3439 +
 59.3440 +    var _setMatrix;
 59.3441 +    if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
 59.3442 +        _setMatrix = function(element, matrix) {
 59.3443 +            element.style.zIndex = (matrix[14] * 1000000) | 0;    // fix for Firefox z-buffer issues
 59.3444 +            element.style.transform = _formatCSSTransform(matrix);
 59.3445 +        };
 59.3446 +    }
 59.3447 +    else if (usePrefix) {
 59.3448 +        _setMatrix = function(element, matrix) {
 59.3449 +            element.style.webkitTransform = _formatCSSTransform(matrix);
 59.3450 +        };
 59.3451 +    }
 59.3452 +    else {
 59.3453 +        _setMatrix = function(element, matrix) {
 59.3454 +            element.style.transform = _formatCSSTransform(matrix);
 59.3455 +        };
 59.3456 +    }
 59.3457 +
 59.3458 +    // format origin as CSS percentage string
 59.3459 +    function _formatCSSOrigin(origin) {
 59.3460 +        return (100 * origin[0]) + '% ' + (100 * origin[1]) + '%';
 59.3461 +    }
 59.3462 +
 59.3463 +     // Directly apply given origin coordinates to the document element as the
 59.3464 +     // appropriate webkit CSS style.
 59.3465 +    var _setOrigin = usePrefix ? function(element, origin) {
 59.3466 +        element.style.webkitTransformOrigin = _formatCSSOrigin(origin);
 59.3467 +    } : function(element, origin) {
 59.3468 +        element.style.transformOrigin = _formatCSSOrigin(origin);
 59.3469 +    };
 59.3470 +
 59.3471 +     // Shrink given document element until it is effectively invisible.
 59.3472 +    var _setInvisible = usePrefix ? function(element) {
 59.3473 +        element.style.webkitTransform = 'scale3d(0.0001,0.0001,1)';
 59.3474 +        element.style.opacity = 0;
 59.3475 +    } : function(element) {
 59.3476 +        element.style.transform = 'scale3d(0.0001,0.0001,1)';
 59.3477 +        element.style.opacity = 0;
 59.3478 +    };
 59.3479 +
 59.3480 +    function _xyNotEquals(a, b) {
 59.3481 +        return (a && b) ? (a[0] !== b[0] || a[1] !== b[1]) : a !== b;
 59.3482 +    }
 59.3483 +
 59.3484 +    /**
 59.3485 +     * One-time setup for an element to be ready for commits to document.
 59.3486 +     *
 59.3487 +     * @private
 59.3488 +     * @method setup
 59.3489 +     *
 59.3490 +     * @param {ElementAllocator} allocator document element pool for this context
 59.3491 +     */
 59.3492 +    Surface.prototype.setup = function setup(allocator) {
 59.3493 +        var target = allocator.allocate(this.elementType);
 59.3494 +        if (this.elementClass) {
 59.3495 +            if (this.elementClass instanceof Array) {
 59.3496 +                for (var i = 0; i < this.elementClass.length; i++) {
 59.3497 +                    target.classList.add(this.elementClass[i]);
 59.3498 +                }
 59.3499 +            }
 59.3500 +            else {
 59.3501 +                target.classList.add(this.elementClass);
 59.3502 +            }
 59.3503 +        }
 59.3504 +        target.style.display = '';
 59.3505 +        _addEventListeners.call(this, target);
 59.3506 +        this._currTarget = target;
 59.3507 +        this._stylesDirty = true;
 59.3508 +        this._classesDirty = true;
 59.3509 +        this._sizeDirty = true;
 59.3510 +        this._contentDirty = true;
 59.3511 +        this._matrix = null;
 59.3512 +        this._opacity = undefined;
 59.3513 +        this._origin = null;
 59.3514 +        this._size = null;
 59.3515 +    };
 59.3516 +
 59.3517 +    /**
 59.3518 +     * Apply changes from this component to the corresponding document element.
 59.3519 +     * This includes changes to classes, styles, size, content, opacity, origin,
 59.3520 +     * and matrix transforms.
 59.3521 +     *
 59.3522 +     * @private
 59.3523 +     * @method commit
 59.3524 +     * @param {Context} context commit context
 59.3525 +     */
 59.3526 +    Surface.prototype.commit = function commit(context) {
 59.3527 +        if (!this._currTarget) this.setup(context.allocator);
 59.3528 +        var target = this._currTarget;
 59.3529 +
 59.3530 +        var matrix = context.transform;
 59.3531 +        var opacity = context.opacity;
 59.3532 +        var origin = context.origin;
 59.3533 +        var size = context.size;
 59.3534 +
 59.3535 +        if (this._classesDirty) {
 59.3536 +            _cleanupClasses.call(this, target);
 59.3537 +            var classList = this.getClassList();
 59.3538 +            for (var i = 0; i < classList.length; i++) target.classList.add(classList[i]);
 59.3539 +            this._classesDirty = false;
 59.3540 +        }
 59.3541 +
 59.3542 +        if (this._stylesDirty) {
 59.3543 +            _applyStyles.call(this, target);
 59.3544 +            this._stylesDirty = false;
 59.3545 +        }
 59.3546 +
 59.3547 +        if (this._contentDirty) {
 59.3548 +            this.deploy(target);
 59.3549 +            this.eventHandler.emit('deploy');
 59.3550 +            this._contentDirty = false;
 59.3551 +        }
 59.3552 +
 59.3553 +        if (this.size) {
 59.3554 +            var origSize = size;
 59.3555 +            size = [this.size[0], this.size[1]];
 59.3556 +            if (size[0] === undefined && origSize[0]) size[0] = origSize[0];
 59.3557 +            if (size[1] === undefined && origSize[1]) size[1] = origSize[1];
 59.3558 +        }
 59.3559 +
 59.3560 +        if (size[0] === true) size[0] = target.clientWidth;
 59.3561 +        if (size[1] === true) size[1] = target.clientHeight;
 59.3562 +
 59.3563 +        if (_xyNotEquals(this._size, size)) {
 59.3564 +            if (!this._size) this._size = [0, 0];
 59.3565 +            this._size[0] = size[0];
 59.3566 +            this._size[1] = size[1];
 59.3567 +            this._sizeDirty = true;
 59.3568 +        }
 59.3569 +
 59.3570 +        if (!matrix && this._matrix) {
 59.3571 +            this._matrix = null;
 59.3572 +            this._opacity = 0;
 59.3573 +            _setInvisible(target);
 59.3574 +            return;
 59.3575 +        }
 59.3576 +
 59.3577 +        if (this._opacity !== opacity) {
 59.3578 +            this._opacity = opacity;
 59.3579 +            target.style.opacity = (opacity >= 1) ? '0.999999' : opacity;
 59.3580 +        }
 59.3581 +
 59.3582 +        if (_xyNotEquals(this._origin, origin) || Transform.notEquals(this._matrix, matrix) || this._sizeDirty) {
 59.3583 +            if (!matrix) matrix = Transform.identity;
 59.3584 +            this._matrix = matrix;
 59.3585 +            var aaMatrix = matrix;
 59.3586 +            if (origin) {
 59.3587 +                if (!this._origin) this._origin = [0, 0];
 59.3588 +                this._origin[0] = origin[0];
 59.3589 +                this._origin[1] = origin[1];
 59.3590 +                aaMatrix = Transform.thenMove(matrix, [-this._size[0] * origin[0], -this._size[1] * origin[1], 0]);
 59.3591 +                _setOrigin(target, origin);
 59.3592 +            }
 59.3593 +            _setMatrix(target, aaMatrix);
 59.3594 +        }
 59.3595 +
 59.3596 +        if (this._sizeDirty) {
 59.3597 +            if (this._size) {
 59.3598 +                target.style.width = (this.size && this.size[0] === true) ? '' : this._size[0] + 'px';
 59.3599 +                target.style.height = (this.size && this.size[1] === true) ?  '' : this._size[1] + 'px';
 59.3600 +            }
 59.3601 +            this._sizeDirty = false;
 59.3602 +        }
 59.3603 +    };
 59.3604 +
 59.3605 +    /**
 59.3606 +     *  Remove all Famous-relevant attributes from a document element.
 59.3607 +     *    This is called by SurfaceManager's detach().
 59.3608 +     *    This is in some sense the reverse of .deploy().
 59.3609 +     *
 59.3610 +     * @private
 59.3611 +     * @method cleanup
 59.3612 +     * @param {ElementAllocator} allocator
 59.3613 +     */
 59.3614 +    Surface.prototype.cleanup = function cleanup(allocator) {
 59.3615 +        var i = 0;
 59.3616 +        var target = this._currTarget;
 59.3617 +        this.eventHandler.emit('recall');
 59.3618 +        this.recall(target);
 59.3619 +        target.style.display = 'none';
 59.3620 +        target.style.width = '';
 59.3621 +        target.style.height = '';
 59.3622 +        this._size = null;
 59.3623 +        _cleanupStyles.call(this, target);
 59.3624 +        var classList = this.getClassList();
 59.3625 +        _cleanupClasses.call(this, target);
 59.3626 +        for (i = 0; i < classList.length; i++) target.classList.remove(classList[i]);
 59.3627 +        if (this.elementClass) {
 59.3628 +            if (this.elementClass instanceof Array) {
 59.3629 +                for (i = 0; i < this.elementClass.length; i++) {
 59.3630 +                    target.classList.remove(this.elementClass[i]);
 59.3631 +                }
 59.3632 +            }
 59.3633 +            else {
 59.3634 +                target.classList.remove(this.elementClass);
 59.3635 +            }
 59.3636 +        }
 59.3637 +        _removeEventListeners.call(this, target);
 59.3638 +        this._currTarget = null;
 59.3639 +        allocator.deallocate(target);
 59.3640 +        _setInvisible(target);
 59.3641 +    };
 59.3642 +
 59.3643 +    /**
 59.3644 +     * Place the document element that this component manages into the document.
 59.3645 +     *
 59.3646 +     * @private
 59.3647 +     * @method deploy
 59.3648 +     * @param {Node} target document parent of this container
 59.3649 +     */
 59.3650 +    Surface.prototype.deploy = function deploy(target) {
 59.3651 +        var content = this.getContent();
 59.3652 +        if (content instanceof Node) {
 59.3653 +            while (target.hasChildNodes()) target.removeChild(target.firstChild);
 59.3654 +            target.appendChild(content);
 59.3655 +        }
 59.3656 +        else target.innerHTML = content;
 59.3657 +    };
 59.3658 +
 59.3659 +    /**
 59.3660 +     * Remove any contained document content associated with this surface
 59.3661 +     *   from the actual document.
 59.3662 +     *
 59.3663 +     * @private
 59.3664 +     * @method recall
 59.3665 +     */
 59.3666 +    Surface.prototype.recall = function recall(target) {
 59.3667 +        var df = document.createDocumentFragment();
 59.3668 +        while (target.hasChildNodes()) df.appendChild(target.firstChild);
 59.3669 +        this.setContent(df);
 59.3670 +    };
 59.3671 +
 59.3672 +    /**
 59.3673 +     *  Get the x and y dimensions of the surface.
 59.3674 +     *
 59.3675 +     * @method getSize
 59.3676 +     * @param {boolean} actual return computed size rather than provided
 59.3677 +     * @return {Array.Number} [x,y] size of surface
 59.3678 +     */
 59.3679 +    Surface.prototype.getSize = function getSize(actual) {
 59.3680 +        return actual ? this._size : (this.size || this._size);
 59.3681 +    };
 59.3682 +
 59.3683 +    /**
 59.3684 +     * Set x and y dimensions of the surface.
 59.3685 +     *
 59.3686 +     * @method setSize
 59.3687 +     * @param {Array.Number} size as [width, height]
 59.3688 +     */
 59.3689 +    Surface.prototype.setSize = function setSize(size) {
 59.3690 +        this.size = size ? [size[0], size[1]] : null;
 59.3691 +        this._sizeDirty = true;
 59.3692 +    };
 59.3693 +
 59.3694 +    module.exports = Surface;
 59.3695 +});
 59.3696 +
 59.3697 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.3698 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.3699 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.3700 + *
 59.3701 + * Owner: mark@famo.us
 59.3702 + * @license MPL 2.0
 59.3703 + * @copyright Famous Industries, Inc. 2014
 59.3704 + */
 59.3705 +
 59.3706 +define('famous/core/Group',['require','exports','module','./Context','./Transform','./Surface'],function(require, exports, module) {
 59.3707 +    var Context = require('./Context');
 59.3708 +    var Transform = require('./Transform');
 59.3709 +    var Surface = require('./Surface');
 59.3710 +
 59.3711 +    /**
 59.3712 +     * A Context designed to contain surfaces and set properties
 59.3713 +     *   to be applied to all of them at once.
 59.3714 +     *   This is primarily used for specific performance improvements in the rendering engine.
 59.3715 +     *   Private.
 59.3716 +     *
 59.3717 +     * @private
 59.3718 +     * @class Group
 59.3719 +     * @extends Surface
 59.3720 +     * @constructor
 59.3721 +     * @param {Object} [options] Surface options array (see Surface})
 59.3722 +     */
 59.3723 +    function Group(options) {
 59.3724 +        Surface.call(this, options);
 59.3725 +        this._shouldRecalculateSize = false;
 59.3726 +        this._container = document.createDocumentFragment();
 59.3727 +        this.context = new Context(this._container);
 59.3728 +        this.setContent(this._container);
 59.3729 +        this._groupSize = [undefined, undefined];
 59.3730 +    }
 59.3731 +
 59.3732 +    /** @const */
 59.3733 +    Group.SIZE_ZERO = [0, 0];
 59.3734 +
 59.3735 +    Group.prototype = Object.create(Surface.prototype);
 59.3736 +    Group.prototype.elementType = 'div';
 59.3737 +    Group.prototype.elementClass = 'famous-group';
 59.3738 +
 59.3739 +    /**
 59.3740 +     * Add renderables to this component's render tree.
 59.3741 +     *
 59.3742 +     * @method add
 59.3743 +     * @private
 59.3744 +     * @param {Object} obj renderable object
 59.3745 +     * @return {RenderNode} Render wrapping provided object, if not already a RenderNode
 59.3746 +     */
 59.3747 +    Group.prototype.add = function add() {
 59.3748 +        return this.context.add.apply(this.context, arguments);
 59.3749 +    };
 59.3750 +
 59.3751 +    /**
 59.3752 +     * Generate a render spec from the contents of this component.
 59.3753 +     *
 59.3754 +     * @private
 59.3755 +     * @method render
 59.3756 +     * @return {Number} Render spec for this component
 59.3757 +     */
 59.3758 +    Group.prototype.render = function render() {
 59.3759 +        return Surface.prototype.render.call(this);
 59.3760 +    };
 59.3761 +
 59.3762 +    /**
 59.3763 +     * Place the document element this component manages into the document.
 59.3764 +     *
 59.3765 +     * @private
 59.3766 +     * @method deploy
 59.3767 +     * @param {Node} target document parent of this container
 59.3768 +     */
 59.3769 +    Group.prototype.deploy = function deploy(target) {
 59.3770 +        this.context.migrate(target);
 59.3771 +    };
 59.3772 +
 59.3773 +    /**
 59.3774 +     * Remove this component and contained content from the document
 59.3775 +     *
 59.3776 +     * @private
 59.3777 +     * @method recall
 59.3778 +     *
 59.3779 +     * @param {Node} target node to which the component was deployed
 59.3780 +     */
 59.3781 +    Group.prototype.recall = function recall(target) {
 59.3782 +        this._container = document.createDocumentFragment();
 59.3783 +        this.context.migrate(this._container);
 59.3784 +    };
 59.3785 +
 59.3786 +    /**
 59.3787 +     * Apply changes from this component to the corresponding document element.
 59.3788 +     *
 59.3789 +     * @private
 59.3790 +     * @method commit
 59.3791 +     *
 59.3792 +     * @param {Object} context update spec passed in from above in the render tree.
 59.3793 +     */
 59.3794 +    Group.prototype.commit = function commit(context) {
 59.3795 +        var transform = context.transform;
 59.3796 +        var origin = context.origin;
 59.3797 +        var opacity = context.opacity;
 59.3798 +        var size = context.size;
 59.3799 +        var result = Surface.prototype.commit.call(this, {
 59.3800 +            allocator: context.allocator,
 59.3801 +            transform: Transform.thenMove(transform, [-origin[0] * size[0], -origin[1] * size[1], 0]),
 59.3802 +            opacity: opacity,
 59.3803 +            origin: origin,
 59.3804 +            size: Group.SIZE_ZERO
 59.3805 +        });
 59.3806 +        if (size[0] !== this._groupSize[0] || size[1] !== this._groupSize[1]) {
 59.3807 +            this._groupSize[0] = size[0];
 59.3808 +            this._groupSize[1] = size[1];
 59.3809 +            this.context.setSize(size);
 59.3810 +        }
 59.3811 +        this.context.update({
 59.3812 +            transform: Transform.translate(-origin[0] * size[0], -origin[1] * size[1], 0),
 59.3813 +            origin: origin,
 59.3814 +            size: size
 59.3815 +        });
 59.3816 +        return result;
 59.3817 +    };
 59.3818 +
 59.3819 +    module.exports = Group;
 59.3820 +});
 59.3821 +
 59.3822 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.3823 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.3824 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.3825 + *
 59.3826 + * Owner: david@famo.us
 59.3827 + * @license MPL 2.0
 59.3828 + * @copyright Famous Industries, Inc. 2014
 59.3829 + */
 59.3830 +
 59.3831 +define('famous/transitions/TransitionableTransform',['require','exports','module','./Transitionable','famous/core/Transform','famous/utilities/Utility'],function(require, exports, module) {
 59.3832 +    var Transitionable = require('./Transitionable');
 59.3833 +    var Transform = require('famous/core/Transform');
 59.3834 +    var Utility = require('famous/utilities/Utility');
 59.3835 +
 59.3836 +    /**
 59.3837 +     * A class for transitioning the state of a Transform by transitioning
 59.3838 +     * its translate, scale, skew and rotate components independently.
 59.3839 +     *
 59.3840 +     * @class TransitionableTransform
 59.3841 +     * @constructor
 59.3842 +     *
 59.3843 +     * @param [transform=Transform.identity] {Transform} The initial transform state
 59.3844 +     */
 59.3845 +    function TransitionableTransform(transform) {
 59.3846 +        this._final = Transform.identity.slice();
 59.3847 +        this.translate = new Transitionable([0, 0, 0]);
 59.3848 +        this.rotate = new Transitionable([0, 0, 0]);
 59.3849 +        this.skew = new Transitionable([0, 0, 0]);
 59.3850 +        this.scale = new Transitionable([1, 1, 1]);
 59.3851 +
 59.3852 +        if (transform) this.set(transform);
 59.3853 +    }
 59.3854 +
 59.3855 +    function _build() {
 59.3856 +        return Transform.build({
 59.3857 +            translate: this.translate.get(),
 59.3858 +            rotate: this.rotate.get(),
 59.3859 +            skew: this.skew.get(),
 59.3860 +            scale: this.scale.get()
 59.3861 +        });
 59.3862 +    }
 59.3863 +
 59.3864 +    /**
 59.3865 +     * An optimized way of setting only the translation component of a Transform
 59.3866 +     *
 59.3867 +     * @method setTranslate
 59.3868 +     * @chainable
 59.3869 +     *
 59.3870 +     * @param translate {Array}     New translation state
 59.3871 +     * @param [transition] {Object} Transition definition
 59.3872 +     * @param [callback] {Function} Callback
 59.3873 +     * @return {TransitionableTransform}
 59.3874 +     */
 59.3875 +    TransitionableTransform.prototype.setTranslate = function setTranslate(translate, transition, callback) {
 59.3876 +        this.translate.set(translate, transition, callback);
 59.3877 +        this._final = this._final.slice();
 59.3878 +        this._final[12] = translate[0];
 59.3879 +        this._final[13] = translate[1];
 59.3880 +        if (translate[2] !== undefined) this._final[14] = translate[2];
 59.3881 +        return this;
 59.3882 +    };
 59.3883 +
 59.3884 +    /**
 59.3885 +     * An optimized way of setting only the scale component of a Transform
 59.3886 +     *
 59.3887 +     * @method setScale
 59.3888 +     * @chainable
 59.3889 +     *
 59.3890 +     * @param scale {Array}         New scale state
 59.3891 +     * @param [transition] {Object} Transition definition
 59.3892 +     * @param [callback] {Function} Callback
 59.3893 +     * @return {TransitionableTransform}
 59.3894 +     */
 59.3895 +    TransitionableTransform.prototype.setScale = function setScale(scale, transition, callback) {
 59.3896 +        this.scale.set(scale, transition, callback);
 59.3897 +        this._final = this._final.slice();
 59.3898 +        this._final[0] = scale[0];
 59.3899 +        this._final[5] = scale[1];
 59.3900 +        if (scale[2] !== undefined) this._final[10] = scale[2];
 59.3901 +        return this;
 59.3902 +    };
 59.3903 +
 59.3904 +    /**
 59.3905 +     * An optimized way of setting only the rotational component of a Transform
 59.3906 +     *
 59.3907 +     * @method setRotate
 59.3908 +     * @chainable
 59.3909 +     *
 59.3910 +     * @param eulerAngles {Array}   Euler angles for new rotation state
 59.3911 +     * @param [transition] {Object} Transition definition
 59.3912 +     * @param [callback] {Function} Callback
 59.3913 +     * @return {TransitionableTransform}
 59.3914 +     */
 59.3915 +    TransitionableTransform.prototype.setRotate = function setRotate(eulerAngles, transition, callback) {
 59.3916 +        this.rotate.set(eulerAngles, transition, callback);
 59.3917 +        this._final = _build.call(this);
 59.3918 +        this._final = Transform.build({
 59.3919 +            translate: this.translate.get(),
 59.3920 +            rotate: eulerAngles,
 59.3921 +            scale: this.scale.get(),
 59.3922 +            skew: this.skew.get()
 59.3923 +        });
 59.3924 +        return this;
 59.3925 +    };
 59.3926 +
 59.3927 +    /**
 59.3928 +     * An optimized way of setting only the skew component of a Transform
 59.3929 +     *
 59.3930 +     * @method setSkew
 59.3931 +     * @chainable
 59.3932 +     *
 59.3933 +     * @param skewAngles {Array}    New skew state
 59.3934 +     * @param [transition] {Object} Transition definition
 59.3935 +     * @param [callback] {Function} Callback
 59.3936 +     * @return {TransitionableTransform}
 59.3937 +     */
 59.3938 +    TransitionableTransform.prototype.setSkew = function setSkew(skewAngles, transition, callback) {
 59.3939 +        this.skew.set(skewAngles, transition, callback);
 59.3940 +        this._final = Transform.build({
 59.3941 +            translate: this.translate.get(),
 59.3942 +            rotate: this.rotate.get(),
 59.3943 +            scale: this.scale.get(),
 59.3944 +            skew: skewAngles
 59.3945 +        });
 59.3946 +        return this;
 59.3947 +    };
 59.3948 +
 59.3949 +    /**
 59.3950 +     * Setter for a TransitionableTransform with optional parameters to transition
 59.3951 +     * between Transforms
 59.3952 +     *
 59.3953 +     * @method set
 59.3954 +     * @chainable
 59.3955 +     *
 59.3956 +     * @param transform {Array}     New transform state
 59.3957 +     * @param [transition] {Object} Transition definition
 59.3958 +     * @param [callback] {Function} Callback
 59.3959 +     * @return {TransitionableTransform}
 59.3960 +     */
 59.3961 +    TransitionableTransform.prototype.set = function set(transform, transition, callback) {
 59.3962 +        this._final = transform;
 59.3963 +        var components = Transform.interpret(transform);
 59.3964 +
 59.3965 +        var _callback = callback ? Utility.after(4, callback) : null;
 59.3966 +        this.translate.set(components.translate, transition, _callback);
 59.3967 +        this.rotate.set(components.rotate, transition, _callback);
 59.3968 +        this.skew.set(components.skew, transition, _callback);
 59.3969 +        this.scale.set(components.scale, transition, _callback);
 59.3970 +        return this;
 59.3971 +    };
 59.3972 +
 59.3973 +    /**
 59.3974 +     * Sets the default transition to use for transitioning betwen Transform states
 59.3975 +     *
 59.3976 +     * @method setDefaultTransition
 59.3977 +     *
 59.3978 +     * @param transition {Object} Transition definition
 59.3979 +     */
 59.3980 +    TransitionableTransform.prototype.setDefaultTransition = function setDefaultTransition(transition) {
 59.3981 +        this.translate.setDefault(transition);
 59.3982 +        this.rotate.setDefault(transition);
 59.3983 +        this.skew.setDefault(transition);
 59.3984 +        this.scale.setDefault(transition);
 59.3985 +    };
 59.3986 +
 59.3987 +    /**
 59.3988 +     * Getter. Returns the current state of the Transform
 59.3989 +     *
 59.3990 +     * @method get
 59.3991 +     *
 59.3992 +     * @return {Transform}
 59.3993 +     */
 59.3994 +    TransitionableTransform.prototype.get = function get() {
 59.3995 +        if (this.isActive()) {
 59.3996 +            return _build.call(this);
 59.3997 +        }
 59.3998 +        else return this._final;
 59.3999 +    };
 59.4000 +
 59.4001 +    /**
 59.4002 +     * Get the destination state of the Transform
 59.4003 +     *
 59.4004 +     * @method getFinal
 59.4005 +     *
 59.4006 +     * @return Transform {Transform}
 59.4007 +     */
 59.4008 +    TransitionableTransform.prototype.getFinal = function getFinal() {
 59.4009 +        return this._final;
 59.4010 +    };
 59.4011 +
 59.4012 +    /**
 59.4013 +     * Determine if the TransitionalTransform is currently transitioning
 59.4014 +     *
 59.4015 +     * @method isActive
 59.4016 +     *
 59.4017 +     * @return {Boolean}
 59.4018 +     */
 59.4019 +    TransitionableTransform.prototype.isActive = function isActive() {
 59.4020 +        return this.translate.isActive() || this.rotate.isActive() || this.scale.isActive() || this.skew.isActive();
 59.4021 +    };
 59.4022 +
 59.4023 +    /**
 59.4024 +     * Halts the transition
 59.4025 +     *
 59.4026 +     * @method halt
 59.4027 +     */
 59.4028 +    TransitionableTransform.prototype.halt = function halt() {
 59.4029 +        this._final = this.get();
 59.4030 +        this.translate.halt();
 59.4031 +        this.rotate.halt();
 59.4032 +        this.skew.halt();
 59.4033 +        this.scale.halt();
 59.4034 +    };
 59.4035 +
 59.4036 +    module.exports = TransitionableTransform;
 59.4037 +});
 59.4038 +
 59.4039 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.4040 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.4041 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.4042 + *
 59.4043 + * Owner: mark@famo.us
 59.4044 + * @license MPL 2.0
 59.4045 + * @copyright Famous Industries, Inc. 2014
 59.4046 + */
 59.4047 +
 59.4048 +define('famous/core/Modifier',['require','exports','module','./Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
 59.4049 +    var Transform = require('./Transform');
 59.4050 +
 59.4051 +    /* TODO: remove these dependencies when deprecation complete */
 59.4052 +    var Transitionable = require('famous/transitions/Transitionable');
 59.4053 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
 59.4054 +
 59.4055 +    /**
 59.4056 +     *
 59.4057 +     *  A collection of visual changes to be
 59.4058 +     *    applied to another renderable component. This collection includes a
 59.4059 +     *    transform matrix, an opacity constant, a size, an origin specifier.
 59.4060 +     *    Modifier objects can be added to any RenderNode or object
 59.4061 +     *    capable of displaying renderables.  The Modifier's children and descendants
 59.4062 +     *    are transformed by the amounts specified in the Modifier's properties.
 59.4063 +     *
 59.4064 +     * @class Modifier
 59.4065 +     * @constructor
 59.4066 +     * @param {Object} [options] overrides of default options
 59.4067 +     * @param {Transform} [options.transform] affine transformation matrix
 59.4068 +     * @param {Number} [options.opacity]
 59.4069 +     * @param {Array.Number} [options.origin] origin adjustment
 59.4070 +     * @param {Array.Number} [options.size] size to apply to descendants
 59.4071 +     */
 59.4072 +    function Modifier(options) {
 59.4073 +        this._transformGetter = null;
 59.4074 +        this._opacityGetter = null;
 59.4075 +        this._originGetter = null;
 59.4076 +        this._alignGetter = null;
 59.4077 +        this._sizeGetter = null;
 59.4078 +
 59.4079 +        /* TODO: remove this when deprecation complete */
 59.4080 +        this._legacyStates = {};
 59.4081 +
 59.4082 +        this._output = {
 59.4083 +            transform: Transform.identity,
 59.4084 +            opacity: 1,
 59.4085 +            origin: null,
 59.4086 +            align: null,
 59.4087 +            size: null,
 59.4088 +            target: null
 59.4089 +        };
 59.4090 +
 59.4091 +        if (options) {
 59.4092 +            if (options.transform) this.transformFrom(options.transform);
 59.4093 +            if (options.opacity !== undefined) this.opacityFrom(options.opacity);
 59.4094 +            if (options.origin) this.originFrom(options.origin);
 59.4095 +            if (options.align) this.alignFrom(options.align);
 59.4096 +            if (options.size) this.sizeFrom(options.size);
 59.4097 +        }
 59.4098 +    }
 59.4099 +
 59.4100 +    /**
 59.4101 +     * Function, object, or static transform matrix which provides the transform.
 59.4102 +     *   This is evaluated on every tick of the engine.
 59.4103 +     *
 59.4104 +     * @method transformFrom
 59.4105 +     *
 59.4106 +     * @param {Object} transform transform provider object
 59.4107 +     * @return {Modifier} this
 59.4108 +     */
 59.4109 +    Modifier.prototype.transformFrom = function transformFrom(transform) {
 59.4110 +        if (transform instanceof Function) this._transformGetter = transform;
 59.4111 +        else if (transform instanceof Object && transform.get) this._transformGetter = transform.get.bind(transform);
 59.4112 +        else {
 59.4113 +            this._transformGetter = null;
 59.4114 +            this._output.transform = transform;
 59.4115 +        }
 59.4116 +        return this;
 59.4117 +    };
 59.4118 +
 59.4119 +    /**
 59.4120 +     * Set function, object, or number to provide opacity, in range [0,1].
 59.4121 +     *
 59.4122 +     * @method opacityFrom
 59.4123 +     *
 59.4124 +     * @param {Object} opacity provider object
 59.4125 +     * @return {Modifier} this
 59.4126 +     */
 59.4127 +    Modifier.prototype.opacityFrom = function opacityFrom(opacity) {
 59.4128 +        if (opacity instanceof Function) this._opacityGetter = opacity;
 59.4129 +        else if (opacity instanceof Object && opacity.get) this._opacityGetter = opacity.get.bind(opacity);
 59.4130 +        else {
 59.4131 +            this._opacityGetter = null;
 59.4132 +            this._output.opacity = opacity;
 59.4133 +        }
 59.4134 +        return this;
 59.4135 +    };
 59.4136 +
 59.4137 +    /**
 59.4138 +     * Set function, object, or numerical array to provide origin, as [x,y],
 59.4139 +     *   where x and y are in the range [0,1].
 59.4140 +     *
 59.4141 +     * @method originFrom
 59.4142 +     *
 59.4143 +     * @param {Object} origin provider object
 59.4144 +     * @return {Modifier} this
 59.4145 +     */
 59.4146 +    Modifier.prototype.originFrom = function originFrom(origin) {
 59.4147 +        if (origin instanceof Function) this._originGetter = origin;
 59.4148 +        else if (origin instanceof Object && origin.get) this._originGetter = origin.get.bind(origin);
 59.4149 +        else {
 59.4150 +            this._originGetter = null;
 59.4151 +            this._output.origin = origin;
 59.4152 +        }
 59.4153 +        return this;
 59.4154 +    };
 59.4155 +
 59.4156 +    /**
 59.4157 +     * Set function, object, or numerical array to provide align, as [x,y],
 59.4158 +     *   where x and y are in the range [0,1].
 59.4159 +     *
 59.4160 +     * @method alignFrom
 59.4161 +     *
 59.4162 +     * @param {Object} align provider object
 59.4163 +     * @return {Modifier} this
 59.4164 +     */
 59.4165 +    Modifier.prototype.alignFrom = function alignFrom(align) {
 59.4166 +        if (align instanceof Function) this._alignGetter = align;
 59.4167 +        else if (align instanceof Object && align.get) this._alignGetter = align.get.bind(align);
 59.4168 +        else {
 59.4169 +            this._alignGetter = null;
 59.4170 +            this._output.align = align;
 59.4171 +        }
 59.4172 +        return this;
 59.4173 +    };
 59.4174 +
 59.4175 +    /**
 59.4176 +     * Set function, object, or numerical array to provide size, as [width, height].
 59.4177 +     *
 59.4178 +     * @method sizeFrom
 59.4179 +     *
 59.4180 +     * @param {Object} size provider object
 59.4181 +     * @return {Modifier} this
 59.4182 +     */
 59.4183 +    Modifier.prototype.sizeFrom = function sizeFrom(size) {
 59.4184 +        if (size instanceof Function) this._sizeGetter = size;
 59.4185 +        else if (size instanceof Object && size.get) this._sizeGetter = size.get.bind(size);
 59.4186 +        else {
 59.4187 +            this._sizeGetter = null;
 59.4188 +            this._output.size = size;
 59.4189 +        }
 59.4190 +        return this;
 59.4191 +    };
 59.4192 +
 59.4193 +     /**
 59.4194 +     * Deprecated: Prefer transformFrom with static Transform, or use a TransitionableTransform.
 59.4195 +     * @deprecated
 59.4196 +     * @method setTransform
 59.4197 +     *
 59.4198 +     * @param {Transform} transform Transform to transition to
 59.4199 +     * @param {Transitionable} transition Valid transitionable object
 59.4200 +     * @param {Function} callback callback to call after transition completes
 59.4201 +     * @return {Modifier} this
 59.4202 +     */
 59.4203 +    Modifier.prototype.setTransform = function setTransform(transform, transition, callback) {
 59.4204 +        if (transition || this._legacyStates.transform) {
 59.4205 +            if (!this._legacyStates.transform) {
 59.4206 +                this._legacyStates.transform = new TransitionableTransform(this._output.transform);
 59.4207 +            }
 59.4208 +            if (!this._transformGetter) this.transformFrom(this._legacyStates.transform);
 59.4209 +
 59.4210 +            this._legacyStates.transform.set(transform, transition, callback);
 59.4211 +            return this;
 59.4212 +        }
 59.4213 +        else return this.transformFrom(transform);
 59.4214 +    };
 59.4215 +
 59.4216 +    /**
 59.4217 +     * Deprecated: Prefer opacityFrom with static opacity array, or use a Transitionable with that opacity.
 59.4218 +     * @deprecated
 59.4219 +     * @method setOpacity
 59.4220 +     *
 59.4221 +     * @param {Number} opacity Opacity value to transition to.
 59.4222 +     * @param {Transitionable} transition Valid transitionable object
 59.4223 +     * @param {Function} callback callback to call after transition completes
 59.4224 +     * @return {Modifier} this
 59.4225 +     */
 59.4226 +    Modifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) {
 59.4227 +        if (transition || this._legacyStates.opacity) {
 59.4228 +            if (!this._legacyStates.opacity) {
 59.4229 +                this._legacyStates.opacity = new Transitionable(this._output.opacity);
 59.4230 +            }
 59.4231 +            if (!this._opacityGetter) this.opacityFrom(this._legacyStates.opacity);
 59.4232 +
 59.4233 +            return this._legacyStates.opacity.set(opacity, transition, callback);
 59.4234 +        }
 59.4235 +        else return this.opacityFrom(opacity);
 59.4236 +    };
 59.4237 +
 59.4238 +    /**
 59.4239 +     * Deprecated: Prefer originFrom with static origin array, or use a Transitionable with that origin.
 59.4240 +     * @deprecated
 59.4241 +     * @method setOrigin
 59.4242 +     *
 59.4243 +     * @param {Array.Number} origin two element array with values between 0 and 1.
 59.4244 +     * @param {Transitionable} transition Valid transitionable object
 59.4245 +     * @param {Function} callback callback to call after transition completes
 59.4246 +     * @return {Modifier} this
 59.4247 +     */
 59.4248 +    Modifier.prototype.setOrigin = function setOrigin(origin, transition, callback) {
 59.4249 +        /* TODO: remove this if statement when deprecation complete */
 59.4250 +        if (transition || this._legacyStates.origin) {
 59.4251 +
 59.4252 +            if (!this._legacyStates.origin) {
 59.4253 +                this._legacyStates.origin = new Transitionable(this._output.origin || [0, 0]);
 59.4254 +            }
 59.4255 +            if (!this._originGetter) this.originFrom(this._legacyStates.origin);
 59.4256 +
 59.4257 +            this._legacyStates.origin.set(origin, transition, callback);
 59.4258 +            return this;
 59.4259 +        }
 59.4260 +        else return this.originFrom(origin);
 59.4261 +    };
 59.4262 +
 59.4263 +    /**
 59.4264 +     * Deprecated: Prefer alignFrom with static align array, or use a Transitionable with that align.
 59.4265 +     * @deprecated
 59.4266 +     * @method setAlign
 59.4267 +     *
 59.4268 +     * @param {Array.Number} align two element array with values between 0 and 1.
 59.4269 +     * @param {Transitionable} transition Valid transitionable object
 59.4270 +     * @param {Function} callback callback to call after transition completes
 59.4271 +     * @return {Modifier} this
 59.4272 +     */
 59.4273 +    Modifier.prototype.setAlign = function setAlign(align, transition, callback) {
 59.4274 +        /* TODO: remove this if statement when deprecation complete */
 59.4275 +        if (transition || this._legacyStates.align) {
 59.4276 +
 59.4277 +            if (!this._legacyStates.align) {
 59.4278 +                this._legacyStates.align = new Transitionable(this._output.align || [0, 0]);
 59.4279 +            }
 59.4280 +            if (!this._alignGetter) this.alignFrom(this._legacyStates.align);
 59.4281 +
 59.4282 +            this._legacyStates.align.set(align, transition, callback);
 59.4283 +            return this;
 59.4284 +        }
 59.4285 +        else return this.alignFrom(align);
 59.4286 +    };
 59.4287 +
 59.4288 +    /**
 59.4289 +     * Deprecated: Prefer sizeFrom with static origin array, or use a Transitionable with that size.
 59.4290 +     * @deprecated
 59.4291 +     * @method setSize
 59.4292 +     * @param {Array.Number} size two element array of [width, height]
 59.4293 +     * @param {Transitionable} transition Valid transitionable object
 59.4294 +     * @param {Function} callback callback to call after transition completes
 59.4295 +     * @return {Modifier} this
 59.4296 +     */
 59.4297 +    Modifier.prototype.setSize = function setSize(size, transition, callback) {
 59.4298 +        if (size && (transition || this._legacyStates.size)) {
 59.4299 +            if (!this._legacyStates.size) {
 59.4300 +                this._legacyStates.size = new Transitionable(this._output.size || [0, 0]);
 59.4301 +            }
 59.4302 +            if (!this._sizeGetter) this.sizeFrom(this._legacyStates.size);
 59.4303 +
 59.4304 +            this._legacyStates.size.set(size, transition, callback);
 59.4305 +            return this;
 59.4306 +        }
 59.4307 +        else return this.sizeFrom(size);
 59.4308 +    };
 59.4309 +
 59.4310 +    /**
 59.4311 +     * Deprecated: Prefer to stop transform in your provider object.
 59.4312 +     * @deprecated
 59.4313 +     * @method halt
 59.4314 +     */
 59.4315 +    Modifier.prototype.halt = function halt() {
 59.4316 +        if (this._legacyStates.transform) this._legacyStates.transform.halt();
 59.4317 +        if (this._legacyStates.opacity) this._legacyStates.opacity.halt();
 59.4318 +        if (this._legacyStates.origin) this._legacyStates.origin.halt();
 59.4319 +        if (this._legacyStates.align) this._legacyStates.align.halt();
 59.4320 +        if (this._legacyStates.size) this._legacyStates.size.halt();
 59.4321 +        this._transformGetter = null;
 59.4322 +        this._opacityGetter = null;
 59.4323 +        this._originGetter = null;
 59.4324 +        this._alignGetter = null;
 59.4325 +        this._sizeGetter = null;
 59.4326 +    };
 59.4327 +
 59.4328 +    /**
 59.4329 +     * Deprecated: Prefer to use your provided transform or output of your transform provider.
 59.4330 +     * @deprecated
 59.4331 +     * @method getTransform
 59.4332 +     * @return {Object} transform provider object
 59.4333 +     */
 59.4334 +    Modifier.prototype.getTransform = function getTransform() {
 59.4335 +        return this._transformGetter();
 59.4336 +    };
 59.4337 +
 59.4338 +    /**
 59.4339 +     * Deprecated: Prefer to determine the end state of your transform from your transform provider
 59.4340 +     * @deprecated
 59.4341 +     * @method getFinalTransform
 59.4342 +     * @return {Transform} transform matrix
 59.4343 +     */
 59.4344 +    Modifier.prototype.getFinalTransform = function getFinalTransform() {
 59.4345 +        return this._legacyStates.transform ? this._legacyStates.transform.getFinal() : this._output.transform;
 59.4346 +    };
 59.4347 +
 59.4348 +    /**
 59.4349 +     * Deprecated: Prefer to use your provided opacity or output of your opacity provider.
 59.4350 +     * @deprecated
 59.4351 +     * @method getOpacity
 59.4352 +     * @return {Object} opacity provider object
 59.4353 +     */
 59.4354 +    Modifier.prototype.getOpacity = function getOpacity() {
 59.4355 +        return this._opacityGetter();
 59.4356 +    };
 59.4357 +
 59.4358 +    /**
 59.4359 +     * Deprecated: Prefer to use your provided origin or output of your origin provider.
 59.4360 +     * @deprecated
 59.4361 +     * @method getOrigin
 59.4362 +     * @return {Object} origin provider object
 59.4363 +     */
 59.4364 +    Modifier.prototype.getOrigin = function getOrigin() {
 59.4365 +        return this._originGetter();
 59.4366 +    };
 59.4367 +
 59.4368 +    /**
 59.4369 +     * Deprecated: Prefer to use your provided align or output of your align provider.
 59.4370 +     * @deprecated
 59.4371 +     * @method getAlign
 59.4372 +     * @return {Object} align provider object
 59.4373 +     */
 59.4374 +    Modifier.prototype.getAlign = function getAlign() {
 59.4375 +        return this._alignGetter();
 59.4376 +    };
 59.4377 +
 59.4378 +    /**
 59.4379 +     * Deprecated: Prefer to use your provided size or output of your size provider.
 59.4380 +     * @deprecated
 59.4381 +     * @method getSize
 59.4382 +     * @return {Object} size provider object
 59.4383 +     */
 59.4384 +    Modifier.prototype.getSize = function getSize() {
 59.4385 +        return this._sizeGetter ? this._sizeGetter() : this._output.size;
 59.4386 +    };
 59.4387 +
 59.4388 +    // call providers on tick to receive render spec elements to apply
 59.4389 +    function _update() {
 59.4390 +        if (this._transformGetter) this._output.transform = this._transformGetter();
 59.4391 +        if (this._opacityGetter) this._output.opacity = this._opacityGetter();
 59.4392 +        if (this._originGetter) this._output.origin = this._originGetter();
 59.4393 +        if (this._alignGetter) this._output.align = this._alignGetter();
 59.4394 +        if (this._sizeGetter) this._output.size = this._sizeGetter();
 59.4395 +    }
 59.4396 +
 59.4397 +    /**
 59.4398 +     * Return render spec for this Modifier, applying to the provided
 59.4399 +     *    target component.  This is similar to render() for Surfaces.
 59.4400 +     *
 59.4401 +     * @private
 59.4402 +     * @method modify
 59.4403 +     *
 59.4404 +     * @param {Object} target (already rendered) render spec to
 59.4405 +     *    which to apply the transform.
 59.4406 +     * @return {Object} render spec for this Modifier, including the
 59.4407 +     *    provided target
 59.4408 +     */
 59.4409 +    Modifier.prototype.modify = function modify(target) {
 59.4410 +        _update.call(this);
 59.4411 +        this._output.target = target;
 59.4412 +        return this._output;
 59.4413 +    };
 59.4414 +
 59.4415 +    module.exports = Modifier;
 59.4416 +});
 59.4417 +
 59.4418 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.4419 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.4420 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.4421 + *
 59.4422 + * Owner: mark@famo.us
 59.4423 + * @license MPL 2.0
 59.4424 + * @copyright Famous Industries, Inc. 2014
 59.4425 + */
 59.4426 +
 59.4427 +define('famous/core/Scene',['require','exports','module','./Transform','./Modifier','./RenderNode'],function(require, exports, module) {
 59.4428 +    var Transform = require('./Transform');
 59.4429 +    var Modifier = require('./Modifier');
 59.4430 +    var RenderNode = require('./RenderNode');
 59.4431 +
 59.4432 +    /**
 59.4433 +     * Builds and renders a scene graph based on a declarative structure definition.
 59.4434 +     * See the Scene examples in the examples distribution (http://github.com/Famous/examples.git).
 59.4435 +     *
 59.4436 +     * @class Scene
 59.4437 +     * @constructor
 59.4438 +     * @param {Object} definition in the format of a render spec.
 59.4439 +     */
 59.4440 +    function Scene(definition) {
 59.4441 +        this.id = null;
 59.4442 +        this._objects = null;
 59.4443 +
 59.4444 +        this.node = new RenderNode();
 59.4445 +        this._definition = null;
 59.4446 +
 59.4447 +        if (definition) this.load(definition);
 59.4448 +    }
 59.4449 +
 59.4450 +    var _MATRIX_GENERATORS = {
 59.4451 +        'translate': Transform.translate,
 59.4452 +        'rotate': Transform.rotate,
 59.4453 +        'rotateX': Transform.rotateX,
 59.4454 +        'rotateY': Transform.rotateY,
 59.4455 +        'rotateZ': Transform.rotateZ,
 59.4456 +        'rotateAxis': Transform.rotateAxis,
 59.4457 +        'scale': Transform.scale,
 59.4458 +        'skew': Transform.skew,
 59.4459 +        'matrix3d': function() {
 59.4460 +            return arguments;
 59.4461 +        }
 59.4462 +    };
 59.4463 +
 59.4464 +    /**
 59.4465 +     * Clone this scene
 59.4466 +     *
 59.4467 +     * @method create
 59.4468 +     * @return {Scene} deep copy of this scene
 59.4469 +     */
 59.4470 +    Scene.prototype.create = function create() {
 59.4471 +        return new Scene(this._definition);
 59.4472 +    };
 59.4473 +
 59.4474 +    function _resolveTransformMatrix(matrixDefinition) {
 59.4475 +        for (var type in _MATRIX_GENERATORS) {
 59.4476 +            if (type in matrixDefinition) {
 59.4477 +                var args = matrixDefinition[type];
 59.4478 +                if (!(args instanceof Array)) args = [args];
 59.4479 +                return _MATRIX_GENERATORS[type].apply(this, args);
 59.4480 +            }
 59.4481 +        }
 59.4482 +    }
 59.4483 +
 59.4484 +    // parse transform into tree of render nodes, doing matrix multiplication
 59.4485 +    // when available
 59.4486 +    function _parseTransform(definition) {
 59.4487 +        var transformDefinition = definition.transform;
 59.4488 +        var opacity = definition.opacity;
 59.4489 +        var origin = definition.origin;
 59.4490 +        var size = definition.size;
 59.4491 +        var transform = Transform.identity;
 59.4492 +        if (transformDefinition instanceof Array) {
 59.4493 +            if (transformDefinition.length === 16 && typeof transformDefinition[0] === 'number') {
 59.4494 +                transform = transformDefinition;
 59.4495 +            }
 59.4496 +            else {
 59.4497 +                for (var i = 0; i < transformDefinition.length; i++) {
 59.4498 +                    transform = Transform.multiply(transform, _resolveTransformMatrix(transformDefinition[i]));
 59.4499 +                }
 59.4500 +            }
 59.4501 +        }
 59.4502 +        else if (transformDefinition instanceof Object) {
 59.4503 +            transform = _resolveTransformMatrix(transformDefinition);
 59.4504 +        }
 59.4505 +
 59.4506 +        var result = new Modifier({
 59.4507 +            transform: transform,
 59.4508 +            opacity: opacity,
 59.4509 +            origin: origin,
 59.4510 +            size: size
 59.4511 +        });
 59.4512 +        return result;
 59.4513 +    }
 59.4514 +
 59.4515 +    function _parseArray(definition) {
 59.4516 +        var result = new RenderNode();
 59.4517 +        for (var i = 0; i < definition.length; i++) {
 59.4518 +            var obj = _parse.call(this, definition[i]);
 59.4519 +            if (obj) result.add(obj);
 59.4520 +        }
 59.4521 +        return result;
 59.4522 +    }
 59.4523 +
 59.4524 +    // parse object directly into tree of RenderNodes
 59.4525 +    function _parse(definition) {
 59.4526 +        var result;
 59.4527 +        var id;
 59.4528 +        if (definition instanceof Array) {
 59.4529 +            result = _parseArray.call(this, definition);
 59.4530 +        }
 59.4531 +        else {
 59.4532 +            id = this._objects.length;
 59.4533 +            if (definition.render && (definition.render instanceof Function)) {
 59.4534 +                result = definition;
 59.4535 +            }
 59.4536 +            else if (definition.target) {
 59.4537 +                var targetObj = _parse.call(this, definition.target);
 59.4538 +                var obj = _parseTransform.call(this, definition);
 59.4539 +
 59.4540 +                result = new RenderNode(obj);
 59.4541 +                result.add(targetObj);
 59.4542 +                if (definition.id) this.id[definition.id] = obj;
 59.4543 +            }
 59.4544 +            else if (definition.id) {
 59.4545 +                result = new RenderNode();
 59.4546 +                this.id[definition.id] = result;
 59.4547 +            }
 59.4548 +        }
 59.4549 +        this._objects[id] = result;
 59.4550 +        return result;
 59.4551 +    }
 59.4552 +
 59.4553 +    /**
 59.4554 +     * Builds and renders a scene graph based on a canonical declarative scene definition.
 59.4555 +     * See examples/Scene/example.js.
 59.4556 +     *
 59.4557 +     * @method load
 59.4558 +     * @param {Object} definition definition in the format of a render spec.
 59.4559 +     */
 59.4560 +    Scene.prototype.load = function load(definition) {
 59.4561 +        this._definition = definition;
 59.4562 +        this.id = {};
 59.4563 +        this._objects = [];
 59.4564 +        this.node.set(_parse.call(this, definition));
 59.4565 +    };
 59.4566 +
 59.4567 +    /**
 59.4568 +     * Add renderables to this component's render tree
 59.4569 +     *
 59.4570 +     * @method add
 59.4571 +     *
 59.4572 +     * @param {Object} obj renderable object
 59.4573 +     * @return {RenderNode} Render wrapping provided object, if not already a RenderNode
 59.4574 +     */
 59.4575 +    Scene.prototype.add = function add() {
 59.4576 +        return this.node.add.apply(this.node, arguments);
 59.4577 +    };
 59.4578 +
 59.4579 +    /**
 59.4580 +     * Generate a render spec from the contents of this component.
 59.4581 +     *
 59.4582 +     * @private
 59.4583 +     * @method render
 59.4584 +     * @return {number} Render spec for this component
 59.4585 +     */
 59.4586 +    Scene.prototype.render = function render() {
 59.4587 +        return this.node.render.apply(this.node, arguments);
 59.4588 +    };
 59.4589 +
 59.4590 +    module.exports = Scene;
 59.4591 +});
 59.4592 +
 59.4593 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.4594 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.4595 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.4596 + *
 59.4597 + * Owner: mark@famo.us
 59.4598 + * @license MPL 2.0
 59.4599 + * @copyright Famous Industries, Inc. 2014
 59.4600 + */
 59.4601 +
 59.4602 +define('famous/core/View',['require','exports','module','./EventHandler','./OptionsManager','./RenderNode'],function(require, exports, module) {
 59.4603 +    var EventHandler = require('./EventHandler');
 59.4604 +    var OptionsManager = require('./OptionsManager');
 59.4605 +    var RenderNode = require('./RenderNode');
 59.4606 +
 59.4607 +    /**
 59.4608 +     * Useful for quickly creating elements within applications
 59.4609 +     *   with large event systems.  Consists of a RenderNode paired with
 59.4610 +     *   an input EventHandler and an output EventHandler.
 59.4611 +     *   Meant to be extended by the developer.
 59.4612 +     *
 59.4613 +     * @class View
 59.4614 +     * @uses EventHandler
 59.4615 +     * @uses OptionsManager
 59.4616 +     * @uses RenderNode
 59.4617 +     * @constructor
 59.4618 +     */
 59.4619 +    function View(options) {
 59.4620 +        this._node = new RenderNode();
 59.4621 +
 59.4622 +        this._eventInput = new EventHandler();
 59.4623 +        this._eventOutput = new EventHandler();
 59.4624 +        EventHandler.setInputHandler(this, this._eventInput);
 59.4625 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.4626 +
 59.4627 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS || View.DEFAULT_OPTIONS);
 59.4628 +        this._optionsManager = new OptionsManager(this.options);
 59.4629 +
 59.4630 +        if (options) this.setOptions(options);
 59.4631 +    }
 59.4632 +
 59.4633 +    View.DEFAULT_OPTIONS = {}; // no defaults
 59.4634 +
 59.4635 +    /**
 59.4636 +     * Look up options value by key
 59.4637 +     * @method getOptions
 59.4638 +     *
 59.4639 +     * @param {string} key key
 59.4640 +     * @return {Object} associated object
 59.4641 +     */
 59.4642 +    View.prototype.getOptions = function getOptions() {
 59.4643 +        return this._optionsManager.value();
 59.4644 +    };
 59.4645 +
 59.4646 +    /*
 59.4647 +     *  Set internal options.
 59.4648 +     *  No defaults options are set in View.
 59.4649 +     *
 59.4650 +     *  @method setOptions
 59.4651 +     *  @param {Object} options
 59.4652 +     */
 59.4653 +    View.prototype.setOptions = function setOptions(options) {
 59.4654 +        this._optionsManager.patch(options);
 59.4655 +    };
 59.4656 +
 59.4657 +    /**
 59.4658 +     * Add a child renderable to the view.
 59.4659 +     *   Note: This is meant to be used by an inheriting class
 59.4660 +     *   rather than from outside the prototype chain.
 59.4661 +     *
 59.4662 +     * @method add
 59.4663 +     * @return {RenderNode}
 59.4664 +     * @protected
 59.4665 +     */
 59.4666 +    View.prototype.add = function add() {
 59.4667 +        return this._node.add.apply(this._node, arguments);
 59.4668 +    };
 59.4669 +
 59.4670 +    /**
 59.4671 +     * Alias for add
 59.4672 +     * @method _add
 59.4673 +     */
 59.4674 +    View.prototype._add = View.prototype.add;
 59.4675 +
 59.4676 +    /**
 59.4677 +     * Generate a render spec from the contents of this component.
 59.4678 +     *
 59.4679 +     * @private
 59.4680 +     * @method render
 59.4681 +     * @return {number} Render spec for this component
 59.4682 +     */
 59.4683 +    View.prototype.render = function render() {
 59.4684 +        return this._node.render();
 59.4685 +    };
 59.4686 +
 59.4687 +    /**
 59.4688 +     * Return size of contained element.
 59.4689 +     *
 59.4690 +     * @method getSize
 59.4691 +     * @return {Array.Number} [width, height]
 59.4692 +     */
 59.4693 +    View.prototype.getSize = function getSize() {
 59.4694 +        if (this._node && this._node.getSize) {
 59.4695 +            return this._node.getSize.apply(this._node, arguments) || this.options.size;
 59.4696 +        }
 59.4697 +        else return this.options.size;
 59.4698 +    };
 59.4699 +
 59.4700 +    module.exports = View;
 59.4701 +});
 59.4702 +
 59.4703 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.4704 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.4705 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.4706 + *
 59.4707 + * Owner: mark@famo.us
 59.4708 + * @license MPL 2.0
 59.4709 + * @copyright Famous Industries, Inc. 2014
 59.4710 + */
 59.4711 +
 59.4712 +define('famous/core/ViewSequence',['require','exports','module'],function(require, exports, module) {
 59.4713 +
 59.4714 +    /**
 59.4715 +     * Helper object used to iterate through items sequentially. Used in
 59.4716 +     *   views that deal with layout.  A ViewSequence object conceptually points
 59.4717 +     *   to a node in a linked list.
 59.4718 +     *
 59.4719 +     * @class ViewSequence
 59.4720 +     *
 59.4721 +     * @constructor
 59.4722 +     * @param {Object|Array} options Options object, or content array.
 59.4723 +     * @param {Number} [options.index] starting index.
 59.4724 +     * @param {Number} [options.array] Array of elements to populate the ViewSequence
 59.4725 +     * @param {Object} [options._] Optional backing store (internal
 59.4726 +     * @param {Boolean} [options.loop] Whether to wrap when accessing elements just past the end
 59.4727 +     *   (or beginning) of the sequence.
 59.4728 +     */
 59.4729 +    function ViewSequence(options) {
 59.4730 +        if (!options) options = [];
 59.4731 +        if (options instanceof Array) options = {array: options};
 59.4732 +
 59.4733 +        this._ = null;
 59.4734 +        this.index = options.index || 0;
 59.4735 +
 59.4736 +        if (options.array) this._ = new (this.constructor.Backing)(options.array);
 59.4737 +        else if (options._) this._ = options._;
 59.4738 +
 59.4739 +        if (this.index === this._.firstIndex) this._.firstNode = this;
 59.4740 +        if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this;
 59.4741 +
 59.4742 +        if (options.loop !== undefined) this._.loop = options.loop;
 59.4743 +
 59.4744 +        this._previousNode = null;
 59.4745 +        this._nextNode = null;
 59.4746 +    }
 59.4747 +
 59.4748 +    // constructor for internal storage
 59.4749 +    ViewSequence.Backing = function Backing(array) {
 59.4750 +        this.array = array;
 59.4751 +        this.firstIndex = 0;
 59.4752 +        this.loop = false;
 59.4753 +        this.firstNode = null;
 59.4754 +        this.lastNode = null;
 59.4755 +    };
 59.4756 +
 59.4757 +    // Get value "i" slots away from the first index.
 59.4758 +    ViewSequence.Backing.prototype.getValue = function getValue(i) {
 59.4759 +        var _i = i - this.firstIndex;
 59.4760 +        if (_i < 0 || _i >= this.array.length) return null;
 59.4761 +        return this.array[_i];
 59.4762 +    };
 59.4763 +
 59.4764 +    // Set value "i" slots away from the first index.
 59.4765 +    ViewSequence.Backing.prototype.setValue = function setValue(i, value) {
 59.4766 +        this.array[i - this.firstIndex] = value;
 59.4767 +    };
 59.4768 +
 59.4769 +    // After splicing into the backing store, restore the indexes of each node correctly.
 59.4770 +    ViewSequence.Backing.prototype.reindex = function reindex(start, removeCount, insertCount) {
 59.4771 +        if (!this.array[0]) return;
 59.4772 +
 59.4773 +        var i = 0;
 59.4774 +        var index = this.firstIndex;
 59.4775 +        var indexShiftAmount = insertCount - removeCount;
 59.4776 +        var node = this.firstNode;
 59.4777 +
 59.4778 +        // find node to begin
 59.4779 +        while (index < start - 1) {
 59.4780 +            node = node.getNext();
 59.4781 +            index++;
 59.4782 +        }
 59.4783 +        // skip removed nodes
 59.4784 +        var spliceStartNode = node;
 59.4785 +        for (i = 0; i < removeCount; i++) {
 59.4786 +            node = node.getNext();
 59.4787 +            if (node) node._previousNode = spliceStartNode;
 59.4788 +        }
 59.4789 +        var spliceResumeNode = node ? node.getNext() : null;
 59.4790 +        // generate nodes for inserted items
 59.4791 +        spliceStartNode._nextNode = null;
 59.4792 +        node = spliceStartNode;
 59.4793 +        for (i = 0; i < insertCount; i++) node = node.getNext();
 59.4794 +        index += insertCount;
 59.4795 +        // resume the chain
 59.4796 +        if (node !== spliceResumeNode) {
 59.4797 +            node._nextNode = spliceResumeNode;
 59.4798 +            if (spliceResumeNode) spliceResumeNode._previousNode = node;
 59.4799 +        }
 59.4800 +        if (spliceResumeNode) {
 59.4801 +            node = spliceResumeNode;
 59.4802 +            index++;
 59.4803 +            while (node && index < this.array.length + this.firstIndex) {
 59.4804 +                if (node._nextNode) node.index += indexShiftAmount;
 59.4805 +                else node.index = index;
 59.4806 +                node = node.getNext();
 59.4807 +                index++;
 59.4808 +            }
 59.4809 +        }
 59.4810 +    };
 59.4811 +
 59.4812 +    /**
 59.4813 +     * Return ViewSequence node previous to this node in the list, respecting looping if applied.
 59.4814 +     *
 59.4815 +     * @method getPrevious
 59.4816 +     * @return {ViewSequence} previous node.
 59.4817 +     */
 59.4818 +    ViewSequence.prototype.getPrevious = function getPrevious() {
 59.4819 +        if (this.index === this._.firstIndex) {
 59.4820 +            if (this._.loop) {
 59.4821 +                this._previousNode = this._.lastNode || new (this.constructor)({_: this._, index: this._.firstIndex + this._.array.length - 1});
 59.4822 +                this._previousNode._nextNode = this;
 59.4823 +            }
 59.4824 +            else {
 59.4825 +                this._previousNode = null;
 59.4826 +            }
 59.4827 +        }
 59.4828 +        else if (!this._previousNode) {
 59.4829 +            this._previousNode = new (this.constructor)({_: this._, index: this.index - 1});
 59.4830 +            this._previousNode._nextNode = this;
 59.4831 +        }
 59.4832 +        return this._previousNode;
 59.4833 +    };
 59.4834 +
 59.4835 +    /**
 59.4836 +     * Return ViewSequence node next after this node in the list, respecting looping if applied.
 59.4837 +     *
 59.4838 +     * @method getNext
 59.4839 +     * @return {ViewSequence} previous node.
 59.4840 +     */
 59.4841 +    ViewSequence.prototype.getNext = function getNext() {
 59.4842 +        if (this.index === this._.firstIndex + this._.array.length - 1) {
 59.4843 +            if (this._.loop) {
 59.4844 +                this._nextNode = this._.firstNode || new (this.constructor)({_: this._, index: this._.firstIndex});
 59.4845 +                this._nextNode._previousNode = this;
 59.4846 +            }
 59.4847 +            else {
 59.4848 +                this._nextNode = null;
 59.4849 +            }
 59.4850 +        }
 59.4851 +        else if (!this._nextNode) {
 59.4852 +            this._nextNode = new (this.constructor)({_: this._, index: this.index + 1});
 59.4853 +            this._nextNode._previousNode = this;
 59.4854 +        }
 59.4855 +        return this._nextNode;
 59.4856 +    };
 59.4857 +
 59.4858 +    /**
 59.4859 +     * Return index of this ViewSequence node.
 59.4860 +     *
 59.4861 +     * @method getIndex
 59.4862 +     * @return {Number} index
 59.4863 +     */
 59.4864 +    ViewSequence.prototype.getIndex = function getIndex() {
 59.4865 +        return this.index;
 59.4866 +    };
 59.4867 +
 59.4868 +    /**
 59.4869 +     * Return printable version of this ViewSequence node.
 59.4870 +     *
 59.4871 +     * @method toString
 59.4872 +     * @return {string} this index as a string
 59.4873 +     */
 59.4874 +    ViewSequence.prototype.toString = function toString() {
 59.4875 +        return '' + this.index;
 59.4876 +    };
 59.4877 +
 59.4878 +    /**
 59.4879 +     * Add one or more objects to the beginning of the sequence.
 59.4880 +     *
 59.4881 +     * @method unshift
 59.4882 +     * @param {...Object} value arguments array of objects
 59.4883 +     */
 59.4884 +    ViewSequence.prototype.unshift = function unshift(value) {
 59.4885 +        this._.array.unshift.apply(this._.array, arguments);
 59.4886 +        this._.firstIndex -= arguments.length;
 59.4887 +    };
 59.4888 +
 59.4889 +    /**
 59.4890 +     * Add one or more objects to the end of the sequence.
 59.4891 +     *
 59.4892 +     * @method push
 59.4893 +     * @param {...Object} value arguments array of objects
 59.4894 +     */
 59.4895 +    ViewSequence.prototype.push = function push(value) {
 59.4896 +        this._.array.push.apply(this._.array, arguments);
 59.4897 +    };
 59.4898 +
 59.4899 +    /**
 59.4900 +     * Remove objects from the sequence
 59.4901 +     *
 59.4902 +     * @method splice
 59.4903 +     * @param {Number} index starting index for removal
 59.4904 +     * @param {Number} howMany how many elements to remove
 59.4905 +     * @param {...Object} value arguments array of objects
 59.4906 +     */
 59.4907 +    ViewSequence.prototype.splice = function splice(index, howMany) {
 59.4908 +        var values = Array.prototype.slice.call(arguments, 2);
 59.4909 +        this._.array.splice.apply(this._.array, [index - this._.firstIndex, howMany].concat(values));
 59.4910 +        this._.reindex(index, howMany, values.length);
 59.4911 +    };
 59.4912 +
 59.4913 +    /**
 59.4914 +     * Exchange this element's sequence position with another's.
 59.4915 +     *
 59.4916 +     * @method swap
 59.4917 +     * @param {ViewSequence} other element to swap with.
 59.4918 +     */
 59.4919 +    ViewSequence.prototype.swap = function swap(other) {
 59.4920 +        var otherValue = other.get();
 59.4921 +        var myValue = this.get();
 59.4922 +        this._.setValue(this.index, otherValue);
 59.4923 +        this._.setValue(other.index, myValue);
 59.4924 +
 59.4925 +        var myPrevious = this._previousNode;
 59.4926 +        var myNext = this._nextNode;
 59.4927 +        var myIndex = this.index;
 59.4928 +        var otherPrevious = other._previousNode;
 59.4929 +        var otherNext = other._nextNode;
 59.4930 +        var otherIndex = other.index;
 59.4931 +
 59.4932 +        this.index = otherIndex;
 59.4933 +        this._previousNode = (otherPrevious === this) ? other : otherPrevious;
 59.4934 +        if (this._previousNode) this._previousNode._nextNode = this;
 59.4935 +        this._nextNode = (otherNext === this) ? other : otherNext;
 59.4936 +        if (this._nextNode) this._nextNode._previousNode = this;
 59.4937 +
 59.4938 +        other.index = myIndex;
 59.4939 +        other._previousNode = (myPrevious === other) ? this : myPrevious;
 59.4940 +        if (other._previousNode) other._previousNode._nextNode = other;
 59.4941 +        other._nextNode = (myNext === other) ? this : myNext;
 59.4942 +        if (other._nextNode) other._nextNode._previousNode = other;
 59.4943 +
 59.4944 +        if (this.index === this._.firstIndex) this._.firstNode = this;
 59.4945 +        else if (this.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = this;
 59.4946 +        if (other.index === this._.firstIndex) this._.firstNode = other;
 59.4947 +        else if (other.index === this._.firstIndex + this._.array.length - 1) this._.lastNode = other;
 59.4948 +    };
 59.4949 +
 59.4950 +   /**
 59.4951 +     * Return value of this ViewSequence node.
 59.4952 +     *
 59.4953 +     * @method get
 59.4954 +     * @return {Object} value of thiss
 59.4955 +     */
 59.4956 +    ViewSequence.prototype.get = function get() {
 59.4957 +        return this._.getValue(this.index);
 59.4958 +    };
 59.4959 +
 59.4960 +   /**
 59.4961 +     * Call getSize() on the contained View.
 59.4962 +     *
 59.4963 +     * @method getSize
 59.4964 +     * @return {Array.Number} [width, height]
 59.4965 +     */
 59.4966 +    ViewSequence.prototype.getSize = function getSize() {
 59.4967 +        var target = this.get();
 59.4968 +        return target ? target.getSize() : null;
 59.4969 +    };
 59.4970 +
 59.4971 +    /**
 59.4972 +     * Generate a render spec from the contents of this component.
 59.4973 +     * Specifically, this will render the value at the current index.
 59.4974 +     * @private
 59.4975 +     * @method render
 59.4976 +     * @return {number} Render spec for this component
 59.4977 +     */
 59.4978 +    ViewSequence.prototype.render = function render() {
 59.4979 +        var target = this.get();
 59.4980 +        return target ? target.render.apply(target, arguments) : null;
 59.4981 +    };
 59.4982 +
 59.4983 +    module.exports = ViewSequence;
 59.4984 +});
 59.4985 +
 59.4986 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.4987 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.4988 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.4989 + *
 59.4990 + * Owner: mark@famo.us
 59.4991 + * @license MPL 2.0
 59.4992 + * @copyright Famous Industries, Inc. 2014
 59.4993 + */
 59.4994 +
 59.4995 +define('famous/math/Utilities',['require','exports','module'],function(require, exports, module) {
 59.4996 +    /**
 59.4997 +     * A few static methods.
 59.4998 +     *
 59.4999 +     * @class Utilities
 59.5000 +     * @static
 59.5001 +     */
 59.5002 +    var Utilities = {};
 59.5003 +
 59.5004 +    /**
 59.5005 +     * Constrain input to range.
 59.5006 +     *
 59.5007 +     * @method clamp
 59.5008 +     * @param {Number} value input
 59.5009 +     * @param {Array.Number} range [min, max]
 59.5010 +     * @static
 59.5011 +     */
 59.5012 +    Utilities.clamp = function clamp(value, range) {
 59.5013 +        return Math.max(Math.min(value, range[1]), range[0]);
 59.5014 +    };
 59.5015 +
 59.5016 +    /**
 59.5017 +     * Euclidean length of numerical array.
 59.5018 +     *
 59.5019 +     * @method length
 59.5020 +     * @param {Array.Number} array array of numbers
 59.5021 +     * @static
 59.5022 +     */
 59.5023 +    Utilities.length = function length(array) {
 59.5024 +        var distanceSquared = 0;
 59.5025 +        for (var i = 0; i < array.length; i++) {
 59.5026 +            distanceSquared += array[i] * array[i];
 59.5027 +        }
 59.5028 +        return Math.sqrt(distanceSquared);
 59.5029 +    };
 59.5030 +
 59.5031 +    module.exports = Utilities;
 59.5032 +});
 59.5033 +
 59.5034 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.5035 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.5036 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.5037 + *
 59.5038 + * Owner: mark@famo.us
 59.5039 + * @license MPL 2.0
 59.5040 + * @copyright Famous Industries, Inc. 2014
 59.5041 + */
 59.5042 +
 59.5043 +define('famous/inputs/GenericSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.5044 +    var EventHandler = require('famous/core/EventHandler');
 59.5045 +
 59.5046 +    /**
 59.5047 +     * Combines multiple types of sync classes (e.g. mouse, touch,
 59.5048 +     *  scrolling) into one standardized interface for inclusion in widgets.
 59.5049 +     *
 59.5050 +     *  Sync classes are first registered with a key, and then can be accessed
 59.5051 +     *  globally by key.
 59.5052 +     *
 59.5053 +     *  Emits 'start', 'update' and 'end' events as a union of the sync class
 59.5054 +     *  providers.
 59.5055 +     *
 59.5056 +     * @class GenericSync
 59.5057 +     * @constructor
 59.5058 +     * @param syncs {Object|Array} object with fields {sync key : sync options}
 59.5059 +     *    or an array of registered sync keys
 59.5060 +     * @param [options] {Object|Array} options object to set on all syncs
 59.5061 +     */
 59.5062 +    function GenericSync(syncs, options) {
 59.5063 +        this._eventInput = new EventHandler();
 59.5064 +        this._eventOutput = new EventHandler();
 59.5065 +
 59.5066 +        EventHandler.setInputHandler(this, this._eventInput);
 59.5067 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.5068 +
 59.5069 +        this._syncs = {};
 59.5070 +        if (syncs) this.addSync(syncs);
 59.5071 +        if (options) this.setOptions(options);
 59.5072 +    }
 59.5073 +
 59.5074 +    GenericSync.DIRECTION_X = 0;
 59.5075 +    GenericSync.DIRECTION_Y = 1;
 59.5076 +    GenericSync.DIRECTION_Z = 2;
 59.5077 +
 59.5078 +    // Global registry of sync classes. Append only.
 59.5079 +    var registry = {};
 59.5080 +
 59.5081 +    /**
 59.5082 +     * Register a global sync class with an identifying key
 59.5083 +     *
 59.5084 +     * @static
 59.5085 +     * @method register
 59.5086 +     *
 59.5087 +     * @param syncObject {Object} an object of {sync key : sync options} fields
 59.5088 +     */
 59.5089 +    GenericSync.register = function register(syncObject) {
 59.5090 +        for (var key in syncObject){
 59.5091 +            if (registry[key]){
 59.5092 +                if (registry[key] === syncObject[key]) return; // redundant registration
 59.5093 +                else throw new Error('this key is registered to a different sync class');
 59.5094 +            }
 59.5095 +            else registry[key] = syncObject[key];
 59.5096 +        }
 59.5097 +    };
 59.5098 +
 59.5099 +    /**
 59.5100 +     * Helper to set options on all sync instances
 59.5101 +     *
 59.5102 +     * @method setOptions
 59.5103 +     * @param options {Object} options object
 59.5104 +     */
 59.5105 +    GenericSync.prototype.setOptions = function(options) {
 59.5106 +        for (var key in this._syncs){
 59.5107 +            this._syncs[key].setOptions(options);
 59.5108 +        }
 59.5109 +    };
 59.5110 +
 59.5111 +    /**
 59.5112 +     * Pipe events to a sync class
 59.5113 +     *
 59.5114 +     * @method pipeSync
 59.5115 +     * @param key {String} identifier for sync class
 59.5116 +     */
 59.5117 +    GenericSync.prototype.pipeSync = function pipeToSync(key) {
 59.5118 +        var sync = this._syncs[key];
 59.5119 +        this._eventInput.pipe(sync);
 59.5120 +        sync.pipe(this._eventOutput);
 59.5121 +    };
 59.5122 +
 59.5123 +    /**
 59.5124 +     * Unpipe events from a sync class
 59.5125 +     *
 59.5126 +     * @method unpipeSync
 59.5127 +     * @param key {String} identifier for sync class
 59.5128 +     */
 59.5129 +    GenericSync.prototype.unpipeSync = function unpipeFromSync(key) {
 59.5130 +        var sync = this._syncs[key];
 59.5131 +        this._eventInput.unpipe(sync);
 59.5132 +        sync.unpipe(this._eventOutput);
 59.5133 +    };
 59.5134 +
 59.5135 +    function _addSingleSync(key, options) {
 59.5136 +        if (!registry[key]) return;
 59.5137 +        this._syncs[key] = new (registry[key])(options);
 59.5138 +        this.pipeSync(key);
 59.5139 +    }
 59.5140 +
 59.5141 +    /**
 59.5142 +     * Add a sync class to from the registered classes
 59.5143 +     *
 59.5144 +     * @method addSync
 59.5145 +     * @param syncs {Object|Array.String} an array of registered sync keys
 59.5146 +     *    or an object with fields {sync key : sync options}
 59.5147 +     */
 59.5148 +    GenericSync.prototype.addSync = function addSync(syncs) {
 59.5149 +        if (syncs instanceof Array)
 59.5150 +            for (var i = 0; i < syncs.length; i++)
 59.5151 +                _addSingleSync.call(this, syncs[i]);
 59.5152 +        else if (syncs instanceof Object)
 59.5153 +            for (var key in syncs)
 59.5154 +                _addSingleSync.call(this, key, syncs[key]);
 59.5155 +    };
 59.5156 +
 59.5157 +    module.exports = GenericSync;
 59.5158 +});
 59.5159 +
 59.5160 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.5161 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.5162 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.5163 + *
 59.5164 + * Owner: mark@famo.us
 59.5165 + * @license MPL 2.0
 59.5166 + * @copyright Famous Industries, Inc. 2014
 59.5167 + */
 59.5168 +
 59.5169 +define('famous/inputs/MouseSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.5170 +    var EventHandler = require('famous/core/EventHandler');
 59.5171 +
 59.5172 +    /**
 59.5173 +     * Handles piped in mouse drag events. Outputs an object with two
 59.5174 +     *   properties, position and velocity.
 59.5175 +     *   Emits 'start', 'update' and 'end' events with DOM event passthroughs,
 59.5176 +     *   with position, velocity, and a delta key.
 59.5177 +     *
 59.5178 +     * @class MouseSync
 59.5179 +     * @constructor
 59.5180 +     *
 59.5181 +     * @param [options] {Object}             default options overrides
 59.5182 +     * @param [options.direction] {Number}   read from a particular axis
 59.5183 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 59.5184 +     * @param [options.propogate] {Boolean}  add listened to document on mouseleave
 59.5185 +     */
 59.5186 +    function MouseSync(options) {
 59.5187 +        this.options =  Object.create(MouseSync.DEFAULT_OPTIONS);
 59.5188 +        if (options) this.setOptions(options);
 59.5189 +
 59.5190 +        this._eventInput = new EventHandler();
 59.5191 +        this._eventOutput = new EventHandler();
 59.5192 +
 59.5193 +        EventHandler.setInputHandler(this, this._eventInput);
 59.5194 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.5195 +
 59.5196 +        this._eventInput.on('mousedown', _handleStart.bind(this));
 59.5197 +        this._eventInput.on('mousemove', _handleMove.bind(this));
 59.5198 +        this._eventInput.on('mouseup', _handleEnd.bind(this));
 59.5199 +
 59.5200 +        if (this.options.propogate) this._eventInput.on('mouseleave', _handleLeave.bind(this));
 59.5201 +        else this._eventInput.on('mouseleave', _handleEnd.bind(this));
 59.5202 +
 59.5203 +        this._payload = {
 59.5204 +            delta    : null,
 59.5205 +            position : null,
 59.5206 +            velocity : null,
 59.5207 +            clientX  : 0,
 59.5208 +            clientY  : 0,
 59.5209 +            offsetX  : 0,
 59.5210 +            offsetY  : 0
 59.5211 +        };
 59.5212 +
 59.5213 +        this._position = null;      // to be deprecated
 59.5214 +        this._prevCoord = undefined;
 59.5215 +        this._prevTime = undefined;
 59.5216 +        this._down = false;
 59.5217 +        this._moved = false;
 59.5218 +    }
 59.5219 +
 59.5220 +    MouseSync.DEFAULT_OPTIONS = {
 59.5221 +        direction: undefined,
 59.5222 +        rails: false,
 59.5223 +        scale: 1,
 59.5224 +        propogate: true  // events piped to document on mouseleave
 59.5225 +    };
 59.5226 +
 59.5227 +    MouseSync.DIRECTION_X = 0;
 59.5228 +    MouseSync.DIRECTION_Y = 1;
 59.5229 +
 59.5230 +    var MINIMUM_TICK_TIME = 8;
 59.5231 +
 59.5232 +    var _now = Date.now;
 59.5233 +
 59.5234 +    function _handleStart(event) {
 59.5235 +        var delta;
 59.5236 +        var velocity;
 59.5237 +        event.preventDefault(); // prevent drag
 59.5238 +
 59.5239 +        var x = event.clientX;
 59.5240 +        var y = event.clientY;
 59.5241 +
 59.5242 +        this._prevCoord = [x, y];
 59.5243 +        this._prevTime = _now();
 59.5244 +        this._down = true;
 59.5245 +        this._move = false;
 59.5246 +
 59.5247 +        if (this.options.direction !== undefined){
 59.5248 +            this._position = 0;
 59.5249 +            delta = 0;
 59.5250 +            velocity = 0;
 59.5251 +        }
 59.5252 +        else {
 59.5253 +            this._position = [0, 0];
 59.5254 +            delta = [0, 0];
 59.5255 +            velocity = [0, 0];
 59.5256 +        }
 59.5257 +
 59.5258 +        var payload = this._payload;
 59.5259 +        payload.delta = delta;
 59.5260 +        payload.position = this._position;
 59.5261 +        payload.velocity = velocity;
 59.5262 +        payload.clientX = x;
 59.5263 +        payload.clientY = y;
 59.5264 +        payload.offsetX = event.offsetX;
 59.5265 +        payload.offsetY = event.offsetY;
 59.5266 +
 59.5267 +        this._eventOutput.emit('start', payload);
 59.5268 +    }
 59.5269 +
 59.5270 +    function _handleMove(event) {
 59.5271 +        if (!this._prevCoord) return;
 59.5272 +
 59.5273 +        var prevCoord = this._prevCoord;
 59.5274 +        var prevTime = this._prevTime;
 59.5275 +
 59.5276 +        var x = event.clientX;
 59.5277 +        var y = event.clientY;
 59.5278 +
 59.5279 +        var currTime = _now();
 59.5280 +
 59.5281 +        var diffX = x - prevCoord[0];
 59.5282 +        var diffY = y - prevCoord[1];
 59.5283 +
 59.5284 +        if (this.options.rails) {
 59.5285 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 59.5286 +            else diffX = 0;
 59.5287 +        }
 59.5288 +
 59.5289 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time
 59.5290 +
 59.5291 +        var velX = diffX / diffTime;
 59.5292 +        var velY = diffY / diffTime;
 59.5293 +
 59.5294 +        var scale = this.options.scale;
 59.5295 +        var nextVel;
 59.5296 +        var nextDelta;
 59.5297 +
 59.5298 +        if (this.options.direction === MouseSync.DIRECTION_X) {
 59.5299 +            nextDelta = scale * diffX;
 59.5300 +            nextVel = scale * velX;
 59.5301 +            this._position += nextDelta;
 59.5302 +        }
 59.5303 +        else if (this.options.direction === MouseSync.DIRECTION_Y) {
 59.5304 +            nextDelta = scale * diffY;
 59.5305 +            nextVel = scale * velY;
 59.5306 +            this._position += nextDelta;
 59.5307 +        }
 59.5308 +        else {
 59.5309 +            nextDelta = [scale * diffX, scale * diffY];
 59.5310 +            nextVel = [scale * velX, scale * velY];
 59.5311 +            this._position[0] += nextDelta[0];
 59.5312 +            this._position[1] += nextDelta[1];
 59.5313 +        }
 59.5314 +
 59.5315 +        var payload = this._payload;
 59.5316 +        payload.delta    = nextDelta;
 59.5317 +        payload.position = this._position;
 59.5318 +        payload.velocity = nextVel;
 59.5319 +        payload.clientX  = x;
 59.5320 +        payload.clientY  = y;
 59.5321 +        payload.offsetX  = event.offsetX;
 59.5322 +        payload.offsetY  = event.offsetY;
 59.5323 +
 59.5324 +        this._eventOutput.emit('update', payload);
 59.5325 +
 59.5326 +        this._prevCoord = [x, y];
 59.5327 +        this._prevTime = currTime;
 59.5328 +        this._move = true;
 59.5329 +    }
 59.5330 +
 59.5331 +    function _handleEnd(event) {
 59.5332 +        if (!this._down) return;
 59.5333 +
 59.5334 +        this._eventOutput.emit('end', this._payload);
 59.5335 +        this._prevCoord = undefined;
 59.5336 +        this._prevTime = undefined;
 59.5337 +        this._down = false;
 59.5338 +        this._move = false;
 59.5339 +    }
 59.5340 +
 59.5341 +    function _handleLeave(event) {
 59.5342 +        if (!this._down || !this._move) return;
 59.5343 +
 59.5344 +        var boundMove = _handleMove.bind(this);
 59.5345 +        var boundEnd = function(event) {
 59.5346 +            _handleEnd.call(this, event);
 59.5347 +            document.removeEventListener('mousemove', boundMove);
 59.5348 +            document.removeEventListener('mouseup', boundEnd);
 59.5349 +        }.bind(this, event);
 59.5350 +
 59.5351 +        document.addEventListener('mousemove', boundMove);
 59.5352 +        document.addEventListener('mouseup', boundEnd);
 59.5353 +    }
 59.5354 +
 59.5355 +    /**
 59.5356 +     * Return entire options dictionary, including defaults.
 59.5357 +     *
 59.5358 +     * @method getOptions
 59.5359 +     * @return {Object} configuration options
 59.5360 +     */
 59.5361 +    MouseSync.prototype.getOptions = function getOptions() {
 59.5362 +        return this.options;
 59.5363 +    };
 59.5364 +
 59.5365 +    /**
 59.5366 +     * Set internal options, overriding any default options
 59.5367 +     *
 59.5368 +     * @method setOptions
 59.5369 +     *
 59.5370 +     * @param [options] {Object}             default options overrides
 59.5371 +     * @param [options.direction] {Number}   read from a particular axis
 59.5372 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 59.5373 +     * @param [options.propogate] {Boolean}  add listened to document on mouseleave
 59.5374 +     */
 59.5375 +    MouseSync.prototype.setOptions = function setOptions(options) {
 59.5376 +        if (options.direction !== undefined) this.options.direction = options.direction;
 59.5377 +        if (options.rails !== undefined) this.options.rails = options.rails;
 59.5378 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.5379 +        if (options.propogate !== undefined) this.options.propogate = options.propogate;
 59.5380 +    };
 59.5381 +
 59.5382 +    module.exports = MouseSync;
 59.5383 +});
 59.5384 +
 59.5385 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.5386 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.5387 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.5388 + *
 59.5389 + * Owner: mark@famo.us
 59.5390 + * @license MPL 2.0
 59.5391 + * @copyright Famous Industries, Inc. 2014
 59.5392 + */
 59.5393 +
 59.5394 +define('famous/inputs/TouchTracker',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.5395 +    var EventHandler = require('famous/core/EventHandler');
 59.5396 +
 59.5397 +    var _now = Date.now;
 59.5398 +
 59.5399 +    function _timestampTouch(touch, event, history) {
 59.5400 +        return {
 59.5401 +            x: touch.clientX,
 59.5402 +            y: touch.clientY,
 59.5403 +            identifier : touch.identifier,
 59.5404 +            origin: event.origin,
 59.5405 +            timestamp: _now(),
 59.5406 +            count: event.touches.length,
 59.5407 +            history: history
 59.5408 +        };
 59.5409 +    }
 59.5410 +
 59.5411 +    function _handleStart(event) {
 59.5412 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.5413 +            var touch = event.changedTouches[i];
 59.5414 +            var data = _timestampTouch(touch, event, null);
 59.5415 +            this.eventOutput.emit('trackstart', data);
 59.5416 +            if (!this.selective && !this.touchHistory[touch.identifier]) this.track(data);
 59.5417 +        }
 59.5418 +    }
 59.5419 +
 59.5420 +    function _handleMove(event) {
 59.5421 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.5422 +            var touch = event.changedTouches[i];
 59.5423 +            var history = this.touchHistory[touch.identifier];
 59.5424 +            if (history) {
 59.5425 +                var data = _timestampTouch(touch, event, history);
 59.5426 +                this.touchHistory[touch.identifier].push(data);
 59.5427 +                this.eventOutput.emit('trackmove', data);
 59.5428 +            }
 59.5429 +        }
 59.5430 +    }
 59.5431 +
 59.5432 +    function _handleEnd(event) {
 59.5433 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.5434 +            var touch = event.changedTouches[i];
 59.5435 +            var history = this.touchHistory[touch.identifier];
 59.5436 +            if (history) {
 59.5437 +                var data = _timestampTouch(touch, event, history);
 59.5438 +                this.eventOutput.emit('trackend', data);
 59.5439 +                delete this.touchHistory[touch.identifier];
 59.5440 +            }
 59.5441 +        }
 59.5442 +    }
 59.5443 +
 59.5444 +    function _handleUnpipe() {
 59.5445 +        for (var i in this.touchHistory) {
 59.5446 +            var history = this.touchHistory[i];
 59.5447 +            this.eventOutput.emit('trackend', {
 59.5448 +                touch: history[history.length - 1].touch,
 59.5449 +                timestamp: Date.now(),
 59.5450 +                count: 0,
 59.5451 +                history: history
 59.5452 +            });
 59.5453 +            delete this.touchHistory[i];
 59.5454 +        }
 59.5455 +    }
 59.5456 +
 59.5457 +    /**
 59.5458 +     * Helper to TouchSync – tracks piped in touch events, organizes touch
 59.5459 +     *   events by ID, and emits track events back to TouchSync.
 59.5460 +     *   Emits 'trackstart', 'trackmove', and 'trackend' events upstream.
 59.5461 +     *
 59.5462 +     * @class TouchTracker
 59.5463 +     * @constructor
 59.5464 +     * @param {Boolean} selective if false, save state for each touch.
 59.5465 +     */
 59.5466 +    function TouchTracker(selective) {
 59.5467 +        this.selective = selective;
 59.5468 +        this.touchHistory = {};
 59.5469 +
 59.5470 +        this.eventInput = new EventHandler();
 59.5471 +        this.eventOutput = new EventHandler();
 59.5472 +
 59.5473 +        EventHandler.setInputHandler(this, this.eventInput);
 59.5474 +        EventHandler.setOutputHandler(this, this.eventOutput);
 59.5475 +
 59.5476 +        this.eventInput.on('touchstart', _handleStart.bind(this));
 59.5477 +        this.eventInput.on('touchmove', _handleMove.bind(this));
 59.5478 +        this.eventInput.on('touchend', _handleEnd.bind(this));
 59.5479 +        this.eventInput.on('touchcancel', _handleEnd.bind(this));
 59.5480 +        this.eventInput.on('unpipe', _handleUnpipe.bind(this));
 59.5481 +    }
 59.5482 +
 59.5483 +    /**
 59.5484 +     * Record touch data, if selective is false.
 59.5485 +     * @private
 59.5486 +     * @method track
 59.5487 +     * @param {Object} data touch data
 59.5488 +     */
 59.5489 +    TouchTracker.prototype.track = function track(data) {
 59.5490 +        this.touchHistory[data.identifier] = [data];
 59.5491 +    };
 59.5492 +
 59.5493 +    module.exports = TouchTracker;
 59.5494 +});
 59.5495 +
 59.5496 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.5497 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.5498 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.5499 + *
 59.5500 + * Owner: mark@famo.us
 59.5501 + * @license MPL 2.0
 59.5502 + * @copyright Famous Industries, Inc. 2014
 59.5503 + */
 59.5504 +
 59.5505 +define('famous/inputs/TouchSync',['require','exports','module','./TouchTracker','famous/core/EventHandler'],function(require, exports, module) {
 59.5506 +    var TouchTracker = require('./TouchTracker');
 59.5507 +    var EventHandler = require('famous/core/EventHandler');
 59.5508 +
 59.5509 +    /**
 59.5510 +     * Handles piped in touch events. Emits 'start', 'update', and 'events'
 59.5511 +     *   events with position, velocity, acceleration, and touch id.
 59.5512 +     *   Useful for dealing with inputs on touch devices.
 59.5513 +     *
 59.5514 +     *
 59.5515 +     * @class TouchSync
 59.5516 +     * @constructor
 59.5517 +     *
 59.5518 +     * @param [options] {Object}             default options overrides
 59.5519 +     * @param [options.direction] {Number}   read from a particular axis
 59.5520 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 59.5521 +     * @param [options.scale] {Number}       constant factor to scale velocity output
 59.5522 +     */
 59.5523 +    function TouchSync(options) {
 59.5524 +        this.options =  Object.create(TouchSync.DEFAULT_OPTIONS);
 59.5525 +        if (options) this.setOptions(options);
 59.5526 +
 59.5527 +        this._eventOutput = new EventHandler();
 59.5528 +        this._touchTracker = new TouchTracker();
 59.5529 +
 59.5530 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.5531 +        EventHandler.setInputHandler(this, this._touchTracker);
 59.5532 +
 59.5533 +        this._touchTracker.on('trackstart', _handleStart.bind(this));
 59.5534 +        this._touchTracker.on('trackmove', _handleMove.bind(this));
 59.5535 +        this._touchTracker.on('trackend', _handleEnd.bind(this));
 59.5536 +
 59.5537 +        this._payload = {
 59.5538 +            delta    : null,
 59.5539 +            position : null,
 59.5540 +            velocity : null,
 59.5541 +            clientX  : undefined,
 59.5542 +            clientY  : undefined,
 59.5543 +            count    : 0,
 59.5544 +            touch    : undefined
 59.5545 +        };
 59.5546 +
 59.5547 +        this._position = null; // to be deprecated
 59.5548 +    }
 59.5549 +
 59.5550 +    TouchSync.DEFAULT_OPTIONS = {
 59.5551 +        direction: undefined,
 59.5552 +        rails: false,
 59.5553 +        scale: 1
 59.5554 +    };
 59.5555 +
 59.5556 +    TouchSync.DIRECTION_X = 0;
 59.5557 +    TouchSync.DIRECTION_Y = 1;
 59.5558 +
 59.5559 +    var MINIMUM_TICK_TIME = 8;
 59.5560 +
 59.5561 +    // handle 'trackstart'
 59.5562 +    function _handleStart(data) {
 59.5563 +        var velocity;
 59.5564 +        var delta;
 59.5565 +        if (this.options.direction !== undefined){
 59.5566 +            this._position = 0;
 59.5567 +            velocity = 0;
 59.5568 +            delta = 0;
 59.5569 +        }
 59.5570 +        else {
 59.5571 +            this._position = [0, 0];
 59.5572 +            velocity = [0, 0];
 59.5573 +            delta = [0, 0];
 59.5574 +        }
 59.5575 +
 59.5576 +        var payload = this._payload;
 59.5577 +        payload.delta = delta;
 59.5578 +        payload.position = this._position;
 59.5579 +        payload.velocity = velocity;
 59.5580 +        payload.clientX = data.x;
 59.5581 +        payload.clientY = data.y;
 59.5582 +        payload.count = data.count;
 59.5583 +        payload.touch = data.identifier;
 59.5584 +
 59.5585 +        this._eventOutput.emit('start', payload);
 59.5586 +    }
 59.5587 +
 59.5588 +    // handle 'trackmove'
 59.5589 +    function _handleMove(data) {
 59.5590 +        var history = data.history;
 59.5591 +
 59.5592 +        var currHistory = history[history.length - 1];
 59.5593 +        var prevHistory = history[history.length - 2];
 59.5594 +
 59.5595 +        var prevTime = prevHistory.timestamp;
 59.5596 +        var currTime = currHistory.timestamp;
 59.5597 +
 59.5598 +        var diffX = currHistory.x - prevHistory.x;
 59.5599 +        var diffY = currHistory.y - prevHistory.y;
 59.5600 +
 59.5601 +        if (this.options.rails) {
 59.5602 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 59.5603 +            else diffX = 0;
 59.5604 +        }
 59.5605 +
 59.5606 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME);
 59.5607 +
 59.5608 +        var velX = diffX / diffTime;
 59.5609 +        var velY = diffY / diffTime;
 59.5610 +
 59.5611 +        var scale = this.options.scale;
 59.5612 +        var nextVel;
 59.5613 +        var nextDelta;
 59.5614 +
 59.5615 +        if (this.options.direction === TouchSync.DIRECTION_X) {
 59.5616 +            nextDelta = scale * diffX;
 59.5617 +            nextVel = scale * velX;
 59.5618 +            this._position += nextDelta;
 59.5619 +        }
 59.5620 +        else if (this.options.direction === TouchSync.DIRECTION_Y) {
 59.5621 +            nextDelta = scale * diffY;
 59.5622 +            nextVel = scale * velY;
 59.5623 +            this._position += nextDelta;
 59.5624 +        }
 59.5625 +        else {
 59.5626 +            nextDelta = [scale * diffX, scale * diffY];
 59.5627 +            nextVel = [scale * velX, scale * velY];
 59.5628 +            this._position[0] += nextDelta[0];
 59.5629 +            this._position[1] += nextDelta[1];
 59.5630 +        }
 59.5631 +
 59.5632 +        var payload = this._payload;
 59.5633 +        payload.delta    = nextDelta;
 59.5634 +        payload.velocity = nextVel;
 59.5635 +        payload.position = this._position;
 59.5636 +        payload.clientX  = data.x;
 59.5637 +        payload.clientY  = data.y;
 59.5638 +        payload.count    = data.count;
 59.5639 +        payload.touch    = data.identifier;
 59.5640 +
 59.5641 +        this._eventOutput.emit('update', payload);
 59.5642 +    }
 59.5643 +
 59.5644 +    // handle 'trackend'
 59.5645 +    function _handleEnd(data) {
 59.5646 +        this._payload.count = data.count;
 59.5647 +        this._eventOutput.emit('end', this._payload);
 59.5648 +    }
 59.5649 +
 59.5650 +    /**
 59.5651 +     * Set internal options, overriding any default options
 59.5652 +     *
 59.5653 +     * @method setOptions
 59.5654 +     *
 59.5655 +     * @param [options] {Object}             default options overrides
 59.5656 +     * @param [options.direction] {Number}   read from a particular axis
 59.5657 +     * @param [options.rails] {Boolean}      read from axis with greatest differential
 59.5658 +     * @param [options.scale] {Number}       constant factor to scale velocity output
 59.5659 +     */
 59.5660 +    TouchSync.prototype.setOptions = function setOptions(options) {
 59.5661 +        if (options.direction !== undefined) this.options.direction = options.direction;
 59.5662 +        if (options.rails !== undefined) this.options.rails = options.rails;
 59.5663 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.5664 +    };
 59.5665 +
 59.5666 +    /**
 59.5667 +     * Return entire options dictionary, including defaults.
 59.5668 +     *
 59.5669 +     * @method getOptions
 59.5670 +     * @return {Object} configuration options
 59.5671 +     */
 59.5672 +    TouchSync.prototype.getOptions = function getOptions() {
 59.5673 +        return this.options;
 59.5674 +    };
 59.5675 +
 59.5676 +    module.exports = TouchSync;
 59.5677 +});
 59.5678 +
 59.5679 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.5680 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.5681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.5682 + *
 59.5683 + * Owner: david@famo.us
 59.5684 + * @license MPL 2.0
 59.5685 + * @copyright Famous Industries, Inc. 2014
 59.5686 + */
 59.5687 +
 59.5688 +define('famous/modifiers/Draggable',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/EventHandler','famous/math/Utilities','famous/inputs/GenericSync','famous/inputs/MouseSync','famous/inputs/TouchSync'],function(require, exports, module) {
 59.5689 +    var Transform = require('famous/core/Transform');
 59.5690 +    var Transitionable = require('famous/transitions/Transitionable');
 59.5691 +    var EventHandler = require('famous/core/EventHandler');
 59.5692 +    var Utilities = require('famous/math/Utilities');
 59.5693 +
 59.5694 +    var GenericSync = require('famous/inputs/GenericSync');
 59.5695 +    var MouseSync = require('famous/inputs/MouseSync');
 59.5696 +    var TouchSync = require('famous/inputs/TouchSync');
 59.5697 +    GenericSync.register({'mouse': MouseSync, 'touch': TouchSync});
 59.5698 +
 59.5699 +    /**
 59.5700 +     * Makes added render nodes responsive to drag beahvior.
 59.5701 +     *   Emits events 'start', 'update', 'end'.
 59.5702 +     * @class Draggable
 59.5703 +     * @constructor
 59.5704 +     * @param {Object} [options] options configuration object.
 59.5705 +     * @param {Number} [options.snapX] grid width for snapping during drag
 59.5706 +     * @param {Number} [options.snapY] grid height for snapping during drag
 59.5707 +     * @param {Array.Number} [options.xRange] maxmimum [negative, positive] x displacement from start of drag
 59.5708 +     * @param {Array.Number} [options.yRange] maxmimum [negative, positive] y displacement from start of drag
 59.5709 +     * @param {Number} [options.scale] one pixel of input motion translates to this many pixels of output drag motion
 59.5710 +     * @param {Number} [options.projection] User should set to Draggable._direction.x or
 59.5711 +     *    Draggable._direction.y to constrain to one axis.
 59.5712 +     *
 59.5713 +     */
 59.5714 +    function Draggable(options) {
 59.5715 +        this.options = Object.create(Draggable.DEFAULT_OPTIONS);
 59.5716 +        if (options) this.setOptions(options);
 59.5717 +
 59.5718 +        this._positionState = new Transitionable([0,0]);
 59.5719 +        this._differential  = [0,0];
 59.5720 +        this._active = true;
 59.5721 +
 59.5722 +        this.sync = new GenericSync(['mouse', 'touch'], {scale : this.options.scale});
 59.5723 +        this.eventOutput = new EventHandler();
 59.5724 +        EventHandler.setInputHandler(this,  this.sync);
 59.5725 +        EventHandler.setOutputHandler(this, this.eventOutput);
 59.5726 +
 59.5727 +        _bindEvents.call(this);
 59.5728 +    }
 59.5729 +
 59.5730 +    //binary representation of directions for bitwise operations
 59.5731 +    var _direction = {
 59.5732 +        x : 0x01,         //001
 59.5733 +        y : 0x02          //010
 59.5734 +    };
 59.5735 +
 59.5736 +    Draggable.DIRECTION_X = _direction.x;
 59.5737 +    Draggable.DIRECTION_Y = _direction.y;
 59.5738 +
 59.5739 +    var _clamp = Utilities.clamp;
 59.5740 +
 59.5741 +    Draggable.DEFAULT_OPTIONS = {
 59.5742 +        projection  : _direction.x | _direction.y,
 59.5743 +        scale       : 1,
 59.5744 +        xRange      : null,
 59.5745 +        yRange      : null,
 59.5746 +        snapX       : 0,
 59.5747 +        snapY       : 0,
 59.5748 +        transition  : {duration : 0}
 59.5749 +    };
 59.5750 +
 59.5751 +    function _mapDifferential(differential) {
 59.5752 +        var opts        = this.options;
 59.5753 +        var projection  = opts.projection;
 59.5754 +        var snapX       = opts.snapX;
 59.5755 +        var snapY       = opts.snapY;
 59.5756 +
 59.5757 +        //axes
 59.5758 +        var tx = (projection & _direction.x) ? differential[0] : 0;
 59.5759 +        var ty = (projection & _direction.y) ? differential[1] : 0;
 59.5760 +
 59.5761 +        //snapping
 59.5762 +        if (snapX > 0) tx -= tx % snapX;
 59.5763 +        if (snapY > 0) ty -= ty % snapY;
 59.5764 +
 59.5765 +        return [tx, ty];
 59.5766 +    }
 59.5767 +
 59.5768 +    function _handleStart() {
 59.5769 +        if (!this._active) return;
 59.5770 +        if (this._positionState.isActive()) this._positionState.halt();
 59.5771 +        this.eventOutput.emit('start', {position : this.getPosition()});
 59.5772 +    }
 59.5773 +
 59.5774 +    function _handleMove(event) {
 59.5775 +        if (!this._active) return;
 59.5776 +
 59.5777 +        var options = this.options;
 59.5778 +        this._differential = event.position;
 59.5779 +        var newDifferential = _mapDifferential.call(this, this._differential);
 59.5780 +
 59.5781 +        //buffer the differential if snapping is set
 59.5782 +        this._differential[0] -= newDifferential[0];
 59.5783 +        this._differential[1] -= newDifferential[1];
 59.5784 +
 59.5785 +        var pos = this.getPosition();
 59.5786 +
 59.5787 +        //modify position, retain reference
 59.5788 +        pos[0] += newDifferential[0];
 59.5789 +        pos[1] += newDifferential[1];
 59.5790 +
 59.5791 +        //handle bounding box
 59.5792 +        if (options.xRange){
 59.5793 +            var xRange = [options.xRange[0] + 0.5 * options.snapX, options.xRange[1] - 0.5 * options.snapX];
 59.5794 +            pos[0] = _clamp(pos[0], xRange);
 59.5795 +        }
 59.5796 +
 59.5797 +        if (options.yRange){
 59.5798 +            var yRange = [options.yRange[0] + 0.5 * options.snapY, options.yRange[1] - 0.5 * options.snapY];
 59.5799 +            pos[1] = _clamp(pos[1], yRange);
 59.5800 +        }
 59.5801 +
 59.5802 +        this.eventOutput.emit('update', {position : pos});
 59.5803 +    }
 59.5804 +
 59.5805 +    function _handleEnd() {
 59.5806 +        if (!this._active) return;
 59.5807 +        this.eventOutput.emit('end', {position : this.getPosition()});
 59.5808 +    }
 59.5809 +
 59.5810 +    function _bindEvents() {
 59.5811 +        this.sync.on('start', _handleStart.bind(this));
 59.5812 +        this.sync.on('update', _handleMove.bind(this));
 59.5813 +        this.sync.on('end', _handleEnd.bind(this));
 59.5814 +    }
 59.5815 +
 59.5816 +    /**
 59.5817 +     * Set internal options, overriding any default options
 59.5818 +     *
 59.5819 +     * @method setOptions
 59.5820 +     *
 59.5821 +     * @param {Object} [options] overrides of default options.  See constructor.
 59.5822 +     */
 59.5823 +    Draggable.prototype.setOptions = function setOptions(options) {
 59.5824 +        var currentOptions = this.options;
 59.5825 +        if (options.projection !== undefined) {
 59.5826 +            var proj = options.projection;
 59.5827 +            this.options.projection = 0;
 59.5828 +            ['x', 'y'].forEach(function(val) {
 59.5829 +                if (proj.indexOf(val) !== -1) currentOptions.projection |= _direction[val];
 59.5830 +            });
 59.5831 +        }
 59.5832 +        if (options.scale  !== undefined) {
 59.5833 +            currentOptions.scale  = options.scale;
 59.5834 +            this.sync.setOptions({
 59.5835 +                scale: options.scale
 59.5836 +            });
 59.5837 +        }
 59.5838 +        if (options.xRange !== undefined) currentOptions.xRange = options.xRange;
 59.5839 +        if (options.yRange !== undefined) currentOptions.yRange = options.yRange;
 59.5840 +        if (options.snapX  !== undefined) currentOptions.snapX  = options.snapX;
 59.5841 +        if (options.snapY  !== undefined) currentOptions.snapY  = options.snapY;
 59.5842 +    };
 59.5843 +
 59.5844 +    /**
 59.5845 +     * Get current delta in position from where this draggable started.
 59.5846 +     *
 59.5847 +     * @method getPosition
 59.5848 +     *
 59.5849 +     * @return {array<number>} [x, y] position delta from start.
 59.5850 +     */
 59.5851 +    Draggable.prototype.getPosition = function getPosition() {
 59.5852 +        return this._positionState.get();
 59.5853 +    };
 59.5854 +
 59.5855 +    /**
 59.5856 +     * Transition the element to the desired relative position via provided transition.
 59.5857 +     *  For example, calling this with [0,0] will not change the position.
 59.5858 +     *  Callback will be executed on completion.
 59.5859 +     *
 59.5860 +     * @method setRelativePosition
 59.5861 +     *
 59.5862 +     * @param {array<number>} position end state to which we interpolate
 59.5863 +     * @param {transition} transition transition object specifying how object moves to new position
 59.5864 +     * @param {function} callback zero-argument function to call on observed completion
 59.5865 +     */
 59.5866 +    Draggable.prototype.setRelativePosition = function setRelativePosition(position, transition, callback) {
 59.5867 +        var currPos = this.getPosition();
 59.5868 +        var relativePosition = [currPos[0] + position[0], currPos[1] + position[1]];
 59.5869 +        this.setPosition(relativePosition, transition, callback);
 59.5870 +    };
 59.5871 +
 59.5872 +    /**
 59.5873 +     * Transition the element to the desired absolute position via provided transition.
 59.5874 +     *  Callback will be executed on completion.
 59.5875 +     *
 59.5876 +     * @method setPosition
 59.5877 +     *
 59.5878 +     * @param {array<number>} position end state to which we interpolate
 59.5879 +     * @param {transition} transition transition object specifying how object moves to new position
 59.5880 +     * @param {function} callback zero-argument function to call on observed completion
 59.5881 +     */
 59.5882 +    Draggable.prototype.setPosition = function setPosition(position, transition, callback) {
 59.5883 +        if (this._positionState.isActive()) this._positionState.halt();
 59.5884 +        this._positionState.set(position, transition, callback);
 59.5885 +    };
 59.5886 +
 59.5887 +    /**
 59.5888 +     * Set this draggable to respond to user input.
 59.5889 +     *
 59.5890 +     * @method activate
 59.5891 +     *
 59.5892 +     */
 59.5893 +    Draggable.prototype.activate = function activate() {
 59.5894 +        this._active = true;
 59.5895 +    };
 59.5896 +
 59.5897 +    /**
 59.5898 +     * Set this draggable to ignore user input.
 59.5899 +     *
 59.5900 +     * @method deactivate
 59.5901 +     *
 59.5902 +     */
 59.5903 +    Draggable.prototype.deactivate = function deactivate() {
 59.5904 +        this._active = false;
 59.5905 +    };
 59.5906 +
 59.5907 +    /**
 59.5908 +     * Switch the input response stage between active and inactive.
 59.5909 +     *
 59.5910 +     * @method toggle
 59.5911 +     *
 59.5912 +     */
 59.5913 +    Draggable.prototype.toggle = function toggle() {
 59.5914 +        this._active = !this._active;
 59.5915 +    };
 59.5916 +
 59.5917 +    /**
 59.5918 +     * Return render spec for this Modifier, applying to the provided
 59.5919 +     *    target component.  This is similar to render() for Surfaces.
 59.5920 +     *
 59.5921 +     * @private
 59.5922 +     * @method modify
 59.5923 +     *
 59.5924 +     * @param {Object} target (already rendered) render spec to
 59.5925 +     *    which to apply the transform.
 59.5926 +     * @return {Object} render spec for this Modifier, including the
 59.5927 +     *    provided target
 59.5928 +     */
 59.5929 +    Draggable.prototype.modify = function modify(target) {
 59.5930 +        var pos = this.getPosition();
 59.5931 +        return {
 59.5932 +            transform: Transform.translate(pos[0], pos[1]),
 59.5933 +            target: target
 59.5934 +        };
 59.5935 +    };
 59.5936 +
 59.5937 +    module.exports = Draggable;
 59.5938 +});
 59.5939 +
 59.5940 +define('famous/modifiers/Fader',['require','exports','module','famous/transitions/Transitionable','famous/core/OptionsManager'],function(require, exports, module) {
 59.5941 +    var Transitionable = require('famous/transitions/Transitionable');
 59.5942 +    var OptionsManager = require('famous/core/OptionsManager');
 59.5943 +
 59.5944 +    /**
 59.5945 +     * Modifier that allows you to fade the opacity of affected renderables in and out.
 59.5946 +     * @class Fader
 59.5947 +     * @constructor
 59.5948 +     * @param {Object} [options] options configuration object.
 59.5949 +     * @param {Boolean} [options.cull=false] Stops returning affected renderables up the tree when they're fully faded when true.
 59.5950 +     * @param {Transition} [options.transition=true] The main transition for showing and hiding.
 59.5951 +     * @param {Transition} [options.pulseInTransition=true] Controls the transition to a pulsed state when the Fader instance's pulse
 59.5952 +     * method is called.
 59.5953 +     * @param {Transition} [options.pulseOutTransition=true]Controls the transition back from a pulsed state when the Fader instance's pulse
 59.5954 +     * method is called.
 59.5955 +     *
 59.5956 +     */
 59.5957 +    function Fader(options, startState) {
 59.5958 +        this.options = Object.create(Fader.DEFAULT_OPTIONS);
 59.5959 +        this._optionsManager = new OptionsManager(this.options);
 59.5960 +
 59.5961 +        if (options) this.setOptions(options);
 59.5962 +
 59.5963 +        if (!startState) startState = 0;
 59.5964 +        this.transitionHelper = new Transitionable(startState);
 59.5965 +    }
 59.5966 +
 59.5967 +    Fader.DEFAULT_OPTIONS = {
 59.5968 +        cull: false,
 59.5969 +        transition: true,
 59.5970 +        pulseInTransition: true,
 59.5971 +        pulseOutTransition: true
 59.5972 +    };
 59.5973 +
 59.5974 +    /**
 59.5975 +     * Set internal options, overriding any default options
 59.5976 +     *
 59.5977 +     * @method setOptions
 59.5978 +     *
 59.5979 +     * @param {Object} [options] overrides of default options.  See constructor.
 59.5980 +     */
 59.5981 +    Fader.prototype.setOptions = function setOptions(options) {
 59.5982 +        return this._optionsManager.setOptions(options);
 59.5983 +    };
 59.5984 +
 59.5985 +    /**
 59.5986 +     * Fully displays the Fader instance's associated renderables.
 59.5987 +     *
 59.5988 +     * @method show
 59.5989 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 59.5990 +     * @param {Function} [callback] A callback that executes once you've transitioned to the fully shown state.
 59.5991 +     */
 59.5992 +    Fader.prototype.show = function show(transition, callback) {
 59.5993 +        transition = transition || this.options.transition;
 59.5994 +        this.set(1, transition, callback);
 59.5995 +    };
 59.5996 +
 59.5997 +    /**
 59.5998 +     * Fully fades the Fader instance's associated renderables.
 59.5999 +     *
 59.6000 +     * @method hide
 59.6001 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 59.6002 +     * @param {Function} [callback] A callback that executes once you've transitioned to the fully faded state.
 59.6003 +     */
 59.6004 +    Fader.prototype.hide = function hide(transition, callback) {
 59.6005 +        transition = transition || this.options.transition;
 59.6006 +        this.set(0, transition, callback);
 59.6007 +    };
 59.6008 +
 59.6009 +    /**
 59.6010 +     * Manually sets the opacity state of the fader to the passed-in one. Executes with an optional
 59.6011 +     * transition and callback.
 59.6012 +     *
 59.6013 +     * @method set
 59.6014 +     * @param {Number} state A number from zero to one: the amount of opacity you want to set to.
 59.6015 +     * @param {Transition} [transition] The transition that coordinates setting to the new state.
 59.6016 +     * @param {Function} [callback] A callback that executes once you've finished executing the pulse.
 59.6017 +     */
 59.6018 +    Fader.prototype.set = function set(state, transition, callback) {
 59.6019 +        this.halt();
 59.6020 +        this.transitionHelper.set(state, transition, callback);
 59.6021 +    };
 59.6022 +
 59.6023 +    /**
 59.6024 +     * Halt the transition
 59.6025 +     *
 59.6026 +     * @method halt
 59.6027 +     */
 59.6028 +    Fader.prototype.halt = function halt() {
 59.6029 +        this.transitionHelper.halt();
 59.6030 +    };
 59.6031 +
 59.6032 +    /**
 59.6033 +     * Tells you if your Fader instance is above its visibility threshold.
 59.6034 +     *
 59.6035 +     * @method isVisible
 59.6036 +     * @return {Boolean} Whether or not your Fader instance is visible.
 59.6037 +     */
 59.6038 +    Fader.prototype.isVisible = function isVisible() {
 59.6039 +        return (this.transitionHelper.get() > 0);
 59.6040 +    };
 59.6041 +
 59.6042 +    /**
 59.6043 +     * Return render spec for this Modifier, applying to the provided
 59.6044 +     *    target component.  This is similar to render() for Surfaces.
 59.6045 +     *
 59.6046 +     * @private
 59.6047 +     * @method modify
 59.6048 +     *
 59.6049 +     * @param {Object} target (already rendered) render spec to
 59.6050 +     *    which to apply the transform.
 59.6051 +     * @return {Object} render spec for this Modifier, including the
 59.6052 +     *    provided target
 59.6053 +     */
 59.6054 +    Fader.prototype.modify = function modify(target) {
 59.6055 +        var currOpacity = this.transitionHelper.get();
 59.6056 +        if (this.options.cull && !currOpacity) return undefined;
 59.6057 +        else return {opacity: currOpacity, target: target};
 59.6058 +    };
 59.6059 +
 59.6060 +    module.exports = Fader;
 59.6061 +});
 59.6062 +
 59.6063 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.6064 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.6065 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.6066 + *
 59.6067 + * Owner: david@famo.us
 59.6068 + * @license MPL 2.0
 59.6069 + * @copyright Famous Industries, Inc. 2014
 59.6070 + */
 59.6071 +
 59.6072 +define('famous/modifiers/ModifierChain',['require','exports','module'],function(require, exports, module) {
 59.6073 +
 59.6074 +    /**
 59.6075 +     * A class to add and remove a chain of modifiers
 59.6076 +     *   at a single point in the render tree
 59.6077 +     *
 59.6078 +     * @class ModifierChain
 59.6079 +     * @constructor
 59.6080 +     */
 59.6081 +    function ModifierChain() {
 59.6082 +        this._chain = [];
 59.6083 +        if (arguments.length) this.addModifier.apply(this, arguments);
 59.6084 +    }
 59.6085 +
 59.6086 +    /**
 59.6087 +     * Add a modifier, or comma separated modifiers, to the modifier chain.
 59.6088 +     *
 59.6089 +     * @method addModifier
 59.6090 +     *
 59.6091 +     * @param {...Modifier*} varargs args list of Modifiers
 59.6092 +     */
 59.6093 +    ModifierChain.prototype.addModifier = function addModifier(varargs) {
 59.6094 +        Array.prototype.push.apply(this._chain, arguments);
 59.6095 +    };
 59.6096 +
 59.6097 +    /**
 59.6098 +     * Remove a modifier from the modifier chain.
 59.6099 +     *
 59.6100 +     * @method removeModifier
 59.6101 +     *
 59.6102 +     * @param {Modifier} modifier
 59.6103 +     */
 59.6104 +    ModifierChain.prototype.removeModifier = function removeModifier(modifier) {
 59.6105 +        var index = this._chain.indexOf(modifier);
 59.6106 +        if (index < 0) return;
 59.6107 +        this._chain.splice(index, 1);
 59.6108 +    };
 59.6109 +
 59.6110 +    /**
 59.6111 +     * Return render spec for this Modifier, applying to the provided
 59.6112 +     *    target component.  This is similar to render() for Surfaces.
 59.6113 +     *
 59.6114 +     * @private
 59.6115 +     * @method modify
 59.6116 +     *
 59.6117 +     * @param {Object} input (already rendered) render spec to
 59.6118 +     *    which to apply the transform.
 59.6119 +     * @return {Object} render spec for this Modifier, including the
 59.6120 +     *    provided target
 59.6121 +     */
 59.6122 +    ModifierChain.prototype.modify = function modify(input) {
 59.6123 +        var chain  = this._chain;
 59.6124 +        var result = input;
 59.6125 +        for (var i = 0; i < chain.length; i++) {
 59.6126 +            result = chain[i].modify(result);
 59.6127 +        }
 59.6128 +        return result;
 59.6129 +    };
 59.6130 +
 59.6131 +    module.exports = ModifierChain;
 59.6132 +});
 59.6133 +
 59.6134 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.6135 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.6136 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.6137 + *
 59.6138 + * Owner: mark@famo.us
 59.6139 + * @license MPL 2.0
 59.6140 + * @copyright Famous Industries, Inc. 2014
 59.6141 + */
 59.6142 +
 59.6143 +define('famous/modifiers/StateModifier',['require','exports','module','famous/core/Modifier','famous/core/Transform','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
 59.6144 +    var Modifier = require('famous/core/Modifier');
 59.6145 +    var Transform = require('famous/core/Transform');
 59.6146 +    var Transitionable = require('famous/transitions/Transitionable');
 59.6147 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
 59.6148 +
 59.6149 +    /**
 59.6150 +     *  A collection of visual changes to be
 59.6151 +     *    applied to another renderable component, strongly coupled with the state that defines
 59.6152 +     *    those changes. This collection includes a
 59.6153 +     *    transform matrix, an opacity constant, a size, an origin specifier, and an alignment specifier.
 59.6154 +     *    StateModifier objects can be added to any RenderNode or object
 59.6155 +     *    capable of displaying renderables.  The StateModifier's children and descendants
 59.6156 +     *    are transformed by the amounts specified in the modifier's properties.
 59.6157 +     *
 59.6158 +     * @class StateModifier
 59.6159 +     * @constructor
 59.6160 +     * @param {Object} [options] overrides of default options
 59.6161 +     * @param {Transform} [options.transform] affine transformation matrix
 59.6162 +     * @param {Number} [options.opacity]
 59.6163 +     * @param {Array.Number} [options.origin] origin adjustment
 59.6164 +     * @param {Array.Number} [options.align] align adjustment
 59.6165 +     * @param {Array.Number} [options.size] size to apply to descendants
 59.6166 +     */
 59.6167 +    function StateModifier(options) {
 59.6168 +        this._transformState = new TransitionableTransform(Transform.identity);
 59.6169 +        this._opacityState = new Transitionable(1);
 59.6170 +        this._originState = new Transitionable([0, 0]);
 59.6171 +        this._alignState = new Transitionable([0, 0]);
 59.6172 +        this._sizeState = new Transitionable([0, 0]);
 59.6173 +
 59.6174 +        this._modifier = new Modifier({
 59.6175 +            transform: this._transformState,
 59.6176 +            opacity: this._opacityState,
 59.6177 +            origin: null,
 59.6178 +            align: null,
 59.6179 +            size: null
 59.6180 +        });
 59.6181 +
 59.6182 +        this._hasOrigin = false;
 59.6183 +        this._hasAlign = false;
 59.6184 +        this._hasSize = false;
 59.6185 +
 59.6186 +        if (options) {
 59.6187 +            if (options.transform) this.setTransform(options.transform);
 59.6188 +            if (options.opacity !== undefined) this.setOpacity(options.opacity);
 59.6189 +            if (options.origin) this.setOrigin(options.origin);
 59.6190 +            if (options.align) this.setAlign(options.align);
 59.6191 +            if (options.size) this.setSize(options.size);
 59.6192 +        }
 59.6193 +    }
 59.6194 +
 59.6195 +    /**
 59.6196 +     * Set the transform matrix of this modifier, either statically or
 59.6197 +     *   through a provided Transitionable.
 59.6198 +     *
 59.6199 +     * @method setTransform
 59.6200 +     *
 59.6201 +     * @param {Transform} transform Transform to transition to.
 59.6202 +     * @param {Transitionable} [transition] Valid transitionable object
 59.6203 +     * @param {Function} [callback] callback to call after transition completes
 59.6204 +     * @return {StateModifier} this
 59.6205 +     */
 59.6206 +    StateModifier.prototype.setTransform = function setTransform(transform, transition, callback) {
 59.6207 +        this._transformState.set(transform, transition, callback);
 59.6208 +        return this;
 59.6209 +    };
 59.6210 +
 59.6211 +    /**
 59.6212 +     * Set the opacity of this modifier, either statically or
 59.6213 +     *   through a provided Transitionable.
 59.6214 +     *
 59.6215 +     * @method setOpacity
 59.6216 +     *
 59.6217 +     * @param {Number} opacity Opacity value to transition to.
 59.6218 +     * @param {Transitionable} transition Valid transitionable object
 59.6219 +     * @param {Function} callback callback to call after transition completes
 59.6220 +     * @return {StateModifier} this
 59.6221 +     */
 59.6222 +    StateModifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) {
 59.6223 +        this._opacityState.set(opacity, transition, callback);
 59.6224 +        return this;
 59.6225 +    };
 59.6226 +
 59.6227 +    /**
 59.6228 +     * Set the origin of this modifier, either statically or
 59.6229 +     *   through a provided Transitionable.
 59.6230 +     *
 59.6231 +     * @method setOrigin
 59.6232 +     *
 59.6233 +     * @param {Array.Number} origin two element array with values between 0 and 1.
 59.6234 +     * @param {Transitionable} transition Valid transitionable object
 59.6235 +     * @param {Function} callback callback to call after transition completes
 59.6236 +     * @return {StateModifier} this
 59.6237 +     */
 59.6238 +    StateModifier.prototype.setOrigin = function setOrigin(origin, transition, callback) {
 59.6239 +        if (origin === null) {
 59.6240 +            if (this._hasOrigin) {
 59.6241 +                this._modifier.originFrom(null);
 59.6242 +                this._hasOrigin = false;
 59.6243 +            }
 59.6244 +            return this;
 59.6245 +        }
 59.6246 +        else if (!this._hasOrigin) {
 59.6247 +            this._hasOrigin = true;
 59.6248 +            this._modifier.originFrom(this._originState);
 59.6249 +        }
 59.6250 +        this._originState.set(origin, transition, callback);
 59.6251 +        return this;
 59.6252 +    };
 59.6253 +
 59.6254 +    /**
 59.6255 +     * Set the alignment of this modifier, either statically or
 59.6256 +     *   through a provided Transitionable.
 59.6257 +     *
 59.6258 +     * @method setAlign
 59.6259 +     *
 59.6260 +     * @param {Array.Number} align two element array with values between 0 and 1.
 59.6261 +     * @param {Transitionable} transition Valid transitionable object
 59.6262 +     * @param {Function} callback callback to call after transition completes
 59.6263 +     * @return {StateModifier} this
 59.6264 +     */
 59.6265 +    StateModifier.prototype.setAlign = function setOrigin(align, transition, callback) {
 59.6266 +        if (align === null) {
 59.6267 +            if (this._hasAlign) {
 59.6268 +                this._modifier.alignFrom(null);
 59.6269 +                this._hasAlign = false;
 59.6270 +            }
 59.6271 +            return this;
 59.6272 +        }
 59.6273 +        else if (!this._hasAlign) {
 59.6274 +            this._hasAlign = true;
 59.6275 +            this._modifier.alignFrom(this._alignState);
 59.6276 +        }
 59.6277 +        this._alignState.set(align, transition, callback);
 59.6278 +        return this;
 59.6279 +    };
 59.6280 +
 59.6281 +    /**
 59.6282 +     * Set the size of this modifier, either statically or
 59.6283 +     *   through a provided Transitionable.
 59.6284 +     *
 59.6285 +     * @method setSize
 59.6286 +     *
 59.6287 +     * @param {Array.Number} size two element array with values between 0 and 1.
 59.6288 +     * @param {Transitionable} transition Valid transitionable object
 59.6289 +     * @param {Function} callback callback to call after transition completes
 59.6290 +     * @return {StateModifier} this
 59.6291 +     */
 59.6292 +    StateModifier.prototype.setSize = function setSize(size, transition, callback) {
 59.6293 +        if (size === null) {
 59.6294 +            if (this._hasSize) {
 59.6295 +                this._modifier.sizeFrom(null);
 59.6296 +                this._hasSize = false;
 59.6297 +            }
 59.6298 +            return this;
 59.6299 +        }
 59.6300 +        else if (!this._hasSize) {
 59.6301 +            this._hasSize = true;
 59.6302 +            this._modifier.sizeFrom(this._sizeState);
 59.6303 +        }
 59.6304 +        this._sizeState.set(size, transition, callback);
 59.6305 +        return this;
 59.6306 +    };
 59.6307 +
 59.6308 +    /**
 59.6309 +     * Stop the transition.
 59.6310 +     *
 59.6311 +     * @method halt
 59.6312 +     */
 59.6313 +    StateModifier.prototype.halt = function halt() {
 59.6314 +        this._transformState.halt();
 59.6315 +        this._opacityState.halt();
 59.6316 +        this._originState.halt();
 59.6317 +        this._alignState.halt();
 59.6318 +        this._sizeState.halt();
 59.6319 +    };
 59.6320 +
 59.6321 +    /**
 59.6322 +     * Get the current state of the transform matrix component.
 59.6323 +     *
 59.6324 +     * @method getTransform
 59.6325 +     * @return {Object} transform provider object
 59.6326 +     */
 59.6327 +    StateModifier.prototype.getTransform = function getTransform() {
 59.6328 +        return this._transformState.get();
 59.6329 +    };
 59.6330 +
 59.6331 +    /**
 59.6332 +     * Get the destination state of the transform component.
 59.6333 +     *
 59.6334 +     * @method getFinalTransform
 59.6335 +     * @return {Transform} transform matrix
 59.6336 +     */
 59.6337 +    StateModifier.prototype.getFinalTransform = function getFinalTransform() {
 59.6338 +        return this._transformState.getFinal();
 59.6339 +    };
 59.6340 +
 59.6341 +    /**
 59.6342 +     * Get the current state of the opacity component.
 59.6343 +     *
 59.6344 +     * @method getOpacity
 59.6345 +     * @return {Object} opacity provider object
 59.6346 +     */
 59.6347 +    StateModifier.prototype.getOpacity = function getOpacity() {
 59.6348 +        return this._opacityState.get();
 59.6349 +    };
 59.6350 +
 59.6351 +    /**
 59.6352 +     * Get the current state of the origin component.
 59.6353 +     *
 59.6354 +     * @method getOrigin
 59.6355 +     * @return {Object} origin provider object
 59.6356 +     */
 59.6357 +    StateModifier.prototype.getOrigin = function getOrigin() {
 59.6358 +        return this._hasOrigin ? this._originState.get() : null;
 59.6359 +    };
 59.6360 +
 59.6361 +    /**
 59.6362 +     * Get the current state of the align component.
 59.6363 +     *
 59.6364 +     * @method getAlign
 59.6365 +     * @return {Object} align provider object
 59.6366 +     */
 59.6367 +    StateModifier.prototype.getAlign = function getAlign() {
 59.6368 +        return this._hasAlign ? this._alignState.get() : null;
 59.6369 +    };
 59.6370 +
 59.6371 +    /**
 59.6372 +     * Get the current state of the size component.
 59.6373 +     *
 59.6374 +     * @method getSize
 59.6375 +     * @return {Object} size provider object
 59.6376 +     */
 59.6377 +    StateModifier.prototype.getSize = function getSize() {
 59.6378 +        return this._hasSize ? this._sizeState.get() : null;
 59.6379 +    };
 59.6380 +
 59.6381 +    /**
 59.6382 +     * Return render spec for this StateModifier, applying to the provided
 59.6383 +     *    target component.  This is similar to render() for Surfaces.
 59.6384 +     *
 59.6385 +     * @private
 59.6386 +     * @method modify
 59.6387 +     *
 59.6388 +     * @param {Object} target (already rendered) render spec to
 59.6389 +     *    which to apply the transform.
 59.6390 +     * @return {Object} render spec for this StateModifier, including the
 59.6391 +     *    provided target
 59.6392 +     */
 59.6393 +    StateModifier.prototype.modify = function modify(target) {
 59.6394 +        return this._modifier.modify(target);
 59.6395 +    };
 59.6396 +
 59.6397 +    module.exports = StateModifier;
 59.6398 +});
 59.6399 +
 59.6400 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.6401 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.6402 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.6403 + *
 59.6404 + * Owner: david@famo.us
 59.6405 + * @license MPL 2.0
 59.6406 + * @copyright Famous Industries, Inc. 2014
 59.6407 + */
 59.6408 +
 59.6409 +define('famous/math/Vector',['require','exports','module'],function(require, exports, module) {
 59.6410 +
 59.6411 +    /**
 59.6412 +     * Three-element floating point vector.
 59.6413 +     *
 59.6414 +     * @class Vector
 59.6415 +     * @constructor
 59.6416 +     *
 59.6417 +     * @param {number} x x element value
 59.6418 +     * @param {number} y y element value
 59.6419 +     * @param {number} z z element value
 59.6420 +     */
 59.6421 +    function Vector(x,y,z) {
 59.6422 +        if (arguments.length === 1) this.set(x);
 59.6423 +        else {
 59.6424 +            this.x = x || 0;
 59.6425 +            this.y = y || 0;
 59.6426 +            this.z = z || 0;
 59.6427 +        }
 59.6428 +        return this;
 59.6429 +    }
 59.6430 +
 59.6431 +    var _register = new Vector(0,0,0);
 59.6432 +
 59.6433 +    /**
 59.6434 +     * Add this element-wise to another Vector, element-wise.
 59.6435 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6436 +     *
 59.6437 +     * @method add
 59.6438 +     * @param {Vector} v addend
 59.6439 +     * @return {Vector} vector sum
 59.6440 +     */
 59.6441 +    Vector.prototype.add = function add(v) {
 59.6442 +        return _setXYZ.call(_register,
 59.6443 +            this.x + v.x,
 59.6444 +            this.y + v.y,
 59.6445 +            this.z + v.z
 59.6446 +        );
 59.6447 +    };
 59.6448 +
 59.6449 +    /**
 59.6450 +     * Subtract another vector from this vector, element-wise.
 59.6451 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6452 +     *
 59.6453 +     * @method sub
 59.6454 +     * @param {Vector} v subtrahend
 59.6455 +     * @return {Vector} vector difference
 59.6456 +     */
 59.6457 +    Vector.prototype.sub = function sub(v) {
 59.6458 +        return _setXYZ.call(_register,
 59.6459 +            this.x - v.x,
 59.6460 +            this.y - v.y,
 59.6461 +            this.z - v.z
 59.6462 +        );
 59.6463 +    };
 59.6464 +
 59.6465 +    /**
 59.6466 +     * Scale Vector by floating point r.
 59.6467 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6468 +     *
 59.6469 +     * @method mult
 59.6470 +     *
 59.6471 +     * @param {number} r scalar
 59.6472 +     * @return {Vector} vector result
 59.6473 +     */
 59.6474 +    Vector.prototype.mult = function mult(r) {
 59.6475 +        return _setXYZ.call(_register,
 59.6476 +            r * this.x,
 59.6477 +            r * this.y,
 59.6478 +            r * this.z
 59.6479 +        );
 59.6480 +    };
 59.6481 +
 59.6482 +    /**
 59.6483 +     * Scale Vector by floating point 1/r.
 59.6484 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6485 +     *
 59.6486 +     * @method div
 59.6487 +     *
 59.6488 +     * @param {number} r scalar
 59.6489 +     * @return {Vector} vector result
 59.6490 +     */
 59.6491 +    Vector.prototype.div = function div(r) {
 59.6492 +        return this.mult(1 / r);
 59.6493 +    };
 59.6494 +
 59.6495 +    /**
 59.6496 +     * Given another vector v, return cross product (v)x(this).
 59.6497 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6498 +     *
 59.6499 +     * @method cross
 59.6500 +     * @param {Vector} v Left Hand Vector
 59.6501 +     * @return {Vector} vector result
 59.6502 +     */
 59.6503 +    Vector.prototype.cross = function cross(v) {
 59.6504 +        var x = this.x;
 59.6505 +        var y = this.y;
 59.6506 +        var z = this.z;
 59.6507 +        var vx = v.x;
 59.6508 +        var vy = v.y;
 59.6509 +        var vz = v.z;
 59.6510 +
 59.6511 +        return _setXYZ.call(_register,
 59.6512 +            z * vy - y * vz,
 59.6513 +            x * vz - z * vx,
 59.6514 +            y * vx - x * vy
 59.6515 +        );
 59.6516 +    };
 59.6517 +
 59.6518 +    /**
 59.6519 +     * Component-wise equality test between this and Vector v.
 59.6520 +     * @method equals
 59.6521 +     * @param {Vector} v vector to compare
 59.6522 +     * @return {boolean}
 59.6523 +     */
 59.6524 +    Vector.prototype.equals = function equals(v) {
 59.6525 +        return (v.x === this.x && v.y === this.y && v.z === this.z);
 59.6526 +    };
 59.6527 +
 59.6528 +    /**
 59.6529 +     * Rotate clockwise around x-axis by theta radians.
 59.6530 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6531 +     * @method rotateX
 59.6532 +     * @param {number} theta radians
 59.6533 +     * @return {Vector} rotated vector
 59.6534 +     */
 59.6535 +    Vector.prototype.rotateX = function rotateX(theta) {
 59.6536 +        var x = this.x;
 59.6537 +        var y = this.y;
 59.6538 +        var z = this.z;
 59.6539 +
 59.6540 +        var cosTheta = Math.cos(theta);
 59.6541 +        var sinTheta = Math.sin(theta);
 59.6542 +
 59.6543 +        return _setXYZ.call(_register,
 59.6544 +            x,
 59.6545 +            y * cosTheta - z * sinTheta,
 59.6546 +            y * sinTheta + z * cosTheta
 59.6547 +        );
 59.6548 +    };
 59.6549 +
 59.6550 +    /**
 59.6551 +     * Rotate clockwise around y-axis by theta radians.
 59.6552 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6553 +     * @method rotateY
 59.6554 +     * @param {number} theta radians
 59.6555 +     * @return {Vector} rotated vector
 59.6556 +     */
 59.6557 +    Vector.prototype.rotateY = function rotateY(theta) {
 59.6558 +        var x = this.x;
 59.6559 +        var y = this.y;
 59.6560 +        var z = this.z;
 59.6561 +
 59.6562 +        var cosTheta = Math.cos(theta);
 59.6563 +        var sinTheta = Math.sin(theta);
 59.6564 +
 59.6565 +        return _setXYZ.call(_register,
 59.6566 +            z * sinTheta + x * cosTheta,
 59.6567 +            y,
 59.6568 +            z * cosTheta - x * sinTheta
 59.6569 +        );
 59.6570 +    };
 59.6571 +
 59.6572 +    /**
 59.6573 +     * Rotate clockwise around z-axis by theta radians.
 59.6574 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6575 +     * @method rotateZ
 59.6576 +     * @param {number} theta radians
 59.6577 +     * @return {Vector} rotated vector
 59.6578 +     */
 59.6579 +    Vector.prototype.rotateZ = function rotateZ(theta) {
 59.6580 +        var x = this.x;
 59.6581 +        var y = this.y;
 59.6582 +        var z = this.z;
 59.6583 +
 59.6584 +        var cosTheta = Math.cos(theta);
 59.6585 +        var sinTheta = Math.sin(theta);
 59.6586 +
 59.6587 +        return _setXYZ.call(_register,
 59.6588 +            x * cosTheta - y * sinTheta,
 59.6589 +            x * sinTheta + y * cosTheta,
 59.6590 +            z
 59.6591 +        );
 59.6592 +    };
 59.6593 +
 59.6594 +    /**
 59.6595 +     * Return dot product of this with a second Vector
 59.6596 +     * @method dot
 59.6597 +     * @param {Vector} v second vector
 59.6598 +     * @return {number} dot product
 59.6599 +     */
 59.6600 +    Vector.prototype.dot = function dot(v) {
 59.6601 +        return this.x * v.x + this.y * v.y + this.z * v.z;
 59.6602 +    };
 59.6603 +
 59.6604 +    /**
 59.6605 +     * Return squared length of this vector
 59.6606 +     * @method normSquared
 59.6607 +     * @return {number} squared length
 59.6608 +     */
 59.6609 +    Vector.prototype.normSquared = function normSquared() {
 59.6610 +        return this.dot(this);
 59.6611 +    };
 59.6612 +
 59.6613 +    /**
 59.6614 +     * Return length of this vector
 59.6615 +     * @method norm
 59.6616 +     * @return {number} length
 59.6617 +     */
 59.6618 +    Vector.prototype.norm = function norm() {
 59.6619 +        return Math.sqrt(this.normSquared());
 59.6620 +    };
 59.6621 +
 59.6622 +    /**
 59.6623 +     * Scale Vector to specified length.
 59.6624 +     *   If length is less than internal tolerance, set vector to [length, 0, 0].
 59.6625 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6626 +     * @method normalize
 59.6627 +     *
 59.6628 +     * @param {number} length target length, default 1.0
 59.6629 +     * @return {Vector}
 59.6630 +     */
 59.6631 +    Vector.prototype.normalize = function normalize(length) {
 59.6632 +        if (arguments.length === 0) length = 1;
 59.6633 +        var norm = this.norm();
 59.6634 +
 59.6635 +        if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm));
 59.6636 +        else return _setXYZ.call(_register, length, 0, 0);
 59.6637 +    };
 59.6638 +
 59.6639 +    /**
 59.6640 +     * Make a separate copy of the Vector.
 59.6641 +     *
 59.6642 +     * @method clone
 59.6643 +     *
 59.6644 +     * @return {Vector}
 59.6645 +     */
 59.6646 +    Vector.prototype.clone = function clone() {
 59.6647 +        return new Vector(this);
 59.6648 +    };
 59.6649 +
 59.6650 +    /**
 59.6651 +     * True if and only if every value is 0 (or falsy)
 59.6652 +     *
 59.6653 +     * @method isZero
 59.6654 +     *
 59.6655 +     * @return {boolean}
 59.6656 +     */
 59.6657 +    Vector.prototype.isZero = function isZero() {
 59.6658 +        return !(this.x || this.y || this.z);
 59.6659 +    };
 59.6660 +
 59.6661 +    function _setXYZ(x,y,z) {
 59.6662 +        this.x = x;
 59.6663 +        this.y = y;
 59.6664 +        this.z = z;
 59.6665 +        return this;
 59.6666 +    }
 59.6667 +
 59.6668 +    function _setFromArray(v) {
 59.6669 +        return _setXYZ.call(this,v[0],v[1],v[2] || 0);
 59.6670 +    }
 59.6671 +
 59.6672 +    function _setFromVector(v) {
 59.6673 +        return _setXYZ.call(this, v.x, v.y, v.z);
 59.6674 +    }
 59.6675 +
 59.6676 +    function _setFromNumber(x) {
 59.6677 +        return _setXYZ.call(this,x,0,0);
 59.6678 +    }
 59.6679 +
 59.6680 +    /**
 59.6681 +     * Set this Vector to the values in the provided Array or Vector.
 59.6682 +     *
 59.6683 +     * @method set
 59.6684 +     * @param {object} v array, Vector, or number
 59.6685 +     * @return {Vector} this
 59.6686 +     */
 59.6687 +    Vector.prototype.set = function set(v) {
 59.6688 +        if (v instanceof Array)    return _setFromArray.call(this, v);
 59.6689 +        if (v instanceof Vector)   return _setFromVector.call(this, v);
 59.6690 +        if (typeof v === 'number') return _setFromNumber.call(this, v);
 59.6691 +    };
 59.6692 +
 59.6693 +    Vector.prototype.setXYZ = function(x,y,z) {
 59.6694 +        return _setXYZ.apply(this, arguments);
 59.6695 +    };
 59.6696 +
 59.6697 +    Vector.prototype.set1D = function(x) {
 59.6698 +        return _setFromNumber.call(this, x);
 59.6699 +    };
 59.6700 +
 59.6701 +    /**
 59.6702 +     * Put result of last internal register calculation in specified output vector.
 59.6703 +     *
 59.6704 +     * @method put
 59.6705 +     * @param {Vector} v destination vector
 59.6706 +     * @return {Vector} destination vector
 59.6707 +     */
 59.6708 +
 59.6709 +    Vector.prototype.put = function put(v) {
 59.6710 +        _setFromVector.call(v, _register);
 59.6711 +    };
 59.6712 +
 59.6713 +    /**
 59.6714 +     * Set this vector to [0,0,0]
 59.6715 +     *
 59.6716 +     * @method clear
 59.6717 +     */
 59.6718 +    Vector.prototype.clear = function clear() {
 59.6719 +        return _setXYZ.call(this,0,0,0);
 59.6720 +    };
 59.6721 +
 59.6722 +    /**
 59.6723 +     * Scale this Vector down to specified "cap" length.
 59.6724 +     *   If Vector shorter than cap, or cap is Infinity, do nothing.
 59.6725 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6726 +     *
 59.6727 +     * @method cap
 59.6728 +     * @return {Vector} capped vector
 59.6729 +     */
 59.6730 +    Vector.prototype.cap = function cap(cap) {
 59.6731 +        if (cap === Infinity) return _setFromVector.call(_register, this);
 59.6732 +        var norm = this.norm();
 59.6733 +        if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm));
 59.6734 +        else return _setFromVector.call(_register, this);
 59.6735 +    };
 59.6736 +
 59.6737 +    /**
 59.6738 +     * Return projection of this Vector onto another.
 59.6739 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6740 +     *
 59.6741 +     * @method project
 59.6742 +     * @param {Vector} n vector to project upon
 59.6743 +     * @return {Vector} projected vector
 59.6744 +     */
 59.6745 +    Vector.prototype.project = function project(n) {
 59.6746 +        return n.mult(this.dot(n));
 59.6747 +    };
 59.6748 +
 59.6749 +    /**
 59.6750 +     * Reflect this Vector across provided vector.
 59.6751 +     *   Note: This sets the internal result register, so other references to that vector will change.
 59.6752 +     *
 59.6753 +     * @method reflectAcross
 59.6754 +     * @param {Vector} n vector to reflect across
 59.6755 +     * @return {Vector} reflected vector
 59.6756 +     */
 59.6757 +    Vector.prototype.reflectAcross = function reflectAcross(n) {
 59.6758 +        n.normalize().put(n);
 59.6759 +        return _setFromVector(_register, this.sub(this.project(n).mult(2)));
 59.6760 +    };
 59.6761 +
 59.6762 +    /**
 59.6763 +     * Convert Vector to three-element array.
 59.6764 +     *
 59.6765 +     * @method get
 59.6766 +     * @return {array<number>} three-element array
 59.6767 +     */
 59.6768 +    Vector.prototype.get = function get() {
 59.6769 +        return [this.x, this.y, this.z];
 59.6770 +    };
 59.6771 +
 59.6772 +    Vector.prototype.get1D = function() {
 59.6773 +        return this.x;
 59.6774 +    };
 59.6775 +
 59.6776 +    module.exports = Vector;
 59.6777 +
 59.6778 +});
 59.6779 +
 59.6780 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.6781 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.6782 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.6783 + *
 59.6784 + * Owner: david@famo.us
 59.6785 + * @license MPL 2.0
 59.6786 + * @copyright Famous Industries, Inc. 2014
 59.6787 + */
 59.6788 +
 59.6789 +define('famous/math/Matrix',['require','exports','module','./Vector'],function(require, exports, module) {
 59.6790 +    var Vector = require('./Vector');
 59.6791 +
 59.6792 +    /**
 59.6793 +     * A library for using a 3x3 numerical matrix, represented as a two-level array.
 59.6794 +     *
 59.6795 +     * @class Matrix
 59.6796 +     * @constructor
 59.6797 +     *
 59.6798 +     * @param {Array.Array} values array of rows
 59.6799 +     */
 59.6800 +    function Matrix(values) {
 59.6801 +        this.values = values ||
 59.6802 +            [
 59.6803 +                [1,0,0],
 59.6804 +                [0,1,0],
 59.6805 +                [0,0,1]
 59.6806 +            ];
 59.6807 +
 59.6808 +        return this;
 59.6809 +    }
 59.6810 +
 59.6811 +    var _register = new Matrix();
 59.6812 +    var _vectorRegister = new Vector();
 59.6813 +
 59.6814 +    /**
 59.6815 +     * Return the values in the matrix as an array of numerical row arrays
 59.6816 +     *
 59.6817 +     * @method get
 59.6818 +     *
 59.6819 +     * @return {Array.array} matrix values as array of rows.
 59.6820 +     */
 59.6821 +    Matrix.prototype.get = function get() {
 59.6822 +        return this.values;
 59.6823 +    };
 59.6824 +
 59.6825 +    /**
 59.6826 +     * Set the nested array of rows in the matrix.
 59.6827 +     *
 59.6828 +     * @method set
 59.6829 +     *
 59.6830 +     * @param {Array.array} values matrix values as array of rows.
 59.6831 +     */
 59.6832 +    Matrix.prototype.set = function set(values) {
 59.6833 +        this.values = values;
 59.6834 +    };
 59.6835 +
 59.6836 +    /**
 59.6837 +     * Take this matrix as A, input vector V as a column vector, and return matrix product (A)(V).
 59.6838 +     *   Note: This sets the internal vector register.  Current handles to the vector register
 59.6839 +     *   will see values changed.
 59.6840 +     *
 59.6841 +     * @method vectorMultiply
 59.6842 +     *
 59.6843 +     * @param {Vector} v input vector V
 59.6844 +     * @return {Vector} result of multiplication, as a handle to the internal vector register
 59.6845 +     */
 59.6846 +    Matrix.prototype.vectorMultiply = function vectorMultiply(v) {
 59.6847 +        var M = this.get();
 59.6848 +        var v0 = v.x;
 59.6849 +        var v1 = v.y;
 59.6850 +        var v2 = v.z;
 59.6851 +
 59.6852 +        var M0 = M[0];
 59.6853 +        var M1 = M[1];
 59.6854 +        var M2 = M[2];
 59.6855 +
 59.6856 +        var M00 = M0[0];
 59.6857 +        var M01 = M0[1];
 59.6858 +        var M02 = M0[2];
 59.6859 +        var M10 = M1[0];
 59.6860 +        var M11 = M1[1];
 59.6861 +        var M12 = M1[2];
 59.6862 +        var M20 = M2[0];
 59.6863 +        var M21 = M2[1];
 59.6864 +        var M22 = M2[2];
 59.6865 +
 59.6866 +        return _vectorRegister.setXYZ(
 59.6867 +            M00*v0 + M01*v1 + M02*v2,
 59.6868 +            M10*v0 + M11*v1 + M12*v2,
 59.6869 +            M20*v0 + M21*v1 + M22*v2
 59.6870 +        );
 59.6871 +    };
 59.6872 +
 59.6873 +    /**
 59.6874 +     * Multiply the provided matrix M2 with this matrix.  Result is (this) * (M2).
 59.6875 +     *   Note: This sets the internal matrix register.  Current handles to the register
 59.6876 +     *   will see values changed.
 59.6877 +     *
 59.6878 +     * @method multiply
 59.6879 +     *
 59.6880 +     * @param {Matrix} M2 input matrix to multiply on the right
 59.6881 +     * @return {Matrix} result of multiplication, as a handle to the internal register
 59.6882 +     */
 59.6883 +    Matrix.prototype.multiply = function multiply(M2) {
 59.6884 +        var M1 = this.get();
 59.6885 +        var result = [[]];
 59.6886 +        for (var i = 0; i < 3; i++) {
 59.6887 +            result[i] = [];
 59.6888 +            for (var j = 0; j < 3; j++) {
 59.6889 +                var sum = 0;
 59.6890 +                for (var k = 0; k < 3; k++) {
 59.6891 +                    sum += M1[i][k] * M2[k][j];
 59.6892 +                }
 59.6893 +                result[i][j] = sum;
 59.6894 +            }
 59.6895 +        }
 59.6896 +        return _register.set(result);
 59.6897 +    };
 59.6898 +
 59.6899 +    /**
 59.6900 +     * Creates a Matrix which is the transpose of this matrix.
 59.6901 +     *   Note: This sets the internal matrix register.  Current handles to the register
 59.6902 +     *   will see values changed.
 59.6903 +     *
 59.6904 +     * @method transpose
 59.6905 +     *
 59.6906 +     * @return {Matrix} result of transpose, as a handle to the internal register
 59.6907 +     */
 59.6908 +    Matrix.prototype.transpose = function transpose() {
 59.6909 +        var result = [];
 59.6910 +        var M = this.get();
 59.6911 +        for (var row = 0; row < 3; row++) {
 59.6912 +            for (var col = 0; col < 3; col++) {
 59.6913 +                result[row][col] = M[col][row];
 59.6914 +            }
 59.6915 +        }
 59.6916 +        return _register.set(result);
 59.6917 +    };
 59.6918 +
 59.6919 +    /**
 59.6920 +     * Clones the matrix
 59.6921 +     *
 59.6922 +     * @method clone
 59.6923 +     * @return {Matrix} New copy of the original matrix
 59.6924 +     */
 59.6925 +    Matrix.prototype.clone = function clone() {
 59.6926 +        var values = this.get();
 59.6927 +        var M = [];
 59.6928 +        for (var row = 0; row < 3; row++)
 59.6929 +            M[row] = values[row].slice();
 59.6930 +        return new Matrix(M);
 59.6931 +    };
 59.6932 +
 59.6933 +    module.exports = Matrix;
 59.6934 +});
 59.6935 +
 59.6936 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.6937 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.6938 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.6939 + *
 59.6940 + * Owner: david@famo.us
 59.6941 + * @license MPL 2.0
 59.6942 + * @copyright Famous Industries, Inc. 2014
 59.6943 + */
 59.6944 +
 59.6945 +define('famous/math/Quaternion',['require','exports','module','./Matrix'],function(require, exports, module) {
 59.6946 +    var Matrix = require('./Matrix');
 59.6947 +
 59.6948 +    /**
 59.6949 +     * @class Quaternion
 59.6950 +     * @constructor
 59.6951 +     *
 59.6952 +     * @param {Number} w
 59.6953 +     * @param {Number} x
 59.6954 +     * @param {Number} y
 59.6955 +     * @param {Number} z
 59.6956 +     */
 59.6957 +    function Quaternion(w,x,y,z) {
 59.6958 +        if (arguments.length === 1) this.set(w);
 59.6959 +        else {
 59.6960 +            this.w = (w !== undefined) ? w : 1;  //Angle
 59.6961 +            this.x = (x !== undefined) ? x : 0;  //Axis.x
 59.6962 +            this.y = (y !== undefined) ? y : 0;  //Axis.y
 59.6963 +            this.z = (z !== undefined) ? z : 0;  //Axis.z
 59.6964 +        }
 59.6965 +        return this;
 59.6966 +    }
 59.6967 +
 59.6968 +    var register = new Quaternion(1,0,0,0);
 59.6969 +
 59.6970 +    /**
 59.6971 +     * Doc: TODO
 59.6972 +     * @method add
 59.6973 +     * @param {Quaternion} q
 59.6974 +     * @return {Quaternion}
 59.6975 +     */
 59.6976 +    Quaternion.prototype.add = function add(q) {
 59.6977 +        return register.setWXYZ(
 59.6978 +            this.w + q.w,
 59.6979 +            this.x + q.x,
 59.6980 +            this.y + q.y,
 59.6981 +            this.z + q.z
 59.6982 +        );
 59.6983 +    };
 59.6984 +
 59.6985 +    /*
 59.6986 +     * Docs: TODO
 59.6987 +     *
 59.6988 +     * @method sub
 59.6989 +     * @param {Quaternion} q
 59.6990 +     * @return {Quaternion}
 59.6991 +     */
 59.6992 +    Quaternion.prototype.sub = function sub(q) {
 59.6993 +        return register.setWXYZ(
 59.6994 +            this.w - q.w,
 59.6995 +            this.x - q.x,
 59.6996 +            this.y - q.y,
 59.6997 +            this.z - q.z
 59.6998 +        );
 59.6999 +    };
 59.7000 +
 59.7001 +    /**
 59.7002 +     * Doc: TODO
 59.7003 +     *
 59.7004 +     * @method scalarDivide
 59.7005 +     * @param {Number} s
 59.7006 +     * @return {Quaternion}
 59.7007 +     */
 59.7008 +    Quaternion.prototype.scalarDivide = function scalarDivide(s) {
 59.7009 +        return this.scalarMultiply(1/s);
 59.7010 +    };
 59.7011 +
 59.7012 +    /*
 59.7013 +     * Docs: TODO
 59.7014 +     *
 59.7015 +     * @method scalarMultiply
 59.7016 +     * @param {Number} s
 59.7017 +     * @return {Quaternion}
 59.7018 +     */
 59.7019 +    Quaternion.prototype.scalarMultiply = function scalarMultiply(s) {
 59.7020 +        return register.setWXYZ(
 59.7021 +            this.w * s,
 59.7022 +            this.x * s,
 59.7023 +            this.y * s,
 59.7024 +            this.z * s
 59.7025 +        );
 59.7026 +    };
 59.7027 +
 59.7028 +    /*
 59.7029 +     * Docs: TODO
 59.7030 +     *
 59.7031 +     * @method multiply
 59.7032 +     * @param {Quaternion} q
 59.7033 +     * @return {Quaternion}
 59.7034 +     */
 59.7035 +    Quaternion.prototype.multiply = function multiply(q) {
 59.7036 +        //left-handed coordinate system multiplication
 59.7037 +        var x1 = this.x;
 59.7038 +        var y1 = this.y;
 59.7039 +        var z1 = this.z;
 59.7040 +        var w1 = this.w;
 59.7041 +        var x2 = q.x;
 59.7042 +        var y2 = q.y;
 59.7043 +        var z2 = q.z;
 59.7044 +        var w2 = q.w || 0;
 59.7045 +
 59.7046 +        return register.setWXYZ(
 59.7047 +            w1*w2 - x1*x2 - y1*y2 - z1*z2,
 59.7048 +            x1*w2 + x2*w1 + y2*z1 - y1*z2,
 59.7049 +            y1*w2 + y2*w1 + x1*z2 - x2*z1,
 59.7050 +            z1*w2 + z2*w1 + x2*y1 - x1*y2
 59.7051 +        );
 59.7052 +    };
 59.7053 +
 59.7054 +    var conj = new Quaternion(1,0,0,0);
 59.7055 +
 59.7056 +    /*
 59.7057 +     * Docs: TODO
 59.7058 +     *
 59.7059 +     * @method rotateVector
 59.7060 +     * @param {Vector} v
 59.7061 +     * @return {Quaternion}
 59.7062 +     */
 59.7063 +    Quaternion.prototype.rotateVector = function rotateVector(v) {
 59.7064 +        conj.set(this.conj());
 59.7065 +        return register.set(this.multiply(v).multiply(conj));
 59.7066 +    };
 59.7067 +
 59.7068 +    /*
 59.7069 +     * Docs: TODO
 59.7070 +     *
 59.7071 +     * @method inverse
 59.7072 +     * @return {Quaternion}
 59.7073 +     */
 59.7074 +    Quaternion.prototype.inverse = function inverse() {
 59.7075 +        return register.set(this.conj().scalarDivide(this.normSquared()));
 59.7076 +    };
 59.7077 +
 59.7078 +    /*
 59.7079 +     * Docs: TODO
 59.7080 +     *
 59.7081 +     * @method negate
 59.7082 +     * @return {Quaternion}
 59.7083 +     */
 59.7084 +    Quaternion.prototype.negate = function negate() {
 59.7085 +        return this.scalarMultiply(-1);
 59.7086 +    };
 59.7087 +
 59.7088 +    /*
 59.7089 +     * Docs: TODO
 59.7090 +     *
 59.7091 +     * @method conj
 59.7092 +     * @return {Quaternion}
 59.7093 +     */
 59.7094 +    Quaternion.prototype.conj = function conj() {
 59.7095 +        return register.setWXYZ(
 59.7096 +             this.w,
 59.7097 +            -this.x,
 59.7098 +            -this.y,
 59.7099 +            -this.z
 59.7100 +        );
 59.7101 +    };
 59.7102 +
 59.7103 +    /*
 59.7104 +     * Docs: TODO
 59.7105 +     *
 59.7106 +     * @method normalize
 59.7107 +     * @param {Number} length
 59.7108 +     * @return {Quaternion}
 59.7109 +     */
 59.7110 +    Quaternion.prototype.normalize = function normalize(length) {
 59.7111 +        length = (length === undefined) ? 1 : length;
 59.7112 +        return this.scalarDivide(length * this.norm());
 59.7113 +    };
 59.7114 +
 59.7115 +    /*
 59.7116 +     * Docs: TODO
 59.7117 +     *
 59.7118 +     * @method makeFromAngleAndAxis
 59.7119 +     * @param {Number} angle
 59.7120 +     * @param {Vector} v
 59.7121 +     * @return {Quaternion}
 59.7122 +     */
 59.7123 +    Quaternion.prototype.makeFromAngleAndAxis = function makeFromAngleAndAxis(angle, v) {
 59.7124 +        //left handed quaternion creation: theta -> -theta
 59.7125 +        var n  = v.normalize();
 59.7126 +        var ha = angle*0.5;
 59.7127 +        var s  = -Math.sin(ha);
 59.7128 +        this.x = s*n.x;
 59.7129 +        this.y = s*n.y;
 59.7130 +        this.z = s*n.z;
 59.7131 +        this.w = Math.cos(ha);
 59.7132 +        return this;
 59.7133 +    };
 59.7134 +
 59.7135 +    /*
 59.7136 +     * Docs: TODO
 59.7137 +     *
 59.7138 +     * @method setWXYZ
 59.7139 +     * @param {Number} w
 59.7140 +     * @param {Number} x
 59.7141 +     * @param {Number} y
 59.7142 +     * @param {Number} z
 59.7143 +     * @return {Quaternion}
 59.7144 +     */
 59.7145 +    Quaternion.prototype.setWXYZ = function setWXYZ(w,x,y,z) {
 59.7146 +        register.clear();
 59.7147 +        this.w = w;
 59.7148 +        this.x = x;
 59.7149 +        this.y = y;
 59.7150 +        this.z = z;
 59.7151 +        return this;
 59.7152 +    };
 59.7153 +
 59.7154 +    /*
 59.7155 +     * Docs: TODO
 59.7156 +     *
 59.7157 +     * @method set
 59.7158 +     * @param {Array|Quaternion} v
 59.7159 +     * @return {Quaternion}
 59.7160 +     */
 59.7161 +    Quaternion.prototype.set = function set(v) {
 59.7162 +        if (v instanceof Array) {
 59.7163 +            this.w = v[0];
 59.7164 +            this.x = v[1];
 59.7165 +            this.y = v[2];
 59.7166 +            this.z = v[3];
 59.7167 +        }
 59.7168 +        else {
 59.7169 +            this.w = v.w;
 59.7170 +            this.x = v.x;
 59.7171 +            this.y = v.y;
 59.7172 +            this.z = v.z;
 59.7173 +        }
 59.7174 +        if (this !== register) register.clear();
 59.7175 +        return this;
 59.7176 +    };
 59.7177 +
 59.7178 +    /**
 59.7179 +     * Docs: TODO
 59.7180 +     *
 59.7181 +     * @method put
 59.7182 +     * @param {Quaternion} q
 59.7183 +     * @return {Quaternion}
 59.7184 +     */
 59.7185 +    Quaternion.prototype.put = function put(q) {
 59.7186 +        q.set(register);
 59.7187 +    };
 59.7188 +
 59.7189 +    /**
 59.7190 +     * Doc: TODO
 59.7191 +     *
 59.7192 +     * @method clone
 59.7193 +     * @return {Quaternion}
 59.7194 +     */
 59.7195 +    Quaternion.prototype.clone = function clone() {
 59.7196 +        return new Quaternion(this);
 59.7197 +    };
 59.7198 +
 59.7199 +    /**
 59.7200 +     * Doc: TODO
 59.7201 +     *
 59.7202 +     * @method clear
 59.7203 +     * @return {Quaternion}
 59.7204 +     */
 59.7205 +    Quaternion.prototype.clear = function clear() {
 59.7206 +        this.w = 1;
 59.7207 +        this.x = 0;
 59.7208 +        this.y = 0;
 59.7209 +        this.z = 0;
 59.7210 +        return this;
 59.7211 +    };
 59.7212 +
 59.7213 +    /**
 59.7214 +     * Doc: TODO
 59.7215 +     *
 59.7216 +     * @method isEqual
 59.7217 +     * @param {Quaternion} q
 59.7218 +     * @return {Boolean}
 59.7219 +     */
 59.7220 +    Quaternion.prototype.isEqual = function isEqual(q) {
 59.7221 +        return q.w === this.w && q.x === this.x && q.y === this.y && q.z === this.z;
 59.7222 +    };
 59.7223 +
 59.7224 +    /**
 59.7225 +     * Doc: TODO
 59.7226 +     *
 59.7227 +     * @method dot
 59.7228 +     * @param {Quaternion} q
 59.7229 +     * @return {Number}
 59.7230 +     */
 59.7231 +    Quaternion.prototype.dot = function dot(q) {
 59.7232 +        return this.w * q.w + this.x * q.x + this.y * q.y + this.z * q.z;
 59.7233 +    };
 59.7234 +
 59.7235 +    /**
 59.7236 +     * Doc: TODO
 59.7237 +     *
 59.7238 +     * @method normSquared
 59.7239 +     * @return {Number}
 59.7240 +     */
 59.7241 +    Quaternion.prototype.normSquared = function normSquared() {
 59.7242 +        return this.dot(this);
 59.7243 +    };
 59.7244 +
 59.7245 +    /**
 59.7246 +     * Doc: TODO
 59.7247 +     *
 59.7248 +     * @method norm
 59.7249 +     * @return {Number}
 59.7250 +     */
 59.7251 +    Quaternion.prototype.norm = function norm() {
 59.7252 +        return Math.sqrt(this.normSquared());
 59.7253 +    };
 59.7254 +
 59.7255 +    /**
 59.7256 +     * Doc: TODO
 59.7257 +     *
 59.7258 +     * @method isZero
 59.7259 +     * @return {Boolean}
 59.7260 +     */
 59.7261 +    Quaternion.prototype.isZero = function isZero() {
 59.7262 +        return !(this.x || this.y || this.z);
 59.7263 +    };
 59.7264 +
 59.7265 +    /**
 59.7266 +     * Doc: TODO
 59.7267 +     *
 59.7268 +     * @method getTransform
 59.7269 +     * @return {Transform}
 59.7270 +     */
 59.7271 +    Quaternion.prototype.getTransform = function getTransform() {
 59.7272 +        var temp = this.normalize(1);
 59.7273 +        var x = temp.x;
 59.7274 +        var y = temp.y;
 59.7275 +        var z = temp.z;
 59.7276 +        var w = temp.w;
 59.7277 +
 59.7278 +        //LHC system flattened to column major = RHC flattened to row major
 59.7279 +        return [
 59.7280 +            1 - 2*y*y - 2*z*z,
 59.7281 +                2*x*y - 2*z*w,
 59.7282 +                2*x*z + 2*y*w,
 59.7283 +            0,
 59.7284 +                2*x*y + 2*z*w,
 59.7285 +            1 - 2*x*x - 2*z*z,
 59.7286 +                2*y*z - 2*x*w,
 59.7287 +            0,
 59.7288 +                2*x*z - 2*y*w,
 59.7289 +                2*y*z + 2*x*w,
 59.7290 +            1 - 2*x*x - 2*y*y,
 59.7291 +            0,
 59.7292 +            0,
 59.7293 +            0,
 59.7294 +            0,
 59.7295 +            1
 59.7296 +        ];
 59.7297 +    };
 59.7298 +
 59.7299 +    var matrixRegister = new Matrix();
 59.7300 +
 59.7301 +    /**
 59.7302 +     * Doc: TODO
 59.7303 +     *
 59.7304 +     * @method getMatrix
 59.7305 +     * @return {Transform}
 59.7306 +     */
 59.7307 +    Quaternion.prototype.getMatrix = function getMatrix() {
 59.7308 +        var temp = this.normalize(1);
 59.7309 +        var x = temp.x;
 59.7310 +        var y = temp.y;
 59.7311 +        var z = temp.z;
 59.7312 +        var w = temp.w;
 59.7313 +
 59.7314 +        //LHC system flattened to row major
 59.7315 +        return matrixRegister.set([
 59.7316 +            [
 59.7317 +                1 - 2*y*y - 2*z*z,
 59.7318 +                    2*x*y + 2*z*w,
 59.7319 +                    2*x*z - 2*y*w
 59.7320 +            ],
 59.7321 +            [
 59.7322 +                    2*x*y - 2*z*w,
 59.7323 +                1 - 2*x*x - 2*z*z,
 59.7324 +                    2*y*z + 2*x*w
 59.7325 +            ],
 59.7326 +            [
 59.7327 +                    2*x*z + 2*y*w,
 59.7328 +                    2*y*z - 2*x*w,
 59.7329 +                1 - 2*x*x - 2*y*y
 59.7330 +            ]
 59.7331 +        ]);
 59.7332 +    };
 59.7333 +
 59.7334 +    var epsilon = 1e-5;
 59.7335 +
 59.7336 +    /**
 59.7337 +     * Doc: TODO
 59.7338 +     *
 59.7339 +     * @method slerp
 59.7340 +     * @param {Quaternion} q
 59.7341 +     * @param {Number} t
 59.7342 +     * @return {Transform}
 59.7343 +     */
 59.7344 +    Quaternion.prototype.slerp = function slerp(q, t) {
 59.7345 +        var omega;
 59.7346 +        var cosomega;
 59.7347 +        var sinomega;
 59.7348 +        var scaleFrom;
 59.7349 +        var scaleTo;
 59.7350 +
 59.7351 +        cosomega = this.dot(q);
 59.7352 +        if ((1.0 - cosomega) > epsilon) {
 59.7353 +            omega       = Math.acos(cosomega);
 59.7354 +            sinomega    = Math.sin(omega);
 59.7355 +            scaleFrom   = Math.sin((1.0 - t) * omega) / sinomega;
 59.7356 +            scaleTo     = Math.sin(t * omega) / sinomega;
 59.7357 +        }
 59.7358 +        else {
 59.7359 +            scaleFrom   = 1.0 - t;
 59.7360 +            scaleTo     = t;
 59.7361 +        }
 59.7362 +        return register.set(this.scalarMultiply(scaleFrom/scaleTo).add(q).multiply(scaleTo));
 59.7363 +    };
 59.7364 +
 59.7365 +    module.exports = Quaternion;
 59.7366 +
 59.7367 +});
 59.7368 +
 59.7369 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.7370 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.7371 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.7372 + *
 59.7373 + * Owner: david@famo.us
 59.7374 + * @license MPL 2.0
 59.7375 + * @copyright Famous Industries, Inc. 2014
 59.7376 + */
 59.7377 +
 59.7378 +define('famous/math/Random',['require','exports','module'],function(require, exports, module) {
 59.7379 +
 59.7380 +    var RAND = Math.random;
 59.7381 +
 59.7382 +    function _randomFloat(min,max) {
 59.7383 +        return min + RAND() * (max - min);
 59.7384 +    }
 59.7385 +
 59.7386 +    function _randomInteger(min,max) {
 59.7387 +        return (min + RAND() * (max - min + 1)) >> 0;
 59.7388 +    }
 59.7389 +
 59.7390 +    /**
 59.7391 +     * Very simple uniform random number generator library wrapping Math.random().
 59.7392 +     *
 59.7393 +     * @class Random
 59.7394 +     * @static
 59.7395 +     */
 59.7396 +    var Random = {};
 59.7397 +
 59.7398 +    /**
 59.7399 +     * Get single random integer between min and max (inclusive), or array
 59.7400 +     *   of size dim if specified.
 59.7401 +     *
 59.7402 +     * @method integer
 59.7403 +     *
 59.7404 +     * @param {Number} min lower bound, default 0
 59.7405 +     * @param {Number} max upper bound, default 1
 59.7406 +     * @param {Number} dim (optional) dimension of output array, if specified
 59.7407 +     * @return {number | array<number>} random integer, or optionally, an array of random integers
 59.7408 +     */
 59.7409 +    Random.integer = function integer(min,max,dim) {
 59.7410 +        min = (min !== undefined) ? min : 0;
 59.7411 +        max = (max !== undefined) ? max : 1;
 59.7412 +        if (dim !== undefined) {
 59.7413 +            var result = [];
 59.7414 +            for (var i = 0; i < dim; i++) result.push(_randomInteger(min,max));
 59.7415 +            return result;
 59.7416 +        }
 59.7417 +        else return _randomInteger(min,max);
 59.7418 +    };
 59.7419 +
 59.7420 +    /**
 59.7421 +     * Get single random float between min and max (inclusive), or array
 59.7422 +     *   of size dim if specified
 59.7423 +     *
 59.7424 +     * @method range
 59.7425 +     *
 59.7426 +     * @param {Number} min lower bound, default 0
 59.7427 +     * @param {Number} max upper bound, default 1
 59.7428 +     * @param {Number} [dim] dimension of output array, if specified
 59.7429 +     * @return {Number} random float, or optionally an array
 59.7430 +     */
 59.7431 +    Random.range = function range(min,max,dim) {
 59.7432 +        min = (min !== undefined) ? min : 0;
 59.7433 +        max = (max !== undefined) ? max : 1;
 59.7434 +        if (dim !== undefined) {
 59.7435 +            var result = [];
 59.7436 +            for (var i = 0; i < dim; i++) result.push(_randomFloat(min,max));
 59.7437 +            return result;
 59.7438 +        }
 59.7439 +        else return _randomFloat(min,max);
 59.7440 +    };
 59.7441 +
 59.7442 +    /**
 59.7443 +     * Return random number among the set {-1 ,1}
 59.7444 +     *
 59.7445 +     * @method sign
 59.7446 +     *
 59.7447 +     * @param {Number} prob probability of returning 1, default 0.5
 59.7448 +     * @return {Number} random sign (-1 or 1)
 59.7449 +     */
 59.7450 +    Random.sign = function sign(prob) {
 59.7451 +        prob = (prob !== undefined) ? prob : 0.5;
 59.7452 +        return (RAND() < prob) ? 1 : -1;
 59.7453 +    };
 59.7454 +
 59.7455 +    /**
 59.7456 +     * Return random boolean value, true or false.
 59.7457 +     *
 59.7458 +     * @method bool
 59.7459 +     *
 59.7460 +     * @param {Number} prob probability of returning true, default 0.5
 59.7461 +     * @return {Boolean} random boolean
 59.7462 +     */
 59.7463 +    Random.bool = function bool(prob) {
 59.7464 +        prob = (prob !== undefined) ? prob : 0.5;
 59.7465 +        return RAND() < prob;
 59.7466 +    };
 59.7467 +
 59.7468 +    module.exports = Random;
 59.7469 +});
 59.7470 +
 59.7471 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.7472 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.7473 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.7474 + *
 59.7475 + * Owner: david@famo.us
 59.7476 + * @license MPL 2.0
 59.7477 + * @copyright Famous Industries, Inc. 2014
 59.7478 + */
 59.7479 +
 59.7480 +define('famous/events/EventArbiter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.7481 +    var EventHandler = require('famous/core/EventHandler');
 59.7482 +
 59.7483 +    /**
 59.7484 +     * A switch which wraps several event destinations and
 59.7485 +     *  redirects received events to at most one of them.
 59.7486 +     *  Setting the 'mode' of the object dictates which one
 59.7487 +     *  of these destinations will receive events.
 59.7488 +     *
 59.7489 +     * @class EventArbiter
 59.7490 +     * @constructor
 59.7491 +     *
 59.7492 +     * @param {Number | string} startMode initial setting of switch,
 59.7493 +     */
 59.7494 +    function EventArbiter(startMode) {
 59.7495 +        this.dispatchers = {};
 59.7496 +        this.currMode = undefined;
 59.7497 +        this.setMode(startMode);
 59.7498 +    }
 59.7499 +
 59.7500 +    /**
 59.7501 +     * Set switch to this mode, passing events to the corresponding
 59.7502 +     *   EventHandler.  If mode has changed, emits 'change' event,
 59.7503 +     *   emits 'unpipe' event to the old mode's handler, and emits 'pipe'
 59.7504 +     *   event to the new mode's handler.
 59.7505 +     *
 59.7506 +     * @method setMode
 59.7507 +     *
 59.7508 +     * @param {string | number} mode indicating which event handler to send to.
 59.7509 +     */
 59.7510 +    EventArbiter.prototype.setMode = function setMode(mode) {
 59.7511 +        if (mode !== this.currMode) {
 59.7512 +            var startMode = this.currMode;
 59.7513 +
 59.7514 +            if (this.dispatchers[this.currMode]) this.dispatchers[this.currMode].trigger('unpipe');
 59.7515 +            this.currMode = mode;
 59.7516 +            if (this.dispatchers[mode]) this.dispatchers[mode].emit('pipe');
 59.7517 +            this.emit('change', {from: startMode, to: mode});
 59.7518 +        }
 59.7519 +    };
 59.7520 +
 59.7521 +    /**
 59.7522 +     * Return the existing EventHandler corresponding to this
 59.7523 +     *   mode, creating one if it doesn't exist.
 59.7524 +     *
 59.7525 +     * @method forMode
 59.7526 +     *
 59.7527 +     * @param {string | number} mode mode to which this eventHandler corresponds
 59.7528 +     *
 59.7529 +     * @return {EventHandler} eventHandler corresponding to this mode
 59.7530 +     */
 59.7531 +    EventArbiter.prototype.forMode = function forMode(mode) {
 59.7532 +        if (!this.dispatchers[mode]) this.dispatchers[mode] = new EventHandler();
 59.7533 +        return this.dispatchers[mode];
 59.7534 +    };
 59.7535 +
 59.7536 +    /**
 59.7537 +     * Trigger an event, sending to currently selected handler, if
 59.7538 +     *   it is listening for provided 'type' key.
 59.7539 +     *
 59.7540 +     * @method emit
 59.7541 +     *
 59.7542 +     * @param {string} eventType event type key (for example, 'click')
 59.7543 +     * @param {Object} event event data
 59.7544 +     * @return {EventHandler} this
 59.7545 +     */
 59.7546 +    EventArbiter.prototype.emit = function emit(eventType, event) {
 59.7547 +        if (this.currMode === undefined) return false;
 59.7548 +        if (!event) event = {};
 59.7549 +        var dispatcher = this.dispatchers[this.currMode];
 59.7550 +        if (dispatcher) return dispatcher.trigger(eventType, event);
 59.7551 +    };
 59.7552 +
 59.7553 +    module.exports = EventArbiter;
 59.7554 +});
 59.7555 +
 59.7556 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.7557 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.7558 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.7559 + *
 59.7560 + * Owner: david@famo.us
 59.7561 + * @license MPL 2.0
 59.7562 + * @copyright Famous Industries, Inc. 2014
 59.7563 + */
 59.7564 +
 59.7565 +define('famous/events/EventFilter',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.7566 +    var EventHandler = require('famous/core/EventHandler');
 59.7567 +
 59.7568 +    /**
 59.7569 +     * EventFilter regulates the broadcasting of events based on
 59.7570 +     *  a specified condition function of standard event type: function(type, data).
 59.7571 +     *
 59.7572 +     * @class EventFilter
 59.7573 +     * @constructor
 59.7574 +     *
 59.7575 +     * @param {function} condition function to determine whether or not
 59.7576 +     *    events are emitted.
 59.7577 +     */
 59.7578 +    function EventFilter(condition) {
 59.7579 +        EventHandler.call(this);
 59.7580 +        this._condition = condition;
 59.7581 +    }
 59.7582 +    EventFilter.prototype = Object.create(EventHandler.prototype);
 59.7583 +    EventFilter.prototype.constructor = EventFilter;
 59.7584 +
 59.7585 +    /**
 59.7586 +     * If filter condition is met, trigger an event, sending to all downstream handlers
 59.7587 +     *   listening for provided 'type' key.
 59.7588 +     *
 59.7589 +     * @method emit
 59.7590 +     *
 59.7591 +     * @param {string} type event type key (for example, 'click')
 59.7592 +     * @param {Object} data event data
 59.7593 +     * @return {EventHandler} this
 59.7594 +     */
 59.7595 +    EventFilter.prototype.emit = function emit(type, data) {
 59.7596 +        if (this._condition(type, data))
 59.7597 +            return EventHandler.prototype.emit.apply(this, arguments);
 59.7598 +    };
 59.7599 +
 59.7600 +    /**
 59.7601 +     * An alias of emit. Trigger determines whether to send
 59.7602 +     *  events based on the return value of it's condition function
 59.7603 +     *  when passed the event type and associated data.
 59.7604 +     *
 59.7605 +     * @method trigger
 59.7606 +     * @param {string} type name of the event
 59.7607 +     * @param {object} data associated data
 59.7608 +     */
 59.7609 +    EventFilter.prototype.trigger = EventFilter.prototype.emit;
 59.7610 +
 59.7611 +    module.exports = EventFilter;
 59.7612 +});
 59.7613 +
 59.7614 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.7615 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.7616 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.7617 + *
 59.7618 + * Owner: david@famo.us
 59.7619 + * @license MPL 2.0
 59.7620 + * @copyright Famous Industries, Inc. 2014
 59.7621 + */
 59.7622 +
 59.7623 +define('famous/events/EventMapper',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.7624 +    var EventHandler = require('famous/core/EventHandler');
 59.7625 +
 59.7626 +    /**
 59.7627 +     * EventMapper routes events to various event destinations
 59.7628 +     *  based on custom logic.  The function signature is arbitrary.
 59.7629 +     *
 59.7630 +     * @class EventMapper
 59.7631 +     * @constructor
 59.7632 +     *
 59.7633 +     * @param {function} mappingFunction function to determine where
 59.7634 +     *  events are routed to.
 59.7635 +     */
 59.7636 +    function EventMapper(mappingFunction) {
 59.7637 +        EventHandler.call(this);
 59.7638 +        this._mappingFunction = mappingFunction;
 59.7639 +    }
 59.7640 +    EventMapper.prototype = Object.create(EventHandler.prototype);
 59.7641 +    EventMapper.prototype.constructor = EventMapper;
 59.7642 +
 59.7643 +    EventMapper.prototype.subscribe = null;
 59.7644 +    EventMapper.prototype.unsubscribe = null;
 59.7645 +
 59.7646 +    /**
 59.7647 +     * Trigger an event, sending to all mapped downstream handlers
 59.7648 +     *   listening for provided 'type' key.
 59.7649 +     *
 59.7650 +     * @method emit
 59.7651 +     *
 59.7652 +     * @param {string} type event type key (for example, 'click')
 59.7653 +     * @param {Object} data event data
 59.7654 +     * @return {EventHandler} this
 59.7655 +     */
 59.7656 +    EventMapper.prototype.emit = function emit(type, data) {
 59.7657 +        var target = this._mappingFunction.apply(this, arguments);
 59.7658 +        if (target && (target.emit instanceof Function)) target.emit(type, data);
 59.7659 +    };
 59.7660 +
 59.7661 +    /**
 59.7662 +     * Alias of emit.
 59.7663 +     * @method trigger
 59.7664 +     */
 59.7665 +    EventMapper.prototype.trigger = EventMapper.prototype.emit;
 59.7666 +
 59.7667 +    module.exports = EventMapper;
 59.7668 +});
 59.7669 +
 59.7670 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.7671 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.7672 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.7673 + *
 59.7674 + * @license MPL 2.0
 59.7675 + * @copyright Famous Industries, Inc. 2014
 59.7676 + */
 59.7677 +define('famous/physics/PhysicsEngine',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.7678 +    var EventHandler = require('famous/core/EventHandler');
 59.7679 +
 59.7680 +    /**
 59.7681 +     * The Physics Engine is responsible for mediating Bodies and their
 59.7682 +     * interaction with forces and constraints. The Physics Engine handles the
 59.7683 +     * logic of adding and removing bodies, updating their state of the over
 59.7684 +     * time.
 59.7685 +     *
 59.7686 +     * @class PhysicsEngine
 59.7687 +     * @constructor
 59.7688 +     * @param options {Object} options
 59.7689 +     */
 59.7690 +    function PhysicsEngine(options) {
 59.7691 +        this.options = Object.create(PhysicsEngine.DEFAULT_OPTIONS);
 59.7692 +        if (options) this.setOptions(options);
 59.7693 +
 59.7694 +        this._particles      = [];   //list of managed particles
 59.7695 +        this._bodies         = [];   //list of managed bodies
 59.7696 +        this._agents         = {};   //hash of managed agents
 59.7697 +        this._forces         = [];   //list of IDs of agents that are forces
 59.7698 +        this._constraints    = [];   //list of IDs of agents that are constraints
 59.7699 +
 59.7700 +        this._buffer         = 0.0;
 59.7701 +        this._prevTime       = now();
 59.7702 +        this._isSleeping     = false;
 59.7703 +        this._eventHandler   = null;
 59.7704 +        this._currAgentId    = 0;
 59.7705 +        this._hasBodies      = false;
 59.7706 +    }
 59.7707 +
 59.7708 +    var TIMESTEP = 17;
 59.7709 +    var MIN_TIME_STEP = 1000 / 120;
 59.7710 +    var MAX_TIME_STEP = 17;
 59.7711 +
 59.7712 +    /**
 59.7713 +     * @property PhysicsEngine.DEFAULT_OPTIONS
 59.7714 +     * @type Object
 59.7715 +     * @protected
 59.7716 +     * @static
 59.7717 +     */
 59.7718 +    PhysicsEngine.DEFAULT_OPTIONS = {
 59.7719 +
 59.7720 +        /**
 59.7721 +         * The number of iterations the engine takes to resolve constraints
 59.7722 +         * @attribute constraintSteps
 59.7723 +         * @type Number
 59.7724 +         */
 59.7725 +        constraintSteps : 1,
 59.7726 +
 59.7727 +        /**
 59.7728 +         * The energy threshold before the Engine stops updating
 59.7729 +         * @attribute sleepTolerance
 59.7730 +         * @type Number
 59.7731 +         */
 59.7732 +        sleepTolerance  : 1e-7
 59.7733 +    };
 59.7734 +
 59.7735 +    var now = (function() {
 59.7736 +        return Date.now;
 59.7737 +    })();
 59.7738 +
 59.7739 +    /**
 59.7740 +     * Options setter
 59.7741 +     * @method setOptions
 59.7742 +     * @param options {Object}
 59.7743 +     */
 59.7744 +    PhysicsEngine.prototype.setOptions = function setOptions(opts) {
 59.7745 +        for (var key in opts) if (this.options[key]) this.options[key] = opts[key];
 59.7746 +    };
 59.7747 +
 59.7748 +    /**
 59.7749 +     * Method to add a physics body to the engine. Necessary to update the
 59.7750 +     * body over time.
 59.7751 +     *
 59.7752 +     * @method addBody
 59.7753 +     * @param body {Body}
 59.7754 +     * @return body {Body}
 59.7755 +     */
 59.7756 +    PhysicsEngine.prototype.addBody = function addBody(body) {
 59.7757 +        body._engine = this;
 59.7758 +        if (body.isBody) {
 59.7759 +            this._bodies.push(body);
 59.7760 +            this._hasBodies = true;
 59.7761 +        }
 59.7762 +        else this._particles.push(body);
 59.7763 +        return body;
 59.7764 +    };
 59.7765 +
 59.7766 +    /**
 59.7767 +     * Remove a body from the engine. Detaches body from all forces and
 59.7768 +     * constraints.
 59.7769 +     *
 59.7770 +     * @method removeBody
 59.7771 +     * @param body {Body}
 59.7772 +     */
 59.7773 +    PhysicsEngine.prototype.removeBody = function removeBody(body) {
 59.7774 +        var array = (body.isBody) ? this._bodies : this._particles;
 59.7775 +        var index = array.indexOf(body);
 59.7776 +        if (index > -1) {
 59.7777 +            for (var i = 0; i < Object.keys(this._agents).length; i++) this.detachFrom(i, body);
 59.7778 +            array.splice(index,1);
 59.7779 +        }
 59.7780 +        if (this.getBodies().length === 0) this._hasBodies = false;
 59.7781 +    };
 59.7782 +
 59.7783 +    function _mapAgentArray(agent) {
 59.7784 +        if (agent.applyForce)      return this._forces;
 59.7785 +        if (agent.applyConstraint) return this._constraints;
 59.7786 +    }
 59.7787 +
 59.7788 +    function _attachOne(agent, targets, source) {
 59.7789 +        if (targets === undefined) targets = this.getParticlesAndBodies();
 59.7790 +        if (!(targets instanceof Array)) targets = [targets];
 59.7791 +
 59.7792 +        this._agents[this._currAgentId] = {
 59.7793 +            agent   : agent,
 59.7794 +            targets : targets,
 59.7795 +            source  : source
 59.7796 +        };
 59.7797 +
 59.7798 +        _mapAgentArray.call(this, agent).push(this._currAgentId);
 59.7799 +        return this._currAgentId++;
 59.7800 +    }
 59.7801 +
 59.7802 +    /**
 59.7803 +     * Attaches a force or constraint to a Body. Returns an AgentId of the
 59.7804 +     * attached agent which can be used to detach the agent.
 59.7805 +     *
 59.7806 +     * @method attach
 59.7807 +     * @param agent {Agent|Array.Agent} A force, constraint, or array of them.
 59.7808 +     * @param [targets=All] {Body|Array.Body} The Body or Bodies affected by the agent
 59.7809 +     * @param [source] {Body} The source of the agent
 59.7810 +     * @return AgentId {Number}
 59.7811 +     */
 59.7812 +    PhysicsEngine.prototype.attach = function attach(agents, targets, source) {
 59.7813 +        if (agents instanceof Array) {
 59.7814 +            var agentIDs = [];
 59.7815 +            for (var i = 0; i < agents.length; i++)
 59.7816 +                agentIDs[i] = _attachOne.call(this, agents[i], targets, source);
 59.7817 +            return agentIDs;
 59.7818 +        }
 59.7819 +        else return _attachOne.call(this, agents, targets, source);
 59.7820 +    };
 59.7821 +
 59.7822 +    /**
 59.7823 +     * Append a body to the targets of a previously defined physics agent.
 59.7824 +     *
 59.7825 +     * @method attachTo
 59.7826 +     * @param agentID {AgentId} The agentId of a previously defined agent
 59.7827 +     * @param target {Body} The Body affected by the agent
 59.7828 +     */
 59.7829 +    PhysicsEngine.prototype.attachTo = function attachTo(agentID, target) {
 59.7830 +        _getBoundAgent.call(this, agentID).targets.push(target);
 59.7831 +    };
 59.7832 +
 59.7833 +    /**
 59.7834 +     * Undoes PhysicsEngine.attach. Removes an agent and its associated
 59.7835 +     * effect on its affected Bodies.
 59.7836 +     *
 59.7837 +     * @method detach
 59.7838 +     * @param agentID {AgentId} The agentId of a previously defined agent
 59.7839 +     */
 59.7840 +    PhysicsEngine.prototype.detach = function detach(id) {
 59.7841 +        // detach from forces/constraints array
 59.7842 +        var agent = this.getAgent(id);
 59.7843 +        var agentArray = _mapAgentArray.call(this, agent);
 59.7844 +        var index = agentArray.indexOf(id);
 59.7845 +        agentArray.splice(index,1);
 59.7846 +
 59.7847 +        // detach agents array
 59.7848 +        delete this._agents[id];
 59.7849 +    };
 59.7850 +
 59.7851 +    /**
 59.7852 +     * Remove a single Body from a previously defined agent.
 59.7853 +     *
 59.7854 +     * @method detach
 59.7855 +     * @param agentID {AgentId} The agentId of a previously defined agent
 59.7856 +     * @param target {Body} The body to remove from the agent
 59.7857 +     */
 59.7858 +    PhysicsEngine.prototype.detachFrom = function detachFrom(id, target) {
 59.7859 +        var boundAgent = _getBoundAgent.call(this, id);
 59.7860 +        if (boundAgent.source === target) this.detach(id);
 59.7861 +        else {
 59.7862 +            var targets = boundAgent.targets;
 59.7863 +            var index = targets.indexOf(target);
 59.7864 +            if (index > -1) targets.splice(index,1);
 59.7865 +        }
 59.7866 +    };
 59.7867 +
 59.7868 +    /**
 59.7869 +     * A convenience method to give the Physics Engine a clean slate of
 59.7870 +     * agents. Preserves all added Body objects.
 59.7871 +     *
 59.7872 +     * @method detachAll
 59.7873 +     */
 59.7874 +    PhysicsEngine.prototype.detachAll = function detachAll() {
 59.7875 +        this._agents        = {};
 59.7876 +        this._forces        = [];
 59.7877 +        this._constraints   = [];
 59.7878 +        this._currAgentId   = 0;
 59.7879 +    };
 59.7880 +
 59.7881 +    function _getBoundAgent(id) {
 59.7882 +        return this._agents[id];
 59.7883 +    }
 59.7884 +
 59.7885 +    /**
 59.7886 +     * Returns the corresponding agent given its agentId.
 59.7887 +     *
 59.7888 +     * @method getAgent
 59.7889 +     * @param id {AgentId}
 59.7890 +     */
 59.7891 +    PhysicsEngine.prototype.getAgent = function getAgent(id) {
 59.7892 +        return _getBoundAgent.call(this, id).agent;
 59.7893 +    };
 59.7894 +
 59.7895 +    /**
 59.7896 +     * Returns all particles that are currently managed by the Physics Engine.
 59.7897 +     *
 59.7898 +     * @method getParticles
 59.7899 +     * @return particles {Array.Particles}
 59.7900 +     */
 59.7901 +    PhysicsEngine.prototype.getParticles = function getParticles() {
 59.7902 +        return this._particles;
 59.7903 +    };
 59.7904 +
 59.7905 +    /**
 59.7906 +     * Returns all bodies, except particles, that are currently managed by the Physics Engine.
 59.7907 +     *
 59.7908 +     * @method getBodies
 59.7909 +     * @return bodies {Array.Bodies}
 59.7910 +     */
 59.7911 +    PhysicsEngine.prototype.getBodies = function getBodies() {
 59.7912 +        return this._bodies;
 59.7913 +    };
 59.7914 +
 59.7915 +    /**
 59.7916 +     * Returns all bodies that are currently managed by the Physics Engine.
 59.7917 +     *
 59.7918 +     * @method getBodies
 59.7919 +     * @return bodies {Array.Bodies}
 59.7920 +     */
 59.7921 +    PhysicsEngine.prototype.getParticlesAndBodies = function getParticlesAndBodies() {
 59.7922 +        return this.getParticles().concat(this.getBodies());
 59.7923 +    };
 59.7924 +
 59.7925 +    /**
 59.7926 +     * Iterates over every Particle and applies a function whose first
 59.7927 +     * argument is the Particle
 59.7928 +     *
 59.7929 +     * @method forEachParticle
 59.7930 +     * @param fn {Function} Function to iterate over
 59.7931 +     * @param [dt] {Number} Delta time
 59.7932 +     */
 59.7933 +    PhysicsEngine.prototype.forEachParticle = function forEachParticle(fn, dt) {
 59.7934 +        var particles = this.getParticles();
 59.7935 +        for (var index = 0, len = particles.length; index < len; index++)
 59.7936 +            fn.call(this, particles[index], dt);
 59.7937 +    };
 59.7938 +
 59.7939 +    /**
 59.7940 +     * Iterates over every Body that isn't a Particle and applies
 59.7941 +     * a function whose first argument is the Body
 59.7942 +     *
 59.7943 +     * @method forEachBody
 59.7944 +     * @param fn {Function} Function to iterate over
 59.7945 +     * @param [dt] {Number} Delta time
 59.7946 +     */
 59.7947 +    PhysicsEngine.prototype.forEachBody = function forEachBody(fn, dt) {
 59.7948 +        if (!this._hasBodies) return;
 59.7949 +        var bodies = this.getBodies();
 59.7950 +        for (var index = 0, len = bodies.length; index < len; index++)
 59.7951 +            fn.call(this, bodies[index], dt);
 59.7952 +    };
 59.7953 +
 59.7954 +    /**
 59.7955 +     * Iterates over every Body and applies a function whose first
 59.7956 +     * argument is the Body
 59.7957 +     *
 59.7958 +     * @method forEach
 59.7959 +     * @param fn {Function} Function to iterate over
 59.7960 +     * @param [dt] {Number} Delta time
 59.7961 +     */
 59.7962 +    PhysicsEngine.prototype.forEach = function forEach(fn, dt) {
 59.7963 +        this.forEachParticle(fn, dt);
 59.7964 +        this.forEachBody(fn, dt);
 59.7965 +    };
 59.7966 +
 59.7967 +    function _updateForce(index) {
 59.7968 +        var boundAgent = _getBoundAgent.call(this, this._forces[index]);
 59.7969 +        boundAgent.agent.applyForce(boundAgent.targets, boundAgent.source);
 59.7970 +    }
 59.7971 +
 59.7972 +    function _updateForces() {
 59.7973 +        for (var index = this._forces.length - 1; index > -1; index--)
 59.7974 +            _updateForce.call(this, index);
 59.7975 +    }
 59.7976 +
 59.7977 +    function _updateConstraint(index, dt) {
 59.7978 +        var boundAgent = this._agents[this._constraints[index]];
 59.7979 +        return boundAgent.agent.applyConstraint(boundAgent.targets, boundAgent.source, dt);
 59.7980 +    }
 59.7981 +
 59.7982 +    function _updateConstraints(dt) {
 59.7983 +        var iteration = 0;
 59.7984 +        while (iteration < this.options.constraintSteps) {
 59.7985 +            for (var index = this._constraints.length - 1; index > -1; index--)
 59.7986 +                _updateConstraint.call(this, index, dt);
 59.7987 +            iteration++;
 59.7988 +        }
 59.7989 +    }
 59.7990 +
 59.7991 +    function _updateVelocities(particle, dt) {
 59.7992 +        particle.integrateVelocity(dt);
 59.7993 +    }
 59.7994 +
 59.7995 +    function _updateAngularVelocities(body, dt) {
 59.7996 +        body.integrateAngularMomentum(dt);
 59.7997 +        body.updateAngularVelocity();
 59.7998 +    }
 59.7999 +
 59.8000 +    function _updateOrientations(body, dt) {
 59.8001 +        body.integrateOrientation(dt);
 59.8002 +    }
 59.8003 +
 59.8004 +    function _updatePositions(particle, dt) {
 59.8005 +        particle.integratePosition(dt);
 59.8006 +        particle.emit('update', particle);
 59.8007 +    }
 59.8008 +
 59.8009 +    function _integrate(dt) {
 59.8010 +        _updateForces.call(this, dt);
 59.8011 +        this.forEach(_updateVelocities, dt);
 59.8012 +        this.forEachBody(_updateAngularVelocities, dt);
 59.8013 +        _updateConstraints.call(this, dt);
 59.8014 +        this.forEachBody(_updateOrientations, dt);
 59.8015 +        this.forEach(_updatePositions, dt);
 59.8016 +    }
 59.8017 +
 59.8018 +    function _getEnergyParticles() {
 59.8019 +        var energy = 0.0;
 59.8020 +        var particleEnergy = 0.0;
 59.8021 +        this.forEach(function(particle) {
 59.8022 +            particleEnergy = particle.getEnergy();
 59.8023 +            energy += particleEnergy;
 59.8024 +            if (particleEnergy < particle.sleepTolerance) particle.sleep();
 59.8025 +        });
 59.8026 +        return energy;
 59.8027 +    }
 59.8028 +
 59.8029 +    function _getEnergyForces() {
 59.8030 +        var energy = 0;
 59.8031 +        for (var index = this._forces.length - 1; index > -1; index--)
 59.8032 +            energy += this._forces[index].getEnergy() || 0.0;
 59.8033 +        return energy;
 59.8034 +    }
 59.8035 +
 59.8036 +    function _getEnergyConstraints() {
 59.8037 +        var energy = 0;
 59.8038 +        for (var index = this._constraints.length - 1; index > -1; index--)
 59.8039 +            energy += this._constraints[index].getEnergy() || 0.0;
 59.8040 +        return energy;
 59.8041 +    }
 59.8042 +
 59.8043 +    /**
 59.8044 +     * Calculates the kinetic energy of all Body objects and potential energy
 59.8045 +     * of all attached agents.
 59.8046 +     *
 59.8047 +     * TODO: implement.
 59.8048 +     * @method getEnergy
 59.8049 +     * @return energy {Number}
 59.8050 +     */
 59.8051 +    PhysicsEngine.prototype.getEnergy = function getEnergy() {
 59.8052 +        return _getEnergyParticles.call(this) + _getEnergyForces.call(this) + _getEnergyConstraints.call(this);
 59.8053 +    };
 59.8054 +
 59.8055 +    /**
 59.8056 +     * Updates all Body objects managed by the physics engine over the
 59.8057 +     * time duration since the last time step was called.
 59.8058 +     *
 59.8059 +     * @method step
 59.8060 +     */
 59.8061 +    PhysicsEngine.prototype.step = function step() {
 59.8062 +//        if (this.getEnergy() < this.options.sleepTolerance) {
 59.8063 +//            this.sleep();
 59.8064 +//            return;
 59.8065 +//        };
 59.8066 +
 59.8067 +        //set current frame's time
 59.8068 +        var currTime = now();
 59.8069 +
 59.8070 +        //milliseconds elapsed since last frame
 59.8071 +        var dtFrame = currTime - this._prevTime;
 59.8072 +
 59.8073 +        this._prevTime = currTime;
 59.8074 +
 59.8075 +        if (dtFrame < MIN_TIME_STEP) return;
 59.8076 +        if (dtFrame > MAX_TIME_STEP) dtFrame = MAX_TIME_STEP;
 59.8077 +
 59.8078 +        //robust integration
 59.8079 +//        this._buffer += dtFrame;
 59.8080 +//        while (this._buffer > this._timestep){
 59.8081 +//            _integrate.call(this, this._timestep);
 59.8082 +//            this._buffer -= this._timestep;
 59.8083 +//        };
 59.8084 +//        _integrate.call(this, this._buffer);
 59.8085 +//        this._buffer = 0.0;
 59.8086 +        _integrate.call(this, TIMESTEP);
 59.8087 +
 59.8088 +//        this.emit('update', this);
 59.8089 +    };
 59.8090 +
 59.8091 +    /**
 59.8092 +     * Tells whether the Physics Engine is sleeping or awake.
 59.8093 +     * @method isSleeping
 59.8094 +     * @return {Boolean}
 59.8095 +     */
 59.8096 +    PhysicsEngine.prototype.isSleeping = function isSleeping() {
 59.8097 +        return this._isSleeping;
 59.8098 +    };
 59.8099 +
 59.8100 +    /**
 59.8101 +     * Stops the Physics Engine from updating. Emits an 'end' event.
 59.8102 +     * @method sleep
 59.8103 +     */
 59.8104 +    PhysicsEngine.prototype.sleep = function sleep() {
 59.8105 +        this.emit('end', this);
 59.8106 +        this._isSleeping = true;
 59.8107 +    };
 59.8108 +
 59.8109 +    /**
 59.8110 +     * Starts the Physics Engine from updating. Emits an 'start' event.
 59.8111 +     * @method wake
 59.8112 +     */
 59.8113 +    PhysicsEngine.prototype.wake = function wake() {
 59.8114 +        this._prevTime = now();
 59.8115 +        this.emit('start', this);
 59.8116 +        this._isSleeping = false;
 59.8117 +    };
 59.8118 +
 59.8119 +    PhysicsEngine.prototype.emit = function emit(type, data) {
 59.8120 +        if (this._eventHandler === null) return;
 59.8121 +        this._eventHandler.emit(type, data);
 59.8122 +    };
 59.8123 +
 59.8124 +    PhysicsEngine.prototype.on = function on(event, fn) {
 59.8125 +        if (this._eventHandler === null) this._eventHandler = new EventHandler();
 59.8126 +        this._eventHandler.on(event, fn);
 59.8127 +    };
 59.8128 +
 59.8129 +    module.exports = PhysicsEngine;
 59.8130 +});
 59.8131 +
 59.8132 +define('famous/inputs/Accumulator',['require','exports','module','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) {
 59.8133 +    var EventHandler = require('famous/core/EventHandler');
 59.8134 +    var Transitionable = require('famous/transitions/Transitionable');
 59.8135 +
 59.8136 +    /**
 59.8137 +     * Accumulates differentials of event sources that emit a `delta`
 59.8138 +     *  attribute taking a Number or Array of Number types. The accumulated
 59.8139 +     *  value is stored in a getter/setter.
 59.8140 +     *
 59.8141 +     * @class Accumulator
 59.8142 +     * @constructor
 59.8143 +     * @param value {Number|Array|Transitionable}   Initializing value
 59.8144 +     * @param [eventName='update'] {String}         Name of update event
 59.8145 +     */
 59.8146 +    function Accumulator(value, eventName) {
 59.8147 +        if (eventName === undefined) eventName = 'update';
 59.8148 +
 59.8149 +        this._state = (value && value.get && value.set)
 59.8150 +            ? value
 59.8151 +            : new Transitionable(value || 0);
 59.8152 +
 59.8153 +        this._eventInput = new EventHandler();
 59.8154 +        EventHandler.setInputHandler(this, this._eventInput);
 59.8155 +
 59.8156 +        this._eventInput.on(eventName, _handleUpdate.bind(this));
 59.8157 +    }
 59.8158 +
 59.8159 +    function _handleUpdate(data) {
 59.8160 +        var delta = data.delta;
 59.8161 +        var state = this.get();
 59.8162 +
 59.8163 +        if (delta.constructor === state.constructor){
 59.8164 +            var newState = (delta instanceof Array)
 59.8165 +                ? [state[0] + delta[0], state[1] + delta[1]]
 59.8166 +                : state + delta;
 59.8167 +            this.set(newState);
 59.8168 +        }
 59.8169 +    }
 59.8170 +
 59.8171 +    /**
 59.8172 +     * Basic getter
 59.8173 +     *
 59.8174 +     * @method get
 59.8175 +     * @return {Number|Array} current value
 59.8176 +     */
 59.8177 +    Accumulator.prototype.get = function get() {
 59.8178 +        return this._state.get();
 59.8179 +    };
 59.8180 +
 59.8181 +    /**
 59.8182 +     * Basic setter
 59.8183 +     *
 59.8184 +     * @method set
 59.8185 +     * @param value {Number|Array} new value
 59.8186 +     */
 59.8187 +    Accumulator.prototype.set = function set(value) {
 59.8188 +        this._state.set(value);
 59.8189 +    };
 59.8190 +
 59.8191 +    module.exports = Accumulator;
 59.8192 +});
 59.8193 +
 59.8194 +define('famous/inputs/DesktopEmulationMode',['require','exports','module'],function(require, exports, module) {
 59.8195 +    var hasTouch = 'ontouchstart' in window;
 59.8196 +
 59.8197 +    function kill(type) {
 59.8198 +        window.addEventListener(type, function(event) {
 59.8199 +            event.stopPropagation();
 59.8200 +            return false;
 59.8201 +        }, true);
 59.8202 +    }
 59.8203 +
 59.8204 +    if (hasTouch) {
 59.8205 +        kill('mousedown');
 59.8206 +        kill('mousemove');
 59.8207 +        kill('mouseup');
 59.8208 +        kill('mouseleave');
 59.8209 +    }
 59.8210 +});
 59.8211 +
 59.8212 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8213 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8214 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8215 + *
 59.8216 + * Owner: mark@famo.us
 59.8217 + * @license MPL 2.0
 59.8218 + * @copyright Famous Industries, Inc. 2014
 59.8219 + */
 59.8220 +
 59.8221 +define('famous/inputs/FastClick',['require','exports','module'],function(require, exports, module) {
 59.8222 +    /**
 59.8223 +     * FastClick is an override shim which maps event pairs of
 59.8224 +     *   'touchstart' and 'touchend' which differ by less than a certain
 59.8225 +     *   threshold to the 'click' event.
 59.8226 +     *   This is used to speed up clicks on some browsers.
 59.8227 +     */
 59.8228 +    if (!window.CustomEvent) return;
 59.8229 +    var clickThreshold = 300;
 59.8230 +    var clickWindow = 500;
 59.8231 +    var potentialClicks = {};
 59.8232 +    var recentlyDispatched = {};
 59.8233 +    var _now = Date.now;
 59.8234 +
 59.8235 +    window.addEventListener('touchstart', function(event) {
 59.8236 +        var timestamp = _now();
 59.8237 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8238 +            var touch = event.changedTouches[i];
 59.8239 +            potentialClicks[touch.identifier] = timestamp;
 59.8240 +        }
 59.8241 +    });
 59.8242 +
 59.8243 +    window.addEventListener('touchmove', function(event) {
 59.8244 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8245 +            var touch = event.changedTouches[i];
 59.8246 +            delete potentialClicks[touch.identifier];
 59.8247 +        }
 59.8248 +    });
 59.8249 +
 59.8250 +    window.addEventListener('touchend', function(event) {
 59.8251 +        var currTime = _now();
 59.8252 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8253 +            var touch = event.changedTouches[i];
 59.8254 +            var startTime = potentialClicks[touch.identifier];
 59.8255 +            if (startTime && currTime - startTime < clickThreshold) {
 59.8256 +                var clickEvt = new window.CustomEvent('click', {
 59.8257 +                    'bubbles': true,
 59.8258 +                    'details': touch
 59.8259 +                });
 59.8260 +                recentlyDispatched[currTime] = event;
 59.8261 +                event.target.dispatchEvent(clickEvt);
 59.8262 +            }
 59.8263 +            delete potentialClicks[touch.identifier];
 59.8264 +        }
 59.8265 +    });
 59.8266 +
 59.8267 +    window.addEventListener('click', function(event) {
 59.8268 +        var currTime = _now();
 59.8269 +        for (var i in recentlyDispatched) {
 59.8270 +            var previousEvent = recentlyDispatched[i];
 59.8271 +            if (currTime - i < clickWindow) {
 59.8272 +                if (event instanceof window.MouseEvent && event.target === previousEvent.target) event.stopPropagation();
 59.8273 +            }
 59.8274 +            else delete recentlyDispatched[i];
 59.8275 +        }
 59.8276 +    }, true);
 59.8277 +});
 59.8278 +
 59.8279 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8280 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8281 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8282 + *
 59.8283 + * Owner: mark@famo.us
 59.8284 + * @license MPL 2.0
 59.8285 + * @copyright Famous Industries, Inc. 2014
 59.8286 + */
 59.8287 +
 59.8288 +define('famous/inputs/TwoFingerSync',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.8289 +    var EventHandler = require('famous/core/EventHandler');
 59.8290 +
 59.8291 +    /**
 59.8292 +     * Helper to PinchSync, RotateSync, and ScaleSync.  Generalized handling of
 59.8293 +     *   two-finger touch events.
 59.8294 +     *   This class is meant to be overridden and not used directly.
 59.8295 +     *
 59.8296 +     * @class TwoFingerSync
 59.8297 +     * @constructor
 59.8298 +     */
 59.8299 +    function TwoFingerSync() {
 59.8300 +        this._eventInput = new EventHandler();
 59.8301 +        this._eventOutput = new EventHandler();
 59.8302 +
 59.8303 +        EventHandler.setInputHandler(this, this._eventInput);
 59.8304 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.8305 +
 59.8306 +        this.touchAEnabled = false;
 59.8307 +        this.touchAId = 0;
 59.8308 +        this.posA = null;
 59.8309 +        this.timestampA = 0;
 59.8310 +        this.touchBEnabled = false;
 59.8311 +        this.touchBId = 0;
 59.8312 +        this.posB = null;
 59.8313 +        this.timestampB = 0;
 59.8314 +
 59.8315 +        this._eventInput.on('touchstart', this.handleStart.bind(this));
 59.8316 +        this._eventInput.on('touchmove', this.handleMove.bind(this));
 59.8317 +        this._eventInput.on('touchend', this.handleEnd.bind(this));
 59.8318 +        this._eventInput.on('touchcancel', this.handleEnd.bind(this));
 59.8319 +    }
 59.8320 +
 59.8321 +    TwoFingerSync.calculateAngle = function(posA, posB) {
 59.8322 +        var diffX = posB[0] - posA[0];
 59.8323 +        var diffY = posB[1] - posA[1];
 59.8324 +        return Math.atan2(diffY, diffX);
 59.8325 +    };
 59.8326 +
 59.8327 +    TwoFingerSync.calculateDistance = function(posA, posB) {
 59.8328 +        var diffX = posB[0] - posA[0];
 59.8329 +        var diffY = posB[1] - posA[1];
 59.8330 +        return Math.sqrt(diffX * diffX + diffY * diffY);
 59.8331 +    };
 59.8332 +
 59.8333 +    TwoFingerSync.calculateCenter = function(posA, posB) {
 59.8334 +        return [(posA[0] + posB[0]) / 2.0, (posA[1] + posB[1]) / 2.0];
 59.8335 +    };
 59.8336 +
 59.8337 +    var _now = Date.now;
 59.8338 +
 59.8339 +    // private
 59.8340 +    TwoFingerSync.prototype.handleStart = function handleStart(event) {
 59.8341 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8342 +            var touch = event.changedTouches[i];
 59.8343 +            if (!this.touchAEnabled) {
 59.8344 +                this.touchAId = touch.identifier;
 59.8345 +                this.touchAEnabled = true;
 59.8346 +                this.posA = [touch.pageX, touch.pageY];
 59.8347 +                this.timestampA = _now();
 59.8348 +            }
 59.8349 +            else if (!this.touchBEnabled) {
 59.8350 +                this.touchBId = touch.identifier;
 59.8351 +                this.touchBEnabled = true;
 59.8352 +                this.posB = [touch.pageX, touch.pageY];
 59.8353 +                this.timestampB = _now();
 59.8354 +                this._startUpdate(event);
 59.8355 +            }
 59.8356 +        }
 59.8357 +    };
 59.8358 +
 59.8359 +    // private
 59.8360 +    TwoFingerSync.prototype.handleMove = function handleMove(event) {
 59.8361 +        if (!(this.touchAEnabled && this.touchBEnabled)) return;
 59.8362 +        var prevTimeA = this.timestampA;
 59.8363 +        var prevTimeB = this.timestampB;
 59.8364 +        var diffTime;
 59.8365 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8366 +            var touch = event.changedTouches[i];
 59.8367 +            if (touch.identifier === this.touchAId) {
 59.8368 +                this.posA = [touch.pageX, touch.pageY];
 59.8369 +                this.timestampA = _now();
 59.8370 +                diffTime = this.timestampA - prevTimeA;
 59.8371 +            }
 59.8372 +            else if (touch.identifier === this.touchBId) {
 59.8373 +                this.posB = [touch.pageX, touch.pageY];
 59.8374 +                this.timestampB = _now();
 59.8375 +                diffTime = this.timestampB - prevTimeB;
 59.8376 +            }
 59.8377 +        }
 59.8378 +        if (diffTime) this._moveUpdate(diffTime);
 59.8379 +    };
 59.8380 +
 59.8381 +    // private
 59.8382 +    TwoFingerSync.prototype.handleEnd = function handleEnd(event) {
 59.8383 +        for (var i = 0; i < event.changedTouches.length; i++) {
 59.8384 +            var touch = event.changedTouches[i];
 59.8385 +            if (touch.identifier === this.touchAId || touch.identifier === this.touchBId) {
 59.8386 +                if (this.touchAEnabled && this.touchBEnabled) {
 59.8387 +                    this._eventOutput.emit('end', {
 59.8388 +                        touches : [this.touchAId, this.touchBId],
 59.8389 +                        angle   : this._angle
 59.8390 +                    });
 59.8391 +                }
 59.8392 +                this.touchAEnabled = false;
 59.8393 +                this.touchAId = 0;
 59.8394 +                this.touchBEnabled = false;
 59.8395 +                this.touchBId = 0;
 59.8396 +            }
 59.8397 +        }
 59.8398 +    };
 59.8399 +
 59.8400 +    module.exports = TwoFingerSync;
 59.8401 +});
 59.8402 +
 59.8403 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8404 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8405 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8406 + *
 59.8407 + * Owner: mark@famo.us
 59.8408 + * @license MPL 2.0
 59.8409 + * @copyright Famous Industries, Inc. 2014
 59.8410 + */
 59.8411 +
 59.8412 +define('famous/inputs/PinchSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 59.8413 +    var TwoFingerSync = require('./TwoFingerSync');
 59.8414 +
 59.8415 +    /**
 59.8416 +     * Handles piped in two-finger touch events to change position via pinching / expanding.
 59.8417 +     *   Emits 'start', 'update' and 'end' events with
 59.8418 +     *   position, velocity, touch ids, and distance between fingers.
 59.8419 +     *
 59.8420 +     * @class PinchSync
 59.8421 +     * @extends TwoFingerSync
 59.8422 +     * @constructor
 59.8423 +     * @param {Object} options default options overrides
 59.8424 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8425 +     */
 59.8426 +    function PinchSync(options) {
 59.8427 +        TwoFingerSync.call(this);
 59.8428 +
 59.8429 +        this.options = Object.create(PinchSync.DEFAULT_OPTIONS);
 59.8430 +        if (options) this.setOptions(options);
 59.8431 +
 59.8432 +        this._displacement = 0;
 59.8433 +        this._previousDistance = 0;
 59.8434 +    }
 59.8435 +
 59.8436 +    PinchSync.prototype = Object.create(TwoFingerSync.prototype);
 59.8437 +    PinchSync.prototype.constructor = PinchSync;
 59.8438 +
 59.8439 +    PinchSync.DEFAULT_OPTIONS = {
 59.8440 +        scale : 1
 59.8441 +    };
 59.8442 +
 59.8443 +    PinchSync.prototype._startUpdate = function _startUpdate(event) {
 59.8444 +        this._previousDistance = TwoFingerSync.calculateDistance(this.posA, this.posB);
 59.8445 +        this._displacement = 0;
 59.8446 +
 59.8447 +        this._eventOutput.emit('start', {
 59.8448 +            count: event.touches.length,
 59.8449 +            touches: [this.touchAId, this.touchBId],
 59.8450 +            distance: this._dist,
 59.8451 +            center: TwoFingerSync.calculateCenter(this.posA, this.posB)
 59.8452 +        });
 59.8453 +    };
 59.8454 +
 59.8455 +    PinchSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 59.8456 +        var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 59.8457 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 59.8458 +
 59.8459 +        var scale = this.options.scale;
 59.8460 +        var delta = scale * (currDist - this._previousDistance);
 59.8461 +        var velocity = delta / diffTime;
 59.8462 +
 59.8463 +        this._previousDistance = currDist;
 59.8464 +        this._displacement += delta;
 59.8465 +
 59.8466 +        this._eventOutput.emit('update', {
 59.8467 +            delta : delta,
 59.8468 +            velocity: velocity,
 59.8469 +            distance: currDist,
 59.8470 +            displacement: this._displacement,
 59.8471 +            center: center,
 59.8472 +            touches: [this.touchAId, this.touchBId]
 59.8473 +        });
 59.8474 +    };
 59.8475 +
 59.8476 +    /**
 59.8477 +     * Return entire options dictionary, including defaults.
 59.8478 +     *
 59.8479 +     * @method getOptions
 59.8480 +     * @return {Object} configuration options
 59.8481 +     */
 59.8482 +    PinchSync.prototype.getOptions = function getOptions() {
 59.8483 +        return this.options;
 59.8484 +    };
 59.8485 +
 59.8486 +    /**
 59.8487 +     * Set internal options, overriding any default options
 59.8488 +     *
 59.8489 +     * @method setOptions
 59.8490 +     *
 59.8491 +     * @param {Object} [options] overrides of default options
 59.8492 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8493 +     */
 59.8494 +    PinchSync.prototype.setOptions = function setOptions(options) {
 59.8495 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.8496 +    };
 59.8497 +
 59.8498 +    module.exports = PinchSync;
 59.8499 +});
 59.8500 +
 59.8501 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8502 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8503 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8504 + *
 59.8505 + * Owner: mark@famo.us
 59.8506 + * @license MPL 2.0
 59.8507 + * @copyright Famous Industries, Inc. 2014
 59.8508 + */
 59.8509 +
 59.8510 +define('famous/inputs/RotateSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 59.8511 +    var TwoFingerSync = require('./TwoFingerSync');
 59.8512 +
 59.8513 +    /**
 59.8514 +     * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding.
 59.8515 +     *   Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, and angle.
 59.8516 +     *   Useful for determining a rotation factor from initial two-finger touch.
 59.8517 +     *
 59.8518 +     * @class RotateSync
 59.8519 +     * @extends TwoFingerSync
 59.8520 +     * @constructor
 59.8521 +     * @param {Object} options default options overrides
 59.8522 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8523 +     */
 59.8524 +    function RotateSync(options) {
 59.8525 +        TwoFingerSync.call(this);
 59.8526 +
 59.8527 +        this.options = Object.create(RotateSync.DEFAULT_OPTIONS);
 59.8528 +        if (options) this.setOptions(options);
 59.8529 +
 59.8530 +        this._angle = 0;
 59.8531 +        this._previousAngle = 0;
 59.8532 +    }
 59.8533 +
 59.8534 +    RotateSync.prototype = Object.create(TwoFingerSync.prototype);
 59.8535 +    RotateSync.prototype.constructor = RotateSync;
 59.8536 +
 59.8537 +    RotateSync.DEFAULT_OPTIONS = {
 59.8538 +        scale : 1
 59.8539 +    };
 59.8540 +
 59.8541 +    RotateSync.prototype._startUpdate = function _startUpdate(event) {
 59.8542 +        this._angle = 0;
 59.8543 +        this._previousAngle = TwoFingerSync.calculateAngle(this.posA, this.posB);
 59.8544 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 59.8545 +        this._eventOutput.emit('start', {
 59.8546 +            count: event.touches.length,
 59.8547 +            angle: this._angle,
 59.8548 +            center: center,
 59.8549 +            touches: [this.touchAId, this.touchBId]
 59.8550 +        });
 59.8551 +    };
 59.8552 +
 59.8553 +    RotateSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 59.8554 +        var scale = this.options.scale;
 59.8555 +
 59.8556 +        var currAngle = TwoFingerSync.calculateAngle(this.posA, this.posB);
 59.8557 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 59.8558 +
 59.8559 +        var diffTheta = scale * (currAngle - this._previousAngle);
 59.8560 +        var velTheta = diffTheta / diffTime;
 59.8561 +
 59.8562 +        this._angle += diffTheta;
 59.8563 +
 59.8564 +        this._eventOutput.emit('update', {
 59.8565 +            delta : diffTheta,
 59.8566 +            velocity: velTheta,
 59.8567 +            angle: this._angle,
 59.8568 +            center: center,
 59.8569 +            touches: [this.touchAId, this.touchBId]
 59.8570 +        });
 59.8571 +
 59.8572 +        this._previousAngle = currAngle;
 59.8573 +    };
 59.8574 +
 59.8575 +    /**
 59.8576 +     * Return entire options dictionary, including defaults.
 59.8577 +     *
 59.8578 +     * @method getOptions
 59.8579 +     * @return {Object} configuration options
 59.8580 +     */
 59.8581 +    RotateSync.prototype.getOptions = function getOptions() {
 59.8582 +        return this.options;
 59.8583 +    };
 59.8584 +
 59.8585 +    /**
 59.8586 +     * Set internal options, overriding any default options
 59.8587 +     *
 59.8588 +     * @method setOptions
 59.8589 +     *
 59.8590 +     * @param {Object} [options] overrides of default options
 59.8591 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8592 +     */
 59.8593 +    RotateSync.prototype.setOptions = function setOptions(options) {
 59.8594 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.8595 +    };
 59.8596 +
 59.8597 +    module.exports = RotateSync;
 59.8598 +});
 59.8599 +
 59.8600 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8601 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8602 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8603 + *
 59.8604 + * Owner: mark@famo.us
 59.8605 + * @license MPL 2.0
 59.8606 + * @copyright Famous Industries, Inc. 2014
 59.8607 + */
 59.8608 +
 59.8609 +define('famous/inputs/ScaleSync',['require','exports','module','./TwoFingerSync'],function(require, exports, module) {
 59.8610 +    var TwoFingerSync = require('./TwoFingerSync');
 59.8611 +
 59.8612 +    /**
 59.8613 +     * Handles piped in two-finger touch events to increase or decrease scale via pinching / expanding.
 59.8614 +     *   Emits 'start', 'update' and 'end' events an object with position, velocity, touch ids, distance, and scale factor.
 59.8615 +     *   Useful for determining a scaling factor from initial two-finger touch.
 59.8616 +     *
 59.8617 +     * @class ScaleSync
 59.8618 +     * @extends TwoFingerSync
 59.8619 +     * @constructor
 59.8620 +     * @param {Object} options default options overrides
 59.8621 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8622 +     */
 59.8623 +    function ScaleSync(options) {
 59.8624 +        TwoFingerSync.call(this);
 59.8625 +
 59.8626 +        this.options = Object.create(ScaleSync.DEFAULT_OPTIONS);
 59.8627 +        if (options) this.setOptions(options);
 59.8628 +
 59.8629 +        this._scaleFactor = 1;
 59.8630 +        this._startDist = 0;
 59.8631 +        this._eventInput.on('pipe', _reset.bind(this));
 59.8632 +    }
 59.8633 +
 59.8634 +    ScaleSync.prototype = Object.create(TwoFingerSync.prototype);
 59.8635 +    ScaleSync.prototype.constructor = ScaleSync;
 59.8636 +
 59.8637 +    ScaleSync.DEFAULT_OPTIONS = {
 59.8638 +        scale : 1
 59.8639 +    };
 59.8640 +
 59.8641 +    function _reset() {
 59.8642 +        this.touchAId = undefined;
 59.8643 +        this.touchBId = undefined;
 59.8644 +    }
 59.8645 +
 59.8646 +    // handles initial touch of two fingers
 59.8647 +    ScaleSync.prototype._startUpdate = function _startUpdate(event) {
 59.8648 +        this._scaleFactor = 1;
 59.8649 +        this._startDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 59.8650 +        this._eventOutput.emit('start', {
 59.8651 +            count: event.touches.length,
 59.8652 +            touches: [this.touchAId, this.touchBId],
 59.8653 +            distance: this._startDist,
 59.8654 +            center: TwoFingerSync.calculateCenter(this.posA, this.posB)
 59.8655 +        });
 59.8656 +    };
 59.8657 +
 59.8658 +    // handles movement of two fingers
 59.8659 +    ScaleSync.prototype._moveUpdate = function _moveUpdate(diffTime) {
 59.8660 +        var scale = this.options.scale;
 59.8661 +
 59.8662 +        var currDist = TwoFingerSync.calculateDistance(this.posA, this.posB);
 59.8663 +        var center = TwoFingerSync.calculateCenter(this.posA, this.posB);
 59.8664 +
 59.8665 +        var delta = (currDist - this._startDist) / this._startDist;
 59.8666 +        var newScaleFactor = Math.max(1 + scale * delta, 0);
 59.8667 +        var veloScale = (newScaleFactor - this._scaleFactor) / diffTime;
 59.8668 +
 59.8669 +        this._eventOutput.emit('update', {
 59.8670 +            delta : delta,
 59.8671 +            scale: newScaleFactor,
 59.8672 +            velocity: veloScale,
 59.8673 +            distance: currDist,
 59.8674 +            center : center,
 59.8675 +            touches: [this.touchAId, this.touchBId]
 59.8676 +        });
 59.8677 +
 59.8678 +        this._scaleFactor = newScaleFactor;
 59.8679 +    };
 59.8680 +
 59.8681 +    /**
 59.8682 +     * Return entire options dictionary, including defaults.
 59.8683 +     *
 59.8684 +     * @method getOptions
 59.8685 +     * @return {Object} configuration options
 59.8686 +     */
 59.8687 +    ScaleSync.prototype.getOptions = function getOptions() {
 59.8688 +        return this.options;
 59.8689 +    };
 59.8690 +
 59.8691 +    /**
 59.8692 +     * Set internal options, overriding any default options
 59.8693 +     *
 59.8694 +     * @method setOptions
 59.8695 +     *
 59.8696 +     * @param {Object} [options] overrides of default options
 59.8697 +     * @param {Number} [options.scale] scale velocity by this factor
 59.8698 +     */
 59.8699 +    ScaleSync.prototype.setOptions = function setOptions(options) {
 59.8700 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.8701 +    };
 59.8702 +
 59.8703 +    module.exports = ScaleSync;
 59.8704 +});
 59.8705 +
 59.8706 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8707 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8708 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8709 + *
 59.8710 + * Owner: mark@famo.us
 59.8711 + * @license MPL 2.0
 59.8712 + * @copyright Famous Industries, Inc. 2014
 59.8713 + */
 59.8714 +
 59.8715 +define('famous/inputs/ScrollSync',['require','exports','module','famous/core/EventHandler','famous/core/Engine'],function(require, exports, module) {
 59.8716 +    var EventHandler = require('famous/core/EventHandler');
 59.8717 +    var Engine = require('famous/core/Engine');
 59.8718 +
 59.8719 +    /**
 59.8720 +     * Handles piped in mousewheel events.
 59.8721 +     *   Emits 'start', 'update', and 'end' events with payloads including:
 59.8722 +     *   delta: change since last position,
 59.8723 +     *   position: accumulated deltas,
 59.8724 +     *   velocity: speed of change in pixels per ms,
 59.8725 +     *   slip: true (unused).
 59.8726 +     *
 59.8727 +     *   Can be used as delegate of GenericSync.
 59.8728 +     *
 59.8729 +     * @class ScrollSync
 59.8730 +     * @constructor
 59.8731 +     * @param {Object} [options] overrides of default options
 59.8732 +     * @param {Number} [options.direction] Pay attention to x changes (ScrollSync.DIRECTION_X),
 59.8733 +     *   y changes (ScrollSync.DIRECTION_Y) or both (undefined)
 59.8734 +     * @param {Number} [options.minimumEndSpeed] End speed calculation floors at this number, in pixels per ms
 59.8735 +     * @param {boolean} [options.rails] whether to snap position calculations to nearest axis
 59.8736 +     * @param {Number | Array.Number} [options.scale] scale outputs in by scalar or pair of scalars
 59.8737 +     * @param {Number} [options.stallTime] reset time for velocity calculation in ms
 59.8738 +     */
 59.8739 +    function ScrollSync(options) {
 59.8740 +        this.options = Object.create(ScrollSync.DEFAULT_OPTIONS);
 59.8741 +        if (options) this.setOptions(options);
 59.8742 +
 59.8743 +        this._payload = {
 59.8744 +            delta    : null,
 59.8745 +            position : null,
 59.8746 +            velocity : null,
 59.8747 +            slip     : true
 59.8748 +        };
 59.8749 +
 59.8750 +        this._eventInput = new EventHandler();
 59.8751 +        this._eventOutput = new EventHandler();
 59.8752 +
 59.8753 +        EventHandler.setInputHandler(this, this._eventInput);
 59.8754 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.8755 +
 59.8756 +        this._position = (this.options.direction === undefined) ? [0,0] : 0;
 59.8757 +        this._prevTime = undefined;
 59.8758 +        this._prevVel = undefined;
 59.8759 +        this._eventInput.on('mousewheel', _handleMove.bind(this));
 59.8760 +        this._eventInput.on('wheel', _handleMove.bind(this));
 59.8761 +        this._inProgress = false;
 59.8762 +        this._loopBound = false;
 59.8763 +    }
 59.8764 +
 59.8765 +    ScrollSync.DEFAULT_OPTIONS = {
 59.8766 +        direction: undefined,
 59.8767 +        minimumEndSpeed: Infinity,
 59.8768 +        rails: false,
 59.8769 +        scale: 1,
 59.8770 +        stallTime: 50,
 59.8771 +        lineHeight: 40
 59.8772 +    };
 59.8773 +
 59.8774 +    ScrollSync.DIRECTION_X = 0;
 59.8775 +    ScrollSync.DIRECTION_Y = 1;
 59.8776 +
 59.8777 +    var MINIMUM_TICK_TIME = 8;
 59.8778 +
 59.8779 +    var _now = Date.now;
 59.8780 +
 59.8781 +    function _newFrame() {
 59.8782 +        if (this._inProgress && (_now() - this._prevTime) > this.options.stallTime) {
 59.8783 +            this._position = (this.options.direction === undefined) ? [0,0] : 0;
 59.8784 +            this._inProgress = false;
 59.8785 +
 59.8786 +            var finalVel = (Math.abs(this._prevVel) >= this.options.minimumEndSpeed)
 59.8787 +                ? this._prevVel
 59.8788 +                : 0;
 59.8789 +
 59.8790 +            var payload = this._payload;
 59.8791 +            payload.position = this._position;
 59.8792 +            payload.velocity = finalVel;
 59.8793 +            payload.slip = true;
 59.8794 +
 59.8795 +            this._eventOutput.emit('end', payload);
 59.8796 +        }
 59.8797 +    }
 59.8798 +
 59.8799 +    function _handleMove(event) {
 59.8800 +        event.preventDefault();
 59.8801 +
 59.8802 +        if (!this._inProgress) {
 59.8803 +            this._inProgress = true;
 59.8804 +
 59.8805 +            payload = this._payload;
 59.8806 +            payload.slip = true;
 59.8807 +            payload.position = this._position;
 59.8808 +            payload.clientX = event.clientX;
 59.8809 +            payload.clientY = event.clientY;
 59.8810 +            payload.offsetX = event.offsetX;
 59.8811 +            payload.offsetY = event.offsetY;
 59.8812 +            this._eventOutput.emit('start', payload);
 59.8813 +            if (!this._loopBound) {
 59.8814 +                Engine.on('prerender', _newFrame.bind(this));
 59.8815 +                this._loopBound = true;
 59.8816 +            }
 59.8817 +        }
 59.8818 +
 59.8819 +        var currTime = _now();
 59.8820 +        var prevTime = this._prevTime || currTime;
 59.8821 +
 59.8822 +        var diffX = (event.wheelDeltaX !== undefined) ? event.wheelDeltaX : -event.deltaX;
 59.8823 +        var diffY = (event.wheelDeltaY !== undefined) ? event.wheelDeltaY : -event.deltaY;
 59.8824 +
 59.8825 +        if (event.deltaMode === 1) { // units in lines, not pixels
 59.8826 +            diffX *= this.options.lineHeight;
 59.8827 +            diffY *= this.options.lineHeight;
 59.8828 +        }
 59.8829 +
 59.8830 +        if (this.options.rails) {
 59.8831 +            if (Math.abs(diffX) > Math.abs(diffY)) diffY = 0;
 59.8832 +            else diffX = 0;
 59.8833 +        }
 59.8834 +
 59.8835 +        var diffTime = Math.max(currTime - prevTime, MINIMUM_TICK_TIME); // minimum tick time
 59.8836 +
 59.8837 +        var velX = diffX / diffTime;
 59.8838 +        var velY = diffY / diffTime;
 59.8839 +
 59.8840 +        var scale = this.options.scale;
 59.8841 +        var nextVel;
 59.8842 +        var nextDelta;
 59.8843 +
 59.8844 +        if (this.options.direction === ScrollSync.DIRECTION_X) {
 59.8845 +            nextDelta = scale * diffX;
 59.8846 +            nextVel = scale * velX;
 59.8847 +            this._position += nextDelta;
 59.8848 +        }
 59.8849 +        else if (this.options.direction === ScrollSync.DIRECTION_Y) {
 59.8850 +            nextDelta = scale * diffY;
 59.8851 +            nextVel = scale * velY;
 59.8852 +            this._position += nextDelta;
 59.8853 +        }
 59.8854 +        else {
 59.8855 +            nextDelta = [scale * diffX, scale * diffY];
 59.8856 +            nextVel = [scale * velX, scale * velY];
 59.8857 +            this._position[0] += nextDelta[0];
 59.8858 +            this._position[1] += nextDelta[1];
 59.8859 +        }
 59.8860 +
 59.8861 +        var payload = this._payload;
 59.8862 +        payload.delta    = nextDelta;
 59.8863 +        payload.velocity = nextVel;
 59.8864 +        payload.position = this._position;
 59.8865 +        payload.slip     = true;
 59.8866 +
 59.8867 +        this._eventOutput.emit('update', payload);
 59.8868 +
 59.8869 +        this._prevTime = currTime;
 59.8870 +        this._prevVel = nextVel;
 59.8871 +    }
 59.8872 +
 59.8873 +    /**
 59.8874 +     * Return entire options dictionary, including defaults.
 59.8875 +     *
 59.8876 +     * @method getOptions
 59.8877 +     * @return {Object} configuration options
 59.8878 +     */
 59.8879 +    ScrollSync.prototype.getOptions = function getOptions() {
 59.8880 +        return this.options;
 59.8881 +    };
 59.8882 +
 59.8883 +    /**
 59.8884 +     * Set internal options, overriding any default options
 59.8885 +     *
 59.8886 +     * @method setOptions
 59.8887 +     *
 59.8888 +     * @param {Object} [options] overrides of default options
 59.8889 +     * @param {Number} [options.minimimEndSpeed] If final velocity smaller than this, round down to 0.
 59.8890 +     * @param {Number} [options.stallTime] ms of non-motion before 'end' emitted
 59.8891 +     * @param {Number} [options.rails] whether to constrain to nearest axis.
 59.8892 +     * @param {Number} [options.direction] ScrollSync.DIRECTION_X, DIRECTION_Y -
 59.8893 +     *    pay attention to one specific direction.
 59.8894 +     * @param {Number} [options.scale] constant factor to scale velocity output
 59.8895 +     */
 59.8896 +    ScrollSync.prototype.setOptions = function setOptions(options) {
 59.8897 +        if (options.direction !== undefined) this.options.direction = options.direction;
 59.8898 +        if (options.minimumEndSpeed !== undefined) this.options.minimumEndSpeed = options.minimumEndSpeed;
 59.8899 +        if (options.rails !== undefined) this.options.rails = options.rails;
 59.8900 +        if (options.scale !== undefined) this.options.scale = options.scale;
 59.8901 +        if (options.stallTime !== undefined) this.options.stallTime = options.stallTime;
 59.8902 +    };
 59.8903 +
 59.8904 +    module.exports = ScrollSync;
 59.8905 +});
 59.8906 +
 59.8907 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8908 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8909 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8910 + *
 59.8911 + * Owner: david@famo.us
 59.8912 + * @license MPL 2.0
 59.8913 + * @copyright Famous Industries, Inc. 2014
 59.8914 + */
 59.8915 +
 59.8916 +define('famous/transitions/CachedMap',['require','exports','module'],function(require, exports, module) {
 59.8917 +    /**
 59.8918 +     * A simple in-memory object cache.  Used as a helper for Views with
 59.8919 +     * provider functions.
 59.8920 +     * @class CachedMap
 59.8921 +     * @constructor
 59.8922 +     */
 59.8923 +    function CachedMap(mappingFunction) {
 59.8924 +        this._map = mappingFunction || null;
 59.8925 +        this._cachedOutput = null;
 59.8926 +        this._cachedInput = Number.NaN; //never valid as input
 59.8927 +    }
 59.8928 +
 59.8929 +    /**
 59.8930 +     * Creates a mapping function with a cache.
 59.8931 +     * This is the main entrypoint for this object.
 59.8932 +     * @static
 59.8933 +     * @method create
 59.8934 +     * @param {function} mappingFunction mapping
 59.8935 +     * @return {function} memoized mapping function
 59.8936 +     */
 59.8937 +    CachedMap.create = function create(mappingFunction) {
 59.8938 +        var instance = new CachedMap(mappingFunction);
 59.8939 +        return instance.get.bind(instance);
 59.8940 +    };
 59.8941 +
 59.8942 +    /**
 59.8943 +     * Retrieve items from cache or from mapping functin.
 59.8944 +     *
 59.8945 +     * @method get
 59.8946 +     * @param {Object} input input key
 59.8947 +     */
 59.8948 +    CachedMap.prototype.get = function get(input) {
 59.8949 +        if (input !== this._cachedInput) {
 59.8950 +            this._cachedInput = input;
 59.8951 +            this._cachedOutput = this._map(input);
 59.8952 +        }
 59.8953 +        return this._cachedOutput;
 59.8954 +    };
 59.8955 +
 59.8956 +    module.exports = CachedMap;
 59.8957 +});
 59.8958 +
 59.8959 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.8960 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.8961 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.8962 + *
 59.8963 + * Owner: david@famo.us
 59.8964 + * @license MPL 2.0
 59.8965 + * @copyright Famous Industries, Inc. 2014
 59.8966 + */
 59.8967 +
 59.8968 +define('famous/transitions/Easing',['require','exports','module'],function(require, exports, module) {
 59.8969 +
 59.8970 +    /*
 59.8971 +     * A library of curves which map an animation explicitly as a function of time.
 59.8972 +     *
 59.8973 +     * @class Easing
 59.8974 +     */
 59.8975 +    var Easing = {
 59.8976 +
 59.8977 +        /**
 59.8978 +         * @property inQuad
 59.8979 +         * @static
 59.8980 +         */
 59.8981 +        inQuad: function(t) {
 59.8982 +            return t*t;
 59.8983 +        },
 59.8984 +
 59.8985 +        /**
 59.8986 +         * @property outQuad
 59.8987 +         * @static
 59.8988 +         */
 59.8989 +        outQuad: function(t) {
 59.8990 +            return -(t-=1)*t+1;
 59.8991 +        },
 59.8992 +
 59.8993 +        /**
 59.8994 +         * @property inOutQuad
 59.8995 +         * @static
 59.8996 +         */
 59.8997 +        inOutQuad: function(t) {
 59.8998 +            if ((t/=.5) < 1) return .5*t*t;
 59.8999 +            return -.5*((--t)*(t-2) - 1);
 59.9000 +        },
 59.9001 +
 59.9002 +        /**
 59.9003 +         * @property inCubic
 59.9004 +         * @static
 59.9005 +         */
 59.9006 +        inCubic: function(t) {
 59.9007 +            return t*t*t;
 59.9008 +        },
 59.9009 +
 59.9010 +        /**
 59.9011 +         * @property outCubic
 59.9012 +         * @static
 59.9013 +         */
 59.9014 +        outCubic: function(t) {
 59.9015 +            return ((--t)*t*t + 1);
 59.9016 +        },
 59.9017 +
 59.9018 +        /**
 59.9019 +         * @property inOutCubic
 59.9020 +         * @static
 59.9021 +         */
 59.9022 +        inOutCubic: function(t) {
 59.9023 +            if ((t/=.5) < 1) return .5*t*t*t;
 59.9024 +            return .5*((t-=2)*t*t + 2);
 59.9025 +        },
 59.9026 +
 59.9027 +        /**
 59.9028 +         * @property inQuart
 59.9029 +         * @static
 59.9030 +         */
 59.9031 +        inQuart: function(t) {
 59.9032 +            return t*t*t*t;
 59.9033 +        },
 59.9034 +
 59.9035 +        /**
 59.9036 +         * @property outQuart
 59.9037 +         * @static
 59.9038 +         */
 59.9039 +        outQuart: function(t) {
 59.9040 +            return -((--t)*t*t*t - 1);
 59.9041 +        },
 59.9042 +
 59.9043 +        /**
 59.9044 +         * @property inOutQuart
 59.9045 +         * @static
 59.9046 +         */
 59.9047 +        inOutQuart: function(t) {
 59.9048 +            if ((t/=.5) < 1) return .5*t*t*t*t;
 59.9049 +            return -.5 * ((t-=2)*t*t*t - 2);
 59.9050 +        },
 59.9051 +
 59.9052 +        /**
 59.9053 +         * @property inQuint
 59.9054 +         * @static
 59.9055 +         */
 59.9056 +        inQuint: function(t) {
 59.9057 +            return t*t*t*t*t;
 59.9058 +        },
 59.9059 +
 59.9060 +        /**
 59.9061 +         * @property outQuint
 59.9062 +         * @static
 59.9063 +         */
 59.9064 +        outQuint: function(t) {
 59.9065 +            return ((--t)*t*t*t*t + 1);
 59.9066 +        },
 59.9067 +
 59.9068 +        /**
 59.9069 +         * @property inOutQuint
 59.9070 +         * @static
 59.9071 +         */
 59.9072 +        inOutQuint: function(t) {
 59.9073 +            if ((t/=.5) < 1) return .5*t*t*t*t*t;
 59.9074 +            return .5*((t-=2)*t*t*t*t + 2);
 59.9075 +        },
 59.9076 +
 59.9077 +        /**
 59.9078 +         * @property inSine
 59.9079 +         * @static
 59.9080 +         */
 59.9081 +        inSine: function(t) {
 59.9082 +            return -1.0*Math.cos(t * (Math.PI/2)) + 1.0;
 59.9083 +        },
 59.9084 +
 59.9085 +        /**
 59.9086 +         * @property outSine
 59.9087 +         * @static
 59.9088 +         */
 59.9089 +        outSine: function(t) {
 59.9090 +            return Math.sin(t * (Math.PI/2));
 59.9091 +        },
 59.9092 +
 59.9093 +        /**
 59.9094 +         * @property inOutSine
 59.9095 +         * @static
 59.9096 +         */
 59.9097 +        inOutSine: function(t) {
 59.9098 +            return -.5*(Math.cos(Math.PI*t) - 1);
 59.9099 +        },
 59.9100 +
 59.9101 +        /**
 59.9102 +         * @property inExpo
 59.9103 +         * @static
 59.9104 +         */
 59.9105 +        inExpo: function(t) {
 59.9106 +            return (t===0) ? 0.0 : Math.pow(2, 10 * (t - 1));
 59.9107 +        },
 59.9108 +
 59.9109 +        /**
 59.9110 +         * @property outExpo
 59.9111 +         * @static
 59.9112 +         */
 59.9113 +        outExpo: function(t) {
 59.9114 +            return (t===1.0) ? 1.0 : (-Math.pow(2, -10 * t) + 1);
 59.9115 +        },
 59.9116 +
 59.9117 +        /**
 59.9118 +         * @property inOutExpo
 59.9119 +         * @static
 59.9120 +         */
 59.9121 +        inOutExpo: function(t) {
 59.9122 +            if (t===0) return 0.0;
 59.9123 +            if (t===1.0) return 1.0;
 59.9124 +            if ((t/=.5) < 1) return .5 * Math.pow(2, 10 * (t - 1));
 59.9125 +            return .5 * (-Math.pow(2, -10 * --t) + 2);
 59.9126 +        },
 59.9127 +
 59.9128 +        /**
 59.9129 +         * @property inCirc
 59.9130 +         * @static
 59.9131 +         */
 59.9132 +        inCirc: function(t) {
 59.9133 +            return -(Math.sqrt(1 - t*t) - 1);
 59.9134 +        },
 59.9135 +
 59.9136 +        /**
 59.9137 +         * @property outCirc
 59.9138 +         * @static
 59.9139 +         */
 59.9140 +        outCirc: function(t) {
 59.9141 +            return Math.sqrt(1 - (--t)*t);
 59.9142 +        },
 59.9143 +
 59.9144 +        /**
 59.9145 +         * @property inOutCirc
 59.9146 +         * @static
 59.9147 +         */
 59.9148 +        inOutCirc: function(t) {
 59.9149 +            if ((t/=.5) < 1) return -.5 * (Math.sqrt(1 - t*t) - 1);
 59.9150 +            return .5 * (Math.sqrt(1 - (t-=2)*t) + 1);
 59.9151 +        },
 59.9152 +
 59.9153 +        /**
 59.9154 +         * @property inElastic
 59.9155 +         * @static
 59.9156 +         */
 59.9157 +        inElastic: function(t) {
 59.9158 +            var s=1.70158;var p=0;var a=1.0;
 59.9159 +            if (t===0) return 0.0;  if (t===1) return 1.0;  if (!p) p=.3;
 59.9160 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 59.9161 +            return -(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/ p));
 59.9162 +        },
 59.9163 +
 59.9164 +        /**
 59.9165 +         * @property outElastic
 59.9166 +         * @static
 59.9167 +         */
 59.9168 +        outElastic: function(t) {
 59.9169 +            var s=1.70158;var p=0;var a=1.0;
 59.9170 +            if (t===0) return 0.0;  if (t===1) return 1.0;  if (!p) p=.3;
 59.9171 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 59.9172 +            return a*Math.pow(2,-10*t) * Math.sin((t-s)*(2*Math.PI)/p) + 1.0;
 59.9173 +        },
 59.9174 +
 59.9175 +        /**
 59.9176 +         * @property inOutElastic
 59.9177 +         * @static
 59.9178 +         */
 59.9179 +        inOutElastic: function(t) {
 59.9180 +            var s=1.70158;var p=0;var a=1.0;
 59.9181 +            if (t===0) return 0.0;  if ((t/=.5)===2) return 1.0;  if (!p) p=(.3*1.5);
 59.9182 +            s = p/(2*Math.PI) * Math.asin(1.0/a);
 59.9183 +            if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p));
 59.9184 +            return a*Math.pow(2,-10*(t-=1)) * Math.sin((t-s)*(2*Math.PI)/p)*.5 + 1.0;
 59.9185 +        },
 59.9186 +
 59.9187 +        /**
 59.9188 +         * @property inBack
 59.9189 +         * @static
 59.9190 +         */
 59.9191 +        inBack: function(t, s) {
 59.9192 +            if (s === undefined) s = 1.70158;
 59.9193 +            return t*t*((s+1)*t - s);
 59.9194 +        },
 59.9195 +
 59.9196 +        /**
 59.9197 +         * @property outBack
 59.9198 +         * @static
 59.9199 +         */
 59.9200 +        outBack: function(t, s) {
 59.9201 +            if (s === undefined) s = 1.70158;
 59.9202 +            return ((--t)*t*((s+1)*t + s) + 1);
 59.9203 +        },
 59.9204 +
 59.9205 +        /**
 59.9206 +         * @property inOutBack
 59.9207 +         * @static
 59.9208 +         */
 59.9209 +        inOutBack: function(t, s) {
 59.9210 +            if (s === undefined) s = 1.70158;
 59.9211 +            if ((t/=.5) < 1) return .5*(t*t*(((s*=(1.525))+1)*t - s));
 59.9212 +            return .5*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2);
 59.9213 +        },
 59.9214 +
 59.9215 +        /**
 59.9216 +         * @property inBounce
 59.9217 +         * @static
 59.9218 +         */
 59.9219 +        inBounce: function(t) {
 59.9220 +            return 1.0 - Easing.outBounce(1.0-t);
 59.9221 +        },
 59.9222 +
 59.9223 +        /**
 59.9224 +         * @property outBounce
 59.9225 +         * @static
 59.9226 +         */
 59.9227 +        outBounce: function(t) {
 59.9228 +            if (t < (1/2.75)) {
 59.9229 +                return (7.5625*t*t);
 59.9230 +            } else if (t < (2/2.75)) {
 59.9231 +                return (7.5625*(t-=(1.5/2.75))*t + .75);
 59.9232 +            } else if (t < (2.5/2.75)) {
 59.9233 +                return (7.5625*(t-=(2.25/2.75))*t + .9375);
 59.9234 +            } else {
 59.9235 +                return (7.5625*(t-=(2.625/2.75))*t + .984375);
 59.9236 +            }
 59.9237 +        },
 59.9238 +
 59.9239 +        /**
 59.9240 +         * @property inOutBounce
 59.9241 +         * @static
 59.9242 +         */
 59.9243 +        inOutBounce: function(t) {
 59.9244 +            if (t < .5) return Easing.inBounce(t*2) * .5;
 59.9245 +            return Easing.outBounce(t*2-1.0) * .5 + .5;
 59.9246 +        }
 59.9247 +    };
 59.9248 +
 59.9249 +    module.exports = Easing;
 59.9250 +});
 59.9251 +
 59.9252 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.9253 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.9254 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.9255 + *
 59.9256 + * Owner: david@famo.us
 59.9257 + * @license MPL 2.0
 59.9258 + * @copyright Famous Industries, Inc. 2014
 59.9259 + */
 59.9260 +
 59.9261 +define('famous/physics/integrators/SymplecticEuler',['require','exports','module','famous/core/OptionsManager'],function(require, exports, module) {
 59.9262 +    var OptionsManager = require('famous/core/OptionsManager');
 59.9263 +
 59.9264 +    /**
 59.9265 +     * Ordinary Differential Equation (ODE) Integrator.
 59.9266 +     * Manages updating a physics body's state over time.
 59.9267 +     *
 59.9268 +     *  p = position, v = velocity, m = mass, f = force, dt = change in time
 59.9269 +     *
 59.9270 +     *      v <- v + dt * f / m
 59.9271 +     *      p <- p + dt * v
 59.9272 +     *
 59.9273 +     *  q = orientation, w = angular velocity, L = angular momentum
 59.9274 +     *
 59.9275 +     *      L <- L + dt * t
 59.9276 +     *      q <- q + dt/2 * q * w
 59.9277 +     *
 59.9278 +     * @class SymplecticEuler
 59.9279 +     * @constructor
 59.9280 +     * @param {Object} options Options to set
 59.9281 +     */
 59.9282 +    function SymplecticEuler(options) {
 59.9283 +        this.options = Object.create(SymplecticEuler.DEFAULT_OPTIONS);
 59.9284 +        this._optionsManager = new OptionsManager(this.options);
 59.9285 +
 59.9286 +        if (options) this.setOptions(options);
 59.9287 +    }
 59.9288 +
 59.9289 +    /**
 59.9290 +     * @property SymplecticEuler.DEFAULT_OPTIONS
 59.9291 +     * @type Object
 59.9292 +     * @protected
 59.9293 +     * @static
 59.9294 +     */
 59.9295 +    SymplecticEuler.DEFAULT_OPTIONS = {
 59.9296 +
 59.9297 +        /**
 59.9298 +         * The maximum velocity of a physics body
 59.9299 +         *      Range : [0, Infinity]
 59.9300 +         * @attribute velocityCap
 59.9301 +         * @type Number
 59.9302 +         */
 59.9303 +
 59.9304 +        velocityCap : undefined,
 59.9305 +
 59.9306 +        /**
 59.9307 +         * The maximum angular velocity of a physics body
 59.9308 +         *      Range : [0, Infinity]
 59.9309 +         * @attribute angularVelocityCap
 59.9310 +         * @type Number
 59.9311 +         */
 59.9312 +        angularVelocityCap : undefined
 59.9313 +    };
 59.9314 +
 59.9315 +    /*
 59.9316 +     * Setter for options
 59.9317 +     *
 59.9318 +     * @method setOptions
 59.9319 +     * @param {Object} options
 59.9320 +     */
 59.9321 +    SymplecticEuler.prototype.setOptions = function setOptions(options) {
 59.9322 +        this._optionsManager.patch(options);
 59.9323 +    };
 59.9324 +
 59.9325 +    /*
 59.9326 +     * Getter for options
 59.9327 +     *
 59.9328 +     * @method getOptions
 59.9329 +     * @return {Object} options
 59.9330 +     */
 59.9331 +    SymplecticEuler.prototype.getOptions = function getOptions() {
 59.9332 +        return this._optionsManager.value();
 59.9333 +    };
 59.9334 +
 59.9335 +    /*
 59.9336 +     * Updates the velocity of a physics body from its accumulated force.
 59.9337 +     *      v <- v + dt * f / m
 59.9338 +     *
 59.9339 +     * @method integrateVelocity
 59.9340 +     * @param {Body} physics body
 59.9341 +     * @param {Number} dt delta time
 59.9342 +     */
 59.9343 +    SymplecticEuler.prototype.integrateVelocity = function integrateVelocity(body, dt) {
 59.9344 +        var v = body.velocity;
 59.9345 +        var w = body.inverseMass;
 59.9346 +        var f = body.force;
 59.9347 +
 59.9348 +        if (f.isZero()) return;
 59.9349 +
 59.9350 +        v.add(f.mult(dt * w)).put(v);
 59.9351 +        f.clear();
 59.9352 +    };
 59.9353 +
 59.9354 +    /*
 59.9355 +     * Updates the position of a physics body from its velocity.
 59.9356 +     *      p <- p + dt * v
 59.9357 +     *
 59.9358 +     * @method integratePosition
 59.9359 +     * @param {Body} physics body
 59.9360 +     * @param {Number} dt delta time
 59.9361 +     */
 59.9362 +    SymplecticEuler.prototype.integratePosition = function integratePosition(body, dt) {
 59.9363 +        var p = body.position;
 59.9364 +        var v = body.velocity;
 59.9365 +
 59.9366 +        if (this.options.velocityCap) v.cap(this.options.velocityCap).put(v);
 59.9367 +        p.add(v.mult(dt)).put(p);
 59.9368 +    };
 59.9369 +
 59.9370 +    /*
 59.9371 +     * Updates the angular momentum of a physics body from its accumuled torque.
 59.9372 +     *      L <- L + dt * t
 59.9373 +     *
 59.9374 +     * @method integrateAngularMomentum
 59.9375 +     * @param {Body} physics body (except a particle)
 59.9376 +     * @param {Number} dt delta time
 59.9377 +     */
 59.9378 +    SymplecticEuler.prototype.integrateAngularMomentum = function integrateAngularMomentum(body, dt) {
 59.9379 +        var L = body.angularMomentum;
 59.9380 +        var t = body.torque;
 59.9381 +
 59.9382 +        if (t.isZero()) return;
 59.9383 +
 59.9384 +        if (this.options.angularVelocityCap) t.cap(this.options.angularVelocityCap).put(t);
 59.9385 +        L.add(t.mult(dt)).put(L);
 59.9386 +        t.clear();
 59.9387 +    };
 59.9388 +
 59.9389 +    /*
 59.9390 +     * Updates the orientation of a physics body from its angular velocity.
 59.9391 +     *      q <- q + dt/2 * q * w
 59.9392 +     *
 59.9393 +     * @method integrateOrientation
 59.9394 +     * @param {Body} physics body (except a particle)
 59.9395 +     * @param {Number} dt delta time
 59.9396 +     */
 59.9397 +    SymplecticEuler.prototype.integrateOrientation = function integrateOrientation(body, dt) {
 59.9398 +        var q = body.orientation;
 59.9399 +        var w = body.angularVelocity;
 59.9400 +
 59.9401 +        if (w.isZero()) return;
 59.9402 +        q.add(q.multiply(w).scalarMultiply(0.5 * dt)).put(q);
 59.9403 +//        q.normalize.put(q);
 59.9404 +    };
 59.9405 +
 59.9406 +    module.exports = SymplecticEuler;
 59.9407 +});
 59.9408 +
 59.9409 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.9410 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.9411 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.9412 + *
 59.9413 + * Owner: david@famo.us
 59.9414 + * @license MPL 2.0
 59.9415 + * @copyright Famous Industries, Inc. 2014
 59.9416 + */
 59.9417 +
 59.9418 +define('famous/physics/bodies/Particle',['require','exports','module','famous/math/Vector','famous/core/Transform','famous/core/EventHandler','../integrators/SymplecticEuler'],function(require, exports, module) {
 59.9419 +    var Vector = require('famous/math/Vector');
 59.9420 +    var Transform = require('famous/core/Transform');
 59.9421 +    var EventHandler = require('famous/core/EventHandler');
 59.9422 +    var Integrator = require('../integrators/SymplecticEuler');
 59.9423 +
 59.9424 +    /**
 59.9425 +     * A point body that is controlled by the Physics Engine. A particle has
 59.9426 +     *   position and velocity states that are updated by the Physics Engine.
 59.9427 +     *   Ultimately, a particle is a _special type of modifier, and can be added to
 59.9428 +     *   the Famous render tree like any other modifier.
 59.9429 +     *
 59.9430 +     * @constructor
 59.9431 +     * @class Particle
 59.9432 +     * @uses EventHandler
 59.9433 +     * @uses Modifier
 59.9434 +     * @extensionfor Body
 59.9435 +     * @param {Options} [options] An object of configurable options.
 59.9436 +     * @param {Array} [options.position] The position of the particle.
 59.9437 +     * @param {Array} [options.velocity] The velocity of the particle.
 59.9438 +     * @param {Number} [options.mass] The mass of the particle.
 59.9439 +     * @param {Hexadecimal} [options.axis] The axis a particle can move along. Can be bitwise ORed e.g., Particle.AXES.X, Particle.AXES.X | Particle.AXES.Y
 59.9440 +     *
 59.9441 +     */
 59.9442 +     function Particle(options) {
 59.9443 +        options = options || {};
 59.9444 +
 59.9445 +        // registers
 59.9446 +        this.position = new Vector();
 59.9447 +        this.velocity = new Vector();
 59.9448 +        this.force    = new Vector();
 59.9449 +
 59.9450 +        var defaults  = Particle.DEFAULT_OPTIONS;
 59.9451 +
 59.9452 +        // set vectors
 59.9453 +        this.setPosition(options.position || defaults.position);
 59.9454 +        this.setVelocity(options.velocity || defaults.velocity);
 59.9455 +        this.force.set(options.force || [0,0,0]);
 59.9456 +
 59.9457 +        // set scalars
 59.9458 +        this.mass = (options.mass !== undefined)
 59.9459 +            ? options.mass
 59.9460 +            : defaults.mass;
 59.9461 +
 59.9462 +        this.axis = (options.axis !== undefined)
 59.9463 +            ? options.axis
 59.9464 +            : defaults.axis;
 59.9465 +
 59.9466 +        this.inverseMass = 1 / this.mass;
 59.9467 +
 59.9468 +        // state variables
 59.9469 +        this._isSleeping     = false;
 59.9470 +        this._engine         = null;
 59.9471 +        this._eventOutput    = null;
 59.9472 +        this._positionGetter = null;
 59.9473 +
 59.9474 +        this.transform = Transform.identity.slice();
 59.9475 +
 59.9476 +        // cached _spec
 59.9477 +        this._spec = {
 59.9478 +            transform : this.transform,
 59.9479 +            target    : null
 59.9480 +        };
 59.9481 +    }
 59.9482 +
 59.9483 +    Particle.DEFAULT_OPTIONS = {
 59.9484 +        position : [0,0,0],
 59.9485 +        velocity : [0,0,0],
 59.9486 +        mass : 1,
 59.9487 +        axis : undefined
 59.9488 +    };
 59.9489 +
 59.9490 +    /**
 59.9491 +     * Kinetic energy threshold needed to update the body
 59.9492 +     *
 59.9493 +     * @property SLEEP_TOLERANCE
 59.9494 +     * @type Number
 59.9495 +     * @static
 59.9496 +     * @default 1e-7
 59.9497 +     */
 59.9498 +    Particle.SLEEP_TOLERANCE = 1e-7;
 59.9499 +
 59.9500 +    /**
 59.9501 +     * Axes by which a body can translate
 59.9502 +     *
 59.9503 +     * @property AXES
 59.9504 +     * @type Hexadecimal
 59.9505 +     * @static
 59.9506 +     * @default 1e-7
 59.9507 +     */
 59.9508 +    Particle.AXES = {
 59.9509 +        X : 0x00, // hexadecimal for 0
 59.9510 +        Y : 0x01, // hexadecimal for 1
 59.9511 +        Z : 0x02  // hexadecimal for 2
 59.9512 +    };
 59.9513 +
 59.9514 +    // Integrator for updating the particle's state
 59.9515 +    // TODO: make this a singleton
 59.9516 +    Particle.INTEGRATOR = new Integrator();
 59.9517 +
 59.9518 +    //Catalogue of outputted events
 59.9519 +    var _events = {
 59.9520 +        start  : 'start',
 59.9521 +        update : 'update',
 59.9522 +        end    : 'end'
 59.9523 +    };
 59.9524 +
 59.9525 +    // Cached timing function
 59.9526 +    var now = (function() {
 59.9527 +        return Date.now;
 59.9528 +    })();
 59.9529 +
 59.9530 +    /**
 59.9531 +     * Stops the particle from updating
 59.9532 +     * @method sleep
 59.9533 +     */
 59.9534 +    Particle.prototype.sleep = function sleep() {
 59.9535 +        if (this._isSleeping) return;
 59.9536 +        this.emit(_events.end, this);
 59.9537 +        this._isSleeping = true;
 59.9538 +    };
 59.9539 +
 59.9540 +    /**
 59.9541 +     * Starts the particle update
 59.9542 +     * @method wake
 59.9543 +     */
 59.9544 +    Particle.prototype.wake = function wake() {
 59.9545 +        if (!this._isSleeping) return;
 59.9546 +        this.emit(_events.start, this);
 59.9547 +        this._isSleeping = false;
 59.9548 +        this._prevTime = now();
 59.9549 +    };
 59.9550 +
 59.9551 +    /**
 59.9552 +     * @attribute isBody
 59.9553 +     * @type Boolean
 59.9554 +     * @static
 59.9555 +     */
 59.9556 +    Particle.prototype.isBody = false;
 59.9557 +
 59.9558 +    /**
 59.9559 +     * Basic setter for position
 59.9560 +     * @method getPosition
 59.9561 +     * @param position {Array|Vector}
 59.9562 +     */
 59.9563 +    Particle.prototype.setPosition = function setPosition(position) {
 59.9564 +        this.position.set(position);
 59.9565 +    };
 59.9566 +
 59.9567 +    /**
 59.9568 +     * 1-dimensional setter for position
 59.9569 +     * @method setPosition1D
 59.9570 +     * @param value {Number}
 59.9571 +     */
 59.9572 +    Particle.prototype.setPosition1D = function setPosition1D(x) {
 59.9573 +        this.position.x = x;
 59.9574 +    };
 59.9575 +
 59.9576 +    /**
 59.9577 +     * Basic getter function for position
 59.9578 +     * @method getPosition
 59.9579 +     * @return position {Array}
 59.9580 +     */
 59.9581 +    Particle.prototype.getPosition = function getPosition() {
 59.9582 +        if (this._positionGetter instanceof Function)
 59.9583 +            this.setPosition(this._positionGetter());
 59.9584 +
 59.9585 +        this._engine.step();
 59.9586 +
 59.9587 +        return this.position.get();
 59.9588 +    };
 59.9589 +
 59.9590 +    /**
 59.9591 +     * 1-dimensional getter for position
 59.9592 +     * @method getPosition1D
 59.9593 +     * @return value {Number}
 59.9594 +     */
 59.9595 +    Particle.prototype.getPosition1D = function getPosition1D() {
 59.9596 +        this._engine.step();
 59.9597 +        return this.position.x;
 59.9598 +    };
 59.9599 +
 59.9600 +    /**
 59.9601 +     * Defines the position from outside the Physics Engine
 59.9602 +     * @method positionFrom
 59.9603 +     * @param positionGetter {Function}
 59.9604 +     */
 59.9605 +    Particle.prototype.positionFrom = function positionFrom(positionGetter) {
 59.9606 +        this._positionGetter = positionGetter;
 59.9607 +    };
 59.9608 +
 59.9609 +    /**
 59.9610 +     * Basic setter function for velocity Vector
 59.9611 +     * @method setVelocity
 59.9612 +     * @function
 59.9613 +     */
 59.9614 +    Particle.prototype.setVelocity = function setVelocity(velocity) {
 59.9615 +        this.velocity.set(velocity);
 59.9616 +        this.wake();
 59.9617 +    };
 59.9618 +
 59.9619 +    /**
 59.9620 +     * 1-dimensional setter for velocity
 59.9621 +     * @method setVelocity1D
 59.9622 +     * @param velocity {Number}
 59.9623 +     */
 59.9624 +    Particle.prototype.setVelocity1D = function setVelocity1D(x) {
 59.9625 +        this.velocity.x = x;
 59.9626 +        this.wake();
 59.9627 +    };
 59.9628 +
 59.9629 +    /**
 59.9630 +     * Basic getter function for velocity Vector
 59.9631 +     * @method getVelocity
 59.9632 +     * @return velocity {Array}
 59.9633 +     */
 59.9634 +    Particle.prototype.getVelocity = function getVelocity() {
 59.9635 +        return this.velocity.get();
 59.9636 +    };
 59.9637 +
 59.9638 +    /**
 59.9639 +     * 1-dimensional getter for velocity
 59.9640 +     * @method getVelocity1D
 59.9641 +     * @return velocity {Number}
 59.9642 +     */
 59.9643 +    Particle.prototype.getVelocity1D = function getVelocity1D() {
 59.9644 +        return this.velocity.x;
 59.9645 +    };
 59.9646 +
 59.9647 +    /**
 59.9648 +     * Basic setter function for mass quantity
 59.9649 +     * @method setMass
 59.9650 +     * @param mass {Number} mass
 59.9651 +     */
 59.9652 +    Particle.prototype.setMass = function setMass(mass) {
 59.9653 +        this.mass = mass;
 59.9654 +        this.inverseMass = 1 / mass;
 59.9655 +    };
 59.9656 +
 59.9657 +    /**
 59.9658 +     * Basic getter function for mass quantity
 59.9659 +     * @method getMass
 59.9660 +     * @return mass {Number}
 59.9661 +     */
 59.9662 +    Particle.prototype.getMass = function getMass() {
 59.9663 +        return this.mass;
 59.9664 +    };
 59.9665 +
 59.9666 +    /**
 59.9667 +     * Reset position and velocity
 59.9668 +     * @method reset
 59.9669 +     * @param position {Array|Vector}
 59.9670 +     * @param velocity {Array|Vector}
 59.9671 +     */
 59.9672 +    Particle.prototype.reset = function reset(position, velocity) {
 59.9673 +        this.setPosition(position || [0,0,0]);
 59.9674 +        this.setVelocity(velocity || [0,0,0]);
 59.9675 +    };
 59.9676 +
 59.9677 +    /**
 59.9678 +     * Add force vector to existing internal force Vector
 59.9679 +     * @method applyForce
 59.9680 +     * @param force {Vector}
 59.9681 +     */
 59.9682 +    Particle.prototype.applyForce = function applyForce(force) {
 59.9683 +        if (force.isZero()) return;
 59.9684 +        this.force.add(force).put(this.force);
 59.9685 +        this.wake();
 59.9686 +    };
 59.9687 +
 59.9688 +    /**
 59.9689 +     * Add impulse (change in velocity) Vector to this Vector's velocity.
 59.9690 +     * @method applyImpulse
 59.9691 +     * @param impulse {Vector}
 59.9692 +     */
 59.9693 +    Particle.prototype.applyImpulse = function applyImpulse(impulse) {
 59.9694 +        if (impulse.isZero()) return;
 59.9695 +        var velocity = this.velocity;
 59.9696 +        velocity.add(impulse.mult(this.inverseMass)).put(velocity);
 59.9697 +    };
 59.9698 +
 59.9699 +    /**
 59.9700 +     * Update a particle's velocity from its force accumulator
 59.9701 +     * @method integrateVelocity
 59.9702 +     * @param dt {Number} Time differential
 59.9703 +     */
 59.9704 +    Particle.prototype.integrateVelocity = function integrateVelocity(dt) {
 59.9705 +        Particle.INTEGRATOR.integrateVelocity(this, dt);
 59.9706 +    };
 59.9707 +
 59.9708 +    /**
 59.9709 +     * Update a particle's position from its velocity
 59.9710 +     * @method integratePosition
 59.9711 +     * @param dt {Number} Time differential
 59.9712 +     */
 59.9713 +    Particle.prototype.integratePosition = function integratePosition(dt) {
 59.9714 +        Particle.INTEGRATOR.integratePosition(this, dt);
 59.9715 +    };
 59.9716 +
 59.9717 +    /**
 59.9718 +     * Update the position and velocity of the particle
 59.9719 +     * @method _integrate
 59.9720 +     * @protected
 59.9721 +     * @param dt {Number} Time differential
 59.9722 +     */
 59.9723 +    Particle.prototype._integrate = function _integrate(dt) {
 59.9724 +        this.integrateVelocity(dt);
 59.9725 +        this.integratePosition(dt);
 59.9726 +    };
 59.9727 +
 59.9728 +    /**
 59.9729 +     * Get kinetic energy of the particle.
 59.9730 +     * @method getEnergy
 59.9731 +     * @function
 59.9732 +     */
 59.9733 +    Particle.prototype.getEnergy = function getEnergy() {
 59.9734 +        return 0.5 * this.mass * this.velocity.normSquared();
 59.9735 +    };
 59.9736 +
 59.9737 +    /**
 59.9738 +     * Generate transform from the current position state
 59.9739 +     * @method getTransform
 59.9740 +     * @return Transform {Transform}
 59.9741 +     */
 59.9742 +    Particle.prototype.getTransform = function getTransform() {
 59.9743 +        this._engine.step();
 59.9744 +
 59.9745 +        var position = this.position;
 59.9746 +        var axis = this.axis;
 59.9747 +        var transform = this.transform;
 59.9748 +
 59.9749 +        if (axis !== undefined) {
 59.9750 +            if (axis & ~Particle.AXES.X) {
 59.9751 +                position.x = 0;
 59.9752 +            }
 59.9753 +            if (axis & ~Particle.AXES.Y) {
 59.9754 +                position.y = 0;
 59.9755 +            }
 59.9756 +            if (axis & ~Particle.AXES.Z) {
 59.9757 +                position.z = 0;
 59.9758 +            }
 59.9759 +        }
 59.9760 +
 59.9761 +        transform[12] = position.x;
 59.9762 +        transform[13] = position.y;
 59.9763 +        transform[14] = position.z;
 59.9764 +
 59.9765 +        return transform;
 59.9766 +    };
 59.9767 +
 59.9768 +    /**
 59.9769 +     * The modify interface of a Modifier
 59.9770 +     * @method modify
 59.9771 +     * @param target {Spec}
 59.9772 +     * @return Spec {Spec}
 59.9773 +     */
 59.9774 +    Particle.prototype.modify = function modify(target) {
 59.9775 +        var _spec = this._spec;
 59.9776 +        _spec.transform = this.getTransform();
 59.9777 +        _spec.target = target;
 59.9778 +        return _spec;
 59.9779 +    };
 59.9780 +
 59.9781 +    // private
 59.9782 +    function _createEventOutput() {
 59.9783 +        this._eventOutput = new EventHandler();
 59.9784 +        this._eventOutput.bindThis(this);
 59.9785 +        //overrides on/removeListener/pipe/unpipe methods
 59.9786 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.9787 +    }
 59.9788 +
 59.9789 +    Particle.prototype.emit = function emit(type, data) {
 59.9790 +        if (!this._eventOutput) return;
 59.9791 +        this._eventOutput.emit(type, data);
 59.9792 +    };
 59.9793 +
 59.9794 +    Particle.prototype.on = function on() {
 59.9795 +        _createEventOutput.call(this);
 59.9796 +        return this.on.apply(this, arguments);
 59.9797 +    };
 59.9798 +    Particle.prototype.removeListener = function removeListener() {
 59.9799 +        _createEventOutput.call(this);
 59.9800 +        return this.removeListener.apply(this, arguments);
 59.9801 +    };
 59.9802 +    Particle.prototype.pipe = function pipe() {
 59.9803 +        _createEventOutput.call(this);
 59.9804 +        return this.pipe.apply(this, arguments);
 59.9805 +    };
 59.9806 +    Particle.prototype.unpipe = function unpipe() {
 59.9807 +        _createEventOutput.call(this);
 59.9808 +        return this.unpipe.apply(this, arguments);
 59.9809 +    };
 59.9810 +
 59.9811 +    module.exports = Particle;
 59.9812 +});
 59.9813 +
 59.9814 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.9815 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.9816 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.9817 + *
 59.9818 + * Owner: david@famo.us
 59.9819 + * @license MPL 2.0
 59.9820 + * @copyright Famous Industries, Inc. 2014
 59.9821 + */
 59.9822 +
 59.9823 +define('famous/physics/constraints/Constraint',['require','exports','module','famous/core/EventHandler'],function(require, exports, module) {
 59.9824 +    var EventHandler = require('famous/core/EventHandler');
 59.9825 +
 59.9826 +    /**
 59.9827 +     *  Allows for two circular bodies to collide and bounce off each other.
 59.9828 +     *
 59.9829 +     *  @class Constraint
 59.9830 +     *  @constructor
 59.9831 +     *  @uses EventHandler
 59.9832 +     *  @param options {Object}
 59.9833 +     */
 59.9834 +    function Constraint() {
 59.9835 +        this.options = this.options || {};
 59.9836 +        this._energy = 0.0;
 59.9837 +        this._eventOutput = null;
 59.9838 +    }
 59.9839 +
 59.9840 +    /*
 59.9841 +     * Setter for options.
 59.9842 +     *
 59.9843 +     * @method setOptions
 59.9844 +     * @param options {Objects}
 59.9845 +     */
 59.9846 +    Constraint.prototype.setOptions = function setOptions(options) {
 59.9847 +        for (var key in options) this.options[key] = options[key];
 59.9848 +    };
 59.9849 +
 59.9850 +    /**
 59.9851 +     * Adds an impulse to a physics body's velocity due to the constraint
 59.9852 +     *
 59.9853 +     * @method applyConstraint
 59.9854 +     */
 59.9855 +    Constraint.prototype.applyConstraint = function applyConstraint() {};
 59.9856 +
 59.9857 +    /**
 59.9858 +     * Getter for energy
 59.9859 +     *
 59.9860 +     * @method getEnergy
 59.9861 +     * @return energy {Number}
 59.9862 +     */
 59.9863 +    Constraint.prototype.getEnergy = function getEnergy() {
 59.9864 +        return this._energy;
 59.9865 +    };
 59.9866 +
 59.9867 +    /**
 59.9868 +     * Setter for energy
 59.9869 +     *
 59.9870 +     * @method setEnergy
 59.9871 +     * @param energy {Number}
 59.9872 +     */
 59.9873 +    Constraint.prototype.setEnergy = function setEnergy(energy) {
 59.9874 +        this._energy = energy;
 59.9875 +    };
 59.9876 +
 59.9877 +    function _createEventOutput() {
 59.9878 +        this._eventOutput = new EventHandler();
 59.9879 +        this._eventOutput.bindThis(this);
 59.9880 +        EventHandler.setOutputHandler(this, this._eventOutput);
 59.9881 +    }
 59.9882 +
 59.9883 +    Constraint.prototype.on = function on() {
 59.9884 +        _createEventOutput.call(this);
 59.9885 +        return this.on.apply(this, arguments);
 59.9886 +    };
 59.9887 +    Constraint.prototype.addListener = function addListener() {
 59.9888 +        _createEventOutput.call(this);
 59.9889 +        return this.addListener.apply(this, arguments);
 59.9890 +    };
 59.9891 +    Constraint.prototype.pipe = function pipe() {
 59.9892 +        _createEventOutput.call(this);
 59.9893 +        return this.pipe.apply(this, arguments);
 59.9894 +    };
 59.9895 +    Constraint.prototype.removeListener = function removeListener() {
 59.9896 +        return this.removeListener.apply(this, arguments);
 59.9897 +    };
 59.9898 +    Constraint.prototype.unpipe = function unpipe() {
 59.9899 +        return this.unpipe.apply(this, arguments);
 59.9900 +    };
 59.9901 +
 59.9902 +    module.exports = Constraint;
 59.9903 +});
 59.9904 +
 59.9905 +/* This Source Code Form is subject to the terms of the Mozilla Public
 59.9906 + * License, v. 2.0. If a copy of the MPL was not distributed with this
 59.9907 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 59.9908 + *
 59.9909 + * Owner: david@famo.us
 59.9910 + * @license MPL 2.0
 59.9911 + * @copyright Famous Industries, Inc. 2014
 59.9912 + */
 59.9913 +
 59.9914 +define('famous/physics/constraints/Snap',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
 59.9915 +    var Constraint = require('./Constraint');
 59.9916 +    var Vector = require('famous/math/Vector');
 59.9917 +
 59.9918 +    /**
 59.9919 +     *  A spring constraint is like a spring force, except that it is always
 59.9920 +     *    numerically stable (even for low periods), at the expense of introducing
 59.9921 +     *    damping (even with dampingRatio set to 0).
 59.9922 +     *
 59.9923 +     *    Use this if you need fast spring-like behavior, e.g., snapping
 59.9924 +     *
 59.9925 +     *  @class Snap
 59.9926 +     *  @constructor
 59.9927 +     *  @extends Constraint
 59.9928 +     *  @param {Options} [options] An object of configurable options.
 59.9929 +     *  @param {Number} [options.period] The amount of time in milliseconds taken for one complete oscillation when there is no damping. Range : [150, Infinity]
 59.9930 +     *  @param {Number} [options.dampingRatio] Additional damping of the spring. Range : [0, 1]. At 0 this spring will still be damped, at 1 the spring will be critically damped (the spring will never oscillate)
 59.9931 +     *  @param {Number} [options.length] The rest length of the spring. Range: [0, Infinity].
 59.9932 +     *  @param {Array} [options.anchor] The location of the spring's anchor, if not another physics body.
 59.9933 +     *
 59.9934 +     */
 59.9935 +    function Snap(options) {
 59.9936 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
 59.9937 +        if (options) this.setOptions(options);
 59.9938 +
 59.9939 +        //registers
 59.9940 +        this.pDiff  = new Vector();
 59.9941 +        this.vDiff  = new Vector();
 59.9942 +        this.impulse1 = new Vector();
 59.9943 +        this.impulse2 = new Vector();
 59.9944 +
 59.9945 +        Constraint.call(this);
 59.9946 +    }
 59.9947 +
 59.9948 +    Snap.prototype = Object.create(Constraint.prototype);
 59.9949 +    Snap.prototype.constructor = Snap;
 59.9950 +
 59.9951 +    Snap.DEFAULT_OPTIONS = {
 59.9952 +        period        : 300,
 59.9953 +        dampingRatio : 0.1,
 59.9954 +        length : 0,
 59.9955 +        anchor : undefined
 59.9956 +    };
 59.9957 +
 59.9958 +    /** const */ var pi = Math.PI;
 59.9959 +
 59.9960 +    function _calcEnergy(impulse, disp, dt) {
 59.9961 +        return Math.abs(impulse.dot(disp)/dt);
 59.9962 +    }
 59.9963 +
 59.9964 +    /**
 59.9965 +     * Basic options setter
 59.9966 +     *
 59.9967 +     * @method setOptions
 59.9968 +     * @param options {Objects} options
 59.9969 +     */
 59.9970 +    Snap.prototype.setOptions = function setOptions(options) {
 59.9971 +        if (options.anchor !== undefined) {
 59.9972 +            if (options.anchor   instanceof Vector) this.options.anchor = options.anchor;
 59.9973 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
 59.9974 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
 59.9975 +        }
 59.9976 +        if (options.length !== undefined) this.options.length = options.length;
 59.9977 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
 59.9978 +        if (options.period !== undefined) this.options.period = options.period;
 59.9979 +    };
 59.9980 +
 59.9981 +    /**
 59.9982 +     * Set the anchor position
 59.9983 +     *
 59.9984 +     * @method setOptions
 59.9985 +     * @param {Array} v TODO
 59.9986 +     */
 59.9987 +
 59.9988 +    Snap.prototype.setAnchor = function setAnchor(v) {
 59.9989 +        if (this.options.anchor !== undefined) this.options.anchor = new Vector();
 59.9990 +        this.options.anchor.set(v);
 59.9991 +    };
 59.9992 +
 59.9993 +    /**
 59.9994 +     * Calculates energy of spring
 59.9995 +     *
 59.9996 +     * @method getEnergy
 59.9997 +     * @param {Object} target TODO
 59.9998 +     * @param {Object} source TODO
 59.9999 +     * @return energy {Number}
59.10000 +     */
59.10001 +    Snap.prototype.getEnergy = function getEnergy(target, source) {
59.10002 +        var options     = this.options;
59.10003 +        var restLength  = options.length;
59.10004 +        var anchor      = options.anchor || source.position;
59.10005 +        var strength    = Math.pow(2 * pi / options.period, 2);
59.10006 +
59.10007 +        var dist = anchor.sub(target.position).norm() - restLength;
59.10008 +
59.10009 +        return 0.5 * strength * dist * dist;
59.10010 +    };
59.10011 +
59.10012 +    /**
59.10013 +     * Adds a spring impulse to a physics body's velocity due to the constraint
59.10014 +     *
59.10015 +     * @method applyConstraint
59.10016 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
59.10017 +     * @param source {Body}         The source of the constraint
59.10018 +     * @param dt {Number}           Delta time
59.10019 +     */
59.10020 +    Snap.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.10021 +        var options         = this.options;
59.10022 +        var pDiff        = this.pDiff;
59.10023 +        var vDiff        = this.vDiff;
59.10024 +        var impulse1     = this.impulse1;
59.10025 +        var impulse2     = this.impulse2;
59.10026 +        var length       = options.length;
59.10027 +        var anchor       = options.anchor || source.position;
59.10028 +        var period       = options.period;
59.10029 +        var dampingRatio = options.dampingRatio;
59.10030 +
59.10031 +        for (var i = 0; i < targets.length ; i++) {
59.10032 +            var target = targets[i];
59.10033 +
59.10034 +            var p1 = target.position;
59.10035 +            var v1 = target.velocity;
59.10036 +            var m1 = target.mass;
59.10037 +            var w1 = target.inverseMass;
59.10038 +
59.10039 +            pDiff.set(p1.sub(anchor));
59.10040 +            var dist = pDiff.norm() - length;
59.10041 +            var effMass;
59.10042 +
59.10043 +            if (source) {
59.10044 +                var w2 = source.inverseMass;
59.10045 +                var v2 = source.velocity;
59.10046 +                vDiff.set(v1.sub(v2));
59.10047 +                effMass = 1/(w1 + w2);
59.10048 +            }
59.10049 +            else {
59.10050 +                vDiff.set(v1);
59.10051 +                effMass = m1;
59.10052 +            }
59.10053 +
59.10054 +            var gamma;
59.10055 +            var beta;
59.10056 +
59.10057 +            if (this.options.period === 0) {
59.10058 +                gamma = 0;
59.10059 +                beta = 1;
59.10060 +            }
59.10061 +            else {
59.10062 +                var k = 4 * effMass * pi * pi / (period * period);
59.10063 +                var c = 4 * effMass * pi * dampingRatio / period;
59.10064 +
59.10065 +                beta  = dt * k / (c + dt * k);
59.10066 +                gamma = 1 / (c + dt*k);
59.10067 +            }
59.10068 +
59.10069 +            var antiDrift = beta/dt * dist;
59.10070 +            pDiff.normalize(-antiDrift)
59.10071 +                .sub(vDiff)
59.10072 +                .mult(dt / (gamma + dt/effMass))
59.10073 +                .put(impulse1);
59.10074 +
59.10075 +            // var n = new Vector();
59.10076 +            // n.set(pDiff.normalize());
59.10077 +            // var lambda = -(n.dot(vDiff) + antiDrift) / (gamma + dt/effMass);
59.10078 +            // impulse2.set(n.mult(dt*lambda));
59.10079 +
59.10080 +            target.applyImpulse(impulse1);
59.10081 +
59.10082 +            if (source) {
59.10083 +                impulse1.mult(-1).put(impulse2);
59.10084 +                source.applyImpulse(impulse2);
59.10085 +            }
59.10086 +
59.10087 +            this.setEnergy(_calcEnergy(impulse1, pDiff, dt));
59.10088 +        }
59.10089 +    };
59.10090 +
59.10091 +    module.exports = Snap;
59.10092 +});
59.10093 +
59.10094 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.10095 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.10096 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.10097 + *
59.10098 + * Owner: david@famo.us
59.10099 + * @license MPL 2.0
59.10100 + * @copyright Famous Industries, Inc. 2014
59.10101 + */
59.10102 +
59.10103 +define('famous/transitions/SnapTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/constraints/Snap','famous/math/Vector'],function(require, exports, module) {
59.10104 +    var PE = require('famous/physics/PhysicsEngine');
59.10105 +    var Particle = require('famous/physics/bodies/Particle');
59.10106 +    var Spring = require('famous/physics/constraints/Snap');
59.10107 +    var Vector = require('famous/math/Vector');
59.10108 +
59.10109 +    /**
59.10110 +     * SnapTransition is a method of transitioning between two values (numbers,
59.10111 +     * or arrays of numbers). It is similar to SpringTransition except
59.10112 +     * the transition can be much faster and always has a damping effect.
59.10113 +     *
59.10114 +     * @class SnapTransition
59.10115 +     * @constructor
59.10116 +     *
59.10117 +     * @param [state=0] {Number|Array} Initial state
59.10118 +     */
59.10119 +    function SnapTransition(state) {
59.10120 +        state = state || 0;
59.10121 +
59.10122 +        this.endState  = new Vector(state);
59.10123 +        this.initState = new Vector();
59.10124 +
59.10125 +        this._dimensions       = 1;
59.10126 +        this._restTolerance    = 1e-10;
59.10127 +        this._absRestTolerance = this._restTolerance;
59.10128 +        this._callback         = undefined;
59.10129 +
59.10130 +        this.PE       = new PE();
59.10131 +        this.particle = new Particle();
59.10132 +        this.spring   = new Spring({anchor : this.endState});
59.10133 +
59.10134 +        this.PE.addBody(this.particle);
59.10135 +        this.PE.attach(this.spring, this.particle);
59.10136 +    }
59.10137 +
59.10138 +    SnapTransition.SUPPORTS_MULTIPLE = 3;
59.10139 +
59.10140 +    /**
59.10141 +     * @property SnapTransition.DEFAULT_OPTIONS
59.10142 +     * @type Object
59.10143 +     * @protected
59.10144 +     * @static
59.10145 +     */
59.10146 +    SnapTransition.DEFAULT_OPTIONS = {
59.10147 +
59.10148 +        /**
59.10149 +         * The amount of time in milliseconds taken for one complete oscillation
59.10150 +         * when there is no damping
59.10151 +         *    Range : [0, Infinity]
59.10152 +         *
59.10153 +         * @attribute period
59.10154 +         * @type Number
59.10155 +         * @default 100
59.10156 +         */
59.10157 +        period : 100,
59.10158 +
59.10159 +        /**
59.10160 +         * The damping of the snap.
59.10161 +         *    Range : [0, 1]
59.10162 +         *
59.10163 +         * @attribute dampingRatio
59.10164 +         * @type Number
59.10165 +         * @default 0.2
59.10166 +         */
59.10167 +        dampingRatio : 0.2,
59.10168 +
59.10169 +        /**
59.10170 +         * The initial velocity of the transition.
59.10171 +         *
59.10172 +         * @attribute velocity
59.10173 +         * @type Number|Array
59.10174 +         * @default 0
59.10175 +         */
59.10176 +        velocity : 0
59.10177 +    };
59.10178 +
59.10179 +    function _getEnergy() {
59.10180 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
59.10181 +    }
59.10182 +
59.10183 +    function _setAbsoluteRestTolerance() {
59.10184 +        var distance = this.endState.sub(this.initState).normSquared();
59.10185 +        this._absRestTolerance = (distance === 0)
59.10186 +            ? this._restTolerance
59.10187 +            : this._restTolerance * distance;
59.10188 +    }
59.10189 +
59.10190 +    function _setTarget(target) {
59.10191 +        this.endState.set(target);
59.10192 +        _setAbsoluteRestTolerance.call(this);
59.10193 +    }
59.10194 +
59.10195 +    function _wake() {
59.10196 +        this.PE.wake();
59.10197 +    }
59.10198 +
59.10199 +    function _sleep() {
59.10200 +        this.PE.sleep();
59.10201 +    }
59.10202 +
59.10203 +    function _setParticlePosition(p) {
59.10204 +        this.particle.position.set(p);
59.10205 +    }
59.10206 +
59.10207 +    function _setParticleVelocity(v) {
59.10208 +        this.particle.velocity.set(v);
59.10209 +    }
59.10210 +
59.10211 +    function _getParticlePosition() {
59.10212 +        return (this._dimensions === 0)
59.10213 +            ? this.particle.getPosition1D()
59.10214 +            : this.particle.getPosition();
59.10215 +    }
59.10216 +
59.10217 +    function _getParticleVelocity() {
59.10218 +        return (this._dimensions === 0)
59.10219 +            ? this.particle.getVelocity1D()
59.10220 +            : this.particle.getVelocity();
59.10221 +    }
59.10222 +
59.10223 +    function _setCallback(callback) {
59.10224 +        this._callback = callback;
59.10225 +    }
59.10226 +
59.10227 +    function _setupDefinition(definition) {
59.10228 +        var defaults = SnapTransition.DEFAULT_OPTIONS;
59.10229 +        if (definition.period === undefined)       definition.period       = defaults.period;
59.10230 +        if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio;
59.10231 +        if (definition.velocity === undefined)     definition.velocity     = defaults.velocity;
59.10232 +
59.10233 +        //setup spring
59.10234 +        this.spring.setOptions({
59.10235 +            period       : definition.period,
59.10236 +            dampingRatio : definition.dampingRatio
59.10237 +        });
59.10238 +
59.10239 +        //setup particle
59.10240 +        _setParticleVelocity.call(this, definition.velocity);
59.10241 +    }
59.10242 +
59.10243 +    function _update() {
59.10244 +        if (this.PE.isSleeping()) {
59.10245 +            if (this._callback) {
59.10246 +                var cb = this._callback;
59.10247 +                this._callback = undefined;
59.10248 +                cb();
59.10249 +            }
59.10250 +            return;
59.10251 +        }
59.10252 +
59.10253 +        if (_getEnergy.call(this) < this._absRestTolerance) {
59.10254 +            _setParticlePosition.call(this, this.endState);
59.10255 +            _setParticleVelocity.call(this, [0,0,0]);
59.10256 +            _sleep.call(this);
59.10257 +        }
59.10258 +    }
59.10259 +
59.10260 +    /**
59.10261 +     * Resets the state and velocity
59.10262 +     *
59.10263 +     * @method reset
59.10264 +     *
59.10265 +     * @param state {Number|Array}      State
59.10266 +     * @param [velocity] {Number|Array} Velocity
59.10267 +     */
59.10268 +    SnapTransition.prototype.reset = function reset(state, velocity) {
59.10269 +        this._dimensions = (state instanceof Array)
59.10270 +            ? state.length
59.10271 +            : 0;
59.10272 +
59.10273 +        this.initState.set(state);
59.10274 +        _setParticlePosition.call(this, state);
59.10275 +        _setTarget.call(this, state);
59.10276 +        if (velocity) _setParticleVelocity.call(this, velocity);
59.10277 +        _setCallback.call(this, undefined);
59.10278 +    };
59.10279 +
59.10280 +    /**
59.10281 +     * Getter for velocity
59.10282 +     *
59.10283 +     * @method getVelocity
59.10284 +     *
59.10285 +     * @return velocity {Number|Array}
59.10286 +     */
59.10287 +    SnapTransition.prototype.getVelocity = function getVelocity() {
59.10288 +        return _getParticleVelocity.call(this);
59.10289 +    };
59.10290 +
59.10291 +    /**
59.10292 +     * Setter for velocity
59.10293 +     *
59.10294 +     * @method setVelocity
59.10295 +     *
59.10296 +     * @return velocity {Number|Array}
59.10297 +     */
59.10298 +    SnapTransition.prototype.setVelocity = function setVelocity(velocity) {
59.10299 +        this.call(this, _setParticleVelocity(velocity));
59.10300 +    };
59.10301 +
59.10302 +    /**
59.10303 +     * Detects whether a transition is in progress
59.10304 +     *
59.10305 +     * @method isActive
59.10306 +     *
59.10307 +     * @return {Boolean}
59.10308 +     */
59.10309 +    SnapTransition.prototype.isActive = function isActive() {
59.10310 +        return !this.PE.isSleeping();
59.10311 +    };
59.10312 +
59.10313 +    /**
59.10314 +     * Halt the transition
59.10315 +     *
59.10316 +     * @method halt
59.10317 +     */
59.10318 +    SnapTransition.prototype.halt = function halt() {
59.10319 +        this.set(this.get());
59.10320 +    };
59.10321 +
59.10322 +    /**
59.10323 +     * Get the current position of the transition
59.10324 +s     *
59.10325 +     * @method get
59.10326 +     *
59.10327 +     * @return state {Number|Array}
59.10328 +     */
59.10329 +    SnapTransition.prototype.get = function get() {
59.10330 +        _update.call(this);
59.10331 +        return _getParticlePosition.call(this);
59.10332 +    };
59.10333 +
59.10334 +    /**
59.10335 +     * Set the end position and transition, with optional callback on completion.
59.10336 +     *
59.10337 +     * @method set
59.10338 +     *
59.10339 +     * @param state {Number|Array}      Final state
59.10340 +     * @param [definition] {Object}     Transition definition
59.10341 +     * @param [callback] {Function}     Callback
59.10342 +     */
59.10343 +    SnapTransition.prototype.set = function set(state, definition, callback) {
59.10344 +        if (!definition) {
59.10345 +            this.reset(state);
59.10346 +            if (callback) callback();
59.10347 +            return;
59.10348 +        }
59.10349 +
59.10350 +        this._dimensions = (state instanceof Array)
59.10351 +            ? state.length
59.10352 +            : 0;
59.10353 +
59.10354 +        _wake.call(this);
59.10355 +        _setupDefinition.call(this, definition);
59.10356 +        _setTarget.call(this, state);
59.10357 +        _setCallback.call(this, callback);
59.10358 +    };
59.10359 +
59.10360 +    module.exports = SnapTransition;
59.10361 +});
59.10362 +
59.10363 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.10364 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.10365 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.10366 + *
59.10367 + * Owner: david@famo.us
59.10368 + * @license MPL 2.0
59.10369 + * @copyright Famous Industries, Inc. 2014
59.10370 + */
59.10371 +
59.10372 +define('famous/physics/forces/Force',['require','exports','module','famous/math/Vector','famous/core/EventHandler'],function(require, exports, module) {
59.10373 +    var Vector = require('famous/math/Vector');
59.10374 +    var EventHandler = require('famous/core/EventHandler');
59.10375 +
59.10376 +    /**
59.10377 +     * Force base class.
59.10378 +     *
59.10379 +     * @class Force
59.10380 +     * @uses EventHandler
59.10381 +     * @constructor
59.10382 +     */
59.10383 +    function Force(force) {
59.10384 +        this.force = new Vector(force);
59.10385 +        this._energy = 0.0;
59.10386 +        this._eventOutput = null;
59.10387 +    }
59.10388 +
59.10389 +    /**
59.10390 +     * Basic setter for options
59.10391 +     *
59.10392 +     * @method setOptions
59.10393 +     * @param options {Objects}
59.10394 +     */
59.10395 +    Force.prototype.setOptions = function setOptions(options) {
59.10396 +        for (var key in options) this.options[key] = options[key];
59.10397 +    };
59.10398 +
59.10399 +    /**
59.10400 +     * Adds a force to a physics body's force accumulator.
59.10401 +     *
59.10402 +     * @method applyForce
59.10403 +     * @param body {Body}
59.10404 +     */
59.10405 +    Force.prototype.applyForce = function applyForce(body) {
59.10406 +        body.applyForce(this.force);
59.10407 +    };
59.10408 +
59.10409 +    /**
59.10410 +     * Getter for a force's potential energy.
59.10411 +     *
59.10412 +     * @method getEnergy
59.10413 +     * @return energy {Number}
59.10414 +     */
59.10415 +    Force.prototype.getEnergy = function getEnergy() {
59.10416 +        return this._energy;
59.10417 +    };
59.10418 +
59.10419 +    /*
59.10420 +     * Setter for a force's potential energy.
59.10421 +     *
59.10422 +     * @method setEnergy
59.10423 +     * @param energy {Number}
59.10424 +     */
59.10425 +    Force.prototype.setEnergy = function setEnergy(energy) {
59.10426 +        this._energy = energy;
59.10427 +    };
59.10428 +
59.10429 +    function _createEventOutput() {
59.10430 +        this._eventOutput = new EventHandler();
59.10431 +        this._eventOutput.bindThis(this);
59.10432 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.10433 +    }
59.10434 +
59.10435 +    Force.prototype.on = function on() {
59.10436 +        _createEventOutput.call(this);
59.10437 +        return this.on.apply(this, arguments);
59.10438 +    };
59.10439 +    Force.prototype.addListener = function addListener() {
59.10440 +        _createEventOutput.call(this);
59.10441 +        return this.addListener.apply(this, arguments);
59.10442 +    };
59.10443 +    Force.prototype.pipe = function pipe() {
59.10444 +        _createEventOutput.call(this);
59.10445 +        return this.pipe.apply(this, arguments);
59.10446 +    };
59.10447 +    Force.prototype.removeListener = function removeListener() {
59.10448 +        return this.removeListener.apply(this, arguments);
59.10449 +    };
59.10450 +    Force.prototype.unpipe = function unpipe() {
59.10451 +        return this.unpipe.apply(this, arguments);
59.10452 +    };
59.10453 +
59.10454 +    module.exports = Force;
59.10455 +});
59.10456 +
59.10457 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.10458 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.10459 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.10460 + *
59.10461 + * Owner: david@famo.us
59.10462 + * @license MPL 2.0
59.10463 + * @copyright Famous Industries, Inc. 2014
59.10464 + */
59.10465 +
59.10466 +define('famous/physics/forces/Spring',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
59.10467 +    var Force = require('./Force');
59.10468 +    var Vector = require('famous/math/Vector');
59.10469 +
59.10470 +    /**
59.10471 +     *  A force that moves a physics body to a location with a spring motion.
59.10472 +     *    The body can be moved to another physics body, or an anchor point.
59.10473 +     *
59.10474 +     *  @class Spring
59.10475 +     *  @constructor
59.10476 +     *  @extends Force
59.10477 +     *  @param {Object} options options to set on drag
59.10478 +     */
59.10479 +    function Spring(options) {
59.10480 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
59.10481 +        if (options) this.setOptions(options);
59.10482 +
59.10483 +        //registers
59.10484 +        this.disp = new Vector(0,0,0);
59.10485 +
59.10486 +        _init.call(this);
59.10487 +        Force.call(this);
59.10488 +    }
59.10489 +
59.10490 +    Spring.prototype = Object.create(Force.prototype);
59.10491 +    Spring.prototype.constructor = Spring;
59.10492 +
59.10493 +    /** @const */ var pi = Math.PI;
59.10494 +
59.10495 +    /**
59.10496 +     * @property Spring.FORCE_FUNCTIONS
59.10497 +     * @type Object
59.10498 +     * @protected
59.10499 +     * @static
59.10500 +     */
59.10501 +    Spring.FORCE_FUNCTIONS = {
59.10502 +
59.10503 +        /**
59.10504 +         * A FENE (Finitely Extensible Nonlinear Elastic) spring force
59.10505 +         *      see: http://en.wikipedia.org/wiki/FENE
59.10506 +         * @attribute FENE
59.10507 +         * @type Function
59.10508 +         * @param {Number} dist current distance target is from source body
59.10509 +         * @param {Number} rMax maximum range of influence
59.10510 +         * @return {Number} unscaled force
59.10511 +         */
59.10512 +        FENE : function(dist, rMax) {
59.10513 +            var rMaxSmall = rMax * .99;
59.10514 +            var r = Math.max(Math.min(dist, rMaxSmall), -rMaxSmall);
59.10515 +            return r / (1 - r * r/(rMax * rMax));
59.10516 +        },
59.10517 +
59.10518 +        /**
59.10519 +         * A Hookean spring force, linear in the displacement
59.10520 +         *      see: http://en.wikipedia.org/wiki/FENE
59.10521 +         * @attribute FENE
59.10522 +         * @type Function
59.10523 +         * @param {Number} dist current distance target is from source body
59.10524 +         * @return {Number} unscaled force
59.10525 +         */
59.10526 +        HOOK : function(dist) {
59.10527 +            return dist;
59.10528 +        }
59.10529 +    };
59.10530 +
59.10531 +    /**
59.10532 +     * @property Spring.DEFAULT_OPTIONS
59.10533 +     * @type Object
59.10534 +     * @protected
59.10535 +     * @static
59.10536 +     */
59.10537 +    Spring.DEFAULT_OPTIONS = {
59.10538 +
59.10539 +        /**
59.10540 +         * The amount of time in milliseconds taken for one complete oscillation
59.10541 +         * when there is no damping
59.10542 +         *    Range : [150, Infinity]
59.10543 +         * @attribute period
59.10544 +         * @type Number
59.10545 +         * @default 300
59.10546 +         */
59.10547 +        period        : 300,
59.10548 +
59.10549 +        /**
59.10550 +         * The damping of the spring.
59.10551 +         *    Range : [0, 1]
59.10552 +         *    0 = no damping, and the spring will oscillate forever
59.10553 +         *    1 = critically damped (the spring will never oscillate)
59.10554 +         * @attribute dampingRatio
59.10555 +         * @type Number
59.10556 +         * @default 0.1
59.10557 +         */
59.10558 +        dampingRatio : 0.1,
59.10559 +
59.10560 +        /**
59.10561 +         * The rest length of the spring
59.10562 +         *    Range : [0, Infinity]
59.10563 +         * @attribute length
59.10564 +         * @type Number
59.10565 +         * @default 0
59.10566 +         */
59.10567 +        length : 0,
59.10568 +
59.10569 +        /**
59.10570 +         * The maximum length of the spring (for a FENE spring)
59.10571 +         *    Range : [0, Infinity]
59.10572 +         * @attribute length
59.10573 +         * @type Number
59.10574 +         * @default Infinity
59.10575 +         */
59.10576 +        maxLength : Infinity,
59.10577 +
59.10578 +        /**
59.10579 +         * The location of the spring's anchor, if not another physics body
59.10580 +         *
59.10581 +         * @attribute anchor
59.10582 +         * @type Array
59.10583 +         * @optional
59.10584 +         */
59.10585 +        anchor : undefined,
59.10586 +
59.10587 +        /**
59.10588 +         * The type of spring force
59.10589 +         * @attribute forceFunction
59.10590 +         * @type Function
59.10591 +         */
59.10592 +        forceFunction : Spring.FORCE_FUNCTIONS.HOOK
59.10593 +    };
59.10594 +
59.10595 +    function _setForceFunction(fn) {
59.10596 +        this.forceFunction = fn;
59.10597 +    }
59.10598 +
59.10599 +    function _calcStiffness() {
59.10600 +        var options = this.options;
59.10601 +        options.stiffness = Math.pow(2 * pi / options.period, 2);
59.10602 +    }
59.10603 +
59.10604 +    function _calcDamping() {
59.10605 +        var options = this.options;
59.10606 +        options.damping = 4 * pi * options.dampingRatio / options.period;
59.10607 +    }
59.10608 +
59.10609 +    function _calcEnergy(strength, dist) {
59.10610 +        return 0.5 * strength * dist * dist;
59.10611 +    }
59.10612 +
59.10613 +    function _init() {
59.10614 +        _setForceFunction.call(this, this.options.forceFunction);
59.10615 +        _calcStiffness.call(this);
59.10616 +        _calcDamping.call(this);
59.10617 +    }
59.10618 +
59.10619 +    /**
59.10620 +     * Basic options setter
59.10621 +     *
59.10622 +     * @method setOptions
59.10623 +     * @param options {Objects}
59.10624 +     */
59.10625 +    Spring.prototype.setOptions = function setOptions(options) {
59.10626 +        if (options.anchor !== undefined) {
59.10627 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
59.10628 +            if (options.anchor   instanceof Vector)  this.options.anchor = options.anchor;
59.10629 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
59.10630 +        }
59.10631 +        if (options.period !== undefined) this.options.period = options.period;
59.10632 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
59.10633 +        if (options.length !== undefined) this.options.length = options.length;
59.10634 +        if (options.forceFunction !== undefined) this.options.forceFunction = options.forceFunction;
59.10635 +        if (options.maxLength !== undefined) this.options.maxLength = options.maxLength;
59.10636 +
59.10637 +        _init.call(this);
59.10638 +    };
59.10639 +
59.10640 +    /**
59.10641 +     * Adds a spring force to a physics body's force accumulator.
59.10642 +     *
59.10643 +     * @method applyForce
59.10644 +     * @param targets {Array.Body} Array of bodies to apply force to.
59.10645 +     */
59.10646 +    Spring.prototype.applyForce = function applyForce(targets, source) {
59.10647 +        var force        = this.force;
59.10648 +        var disp         = this.disp;
59.10649 +        var options      = this.options;
59.10650 +
59.10651 +        var stiffness    = options.stiffness;
59.10652 +        var damping      = options.damping;
59.10653 +        var restLength   = options.length;
59.10654 +        var lMax         = options.maxLength;
59.10655 +        var anchor       = options.anchor || source.position;
59.10656 +
59.10657 +        for (var i = 0; i < targets.length; i++) {
59.10658 +            var target = targets[i];
59.10659 +            var p2 = target.position;
59.10660 +            var v2 = target.velocity;
59.10661 +
59.10662 +            anchor.sub(p2).put(disp);
59.10663 +            var dist = disp.norm() - restLength;
59.10664 +
59.10665 +            if (dist === 0) return;
59.10666 +
59.10667 +            //if dampingRatio specified, then override strength and damping
59.10668 +            var m      = target.mass;
59.10669 +            stiffness *= m;
59.10670 +            damping   *= m;
59.10671 +
59.10672 +            disp.normalize(stiffness * this.forceFunction(dist, lMax))
59.10673 +                .put(force);
59.10674 +
59.10675 +            if (damping)
59.10676 +                if (source) force.add(v2.sub(source.velocity).mult(-damping)).put(force);
59.10677 +                else force.add(v2.mult(-damping)).put(force);
59.10678 +
59.10679 +            target.applyForce(force);
59.10680 +            if (source) source.applyForce(force.mult(-1));
59.10681 +
59.10682 +            this.setEnergy(_calcEnergy(stiffness, dist));
59.10683 +        }
59.10684 +    };
59.10685 +
59.10686 +    /**
59.10687 +     * Calculates the potential energy of the spring.
59.10688 +     *
59.10689 +     * @method getEnergy
59.10690 +     * @param target {Body}     The physics body attached to the spring
59.10691 +     * @return energy {Number}
59.10692 +     */
59.10693 +    Spring.prototype.getEnergy = function getEnergy(target) {
59.10694 +        var options        = this.options;
59.10695 +        var restLength  = options.length;
59.10696 +        var anchor      = options.anchor;
59.10697 +        var strength    = options.stiffness;
59.10698 +
59.10699 +        var dist = anchor.sub(target.position).norm() - restLength;
59.10700 +        return 0.5 * strength * dist * dist;
59.10701 +    };
59.10702 +
59.10703 +    /**
59.10704 +     * Sets the anchor to a new position
59.10705 +     *
59.10706 +     * @method setAnchor
59.10707 +     * @param anchor {Array}    New anchor of the spring
59.10708 +     */
59.10709 +    Spring.prototype.setAnchor = function setAnchor(anchor) {
59.10710 +        if (!this.options.anchor) this.options.anchor = new Vector();
59.10711 +        this.options.anchor.set(anchor);
59.10712 +    };
59.10713 +
59.10714 +    module.exports = Spring;
59.10715 +});
59.10716 +
59.10717 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.10718 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.10719 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.10720 + *
59.10721 + * Owner: david@famo.us
59.10722 + * @license MPL 2.0
59.10723 + * @copyright Famous Industries, Inc. 2014
59.10724 + */
59.10725 +
59.10726 +/*global console*/
59.10727 +
59.10728 +define('famous/transitions/SpringTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/math/Vector'],function(require, exports, module) {
59.10729 +    var PE = require('famous/physics/PhysicsEngine');
59.10730 +    var Particle = require('famous/physics/bodies/Particle');
59.10731 +    var Spring = require('famous/physics/forces/Spring');
59.10732 +    var Vector = require('famous/math/Vector');
59.10733 +
59.10734 +    /**
59.10735 +     * SpringTransition is a method of transitioning between two values (numbers,
59.10736 +     * or arrays of numbers) with a bounce. The transition will overshoot the target
59.10737 +     * state depending on the parameters of the transition.
59.10738 +     *
59.10739 +     * @class SpringTransition
59.10740 +     * @constructor
59.10741 +     *
59.10742 +     * @param {Number|Array} [state=0] Initial state
59.10743 +     */
59.10744 +    function SpringTransition(state) {
59.10745 +        state = state || 0;
59.10746 +        this.endState  = new Vector(state);
59.10747 +        this.initState = new Vector();
59.10748 +
59.10749 +        this._dimensions       = undefined;
59.10750 +        this._restTolerance    = 1e-10;
59.10751 +        this._absRestTolerance = this._restTolerance;
59.10752 +        this._callback         = undefined;
59.10753 +
59.10754 +        this.PE       = new PE();
59.10755 +        this.spring   = new Spring({anchor : this.endState});
59.10756 +        this.particle = new Particle();
59.10757 +
59.10758 +        this.PE.addBody(this.particle);
59.10759 +        this.PE.attach(this.spring, this.particle);
59.10760 +    }
59.10761 +
59.10762 +    SpringTransition.SUPPORTS_MULTIPLE = 3;
59.10763 +
59.10764 +    /**
59.10765 +     * @property SpringTransition.DEFAULT_OPTIONS
59.10766 +     * @type Object
59.10767 +     * @protected
59.10768 +     * @static
59.10769 +     */
59.10770 +    SpringTransition.DEFAULT_OPTIONS = {
59.10771 +
59.10772 +        /**
59.10773 +         * The amount of time in milliseconds taken for one complete oscillation
59.10774 +         * when there is no damping
59.10775 +         *    Range : [0, Infinity]
59.10776 +         *
59.10777 +         * @attribute period
59.10778 +         * @type Number
59.10779 +         * @default 300
59.10780 +         */
59.10781 +        period : 300,
59.10782 +
59.10783 +        /**
59.10784 +         * The damping of the snap.
59.10785 +         *    Range : [0, 1]
59.10786 +         *    0 = no damping, and the spring will oscillate forever
59.10787 +         *    1 = critically damped (the spring will never oscillate)
59.10788 +         *
59.10789 +         * @attribute dampingRatio
59.10790 +         * @type Number
59.10791 +         * @default 0.5
59.10792 +         */
59.10793 +        dampingRatio : 0.5,
59.10794 +
59.10795 +        /**
59.10796 +         * The initial velocity of the transition.
59.10797 +         *
59.10798 +         * @attribute velocity
59.10799 +         * @type Number|Array
59.10800 +         * @default 0
59.10801 +         */
59.10802 +        velocity : 0
59.10803 +    };
59.10804 +
59.10805 +    function _getEnergy() {
59.10806 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
59.10807 +    }
59.10808 +
59.10809 +    function _setParticlePosition(p) {
59.10810 +        this.particle.setPosition(p);
59.10811 +    }
59.10812 +
59.10813 +    function _setParticleVelocity(v) {
59.10814 +        this.particle.setVelocity(v);
59.10815 +    }
59.10816 +
59.10817 +    function _getParticlePosition() {
59.10818 +        return (this._dimensions === 0)
59.10819 +            ? this.particle.getPosition1D()
59.10820 +            : this.particle.getPosition();
59.10821 +    }
59.10822 +
59.10823 +    function _getParticleVelocity() {
59.10824 +        return (this._dimensions === 0)
59.10825 +            ? this.particle.getVelocity1D()
59.10826 +            : this.particle.getVelocity();
59.10827 +    }
59.10828 +
59.10829 +    function _setCallback(callback) {
59.10830 +        this._callback = callback;
59.10831 +    }
59.10832 +
59.10833 +    function _wake() {
59.10834 +        this.PE.wake();
59.10835 +    }
59.10836 +
59.10837 +    function _sleep() {
59.10838 +        this.PE.sleep();
59.10839 +    }
59.10840 +
59.10841 +    function _update() {
59.10842 +        if (this.PE.isSleeping()) {
59.10843 +            if (this._callback) {
59.10844 +                var cb = this._callback;
59.10845 +                this._callback = undefined;
59.10846 +                cb();
59.10847 +            }
59.10848 +            return;
59.10849 +        }
59.10850 +
59.10851 +        if (_getEnergy.call(this) < this._absRestTolerance) {
59.10852 +            _setParticlePosition.call(this, this.endState);
59.10853 +            _setParticleVelocity.call(this, [0,0,0]);
59.10854 +            _sleep.call(this);
59.10855 +        }
59.10856 +    }
59.10857 +
59.10858 +    function _setupDefinition(definition) {
59.10859 +        // TODO fix no-console error
59.10860 +        /* eslint no-console: 0 */
59.10861 +        var defaults = SpringTransition.DEFAULT_OPTIONS;
59.10862 +        if (definition.period === undefined)       definition.period       = defaults.period;
59.10863 +        if (definition.dampingRatio === undefined) definition.dampingRatio = defaults.dampingRatio;
59.10864 +        if (definition.velocity === undefined)     definition.velocity     = defaults.velocity;
59.10865 +
59.10866 +        if (definition.period < 150) {
59.10867 +            definition.period = 150;
59.10868 +            console.warn('The period of a SpringTransition is capped at 150 ms. Use a SnapTransition for faster transitions');
59.10869 +        }
59.10870 +
59.10871 +        //setup spring
59.10872 +        this.spring.setOptions({
59.10873 +            period       : definition.period,
59.10874 +            dampingRatio : definition.dampingRatio
59.10875 +        });
59.10876 +
59.10877 +        //setup particle
59.10878 +        _setParticleVelocity.call(this, definition.velocity);
59.10879 +    }
59.10880 +
59.10881 +    function _setAbsoluteRestTolerance() {
59.10882 +        var distance = this.endState.sub(this.initState).normSquared();
59.10883 +        this._absRestTolerance = (distance === 0)
59.10884 +            ? this._restTolerance
59.10885 +            : this._restTolerance * distance;
59.10886 +    }
59.10887 +
59.10888 +    function _setTarget(target) {
59.10889 +        this.endState.set(target);
59.10890 +        _setAbsoluteRestTolerance.call(this);
59.10891 +    }
59.10892 +
59.10893 +    /**
59.10894 +     * Resets the position and velocity
59.10895 +     *
59.10896 +     * @method reset
59.10897 +     *
59.10898 +     * @param {Number|Array.Number} pos positional state
59.10899 +     * @param {Number|Array} vel velocity
59.10900 +     */
59.10901 +    SpringTransition.prototype.reset = function reset(pos, vel) {
59.10902 +        this._dimensions = (pos instanceof Array)
59.10903 +            ? pos.length
59.10904 +            : 0;
59.10905 +
59.10906 +        this.initState.set(pos);
59.10907 +        _setParticlePosition.call(this, pos);
59.10908 +        _setTarget.call(this, pos);
59.10909 +        if (vel) _setParticleVelocity.call(this, vel);
59.10910 +        _setCallback.call(this, undefined);
59.10911 +    };
59.10912 +
59.10913 +    /**
59.10914 +     * Getter for velocity
59.10915 +     *
59.10916 +     * @method getVelocity
59.10917 +     *
59.10918 +     * @return {Number|Array} velocity
59.10919 +     */
59.10920 +    SpringTransition.prototype.getVelocity = function getVelocity() {
59.10921 +        return _getParticleVelocity.call(this);
59.10922 +    };
59.10923 +
59.10924 +    /**
59.10925 +     * Setter for velocity
59.10926 +     *
59.10927 +     * @method setVelocity
59.10928 +     *
59.10929 +     * @return {Number|Array} velocity
59.10930 +     */
59.10931 +    SpringTransition.prototype.setVelocity = function setVelocity(v) {
59.10932 +        this.call(this, _setParticleVelocity(v));
59.10933 +    };
59.10934 +
59.10935 +    /**
59.10936 +     * Detects whether a transition is in progress
59.10937 +     *
59.10938 +     * @method isActive
59.10939 +     *
59.10940 +     * @return {Boolean}
59.10941 +     */
59.10942 +    SpringTransition.prototype.isActive = function isActive() {
59.10943 +        return !this.PE.isSleeping();
59.10944 +    };
59.10945 +
59.10946 +    /**
59.10947 +     * Halt the transition
59.10948 +     *
59.10949 +     * @method halt
59.10950 +     */
59.10951 +    SpringTransition.prototype.halt = function halt() {
59.10952 +        this.set(this.get());
59.10953 +    };
59.10954 +
59.10955 +    /**
59.10956 +     * Get the current position of the transition
59.10957 +     *
59.10958 +     * @method get
59.10959 +     *
59.10960 +     * @return {Number|Array} state
59.10961 +     */
59.10962 +    SpringTransition.prototype.get = function get() {
59.10963 +        _update.call(this);
59.10964 +        return _getParticlePosition.call(this);
59.10965 +    };
59.10966 +
59.10967 +    /**
59.10968 +     * Set the end position and transition, with optional callback on completion.
59.10969 +     *
59.10970 +     * @method set
59.10971 +     *
59.10972 +     * @param  {Number|Array} endState Final state
59.10973 +     * @param {Object}  definition  Transition definition
59.10974 +     * @param  {Function} callback Callback
59.10975 +     */
59.10976 +    SpringTransition.prototype.set = function set(endState, definition, callback) {
59.10977 +        if (!definition) {
59.10978 +            this.reset(endState);
59.10979 +            if (callback) callback();
59.10980 +            return;
59.10981 +        }
59.10982 +
59.10983 +        this._dimensions = (endState instanceof Array)
59.10984 +            ? endState.length
59.10985 +            : 0;
59.10986 +
59.10987 +        _wake.call(this);
59.10988 +        _setupDefinition.call(this, definition);
59.10989 +        _setTarget.call(this, endState);
59.10990 +        _setCallback.call(this, callback);
59.10991 +    };
59.10992 +
59.10993 +    module.exports = SpringTransition;
59.10994 +});
59.10995 +
59.10996 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.10997 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.10998 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.10999 + *
59.11000 + * Owner: david@famo.us
59.11001 + * @license MPL 2.0
59.11002 + * @copyright Famous Industries, Inc. 2014
59.11003 + */
59.11004 +
59.11005 +define('famous/physics/constraints/Wall',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
59.11006 +    var Constraint = require('./Constraint');
59.11007 +    var Vector = require('famous/math/Vector');
59.11008 +
59.11009 +    /**
59.11010 +     *  A wall describes an infinite two-dimensional plane that physics bodies
59.11011 +     *    can collide with. To define a wall, you must give it a distance (from
59.11012 +     *    the center of the physics engine's origin, and a normal defining the plane
59.11013 +     *    of the wall.
59.11014 +     *
59.11015 +     *    (wall)
59.11016 +     *      |
59.11017 +     *      | (normal)     (origin)
59.11018 +     *      | --->            *
59.11019 +     *      |
59.11020 +     *      |    (distance)
59.11021 +     *      ...................
59.11022 +     *            (100px)
59.11023 +     *
59.11024 +     *      e.g., Wall({normal : [1,0,0], distance : 100})
59.11025 +     *      would be a wall 100 pixels to the left, whose normal points right
59.11026 +     *
59.11027 +     *  @class Wall
59.11028 +     *  @constructor
59.11029 +     *  @extends Constraint
59.11030 +     *  @param {Options} [options] An object of configurable options.
59.11031 +     *  @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic). Range : [0, 1]
59.11032 +     *  @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
59.11033 +     *  @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers.
59.11034 +     *  @param {Array} [options.normal] The normal direction to the wall.
59.11035 +     *  @param {Number} [options.distance] The distance from the origin that the wall is placed.
59.11036 +     *  @param {onContact} [options.onContact] How to handle collision against the wall.
59.11037 +     *
59.11038 +     */
59.11039 +    function Wall(options) {
59.11040 +        this.options = Object.create(Wall.DEFAULT_OPTIONS);
59.11041 +        if (options) this.setOptions(options);
59.11042 +
59.11043 +        //registers
59.11044 +        this.diff = new Vector();
59.11045 +        this.impulse = new Vector();
59.11046 +
59.11047 +        Constraint.call(this);
59.11048 +    }
59.11049 +
59.11050 +    Wall.prototype = Object.create(Constraint.prototype);
59.11051 +    Wall.prototype.constructor = Wall;
59.11052 +
59.11053 +    /**
59.11054 +     * @property Wall.ON_CONTACT
59.11055 +     * @type Object
59.11056 +     * @protected
59.11057 +     * @static
59.11058 +     */
59.11059 +    Wall.ON_CONTACT = {
59.11060 +
59.11061 +        /**
59.11062 +         * Physical bodies bounce off the wall
59.11063 +         * @attribute REFLECT
59.11064 +         */
59.11065 +        REFLECT : 0,
59.11066 +
59.11067 +        /**
59.11068 +         * Physical bodies are unaffected. Usecase is to fire events on contact.
59.11069 +         * @attribute SILENT
59.11070 +         */
59.11071 +        SILENT : 1
59.11072 +    };
59.11073 +
59.11074 +    Wall.DEFAULT_OPTIONS = {
59.11075 +        restitution : 0.5,
59.11076 +        drift : 0.5,
59.11077 +        slop : 0,
59.11078 +        normal : [1, 0, 0],
59.11079 +        distance : 0,
59.11080 +        onContact : Wall.ON_CONTACT.REFLECT
59.11081 +    };
59.11082 +
59.11083 +    /*
59.11084 +     * Setter for options.
59.11085 +     *
59.11086 +     * @method setOptions
59.11087 +     * @param options {Objects}
59.11088 +     */
59.11089 +    Wall.prototype.setOptions = function setOptions(options) {
59.11090 +        if (options.normal !== undefined) {
59.11091 +            if (options.normal instanceof Vector) this.options.normal = options.normal.clone();
59.11092 +            if (options.normal instanceof Array)  this.options.normal = new Vector(options.normal);
59.11093 +        }
59.11094 +        if (options.restitution !== undefined) this.options.restitution = options.restitution;
59.11095 +        if (options.drift !== undefined) this.options.drift = options.drift;
59.11096 +        if (options.slop !== undefined) this.options.slop = options.slop;
59.11097 +        if (options.distance !== undefined) this.options.distance = options.distance;
59.11098 +        if (options.onContact !== undefined) this.options.onContact = options.onContact;
59.11099 +    };
59.11100 +
59.11101 +    function _getNormalVelocity(n, v) {
59.11102 +        return v.dot(n);
59.11103 +    }
59.11104 +
59.11105 +    function _getDistanceFromOrigin(p) {
59.11106 +        var n = this.options.normal;
59.11107 +        var d = this.options.distance;
59.11108 +        return p.dot(n) + d;
59.11109 +    }
59.11110 +
59.11111 +    function _onEnter(particle, overlap, dt) {
59.11112 +        var p = particle.position;
59.11113 +        var v = particle.velocity;
59.11114 +        var m = particle.mass;
59.11115 +        var n = this.options.normal;
59.11116 +        var action = this.options.onContact;
59.11117 +        var restitution = this.options.restitution;
59.11118 +        var impulse = this.impulse;
59.11119 +
59.11120 +        var drift = this.options.drift;
59.11121 +        var slop = -this.options.slop;
59.11122 +        var gamma = 0;
59.11123 +
59.11124 +        if (this._eventOutput) {
59.11125 +            var data = {particle : particle, wall : this, overlap : overlap, normal : n};
59.11126 +            this._eventOutput.emit('preCollision', data);
59.11127 +            this._eventOutput.emit('collision', data);
59.11128 +        }
59.11129 +
59.11130 +        switch (action) {
59.11131 +            case Wall.ON_CONTACT.REFLECT:
59.11132 +                var lambda = (overlap < slop)
59.11133 +                    ? -((1 + restitution) * n.dot(v) + drift / dt * (overlap - slop)) / (m * dt + gamma)
59.11134 +                    : -((1 + restitution) * n.dot(v)) / (m * dt + gamma);
59.11135 +
59.11136 +                impulse.set(n.mult(dt * lambda));
59.11137 +                particle.applyImpulse(impulse);
59.11138 +                particle.setPosition(p.add(n.mult(-overlap)));
59.11139 +                break;
59.11140 +        }
59.11141 +
59.11142 +        if (this._eventOutput) this._eventOutput.emit('postCollision', data);
59.11143 +    }
59.11144 +
59.11145 +    function _onExit(particle, overlap, dt) {
59.11146 +        var action = this.options.onContact;
59.11147 +        var p = particle.position;
59.11148 +        var n = this.options.normal;
59.11149 +
59.11150 +        if (action === Wall.ON_CONTACT.REFLECT) {
59.11151 +            particle.setPosition(p.add(n.mult(-overlap)));
59.11152 +        }
59.11153 +    }
59.11154 +
59.11155 +    /**
59.11156 +     * Adds an impulse to a physics body's velocity due to the wall constraint
59.11157 +     *
59.11158 +     * @method applyConstraint
59.11159 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
59.11160 +     * @param source {Body}         The source of the constraint
59.11161 +     * @param dt {Number}           Delta time
59.11162 +     */
59.11163 +    Wall.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.11164 +        var n = this.options.normal;
59.11165 +
59.11166 +        for (var i = 0; i < targets.length; i++) {
59.11167 +            var particle = targets[i];
59.11168 +            var p = particle.position;
59.11169 +            var v = particle.velocity;
59.11170 +            var r = particle.radius || 0;
59.11171 +
59.11172 +            var overlap = _getDistanceFromOrigin.call(this, p.add(n.mult(-r)));
59.11173 +            var nv = _getNormalVelocity.call(this, n, v);
59.11174 +
59.11175 +            if (overlap <= 0) {
59.11176 +                if (nv < 0) _onEnter.call(this, particle, overlap, dt);
59.11177 +                else _onExit.call(this, particle, overlap, dt);
59.11178 +            }
59.11179 +        }
59.11180 +    };
59.11181 +
59.11182 +    module.exports = Wall;
59.11183 +});
59.11184 +
59.11185 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11186 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11187 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11188 + *
59.11189 + * Owner: david@famo.us
59.11190 + * @license MPL 2.0
59.11191 + * @copyright Famous Industries, Inc. 2014
59.11192 + */
59.11193 +
59.11194 +define('famous/transitions/WallTransition',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Spring','famous/physics/constraints/Wall','famous/math/Vector'],function(require, exports, module) {
59.11195 +    var PE = require('famous/physics/PhysicsEngine');
59.11196 +    var Particle = require('famous/physics/bodies/Particle');
59.11197 +    var Spring = require('famous/physics/forces/Spring');
59.11198 +    var Wall = require('famous/physics/constraints/Wall');
59.11199 +    var Vector = require('famous/math/Vector');
59.11200 +
59.11201 +    /**
59.11202 +     * WallTransition is a method of transitioning between two values (numbers,
59.11203 +     *   or arrays of numbers) with a bounce. Unlike a SpringTransition
59.11204 +     *   The transition will not overshoot the target, but bounce back against it.
59.11205 +     *   The behavior of the bounce is specified by the transition options.
59.11206 +     *
59.11207 +     * @class WallTransition
59.11208 +     * @constructor
59.11209 +     *
59.11210 +     * @param {Number|Array} [state=0] Initial state
59.11211 +     */
59.11212 +    function WallTransition(state) {
59.11213 +        state = state || 0;
59.11214 +
59.11215 +        this.endState  = new Vector(state);
59.11216 +        this.initState = new Vector();
59.11217 +
59.11218 +        this.spring = new Spring({anchor : this.endState});
59.11219 +        this.wall   = new Wall();
59.11220 +
59.11221 +        this._restTolerance = 1e-10;
59.11222 +        this._dimensions = 1;
59.11223 +        this._absRestTolerance = this._restTolerance;
59.11224 +        this._callback = undefined;
59.11225 +
59.11226 +        this.PE = new PE();
59.11227 +        this.particle = new Particle();
59.11228 +
59.11229 +        this.PE.addBody(this.particle);
59.11230 +        this.PE.attach([this.wall, this.spring], this.particle);
59.11231 +    }
59.11232 +
59.11233 +    WallTransition.SUPPORTS_MULTIPLE = 3;
59.11234 +
59.11235 +    /**
59.11236 +     * @property WallTransition.DEFAULT_OPTIONS
59.11237 +     * @type Object
59.11238 +     * @protected
59.11239 +     * @static
59.11240 +     */
59.11241 +    WallTransition.DEFAULT_OPTIONS = {
59.11242 +
59.11243 +        /**
59.11244 +         * The amount of time in milliseconds taken for one complete oscillation
59.11245 +         * when there is no damping
59.11246 +         *    Range : [0, Infinity]
59.11247 +         *
59.11248 +         * @attribute period
59.11249 +         * @type Number
59.11250 +         * @default 300
59.11251 +         */
59.11252 +        period : 300,
59.11253 +
59.11254 +        /**
59.11255 +         * The damping of the snap.
59.11256 +         *    Range : [0, 1]
59.11257 +         *    0 = no damping, and the spring will oscillate forever
59.11258 +         *    1 = critically damped (the spring will never oscillate)
59.11259 +         *
59.11260 +         * @attribute dampingRatio
59.11261 +         * @type Number
59.11262 +         * @default 0.5
59.11263 +         */
59.11264 +        dampingRatio : 0.5,
59.11265 +
59.11266 +        /**
59.11267 +         * The initial velocity of the transition.
59.11268 +         *
59.11269 +         * @attribute velocity
59.11270 +         * @type Number|Array
59.11271 +         * @default 0
59.11272 +         */
59.11273 +        velocity : 0,
59.11274 +
59.11275 +        /**
59.11276 +         * The percentage of momentum transferred to the wall
59.11277 +         *
59.11278 +         * @attribute restitution
59.11279 +         * @type Number
59.11280 +         * @default 0.5
59.11281 +         */
59.11282 +        resitution : 0.5
59.11283 +    };
59.11284 +
59.11285 +    function _getEnergy() {
59.11286 +        return this.particle.getEnergy() + this.spring.getEnergy(this.particle);
59.11287 +    }
59.11288 +
59.11289 +    function _setAbsoluteRestTolerance() {
59.11290 +        var distance = this.endState.sub(this.initState).normSquared();
59.11291 +        this._absRestTolerance = (distance === 0)
59.11292 +            ? this._restTolerance
59.11293 +            : this._restTolerance * distance;
59.11294 +    }
59.11295 +
59.11296 +    function _wake() {
59.11297 +        this.PE.wake();
59.11298 +    }
59.11299 +
59.11300 +    function _sleep() {
59.11301 +        this.PE.sleep();
59.11302 +    }
59.11303 +
59.11304 +    function _setTarget(target) {
59.11305 +        this.endState.set(target);
59.11306 +
59.11307 +        var dist = this.endState.sub(this.initState).norm();
59.11308 +
59.11309 +        this.wall.setOptions({
59.11310 +            distance : this.endState.norm(),
59.11311 +            normal : (dist === 0)
59.11312 +                ? this.particle.velocity.normalize(-1)
59.11313 +                : this.endState.sub(this.initState).normalize(-1)
59.11314 +        });
59.11315 +
59.11316 +        _setAbsoluteRestTolerance.call(this);
59.11317 +    }
59.11318 +
59.11319 +    function _setParticlePosition(p) {
59.11320 +        this.particle.position.set(p);
59.11321 +    }
59.11322 +
59.11323 +    function _setParticleVelocity(v) {
59.11324 +        this.particle.velocity.set(v);
59.11325 +    }
59.11326 +
59.11327 +    function _getParticlePosition() {
59.11328 +        return (this._dimensions === 0)
59.11329 +            ? this.particle.getPosition1D()
59.11330 +            : this.particle.getPosition();
59.11331 +    }
59.11332 +
59.11333 +    function _getParticleVelocity() {
59.11334 +        return (this._dimensions === 0)
59.11335 +            ? this.particle.getVelocity1D()
59.11336 +            : this.particle.getVelocity();
59.11337 +    }
59.11338 +
59.11339 +    function _setCallback(callback) {
59.11340 +        this._callback = callback;
59.11341 +    }
59.11342 +
59.11343 +    function _update() {
59.11344 +        if (this.PE.isSleeping()) {
59.11345 +            if (this._callback) {
59.11346 +                var cb = this._callback;
59.11347 +                this._callback = undefined;
59.11348 +                cb();
59.11349 +            }
59.11350 +            return;
59.11351 +        }
59.11352 +        var energy = _getEnergy.call(this);
59.11353 +        if (energy < this._absRestTolerance) {
59.11354 +            _sleep.call(this);
59.11355 +            _setParticlePosition.call(this, this.endState);
59.11356 +            _setParticleVelocity.call(this, [0,0,0]);
59.11357 +        }
59.11358 +    }
59.11359 +
59.11360 +    function _setupDefinition(def) {
59.11361 +        var defaults = WallTransition.DEFAULT_OPTIONS;
59.11362 +        if (def.period === undefined) def.period = defaults.period;
59.11363 +        if (def.dampingRatio === undefined) def.dampingRatio = defaults.dampingRatio;
59.11364 +        if (def.velocity === undefined) def.velocity = defaults.velocity;
59.11365 +        if (def.restitution === undefined) def.restitution = defaults.restitution;
59.11366 +
59.11367 +        //setup spring
59.11368 +        this.spring.setOptions({
59.11369 +            period : def.period,
59.11370 +            dampingRatio : def.dampingRatio
59.11371 +        });
59.11372 +
59.11373 +        //setup wall
59.11374 +        this.wall.setOptions({
59.11375 +            restitution : def.restitution
59.11376 +        });
59.11377 +
59.11378 +        //setup particle
59.11379 +        _setParticleVelocity.call(this, def.velocity);
59.11380 +    }
59.11381 +
59.11382 +    /**
59.11383 +     * Resets the state and velocity
59.11384 +     *
59.11385 +     * @method reset
59.11386 +     *
59.11387 +     * @param {Number|Array}  state     State
59.11388 +     * @param  {Number|Array} [velocity] Velocity
59.11389 +     */
59.11390 +    WallTransition.prototype.reset = function reset(state, velocity) {
59.11391 +        this._dimensions = (state instanceof Array)
59.11392 +            ? state.length
59.11393 +            : 0;
59.11394 +
59.11395 +        this.initState.set(state);
59.11396 +        _setParticlePosition.call(this, state);
59.11397 +        if (velocity) _setParticleVelocity.call(this, velocity);
59.11398 +        _setTarget.call(this, state);
59.11399 +        _setCallback.call(this, undefined);
59.11400 +    };
59.11401 +
59.11402 +    /**
59.11403 +     * Getter for velocity
59.11404 +     *
59.11405 +     * @method getVelocity
59.11406 +     *
59.11407 +     * @return velocity {Number|Array}
59.11408 +     */
59.11409 +    WallTransition.prototype.getVelocity = function getVelocity() {
59.11410 +        return _getParticleVelocity.call(this);
59.11411 +    };
59.11412 +
59.11413 +    /**
59.11414 +     * Setter for velocity
59.11415 +     *
59.11416 +     * @method setVelocity
59.11417 +     *
59.11418 +     * @return velocity {Number|Array}
59.11419 +     */
59.11420 +    WallTransition.prototype.setVelocity = function setVelocity(velocity) {
59.11421 +        this.call(this, _setParticleVelocity(velocity));
59.11422 +    };
59.11423 +
59.11424 +    /**
59.11425 +     * Detects whether a transition is in progress
59.11426 +     *
59.11427 +     * @method isActive
59.11428 +     *
59.11429 +     * @return {Boolean}
59.11430 +     */
59.11431 +    WallTransition.prototype.isActive = function isActive() {
59.11432 +        return !this.PE.isSleeping();
59.11433 +    };
59.11434 +
59.11435 +    /**
59.11436 +     * Halt the transition
59.11437 +     *
59.11438 +     * @method halt
59.11439 +     */
59.11440 +    WallTransition.prototype.halt = function halt() {
59.11441 +        this.set(this.get());
59.11442 +    };
59.11443 +
59.11444 +    /**
59.11445 +     * Getter
59.11446 +     *
59.11447 +     * @method get
59.11448 +     *
59.11449 +     * @return state {Number|Array}
59.11450 +     */
59.11451 +    WallTransition.prototype.get = function get() {
59.11452 +        _update.call(this);
59.11453 +        return _getParticlePosition.call(this);
59.11454 +    };
59.11455 +
59.11456 +    /**
59.11457 +     * Set the end position and transition, with optional callback on completion.
59.11458 +     *
59.11459 +     * @method set
59.11460 +     *
59.11461 +     * @param state {Number|Array}      Final state
59.11462 +     * @param [definition] {Object}     Transition definition
59.11463 +     * @param [callback] {Function}     Callback
59.11464 +     */
59.11465 +    WallTransition.prototype.set = function set(state, definition, callback) {
59.11466 +        if (!definition) {
59.11467 +            this.reset(state);
59.11468 +            if (callback) callback();
59.11469 +            return;
59.11470 +        }
59.11471 +
59.11472 +        this._dimensions = (state instanceof Array)
59.11473 +            ? state.length
59.11474 +            : 0;
59.11475 +
59.11476 +        _wake.call(this);
59.11477 +        _setupDefinition.call(this, definition);
59.11478 +        _setTarget.call(this, state);
59.11479 +        _setCallback.call(this, callback);
59.11480 +    };
59.11481 +
59.11482 +    module.exports = WallTransition;
59.11483 +});
59.11484 +
59.11485 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11486 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11487 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11488 + *
59.11489 + * Owner: mark@famo.us
59.11490 + * @license MPL 2.0
59.11491 + * @copyright Famous Industries, Inc. 2014
59.11492 + */
59.11493 +
59.11494 +define('famous/surfaces/CanvasSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
59.11495 +    var Surface = require('famous/core/Surface');
59.11496 +
59.11497 +    /**
59.11498 +     * A surface containing an HTML5 Canvas element.
59.11499 +     *   This extends the Surface class.
59.11500 +     *
59.11501 +     * @class CanvasSurface
59.11502 +     * @extends Surface
59.11503 +     * @constructor
59.11504 +     * @param {Object} [options] overrides of default options
59.11505 +     * @param {Array.Number} [options.canvasSize] [width, height] for document element
59.11506 +     */
59.11507 +    function CanvasSurface(options) {
59.11508 +        if (options && options.canvasSize) this._canvasSize = options.canvasSize;
59.11509 +        Surface.apply(this, arguments);
59.11510 +        if (!this._canvasSize) this._canvasSize = this.getSize();
59.11511 +        this._backBuffer = document.createElement('canvas');
59.11512 +        if (this._canvasSize) {
59.11513 +            this._backBuffer.width = this._canvasSize[0];
59.11514 +            this._backBuffer.height = this._canvasSize[1];
59.11515 +        }
59.11516 +        this._contextId = undefined;
59.11517 +    }
59.11518 +
59.11519 +    CanvasSurface.prototype = Object.create(Surface.prototype);
59.11520 +    CanvasSurface.prototype.constructor = CanvasSurface;
59.11521 +    CanvasSurface.prototype.elementType = 'canvas';
59.11522 +    CanvasSurface.prototype.elementClass = 'famous-surface';
59.11523 +
59.11524 +    /**
59.11525 +     * Set inner document content.  Note that this is a noop for CanvasSurface.
59.11526 +     *
59.11527 +     * @method setContent
59.11528 +     *
59.11529 +     */
59.11530 +    CanvasSurface.prototype.setContent = function setContent() {};
59.11531 +
59.11532 +    /**
59.11533 +     * Place the document element this component manages into the document.
59.11534 +     *    This will draw the content to the document.
59.11535 +     *
59.11536 +     * @private
59.11537 +     * @method deploy
59.11538 +     * @param {Node} target document parent of this container
59.11539 +     */
59.11540 +    CanvasSurface.prototype.deploy = function deploy(target) {
59.11541 +        if (this._canvasSize) {
59.11542 +            target.width = this._canvasSize[0];
59.11543 +            target.height = this._canvasSize[1];
59.11544 +        }
59.11545 +        if (this._contextId === '2d') {
59.11546 +            target.getContext(this._contextId).drawImage(this._backBuffer, 0, 0);
59.11547 +            this._backBuffer.width = 0;
59.11548 +            this._backBuffer.height = 0;
59.11549 +        }
59.11550 +    };
59.11551 +
59.11552 +    /**
59.11553 +     * Remove this component and contained content from the document
59.11554 +     *
59.11555 +     * @private
59.11556 +     * @method recall
59.11557 +     *
59.11558 +     * @param {Node} target node to which the component was deployed
59.11559 +     */
59.11560 +    CanvasSurface.prototype.recall = function recall(target) {
59.11561 +        var size = this.getSize();
59.11562 +
59.11563 +        this._backBuffer.width = target.width;
59.11564 +        this._backBuffer.height = target.height;
59.11565 +
59.11566 +        if (this._contextId === '2d') {
59.11567 +            this._backBuffer.getContext(this._contextId).drawImage(target, 0, 0);
59.11568 +            target.width = 0;
59.11569 +            target.height = 0;
59.11570 +        }
59.11571 +    };
59.11572 +
59.11573 +    /**
59.11574 +     * Returns the canvas element's context
59.11575 +     *
59.11576 +     * @method getContext
59.11577 +     * @param {string} contextId context identifier
59.11578 +     */
59.11579 +    CanvasSurface.prototype.getContext = function getContext(contextId) {
59.11580 +        this._contextId = contextId;
59.11581 +        return this._currTarget ? this._currTarget.getContext(contextId) : this._backBuffer.getContext(contextId);
59.11582 +    };
59.11583 +
59.11584 +    /**
59.11585 +     *  Set the size of the surface and canvas element.
59.11586 +     *
59.11587 +     *  @method setSize
59.11588 +     *  @param {Array.number} size [width, height] of surface
59.11589 +     *  @param {Array.number} canvasSize [width, height] of canvas surface
59.11590 +     */
59.11591 +    CanvasSurface.prototype.setSize = function setSize(size, canvasSize) {
59.11592 +        Surface.prototype.setSize.apply(this, arguments);
59.11593 +        if (canvasSize) this._canvasSize = [canvasSize[0], canvasSize[1]];
59.11594 +        if (this._currTarget) {
59.11595 +            this._currTarget.width = this._canvasSize[0];
59.11596 +            this._currTarget.height = this._canvasSize[1];
59.11597 +        }
59.11598 +    };
59.11599 +
59.11600 +    module.exports = CanvasSurface;
59.11601 +});
59.11602 +
59.11603 +
59.11604 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11605 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11606 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11607 + *
59.11608 + * Owner: mark@famo.us
59.11609 + * @license MPL 2.0
59.11610 + * @copyright Famous Industries, Inc. 2014
59.11611 + */
59.11612 +
59.11613 +define('famous/surfaces/ContainerSurface',['require','exports','module','famous/core/Surface','famous/core/Context'],function(require, exports, module) {
59.11614 +    var Surface = require('famous/core/Surface');
59.11615 +    var Context = require('famous/core/Context');
59.11616 +
59.11617 +    /**
59.11618 +     * ContainerSurface is an object designed to contain surfaces and
59.11619 +     *   set properties to be applied to all of them at once.
59.11620 +     *   This extends the Surface class.
59.11621 +     *   A container surface will enforce these properties on the
59.11622 +     *   surfaces it contains:
59.11623 +     *
59.11624 +     *   size (clips contained surfaces to its own width and height);
59.11625 +     *
59.11626 +     *   origin;
59.11627 +     *
59.11628 +     *   its own opacity and transform, which will be automatically
59.11629 +     *   applied to  all Surfaces contained directly and indirectly.
59.11630 +     *
59.11631 +     * @class ContainerSurface
59.11632 +     * @extends Surface
59.11633 +     * @constructor
59.11634 +     * @param {Array.Number} [options.size] [width, height] in pixels
59.11635 +     * @param {Array.string} [options.classes] CSS classes to set on all inner content
59.11636 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
59.11637 +     * @param {string} [options.content] inner (HTML) content of surface (should not be used)
59.11638 +     */
59.11639 +    function ContainerSurface(options) {
59.11640 +        Surface.call(this, options);
59.11641 +        this._container = document.createElement('div');
59.11642 +        this._container.classList.add('famous-group');
59.11643 +        this._container.classList.add('famous-container-group');
59.11644 +        this._shouldRecalculateSize = false;
59.11645 +        this.context = new Context(this._container);
59.11646 +        this.setContent(this._container);
59.11647 +    }
59.11648 +
59.11649 +    ContainerSurface.prototype = Object.create(Surface.prototype);
59.11650 +    ContainerSurface.prototype.constructor = ContainerSurface;
59.11651 +    ContainerSurface.prototype.elementType = 'div';
59.11652 +    ContainerSurface.prototype.elementClass = 'famous-surface';
59.11653 +
59.11654 +    /**
59.11655 +     * Add renderables to this object's render tree
59.11656 +     *
59.11657 +     * @method add
59.11658 +     *
59.11659 +     * @param {Object} obj renderable object
59.11660 +     * @return {RenderNode} RenderNode wrapping this object, if not already a RenderNode
59.11661 +     */
59.11662 +    ContainerSurface.prototype.add = function add() {
59.11663 +        return this.context.add.apply(this.context, arguments);
59.11664 +    };
59.11665 +
59.11666 +    /**
59.11667 +     * Return spec for this surface.  Note: Can result in a size recalculation.
59.11668 +     *
59.11669 +     * @private
59.11670 +     * @method render
59.11671 +     *
59.11672 +     * @return {Object} render spec for this surface (spec id)
59.11673 +     */
59.11674 +    ContainerSurface.prototype.render = function render() {
59.11675 +        if (this._sizeDirty) this._shouldRecalculateSize = true;
59.11676 +        return Surface.prototype.render.apply(this, arguments);
59.11677 +    };
59.11678 +
59.11679 +    /**
59.11680 +     * Place the document element this component manages into the document.
59.11681 +     *
59.11682 +     * @private
59.11683 +     * @method deploy
59.11684 +     * @param {Node} target document parent of this container
59.11685 +     */
59.11686 +    ContainerSurface.prototype.deploy = function deploy() {
59.11687 +        this._shouldRecalculateSize = true;
59.11688 +        return Surface.prototype.deploy.apply(this, arguments);
59.11689 +    };
59.11690 +
59.11691 +    /**
59.11692 +     * Apply changes from this component to the corresponding document element.
59.11693 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.11694 +     * and matrix transforms.
59.11695 +     *
59.11696 +     * @private
59.11697 +     * @method commit
59.11698 +     * @param {Context} context commit context
59.11699 +     * @param {Transform} transform unused TODO
59.11700 +     * @param {Number} opacity  unused TODO
59.11701 +     * @param {Array.Number} origin unused TODO
59.11702 +     * @param {Array.Number} size unused TODO
59.11703 +     * @return {undefined} TODO returns an undefined value
59.11704 +     */
59.11705 +    ContainerSurface.prototype.commit = function commit(context, transform, opacity, origin, size) {
59.11706 +        var previousSize = this._size ? [this._size[0], this._size[1]] : null;
59.11707 +        var result = Surface.prototype.commit.apply(this, arguments);
59.11708 +        if (this._shouldRecalculateSize || (previousSize && (this._size[0] !== previousSize[0] || this._size[1] !== previousSize[1]))) {
59.11709 +            this.context.setSize();
59.11710 +            this._shouldRecalculateSize = false;
59.11711 +        }
59.11712 +        this.context.update();
59.11713 +        return result;
59.11714 +    };
59.11715 +
59.11716 +    module.exports = ContainerSurface;
59.11717 +});
59.11718 +
59.11719 +define('famous/surfaces/FormContainerSurface',['require','exports','module','./ContainerSurface'],function(require, exports, module) {
59.11720 +    var ContainerSurface = require('./ContainerSurface');
59.11721 +
59.11722 +    function FormContainerSurface(options) {
59.11723 +        if (options) this._method = options.method || '';
59.11724 +        ContainerSurface.apply(this, arguments);
59.11725 +    }
59.11726 +
59.11727 +    FormContainerSurface.prototype = Object.create(ContainerSurface.prototype);
59.11728 +    FormContainerSurface.prototype.constructor = FormContainerSurface;
59.11729 +
59.11730 +    FormContainerSurface.prototype.elementType = 'form';
59.11731 +
59.11732 +    FormContainerSurface.prototype.deploy = function deploy(target) {
59.11733 +        if (this._method) target.method = this._method;
59.11734 +        return ContainerSurface.prototype.deploy.apply(this, arguments);
59.11735 +    };
59.11736 +
59.11737 +    module.exports = FormContainerSurface;
59.11738 +});
59.11739 +
59.11740 +
59.11741 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11742 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11743 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11744 + *
59.11745 + * Owner: mark@famo.us
59.11746 + * @license MPL 2.0
59.11747 + * @copyright Famous Industries, Inc. 2014
59.11748 + */
59.11749 +
59.11750 +define('famous/surfaces/ImageSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
59.11751 +    var Surface = require('famous/core/Surface');
59.11752 +
59.11753 +    /**
59.11754 +     * A surface containing image content.
59.11755 +     *   This extends the Surface class.
59.11756 +     *
59.11757 +     * @class ImageSurface
59.11758 +     *
59.11759 +     * @extends Surface
59.11760 +     * @constructor
59.11761 +     * @param {Object} [options] overrides of default options
59.11762 +     */
59.11763 +    function ImageSurface(options) {
59.11764 +        this._imageUrl = undefined;
59.11765 +        Surface.apply(this, arguments);
59.11766 +    }
59.11767 +
59.11768 +    ImageSurface.prototype = Object.create(Surface.prototype);
59.11769 +    ImageSurface.prototype.constructor = ImageSurface;
59.11770 +    ImageSurface.prototype.elementType = 'img';
59.11771 +    ImageSurface.prototype.elementClass = 'famous-surface';
59.11772 +
59.11773 +    /**
59.11774 +     * Set content URL.  This will cause a re-rendering.
59.11775 +     * @method setContent
59.11776 +     * @param {string} imageUrl
59.11777 +     */
59.11778 +    ImageSurface.prototype.setContent = function setContent(imageUrl) {
59.11779 +        this._imageUrl = imageUrl;
59.11780 +        this._contentDirty = true;
59.11781 +    };
59.11782 +
59.11783 +    /**
59.11784 +     * Place the document element that this component manages into the document.
59.11785 +     *
59.11786 +     * @private
59.11787 +     * @method deploy
59.11788 +     * @param {Node} target document parent of this container
59.11789 +     */
59.11790 +    ImageSurface.prototype.deploy = function deploy(target) {
59.11791 +        target.src = this._imageUrl || '';
59.11792 +    };
59.11793 +
59.11794 +    /**
59.11795 +     * Remove this component and contained content from the document
59.11796 +     *
59.11797 +     * @private
59.11798 +     * @method recall
59.11799 +     *
59.11800 +     * @param {Node} target node to which the component was deployed
59.11801 +     */
59.11802 +    ImageSurface.prototype.recall = function recall(target) {
59.11803 +        target.src = '';
59.11804 +    };
59.11805 +
59.11806 +    module.exports = ImageSurface;
59.11807 +});
59.11808 +
59.11809 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11810 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11811 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11812 + *
59.11813 + * Owner: mark@famo.us
59.11814 + * @license MPL 2.0
59.11815 + * @copyright Famous Industries, Inc. 2014
59.11816 + */
59.11817 +
59.11818 +define('famous/surfaces/InputSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
59.11819 +    var Surface = require('famous/core/Surface');
59.11820 +
59.11821 +    /**
59.11822 +     * A Famo.us surface in the form of an HTML input element.
59.11823 +     *   This extends the Surface class.
59.11824 +     *
59.11825 +     * @class InputSurface
59.11826 +     * @extends Surface
59.11827 +     * @constructor
59.11828 +     * @param {Object} [options] overrides of default options
59.11829 +     * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an <input> element
59.11830 +     * @param {string} [options.type] specifies the type of element to display (e.g. 'datetime', 'text', 'button', etc.)
59.11831 +     * @param {string} [options.value] value of text
59.11832 +     */
59.11833 +    function InputSurface(options) {
59.11834 +        this._placeholder = options.placeholder || '';
59.11835 +        this._value       = options.value || '';
59.11836 +        this._type        = options.type || 'text';
59.11837 +        this._name        = options.name || '';
59.11838 +
59.11839 +        Surface.apply(this, arguments);
59.11840 +
59.11841 +        this.on('click', this.focus.bind(this));
59.11842 +        window.addEventListener('click', function(event) {
59.11843 +            if (event.target !== this._currTarget) this.blur();
59.11844 +        }.bind(this));
59.11845 +    }
59.11846 +    InputSurface.prototype = Object.create(Surface.prototype);
59.11847 +    InputSurface.prototype.constructor = InputSurface;
59.11848 +
59.11849 +    InputSurface.prototype.elementType = 'input';
59.11850 +    InputSurface.prototype.elementClass = 'famous-surface';
59.11851 +
59.11852 +    /**
59.11853 +     * Set placeholder text.  Note: Triggers a repaint.
59.11854 +     *
59.11855 +     * @method setPlaceholder
59.11856 +     * @param {string} str Value to set the placeholder to.
59.11857 +     * @return {InputSurface} this, allowing method chaining.
59.11858 +     */
59.11859 +    InputSurface.prototype.setPlaceholder = function setPlaceholder(str) {
59.11860 +        this._placeholder = str;
59.11861 +        this._contentDirty = true;
59.11862 +        return this;
59.11863 +    };
59.11864 +
59.11865 +    /**
59.11866 +     * Focus on the current input, pulling up the keyboard on mobile.
59.11867 +     *
59.11868 +     * @method focus
59.11869 +     * @return {InputSurface} this, allowing method chaining.
59.11870 +     */
59.11871 +    InputSurface.prototype.focus = function focus() {
59.11872 +        if (this._currTarget) this._currTarget.focus();
59.11873 +        return this;
59.11874 +    };
59.11875 +
59.11876 +    /**
59.11877 +     * Blur the current input, hiding the keyboard on mobile.
59.11878 +     *
59.11879 +     * @method blur
59.11880 +     * @return {InputSurface} this, allowing method chaining.
59.11881 +     */
59.11882 +    InputSurface.prototype.blur = function blur() {
59.11883 +        if (this._currTarget) this._currTarget.blur();
59.11884 +        return this;
59.11885 +    };
59.11886 +
59.11887 +    /**
59.11888 +     * Set the placeholder conent.
59.11889 +     *   Note: Triggers a repaint next tick.
59.11890 +     *
59.11891 +     * @method setValue
59.11892 +     * @param {string} str Value to set the main input value to.
59.11893 +     * @return {InputSurface} this, allowing method chaining.
59.11894 +     */
59.11895 +    InputSurface.prototype.setValue = function setValue(str) {
59.11896 +        this._value = str;
59.11897 +        this._contentDirty = true;
59.11898 +        return this;
59.11899 +    };
59.11900 +
59.11901 +    /**
59.11902 +     * Set the type of element to display conent.
59.11903 +     *   Note: Triggers a repaint next tick.
59.11904 +     *
59.11905 +     * @method setType
59.11906 +     * @param {string} str type of the input surface (e.g. 'button', 'text')
59.11907 +     * @return {InputSurface} this, allowing method chaining.
59.11908 +     */
59.11909 +    InputSurface.prototype.setType = function setType(str) {
59.11910 +        this._type = str;
59.11911 +        this._contentDirty = true;
59.11912 +        return this;
59.11913 +    };
59.11914 +
59.11915 +    /**
59.11916 +     * Get the value of the inner content of the element (e.g. the entered text)
59.11917 +     *
59.11918 +     * @method getValue
59.11919 +     * @return {string} value of element
59.11920 +     */
59.11921 +    InputSurface.prototype.getValue = function getValue() {
59.11922 +        if (this._currTarget) {
59.11923 +            return this._currTarget.value;
59.11924 +        }
59.11925 +        else {
59.11926 +            return this._value;
59.11927 +        }
59.11928 +    };
59.11929 +
59.11930 +    /**
59.11931 +     * Set the name attribute of the element.
59.11932 +     *   Note: Triggers a repaint next tick.
59.11933 +     *
59.11934 +     * @method setName
59.11935 +     * @param {string} str element name
59.11936 +     * @return {InputSurface} this, allowing method chaining.
59.11937 +     */
59.11938 +    InputSurface.prototype.setName = function setName(str) {
59.11939 +        this._name = str;
59.11940 +        this._contentDirty = true;
59.11941 +        return this;
59.11942 +    };
59.11943 +
59.11944 +    /**
59.11945 +     * Get the name attribute of the element.
59.11946 +     *
59.11947 +     * @method getName
59.11948 +     * @return {string} name of element
59.11949 +     */
59.11950 +    InputSurface.prototype.getName = function getName() {
59.11951 +        return this._name;
59.11952 +    };
59.11953 +
59.11954 +    /**
59.11955 +     * Place the document element this component manages into the document.
59.11956 +     *
59.11957 +     * @private
59.11958 +     * @method deploy
59.11959 +     * @param {Node} target document parent of this container
59.11960 +     */
59.11961 +    InputSurface.prototype.deploy = function deploy(target) {
59.11962 +        if (this._placeholder !== '') target.placeholder = this._placeholder;
59.11963 +        target.value = this._value;
59.11964 +        target.type = this._type;
59.11965 +        target.name = this._name;
59.11966 +    };
59.11967 +
59.11968 +    module.exports = InputSurface;
59.11969 +});
59.11970 +
59.11971 +define('famous/surfaces/SubmitInputSurface',['require','exports','module','./InputSurface'],function(require, exports, module) {
59.11972 +    var InputSurface = require('./InputSurface');
59.11973 +
59.11974 +    function SubmitInputSurface(options) {
59.11975 +        InputSurface.apply(this, arguments);
59.11976 +        this._type = 'submit';
59.11977 +        if (options && options.onClick) this.setOnClick(options.onClick);
59.11978 +    }
59.11979 +
59.11980 +    SubmitInputSurface.prototype = Object.create(InputSurface.prototype);
59.11981 +    SubmitInputSurface.prototype.constructor = SubmitInputSurface;
59.11982 +
59.11983 +    SubmitInputSurface.prototype.setOnClick = function(onClick) {
59.11984 +        this.onClick = onClick;
59.11985 +    };
59.11986 +
59.11987 +    SubmitInputSurface.prototype.deploy = function deploy(target) {
59.11988 +        if (this.onclick) target.onClick = this.onClick;
59.11989 +        InputSurface.prototype.deploy.apply(this, arguments);
59.11990 +    };
59.11991 +
59.11992 +    module.exports = SubmitInputSurface;
59.11993 +});
59.11994 +
59.11995 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.11996 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.11997 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.11998 + *
59.11999 + * Owner: mark@famo.us
59.12000 + * @license MPL 2.0
59.12001 + * @copyright Famous Industries, Inc. 2014
59.12002 + */
59.12003 +
59.12004 +define('famous/surfaces/TextareaSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
59.12005 +    var Surface = require('famous/core/Surface');
59.12006 +
59.12007 +    /**
59.12008 +     * A Famo.us surface in the form of an HTML textarea element.
59.12009 +     *   This extends the Surface class.
59.12010 +     *
59.12011 +     * @class TextareaSurface
59.12012 +     * @extends Surface
59.12013 +     * @constructor
59.12014 +     * @param {Object} [options] overrides of default options
59.12015 +     * @param {string} [options.placeholder] placeholder text hint that describes the expected value of an textarea element
59.12016 +     * @param {string} [options.value] value of text
59.12017 +     * @param {string} [options.name] specifies the name of textarea
59.12018 +     * @param {string} [options.wrap] specify 'hard' or 'soft' wrap for textarea
59.12019 +     * @param {number} [options.cols] number of columns in textarea
59.12020 +     * @param {number} [options.rows] number of rows in textarea
59.12021 +     */
59.12022 +    function TextareaSurface(options) {
59.12023 +        this._placeholder = options.placeholder || '';
59.12024 +        this._value       = options.value || '';
59.12025 +        this._name        = options.name || '';
59.12026 +        this._wrap        = options.wrap || '';
59.12027 +        this._cols        = options.cols || '';
59.12028 +        this._rows        = options.rows || '';
59.12029 +
59.12030 +        Surface.apply(this, arguments);
59.12031 +        this.on('click', this.focus.bind(this));
59.12032 +    }
59.12033 +    TextareaSurface.prototype = Object.create(Surface.prototype);
59.12034 +    TextareaSurface.prototype.constructor = TextareaSurface;
59.12035 +
59.12036 +    TextareaSurface.prototype.elementType = 'textarea';
59.12037 +    TextareaSurface.prototype.elementClass = 'famous-surface';
59.12038 +
59.12039 +    /**
59.12040 +     * Set placeholder text.  Note: Triggers a repaint.
59.12041 +     *
59.12042 +     * @method setPlaceholder
59.12043 +     * @param {string} str Value to set the placeholder to.
59.12044 +     * @return {TextareaSurface} this, allowing method chaining.
59.12045 +     */
59.12046 +    TextareaSurface.prototype.setPlaceholder = function setPlaceholder(str) {
59.12047 +        this._placeholder = str;
59.12048 +        this._contentDirty = true;
59.12049 +        return this;
59.12050 +    };
59.12051 +
59.12052 +    /**
59.12053 +     * Focus on the current input, pulling up the keyboard on mobile.
59.12054 +     *
59.12055 +     * @method focus
59.12056 +     * @return {TextareaSurface} this, allowing method chaining.
59.12057 +     */
59.12058 +    TextareaSurface.prototype.focus = function focus() {
59.12059 +        if (this._currTarget) this._currTarget.focus();
59.12060 +        return this;
59.12061 +    };
59.12062 +
59.12063 +    /**
59.12064 +     * Blur the current input, hiding the keyboard on mobile.
59.12065 +     *
59.12066 +     * @method focus
59.12067 +     * @return {TextareaSurface} this, allowing method chaining.
59.12068 +     */
59.12069 +    TextareaSurface.prototype.blur = function blur() {
59.12070 +        if (this._currTarget) this._currTarget.blur();
59.12071 +        return this;
59.12072 +    };
59.12073 +
59.12074 +    /**
59.12075 +     * Set the value of textarea.
59.12076 +     *   Note: Triggers a repaint next tick.
59.12077 +     *
59.12078 +     * @method setValue
59.12079 +     * @param {string} str Value to set the main textarea value to.
59.12080 +     * @return {TextareaSurface} this, allowing method chaining.
59.12081 +     */
59.12082 +    TextareaSurface.prototype.setValue = function setValue(str) {
59.12083 +        this._value = str;
59.12084 +        this._contentDirty = true;
59.12085 +        return this;
59.12086 +    };
59.12087 +
59.12088 +    /**
59.12089 +     * Get the value of the inner content of the textarea (e.g. the entered text)
59.12090 +     *
59.12091 +     * @method getValue
59.12092 +     * @return {string} value of element
59.12093 +     */
59.12094 +    TextareaSurface.prototype.getValue = function getValue() {
59.12095 +        if (this._currTarget) {
59.12096 +            return this._currTarget.value;
59.12097 +        }
59.12098 +        else {
59.12099 +            return this._value;
59.12100 +        }
59.12101 +    };
59.12102 +
59.12103 +    /**
59.12104 +     * Set the name attribute of the element.
59.12105 +     *   Note: Triggers a repaint next tick.
59.12106 +     *
59.12107 +     * @method setName
59.12108 +     * @param {string} str element name
59.12109 +     * @return {TextareaSurface} this, allowing method chaining.
59.12110 +     */
59.12111 +    TextareaSurface.prototype.setName = function setName(str) {
59.12112 +        this._name = str;
59.12113 +        this._contentDirty = true;
59.12114 +        return this;
59.12115 +    };
59.12116 +
59.12117 +    /**
59.12118 +     * Get the name attribute of the element.
59.12119 +     *
59.12120 +     * @method getName
59.12121 +     * @return {string} name of element
59.12122 +     */
59.12123 +    TextareaSurface.prototype.getName = function getName() {
59.12124 +        return this._name;
59.12125 +    };
59.12126 +
59.12127 +    /**
59.12128 +     * Set the wrap of textarea.
59.12129 +     *   Note: Triggers a repaint next tick.
59.12130 +     *
59.12131 +     * @method setWrap
59.12132 +     * @param {string} str wrap of the textarea surface (e.g. 'soft', 'hard')
59.12133 +     * @return {TextareaSurface} this, allowing method chaining.
59.12134 +     */
59.12135 +    TextareaSurface.prototype.setWrap = function setWrap(str) {
59.12136 +        this._wrap = str;
59.12137 +        this._contentDirty = true;
59.12138 +        return this;
59.12139 +    };
59.12140 +
59.12141 +    /**
59.12142 +     * Set the number of columns visible in the textarea.
59.12143 +     *   Note: Overridden by surface size; set width to true. (eg. size: [true, *])
59.12144 +     *         Triggers a repaint next tick.
59.12145 +     *
59.12146 +     * @method setColumns
59.12147 +     * @param {number} num columns in textarea surface
59.12148 +     * @return {TextareaSurface} this, allowing method chaining.
59.12149 +     */
59.12150 +    TextareaSurface.prototype.setColumns = function setColumns(num) {
59.12151 +        this._cols = num;
59.12152 +        this._contentDirty = true;
59.12153 +        return this;
59.12154 +    };
59.12155 +
59.12156 +    /**
59.12157 +     * Set the number of rows visible in the textarea.
59.12158 +     *   Note: Overridden by surface size; set height to true. (eg. size: [*, true])
59.12159 +     *         Triggers a repaint next tick.
59.12160 +     *
59.12161 +     * @method setRows
59.12162 +     * @param {number} num rows in textarea surface
59.12163 +     * @return {TextareaSurface} this, allowing method chaining.
59.12164 +     */
59.12165 +    TextareaSurface.prototype.setRows = function setRows(num) {
59.12166 +        this._rows = num;
59.12167 +        this._contentDirty = true;
59.12168 +        return this;
59.12169 +    };
59.12170 +
59.12171 +    /**
59.12172 +     * Place the document element this component manages into the document.
59.12173 +     *
59.12174 +     * @private
59.12175 +     * @method deploy
59.12176 +     * @param {Node} target document parent of this container
59.12177 +     */
59.12178 +    TextareaSurface.prototype.deploy = function deploy(target) {
59.12179 +        if (this._placeholder !== '') target.placeholder = this._placeholder;
59.12180 +        if (this._value !== '') target.value = this._value;
59.12181 +        if (this._name !== '') target.name = this._name;
59.12182 +        if (this._wrap !== '') target.wrap = this._wrap;
59.12183 +        if (this._cols !== '') target.cols = this._cols;
59.12184 +        if (this._rows !== '') target.rows = this._rows;
59.12185 +    };
59.12186 +
59.12187 +    module.exports = TextareaSurface;
59.12188 +});
59.12189 +
59.12190 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12191 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12192 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12193 + *
59.12194 + * Owner: mark@famo.us
59.12195 + * @license MPL 2.0
59.12196 + * @copyright Famous Industries, Inc. 2014
59.12197 + */
59.12198 +
59.12199 +define('famous/surfaces/VideoSurface',['require','exports','module','famous/core/Surface'],function(require, exports, module) {
59.12200 +    var Surface = require('famous/core/Surface');
59.12201 +
59.12202 +    /**
59.12203 +     * Creates a famous surface containing video content. Currently adding
59.12204 +     *   controls and manipulating the video are not supported through the
59.12205 +     *   surface interface, but can be accomplished via standard JavaScript
59.12206 +     *   manipulation of the video DOM element.
59.12207 +     *   This extends the Surface class.
59.12208 +     *
59.12209 +     * @class VideoSurface
59.12210 +     * @extends Surface
59.12211 +     * @constructor
59.12212 +     * @param {Object} [options] default option overrides
59.12213 +     * @param {Array.Number} [options.size] [width, height] in pixels
59.12214 +     * @param {Array.string} [options.classes] CSS classes to set on inner content
59.12215 +     * @param {Array} [options.properties] string dictionary of HTML attributes to set on target div
59.12216 +     * @param {string} [options.content] inner (HTML) content of surface
59.12217 +     * @param {boolean} [options.autoplay] autoplay
59.12218 +     */
59.12219 +    function VideoSurface(options) {
59.12220 +        this._videoUrl = undefined;
59.12221 +        this.options = Object.create(VideoSurface.DEFAULT_OPTIONS);
59.12222 +        if (options) this.setOptions(options);
59.12223 +
59.12224 +        Surface.apply(this, arguments);
59.12225 +    }
59.12226 +    VideoSurface.prototype = Object.create(Surface.prototype);
59.12227 +    VideoSurface.prototype.constructor = VideoSurface;
59.12228 +
59.12229 +    VideoSurface.DEFAULT_OPTIONS = {
59.12230 +        autoplay: false
59.12231 +    };
59.12232 +
59.12233 +    VideoSurface.prototype.elementType = 'video';
59.12234 +    VideoSurface.prototype.elementClass = 'famous-surface';
59.12235 +
59.12236 +    /**
59.12237 +     * Set internal options, overriding any default options
59.12238 +     *
59.12239 +     * @method setOptions
59.12240 +     *
59.12241 +     * @param {Object} [options] overrides of default options
59.12242 +     * @param {Boolean} [options.autoplay] HTML autoplay
59.12243 +     */
59.12244 +    VideoSurface.prototype.setOptions = function setOptions(options) {
59.12245 +        for (var key in VideoSurface.DEFAULT_OPTIONS) {
59.12246 +            if (options[key] !== undefined) this.options[key] = options[key];
59.12247 +        }
59.12248 +    };
59.12249 +
59.12250 +    /**
59.12251 +     * Set url of the video.
59.12252 +     *
59.12253 +     * @method setContent
59.12254 +     * @param {string} videoUrl URL
59.12255 +     */
59.12256 +    VideoSurface.prototype.setContent = function setContent(videoUrl) {
59.12257 +        this._videoUrl = videoUrl;
59.12258 +        this._contentDirty = true;
59.12259 +    };
59.12260 +
59.12261 +    /**
59.12262 +     * Place the document element this component manages into the document.
59.12263 +     *   Note: In the case of VideoSurface, simply changes the options on the target.
59.12264 +     *
59.12265 +     * @private
59.12266 +     * @method deploy
59.12267 +     * @param {Node} target document parent of this container
59.12268 +     */
59.12269 +    VideoSurface.prototype.deploy = function deploy(target) {
59.12270 +        target.src = this._videoUrl;
59.12271 +        target.autoplay = this.options.autoplay;
59.12272 +    };
59.12273 +
59.12274 +    /**
59.12275 +     * Remove this component and contained content from the document.
59.12276 +     *   Note: This doesn't actually remove the <video> element from the
59.12277 +     *   document.
59.12278 +     * @private
59.12279 +     * @method recall
59.12280 +     *
59.12281 +     * @param {Node} target node to which the component was deployed
59.12282 +     */
59.12283 +    VideoSurface.prototype.recall = function recall(target) {
59.12284 +        target.src = '';
59.12285 +    };
59.12286 +
59.12287 +    module.exports = VideoSurface;
59.12288 +});
59.12289 +
59.12290 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12291 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12292 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12293 + *
59.12294 + * Owner: mark@famo.us
59.12295 + * @license MPL 2.0
59.12296 + * @copyright Famous Industries, Inc. 2014
59.12297 + */
59.12298 +
59.12299 +define('famous/utilities/KeyCodes',['require','exports','module'],function(require, exports, module) {
59.12300 +
59.12301 +    /**
59.12302 +     * Collection to map keyboard codes in plain english
59.12303 +     *
59.12304 +     * @class KeyCodes
59.12305 +     * @static
59.12306 +     */
59.12307 +    var KeyCodes = {
59.12308 +        0 : 48,
59.12309 +        1 : 49,
59.12310 +        2 : 50,
59.12311 +        3 : 51,
59.12312 +        4 : 52,
59.12313 +        5 : 53,
59.12314 +        6 : 54,
59.12315 +        7 : 55,
59.12316 +        8 : 56,
59.12317 +        9 : 57,
59.12318 +        a : 97,
59.12319 +        b : 98,
59.12320 +        c : 99,
59.12321 +        d : 100,
59.12322 +        e : 101,
59.12323 +        f : 102,
59.12324 +        g : 103,
59.12325 +        h : 104,
59.12326 +        i : 105,
59.12327 +        j : 106,
59.12328 +        k : 107,
59.12329 +        l : 108,
59.12330 +        m : 109,
59.12331 +        n : 110,
59.12332 +        o : 111,
59.12333 +        p : 112,
59.12334 +        q : 113,
59.12335 +        r : 114,
59.12336 +        s : 115,
59.12337 +        t : 116,
59.12338 +        u : 117,
59.12339 +        v : 118,
59.12340 +        w : 119,
59.12341 +        x : 120,
59.12342 +        y : 121,
59.12343 +        z : 122,
59.12344 +        A : 65,
59.12345 +        B : 66,
59.12346 +        C : 67,
59.12347 +        D : 68,
59.12348 +        E : 69,
59.12349 +        F : 70,
59.12350 +        G : 71,
59.12351 +        H : 72,
59.12352 +        I : 73,
59.12353 +        J : 74,
59.12354 +        K : 75,
59.12355 +        L : 76,
59.12356 +        M : 77,
59.12357 +        N : 78,
59.12358 +        O : 79,
59.12359 +        P : 80,
59.12360 +        Q : 81,
59.12361 +        R : 82,
59.12362 +        S : 83,
59.12363 +        T : 84,
59.12364 +        U : 85,
59.12365 +        V : 86,
59.12366 +        W : 87,
59.12367 +        X : 88,
59.12368 +        Y : 89,
59.12369 +        Z : 90,
59.12370 +        ENTER : 13,
59.12371 +        LEFT_ARROW: 37,
59.12372 +        RIGHT_ARROW: 39,
59.12373 +        UP_ARROW: 38,
59.12374 +        DOWN_ARROW: 40,
59.12375 +        SPACE: 32,
59.12376 +        SHIFT: 16,
59.12377 +        TAB: 9
59.12378 +    };
59.12379 +
59.12380 +    module.exports = KeyCodes;
59.12381 +});
59.12382 +
59.12383 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12384 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12385 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12386 + *
59.12387 + * Owner: mark@famo.us
59.12388 + * @license MPL 2.0
59.12389 + * @copyright Famous Industries, Inc. 2014
59.12390 + */
59.12391 +// TODO fix func-style
59.12392 +/*eslint func-style: [0, "declaration"] */
59.12393 +
59.12394 +define('famous/utilities/Timer',['require','exports','module','famous/core/Engine'],function(require, exports, module) {
59.12395 +    /**
59.12396 +     * An internal library to reproduce javascript time-based scheduling.
59.12397 +     *   Using standard javascript setTimeout methods can have a negative performance impact
59.12398 +     *   when combined with the Famous rendering process, so instead require Timer and call
59.12399 +     *   Timer.setTimeout, Timer.setInterval, etc.
59.12400 +     *
59.12401 +     * @class Timer
59.12402 +     * @constructor
59.12403 +     */
59.12404 +    var FamousEngine = require('famous/core/Engine');
59.12405 +
59.12406 +    var _event  = 'prerender';
59.12407 +
59.12408 +    var getTime = (window.performance) ?
59.12409 +        function() {
59.12410 +            return window.performance.now();
59.12411 +        }
59.12412 +        : function() {
59.12413 +            return Date.now();
59.12414 +        };
59.12415 +
59.12416 +    /**
59.12417 +     * Add a function to be run on every prerender
59.12418 +     *
59.12419 +     * @method addTimerFunction
59.12420 +     *
59.12421 +     * @param {function} fn function to be run every prerender
59.12422 +     *
59.12423 +     * @return {function} function passed in as parameter
59.12424 +     */
59.12425 +    function addTimerFunction(fn) {
59.12426 +        FamousEngine.on(_event, fn);
59.12427 +        return fn;
59.12428 +    }
59.12429 +
59.12430 +    /**
59.12431 +     * Wraps a function to be invoked after a certain amount of time.
59.12432 +     *  After a set duration has passed, it executes the function and
59.12433 +     *  removes it as a listener to 'prerender'.
59.12434 +     *
59.12435 +     * @method setTimeout
59.12436 +     *
59.12437 +     * @param {function} fn function to be run after a specified duration
59.12438 +     * @param {number} duration milliseconds from now to execute the function
59.12439 +     *
59.12440 +     * @return {function} function passed in as parameter
59.12441 +     */
59.12442 +    function setTimeout(fn, duration) {
59.12443 +        var t = getTime();
59.12444 +        var callback = function() {
59.12445 +            var t2 = getTime();
59.12446 +            if (t2 - t >= duration) {
59.12447 +                fn.apply(this, arguments);
59.12448 +                FamousEngine.removeListener(_event, callback);
59.12449 +            }
59.12450 +        };
59.12451 +        return addTimerFunction(callback);
59.12452 +    }
59.12453 +
59.12454 +    /**
59.12455 +     * Wraps a function to be invoked after a certain amount of time.
59.12456 +     *  After a set duration has passed, it executes the function and
59.12457 +     *  resets the execution time.
59.12458 +     *
59.12459 +     * @method setInterval
59.12460 +     *
59.12461 +     * @param {function} fn function to be run after a specified duration
59.12462 +     * @param {number} duration interval to execute function in milliseconds
59.12463 +     *
59.12464 +     * @return {function} function passed in as parameter
59.12465 +     */
59.12466 +    function setInterval(fn, duration) {
59.12467 +        var t = getTime();
59.12468 +        var callback = function() {
59.12469 +            var t2 = getTime();
59.12470 +            if (t2 - t >= duration) {
59.12471 +                fn.apply(this, arguments);
59.12472 +                t = getTime();
59.12473 +            }
59.12474 +        };
59.12475 +        return addTimerFunction(callback);
59.12476 +    }
59.12477 +
59.12478 +    /**
59.12479 +     * Wraps a function to be invoked after a certain amount of prerender ticks.
59.12480 +     *  Similar use to setTimeout but tied to the engine's run speed.
59.12481 +     *
59.12482 +     * @method after
59.12483 +     *
59.12484 +     * @param {function} fn function to be run after a specified amount of ticks
59.12485 +     * @param {number} numTicks number of prerender frames to wait
59.12486 +     *
59.12487 +     * @return {function} function passed in as parameter
59.12488 +     */
59.12489 +    function after(fn, numTicks) {
59.12490 +        if (numTicks === undefined) return undefined;
59.12491 +        var callback = function() {
59.12492 +            numTicks--;
59.12493 +            if (numTicks <= 0) { //in case numTicks is fraction or negative
59.12494 +                fn.apply(this, arguments);
59.12495 +                clear(callback);
59.12496 +            }
59.12497 +        };
59.12498 +        return addTimerFunction(callback);
59.12499 +    }
59.12500 +
59.12501 +    /**
59.12502 +     * Wraps a function to be continually invoked after a certain amount of prerender ticks.
59.12503 +     *  Similar use to setInterval but tied to the engine's run speed.
59.12504 +     *
59.12505 +     * @method every
59.12506 +     *
59.12507 +     * @param {function} fn function to be run after a specified amount of ticks
59.12508 +     * @param {number} numTicks number of prerender frames to wait
59.12509 +     *
59.12510 +     * @return {function} function passed in as parameter
59.12511 +     */
59.12512 +    function every(fn, numTicks) {
59.12513 +        numTicks = numTicks || 1;
59.12514 +        var initial = numTicks;
59.12515 +        var callback = function() {
59.12516 +            numTicks--;
59.12517 +            if (numTicks <= 0) { //in case numTicks is fraction or negative
59.12518 +                fn.apply(this, arguments);
59.12519 +                numTicks = initial;
59.12520 +            }
59.12521 +        };
59.12522 +        return addTimerFunction(callback);
59.12523 +    }
59.12524 +
59.12525 +    /**
59.12526 +     * Remove a function that gets called every prerender
59.12527 +     *
59.12528 +     * @method clear
59.12529 +     *
59.12530 +     * @param {function} fn event linstener
59.12531 +     */
59.12532 +    function clear(fn) {
59.12533 +        FamousEngine.removeListener(_event, fn);
59.12534 +    }
59.12535 +
59.12536 +    /**
59.12537 +     * Executes a function after a certain amount of time. Makes sure
59.12538 +     *  the function is not run multiple times.
59.12539 +     *
59.12540 +     * @method debounce
59.12541 +     *
59.12542 +     * @param {function} func function to run after certain amount of time
59.12543 +     * @param {number} wait amount of time
59.12544 +     *
59.12545 +     * @return {function} function that is not able to debounce
59.12546 +     */
59.12547 +    function debounce(func, wait) {
59.12548 +        var timeout;
59.12549 +        var ctx;
59.12550 +        var timestamp;
59.12551 +        var result;
59.12552 +        var args;
59.12553 +        return function() {
59.12554 +            ctx = this;
59.12555 +            args = arguments;
59.12556 +            timestamp = getTime();
59.12557 +
59.12558 +            var fn = function() {
59.12559 +                var last = getTime - timestamp;
59.12560 +
59.12561 +                if (last < wait) {
59.12562 +                    timeout = setTimeout(fn, wait - last);
59.12563 +                } else {
59.12564 +                    timeout = null;
59.12565 +                    result = func.apply(ctx, args);
59.12566 +                }
59.12567 +            };
59.12568 +
59.12569 +            clear(timeout);
59.12570 +            timeout = setTimeout(fn, wait);
59.12571 +
59.12572 +            return result;
59.12573 +        };
59.12574 +    }
59.12575 +
59.12576 +    module.exports = {
59.12577 +        setTimeout : setTimeout,
59.12578 +        setInterval : setInterval,
59.12579 +        debounce : debounce,
59.12580 +        after : after,
59.12581 +        every : every,
59.12582 +        clear : clear
59.12583 +    };
59.12584 +
59.12585 +});
59.12586 +
59.12587 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12588 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12589 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12590 + *
59.12591 + * Owner: mike@famo.us
59.12592 + * @license MPL 2.0
59.12593 + * @copyright Famous Industries, Inc. 2014
59.12594 + */
59.12595 +
59.12596 +define('famous/views/ContextualView',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/EventHandler','famous/core/OptionsManager'],function(require, exports, module) {
59.12597 +    var Entity = require('famous/core/Entity');
59.12598 +    var Transform = require('famous/core/Transform');
59.12599 +    var EventHandler = require('famous/core/EventHandler');
59.12600 +    var OptionsManager = require('famous/core/OptionsManager');
59.12601 +
59.12602 +    /**
59.12603 +     * ContextualView is an interface for creating views that need to
59.12604 +     *   be aware of their parent's transform, size, and/or origin.
59.12605 +     *   Consists of a OptionsManager paired with an input EventHandler
59.12606 +     *   and an output EventHandler. Meant to be extended by the developer.
59.12607 +     * @class ContextualView
59.12608 +     * @constructor
59.12609 +     * @param {Options} [options] An object of configurable options.
59.12610 +     */
59.12611 +    function ContextualView(options) {
59.12612 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS || ContextualView.DEFAULT_OPTIONS);
59.12613 +        this._optionsManager = new OptionsManager(this.options);
59.12614 +        if (options) this.setOptions(options);
59.12615 +
59.12616 +        this._eventInput = new EventHandler();
59.12617 +        this._eventOutput = new EventHandler();
59.12618 +        EventHandler.setInputHandler(this, this._eventInput);
59.12619 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.12620 +
59.12621 +        this._id = Entity.register(this);
59.12622 +    }
59.12623 +
59.12624 +    ContextualView.DEFAULT_OPTIONS = {};
59.12625 +
59.12626 +    /**
59.12627 +     * Patches the ContextualLayout instance's options with the passed-in ones.
59.12628 +     *
59.12629 +     * @method setOptions
59.12630 +     * @param {Options} options An object of configurable options for the ContextualLayout instance.
59.12631 +     */
59.12632 +    ContextualView.prototype.setOptions = function setOptions(options) {
59.12633 +        return this._optionsManager.setOptions(options);
59.12634 +    };
59.12635 +
59.12636 +    /**
59.12637 +     * Returns ContextualLayout instance's options.
59.12638 +     *
59.12639 +     * @method setOptions
59.12640 +     * @return {Options} options The instance's object of configurable options.
59.12641 +     */
59.12642 +    ContextualView.prototype.getOptions = function getOptions() {
59.12643 +        return this._optionsManager.getOptions();
59.12644 +    };
59.12645 +
59.12646 +    /**
59.12647 +     * Return the registers Entity id for the ContextualView.
59.12648 +     *
59.12649 +     * @private
59.12650 +     * @method render
59.12651 +     * @return {Number} Registered Entity id
59.12652 +     */
59.12653 +    ContextualView.prototype.render = function render() {
59.12654 +        return this._id;
59.12655 +    };
59.12656 +
59.12657 +    /**
59.12658 +     * Apply changes from this component to the corresponding document element.
59.12659 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.12660 +     * and matrix transforms.
59.12661 +     *
59.12662 +     * @private
59.12663 +     * @method commit
59.12664 +     * @param {Context} context commit context
59.12665 +     */
59.12666 +    ContextualView.prototype.commit = function commit(context) {};
59.12667 +
59.12668 +    module.exports = ContextualView;
59.12669 +});
59.12670 +
59.12671 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12672 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12673 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12674 + *
59.12675 + * Owner: felix@famo.us
59.12676 + * @license MPL 2.0
59.12677 + * @copyright Famous Industries, Inc. 2014
59.12678 + */
59.12679 +
59.12680 +define('famous/views/SequentialLayout',['require','exports','module','famous/core/OptionsManager','famous/core/Transform','famous/core/ViewSequence','famous/utilities/Utility'],function(require, exports, module) {
59.12681 +    var OptionsManager = require('famous/core/OptionsManager');
59.12682 +    var Transform = require('famous/core/Transform');
59.12683 +    var ViewSequence = require('famous/core/ViewSequence');
59.12684 +    var Utility = require('famous/utilities/Utility');
59.12685 +
59.12686 +    /**
59.12687 +     * SequentialLayout will lay out a collection of renderables sequentially in the specified direction.
59.12688 +     * @class SequentialLayout
59.12689 +     * @constructor
59.12690 +     * @param {Options} [options] An object of configurable options.
59.12691 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
59.12692 +     * module, this option will lay out the SequentialLayout instance's renderables either horizontally
59.12693 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
59.12694 +     * to just use integers as well.
59.12695 +     * @param {Array.Number} [options.defaultItemSize=[50, 50]] In the case where a renderable layed out
59.12696 +     * under SequentialLayout's control doesen't have a getSize method, SequentialLayout will assign it
59.12697 +     * this default size. (Commonly a case with Views).
59.12698 +     */
59.12699 +    function SequentialLayout(options) {
59.12700 +        this._items = null;
59.12701 +        this._size = null;
59.12702 +        this._outputFunction = SequentialLayout.DEFAULT_OUTPUT_FUNCTION;
59.12703 +
59.12704 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
59.12705 +        this.optionsManager = new OptionsManager(this.options);
59.12706 +
59.12707 +        this._itemsCache = [];
59.12708 +        this._outputCache = {
59.12709 +            size: null,
59.12710 +            target: this._itemsCache
59.12711 +        };
59.12712 +
59.12713 +        if (options) this.setOptions(options);
59.12714 +    }
59.12715 +
59.12716 +    SequentialLayout.DEFAULT_OPTIONS = {
59.12717 +        direction: Utility.Direction.Y,
59.12718 +        itemSpacing: 0,
59.12719 +        defaultItemSize: [50, 50]
59.12720 +    };
59.12721 +
59.12722 +    SequentialLayout.DEFAULT_OUTPUT_FUNCTION = function DEFAULT_OUTPUT_FUNCTION(input, offset, index) {
59.12723 +        var transform = (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset);
59.12724 +        return {
59.12725 +            transform: transform,
59.12726 +            target: input.render()
59.12727 +        };
59.12728 +    };
59.12729 +
59.12730 +    /**
59.12731 +     * Returns the width and the height of the SequentialLayout instance.
59.12732 +     *
59.12733 +     * @method getSize
59.12734 +     * @return {Array} A two value array of the SequentialLayout instance's current width and height (in that order).
59.12735 +     */
59.12736 +    SequentialLayout.prototype.getSize = function getSize() {
59.12737 +        if (!this._size) this.render(); // hack size in
59.12738 +        return this._size;
59.12739 +    };
59.12740 +
59.12741 +    /**
59.12742 +     * Sets the collection of renderables under the SequentialLayout instance's control.
59.12743 +     *
59.12744 +     * @method sequenceFrom
59.12745 +     * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence.
59.12746 +     * @chainable
59.12747 +     */
59.12748 +    SequentialLayout.prototype.sequenceFrom = function sequenceFrom(items) {
59.12749 +        if (items instanceof Array) items = new ViewSequence(items);
59.12750 +        this._items = items;
59.12751 +        return this;
59.12752 +    };
59.12753 +
59.12754 +    /**
59.12755 +     * Patches the SequentialLayout instance's options with the passed-in ones.
59.12756 +     *
59.12757 +     * @method setOptions
59.12758 +     * @param {Options} options An object of configurable options for the SequentialLayout instance.
59.12759 +     * @chainable
59.12760 +     */
59.12761 +    SequentialLayout.prototype.setOptions = function setOptions(options) {
59.12762 +        this.optionsManager.setOptions.apply(this.optionsManager, arguments);
59.12763 +        return this;
59.12764 +    };
59.12765 +
59.12766 +    /**
59.12767 +     * setOutputFunction is used to apply a user-defined output transform on each processed renderable.
59.12768 +     *  For a good example, check out SequentialLayout's own DEFAULT_OUTPUT_FUNCTION in the code.
59.12769 +     *
59.12770 +     * @method setOutputFunction
59.12771 +     * @param {Function} outputFunction An output processer for each renderable in the SequentialLayout
59.12772 +     * instance.
59.12773 +     * @chainable
59.12774 +     */
59.12775 +    SequentialLayout.prototype.setOutputFunction = function setOutputFunction(outputFunction) {
59.12776 +        this._outputFunction = outputFunction;
59.12777 +        return this;
59.12778 +    };
59.12779 +
59.12780 +    /**
59.12781 +     * Generate a render spec from the contents of this component.
59.12782 +     *
59.12783 +     * @private
59.12784 +     * @method render
59.12785 +     * @return {number} Render spec for this component
59.12786 +     */
59.12787 +    SequentialLayout.prototype.render = function render() {
59.12788 +        var length = 0;
59.12789 +        var girth = 0;
59.12790 +
59.12791 +        var lengthDim = (this.options.direction === Utility.Direction.X) ? 0 : 1;
59.12792 +        var girthDim = (this.options.direction === Utility.Direction.X) ? 1 : 0;
59.12793 +
59.12794 +        var currentNode = this._items;
59.12795 +        var result = this._itemsCache;
59.12796 +        var i = 0;
59.12797 +        while (currentNode) {
59.12798 +            var item = currentNode.get();
59.12799 +            if (!item) break;
59.12800 +
59.12801 +            var itemSize;
59.12802 +            if (item && item.getSize) itemSize = item.getSize();
59.12803 +            if (!itemSize) itemSize = this.options.defaultItemSize;
59.12804 +            if (itemSize[girthDim] !== true) girth = Math.max(girth, itemSize[girthDim]);
59.12805 +
59.12806 +            var output = this._outputFunction.call(this, item, length, i);
59.12807 +            result[i] = output;
59.12808 +
59.12809 +            if (itemSize[lengthDim] && (itemSize[lengthDim] !== true)) length += itemSize[lengthDim] + this.options.itemSpacing;
59.12810 +            currentNode = currentNode.getNext();
59.12811 +            i++;
59.12812 +        }
59.12813 +        this._itemsCache.splice(i);
59.12814 +
59.12815 +        if (!girth) girth = undefined;
59.12816 +
59.12817 +        if (!this._size) this._size = [0, 0];
59.12818 +        this._size[lengthDim] = length - this.options.itemSpacing; // account for last itemSpacing
59.12819 +        this._size[girthDim] = girth;
59.12820 +
59.12821 +        this._outputCache.size = this.getSize();
59.12822 +        return this._outputCache;
59.12823 +    };
59.12824 +
59.12825 +    module.exports = SequentialLayout;
59.12826 +});
59.12827 +
59.12828 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12829 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12830 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12831 + *
59.12832 + * Owner: felix@famo.us
59.12833 + * @license MPL 2.0
59.12834 + * @copyright Famous Industries, Inc. 2014
59.12835 + */
59.12836 +
59.12837 +define('famous/views/Deck',['require','exports','module','famous/core/Transform','famous/core/OptionsManager','famous/transitions/Transitionable','famous/utilities/Utility','./SequentialLayout'],function(require, exports, module) {
59.12838 +    var Transform = require('famous/core/Transform');
59.12839 +    var OptionsManager = require('famous/core/OptionsManager');
59.12840 +    var Transitionable = require('famous/transitions/Transitionable');
59.12841 +    var Utility = require('famous/utilities/Utility');
59.12842 +    var SequentialLayout = require('./SequentialLayout');
59.12843 +
59.12844 +    /**
59.12845 +     * A Sequential Layout that can be opened and closed with animations.
59.12846 +     *
59.12847 +     *   Takes the same options as SequentialLayout
59.12848 +     *   as well as options for the open/close transition
59.12849 +     *   and the rotation you want your Deck instance to layout in.
59.12850 +     *
59.12851 +     * @class Deck
59.12852 +     * @constructor
59.12853 +     * @extends SequentialLayout
59.12854 +     *
59.12855 +     * @param {Options} [options] An object of configurable options
59.12856 +     * @param {Transition} [options.transition={duration: 500, curve: 'easeOutBounce'}
59.12857 +     *   The transition that executes upon opening or closing your deck instance.
59.12858 +     * @param {Number} [stackRotation=0] The amount of rotation applied to the propogation
59.12859 +     *   of the Deck instance's stack of renderables.
59.12860 +     * @param {Object} [options.transition] A transition object for changing between states.
59.12861 +     * @param {Number} [options.direction] axis of expansion (Utility.Direction.X or .Y)
59.12862 +     */
59.12863 +    function Deck(options) {
59.12864 +        SequentialLayout.apply(this, arguments);
59.12865 +        this.state = new Transitionable(0);
59.12866 +        this._isOpen = false;
59.12867 +
59.12868 +        this.setOutputFunction(function(input, offset, index) {
59.12869 +            var state = _getState.call(this);
59.12870 +            var positionMatrix = (this.options.direction === Utility.Direction.X) ?
59.12871 +                Transform.translate(state * offset, 0, 0.001 * (state - 1) * offset) :
59.12872 +                Transform.translate(0, state * offset, 0.001 * (state - 1) * offset);
59.12873 +            var output = input.render();
59.12874 +            if (this.options.stackRotation) {
59.12875 +                var amount = this.options.stackRotation * index * (1 - state);
59.12876 +                output = {
59.12877 +                    transform: Transform.rotateZ(amount),
59.12878 +                    origin: [0.5, 0.5],
59.12879 +                    target: output
59.12880 +                };
59.12881 +            }
59.12882 +            return {
59.12883 +                transform: positionMatrix,
59.12884 +                size: input.getSize(),
59.12885 +                target: output
59.12886 +            };
59.12887 +        });
59.12888 +    }
59.12889 +    Deck.prototype = Object.create(SequentialLayout.prototype);
59.12890 +    Deck.prototype.constructor = Deck;
59.12891 +
59.12892 +    Deck.DEFAULT_OPTIONS = OptionsManager.patch(SequentialLayout.DEFAULT_OPTIONS, {
59.12893 +        transition: {
59.12894 +            curve: 'easeOutBounce',
59.12895 +            duration: 500
59.12896 +        },
59.12897 +        stackRotation: 0
59.12898 +    });
59.12899 +
59.12900 +    /**
59.12901 +     * Returns the width and the height of the Deck instance.
59.12902 +     *
59.12903 +     * @method getSize
59.12904 +     * @return {Array} A two value array of Deck's current width and height (in that order).
59.12905 +     *   Scales as Deck opens and closes.
59.12906 +     */
59.12907 +    Deck.prototype.getSize = function getSize() {
59.12908 +        var originalSize = SequentialLayout.prototype.getSize.apply(this, arguments);
59.12909 +        var firstSize = this._items ? this._items.get().getSize() : [0, 0];
59.12910 +        if (!firstSize) firstSize = [0, 0];
59.12911 +        var state = _getState.call(this);
59.12912 +        var invState = 1 - state;
59.12913 +        return [firstSize[0] * invState + originalSize[0] * state, firstSize[1] * invState + originalSize[1] * state];
59.12914 +    };
59.12915 +
59.12916 +    function _getState(returnFinal) {
59.12917 +        if (returnFinal) return this._isOpen ? 1 : 0;
59.12918 +        else return this.state.get();
59.12919 +    }
59.12920 +
59.12921 +    function _setState(pos, transition, callback) {
59.12922 +        this.state.halt();
59.12923 +        this.state.set(pos, transition, callback);
59.12924 +    }
59.12925 +
59.12926 +    /**
59.12927 +     * An accesor method to find out if the messaged Deck instance is open or closed.
59.12928 +     *
59.12929 +     * @method isOpen
59.12930 +     * @return {Boolean} Returns true if the instance is open or false if it's closed.
59.12931 +     */
59.12932 +    Deck.prototype.isOpen = function isOpen() {
59.12933 +        return this._isOpen;
59.12934 +    };
59.12935 +
59.12936 +    /**
59.12937 +     * Sets the Deck instance to an open state.
59.12938 +     *
59.12939 +     * @method open
59.12940 +     * @param {function} [callback] Executes after transitioning to a fully open state.
59.12941 +     */
59.12942 +    Deck.prototype.open = function open(callback) {
59.12943 +        this._isOpen = true;
59.12944 +       _setState.call(this, 1, this.options.transition, callback);
59.12945 +    };
59.12946 +
59.12947 +    /**
59.12948 +     * Sets the Deck instance to an open state.
59.12949 +     *
59.12950 +     * @method close
59.12951 +     * @param {function} [callback] Executes after transitioning to a fully closed state.
59.12952 +     */
59.12953 +    Deck.prototype.close = function close(callback) {
59.12954 +        this._isOpen = false;
59.12955 +        _setState.call(this, 0, this.options.transition, callback);
59.12956 +    };
59.12957 +
59.12958 +    /**
59.12959 +     * Sets the Deck instance from its current state to the opposite state.
59.12960 +     *
59.12961 +     * @method close
59.12962 +     * @param {function} [callback] Executes after transitioning to the toggled state.
59.12963 +     */
59.12964 +    Deck.prototype.toggle = function toggle(callback) {
59.12965 +        if (this._isOpen) this.close(callback);
59.12966 +        else this.open(callback);
59.12967 +    };
59.12968 +
59.12969 +    module.exports = Deck;
59.12970 +});
59.12971 +
59.12972 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.12973 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.12974 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.12975 + *
59.12976 + * Owner: felix@famo.us
59.12977 + * @license MPL 2.0
59.12978 + * @copyright Famous Industries, Inc. 2014
59.12979 + */
59.12980 +
59.12981 +define('famous/views/RenderController',['require','exports','module','famous/core/Modifier','famous/core/RenderNode','famous/core/Transform','famous/transitions/Transitionable','famous/core/View'],function(require, exports, module) {
59.12982 +    var Modifier = require('famous/core/Modifier');
59.12983 +    var RenderNode = require('famous/core/RenderNode');
59.12984 +    var Transform = require('famous/core/Transform');
59.12985 +    var Transitionable = require('famous/transitions/Transitionable');
59.12986 +    var View = require('famous/core/View');
59.12987 +
59.12988 +    /**
59.12989 +     * A dynamic view that can show or hide different renerables with transitions.
59.12990 +     * @class RenderController
59.12991 +     * @constructor
59.12992 +     * @param {Options} [options] An object of configurable options.
59.12993 +     * @param {Transition} [inTransition=true] The transition in charge of showing a renderable.
59.12994 +     * @param {Transition} [outTransition=true]  The transition in charge of removing your previous renderable when
59.12995 +     * you show a new one, or hiding your current renderable.
59.12996 +     * @param {Boolean} [overlap=true] When showing a new renderable, overlap determines if the
59.12997 +      out transition of the old one executes concurrently with the in transition of the new one,
59.12998 +       or synchronously beforehand.
59.12999 +     */
59.13000 +    function RenderController(options) {
59.13001 +        View.apply(this, arguments);
59.13002 +
59.13003 +        this._showing = -1;
59.13004 +        this._outgoingRenderables = [];
59.13005 +        this._nextRenderable = null;
59.13006 +
59.13007 +        this._renderables = [];
59.13008 +        this._nodes = [];
59.13009 +        this._modifiers = [];
59.13010 +        this._states = [];
59.13011 +
59.13012 +        this.inTransformMap = RenderController.DefaultMap.transform;
59.13013 +        this.inOpacityMap = RenderController.DefaultMap.opacity;
59.13014 +        this.inOriginMap = RenderController.DefaultMap.origin;
59.13015 +        this.outTransformMap = RenderController.DefaultMap.transform;
59.13016 +        this.outOpacityMap = RenderController.DefaultMap.opacity;
59.13017 +        this.outOriginMap = RenderController.DefaultMap.origin;
59.13018 +
59.13019 +        this._output = [];
59.13020 +    }
59.13021 +    RenderController.prototype = Object.create(View.prototype);
59.13022 +    RenderController.prototype.constructor = RenderController;
59.13023 +
59.13024 +    RenderController.DEFAULT_OPTIONS = {
59.13025 +        inTransition: true,
59.13026 +        outTransition: true,
59.13027 +        overlap: true
59.13028 +    };
59.13029 +
59.13030 +    RenderController.DefaultMap = {
59.13031 +        transform: function() {
59.13032 +            return Transform.identity;
59.13033 +        },
59.13034 +        opacity: function(progress) {
59.13035 +            return progress;
59.13036 +        },
59.13037 +        origin: null
59.13038 +    };
59.13039 +
59.13040 +    function _mappedState(map, state) {
59.13041 +        return map(state.get());
59.13042 +    }
59.13043 +
59.13044 +    /**
59.13045 +     * As your RenderController shows a new renderable, it executes a transition in. This transition in
59.13046 +     *  will affect a default interior state and modify it as you bring renderables in and out. However, if you want to control
59.13047 +     *  the transform, opacity, and origin state yourself, you may call certain methods (such as inTransformFrom) to obtain state from an outside source,
59.13048 +     *  that may either be a function or a Famous transitionable. inTransformFrom sets the accessor for the state of
59.13049 +     *  the transform used in transitioning in renderables.
59.13050 +     *
59.13051 +     * @method inTransformFrom
59.13052 +     * @param {Function|Transitionable} transform  A function that returns a transform from outside closure, or a
59.13053 +     * a transitionable that manages a full transform (a sixteen value array).
59.13054 +     * @chainable
59.13055 +     */
59.13056 +    RenderController.prototype.inTransformFrom = function inTransformFrom(transform) {
59.13057 +        if (transform instanceof Function) this.inTransformMap = transform;
59.13058 +        else if (transform && transform.get) this.inTransformMap = transform.get.bind(transform);
59.13059 +        else throw new Error('inTransformFrom takes only function or getter object');
59.13060 +        //TODO: tween transition
59.13061 +        return this;
59.13062 +    };
59.13063 +
59.13064 +    /**
59.13065 +     * inOpacityFrom sets the accessor for the state of the opacity used in transitioning in renderables.
59.13066 +     * @method inOpacityFrom
59.13067 +     * @param {Function|Transitionable} opacity  A function that returns an opacity from outside closure, or a
59.13068 +     * a transitionable that manages opacity (a number between zero and one).
59.13069 +     * @chainable
59.13070 +     */
59.13071 +    RenderController.prototype.inOpacityFrom = function inOpacityFrom(opacity) {
59.13072 +        if (opacity instanceof Function) this.inOpacityMap = opacity;
59.13073 +        else if (opacity && opacity.get) this.inOpacityMap = opacity.get.bind(opacity);
59.13074 +        else throw new Error('inOpacityFrom takes only function or getter object');
59.13075 +        //TODO: tween opacity
59.13076 +        return this;
59.13077 +    };
59.13078 +
59.13079 +    /**
59.13080 +     * inOriginFrom sets the accessor for the state of the origin used in transitioning in renderables.
59.13081 +     * @method inOriginFrom
59.13082 +     * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a
59.13083 +     * a transitionable that manages origin (a two value array of numbers between zero and one).
59.13084 +     * @chainable
59.13085 +     */
59.13086 +    RenderController.prototype.inOriginFrom = function inOriginFrom(origin) {
59.13087 +        if (origin instanceof Function) this.inOriginMap = origin;
59.13088 +        else if (origin && origin.get) this.inOriginMap = origin.get.bind(origin);
59.13089 +        else throw new Error('inOriginFrom takes only function or getter object');
59.13090 +        //TODO: tween origin
59.13091 +        return this;
59.13092 +    };
59.13093 +
59.13094 +    /**
59.13095 +     * outTransformFrom sets the accessor for the state of the transform used in transitioning out renderables.
59.13096 +     * @method show
59.13097 +     * @param {Function|Transitionable} transform  A function that returns a transform from outside closure, or a
59.13098 +     * a transitionable that manages a full transform (a sixteen value array).
59.13099 +     * @chainable
59.13100 +     */
59.13101 +    RenderController.prototype.outTransformFrom = function outTransformFrom(transform) {
59.13102 +        if (transform instanceof Function) this.outTransformMap = transform;
59.13103 +        else if (transform && transform.get) this.outTransformMap = transform.get.bind(transform);
59.13104 +        else throw new Error('inTransformFrom takes only function or getter object');
59.13105 +        //TODO: tween transition
59.13106 +        return this;
59.13107 +    };
59.13108 +
59.13109 +    /**
59.13110 +     * outOpacityFrom sets the accessor for the state of the opacity used in transitioning out renderables.
59.13111 +     * @method inOpacityFrom
59.13112 +     * @param {Function|Transitionable} opacity  A function that returns an opacity from outside closure, or a
59.13113 +     * a transitionable that manages opacity (a number between zero and one).
59.13114 +     * @chainable
59.13115 +     */
59.13116 +    RenderController.prototype.outOpacityFrom = function outOpacityFrom(opacity) {
59.13117 +        if (opacity instanceof Function) this.outOpacityMap = opacity;
59.13118 +        else if (opacity && opacity.get) this.outOpacityMap = opacity.get.bind(opacity);
59.13119 +        else throw new Error('inOpacityFrom takes only function or getter object');
59.13120 +        //TODO: tween opacity
59.13121 +        return this;
59.13122 +    };
59.13123 +
59.13124 +    /**
59.13125 +     * outOriginFrom sets the accessor for the state of the origin used in transitioning out renderables.
59.13126 +     * @method inOriginFrom
59.13127 +     * @param {Function|Transitionable} origin A function that returns an origin from outside closure, or a
59.13128 +     * a transitionable that manages origin (a two value array of numbers between zero and one).
59.13129 +     * @chainable
59.13130 +     */
59.13131 +    RenderController.prototype.outOriginFrom = function outOriginFrom(origin) {
59.13132 +        if (origin instanceof Function) this.outOriginMap = origin;
59.13133 +        else if (origin && origin.get) this.outOriginMap = origin.get.bind(origin);
59.13134 +        else throw new Error('inOriginFrom takes only function or getter object');
59.13135 +        //TODO: tween origin
59.13136 +        return this;
59.13137 +    };
59.13138 +
59.13139 +    /**
59.13140 +     * Show displays the targeted renderable with a transition and an optional callback to
59.13141 +     * execute afterwards.
59.13142 +     * @method show
59.13143 +     * @param {Object} renderable The renderable you want to show.
59.13144 +     * @param {Transition} [transition] Overwrites the default transition in to display the
59.13145 +     * passed-in renderable.
59.13146 +     * @param {function} [callback] Executes after transitioning in the renderable.
59.13147 +     * @chainable
59.13148 +     */
59.13149 +    RenderController.prototype.show = function show(renderable, transition, callback) {
59.13150 +        if (!renderable) {
59.13151 +            return this.hide(callback);
59.13152 +        }
59.13153 +
59.13154 +        if (transition instanceof Function) {
59.13155 +            callback = transition;
59.13156 +            transition = null;
59.13157 +        }
59.13158 +
59.13159 +        if (this._showing >= 0) {
59.13160 +            if (this.options.overlap) this.hide();
59.13161 +            else {
59.13162 +                if (this._nextRenderable) {
59.13163 +                    this._nextRenderable = renderable;
59.13164 +                }
59.13165 +                else {
59.13166 +                    this._nextRenderable = renderable;
59.13167 +                    this.hide(function() {
59.13168 +                        if (this._nextRenderable === renderable) this.show(this._nextRenderable, callback);
59.13169 +                        this._nextRenderable = null;
59.13170 +                    });
59.13171 +                }
59.13172 +                return undefined;
59.13173 +            }
59.13174 +        }
59.13175 +
59.13176 +        var state = null;
59.13177 +
59.13178 +        // check to see if we should restore
59.13179 +        var renderableIndex = this._renderables.indexOf(renderable);
59.13180 +        if (renderableIndex >= 0) {
59.13181 +            this._showing = renderableIndex;
59.13182 +            state = this._states[renderableIndex];
59.13183 +            state.halt();
59.13184 +
59.13185 +            var outgoingIndex = this._outgoingRenderables.indexOf(renderable);
59.13186 +            if (outgoingIndex >= 0) this._outgoingRenderables.splice(outgoingIndex, 1);
59.13187 +        }
59.13188 +        else {
59.13189 +            state = new Transitionable(0);
59.13190 +
59.13191 +            var modifier = new Modifier({
59.13192 +                transform: this.inTransformMap ? _mappedState.bind(this, this.inTransformMap, state) : null,
59.13193 +                opacity: this.inOpacityMap ? _mappedState.bind(this, this.inOpacityMap, state) : null,
59.13194 +                origin: this.inOriginMap ? _mappedState.bind(this, this.inOriginMap, state) : null
59.13195 +            });
59.13196 +            var node = new RenderNode();
59.13197 +            node.add(modifier).add(renderable);
59.13198 +
59.13199 +            this._showing = this._nodes.length;
59.13200 +            this._nodes.push(node);
59.13201 +            this._modifiers.push(modifier);
59.13202 +            this._states.push(state);
59.13203 +            this._renderables.push(renderable);
59.13204 +        }
59.13205 +
59.13206 +        if (!transition) transition = this.options.inTransition;
59.13207 +        state.set(1, transition, callback);
59.13208 +    };
59.13209 +
59.13210 +    /**
59.13211 +     * Hide hides the currently displayed renderable with an out transition.
59.13212 +     * @method hide
59.13213 +     * @param {Transition} [transition] Overwrites the default transition in to hide the
59.13214 +     * currently controlled renderable.
59.13215 +     * @param {function} [callback] Executes after transitioning out the renderable.
59.13216 +     * @chainable
59.13217 +     */
59.13218 +    RenderController.prototype.hide = function hide(transition, callback) {
59.13219 +        if (this._showing < 0) return;
59.13220 +        var index = this._showing;
59.13221 +        this._showing = -1;
59.13222 +
59.13223 +        if (transition instanceof Function) {
59.13224 +            callback = transition;
59.13225 +            transition = undefined;
59.13226 +        }
59.13227 +
59.13228 +        var node = this._nodes[index];
59.13229 +        var modifier = this._modifiers[index];
59.13230 +        var state = this._states[index];
59.13231 +        var renderable = this._renderables[index];
59.13232 +
59.13233 +        modifier.transformFrom(this.outTransformMap ? _mappedState.bind(this, this.outTransformMap, state) : null);
59.13234 +        modifier.opacityFrom(this.outOpacityMap ? _mappedState.bind(this, this.outOpacityMap, state) : null);
59.13235 +        modifier.originFrom(this.outOriginMap ? _mappedState.bind(this, this.outOriginMap, state) : null);
59.13236 +
59.13237 +        if (this._outgoingRenderables.indexOf(renderable) < 0) this._outgoingRenderables.push(renderable);
59.13238 +
59.13239 +        if (!transition) transition = this.options.outTransition;
59.13240 +        state.halt();
59.13241 +        state.set(0, transition, function(node, modifier, state, renderable) {
59.13242 +            if (this._outgoingRenderables.indexOf(renderable) >= 0) {
59.13243 +                var index = this._nodes.indexOf(node);
59.13244 +                this._nodes.splice(index, 1);
59.13245 +                this._modifiers.splice(index, 1);
59.13246 +                this._states.splice(index, 1);
59.13247 +                this._renderables.splice(index, 1);
59.13248 +                this._outgoingRenderables.splice(this._outgoingRenderables.indexOf(renderable), 1);
59.13249 +
59.13250 +                if (this._showing >= index) this._showing--;
59.13251 +            }
59.13252 +            if (callback) callback.call(this);
59.13253 +        }.bind(this, node, modifier, state, renderable));
59.13254 +    };
59.13255 +
59.13256 +    /**
59.13257 +     * Generate a render spec from the contents of this component.
59.13258 +     *
59.13259 +     * @private
59.13260 +     * @method render
59.13261 +     * @return {number} Render spec for this component
59.13262 +     */
59.13263 +    RenderController.prototype.render = function render() {
59.13264 +        var result = this._output;
59.13265 +        if (result.length > this._nodes.length) result.splice(this._nodes.length);
59.13266 +        for (var i = 0; i < this._nodes.length; i++) {
59.13267 +            result[i] = this._nodes[i].render();
59.13268 +        }
59.13269 +        return result;
59.13270 +    };
59.13271 +
59.13272 +    module.exports = RenderController;
59.13273 +});
59.13274 +
59.13275 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.13276 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.13277 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.13278 + *
59.13279 + * Owner: felix@famo.us
59.13280 + * @license MPL 2.0
59.13281 + * @copyright Famous Industries, Inc. 2014
59.13282 + */
59.13283 +
59.13284 +define('famous/views/EdgeSwapper',['require','exports','module','famous/transitions/CachedMap','famous/core/Entity','famous/core/EventHandler','famous/core/Transform','./RenderController'],function(require, exports, module) {
59.13285 +    var CachedMap = require('famous/transitions/CachedMap');
59.13286 +    var Entity = require('famous/core/Entity');
59.13287 +    var EventHandler = require('famous/core/EventHandler');
59.13288 +    var Transform = require('famous/core/Transform');
59.13289 +    var RenderController = require('./RenderController');
59.13290 +
59.13291 +    /**
59.13292 +     * Container which handles swapping renderables from the edge of its parent context.
59.13293 +     * @class EdgeSwapper
59.13294 +     * @constructor
59.13295 +     * @param {Options} [options] An object of configurable options.
59.13296 +     *   Takes the same options as RenderController.
59.13297 +     * @uses RenderController
59.13298 +     */
59.13299 +    function EdgeSwapper(options) {
59.13300 +        this._currentTarget = null;
59.13301 +        this._size = [undefined, undefined];
59.13302 +
59.13303 +        this._controller = new RenderController(options);
59.13304 +        this._controller.inTransformFrom(CachedMap.create(_transformMap.bind(this, 0.0001)));
59.13305 +        this._controller.outTransformFrom(CachedMap.create(_transformMap.bind(this, -0.0001)));
59.13306 +
59.13307 +        this._eventInput = new EventHandler();
59.13308 +        EventHandler.setInputHandler(this, this._eventInput);
59.13309 +
59.13310 +        this._entityId = Entity.register(this);
59.13311 +        if (options) this.setOptions(options);
59.13312 +    }
59.13313 +
59.13314 +    function _transformMap(zMax, progress) {
59.13315 +        return Transform.translate(this._size[0] * (1 - progress), 0, zMax * (1 - progress));
59.13316 +    }
59.13317 +
59.13318 +    /**
59.13319 +     * Displays the passed-in content with the EdgeSwapper instance's default transition.
59.13320 +     *
59.13321 +     * @method show
59.13322 +     * @param {Object} content The renderable you want to display.
59.13323 +     */
59.13324 +    EdgeSwapper.prototype.show = function show(content) {
59.13325 +        // stop sending input to old target
59.13326 +        if (this._currentTarget) this._eventInput.unpipe(this._currentTarget);
59.13327 +
59.13328 +        this._currentTarget = content;
59.13329 +
59.13330 +        // start sending input to new target
59.13331 +        if (this._currentTarget && this._currentTarget.trigger) this._eventInput.pipe(this._currentTarget);
59.13332 +
59.13333 +        this._controller.show.apply(this._controller, arguments);
59.13334 +    };
59.13335 +
59.13336 +    /**
59.13337 +     * Patches the EdgeSwapper instance's options with the passed-in ones.
59.13338 +     *
59.13339 +     * @method setOptions
59.13340 +     * @param {Options} options An object of configurable options for the Edgeswapper instance.
59.13341 +     */
59.13342 +    EdgeSwapper.prototype.setOptions = function setOptions(options) {
59.13343 +        this._controller.setOptions(options);
59.13344 +    };
59.13345 +
59.13346 +    /**
59.13347 +     * Generate a render spec from the contents of this component.
59.13348 +     *
59.13349 +     * @private
59.13350 +     * @method render
59.13351 +     * @return {number} Render spec for this component
59.13352 +     */
59.13353 +    EdgeSwapper.prototype.render = function render() {
59.13354 +        return this._entityId;
59.13355 +    };
59.13356 +
59.13357 +    /**
59.13358 +     * Apply changes from this component to the corresponding document element.
59.13359 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.13360 +     * and matrix transforms.
59.13361 +     *
59.13362 +     * @private
59.13363 +     * @method commit
59.13364 +     * @param {Context} context commit context
59.13365 +     */
59.13366 +    EdgeSwapper.prototype.commit = function commit(context) {
59.13367 +        this._size[0] = context.size[0];
59.13368 +        this._size[1] = context.size[1];
59.13369 +
59.13370 +        return {
59.13371 +            transform: context.transform,
59.13372 +            opacity: context.opacity,
59.13373 +            origin: context.origin,
59.13374 +            size: context.size,
59.13375 +            target: this._controller.render()
59.13376 +        };
59.13377 +    };
59.13378 +
59.13379 +    module.exports = EdgeSwapper;
59.13380 +});
59.13381 +
59.13382 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.13383 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.13384 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.13385 + *
59.13386 + * Owner: mike@famo.us
59.13387 + * @license MPL 2.0
59.13388 + * @copyright Famous Industries, Inc. 2014
59.13389 + */
59.13390 +
59.13391 +define('famous/views/FlexibleLayout',['require','exports','module','famous/core/Entity','famous/core/Transform','famous/core/OptionsManager','famous/core/EventHandler','famous/transitions/Transitionable'],function(require, exports, module) {
59.13392 +    var Entity = require('famous/core/Entity');
59.13393 +    var Transform = require('famous/core/Transform');
59.13394 +    var OptionsManager = require('famous/core/OptionsManager');
59.13395 +    var EventHandler = require('famous/core/EventHandler');
59.13396 +    var Transitionable = require('famous/transitions/Transitionable');
59.13397 +
59.13398 +    /**
59.13399 +     * A layout which divides a context into sections based on a proportion
59.13400 +     *   of the total sum of ratios.  FlexibleLayout can either lay renderables
59.13401 +     *   out vertically or horizontally.
59.13402 +     * @class FlexibleLayout
59.13403 +     * @constructor
59.13404 +     * @param {Options} [options] An object of configurable options.
59.13405 +     * @param {Number} [options.direction=0] Direction the FlexibleLayout instance should lay out renderables.
59.13406 +     * @param {Transition} [options.transition=false] The transiton that controls the FlexibleLayout instance's reflow.
59.13407 +     * @param {Ratios} [options.ratios=[]] The proportions for the renderables to maintain
59.13408 +     */
59.13409 +    function FlexibleLayout(options) {
59.13410 +        this.options = Object.create(FlexibleLayout.DEFAULT_OPTIONS);
59.13411 +        this.optionsManager = new OptionsManager(this.options);
59.13412 +        if (options) this.setOptions(options);
59.13413 +
59.13414 +        this.id = Entity.register(this);
59.13415 +
59.13416 +        this._ratios = new Transitionable(this.options.ratios);
59.13417 +        this._nodes = [];
59.13418 +
59.13419 +        this._cachedDirection = null;
59.13420 +        this._cachedTotalLength = false;
59.13421 +        this._cachedLengths = [];
59.13422 +        this._cachedTransforms = null;
59.13423 +        this._ratiosDirty = false;
59.13424 +
59.13425 +        this._eventOutput = new EventHandler();
59.13426 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.13427 +    }
59.13428 +
59.13429 +    FlexibleLayout.DIRECTION_X = 0;
59.13430 +    FlexibleLayout.DIRECTION_Y = 1;
59.13431 +
59.13432 +    FlexibleLayout.DEFAULT_OPTIONS = {
59.13433 +        direction: FlexibleLayout.DIRECTION_X,
59.13434 +        transition: false,
59.13435 +        ratios : []
59.13436 +    };
59.13437 +
59.13438 +    function _reflow(ratios, length, direction) {
59.13439 +        var currTransform;
59.13440 +        var translation = 0;
59.13441 +        var flexLength = length;
59.13442 +        var ratioSum = 0;
59.13443 +        var ratio;
59.13444 +        var node;
59.13445 +        var i;
59.13446 +
59.13447 +        this._cachedLengths = [];
59.13448 +        this._cachedTransforms = [];
59.13449 +
59.13450 +        for (i = 0; i < ratios.length; i++){
59.13451 +            ratio = ratios[i];
59.13452 +            node = this._nodes[i];
59.13453 +
59.13454 +            if (typeof ratio !== 'number')
59.13455 +                flexLength -= node.getSize()[direction] || 0;
59.13456 +            else
59.13457 +                ratioSum += ratio;
59.13458 +        }
59.13459 +
59.13460 +        for (i = 0; i < ratios.length; i++) {
59.13461 +            node = this._nodes[i];
59.13462 +            ratio = ratios[i];
59.13463 +
59.13464 +            length = (typeof ratio === 'number')
59.13465 +                ? flexLength * ratio / ratioSum
59.13466 +                : node.getSize()[direction];
59.13467 +
59.13468 +            currTransform = (direction === FlexibleLayout.DIRECTION_X)
59.13469 +                ? Transform.translate(translation, 0, 0)
59.13470 +                : Transform.translate(0, translation, 0);
59.13471 +
59.13472 +            this._cachedTransforms.push(currTransform);
59.13473 +            this._cachedLengths.push(length);
59.13474 +
59.13475 +            translation += length;
59.13476 +        }
59.13477 +    }
59.13478 +
59.13479 +    /**
59.13480 +     * Generate a render spec from the contents of this component.
59.13481 +     *
59.13482 +     * @private
59.13483 +     * @method render
59.13484 +     * @return {Object} Render spec for this component
59.13485 +     */
59.13486 +    FlexibleLayout.prototype.render = function render() {
59.13487 +        return this.id;
59.13488 +    };
59.13489 +
59.13490 +    /**
59.13491 +     * Patches the FlexibleLayouts instance's options with the passed-in ones.
59.13492 +     *
59.13493 +     * @method setOptions
59.13494 +     * @param {Options} options An object of configurable options for the FlexibleLayout instance.
59.13495 +     */
59.13496 +    FlexibleLayout.prototype.setOptions = function setOptions(options) {
59.13497 +        this.optionsManager.setOptions(options);
59.13498 +    };
59.13499 +
59.13500 +    /**
59.13501 +     * Sets the collection of renderables under the FlexibleLayout instance's control.  Also sets
59.13502 +     * the associated ratio values for sizing the renderables if given.
59.13503 +     *
59.13504 +     * @method sequenceFrom
59.13505 +     * @param {Array} sequence An array of renderables.
59.13506 +     */
59.13507 +    FlexibleLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
59.13508 +        this._nodes = sequence;
59.13509 +
59.13510 +        if (this._ratios.get().length === 0) {
59.13511 +            var ratios = [];
59.13512 +            for (var i = 0; i < this._nodes.length; i++) ratios.push(1);
59.13513 +            this.setRatios(ratios);
59.13514 +        }
59.13515 +    };
59.13516 +
59.13517 +    /**
59.13518 +     * Sets the associated ratio values for sizing the renderables.
59.13519 +     *
59.13520 +     * @method setRatios
59.13521 +     * @param {Array} ratios Array of ratios corresponding to the percentage sizes each renderable should be
59.13522 +     */
59.13523 +    FlexibleLayout.prototype.setRatios = function setRatios(ratios, transition, callback) {
59.13524 +        if (transition === undefined) transition = this.options.transition;
59.13525 +        var currRatios = this._ratios;
59.13526 +        if (currRatios.get().length === 0) transition = undefined;
59.13527 +        if (currRatios.isActive()) currRatios.halt();
59.13528 +        currRatios.set(ratios, transition, callback);
59.13529 +        this._ratiosDirty = true;
59.13530 +    };
59.13531 +
59.13532 +    /**
59.13533 +     * Apply changes from this component to the corresponding document element.
59.13534 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.13535 +     * and matrix transforms.
59.13536 +     *
59.13537 +     * @private
59.13538 +     * @method commit
59.13539 +     * @param {Context} context commit context
59.13540 +     */
59.13541 +    FlexibleLayout.prototype.commit = function commit(context) {
59.13542 +        var parentSize = context.size;
59.13543 +        var parentTransform = context.transform;
59.13544 +        var parentOrigin = context.origin;
59.13545 +
59.13546 +        var ratios = this._ratios.get();
59.13547 +        var direction = this.options.direction;
59.13548 +        var length = parentSize[direction];
59.13549 +        var size;
59.13550 +
59.13551 +        if (length !== this._cachedTotalLength || this._ratiosDirty || this._ratios.isActive() || direction !== this._cachedDirection) {
59.13552 +            _reflow.call(this, ratios, length, direction);
59.13553 +
59.13554 +            if (length !== this._cachedTotalLength) this._cachedTotalLength = length;
59.13555 +            if (direction !== this._cachedDirection) this._cachedDirection = direction;
59.13556 +            if (this._ratiosDirty) this._ratiosDirty = false;
59.13557 +        }
59.13558 +
59.13559 +        var result = [];
59.13560 +        for (var i = 0; i < ratios.length; i++) {
59.13561 +            size = [undefined, undefined];
59.13562 +            length = this._cachedLengths[i];
59.13563 +            size[direction] = length;
59.13564 +            result.push({
59.13565 +                transform : this._cachedTransforms[i],
59.13566 +                size: size,
59.13567 +                target : this._nodes[i].render()
59.13568 +            });
59.13569 +        }
59.13570 +
59.13571 +        if (parentSize && (parentOrigin[0] !== 0 && parentOrigin[1] !== 0))
59.13572 +            parentTransform = Transform.moveThen([-parentSize[0]*parentOrigin[0], -parentSize[1]*parentOrigin[1], 0], parentTransform);
59.13573 +
59.13574 +        return {
59.13575 +            transform: parentTransform,
59.13576 +            size: parentSize,
59.13577 +            target: result
59.13578 +        };
59.13579 +    };
59.13580 +
59.13581 +    module.exports = FlexibleLayout;
59.13582 +});
59.13583 +
59.13584 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.13585 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.13586 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.13587 + *
59.13588 + * Owner: felix@famo.us
59.13589 + * @license MPL 2.0
59.13590 + * @copyright Famous Industries, Inc. 2014
59.13591 + */
59.13592 +
59.13593 +define('famous/views/Flipper',['require','exports','module','famous/core/Transform','famous/transitions/Transitionable','famous/core/RenderNode','famous/core/OptionsManager'],function(require, exports, module) {
59.13594 +    var Transform = require('famous/core/Transform');
59.13595 +    var Transitionable = require('famous/transitions/Transitionable');
59.13596 +    var RenderNode = require('famous/core/RenderNode');
59.13597 +    var OptionsManager = require('famous/core/OptionsManager');
59.13598 +
59.13599 +    /**
59.13600 +     * Allows you to link two renderables as front and back sides that can be
59.13601 +     *  'flipped' back and forth along a chosen axis. Rendering optimizations are
59.13602 +     *  automatically handled.
59.13603 +     *
59.13604 +     * @class Flipper
59.13605 +     * @constructor
59.13606 +     * @param {Options} [options] An object of options.
59.13607 +     * @param {Transition} [options.transition=true] The transition executed when flipping your Flipper instance.
59.13608 +     */
59.13609 +    function Flipper(options) {
59.13610 +        this.options = Object.create(Flipper.DEFAULT_OPTIONS);
59.13611 +        this._optionsManager = new OptionsManager(this.options);
59.13612 +        if (options) this.setOptions(options);
59.13613 +
59.13614 +        this.angle = new Transitionable(0);
59.13615 +
59.13616 +        this.frontNode = undefined;
59.13617 +        this.backNode = undefined;
59.13618 +
59.13619 +        this.flipped = false;
59.13620 +    }
59.13621 +
59.13622 +    Flipper.DIRECTION_X = 0;
59.13623 +    Flipper.DIRECTION_Y = 1;
59.13624 +
59.13625 +    var SEPERATION_LENGTH = 1;
59.13626 +
59.13627 +    Flipper.DEFAULT_OPTIONS = {
59.13628 +        transition: true,
59.13629 +        direction: Flipper.DIRECTION_X
59.13630 +    };
59.13631 +
59.13632 +    /**
59.13633 +     * Toggles the rotation between the front and back renderables
59.13634 +     *
59.13635 +     * @method flip
59.13636 +     * @param {Object} [transition] Transition definition
59.13637 +     * @param {Function} [callback] Callback
59.13638 +     */
59.13639 +    Flipper.prototype.flip = function flip(transition, callback) {
59.13640 +        var angle = this.flipped ? 0 : Math.PI;
59.13641 +        this.setAngle(angle, transition, callback);
59.13642 +        this.flipped = !this.flipped;
59.13643 +    };
59.13644 +
59.13645 +    /**
59.13646 +     * Basic setter to the angle
59.13647 +     *
59.13648 +     * @method setAngle
59.13649 +     * @param {Number} angle
59.13650 +     * @param {Object} [transition] Transition definition
59.13651 +     * @param {Function} [callback] Callback
59.13652 +     */
59.13653 +    Flipper.prototype.setAngle = function setAngle(angle, transition, callback) {
59.13654 +        if (transition === undefined) transition = this.options.transition;
59.13655 +        if (this.angle.isActive()) this.angle.halt();
59.13656 +        this.angle.set(angle, transition, callback);
59.13657 +    };
59.13658 +
59.13659 +    /**
59.13660 +     * Patches the Flipper instance's options with the passed-in ones.
59.13661 +     *
59.13662 +     * @method setOptions
59.13663 +     * @param {Options} options An object of configurable options for the Flipper instance.
59.13664 +     */
59.13665 +    Flipper.prototype.setOptions = function setOptions(options) {
59.13666 +        return this._optionsManager.setOptions(options);
59.13667 +    };
59.13668 +
59.13669 +    /**
59.13670 +     * Adds the passed-in renderable to the view associated with the 'front' of the Flipper instance.
59.13671 +     *
59.13672 +     * @method setFront
59.13673 +     * @chainable
59.13674 +     * @param {Object} node The renderable you want to add to the front.
59.13675 +     */
59.13676 +    Flipper.prototype.setFront = function setFront(node) {
59.13677 +        this.frontNode = node;
59.13678 +    };
59.13679 +
59.13680 +    /**
59.13681 +     * Adds the passed-in renderable to the view associated with the 'back' of the Flipper instance.
59.13682 +     *
59.13683 +     * @method setBack
59.13684 +     * @chainable
59.13685 +     * @param {Object} node The renderable you want to add to the back.
59.13686 +     */
59.13687 +    Flipper.prototype.setBack = function setBack(node) {
59.13688 +        this.backNode = node;
59.13689 +    };
59.13690 +
59.13691 +    /**
59.13692 +     * Generate a render spec from the contents of this component.
59.13693 +     *
59.13694 +     * @private
59.13695 +     * @method render
59.13696 +     * @return {Number} Render spec for this component
59.13697 +     */
59.13698 +    Flipper.prototype.render = function render() {
59.13699 +        var angle = this.angle.get();
59.13700 +
59.13701 +        var frontTransform;
59.13702 +        var backTransform;
59.13703 +
59.13704 +        if (this.options.direction === Flipper.DIRECTION_X) {
59.13705 +            frontTransform = Transform.rotateY(angle);
59.13706 +            backTransform = Transform.rotateY(angle + Math.PI);
59.13707 +        }
59.13708 +        else {
59.13709 +            frontTransform = Transform.rotateX(angle);
59.13710 +            backTransform = Transform.rotateX(angle + Math.PI);
59.13711 +        }
59.13712 +
59.13713 +        var result = [];
59.13714 +        if (this.frontNode){
59.13715 +            result.push({
59.13716 +                transform: frontTransform,
59.13717 +                target: this.frontNode.render()
59.13718 +            });
59.13719 +        }
59.13720 +
59.13721 +        if (this.backNode){
59.13722 +            result.push({
59.13723 +                transform: Transform.moveThen([0, 0, SEPERATION_LENGTH], backTransform),
59.13724 +                target: this.backNode.render()
59.13725 +            });
59.13726 +        }
59.13727 +
59.13728 +        return result;
59.13729 +    };
59.13730 +
59.13731 +    module.exports = Flipper;
59.13732 +});
59.13733 +
59.13734 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.13735 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.13736 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.13737 + *
59.13738 + * Owner: felix@famo.us
59.13739 + * @license MPL 2.0
59.13740 + * @copyright Famous Industries, Inc. 2014
59.13741 + */
59.13742 +
59.13743 +define('famous/views/GridLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/ViewSequence','famous/core/EventHandler','famous/core/Modifier','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
59.13744 +    var Entity = require('famous/core/Entity');
59.13745 +    var RenderNode = require('famous/core/RenderNode');
59.13746 +    var Transform = require('famous/core/Transform');
59.13747 +    var ViewSequence = require('famous/core/ViewSequence');
59.13748 +    var EventHandler = require('famous/core/EventHandler');
59.13749 +    var Modifier = require('famous/core/Modifier');
59.13750 +    var OptionsManager = require('famous/core/OptionsManager');
59.13751 +    var Transitionable = require('famous/transitions/Transitionable');
59.13752 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
59.13753 +
59.13754 +    /**
59.13755 +     * A layout which divides a context into several evenly-sized grid cells.
59.13756 +     *   If dimensions are provided, the grid is evenly subdivided with children
59.13757 +     *   cells representing their own context, otherwise the cellSize property is used to compute
59.13758 +     *   dimensions so that items of cellSize will fit.
59.13759 +     * @class GridLayout
59.13760 +     * @constructor
59.13761 +     * @param {Options} [options] An object of configurable options.
59.13762 +     * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns
59.13763 +     * and rows in your Gridlayout instance.
59.13764 +     * @param {Array.Number} [options.cellSize=[250, 250]]  A two-value array which specifies the width and height
59.13765 +     * of each cell in your Gridlayout instance.
59.13766 +     * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow.
59.13767 +     */
59.13768 +    function GridLayout(options) {
59.13769 +        this.options = Object.create(GridLayout.DEFAULT_OPTIONS);
59.13770 +        this.optionsManager = new OptionsManager(this.options);
59.13771 +        if (options) this.setOptions(options);
59.13772 +
59.13773 +        this.id = Entity.register(this);
59.13774 +
59.13775 +        this._modifiers = [];
59.13776 +        this._states = [];
59.13777 +        this._contextSizeCache = [0, 0];
59.13778 +        this._dimensionsCache = [0, 0];
59.13779 +        this._activeCount = 0;
59.13780 +
59.13781 +        this._eventOutput = new EventHandler();
59.13782 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.13783 +    }
59.13784 +
59.13785 +    function _reflow(size, cols, rows) {
59.13786 +        var usableSize = [size[0], size[1]];
59.13787 +        usableSize[0] -= this.options.gutterSize[0] * (cols - 1);
59.13788 +        usableSize[1] -= this.options.gutterSize[1] * (rows - 1);
59.13789 +
59.13790 +        var rowSize = Math.round(usableSize[1] / rows);
59.13791 +        var colSize = Math.round(usableSize[0] / cols);
59.13792 +
59.13793 +        var currY = 0;
59.13794 +        var currX;
59.13795 +        var currIndex = 0;
59.13796 +        for (var i = 0; i < rows; i++) {
59.13797 +            currX = 0;
59.13798 +            for (var j = 0; j < cols; j++) {
59.13799 +                if (this._modifiers[currIndex] === undefined) {
59.13800 +                    _createModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1);
59.13801 +                }
59.13802 +                else {
59.13803 +                    _animateModifier.call(this, currIndex, [colSize, rowSize], [currX, currY, 0], 1);
59.13804 +                }
59.13805 +
59.13806 +                currIndex++;
59.13807 +                currX += colSize + this.options.gutterSize[0];
59.13808 +            }
59.13809 +
59.13810 +            currY += rowSize + this.options.gutterSize[1];
59.13811 +        }
59.13812 +
59.13813 +        this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]];
59.13814 +        this._contextSizeCache = [size[0], size[1]];
59.13815 +
59.13816 +        this._activeCount = rows * cols;
59.13817 +
59.13818 +        for (i = this._activeCount ; i < this._modifiers.length; i++) _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0);
59.13819 +
59.13820 +        this._eventOutput.emit('reflow');
59.13821 +    }
59.13822 +
59.13823 +    function _createModifier(index, size, position, opacity) {
59.13824 +        var transitionItem = {
59.13825 +            transform: new TransitionableTransform(Transform.translate.apply(null, position)),
59.13826 +            opacity: new Transitionable(opacity),
59.13827 +            size: new Transitionable(size)
59.13828 +        };
59.13829 +
59.13830 +        var modifier = new Modifier({
59.13831 +            transform: transitionItem.transform,
59.13832 +            opacity: transitionItem.opacity,
59.13833 +            size: transitionItem.size
59.13834 +        });
59.13835 +
59.13836 +        this._states[index] = transitionItem;
59.13837 +        this._modifiers[index] = modifier;
59.13838 +
59.13839 +    }
59.13840 +
59.13841 +    function _animateModifier(index, size, position, opacity) {
59.13842 +        var currState = this._states[index];
59.13843 +
59.13844 +        var currSize = currState.size;
59.13845 +        var currOpacity = currState.opacity;
59.13846 +        var currTransform = currState.transform;
59.13847 +
59.13848 +        var transition = this.options.transition;
59.13849 +
59.13850 +        currTransform.halt();
59.13851 +        currOpacity.halt();
59.13852 +        currSize.halt();
59.13853 +
59.13854 +        currTransform.setTranslate(position, transition);
59.13855 +        currSize.set(size, transition);
59.13856 +        currOpacity.set(opacity, transition);
59.13857 +    }
59.13858 +
59.13859 +    GridLayout.DEFAULT_OPTIONS = {
59.13860 +        dimensions: [1, 1],
59.13861 +        transition: false,
59.13862 +        gutterSize: [0, 0]
59.13863 +    };
59.13864 +
59.13865 +    /**
59.13866 +     * Generate a render spec from the contents of this component.
59.13867 +     *
59.13868 +     * @private
59.13869 +     * @method render
59.13870 +     * @return {Object} Render spec for this component
59.13871 +     */
59.13872 +    GridLayout.prototype.render = function render() {
59.13873 +        return this.id;
59.13874 +    };
59.13875 +
59.13876 +    /**
59.13877 +     * Patches the GridLayout instance's options with the passed-in ones.
59.13878 +     *
59.13879 +     * @method setOptions
59.13880 +     * @param {Options} options An object of configurable options for the GridLayout instance.
59.13881 +     */
59.13882 +    GridLayout.prototype.setOptions = function setOptions(options) {
59.13883 +        return this.optionsManager.setOptions(options);
59.13884 +    };
59.13885 +
59.13886 +    /**
59.13887 +     * Sets the collection of renderables under the Gridlayout instance's control.
59.13888 +     *
59.13889 +     * @method sequenceFrom
59.13890 +     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence.
59.13891 +     */
59.13892 +    GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
59.13893 +        if (sequence instanceof Array) sequence = new ViewSequence(sequence);
59.13894 +        this.sequence = sequence;
59.13895 +    };
59.13896 +
59.13897 +    /**
59.13898 +     * Apply changes from this component to the corresponding document element.
59.13899 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.13900 +     * and matrix transforms.
59.13901 +     *
59.13902 +     * @private
59.13903 +     * @method commit
59.13904 +     * @param {Context} context commit context
59.13905 +     */
59.13906 +    GridLayout.prototype.commit = function commit(context) {
59.13907 +        var transform = context.transform;
59.13908 +        var opacity = context.opacity;
59.13909 +        var origin = context.origin;
59.13910 +        var size = context.size;
59.13911 +
59.13912 +        var cols = this.options.dimensions[0];
59.13913 +        var rows = this.options.dimensions[1];
59.13914 +
59.13915 +        if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) {
59.13916 +            _reflow.call(this, size, cols, rows);
59.13917 +        }
59.13918 +
59.13919 +        var sequence = this.sequence;
59.13920 +        var result = [];
59.13921 +        var currIndex = 0;
59.13922 +        while (sequence && (currIndex < this._modifiers.length)) {
59.13923 +            var item = sequence.get();
59.13924 +            var modifier = this._modifiers[currIndex];
59.13925 +            if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) {
59.13926 +                this._modifiers.splice(currIndex, 1);
59.13927 +                this._states.splice(currIndex, 1);
59.13928 +            }
59.13929 +            if (item) {
59.13930 +                result.push(
59.13931 +                    modifier.modify({
59.13932 +                        origin: origin,
59.13933 +                        target: item.render()
59.13934 +                    })
59.13935 +                );
59.13936 +            }
59.13937 +            sequence = sequence.getNext();
59.13938 +            currIndex++;
59.13939 +        }
59.13940 +
59.13941 +        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
59.13942 +        return {
59.13943 +            transform: transform,
59.13944 +            opacity: opacity,
59.13945 +            size: size,
59.13946 +            target: result
59.13947 +        };
59.13948 +    };
59.13949 +
59.13950 +    module.exports = GridLayout;
59.13951 +});
59.13952 +
59.13953 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.13954 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.13955 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.13956 + *
59.13957 + * Owner: felix@famo.us
59.13958 + * @license MPL 2.0
59.13959 + * @copyright Famous Industries, Inc. 2014
59.13960 + */
59.13961 +
59.13962 +define('famous/views/HeaderFooterLayout',['require','exports','module','famous/core/Entity','famous/core/RenderNode','famous/core/Transform','famous/core/OptionsManager'],function(require, exports, module) {
59.13963 +    var Entity = require('famous/core/Entity');
59.13964 +    var RenderNode = require('famous/core/RenderNode');
59.13965 +    var Transform = require('famous/core/Transform');
59.13966 +    var OptionsManager = require('famous/core/OptionsManager');
59.13967 +
59.13968 +    /**
59.13969 +     * A layout which will arrange three renderables into a header and footer area of defined size,
59.13970 +      and a content area of flexible size.
59.13971 +     * @class HeaderFooterLayout
59.13972 +     * @constructor
59.13973 +     * @param {Options} [options] An object of configurable options.
59.13974 +     * @param {Number} [options.direction=HeaderFooterLayout.DIRECTION_Y] A direction of HeaderFooterLayout.DIRECTION_X
59.13975 +     * lays your HeaderFooterLayout instance horizontally, and a direction of HeaderFooterLayout.DIRECTION_Y
59.13976 +     * lays it out vertically.
59.13977 +     * @param {Number} [options.headerSize=undefined]  The amount of pixels allocated to the header node
59.13978 +     * in the HeaderFooterLayout instance's direction.
59.13979 +     * @param {Number} [options.footerSize=undefined] The amount of pixels allocated to the footer node
59.13980 +     * in the HeaderFooterLayout instance's direction.
59.13981 +     */
59.13982 +    function HeaderFooterLayout(options) {
59.13983 +        this.options = Object.create(HeaderFooterLayout.DEFAULT_OPTIONS);
59.13984 +        this._optionsManager = new OptionsManager(this.options);
59.13985 +        if (options) this.setOptions(options);
59.13986 +
59.13987 +        this._entityId = Entity.register(this);
59.13988 +
59.13989 +        this.header = new RenderNode();
59.13990 +        this.footer = new RenderNode();
59.13991 +        this.content = new RenderNode();
59.13992 +    }
59.13993 +
59.13994 +    /**
59.13995 +     *  When used as a value for your HeaderFooterLayout's direction option, causes it to lay out horizontally.
59.13996 +     *
59.13997 +     *  @attribute DIRECTION_X
59.13998 +     *  @type Number
59.13999 +     *  @static
59.14000 +     *  @default 0
59.14001 +     *  @protected
59.14002 +     */
59.14003 +    HeaderFooterLayout.DIRECTION_X = 0;
59.14004 +
59.14005 +    /**
59.14006 +     *  When used as a value for your HeaderFooterLayout's direction option, causes it to lay out vertically.
59.14007 +     *
59.14008 +     *  @attribute DIRECTION_Y
59.14009 +     *  @type Number
59.14010 +     *  @static
59.14011 +     *  @default 1
59.14012 +     *  @protected
59.14013 +     */
59.14014 +    HeaderFooterLayout.DIRECTION_Y = 1;
59.14015 +
59.14016 +    HeaderFooterLayout.DEFAULT_OPTIONS = {
59.14017 +        direction: HeaderFooterLayout.DIRECTION_Y,
59.14018 +        headerSize: undefined,
59.14019 +        footerSize: undefined,
59.14020 +        defaultHeaderSize: 0,
59.14021 +        defaultFooterSize: 0
59.14022 +    };
59.14023 +
59.14024 +    /**
59.14025 +     * Generate a render spec from the contents of this component.
59.14026 +     *
59.14027 +     * @private
59.14028 +     * @method render
59.14029 +     * @return {Object} Render spec for this component
59.14030 +     */
59.14031 +    HeaderFooterLayout.prototype.render = function render() {
59.14032 +        return this._entityId;
59.14033 +    };
59.14034 +
59.14035 +    /**
59.14036 +     * Patches the HeaderFooterLayout instance's options with the passed-in ones.
59.14037 +     *
59.14038 +     * @method setOptions
59.14039 +     * @param {Options} options An object of configurable options for the HeaderFooterLayout instance.
59.14040 +     */
59.14041 +    HeaderFooterLayout.prototype.setOptions = function setOptions(options) {
59.14042 +        return this._optionsManager.setOptions(options);
59.14043 +    };
59.14044 +
59.14045 +    function _resolveNodeSize(node, defaultSize) {
59.14046 +        var nodeSize = node.getSize();
59.14047 +        return nodeSize ? nodeSize[this.options.direction] : defaultSize;
59.14048 +    }
59.14049 +
59.14050 +    function _outputTransform(offset) {
59.14051 +        if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return Transform.translate(offset, 0, 0);
59.14052 +        else return Transform.translate(0, offset, 0);
59.14053 +    }
59.14054 +
59.14055 +    function _finalSize(directionSize, size) {
59.14056 +        if (this.options.direction === HeaderFooterLayout.DIRECTION_X) return [directionSize, size[1]];
59.14057 +        else return [size[0], directionSize];
59.14058 +    }
59.14059 +
59.14060 +    /**
59.14061 +     * Apply changes from this component to the corresponding document element.
59.14062 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.14063 +     * and matrix transforms.
59.14064 +     *
59.14065 +     * @private
59.14066 +     * @method commit
59.14067 +     * @param {Context} context commit context
59.14068 +     */
59.14069 +    HeaderFooterLayout.prototype.commit = function commit(context) {
59.14070 +        var transform = context.transform;
59.14071 +        var origin = context.origin;
59.14072 +        var size = context.size;
59.14073 +        var opacity = context.opacity;
59.14074 +
59.14075 +        var headerSize = (this.options.headerSize !== undefined) ? this.options.headerSize : _resolveNodeSize.call(this, this.header, this.options.defaultHeaderSize);
59.14076 +        var footerSize = (this.options.footerSize !== undefined) ? this.options.footerSize : _resolveNodeSize.call(this, this.footer, this.options.defaultFooterSize);
59.14077 +        var contentSize = size[this.options.direction] - headerSize - footerSize;
59.14078 +
59.14079 +        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
59.14080 +
59.14081 +        var result = [
59.14082 +            {
59.14083 +                size: _finalSize.call(this, headerSize, size),
59.14084 +                target: this.header.render()
59.14085 +            },
59.14086 +            {
59.14087 +                transform: _outputTransform.call(this, headerSize),
59.14088 +                size: _finalSize.call(this, contentSize, size),
59.14089 +                target: this.content.render()
59.14090 +            },
59.14091 +            {
59.14092 +                transform: _outputTransform.call(this, headerSize + contentSize),
59.14093 +                size: _finalSize.call(this, footerSize, size),
59.14094 +                target: this.footer.render()
59.14095 +            }
59.14096 +        ];
59.14097 +
59.14098 +        return {
59.14099 +            transform: transform,
59.14100 +            opacity: opacity,
59.14101 +            size: size,
59.14102 +            target: result
59.14103 +        };
59.14104 +    };
59.14105 +
59.14106 +    module.exports = HeaderFooterLayout;
59.14107 +});
59.14108 +
59.14109 +define('famous/views/Lightbox',['require','exports','module','famous/core/Transform','famous/core/Modifier','famous/core/RenderNode','famous/utilities/Utility','famous/core/OptionsManager','famous/transitions/Transitionable','famous/transitions/TransitionableTransform'],function(require, exports, module) {
59.14110 +    var Transform = require('famous/core/Transform');
59.14111 +    var Modifier = require('famous/core/Modifier');
59.14112 +    var RenderNode = require('famous/core/RenderNode');
59.14113 +    var Utility = require('famous/utilities/Utility');
59.14114 +    var OptionsManager = require('famous/core/OptionsManager');
59.14115 +    var Transitionable = require('famous/transitions/Transitionable');
59.14116 +    var TransitionableTransform = require('famous/transitions/TransitionableTransform');
59.14117 +
59.14118 +    /**
59.14119 +     * Lightbox, using transitions, shows and hides different renderables. Lightbox can essentially be
59.14120 +     * thought of as RenderController with a stateful implementation and interface.
59.14121 +     *
59.14122 +     * @class Lightbox
59.14123 +     * @constructor
59.14124 +     * @param {Options} [options] An object of configurable options.
59.14125 +     * @param {Transform} [options.inTransform] The transform at the start of transitioning in a shown renderable.
59.14126 +     * @param {Transform} [options.outTransform] The transform at the end of transitioning out a renderable.
59.14127 +     * @param {Transform} [options.showTransform] The transform applied to your shown renderable in its state of equilibrium.
59.14128 +     * @param {Number} [options.inOpacity] A number between one and zero that defines the state of a shown renderables opacity upon initially
59.14129 +     * being transitioned in.
59.14130 +     * @param {Number} [options.outOpacity] A number between one and zero that defines the state of a shown renderables opacity upon being
59.14131 +     * fully transitioned out.
59.14132 +     * @param {Number} [options.showOpacity] A number between one and zero that defines the state of a shown renderables opacity
59.14133 +     * once succesfully transitioned in.
59.14134 +     * @param {Array<Number>} [options.inOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables
59.14135 +     * origin upon intially being transitioned in.
59.14136 +     * @param {Array<Number>} [options.outOrigin] A two value array of numbers between one and zero that defines the state of a shown renderable
59.14137 +     * once fully hidden.
59.14138 +     * @param {Array<Number>} [options.showOrigin] A two value array of numbers between one and zero that defines the state of a shown renderables
59.14139 +     * origin upon succesfully being shown.
59.14140 +     * @param {Transition} [options.inTransition=true] The transition in charge of showing a renderable.
59.14141 +     * @param {Transition} [options.outTransition=true]  The transition in charge of removing your previous renderable when
59.14142 +     * you show a new one, or hiding your current renderable.
59.14143 +     * @param {Boolean} [options.overlap=false] When showing a new renderable, overlap determines if the
59.14144 +     *   out transition of the old one executes concurrently with the in transition of the new one,
59.14145 +      *  or synchronously beforehand.
59.14146 +     */
59.14147 +    function Lightbox(options) {
59.14148 +        this.options = Object.create(Lightbox.DEFAULT_OPTIONS);
59.14149 +        this._optionsManager = new OptionsManager(this.options);
59.14150 +
59.14151 +        if (options) this.setOptions(options);
59.14152 +
59.14153 +        this._showing = false;
59.14154 +        this.nodes = [];
59.14155 +        this.transforms = [];
59.14156 +        this.states = [];
59.14157 +    }
59.14158 +
59.14159 +    Lightbox.DEFAULT_OPTIONS = {
59.14160 +        inTransform: Transform.scale(0.001, 0.001, 0.001),
59.14161 +        inOpacity: 0,
59.14162 +        inOrigin: [0.5, 0.5],
59.14163 +        outTransform: Transform.scale(0.001, 0.001, 0.001),
59.14164 +        outOpacity: 0,
59.14165 +        outOrigin: [0.5, 0.5],
59.14166 +        showTransform: Transform.identity,
59.14167 +        showOpacity: 1,
59.14168 +        showOrigin: [0.5, 0.5],
59.14169 +        inTransition: true,
59.14170 +        outTransition: true,
59.14171 +        overlap: false
59.14172 +    };
59.14173 +
59.14174 +    /**
59.14175 +     * Patches the Lightbox instance's options with the passed-in ones.
59.14176 +     *
59.14177 +     * @method setOptions
59.14178 +     * @param {Options} options An object of configurable options for the Lightbox instance.
59.14179 +     */
59.14180 +    Lightbox.prototype.setOptions = function setOptions(options) {
59.14181 +        return this._optionsManager.setOptions(options);
59.14182 +    };
59.14183 +
59.14184 +   /**
59.14185 +     * Show displays the targeted renderable with a transition and an optional callback to
59.14186 +     *  execute afterwards.
59.14187 +     * @method show
59.14188 +     * @param {Object} renderable The renderable you want to show.
59.14189 +     * @param {Transition} [transition] Overwrites the default transition in to display the
59.14190 +     * passed-in renderable.
59.14191 +     * @param {function} [callback] Executes after transitioning in the renderable.
59.14192 +     */
59.14193 +    Lightbox.prototype.show = function show(renderable, transition, callback) {
59.14194 +        if (!renderable) {
59.14195 +            return this.hide(callback);
59.14196 +        }
59.14197 +
59.14198 +        if (transition instanceof Function) {
59.14199 +            callback = transition;
59.14200 +            transition = undefined;
59.14201 +        }
59.14202 +
59.14203 +        if (this._showing) {
59.14204 +            if (this.options.overlap) this.hide();
59.14205 +            else {
59.14206 +                return this.hide(this.show.bind(this, renderable, transition, callback));
59.14207 +            }
59.14208 +        }
59.14209 +        this._showing = true;
59.14210 +
59.14211 +        var stateItem = {
59.14212 +            transform: new TransitionableTransform(this.options.inTransform),
59.14213 +            origin: new Transitionable(this.options.inOrigin),
59.14214 +            opacity: new Transitionable(this.options.inOpacity)
59.14215 +        };
59.14216 +
59.14217 +        var transform = new Modifier({
59.14218 +            transform: stateItem.transform,
59.14219 +            opacity: stateItem.opacity,
59.14220 +            origin: stateItem.origin
59.14221 +        });
59.14222 +        var node = new RenderNode();
59.14223 +        node.add(transform).add(renderable);
59.14224 +        this.nodes.push(node);
59.14225 +        this.states.push(stateItem);
59.14226 +        this.transforms.push(transform);
59.14227 +
59.14228 +        var _cb = callback ? Utility.after(3, callback) : undefined;
59.14229 +
59.14230 +        if (!transition) transition = this.options.inTransition;
59.14231 +        stateItem.transform.set(this.options.showTransform, transition, _cb);
59.14232 +        stateItem.opacity.set(this.options.showOpacity, transition, _cb);
59.14233 +        stateItem.origin.set(this.options.showOrigin, transition, _cb);
59.14234 +    };
59.14235 +
59.14236 +    /**
59.14237 +     * Hide hides the currently displayed renderable with an out transition.
59.14238 +     * @method hide
59.14239 +     * @param {Transition} [transition] Overwrites the default transition in to hide the
59.14240 +     * currently controlled renderable.
59.14241 +     * @param {function} [callback] Executes after transitioning out the renderable.
59.14242 +     */
59.14243 +    Lightbox.prototype.hide = function hide(transition, callback) {
59.14244 +        if (!this._showing) return;
59.14245 +        this._showing = false;
59.14246 +
59.14247 +        if (transition instanceof Function) {
59.14248 +            callback = transition;
59.14249 +            transition = undefined;
59.14250 +        }
59.14251 +
59.14252 +        var node = this.nodes[this.nodes.length - 1];
59.14253 +        var transform = this.transforms[this.transforms.length - 1];
59.14254 +        var stateItem = this.states[this.states.length - 1];
59.14255 +        var _cb = Utility.after(3, function() {
59.14256 +            this.nodes.splice(this.nodes.indexOf(node), 1);
59.14257 +            this.states.splice(this.states.indexOf(stateItem), 1);
59.14258 +            this.transforms.splice(this.transforms.indexOf(transform), 1);
59.14259 +            if (callback) callback.call(this);
59.14260 +        }.bind(this));
59.14261 +
59.14262 +        if (!transition) transition = this.options.outTransition;
59.14263 +        stateItem.transform.set(this.options.outTransform, transition, _cb);
59.14264 +        stateItem.opacity.set(this.options.outOpacity, transition, _cb);
59.14265 +        stateItem.origin.set(this.options.outOrigin, transition, _cb);
59.14266 +    };
59.14267 +
59.14268 +    /**
59.14269 +     * Generate a render spec from the contents of this component.
59.14270 +     *
59.14271 +     * @private
59.14272 +     * @method render
59.14273 +     * @return {number} Render spec for this component
59.14274 +     */
59.14275 +    Lightbox.prototype.render = function render() {
59.14276 +        var result = [];
59.14277 +        for (var i = 0; i < this.nodes.length; i++) {
59.14278 +            result.push(this.nodes[i].render());
59.14279 +        }
59.14280 +        return result;
59.14281 +    };
59.14282 +
59.14283 +    module.exports = Lightbox;
59.14284 +});
59.14285 +
59.14286 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.14287 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.14288 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.14289 + *
59.14290 + * Owner: david@famo.us
59.14291 + * @license MPL 2.0
59.14292 + * @copyright Famous Industries, Inc. 2014
59.14293 + */
59.14294 +
59.14295 +define('famous/physics/forces/Drag',['require','exports','module','./Force'],function(require, exports, module) {
59.14296 +    var Force = require('./Force');
59.14297 +
59.14298 +    /**
59.14299 +     * Drag is a force that opposes velocity. Attach it to the physics engine
59.14300 +     * to slow down a physics body in motion.
59.14301 +     *
59.14302 +     * @class Drag
59.14303 +     * @constructor
59.14304 +     * @extends Force
59.14305 +     * @param {Object} options options to set on drag
59.14306 +     */
59.14307 +    function Drag(options) {
59.14308 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
59.14309 +        if (options) this.setOptions(options);
59.14310 +
59.14311 +        Force.call(this);
59.14312 +    }
59.14313 +
59.14314 +    Drag.prototype = Object.create(Force.prototype);
59.14315 +    Drag.prototype.constructor = Drag;
59.14316 +
59.14317 +    /**
59.14318 +     * @property Drag.FORCE_FUNCTIONS
59.14319 +     * @type Object
59.14320 +     * @protected
59.14321 +     * @static
59.14322 +     */
59.14323 +    Drag.FORCE_FUNCTIONS = {
59.14324 +
59.14325 +        /**
59.14326 +         * A drag force proportional to the velocity
59.14327 +         * @attribute LINEAR
59.14328 +         * @type Function
59.14329 +         * @param {Vector} velocity
59.14330 +         * @return {Vector} drag force
59.14331 +         */
59.14332 +        LINEAR : function(velocity) {
59.14333 +            return velocity;
59.14334 +        },
59.14335 +
59.14336 +        /**
59.14337 +         * A drag force proportional to the square of the velocity
59.14338 +         * @attribute QUADRATIC
59.14339 +         * @type Function
59.14340 +         * @param {Vector} velocity
59.14341 +         * @return {Vector} drag force
59.14342 +         */
59.14343 +        QUADRATIC : function(velocity) {
59.14344 +            return velocity.mult(velocity.norm());
59.14345 +        }
59.14346 +    };
59.14347 +
59.14348 +    /**
59.14349 +     * @property Drag.DEFAULT_OPTIONS
59.14350 +     * @type Object
59.14351 +     * @protected
59.14352 +     * @static
59.14353 +     */
59.14354 +    Drag.DEFAULT_OPTIONS = {
59.14355 +
59.14356 +        /**
59.14357 +         * The strength of the force
59.14358 +         *    Range : [0, 0.1]
59.14359 +         * @attribute strength
59.14360 +         * @type Number
59.14361 +         * @default 0.01
59.14362 +         */
59.14363 +        strength : 0.01,
59.14364 +
59.14365 +        /**
59.14366 +         * The type of opposing force
59.14367 +         * @attribute forceFunction
59.14368 +         * @type Function
59.14369 +         */
59.14370 +        forceFunction : Drag.FORCE_FUNCTIONS.LINEAR
59.14371 +    };
59.14372 +
59.14373 +    /**
59.14374 +     * Adds a drag force to a physics body's force accumulator.
59.14375 +     *
59.14376 +     * @method applyForce
59.14377 +     * @param targets {Array.Body} Array of bodies to apply drag force to.
59.14378 +     */
59.14379 +    Drag.prototype.applyForce = function applyForce(targets) {
59.14380 +        var strength        = this.options.strength;
59.14381 +        var forceFunction   = this.options.forceFunction;
59.14382 +        var force           = this.force;
59.14383 +        for (var index = 0; index < targets.length; index++) {
59.14384 +            var particle = targets[index];
59.14385 +            forceFunction(particle.velocity).mult(-strength).put(force);
59.14386 +            particle.applyForce(force);
59.14387 +        }
59.14388 +    };
59.14389 +
59.14390 +    /**
59.14391 +     * Basic options setter
59.14392 +     *
59.14393 +     * @method setOptions
59.14394 +     * @param {Objects} options
59.14395 +     */
59.14396 +    Drag.prototype.setOptions = function setOptions(options) {
59.14397 +        for (var key in options) this.options[key] = options[key];
59.14398 +    };
59.14399 +
59.14400 +    module.exports = Drag;
59.14401 +});
59.14402 +
59.14403 +define('famous/views/Scroller',['require','exports','module','famous/core/Entity','famous/core/Group','famous/core/OptionsManager','famous/core/Transform','famous/utilities/Utility','famous/core/ViewSequence','famous/core/EventHandler'],function(require, exports, module) {
59.14404 +    var Entity = require('famous/core/Entity');
59.14405 +    var Group = require('famous/core/Group');
59.14406 +    var OptionsManager = require('famous/core/OptionsManager');
59.14407 +    var Transform = require('famous/core/Transform');
59.14408 +    var Utility = require('famous/utilities/Utility');
59.14409 +    var ViewSequence = require('famous/core/ViewSequence');
59.14410 +    var EventHandler = require('famous/core/EventHandler');
59.14411 +
59.14412 +    /**
59.14413 +     * Scroller lays out a collection of renderables, and will browse through them based on
59.14414 +     * accessed position. Scroller also broadcasts an 'edgeHit' event, with a position property of the location of the edge,
59.14415 +     * when you've hit the 'edges' of it's renderable collection.
59.14416 +     * @class Scroller
59.14417 +     * @constructor
59.14418 +      * @event error
59.14419 +     * @param {Options} [options] An object of configurable options.
59.14420 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
59.14421 +     * module, this option will lay out the Scroller instance's renderables either horizontally
59.14422 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
59.14423 +     * to just use integers as well.
59.14424 +     * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scroller will display content in.
59.14425 +     * @param {Number} [margin=undefined] The size of the area (in pixels) that Scroller will process renderables' associated calculations in.
59.14426 +     */
59.14427 +    function Scroller(options) {
59.14428 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
59.14429 +        this._optionsManager = new OptionsManager(this.options);
59.14430 +        if (options) this._optionsManager.setOptions(options);
59.14431 +
59.14432 +        this._node = null;
59.14433 +        this._position = 0;
59.14434 +
59.14435 +        // used for shifting nodes
59.14436 +        this._positionOffset = 0;
59.14437 +
59.14438 +        this._positionGetter = null;
59.14439 +        this._outputFunction = null;
59.14440 +        this._masterOutputFunction = null;
59.14441 +        this.outputFrom();
59.14442 +
59.14443 +        this._onEdge = 0; // -1 for top, 1 for bottom
59.14444 +
59.14445 +        this.group = new Group();
59.14446 +        this.group.add({render: _innerRender.bind(this)});
59.14447 +
59.14448 +        this._entityId = Entity.register(this);
59.14449 +        this._size = [undefined, undefined];
59.14450 +        this._contextSize = [undefined, undefined];
59.14451 +
59.14452 +        this._eventInput = new EventHandler();
59.14453 +        this._eventOutput = new EventHandler();
59.14454 +
59.14455 +        EventHandler.setInputHandler(this, this._eventInput);
59.14456 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.14457 +    }
59.14458 +
59.14459 +    Scroller.DEFAULT_OPTIONS = {
59.14460 +        direction: Utility.Direction.Y,
59.14461 +        margin: 0,
59.14462 +        clipSize: undefined,
59.14463 +        groupScroll: false
59.14464 +    };
59.14465 +
59.14466 +    function _sizeForDir(size) {
59.14467 +        if (!size) size = this._contextSize;
59.14468 +        var dimension = (this.options.direction === Utility.Direction.X) ? 0 : 1;
59.14469 +        return (size[dimension] === undefined) ? this._contextSize[dimension] : size[dimension];
59.14470 +    }
59.14471 +
59.14472 +    function _output(node, offset, target) {
59.14473 +        var size = node.getSize ? node.getSize() : this._contextSize;
59.14474 +        var transform = this._outputFunction(offset);
59.14475 +        target.push({transform: transform, target: node.render()});
59.14476 +        return _sizeForDir.call(this, size);
59.14477 +    }
59.14478 +
59.14479 +    function _getClipSize() {
59.14480 +        if (this.options.clipSize) return this.options.clipSize;
59.14481 +        else return _sizeForDir.call(this, this._contextSize);
59.14482 +    }
59.14483 +
59.14484 +    /**
59.14485 +     * Patches the Scroller instance's options with the passed-in ones.
59.14486 +     * @method setOptions
59.14487 +     * @param {Options} options An object of configurable options for the Scroller instance.
59.14488 +     */
59.14489 +    Scroller.prototype.setOptions = function setOptions(options) {
59.14490 +        this._optionsManager.setOptions(options);
59.14491 +
59.14492 +        if (this.options.groupScroll) {
59.14493 +          this.group.pipe(this._eventOutput);
59.14494 +        }
59.14495 +        else {
59.14496 +          this.group.unpipe(this._eventOutput);
59.14497 +        }
59.14498 +    };
59.14499 +
59.14500 +    /**
59.14501 +     * Tells you if the Scroller instance is on an edge.
59.14502 +     * @method onEdge
59.14503 +     * @return {Boolean} Whether the Scroller instance is on an edge or not.
59.14504 +     */
59.14505 +    Scroller.prototype.onEdge = function onEdge() {
59.14506 +        return this._onEdge;
59.14507 +    };
59.14508 +
59.14509 +    /**
59.14510 +     * Allows you to overwrite the way Scroller lays out it's renderables. Scroller will
59.14511 +     * pass an offset into the function. By default the Scroller instance just translates each node
59.14512 +     * in it's direction by the passed-in offset.
59.14513 +     * Scroller will translate each renderable down
59.14514 +     * @method outputFrom
59.14515 +     * @param {Function} fn A function that takes an offset and returns a transform.
59.14516 +     * @param {Function} [masterFn]
59.14517 +     */
59.14518 +    Scroller.prototype.outputFrom = function outputFrom(fn, masterFn) {
59.14519 +        if (!fn) {
59.14520 +            fn = function(offset) {
59.14521 +                return (this.options.direction === Utility.Direction.X) ? Transform.translate(offset, 0) : Transform.translate(0, offset);
59.14522 +            }.bind(this);
59.14523 +            if (!masterFn) masterFn = fn;
59.14524 +        }
59.14525 +        this._outputFunction = fn;
59.14526 +        this._masterOutputFunction = masterFn ? masterFn : function(offset) {
59.14527 +            return Transform.inverse(fn(-offset));
59.14528 +        };
59.14529 +    };
59.14530 +
59.14531 +    /**
59.14532 +     * The Scroller instance's method for reading from an external position. Scroller uses
59.14533 +     * the external position to actually scroll through it's renderables.
59.14534 +     * @method positionFrom
59.14535 +     * @param {Getter} position Can be either a function that returns a position,
59.14536 +     * or an object with a get method that returns a position.
59.14537 +     */
59.14538 +    Scroller.prototype.positionFrom = function positionFrom(position) {
59.14539 +        if (position instanceof Function) this._positionGetter = position;
59.14540 +        else if (position && position.get) this._positionGetter = position.get.bind(position);
59.14541 +        else {
59.14542 +            this._positionGetter = null;
59.14543 +            this._position = position;
59.14544 +        }
59.14545 +        if (this._positionGetter) this._position = this._positionGetter.call(this);
59.14546 +    };
59.14547 +
59.14548 +    /**
59.14549 +     * Sets the collection of renderables under the Scroller instance's control.
59.14550 +     *
59.14551 +     * @method sequenceFrom
59.14552 +     * @param {Array|ViewSequence} items Either an array of renderables or a Famous viewSequence.
59.14553 +     * @chainable
59.14554 +     */
59.14555 +    Scroller.prototype.sequenceFrom = function sequenceFrom(node) {
59.14556 +        if (node instanceof Array) node = new ViewSequence({array: node});
59.14557 +        this._node = node;
59.14558 +        this._positionOffset = 0;
59.14559 +    };
59.14560 +
59.14561 +    /**
59.14562 +     * Returns the width and the height of the Scroller instance.
59.14563 +     *
59.14564 +     * @method getSize
59.14565 +     * @return {Array} A two value array of the Scroller instance's current width and height (in that order).
59.14566 +     */
59.14567 +    Scroller.prototype.getSize = function getSize(actual) {
59.14568 +        return actual ? this._contextSize : this._size;
59.14569 +    };
59.14570 +
59.14571 +    /**
59.14572 +     * Generate a render spec from the contents of this component.
59.14573 +     *
59.14574 +     * @private
59.14575 +     * @method render
59.14576 +     * @return {number} Render spec for this component
59.14577 +     */
59.14578 +    Scroller.prototype.render = function render() {
59.14579 +        if (!this._node) return null;
59.14580 +        if (this._positionGetter) this._position = this._positionGetter.call(this);
59.14581 +        return this._entityId;
59.14582 +    };
59.14583 +
59.14584 +    /**
59.14585 +     * Apply changes from this component to the corresponding document element.
59.14586 +     * This includes changes to classes, styles, size, content, opacity, origin,
59.14587 +     * and matrix transforms.
59.14588 +     *
59.14589 +     * @private
59.14590 +     * @method commit
59.14591 +     * @param {Context} context commit context
59.14592 +     */
59.14593 +    Scroller.prototype.commit = function commit(context) {
59.14594 +        var transform = context.transform;
59.14595 +        var opacity = context.opacity;
59.14596 +        var origin = context.origin;
59.14597 +        var size = context.size;
59.14598 +
59.14599 +        // reset edge detection on size change
59.14600 +        if (!this.options.clipSize && (size[0] !== this._contextSize[0] || size[1] !== this._contextSize[1])) {
59.14601 +            this._onEdge = 0;
59.14602 +            this._contextSize[0] = size[0];
59.14603 +            this._contextSize[1] = size[1];
59.14604 +
59.14605 +            if (this.options.direction === Utility.Direction.X) {
59.14606 +                this._size[0] = _getClipSize.call(this);
59.14607 +                this._size[1] = undefined;
59.14608 +            }
59.14609 +            else {
59.14610 +                this._size[0] = undefined;
59.14611 +                this._size[1] = _getClipSize.call(this);
59.14612 +            }
59.14613 +        }
59.14614 +
59.14615 +        var scrollTransform = this._masterOutputFunction(-this._position);
59.14616 +
59.14617 +        return {
59.14618 +            transform: Transform.multiply(transform, scrollTransform),
59.14619 +            size: size,
59.14620 +            opacity: opacity,
59.14621 +            origin: origin,
59.14622 +            target: this.group.render()
59.14623 +        };
59.14624 +    };
59.14625 +
59.14626 +    function _normalizeState() {
59.14627 +        var nodeSize = _sizeForDir.call(this, this._node.getSize());
59.14628 +        var nextNode = this._node && this._node.getNext ? this._node.getNext() : null;
59.14629 +        while (nextNode && this._position + this._positionOffset >= nodeSize) {
59.14630 +            this._positionOffset -= nodeSize;
59.14631 +            this._node = nextNode;
59.14632 +            nodeSize = _sizeForDir.call(this, this._node.getSize());
59.14633 +            nextNode = this._node && this._node.getNext ? this._node.getNext() : null;
59.14634 +        }
59.14635 +        var prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null;
59.14636 +        while (prevNode && this._position + this._positionOffset < 0) {
59.14637 +            var prevNodeSize = _sizeForDir.call(this, prevNode.getSize());
59.14638 +            this._positionOffset += prevNodeSize;
59.14639 +            this._node = prevNode;
59.14640 +            prevNode = this._node && this._node.getPrevious ? this._node.getPrevious() : null;
59.14641 +        }
59.14642 +    }
59.14643 +
59.14644 +    function _innerRender() {
59.14645 +        var size = null;
59.14646 +        var position = this._position;
59.14647 +        var result = [];
59.14648 +
59.14649 +        this._onEdge = 0;
59.14650 +
59.14651 +        var offset = -this._positionOffset;
59.14652 +        var clipSize = _getClipSize.call(this);
59.14653 +        var currNode = this._node;
59.14654 +        while (currNode && offset - position < clipSize + this.options.margin) {
59.14655 +            offset += _output.call(this, currNode, offset, result);
59.14656 +            currNode = currNode.getNext ? currNode.getNext() : null;
59.14657 +        }
59.14658 +
59.14659 +        var sizeNode = this._node;
59.14660 +        var nodesSize = _sizeForDir.call(this, sizeNode.getSize());
59.14661 +        if (offset < clipSize) {
59.14662 +            while (sizeNode && nodesSize < clipSize) {
59.14663 +                sizeNode = sizeNode.getPrevious();
59.14664 +                if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize());
59.14665 +            }
59.14666 +            sizeNode = this._node;
59.14667 +            while (sizeNode && nodesSize < clipSize) {
59.14668 +                sizeNode = sizeNode.getNext();
59.14669 +                if (sizeNode) nodesSize += _sizeForDir.call(this, sizeNode.getSize());
59.14670 +            }
59.14671 +        }
59.14672 +
59.14673 +        var edgeSize = (nodesSize !== undefined && nodesSize < clipSize) ? nodesSize : clipSize;
59.14674 +
59.14675 +        if (!currNode && offset - position <= edgeSize) {
59.14676 +            this._onEdge = 1;
59.14677 +            this._eventOutput.emit('edgeHit', {
59.14678 +                position: offset - edgeSize
59.14679 +            });
59.14680 +        }
59.14681 +        else if (!this._node.getPrevious() && position <= 0) {
59.14682 +            this._onEdge = -1;
59.14683 +            this._eventOutput.emit('edgeHit', {
59.14684 +                position: 0
59.14685 +            });
59.14686 +        }
59.14687 +
59.14688 +        // backwards
59.14689 +        currNode = (this._node && this._node.getPrevious) ? this._node.getPrevious() : null;
59.14690 +        offset = -this._positionOffset;
59.14691 +        if (currNode) {
59.14692 +            size = currNode.getSize ? currNode.getSize() : this._contextSize;
59.14693 +            offset -= _sizeForDir.call(this, size);
59.14694 +        }
59.14695 +
59.14696 +        while (currNode && ((offset - position) > -(_getClipSize.call(this) + this.options.margin))) {
59.14697 +            _output.call(this, currNode, offset, result);
59.14698 +            currNode = currNode.getPrevious ? currNode.getPrevious() : null;
59.14699 +            if (currNode) {
59.14700 +                size = currNode.getSize ? currNode.getSize() : this._contextSize;
59.14701 +                offset -= _sizeForDir.call(this, size);
59.14702 +            }
59.14703 +        }
59.14704 +
59.14705 +        _normalizeState.call(this);
59.14706 +        return result;
59.14707 +    }
59.14708 +
59.14709 +    module.exports = Scroller;
59.14710 +});
59.14711 +
59.14712 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.14713 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.14714 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.14715 + *
59.14716 + * Owner: felix@famo.us
59.14717 + * @license MPL 2.0
59.14718 + * @copyright Famous Industries, Inc. 2014
59.14719 + */
59.14720 +
59.14721 +define('famous/views/Scrollview',['require','exports','module','famous/physics/PhysicsEngine','famous/physics/bodies/Particle','famous/physics/forces/Drag','famous/physics/forces/Spring','famous/core/EventHandler','famous/core/OptionsManager','famous/core/ViewSequence','famous/views/Scroller','famous/utilities/Utility','famous/inputs/GenericSync','famous/inputs/ScrollSync','famous/inputs/TouchSync'],function(require, exports, module) {
59.14722 +    var PhysicsEngine = require('famous/physics/PhysicsEngine');
59.14723 +    var Particle = require('famous/physics/bodies/Particle');
59.14724 +    var Drag = require('famous/physics/forces/Drag');
59.14725 +    var Spring = require('famous/physics/forces/Spring');
59.14726 +
59.14727 +    var EventHandler = require('famous/core/EventHandler');
59.14728 +    var OptionsManager = require('famous/core/OptionsManager');
59.14729 +    var ViewSequence = require('famous/core/ViewSequence');
59.14730 +    var Scroller = require('famous/views/Scroller');
59.14731 +    var Utility = require('famous/utilities/Utility');
59.14732 +
59.14733 +    var GenericSync = require('famous/inputs/GenericSync');
59.14734 +    var ScrollSync = require('famous/inputs/ScrollSync');
59.14735 +    var TouchSync = require('famous/inputs/TouchSync');
59.14736 +    GenericSync.register({scroll : ScrollSync, touch : TouchSync});
59.14737 +
59.14738 +    /**
59.14739 +     * Scrollview will lay out a collection of renderables sequentially in the specified direction, and will
59.14740 +     * allow you to scroll through them with mousewheel or touch events.
59.14741 +     * @class Scrollview
59.14742 +     * @constructor
59.14743 +     * @param {Options} [options] An object of configurable options.
59.14744 +     * @param {Number} [options.direction=Utility.Direction.Y] Using the direction helper found in the famous Utility
59.14745 +     * module, this option will lay out the Scrollview instance's renderables either horizontally
59.14746 +     * (x) or vertically (y). Utility's direction is essentially either zero (X) or one (Y), so feel free
59.14747 +     * to just use integers as well.
59.14748 +     * @param {Boolean} [options.rails=true] When true, Scrollview's genericSync will only process input in it's primary access.
59.14749 +     * @param {Number} [clipSize=undefined] The size of the area (in pixels) that Scrollview will display content in.
59.14750 +     * @param {Number} [margin=undefined] The size of the area (in pixels) that Scrollview will process renderables' associated calculations in.
59.14751 +     * @param {Number} [friction=0.001] Input resistance proportional to the velocity of the input.
59.14752 +     * Controls the feel of the Scrollview instance at low velocities.
59.14753 +     * @param {Number} [drag=0.0001] Input resistance proportional to the square of the velocity of the input.
59.14754 +     * Affects Scrollview instance more prominently at high velocities.
59.14755 +     * @param {Number} [edgeGrip=0.5] A coefficient for resistance against after-touch momentum.
59.14756 +     * @param {Number} [egePeriod=300] Sets the period on the spring that handles the physics associated
59.14757 +     * with hitting the end of a scrollview.
59.14758 +     * @param {Number} [edgeDamp=1] Sets the damping on the spring that handles the physics associated
59.14759 +     * with hitting the end of a scrollview.
59.14760 +     * @param {Boolean} [paginated=false] A paginated scrollview will scroll through items discretely
59.14761 +     * rather than continously.
59.14762 +     * @param {Number} [pagePeriod=500] Sets the period on the spring that handles the physics associated
59.14763 +     * with pagination.
59.14764 +     * @param {Number} [pageDamp=0.8] Sets the damping on the spring that handles the physics associated
59.14765 +     * with pagination.
59.14766 +     * @param {Number} [pageStopSpeed=Infinity] The threshold for determining the amount of velocity
59.14767 +     * required to trigger pagination. The lower the threshold, the easier it is to scroll continuosly.
59.14768 +     * @param {Number} [pageSwitchSpeed=1] The threshold for momentum-based velocity pagination.
59.14769 +     * @param {Number} [speedLimit=10] The highest scrolling speed you can reach.
59.14770 +     */
59.14771 +    function Scrollview(options) {
59.14772 +        this.options = Object.create(Scrollview.DEFAULT_OPTIONS);
59.14773 +        this._optionsManager = new OptionsManager(this.options);
59.14774 +
59.14775 +        this._node = null;
59.14776 +
59.14777 +        this._physicsEngine = new PhysicsEngine();
59.14778 +        this._particle = new Particle();
59.14779 +        this._physicsEngine.addBody(this._particle);
59.14780 +
59.14781 +        this.spring = new Spring({anchor: [0, 0, 0]});
59.14782 +
59.14783 +        this.drag = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.QUADRATIC});
59.14784 +        this.friction = new Drag({forceFunction: Drag.FORCE_FUNCTIONS.LINEAR});
59.14785 +
59.14786 +        this.sync = new GenericSync(['scroll', 'touch'], {direction : this.options.direction});
59.14787 +
59.14788 +        this._eventInput = new EventHandler();
59.14789 +        this._eventOutput = new EventHandler();
59.14790 +
59.14791 +        this._eventInput.pipe(this.sync);
59.14792 +        this.sync.pipe(this._eventInput);
59.14793 +
59.14794 +        EventHandler.setInputHandler(this, this._eventInput);
59.14795 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.14796 +
59.14797 +        this._touchCount = 0;
59.14798 +        this._springState = 0;
59.14799 +        this._onEdge = 0; // -1 for top, 1 for bottom
59.14800 +        this._pageSpringPosition = 0;
59.14801 +        this._edgeSpringPosition = 0;
59.14802 +        this._touchVelocity = undefined;
59.14803 +        this._earlyEnd = false;
59.14804 +        this._needsPaginationCheck = false;
59.14805 +
59.14806 +        this._scroller = new Scroller();
59.14807 +        this._scroller.positionFrom(this.getPosition.bind(this));
59.14808 +
59.14809 +        this.setOptions(options);
59.14810 +
59.14811 +        _bindEvents.call(this);
59.14812 +    }
59.14813 +
59.14814 +    /** @const */
59.14815 +    var TOLERANCE = 0.5;
59.14816 +
59.14817 +    Scrollview.DEFAULT_OPTIONS = {
59.14818 +        direction: Utility.Direction.Y,
59.14819 +        rails: true,
59.14820 +        friction: 0.001,
59.14821 +        drag: 0.0001,
59.14822 +        edgeGrip: 0.5,
59.14823 +        edgePeriod: 300,
59.14824 +        edgeDamp: 1,
59.14825 +        margin: 1000,       // mostly safe
59.14826 +        paginated: false,
59.14827 +        pagePeriod: 500,
59.14828 +        pageDamp: 0.8,
59.14829 +        pageStopSpeed: 10,
59.14830 +        pageSwitchSpeed: 0.5,
59.14831 +        speedLimit: 10,
59.14832 +        groupScroll: false
59.14833 +    };
59.14834 +
59.14835 +    /** @enum */
59.14836 +    var SpringStates = {
59.14837 +        NONE: 0,
59.14838 +        EDGE: 1,
59.14839 +        PAGE: 2
59.14840 +    };
59.14841 +
59.14842 +    function _handleStart(event) {
59.14843 +        this._touchCount = event.count;
59.14844 +        if (event.count === undefined) this._touchCount = 1;
59.14845 +
59.14846 +        _detachAgents.call(this);
59.14847 +        this.setVelocity(0);
59.14848 +        this._touchVelocity = 0;
59.14849 +        this._earlyEnd = false;
59.14850 +    }
59.14851 +
59.14852 +    function _handleMove(event) {
59.14853 +        var velocity = -event.velocity;
59.14854 +        var delta = -event.delta;
59.14855 +
59.14856 +        if (this._onEdge && event.slip) {
59.14857 +            if ((velocity < 0 && this._onEdge < 0) || (velocity > 0 && this._onEdge > 0)) {
59.14858 +                if (!this._earlyEnd) {
59.14859 +                    _handleEnd.call(this, event);
59.14860 +                    this._earlyEnd = true;
59.14861 +                }
59.14862 +            }
59.14863 +            else if (this._earlyEnd && (Math.abs(velocity) > Math.abs(this.getVelocity()))) {
59.14864 +                _handleStart.call(this, event);
59.14865 +            }
59.14866 +        }
59.14867 +        if (this._earlyEnd) return;
59.14868 +        this._touchVelocity = velocity;
59.14869 +
59.14870 +        if (event.slip) this.setVelocity(velocity);
59.14871 +        else this.setPosition(this.getPosition() + delta);
59.14872 +    }
59.14873 +
59.14874 +    function _handleEnd(event) {
59.14875 +        this._touchCount = event.count || 0;
59.14876 +        if (!this._touchCount) {
59.14877 +            _detachAgents.call(this);
59.14878 +            if (this._onEdge) _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE);
59.14879 +            _attachAgents.call(this);
59.14880 +            var velocity = -event.velocity;
59.14881 +            var speedLimit = this.options.speedLimit;
59.14882 +            if (event.slip) speedLimit *= this.options.edgeGrip;
59.14883 +            if (velocity < -speedLimit) velocity = -speedLimit;
59.14884 +            else if (velocity > speedLimit) velocity = speedLimit;
59.14885 +            this.setVelocity(velocity);
59.14886 +            this._touchVelocity = undefined;
59.14887 +            this._needsPaginationCheck = true;
59.14888 +        }
59.14889 +    }
59.14890 +
59.14891 +    function _bindEvents() {
59.14892 +        this._eventInput.bindThis(this);
59.14893 +        this._eventInput.on('start', _handleStart);
59.14894 +        this._eventInput.on('update', _handleMove);
59.14895 +        this._eventInput.on('end', _handleEnd);
59.14896 +
59.14897 +        this._scroller.on('edgeHit', function(data) {
59.14898 +            this._edgeSpringPosition = data.position;
59.14899 +        }.bind(this));
59.14900 +    }
59.14901 +
59.14902 +    function _attachAgents() {
59.14903 +        if (this._springState) this._physicsEngine.attach([this.spring], this._particle);
59.14904 +        else this._physicsEngine.attach([this.drag, this.friction], this._particle);
59.14905 +    }
59.14906 +
59.14907 +    function _detachAgents() {
59.14908 +        this._springState = SpringStates.NONE;
59.14909 +        this._physicsEngine.detachAll();
59.14910 +    }
59.14911 +
59.14912 +    function _nodeSizeForDirection(node) {
59.14913 +        var direction = this.options.direction;
59.14914 +        var nodeSize = (node.getSize() || this._scroller.getSize())[direction];
59.14915 +        if (!nodeSize) nodeSize = this._scroller.getSize()[direction];
59.14916 +        return nodeSize;
59.14917 +    }
59.14918 +
59.14919 +    function _handleEdge(edgeDetected) {
59.14920 +        if (!this._onEdge && edgeDetected) {
59.14921 +            this.sync.setOptions({scale: this.options.edgeGrip});
59.14922 +            if (!this._touchCount && this._springState !== SpringStates.EDGE) {
59.14923 +                _setSpring.call(this, this._edgeSpringPosition, SpringStates.EDGE);
59.14924 +            }
59.14925 +        }
59.14926 +        else if (this._onEdge && !edgeDetected) {
59.14927 +            this.sync.setOptions({scale: 1});
59.14928 +            if (this._springState && Math.abs(this.getVelocity()) < 0.001) {
59.14929 +                // reset agents, detaching the spring
59.14930 +                _detachAgents.call(this);
59.14931 +                _attachAgents.call(this);
59.14932 +            }
59.14933 +        }
59.14934 +        this._onEdge = edgeDetected;
59.14935 +    }
59.14936 +
59.14937 +    function _handlePagination() {
59.14938 +        if (!this._needsPaginationCheck) return;
59.14939 +
59.14940 +        if (this._touchCount) return;
59.14941 +        if (this._springState === SpringStates.EDGE) return;
59.14942 +
59.14943 +        var velocity = this.getVelocity();
59.14944 +        if (Math.abs(velocity) >= this.options.pageStopSpeed) return;
59.14945 +
59.14946 +        var position = this.getPosition();
59.14947 +        var velocitySwitch = Math.abs(velocity) > this.options.pageSwitchSpeed;
59.14948 +
59.14949 +        // parameters to determine when to switch
59.14950 +        var nodeSize = _nodeSizeForDirection.call(this, this._node);
59.14951 +        var positionNext = position > 0.5 * nodeSize;
59.14952 +        var velocityNext = velocity > 0;
59.14953 +
59.14954 +        if ((positionNext && !velocitySwitch) || (velocitySwitch && velocityNext)) this.goToNextPage();
59.14955 +        else _setSpring.call(this, 0, SpringStates.PAGE);
59.14956 +
59.14957 +        this._needsPaginationCheck = false;
59.14958 +    }
59.14959 +
59.14960 +    function _setSpring(position, springState) {
59.14961 +        var springOptions;
59.14962 +        if (springState === SpringStates.EDGE) {
59.14963 +            this._edgeSpringPosition = position;
59.14964 +            springOptions = {
59.14965 +                anchor: [this._edgeSpringPosition, 0, 0],
59.14966 +                period: this.options.edgePeriod,
59.14967 +                dampingRatio: this.options.edgeDamp
59.14968 +            };
59.14969 +        }
59.14970 +        else if (springState === SpringStates.PAGE) {
59.14971 +            this._pageSpringPosition = position;
59.14972 +            springOptions = {
59.14973 +                anchor: [this._pageSpringPosition, 0, 0],
59.14974 +                period: this.options.pagePeriod,
59.14975 +                dampingRatio: this.options.pageDamp
59.14976 +            };
59.14977 +        }
59.14978 +
59.14979 +        this.spring.setOptions(springOptions);
59.14980 +        if (springState && !this._springState) {
59.14981 +            _detachAgents.call(this);
59.14982 +            this._springState = springState;
59.14983 +            _attachAgents.call(this);
59.14984 +        }
59.14985 +        this._springState = springState;
59.14986 +    }
59.14987 +
59.14988 +    function _normalizeState() {
59.14989 +        var position = this.getPosition();
59.14990 +        var nodeSize = _nodeSizeForDirection.call(this, this._node);
59.14991 +        var nextNode = this._node.getNext();
59.14992 +
59.14993 +        while (position > nodeSize + TOLERANCE && nextNode) {
59.14994 +            _shiftOrigin.call(this, -nodeSize);
59.14995 +            position -= nodeSize;
59.14996 +            this._scroller.sequenceFrom(nextNode);
59.14997 +            this._node = nextNode;
59.14998 +            nextNode = this._node.getNext();
59.14999 +            nodeSize = _nodeSizeForDirection.call(this, this._node);
59.15000 +        }
59.15001 +
59.15002 +        var previousNode = this._node.getPrevious();
59.15003 +        var previousNodeSize;
59.15004 +
59.15005 +        while (position < -TOLERANCE && previousNode) {
59.15006 +            previousNodeSize = _nodeSizeForDirection.call(this, previousNode);
59.15007 +            this._scroller.sequenceFrom(previousNode);
59.15008 +            this._node = previousNode;
59.15009 +            _shiftOrigin.call(this, previousNodeSize);
59.15010 +            position += previousNodeSize;
59.15011 +            previousNode = this._node.getPrevious();
59.15012 +        }
59.15013 +    }
59.15014 +
59.15015 +    function _shiftOrigin(amount) {
59.15016 +        this._edgeSpringPosition += amount;
59.15017 +        this._pageSpringPosition += amount;
59.15018 +        this.setPosition(this.getPosition() + amount);
59.15019 +        if (this._springState === SpringStates.EDGE) {
59.15020 +            this.spring.setOptions({anchor: [this._edgeSpringPosition, 0, 0]});
59.15021 +        }
59.15022 +        else if (this._springState === SpringStates.PAGE) {
59.15023 +            this.spring.setOptions({anchor: [this._pageSpringPosition, 0, 0]});
59.15024 +        }
59.15025 +    }
59.15026 +
59.15027 +    Scrollview.prototype.outputFrom = function outputFrom() {
59.15028 +        return this._scroller.outputFrom.apply(this._scroller, arguments);
59.15029 +    };
59.15030 +
59.15031 +    /**
59.15032 +     * Returns the position associated with the Scrollview instance's current node
59.15033 +     *  (generally the node currently at the top).
59.15034 +     * @method getPosition
59.15035 +     * @param {number} [node] If specified, returns the position of the node at that index in the
59.15036 +     * Scrollview instance's currently managed collection.
59.15037 +     * @return {number} The position of either the specified node, or the Scrollview's current Node,
59.15038 +     * in pixels translated.
59.15039 +     */
59.15040 +    Scrollview.prototype.getPosition = function getPosition() {
59.15041 +        return this._particle.getPosition1D();
59.15042 +    };
59.15043 +
59.15044 +    /**
59.15045 +     * Sets position of the physics particle that controls Scrollview instance's "position"
59.15046 +     * @method setPosition
59.15047 +     * @param {number} x The amount of pixels you want your scrollview to progress by.
59.15048 +     */
59.15049 +    Scrollview.prototype.setPosition = function setPosition(x) {
59.15050 +        this._particle.setPosition1D(x);
59.15051 +    };
59.15052 +
59.15053 +    /**
59.15054 +     * Returns the Scrollview instance's velocity.
59.15055 +     * @method getVelocity
59.15056 +     * @return {Number} The velocity.
59.15057 +     */
59.15058 +
59.15059 +    Scrollview.prototype.getVelocity = function getVelocity() {
59.15060 +        return this._touchCount ? this._touchVelocity : this._particle.getVelocity1D();
59.15061 +    };
59.15062 +
59.15063 +    /**
59.15064 +     * Sets the Scrollview instance's velocity. Until affected by input or another call of setVelocity
59.15065 +     *  the Scrollview instance will scroll at the passed-in velocity.
59.15066 +     * @method setVelocity
59.15067 +     * @param {number} v The magnitude of the velocity.
59.15068 +     */
59.15069 +    Scrollview.prototype.setVelocity = function setVelocity(v) {
59.15070 +        this._particle.setVelocity1D(v);
59.15071 +    };
59.15072 +
59.15073 +    /**
59.15074 +     * Patches the Scrollview instance's options with the passed-in ones.
59.15075 +     * @method setOptions
59.15076 +     * @param {Options} options An object of configurable options for the Scrollview instance.
59.15077 +     */
59.15078 +    Scrollview.prototype.setOptions = function setOptions(options) {
59.15079 +        if (options) {
59.15080 +            if (options.direction !== undefined) {
59.15081 +                if (options.direction === 'x') options.direction = Utility.Direction.X;
59.15082 +                else if (options.direction === 'y') options.direction = Utility.Direction.Y;
59.15083 +            }
59.15084 +
59.15085 +            this._scroller.setOptions(options);
59.15086 +            this._optionsManager.setOptions(options);
59.15087 +        }
59.15088 +
59.15089 +        this._scroller.setOptions(this.options);
59.15090 +        if (this.options.groupScroll)
59.15091 +            this._scroller.pipe(this._eventInput);
59.15092 +        else
59.15093 +            this._scroller.unpipe(this._eventInput);
59.15094 +
59.15095 +        this.drag.setOptions({strength: this.options.drag});
59.15096 +        this.friction.setOptions({strength: this.options.friction});
59.15097 +
59.15098 +        this.spring.setOptions({
59.15099 +            period: this.options.edgePeriod,
59.15100 +            dampingRatio: this.options.edgeDamp
59.15101 +        });
59.15102 +
59.15103 +        this.sync.setOptions({
59.15104 +            rails: this.options.rails,
59.15105 +            direction: (this.options.direction === Utility.Direction.X) ? GenericSync.DIRECTION_X : GenericSync.DIRECTION_Y
59.15106 +        });
59.15107 +    };
59.15108 +
59.15109 +    /**
59.15110 +     * goToPreviousPage paginates your Scrollview instance backwards by one item.
59.15111 +     * @method goToPreviousPage
59.15112 +     * @return {ViewSequence} The previous node.
59.15113 +     */
59.15114 +    Scrollview.prototype.goToPreviousPage = function goToPreviousPage() {
59.15115 +        if (!this._node) return null;
59.15116 +        var previousNode = this._node.getPrevious();
59.15117 +        if (previousNode) {
59.15118 +            var currentPosition = this.getPosition();
59.15119 +            var previousNodeSize = _nodeSizeForDirection.call(this, previousNode);
59.15120 +            this._scroller.sequenceFrom(previousNode);
59.15121 +            this._node = previousNode;
59.15122 +            var previousSpringPosition = (currentPosition < TOLERANCE) ? -previousNodeSize : 0;
59.15123 +            _setSpring.call(this, previousSpringPosition, SpringStates.PAGE);
59.15124 +            _shiftOrigin.call(this, previousNodeSize);
59.15125 +        }
59.15126 +        this._eventOutput.emit('pageChange', {direction: -1});
59.15127 +        return previousNode;
59.15128 +    };
59.15129 +
59.15130 +    /**
59.15131 +     * goToNextPage paginates your Scrollview instance forwards by one item.
59.15132 +     * @method goToNextPage
59.15133 +     * @return {ViewSequence} The next node.
59.15134 +     */
59.15135 +    Scrollview.prototype.goToNextPage = function goToNextPage() {
59.15136 +        if (!this._node) return null;
59.15137 +        var nextNode = this._node.getNext();
59.15138 +        if (nextNode) {
59.15139 +            var currentPosition = this.getPosition();
59.15140 +            var currentNodeSize = _nodeSizeForDirection.call(this, this._node);
59.15141 +            var nextNodeSize = _nodeSizeForDirection.call(this, nextNode);
59.15142 +            this._scroller.sequenceFrom(nextNode);
59.15143 +            this._node = nextNode;
59.15144 +            var nextSpringPosition = (currentPosition > currentNodeSize - TOLERANCE) ? currentNodeSize + nextNodeSize : currentNodeSize;
59.15145 +            _setSpring.call(this, nextSpringPosition, SpringStates.PAGE);
59.15146 +            _shiftOrigin.call(this, -currentNodeSize);
59.15147 +        }
59.15148 +        this._eventOutput.emit('pageChange', {direction: 1});
59.15149 +        return nextNode;
59.15150 +    };
59.15151 +
59.15152 +    /**
59.15153 +     * Sets the collection of renderables under the Scrollview instance's control, by
59.15154 +     *  setting its current node to the passed in ViewSequence. If you
59.15155 +     *  pass in an array, the Scrollview instance will set its node as a ViewSequence instantiated with
59.15156 +     *  the passed-in array.
59.15157 +     *
59.15158 +     * @method sequenceFrom
59.15159 +     * @param {Array|ViewSequence} node Either an array of renderables or a Famous viewSequence.
59.15160 +     */
59.15161 +    Scrollview.prototype.sequenceFrom = function sequenceFrom(node) {
59.15162 +        if (node instanceof Array) node = new ViewSequence({array: node});
59.15163 +        this._node = node;
59.15164 +        return this._scroller.sequenceFrom(node);
59.15165 +    };
59.15166 +
59.15167 +    /**
59.15168 +     * Returns the width and the height of the Scrollview instance.
59.15169 +     *
59.15170 +     * @method getSize
59.15171 +     * @return {Array} A two value array of the Scrollview instance's current width and height (in that order).
59.15172 +     */
59.15173 +    Scrollview.prototype.getSize = function getSize() {
59.15174 +        return this._scroller.getSize.apply(this._scroller, arguments);
59.15175 +    };
59.15176 +
59.15177 +    /**
59.15178 +     * Generate a render spec from the contents of this component.
59.15179 +     *
59.15180 +     * @private
59.15181 +     * @method render
59.15182 +     * @return {number} Render spec for this component
59.15183 +     */
59.15184 +    Scrollview.prototype.render = function render() {
59.15185 +        if (!this._node) return null;
59.15186 +
59.15187 +        _normalizeState.call(this);
59.15188 +        _handleEdge.call(this, this._scroller.onEdge());
59.15189 +        if (this.options.paginated) _handlePagination.call(this);
59.15190 +
59.15191 +        return this._scroller.render();
59.15192 +    };
59.15193 +
59.15194 +    module.exports = Scrollview;
59.15195 +});
59.15196 +
59.15197 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15198 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15199 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15200 + *
59.15201 + * Owner: felix@famo.us
59.15202 + * @license MPL 2.0
59.15203 + * @copyright Famous Industries, Inc. 2014
59.15204 + */
59.15205 +
59.15206 +define('famous/views/ScrollContainer',['require','exports','module','famous/surfaces/ContainerSurface','famous/core/EventHandler','./Scrollview','famous/utilities/Utility','famous/core/OptionsManager'],function(require, exports, module) {
59.15207 +    var ContainerSurface = require('famous/surfaces/ContainerSurface');
59.15208 +    var EventHandler = require('famous/core/EventHandler');
59.15209 +    var Scrollview = require('./Scrollview');
59.15210 +    var Utility = require('famous/utilities/Utility');
59.15211 +    var OptionsManager = require('famous/core/OptionsManager');
59.15212 +
59.15213 +    /**
59.15214 +     * A Container surface with a scrollview automatically added. The convenience of ScrollContainer lies in
59.15215 +     * being able to clip out portions of the associated scrollview that lie outside the bounding surface,
59.15216 +     * and in being able to move the scrollview more easily by applying modifiers to the parent container
59.15217 +     * surface.
59.15218 +     * @class ScrollContainer
59.15219 +     * @constructor
59.15220 +     * @param {Options} [options] An object of configurable options.
59.15221 +     * @param {Options} [options.container=undefined] Options for the ScrollContainer instance's surface.
59.15222 +     * @param {Options} [options.scrollview={direction:Utility.Direction.X}]  Options for the ScrollContainer instance's scrollview.
59.15223 +     */
59.15224 +    function ScrollContainer(options) {
59.15225 +        this.options = Object.create(ScrollContainer.DEFAULT_OPTIONS);
59.15226 +        this._optionsManager = new OptionsManager(this.options);
59.15227 +
59.15228 +        if (options) this.setOptions(options);
59.15229 +
59.15230 +        this.container = new ContainerSurface(this.options.container);
59.15231 +        this.scrollview = new Scrollview(this.options.scrollview);
59.15232 +
59.15233 +        this.container.add(this.scrollview);
59.15234 +
59.15235 +        EventHandler.setInputHandler(this, this.scrollview);
59.15236 +        EventHandler.setOutputHandler(this, this.scrollview);
59.15237 +        this.scrollview.subscribe(this.container);
59.15238 +    }
59.15239 +
59.15240 +    ScrollContainer.DEFAULT_OPTIONS = {
59.15241 +        container: {
59.15242 +            properties: {overflow : 'hidden'}
59.15243 +        },
59.15244 +        scrollview: {direction: Utility.Direction.X}
59.15245 +    };
59.15246 +
59.15247 +    /**
59.15248 +     * Patches the ScrollContainer instance's options with the passed-in ones.
59.15249 +     *
59.15250 +     * @method setOptions
59.15251 +     * @param {Options} options An object of configurable options for the ScrollContainer instance.
59.15252 +     */
59.15253 +    ScrollContainer.prototype.setOptions = function setOptions(options) {
59.15254 +        return this._optionsManager.setOptions(options);
59.15255 +    };
59.15256 +
59.15257 +    /**
59.15258 +     * Sets the collection of renderables under the ScrollContainer instance scrollview's control.
59.15259 +     *
59.15260 +     * @method sequenceFrom
59.15261 +     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous ViewSequence.
59.15262 +     */
59.15263 +    ScrollContainer.prototype.sequenceFrom = function sequenceFrom() {
59.15264 +        return this.scrollview.sequenceFrom.apply(this.scrollview, arguments);
59.15265 +    };
59.15266 +
59.15267 +    /**
59.15268 +     * Generate a render spec from the contents of this component.
59.15269 +     *
59.15270 +     * @private
59.15271 +     * @method render
59.15272 +     * @return {number} Render spec for this component
59.15273 +     */
59.15274 +    ScrollContainer.prototype.render = function render() {
59.15275 +        return this.container.render.apply(this.container, arguments);
59.15276 +    };
59.15277 +
59.15278 +    module.exports = ScrollContainer;
59.15279 +});
59.15280 +
59.15281 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15282 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15283 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15284 + *
59.15285 + * Owner: mark@famo.us
59.15286 + * @license MPL 2.0
59.15287 + * @copyright Famous Industries, Inc. 2014
59.15288 + */
59.15289 +
59.15290 +define('famous/widgets/NavigationBar',['require','exports','module','famous/core/Scene','famous/core/Surface','famous/core/Transform','famous/core/View'],function(require, exports, module) {
59.15291 +    var Scene = require('famous/core/Scene');
59.15292 +    var Surface = require('famous/core/Surface');
59.15293 +    var Transform = require('famous/core/Transform');
59.15294 +    var View = require('famous/core/View');
59.15295 +
59.15296 +    /**
59.15297 +     * A view for displaying the title of the current page
59.15298 +     *  as well as icons for navigating backwards and opening
59.15299 +     *  further options
59.15300 +     *
59.15301 +     * @class NavigationBar
59.15302 +     * @extends View
59.15303 +     * @constructor
59.15304 +     *
59.15305 +     * @param {object} [options] overrides of default options
59.15306 +     * @param {Array.number} [options.size=(undefined,0.5)] Size of the navigation bar and it's componenets.
59.15307 +     * @param {Array.string} [options.backClasses=(back)] CSS Classes attached to back of Navigation.
59.15308 +     * @param {String} [options.backContent=(&#x25c0;)] Content of the back button.
59.15309 +     * @param {Array.string} [options.classes=(navigation)] CSS Classes attached to the surfaces.
59.15310 +     * @param {String} [options.content] Content to pass into title bar.
59.15311 +     * @param {Array.string} [options.classes=(more)] CSS Classes attached to the More surface.
59.15312 +     * @param {String} [options.moreContent=(&#x271a;)] Content of the more button.
59.15313 +     */
59.15314 +    function NavigationBar(options) {
59.15315 +        View.apply(this, arguments);
59.15316 +
59.15317 +        this.title = new Surface({
59.15318 +            classes: this.options.classes,
59.15319 +            content: this.options.content
59.15320 +        });
59.15321 +
59.15322 +        this.back = new Surface({
59.15323 +            size: [this.options.size[1], this.options.size[1]],
59.15324 +            classes: this.options.classes,
59.15325 +            content: this.options.backContent
59.15326 +        });
59.15327 +        this.back.on('click', function() {
59.15328 +            this._eventOutput.emit('back', {});
59.15329 +        }.bind(this));
59.15330 +
59.15331 +        this.more = new Surface({
59.15332 +            size: [this.options.size[1], this.options.size[1]],
59.15333 +            classes: this.options.classes,
59.15334 +            content: this.options.moreContent
59.15335 +        });
59.15336 +        this.more.on('click', function() {
59.15337 +            this._eventOutput.emit('more', {});
59.15338 +        }.bind(this));
59.15339 +
59.15340 +        this.layout = new Scene({
59.15341 +            id: 'master',
59.15342 +            size: this.options.size,
59.15343 +            target: [
59.15344 +                {
59.15345 +                    transform: Transform.inFront,
59.15346 +                    origin: [0, 0.5],
59.15347 +                    target: this.back
59.15348 +                },
59.15349 +                {
59.15350 +                    origin: [0.5, 0.5],
59.15351 +                    target: this.title
59.15352 +                },
59.15353 +                {
59.15354 +                    transform: Transform.inFront,
59.15355 +                    origin: [1, 0.5],
59.15356 +                    target: this.more
59.15357 +                }
59.15358 +            ]
59.15359 +        });
59.15360 +
59.15361 +        this._add(this.layout);
59.15362 +
59.15363 +        this._optionsManager.on('change', function(event) {
59.15364 +            var key = event.id;
59.15365 +            var data = event.value;
59.15366 +            if (key === 'size') {
59.15367 +                this.layout.id.master.setSize(data);
59.15368 +                this.title.setSize(data);
59.15369 +                this.back.setSize([data[1], data[1]]);
59.15370 +                this.more.setSize([data[1], data[1]]);
59.15371 +            }
59.15372 +            else if (key === 'backClasses') {
59.15373 +                this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)});
59.15374 +            }
59.15375 +            else if (key === 'backContent') {
59.15376 +                this.back.setContent(this.options.backContent);
59.15377 +            }
59.15378 +            else if (key === 'classes') {
59.15379 +                this.title.setOptions({classes: this.options.classes});
59.15380 +                this.back.setOptions({classes: this.options.classes.concat(this.options.backClasses)});
59.15381 +                this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)});
59.15382 +            }
59.15383 +            else if (key === 'content') {
59.15384 +                this.setContent(this.options.content);
59.15385 +            }
59.15386 +            else if (key === 'moreClasses') {
59.15387 +                this.more.setOptions({classes: this.options.classes.concat(this.options.moreClasses)});
59.15388 +            }
59.15389 +            else if (key === 'moreContent') {
59.15390 +                this.more.setContent(this.options.content);
59.15391 +            }
59.15392 +        }.bind(this));
59.15393 +    }
59.15394 +
59.15395 +    NavigationBar.prototype = Object.create(View.prototype);
59.15396 +    NavigationBar.prototype.constructor = NavigationBar;
59.15397 +
59.15398 +    NavigationBar.DEFAULT_OPTIONS = {
59.15399 +        size: [undefined, 50],
59.15400 +        backClasses: ['back'],
59.15401 +        backContent: '&#x25c0;',
59.15402 +        classes: ['navigation'],
59.15403 +        content: '',
59.15404 +        moreClasses: ['more'],
59.15405 +        moreContent: '&#x271a;'
59.15406 +    };
59.15407 +
59.15408 +    /**
59.15409 +     * Set the title of the NavigationBar
59.15410 +     *
59.15411 +     * @method setContent
59.15412 +     *
59.15413 +     * @param {object} content JSON object containing title information
59.15414 +     *
59.15415 +     * @return {undefined}
59.15416 +     */
59.15417 +    NavigationBar.prototype.setContent = function setContent(content) {
59.15418 +        return this.title.setContent(content);
59.15419 +    };
59.15420 +
59.15421 +    module.exports = NavigationBar;
59.15422 +});
59.15423 +
59.15424 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15425 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15426 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15427 + *
59.15428 + * Owner: mark@famo.us
59.15429 + * @license MPL 2.0
59.15430 + * @copyright Famous Industries, Inc. 2014
59.15431 + */
59.15432 +
59.15433 +define('famous/widgets/Slider',['require','exports','module','famous/core/Surface','famous/surfaces/CanvasSurface','famous/core/Transform','famous/core/EventHandler','famous/math/Utilities','famous/core/OptionsManager','famous/inputs/MouseSync','famous/inputs/TouchSync','famous/inputs/GenericSync'],function(require, exports, module) {
59.15434 +    var Surface = require('famous/core/Surface');
59.15435 +    var CanvasSurface = require('famous/surfaces/CanvasSurface');
59.15436 +    var Transform = require('famous/core/Transform');
59.15437 +    var EventHandler = require('famous/core/EventHandler');
59.15438 +    var Utilities = require('famous/math/Utilities');
59.15439 +    var OptionsManager = require('famous/core/OptionsManager');
59.15440 +
59.15441 +    var MouseSync = require('famous/inputs/MouseSync');
59.15442 +    var TouchSync = require('famous/inputs/TouchSync');
59.15443 +    var GenericSync = require('famous/inputs/GenericSync');
59.15444 +
59.15445 +    GenericSync.register({
59.15446 +        mouse : MouseSync,
59.15447 +        touch : TouchSync
59.15448 +    });
59.15449 +
59.15450 +    /** @constructor */
59.15451 +    function Slider(options) {
59.15452 +        this.options = Object.create(Slider.DEFAULT_OPTIONS);
59.15453 +        this.optionsManager = new OptionsManager(this.options);
59.15454 +        if (options) this.setOptions(options);
59.15455 +
59.15456 +        this.indicator = new CanvasSurface({
59.15457 +            size: this.options.indicatorSize,
59.15458 +            classes : ['slider-back']
59.15459 +        });
59.15460 +
59.15461 +        this.label = new Surface({
59.15462 +            size: this.options.labelSize,
59.15463 +            content: this.options.label,
59.15464 +            properties : {pointerEvents : 'none'},
59.15465 +            classes: ['slider-label']
59.15466 +        });
59.15467 +
59.15468 +        this.eventOutput = new EventHandler();
59.15469 +        this.eventInput = new EventHandler();
59.15470 +        EventHandler.setInputHandler(this, this.eventInput);
59.15471 +        EventHandler.setOutputHandler(this, this.eventOutput);
59.15472 +
59.15473 +        var scale = (this.options.range[1] - this.options.range[0]) / this.options.indicatorSize[0];
59.15474 +
59.15475 +        this.sync = new GenericSync(
59.15476 +            ['mouse', 'touch'],
59.15477 +            {
59.15478 +                scale : scale,
59.15479 +                direction : GenericSync.DIRECTION_X
59.15480 +            }
59.15481 +        );
59.15482 +
59.15483 +        this.indicator.pipe(this.sync);
59.15484 +        this.sync.pipe(this);
59.15485 +
59.15486 +        this.eventInput.on('update', function(data) {
59.15487 +            this.set(data.position);
59.15488 +        }.bind(this));
59.15489 +
59.15490 +        this._drawPos = 0;
59.15491 +        _updateLabel.call(this);
59.15492 +    }
59.15493 +
59.15494 +    Slider.DEFAULT_OPTIONS = {
59.15495 +        size: [200, 60],
59.15496 +        indicatorSize: [200, 30],
59.15497 +        labelSize: [200, 30],
59.15498 +        range: [0, 1],
59.15499 +        precision: 2,
59.15500 +        value: 0,
59.15501 +        label: '',
59.15502 +        fillColor: 'rgba(170, 170, 170, 1)'
59.15503 +    };
59.15504 +
59.15505 +    function _updateLabel() {
59.15506 +        this.label.setContent(this.options.label + '<span style="float: right">' + this.get().toFixed(this.options.precision) + '</span>');
59.15507 +    }
59.15508 +
59.15509 +    Slider.prototype.setOptions = function setOptions(options) {
59.15510 +        return this.optionsManager.setOptions(options);
59.15511 +    };
59.15512 +
59.15513 +    Slider.prototype.get = function get() {
59.15514 +        return this.options.value;
59.15515 +    };
59.15516 +
59.15517 +    Slider.prototype.set = function set(value) {
59.15518 +        if (value === this.options.value) return;
59.15519 +        this.options.value = Utilities.clamp(value, this.options.range);
59.15520 +        _updateLabel.call(this);
59.15521 +        this.eventOutput.emit('change', {value: value});
59.15522 +    };
59.15523 +
59.15524 +    Slider.prototype.getSize = function getSize() {
59.15525 +        return this.options.size;
59.15526 +    };
59.15527 +
59.15528 +    Slider.prototype.render = function render() {
59.15529 +        var range = this.options.range;
59.15530 +        var fillSize = Math.floor(((this.get() - range[0]) / (range[1] - range[0])) * this.options.indicatorSize[0]);
59.15531 +
59.15532 +        if (fillSize < this._drawPos) {
59.15533 +            this.indicator.getContext('2d').clearRect(fillSize, 0, this._drawPos - fillSize + 1, this.options.indicatorSize[1]);
59.15534 +        }
59.15535 +        else if (fillSize > this._drawPos) {
59.15536 +            var ctx = this.indicator.getContext('2d');
59.15537 +            ctx.fillStyle = this.options.fillColor;
59.15538 +            ctx.fillRect(this._drawPos-1, 0, fillSize - this._drawPos+1, this.options.indicatorSize[1]);
59.15539 +        }
59.15540 +        this._drawPos = fillSize;
59.15541 +
59.15542 +        return {
59.15543 +            size: this.options.size,
59.15544 +            target: [
59.15545 +                {
59.15546 +                    origin: [0, 0],
59.15547 +                    target: this.indicator.render()
59.15548 +                },
59.15549 +                {
59.15550 +                    transform: Transform.translate(0, 0, 1),
59.15551 +                    origin: [0, 0],
59.15552 +                    target: this.label.render()
59.15553 +                }
59.15554 +            ]
59.15555 +        };
59.15556 +    };
59.15557 +
59.15558 +    module.exports = Slider;
59.15559 +});
59.15560 +
59.15561 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15562 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15563 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15564 + *
59.15565 + * Owner: mark@famo.us
59.15566 + * @license MPL 2.0
59.15567 + * @copyright Famous Industries, Inc. 2014
59.15568 + */
59.15569 +
59.15570 +define('famous/widgets/ToggleButton',['require','exports','module','famous/core/Surface','famous/core/EventHandler','famous/views/RenderController'],function(require, exports, module) {
59.15571 +    var Surface = require('famous/core/Surface');
59.15572 +    var EventHandler = require('famous/core/EventHandler');
59.15573 +    var RenderController = require('famous/views/RenderController');
59.15574 +
59.15575 +    /**
59.15576 +     * A view for transitioning between two surfaces based
59.15577 +     *  on a 'on' and 'off' state
59.15578 +     *
59.15579 +     * @class TabBar
59.15580 +     * @extends View
59.15581 +     * @constructor
59.15582 +     *
59.15583 +     * @param {object} options overrides of default options
59.15584 +     */
59.15585 +    function ToggleButton(options) {
59.15586 +        this.options = {
59.15587 +            content: '',
59.15588 +            offClasses: ['off'],
59.15589 +            onClasses: ['on'],
59.15590 +            size: undefined,
59.15591 +            outTransition: {curve: 'easeInOut', duration: 300},
59.15592 +            inTransition: {curve: 'easeInOut', duration: 300},
59.15593 +            toggleMode: ToggleButton.TOGGLE,
59.15594 +            crossfade: true
59.15595 +        };
59.15596 +
59.15597 +        this._eventOutput = new EventHandler();
59.15598 +        EventHandler.setOutputHandler(this, this._eventOutput);
59.15599 +
59.15600 +        this.offSurface = new Surface();
59.15601 +        this.offSurface.on('click', function() {
59.15602 +            if (this.options.toggleMode !== ToggleButton.OFF) this.select();
59.15603 +        }.bind(this));
59.15604 +        this.offSurface.pipe(this._eventOutput);
59.15605 +
59.15606 +        this.onSurface = new Surface();
59.15607 +        this.onSurface.on('click', function() {
59.15608 +            if (this.options.toggleMode !== ToggleButton.ON) this.deselect();
59.15609 +        }.bind(this));
59.15610 +        this.onSurface.pipe(this._eventOutput);
59.15611 +
59.15612 +        this.arbiter = new RenderController({
59.15613 +            overlap : this.options.crossfade
59.15614 +        });
59.15615 +
59.15616 +        this.deselect();
59.15617 +
59.15618 +        if (options) this.setOptions(options);
59.15619 +    }
59.15620 +
59.15621 +    ToggleButton.OFF = 0;
59.15622 +    ToggleButton.ON = 1;
59.15623 +    ToggleButton.TOGGLE = 2;
59.15624 +
59.15625 +    /**
59.15626 +     * Transition towards the 'on' state and dispatch an event to
59.15627 +     *  listeners to announce it was selected
59.15628 +     *
59.15629 +     * @method select
59.15630 +     */
59.15631 +    ToggleButton.prototype.select = function select() {
59.15632 +        this.selected = true;
59.15633 +        this.arbiter.show(this.onSurface, this.options.inTransition);
59.15634 +//        this.arbiter.setMode(ToggleButton.ON, this.options.inTransition);
59.15635 +        this._eventOutput.emit('select');
59.15636 +    };
59.15637 +
59.15638 +    /**
59.15639 +     * Transition towards the 'off' state and dispatch an event to
59.15640 +     *  listeners to announce it was deselected
59.15641 +     *
59.15642 +     * @method deselect
59.15643 +     */
59.15644 +    ToggleButton.prototype.deselect = function deselect() {
59.15645 +        this.selected = false;
59.15646 +        this.arbiter.show(this.offSurface, this.options.outTransition);
59.15647 +        this._eventOutput.emit('deselect');
59.15648 +    };
59.15649 +
59.15650 +    /**
59.15651 +     * Return the state of the button
59.15652 +     *
59.15653 +     * @method isSelected
59.15654 +     *
59.15655 +     * @return {boolean} selected state
59.15656 +     */
59.15657 +    ToggleButton.prototype.isSelected = function isSelected() {
59.15658 +        return this.selected;
59.15659 +    };
59.15660 +
59.15661 +    /**
59.15662 +     * Override the current options
59.15663 +     *
59.15664 +     * @method setOptions
59.15665 +     *
59.15666 +     * @param {object} options JSON
59.15667 +     */
59.15668 +    ToggleButton.prototype.setOptions = function setOptions(options) {
59.15669 +        if (options.content !== undefined) {
59.15670 +            this.options.content = options.content;
59.15671 +            this.offSurface.setContent(this.options.content);
59.15672 +            this.onSurface.setContent(this.options.content);
59.15673 +        }
59.15674 +        if (options.offClasses) {
59.15675 +            this.options.offClasses = options.offClasses;
59.15676 +            this.offSurface.setClasses(this.options.offClasses);
59.15677 +        }
59.15678 +        if (options.onClasses) {
59.15679 +            this.options.onClasses = options.onClasses;
59.15680 +            this.onSurface.setClasses(this.options.onClasses);
59.15681 +        }
59.15682 +        if (options.size !== undefined) {
59.15683 +            this.options.size = options.size;
59.15684 +            this.onSurface.setSize(this.options.size);
59.15685 +            this.offSurface.setSize(this.options.size);
59.15686 +        }
59.15687 +        if (options.toggleMode !== undefined) this.options.toggleMode = options.toggleMode;
59.15688 +        if (options.outTransition !== undefined) this.options.outTransition = options.outTransition;
59.15689 +        if (options.inTransition !== undefined) this.options.inTransition = options.inTransition;
59.15690 +        if (options.crossfade !== undefined) {
59.15691 +            this.options.crossfade = options.crossfade;
59.15692 +            this.arbiter.setOptions({overlap: this.options.crossfade});
59.15693 +        }
59.15694 +    };
59.15695 +
59.15696 +    /**
59.15697 +     * Return the size defined in the options object
59.15698 +     *
59.15699 +     * @method getSize
59.15700 +     *
59.15701 +     * @return {array} two element array [height, width]
59.15702 +     */
59.15703 +    ToggleButton.prototype.getSize = function getSize() {
59.15704 +        return this.options.size;
59.15705 +    };
59.15706 +
59.15707 +    /**
59.15708 +     * Generate a render spec from the contents of this component.
59.15709 +     *
59.15710 +     * @private
59.15711 +     * @method render
59.15712 +     * @return {number} Render spec for this component
59.15713 +     */
59.15714 +    ToggleButton.prototype.render = function render() {
59.15715 +        return this.arbiter.render();
59.15716 +    };
59.15717 +
59.15718 +    module.exports = ToggleButton;
59.15719 +});
59.15720 +
59.15721 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15722 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15723 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15724 + *
59.15725 + * Owner: mark@famo.us
59.15726 + * @license MPL 2.0
59.15727 + * @copyright Famous Industries, Inc. 2014
59.15728 + */
59.15729 +
59.15730 +define('famous/widgets/TabBar',['require','exports','module','famous/utilities/Utility','famous/core/View','famous/views/GridLayout','./ToggleButton'],function(require, exports, module) {
59.15731 +    var Utility = require('famous/utilities/Utility');
59.15732 +    var View = require('famous/core/View');
59.15733 +    var GridLayout = require('famous/views/GridLayout');
59.15734 +    var ToggleButton = require('./ToggleButton');
59.15735 +
59.15736 +    /**
59.15737 +     * A view for displaying various tabs that dispatch events
59.15738 +     *  based on the id of the button that was clicked
59.15739 +     *
59.15740 +     * @class TabBar
59.15741 +     * @extends View
59.15742 +     * @constructor
59.15743 +     *
59.15744 +     * @param {object} options overrides of default options
59.15745 +     */
59.15746 +    function TabBar(options) {
59.15747 +        View.apply(this, arguments);
59.15748 +
59.15749 +        this.layout = new GridLayout();
59.15750 +        this.buttons = [];
59.15751 +        this._buttonIds = {};
59.15752 +        this._buttonCallbacks = {};
59.15753 +
59.15754 +        this.layout.sequenceFrom(this.buttons);
59.15755 +        this._add(this.layout);
59.15756 +
59.15757 +        this._optionsManager.on('change', _updateOptions.bind(this));
59.15758 +    }
59.15759 +
59.15760 +    TabBar.prototype = Object.create(View.prototype);
59.15761 +    TabBar.prototype.constructor = TabBar;
59.15762 +
59.15763 +    TabBar.DEFAULT_OPTIONS = {
59.15764 +        sections: [],
59.15765 +        widget: ToggleButton,
59.15766 +        size: [undefined, 50],
59.15767 +        direction: Utility.Direction.X,
59.15768 +        buttons: {
59.15769 +            toggleMode: ToggleButton.ON
59.15770 +        }
59.15771 +    };
59.15772 +
59.15773 +    /**
59.15774 +     * Update the options for all components of the view
59.15775 +     *
59.15776 +     * @method _updateOptions
59.15777 +     *
59.15778 +     * @param {object} data component options
59.15779 +     */
59.15780 +    function _updateOptions(data) {
59.15781 +        var id = data.id;
59.15782 +        var value = data.value;
59.15783 +
59.15784 +        if (id === 'direction') {
59.15785 +            this.layout.setOptions({dimensions: _resolveGridDimensions.call(this.buttons.length, this.options.direction)});
59.15786 +        }
59.15787 +        else if (id === 'buttons') {
59.15788 +            for (var i in this.buttons) {
59.15789 +                this.buttons[i].setOptions(value);
59.15790 +            }
59.15791 +        }
59.15792 +        else if (id === 'sections') {
59.15793 +            for (var sectionId in this.options.sections) {
59.15794 +                this.defineSection(sectionId, this.options.sections[sectionId]);
59.15795 +            }
59.15796 +        }
59.15797 +    }
59.15798 +
59.15799 +    /**
59.15800 +     * Return an array of the proper dimensions for the tabs
59.15801 +     *
59.15802 +     * @method _resolveGridDimensions
59.15803 +     *
59.15804 +     * @param {number} count number of buttons
59.15805 +     * @param {number} direction direction of the layout
59.15806 +     *
59.15807 +     * @return {array} the dimensions of the tab section
59.15808 +     */
59.15809 +    function _resolveGridDimensions(count, direction) {
59.15810 +        if (direction === Utility.Direction.X) return [count, 1];
59.15811 +        else return [1, count];
59.15812 +    }
59.15813 +
59.15814 +    /**
59.15815 +     * Create a new button with the specified id.  If one already exists with
59.15816 +     *  that id, unbind all listeners.
59.15817 +     *
59.15818 +     * @method defineSection
59.15819 +     *
59.15820 +     * @param {string} id name of the button
59.15821 +     * @param {object} content data for the creation of a new ToggleButton
59.15822 +     */
59.15823 +    TabBar.prototype.defineSection = function defineSection(id, content) {
59.15824 +        var button;
59.15825 +        var i = this._buttonIds[id];
59.15826 +
59.15827 +        if (i === undefined) {
59.15828 +            i = this.buttons.length;
59.15829 +            this._buttonIds[id] = i;
59.15830 +            var widget = this.options.widget;
59.15831 +            button = new widget();
59.15832 +            this.buttons[i] = button;
59.15833 +            this.layout.setOptions({dimensions: _resolveGridDimensions(this.buttons.length, this.options.direction)});
59.15834 +        }
59.15835 +        else {
59.15836 +            button = this.buttons[i];
59.15837 +            button.unbind('select', this._buttonCallbacks[id]);
59.15838 +        }
59.15839 +
59.15840 +        if (this.options.buttons) button.setOptions(this.options.buttons);
59.15841 +        button.setOptions(content);
59.15842 +
59.15843 +        this._buttonCallbacks[id] = this.select.bind(this, id);
59.15844 +        button.on('select', this._buttonCallbacks[id]);
59.15845 +    };
59.15846 +
59.15847 +    /**
59.15848 +     * Select a particular button and dispatch the id of the selection
59.15849 +     *  to any listeners.  Deselect all others
59.15850 +     *
59.15851 +     * @method select
59.15852 +     *
59.15853 +     * @param {string} id button id
59.15854 +     */
59.15855 +    TabBar.prototype.select = function select(id) {
59.15856 +        var btn = this._buttonIds[id];
59.15857 +        // this prevents event loop
59.15858 +        if (this.buttons[btn] && this.buttons[btn].isSelected()) {
59.15859 +            this._eventOutput.emit('select', {id: id});
59.15860 +        }
59.15861 +        else if (this.buttons[btn]) {
59.15862 +            this.buttons[btn].select();
59.15863 +        }
59.15864 +
59.15865 +        for (var i = 0; i < this.buttons.length; i++) {
59.15866 +            if (i !== btn) this.buttons[i].deselect();
59.15867 +        }
59.15868 +    };
59.15869 +
59.15870 +    module.exports = TabBar;
59.15871 +});
59.15872 +
59.15873 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.15874 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.15875 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.15876 + *
59.15877 + * Owner: david@famo.us
59.15878 + * @license MPL 2.0
59.15879 + * @copyright Famous Industries, Inc. 2014
59.15880 + */
59.15881 +
59.15882 +define('famous/physics/bodies/Body',['require','exports','module','./Particle','famous/core/Transform','famous/math/Vector','famous/math/Quaternion','famous/math/Matrix'],function(require, exports, module) {
59.15883 +    var Particle = require('./Particle');
59.15884 +    var Transform = require('famous/core/Transform');
59.15885 +    var Vector = require('famous/math/Vector');
59.15886 +    var Quaternion = require('famous/math/Quaternion');
59.15887 +    var Matrix = require('famous/math/Matrix');
59.15888 +
59.15889 +    /**
59.15890 +     * A unit controlled by the physics engine which extends the zero-dimensional
59.15891 +     * Particle to include geometry. In addition to maintaining the state
59.15892 +     * of a Particle its state includes orientation, angular velocity
59.15893 +     * and angular momentum and responds to torque forces.
59.15894 +     *
59.15895 +     * @class Body
59.15896 +     * @extends Particle
59.15897 +     * @constructor
59.15898 +     */
59.15899 +    function Body(options) {
59.15900 +        Particle.call(this, options);
59.15901 +        options = options || {};
59.15902 +
59.15903 +        this.orientation     = new Quaternion();
59.15904 +        this.angularVelocity = new Vector();
59.15905 +        this.angularMomentum = new Vector();
59.15906 +        this.torque          = new Vector();
59.15907 +
59.15908 +        if (options.orientation)     this.orientation.set(options.orientation);
59.15909 +        if (options.angularVelocity) this.angularVelocity.set(options.angularVelocity);
59.15910 +        if (options.angularMomentum) this.angularMomentum.set(options.angularMomentum);
59.15911 +        if (options.torque)          this.torque.set(options.torque);
59.15912 +
59.15913 +        this.setMomentsOfInertia();
59.15914 +
59.15915 +        this.angularVelocity.w = 0;        //quaternify the angular velocity
59.15916 +
59.15917 +        //registers
59.15918 +        this.pWorld = new Vector();        //placeholder for world space position
59.15919 +    }
59.15920 +
59.15921 +    Body.DEFAULT_OPTIONS = Particle.DEFAULT_OPTIONS;
59.15922 +    Body.DEFAULT_OPTIONS.orientation = [0,0,0,1];
59.15923 +    Body.DEFAULT_OPTIONS.angularVelocity = [0,0,0];
59.15924 +
59.15925 +    Body.AXES = Particle.AXES;
59.15926 +    Body.SLEEP_TOLERANCE = Particle.SLEEP_TOLERANCE;
59.15927 +    Body.INTEGRATOR = Particle.INTEGRATOR;
59.15928 +
59.15929 +    Body.prototype = Object.create(Particle.prototype);
59.15930 +    Body.prototype.constructor = Body;
59.15931 +
59.15932 +    Body.prototype.isBody = true;
59.15933 +
59.15934 +    Body.prototype.setMass = function setMass() {
59.15935 +        Particle.prototype.setMass.apply(this, arguments);
59.15936 +        this.setMomentsOfInertia();
59.15937 +    };
59.15938 +
59.15939 +    /**
59.15940 +     * Setter for moment of inertia, which is necessary to give proper
59.15941 +     * angular inertia depending on the geometry of the body.
59.15942 +     *
59.15943 +     * @method setMomentsOfInertia
59.15944 +     */
59.15945 +    Body.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
59.15946 +        this.inertia = new Matrix();
59.15947 +        this.inverseInertia = new Matrix();
59.15948 +    };
59.15949 +
59.15950 +    /**
59.15951 +     * Update the angular velocity from the angular momentum state.
59.15952 +     *
59.15953 +     * @method updateAngularVelocity
59.15954 +     */
59.15955 +    Body.prototype.updateAngularVelocity = function updateAngularVelocity() {
59.15956 +        this.angularVelocity.set(this.inverseInertia.vectorMultiply(this.angularMomentum));
59.15957 +    };
59.15958 +
59.15959 +    /**
59.15960 +     * Determine world coordinates from the local coordinate system. Useful
59.15961 +     * if the Body has rotated in space.
59.15962 +     *
59.15963 +     * @method toWorldCoordinates
59.15964 +     * @param localPosition {Vector} local coordinate vector
59.15965 +     * @return global coordinate vector {Vector}
59.15966 +     */
59.15967 +    Body.prototype.toWorldCoordinates = function toWorldCoordinates(localPosition) {
59.15968 +        return this.pWorld.set(this.orientation.rotateVector(localPosition));
59.15969 +    };
59.15970 +
59.15971 +    /**
59.15972 +     * Calculates the kinetic and intertial energy of a body.
59.15973 +     *
59.15974 +     * @method getEnergy
59.15975 +     * @return energy {Number}
59.15976 +     */
59.15977 +    Body.prototype.getEnergy = function getEnergy() {
59.15978 +        return Particle.prototype.getEnergy.call(this)
59.15979 +            + 0.5 * this.inertia.vectorMultiply(this.angularVelocity).dot(this.angularVelocity);
59.15980 +    };
59.15981 +
59.15982 +    /**
59.15983 +     * Extends Particle.reset to reset orientation, angular velocity
59.15984 +     * and angular momentum.
59.15985 +     *
59.15986 +     * @method reset
59.15987 +     * @param [p] {Array|Vector} position
59.15988 +     * @param [v] {Array|Vector} velocity
59.15989 +     * @param [q] {Array|Quaternion} orientation
59.15990 +     * @param [L] {Array|Vector} angular momentum
59.15991 +     */
59.15992 +    Body.prototype.reset = function reset(p, v, q, L) {
59.15993 +        Particle.prototype.reset.call(this, p, v);
59.15994 +        this.angularVelocity.clear();
59.15995 +        this.setOrientation(q || [1,0,0,0]);
59.15996 +        this.setAngularMomentum(L || [0,0,0]);
59.15997 +    };
59.15998 +
59.15999 +    /**
59.16000 +     * Setter for orientation
59.16001 +     *
59.16002 +     * @method setOrientation
59.16003 +     * @param q {Array|Quaternion} orientation
59.16004 +     */
59.16005 +    Body.prototype.setOrientation = function setOrientation(q) {
59.16006 +        this.orientation.set(q);
59.16007 +    };
59.16008 +
59.16009 +    /**
59.16010 +     * Setter for angular velocity
59.16011 +     *
59.16012 +     * @method setAngularVelocity
59.16013 +     * @param w {Array|Vector} angular velocity
59.16014 +     */
59.16015 +    Body.prototype.setAngularVelocity = function setAngularVelocity(w) {
59.16016 +        this.wake();
59.16017 +        this.angularVelocity.set(w);
59.16018 +    };
59.16019 +
59.16020 +    /**
59.16021 +     * Setter for angular momentum
59.16022 +     *
59.16023 +     * @method setAngularMomentum
59.16024 +     * @param L {Array|Vector} angular momentum
59.16025 +     */
59.16026 +    Body.prototype.setAngularMomentum = function setAngularMomentum(L) {
59.16027 +        this.wake();
59.16028 +        this.angularMomentum.set(L);
59.16029 +    };
59.16030 +
59.16031 +    /**
59.16032 +     * Extends Particle.applyForce with an optional argument
59.16033 +     * to apply the force at an off-centered location, resulting in a torque.
59.16034 +     *
59.16035 +     * @method applyForce
59.16036 +     * @param force {Vector} force
59.16037 +     * @param [location] {Vector} off-center location on the body
59.16038 +     */
59.16039 +    Body.prototype.applyForce = function applyForce(force, location) {
59.16040 +        Particle.prototype.applyForce.call(this, force);
59.16041 +        if (location !== undefined) this.applyTorque(location.cross(force));
59.16042 +    };
59.16043 +
59.16044 +    /**
59.16045 +     * Applied a torque force to a body, inducing a rotation.
59.16046 +     *
59.16047 +     * @method applyTorque
59.16048 +     * @param torque {Vector} torque
59.16049 +     */
59.16050 +    Body.prototype.applyTorque = function applyTorque(torque) {
59.16051 +        this.wake();
59.16052 +        this.torque.set(this.torque.add(torque));
59.16053 +    };
59.16054 +
59.16055 +    /**
59.16056 +     * Extends Particle.getTransform to include a rotational component
59.16057 +     * derived from the particle's orientation.
59.16058 +     *
59.16059 +     * @method getTransform
59.16060 +     * @return transform {Transform}
59.16061 +     */
59.16062 +    Body.prototype.getTransform = function getTransform() {
59.16063 +        return Transform.thenMove(
59.16064 +            this.orientation.getTransform(),
59.16065 +            Transform.getTranslate(Particle.prototype.getTransform.call(this))
59.16066 +        );
59.16067 +    };
59.16068 +
59.16069 +    /**
59.16070 +     * Extends Particle._integrate to also update the rotational states
59.16071 +     * of the body.
59.16072 +     *
59.16073 +     * @method getTransform
59.16074 +     * @protected
59.16075 +     * @param dt {Number} delta time
59.16076 +     */
59.16077 +    Body.prototype._integrate = function _integrate(dt) {
59.16078 +        Particle.prototype._integrate.call(this, dt);
59.16079 +        this.integrateAngularMomentum(dt);
59.16080 +        this.updateAngularVelocity(dt);
59.16081 +        this.integrateOrientation(dt);
59.16082 +    };
59.16083 +
59.16084 +    /**
59.16085 +     * Updates the angular momentum via the its integrator.
59.16086 +     *
59.16087 +     * @method integrateAngularMomentum
59.16088 +     * @param dt {Number} delta time
59.16089 +     */
59.16090 +    Body.prototype.integrateAngularMomentum = function integrateAngularMomentum(dt) {
59.16091 +        Body.INTEGRATOR.integrateAngularMomentum(this, dt);
59.16092 +    };
59.16093 +
59.16094 +    /**
59.16095 +     * Updates the orientation via the its integrator.
59.16096 +     *
59.16097 +     * @method integrateOrientation
59.16098 +     * @param dt {Number} delta time
59.16099 +     */
59.16100 +    Body.prototype.integrateOrientation = function integrateOrientation(dt) {
59.16101 +        Body.INTEGRATOR.integrateOrientation(this, dt);
59.16102 +    };
59.16103 +
59.16104 +    module.exports = Body;
59.16105 +});
59.16106 +
59.16107 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16108 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16109 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16110 + *
59.16111 + * Owner: david@famo.us
59.16112 + * @license MPL 2.0
59.16113 + * @copyright Famous Industries, Inc. 2014
59.16114 + */
59.16115 +
59.16116 +define('famous/physics/bodies/Circle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) {
59.16117 +    var Body = require('./Body');
59.16118 +    var Matrix = require('famous/math/Matrix');
59.16119 +
59.16120 +    /**
59.16121 +     * Implements a circle, or spherical, geometry for an Body with
59.16122 +     * radius.
59.16123 +     *
59.16124 +     * @class Circle
59.16125 +     * @extends Body
59.16126 +     * @constructor
59.16127 +     */
59.16128 +    function Circle(options) {
59.16129 +        options = options || {};
59.16130 +        this.setRadius(options.radius || 0);
59.16131 +        Body.call(this, options);
59.16132 +    }
59.16133 +
59.16134 +    Circle.prototype = Object.create(Body.prototype);
59.16135 +    Circle.prototype.constructor = Circle;
59.16136 +
59.16137 +    /**
59.16138 +     * Basic setter for radius.
59.16139 +     * @method setRadius
59.16140 +     * @param r {Number} radius
59.16141 +     */
59.16142 +    Circle.prototype.setRadius = function setRadius(r) {
59.16143 +        this.radius = r;
59.16144 +        this.size = [2*this.radius, 2*this.radius];
59.16145 +        this.setMomentsOfInertia();
59.16146 +    };
59.16147 +
59.16148 +    Circle.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
59.16149 +        var m = this.mass;
59.16150 +        var r = this.radius;
59.16151 +
59.16152 +        this.inertia = new Matrix([
59.16153 +            [0.25 * m * r * r, 0, 0],
59.16154 +            [0, 0.25 * m * r * r, 0],
59.16155 +            [0, 0, 0.5 * m * r * r]
59.16156 +        ]);
59.16157 +
59.16158 +        this.inverseInertia = new Matrix([
59.16159 +            [4 / (m * r * r), 0, 0],
59.16160 +            [0, 4 / (m * r * r), 0],
59.16161 +            [0, 0, 2 / (m * r * r)]
59.16162 +        ]);
59.16163 +    };
59.16164 +
59.16165 +    module.exports = Circle;
59.16166 +
59.16167 +});
59.16168 +
59.16169 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16170 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16171 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16172 + *
59.16173 + * Owner: david@famo.us
59.16174 + * @license MPL 2.0
59.16175 + * @copyright Famous Industries, Inc. 2014
59.16176 + */
59.16177 +
59.16178 +define('famous/physics/bodies/Rectangle',['require','exports','module','./Body','famous/math/Matrix'],function(require, exports, module) {
59.16179 +    var Body = require('./Body');
59.16180 +    var Matrix = require('famous/math/Matrix');
59.16181 +
59.16182 +    /**
59.16183 +     * Implements a rectangular geometry for an Body with
59.16184 +     * size = [width, height].
59.16185 +     *
59.16186 +     * @class Rectangle
59.16187 +     * @extends Body
59.16188 +     * @constructor
59.16189 +     */
59.16190 +    function Rectangle(options) {
59.16191 +        options = options || {};
59.16192 +        this.size = options.size || [0,0];
59.16193 +        Body.call(this, options);
59.16194 +    }
59.16195 +
59.16196 +    Rectangle.prototype = Object.create(Body.prototype);
59.16197 +    Rectangle.prototype.constructor = Rectangle;
59.16198 +
59.16199 +    /**
59.16200 +     * Basic setter for size.
59.16201 +     * @method setSize
59.16202 +     * @param size {Array} size = [width, height]
59.16203 +     */
59.16204 +    Rectangle.prototype.setSize = function setSize(size) {
59.16205 +        this.size = size;
59.16206 +        this.setMomentsOfInertia();
59.16207 +    };
59.16208 +
59.16209 +    Rectangle.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
59.16210 +        var m = this.mass;
59.16211 +        var w = this.size[0];
59.16212 +        var h = this.size[1];
59.16213 +
59.16214 +        this.inertia = new Matrix([
59.16215 +            [m * h * h / 12, 0, 0],
59.16216 +            [0, m * w * w / 12, 0],
59.16217 +            [0, 0, m * (w * w + h * h) / 12]
59.16218 +        ]);
59.16219 +
59.16220 +        this.inverseInertia = new Matrix([
59.16221 +            [12 / (m * h * h), 0, 0],
59.16222 +            [0, 12 / (m * w * w), 0],
59.16223 +            [0, 0, 12 / (m * (w * w + h * h))]
59.16224 +        ]);
59.16225 +    };
59.16226 +
59.16227 +    module.exports = Rectangle;
59.16228 +
59.16229 +});
59.16230 +
59.16231 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16232 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16233 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16234 + *
59.16235 + * Owner: david@famo.us
59.16236 + * @license MPL 2.0
59.16237 + * @copyright Famous Industries, Inc. 2014
59.16238 + */
59.16239 +
59.16240 +define('famous/physics/constraints/Collision',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
59.16241 +    var Constraint = require('./Constraint');
59.16242 +    var Vector = require('famous/math/Vector');
59.16243 +
59.16244 +    /**
59.16245 +     *  Allows for two circular bodies to collide and bounce off each other.
59.16246 +     *
59.16247 +     *  @class Collision
59.16248 +     *  @constructor
59.16249 +     *  @extends Constraint
59.16250 +     *  @param {Options} [options] An object of configurable options.
59.16251 +     *  @param {Number} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) Range : [0, 1]
59.16252 +     *  @param {Number} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
59.16253 +     *  @param {Number} [options.slop] Amount of penetration in pixels to ignore before collision event triggers
59.16254 +     *
59.16255 +     */
59.16256 +    function Collision(options) {
59.16257 +        this.options = Object.create(Collision.DEFAULT_OPTIONS);
59.16258 +        if (options) this.setOptions(options);
59.16259 +
59.16260 +        //registers
59.16261 +        this.normal   = new Vector();
59.16262 +        this.pDiff    = new Vector();
59.16263 +        this.vDiff    = new Vector();
59.16264 +        this.impulse1 = new Vector();
59.16265 +        this.impulse2 = new Vector();
59.16266 +
59.16267 +        Constraint.call(this);
59.16268 +    }
59.16269 +
59.16270 +    Collision.prototype = Object.create(Constraint.prototype);
59.16271 +    Collision.prototype.constructor = Collision;
59.16272 +
59.16273 +    Collision.DEFAULT_OPTIONS = {
59.16274 +        restitution : 0.5,
59.16275 +        drift : 0.5,
59.16276 +        slop : 0
59.16277 +    };
59.16278 +
59.16279 +    function _normalVelocity(particle1, particle2) {
59.16280 +        return particle1.velocity.dot(particle2.velocity);
59.16281 +    }
59.16282 +
59.16283 +    /*
59.16284 +     * Setter for options.
59.16285 +     *
59.16286 +     * @method setOptions
59.16287 +     * @param options {Objects}
59.16288 +     */
59.16289 +    Collision.prototype.setOptions = function setOptions(options) {
59.16290 +        for (var key in options) this.options[key] = options[key];
59.16291 +    };
59.16292 +
59.16293 +    /**
59.16294 +     * Adds an impulse to a physics body's velocity due to the constraint
59.16295 +     *
59.16296 +     * @method applyConstraint
59.16297 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
59.16298 +     * @param source {Body}         The source of the constraint
59.16299 +     * @param dt {Number}           Delta time
59.16300 +     */
59.16301 +    Collision.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.16302 +        if (source === undefined) return;
59.16303 +
59.16304 +        var v1 = source.velocity;
59.16305 +        var p1 = source.position;
59.16306 +        var w1 = source.inverseMass;
59.16307 +        var r1 = source.radius;
59.16308 +
59.16309 +        var options = this.options;
59.16310 +        var drift = options.drift;
59.16311 +        var slop = -options.slop;
59.16312 +        var restitution = options.restitution;
59.16313 +
59.16314 +        var n     = this.normal;
59.16315 +        var pDiff = this.pDiff;
59.16316 +        var vDiff = this.vDiff;
59.16317 +        var impulse1 = this.impulse1;
59.16318 +        var impulse2 = this.impulse2;
59.16319 +
59.16320 +        for (var i = 0; i < targets.length; i++) {
59.16321 +            var target = targets[i];
59.16322 +
59.16323 +            if (target === source) continue;
59.16324 +
59.16325 +            var v2 = target.velocity;
59.16326 +            var p2 = target.position;
59.16327 +            var w2 = target.inverseMass;
59.16328 +            var r2 = target.radius;
59.16329 +
59.16330 +            pDiff.set(p2.sub(p1));
59.16331 +            vDiff.set(v2.sub(v1));
59.16332 +
59.16333 +            var dist    = pDiff.norm();
59.16334 +            var overlap = dist - (r1 + r2);
59.16335 +            var effMass = 1/(w1 + w2);
59.16336 +            var gamma   = 0;
59.16337 +
59.16338 +            if (overlap < 0) {
59.16339 +
59.16340 +                n.set(pDiff.normalize());
59.16341 +
59.16342 +                if (this._eventOutput) {
59.16343 +                    var collisionData = {
59.16344 +                        target  : target,
59.16345 +                        source  : source,
59.16346 +                        overlap : overlap,
59.16347 +                        normal  : n
59.16348 +                    };
59.16349 +
59.16350 +                    this._eventOutput.emit('preCollision', collisionData);
59.16351 +                    this._eventOutput.emit('collision', collisionData);
59.16352 +                }
59.16353 +
59.16354 +                var lambda = (overlap <= slop)
59.16355 +                    ? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
59.16356 +                    : ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass);
59.16357 +
59.16358 +                n.mult(dt*lambda).put(impulse1);
59.16359 +                impulse1.mult(-1).put(impulse2);
59.16360 +
59.16361 +                source.applyImpulse(impulse1);
59.16362 +                target.applyImpulse(impulse2);
59.16363 +
59.16364 +                //source.setPosition(p1.add(n.mult(overlap/2)));
59.16365 +                //target.setPosition(p2.sub(n.mult(overlap/2)));
59.16366 +
59.16367 +                if (this._eventOutput) this._eventOutput.emit('postCollision', collisionData);
59.16368 +
59.16369 +            }
59.16370 +        }
59.16371 +    };
59.16372 +
59.16373 +    module.exports = Collision;
59.16374 +});
59.16375 +
59.16376 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16377 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16378 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16379 + *
59.16380 + * Owner: david@famo.us
59.16381 + * @license MPL 2.0
59.16382 + * @copyright Famous Industries, Inc. 2014
59.16383 + */
59.16384 +
59.16385 +define('famous/physics/constraints/Curve',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
59.16386 +    var Constraint = require('./Constraint');
59.16387 +    var Vector = require('famous/math/Vector');
59.16388 +
59.16389 +    /**
59.16390 +     *  A constraint that keeps a physics body on a given implicit curve
59.16391 +     *    regardless of other physical forces are applied to it.
59.16392 +     *
59.16393 +     *    A curve constraint is two surface constraints in disguise, as a curve is
59.16394 +     *    the intersection of two surfaces, and is essentially constrained to both
59.16395 +     *
59.16396 +     *  @class Curve
59.16397 +     *  @constructor
59.16398 +     *  @extends Constraint
59.16399 +     *  @param {Options} [options] An object of configurable options.
59.16400 +     *  @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y - r*r } corresponds to a circle of radius r pixels
59.16401 +     *  @param {Function} [options.plane] An implicitly defined second surface that the body is constrained to
59.16402 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is violated
59.16403 +     *  @param {Number} [options.number] The damping-like reaction when the constraint is violated
59.16404 +     */
59.16405 +    function Curve(options) {
59.16406 +        this.options = Object.create(Curve.DEFAULT_OPTIONS);
59.16407 +        if (options) this.setOptions(options);
59.16408 +
59.16409 +        //registers
59.16410 +        this.J = new Vector();
59.16411 +        this.impulse = new Vector();
59.16412 +
59.16413 +        Constraint.call(this);
59.16414 +    }
59.16415 +
59.16416 +    Curve.prototype = Object.create(Constraint.prototype);
59.16417 +    Curve.prototype.constructor = Curve;
59.16418 +
59.16419 +    /** @const */ var epsilon = 1e-7;
59.16420 +    /** @const */ var pi = Math.PI;
59.16421 +
59.16422 +    Curve.DEFAULT_OPTIONS = {
59.16423 +        equation  : function(x,y,z) {
59.16424 +            return 0;
59.16425 +        },
59.16426 +        plane : function(x,y,z) {
59.16427 +            return z;
59.16428 +        },
59.16429 +        period : 0,
59.16430 +        dampingRatio : 0
59.16431 +    };
59.16432 +
59.16433 +    /**
59.16434 +     * Basic options setter
59.16435 +     *
59.16436 +     * @method setOptions
59.16437 +     * @param options {Objects}
59.16438 +     */
59.16439 +    Curve.prototype.setOptions = function setOptions(options) {
59.16440 +        for (var key in options) this.options[key] = options[key];
59.16441 +    };
59.16442 +
59.16443 +    /**
59.16444 +     * Adds a curve impulse to a physics body.
59.16445 +     *
59.16446 +     * @method applyConstraint
59.16447 +     * @param targets {Array.Body} Array of bodies to apply force to.
59.16448 +     * @param source {Body} Not applicable
59.16449 +     * @param dt {Number} Delta time
59.16450 +     */
59.16451 +    Curve.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.16452 +        var options = this.options;
59.16453 +        var impulse = this.impulse;
59.16454 +        var J = this.J;
59.16455 +
59.16456 +        var f = options.equation;
59.16457 +        var g = options.plane;
59.16458 +        var dampingRatio = options.dampingRatio;
59.16459 +        var period = options.period;
59.16460 +
59.16461 +        for (var i = 0; i < targets.length; i++) {
59.16462 +            var body = targets[i];
59.16463 +
59.16464 +            var v = body.velocity;
59.16465 +            var p = body.position;
59.16466 +            var m = body.mass;
59.16467 +
59.16468 +            var gamma;
59.16469 +            var beta;
59.16470 +
59.16471 +            if (period === 0) {
59.16472 +                gamma = 0;
59.16473 +                beta = 1;
59.16474 +            }
59.16475 +            else {
59.16476 +                var c = 4 * m * pi * dampingRatio / period;
59.16477 +                var k = 4 * m * pi * pi / (period * period);
59.16478 +
59.16479 +                gamma = 1 / (c + dt*k);
59.16480 +                beta  = dt*k / (c + dt*k);
59.16481 +            }
59.16482 +
59.16483 +            var x = p.x;
59.16484 +            var y = p.y;
59.16485 +            var z = p.z;
59.16486 +
59.16487 +            var f0  = f(x, y, z);
59.16488 +            var dfx = (f(x + epsilon, p, p) - f0) / epsilon;
59.16489 +            var dfy = (f(x, y + epsilon, p) - f0) / epsilon;
59.16490 +            var dfz = (f(x, y, p + epsilon) - f0) / epsilon;
59.16491 +
59.16492 +            var g0  = g(x, y, z);
59.16493 +            var dgx = (g(x + epsilon, y, z) - g0) / epsilon;
59.16494 +            var dgy = (g(x, y + epsilon, z) - g0) / epsilon;
59.16495 +            var dgz = (g(x, y, z + epsilon) - g0) / epsilon;
59.16496 +
59.16497 +            J.setXYZ(dfx + dgx, dfy + dgy, dfz + dgz);
59.16498 +
59.16499 +            var antiDrift = beta/dt * (f0 + g0);
59.16500 +            var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m);
59.16501 +
59.16502 +            impulse.set(J.mult(dt*lambda));
59.16503 +            body.applyImpulse(impulse);
59.16504 +        }
59.16505 +    };
59.16506 +
59.16507 +    module.exports = Curve;
59.16508 +});
59.16509 +
59.16510 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16511 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16512 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16513 + *
59.16514 + * Owner: david@famo.us
59.16515 + * @license MPL 2.0
59.16516 + * @copyright Famous Industries, Inc. 2014
59.16517 + */
59.16518 +
59.16519 +define('famous/physics/constraints/Distance',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
59.16520 +    var Constraint = require('./Constraint');
59.16521 +    var Vector = require('famous/math/Vector');
59.16522 +
59.16523 +    /**
59.16524 +     *  A constraint that keeps a physics body a given distance away from a given
59.16525 +     *  anchor, or another attached body.
59.16526 +     *
59.16527 +     *
59.16528 +     *  @class Distance
59.16529 +     *  @constructor
59.16530 +     *  @extends Constraint
59.16531 +     *  @param {Options} [options] An object of configurable options.
59.16532 +     *  @param {Array} [options.anchor] The location of the anchor
59.16533 +     *  @param {Number} [options.length] The amount of distance from the anchor the constraint should enforce
59.16534 +     *  @param {Number} [options.minLength] The minimum distance before the constraint is activated. Use this property for a "rope" effect.
59.16535 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is broken.
59.16536 +     *  @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is broken.
59.16537 +     *
59.16538 +     */
59.16539 +    function Distance(options) {
59.16540 +        this.options = Object.create(this.constructor.DEFAULT_OPTIONS);
59.16541 +        if (options) this.setOptions(options);
59.16542 +
59.16543 +        //registers
59.16544 +        this.impulse  = new Vector();
59.16545 +        this.normal   = new Vector();
59.16546 +        this.diffP    = new Vector();
59.16547 +        this.diffV    = new Vector();
59.16548 +
59.16549 +        Constraint.call(this);
59.16550 +    }
59.16551 +
59.16552 +    Distance.prototype = Object.create(Constraint.prototype);
59.16553 +    Distance.prototype.constructor = Distance;
59.16554 +
59.16555 +    Distance.DEFAULT_OPTIONS = {
59.16556 +        anchor : null,
59.16557 +        length : 0,
59.16558 +        minLength : 0,
59.16559 +        period : 0,
59.16560 +        dampingRatio : 0
59.16561 +    };
59.16562 +
59.16563 +    /** @const */ var pi = Math.PI;
59.16564 +
59.16565 +    /**
59.16566 +     * Basic options setter
59.16567 +     *
59.16568 +     * @method setOptions
59.16569 +     * @param options {Objects}
59.16570 +     */
59.16571 +    Distance.prototype.setOptions = function setOptions(options) {
59.16572 +        if (options.anchor) {
59.16573 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
59.16574 +            if (options.anchor   instanceof Vector)  this.options.anchor = options.anchor;
59.16575 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
59.16576 +        }
59.16577 +        if (options.length !== undefined) this.options.length = options.length;
59.16578 +        if (options.dampingRatio !== undefined) this.options.dampingRatio = options.dampingRatio;
59.16579 +        if (options.period !== undefined) this.options.period = options.period;
59.16580 +        if (options.minLength !== undefined) this.options.minLength = options.minLength;
59.16581 +    };
59.16582 +
59.16583 +    function _calcError(impulse, body) {
59.16584 +        return body.mass * impulse.norm();
59.16585 +    }
59.16586 +
59.16587 +    /**
59.16588 +     * Set the anchor position
59.16589 +     *
59.16590 +     * @method setOptions
59.16591 +     * @param anchor {Array}
59.16592 +     */
59.16593 +    Distance.prototype.setAnchor = function setAnchor(anchor) {
59.16594 +        if (!this.options.anchor) this.options.anchor = new Vector();
59.16595 +        this.options.anchor.set(anchor);
59.16596 +    };
59.16597 +
59.16598 +    /**
59.16599 +     * Adds an impulse to a physics body's velocity due to the constraint
59.16600 +     *
59.16601 +     * @method applyConstraint
59.16602 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
59.16603 +     * @param source {Body}         The source of the constraint
59.16604 +     * @param dt {Number}           Delta time
59.16605 +     */
59.16606 +    Distance.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.16607 +        var n        = this.normal;
59.16608 +        var diffP    = this.diffP;
59.16609 +        var diffV    = this.diffV;
59.16610 +        var impulse  = this.impulse;
59.16611 +        var options  = this.options;
59.16612 +
59.16613 +        var dampingRatio = options.dampingRatio;
59.16614 +        var period       = options.period;
59.16615 +        var minLength    = options.minLength;
59.16616 +
59.16617 +        var p2;
59.16618 +        var w2;
59.16619 +
59.16620 +        if (source) {
59.16621 +            var v2 = source.velocity;
59.16622 +            p2 = source.position;
59.16623 +            w2 = source.inverseMass;
59.16624 +        }
59.16625 +        else {
59.16626 +            p2 = this.options.anchor;
59.16627 +            w2 = 0;
59.16628 +        }
59.16629 +
59.16630 +        var length = this.options.length;
59.16631 +
59.16632 +        for (var i = 0; i < targets.length; i++) {
59.16633 +            var body = targets[i];
59.16634 +
59.16635 +            var v1 = body.velocity;
59.16636 +            var p1 = body.position;
59.16637 +            var w1 = body.inverseMass;
59.16638 +
59.16639 +            diffP.set(p1.sub(p2));
59.16640 +            n.set(diffP.normalize());
59.16641 +
59.16642 +            var dist = diffP.norm() - length;
59.16643 +
59.16644 +            //rope effect
59.16645 +            if (Math.abs(dist) < minLength) return;
59.16646 +
59.16647 +            if (source) diffV.set(v1.sub(v2));
59.16648 +            else diffV.set(v1);
59.16649 +
59.16650 +            var effMass = 1 / (w1 + w2);
59.16651 +            var gamma;
59.16652 +            var beta;
59.16653 +
59.16654 +            if (period === 0) {
59.16655 +                gamma = 0;
59.16656 +                beta  = 1;
59.16657 +            }
59.16658 +            else {
59.16659 +                var c = 4 * effMass * pi * dampingRatio / period;
59.16660 +                var k = 4 * effMass * pi * pi / (period * period);
59.16661 +
59.16662 +                gamma = 1 / (c + dt*k);
59.16663 +                beta  = dt*k / (c + dt*k);
59.16664 +            }
59.16665 +
59.16666 +            var antiDrift = beta/dt * dist;
59.16667 +            var lambda    = -(n.dot(diffV) + antiDrift) / (gamma + dt/effMass);
59.16668 +
59.16669 +            impulse.set(n.mult(dt*lambda));
59.16670 +            body.applyImpulse(impulse);
59.16671 +
59.16672 +            if (source) source.applyImpulse(impulse.mult(-1));
59.16673 +        }
59.16674 +    };
59.16675 +
59.16676 +    module.exports = Distance;
59.16677 +});
59.16678 +
59.16679 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16680 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16681 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16682 + *
59.16683 + * Owner: david@famo.us
59.16684 + * @license MPL 2.0
59.16685 + * @copyright Famous Industries, Inc. 2014
59.16686 + */
59.16687 +
59.16688 +define('famous/physics/constraints/Surface',['require','exports','module','./Constraint','famous/math/Vector'],function(require, exports, module) {
59.16689 +    var Constraint = require('./Constraint');
59.16690 +    var Vector = require('famous/math/Vector');
59.16691 +
59.16692 +    /**
59.16693 +     *  A constraint that keeps a physics body on a given implicit surface
59.16694 +     *    regardless of other physical forces are applied to it.
59.16695 +     *
59.16696 +     *  @class Surface
59.16697 +     *  @constructor
59.16698 +     *  @extends Constraint
59.16699 +     *  @param {Options} [options] An object of configurable options.
59.16700 +     *  @param {Function} [options.equation] An implicitly defined surface f(x,y,z) = 0 that body is constrained to e.g. function(x,y,z) { x*x + y*y + z*z - r*r } corresponds to a sphere of radius r pixels.
59.16701 +     *  @param {Number} [options.period] The spring-like reaction when the constraint is violated.
59.16702 +     *  @param {Number} [options.dampingRatio] The damping-like reaction when the constraint is violated.
59.16703 +     */
59.16704 +    function Surface(options) {
59.16705 +        this.options = Object.create(Surface.DEFAULT_OPTIONS);
59.16706 +        if (options) this.setOptions(options);
59.16707 +
59.16708 +        this.J = new Vector();
59.16709 +        this.impulse  = new Vector();
59.16710 +
59.16711 +        Constraint.call(this);
59.16712 +    }
59.16713 +
59.16714 +    Surface.prototype = Object.create(Constraint.prototype);
59.16715 +    Surface.prototype.constructor = Surface;
59.16716 +
59.16717 +    Surface.DEFAULT_OPTIONS = {
59.16718 +        equation : undefined,
59.16719 +        period : 0,
59.16720 +        dampingRatio : 0
59.16721 +    };
59.16722 +
59.16723 +    /** @const */ var epsilon = 1e-7;
59.16724 +    /** @const */ var pi = Math.PI;
59.16725 +
59.16726 +    /**
59.16727 +     * Basic options setter
59.16728 +     *
59.16729 +     * @method setOptions
59.16730 +     * @param options {Objects}
59.16731 +     */
59.16732 +    Surface.prototype.setOptions = function setOptions(options) {
59.16733 +        for (var key in options) this.options[key] = options[key];
59.16734 +    };
59.16735 +
59.16736 +    /**
59.16737 +     * Adds a surface impulse to a physics body.
59.16738 +     *
59.16739 +     * @method applyConstraint
59.16740 +     * @param targets {Array.Body} Array of bodies to apply force to.
59.16741 +     * @param source {Body} Not applicable
59.16742 +     * @param dt {Number} Delta time
59.16743 +     */
59.16744 +    Surface.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.16745 +        var impulse = this.impulse;
59.16746 +        var J       = this.J;
59.16747 +        var options = this.options;
59.16748 +
59.16749 +        var f = options.equation;
59.16750 +        var dampingRatio = options.dampingRatio;
59.16751 +        var period = options.period;
59.16752 +
59.16753 +        for (var i = 0; i < targets.length; i++) {
59.16754 +            var particle = targets[i];
59.16755 +
59.16756 +            var v = particle.velocity;
59.16757 +            var p = particle.position;
59.16758 +            var m = particle.mass;
59.16759 +
59.16760 +            var gamma;
59.16761 +            var beta;
59.16762 +
59.16763 +            if (period === 0) {
59.16764 +                gamma = 0;
59.16765 +                beta = 1;
59.16766 +            }
59.16767 +            else {
59.16768 +                var c = 4 * m * pi * dampingRatio / period;
59.16769 +                var k = 4 * m * pi * pi / (period * period);
59.16770 +
59.16771 +                gamma = 1 / (c + dt*k);
59.16772 +                beta  = dt*k / (c + dt*k);
59.16773 +            }
59.16774 +
59.16775 +            var x = p.x;
59.16776 +            var y = p.y;
59.16777 +            var z = p.z;
59.16778 +
59.16779 +            var f0  = f(x, y, z);
59.16780 +            var dfx = (f(x + epsilon, p, p) - f0) / epsilon;
59.16781 +            var dfy = (f(x, y + epsilon, p) - f0) / epsilon;
59.16782 +            var dfz = (f(x, y, p + epsilon) - f0) / epsilon;
59.16783 +            J.setXYZ(dfx, dfy, dfz);
59.16784 +
59.16785 +            var antiDrift = beta/dt * f0;
59.16786 +            var lambda = -(J.dot(v) + antiDrift) / (gamma + dt * J.normSquared() / m);
59.16787 +
59.16788 +            impulse.set(J.mult(dt*lambda));
59.16789 +            particle.applyImpulse(impulse);
59.16790 +        }
59.16791 +    };
59.16792 +
59.16793 +    module.exports = Surface;
59.16794 +});
59.16795 +
59.16796 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.16797 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.16798 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.16799 + *
59.16800 + * Owner: david@famo.us
59.16801 + * @license MPL 2.0
59.16802 + * @copyright Famous Industries, Inc. 2014
59.16803 + */
59.16804 +
59.16805 +define('famous/physics/constraints/Walls',['require','exports','module','./Constraint','./Wall','famous/math/Vector'],function(require, exports, module) {
59.16806 +    var Constraint = require('./Constraint');
59.16807 +    var Wall = require('./Wall');
59.16808 +    var Vector = require('famous/math/Vector');
59.16809 +
59.16810 +    /**
59.16811 +     *  Walls combines one or more Wall primitives and exposes a simple API to
59.16812 +     *  interact with several walls at once. A common use case would be to set up
59.16813 +     *  a bounding box for a physics body, that would collide with each side.
59.16814 +     *
59.16815 +     *  @class Walls
59.16816 +     *  @constructor
59.16817 +     *  @extends Constraint
59.16818 +     *  @uses Wall
59.16819 +     *  @param {Options} [options] An object of configurable options.
59.16820 +     *  @param {Array} [options.sides] An array of sides e.g., [Walls.LEFT, Walls.TOP]
59.16821 +     *  @param {Array} [options.size] The size of the bounding box of the walls.
59.16822 +     *  @param {Array} [options.origin] The center of the wall relative to the size.
59.16823 +     *  @param {Array} [options.drift] Baumgarte stabilization parameter. Makes constraints "loosely" (0) or "tightly" (1) enforced. Range : [0, 1]
59.16824 +     *  @param {Array} [options.slop] Amount of penetration in pixels to ignore before collision event triggers.
59.16825 +     *  @param {Array} [options.restitution] The energy ratio lost in a collision (0 = stick, 1 = elastic) The energy ratio lost in a collision (0 = stick, 1 = elastic)
59.16826 +     *  @param {Array} [options.onContact] How to handle collision against the wall.
59.16827 +     */
59.16828 +    function Walls(options) {
59.16829 +        this.options = Object.create(Walls.DEFAULT_OPTIONS);
59.16830 +        if (options) this.setOptions(options);
59.16831 +        _createComponents.call(this, options.sides || this.options.sides);
59.16832 +
59.16833 +        Constraint.call(this);
59.16834 +    }
59.16835 +
59.16836 +    Walls.prototype = Object.create(Constraint.prototype);
59.16837 +    Walls.prototype.constructor = Walls;
59.16838 +    /**
59.16839 +     * @property Walls.ON_CONTACT
59.16840 +     * @type Object
59.16841 +     * @extends Wall.ON_CONTACT
59.16842 +     * @static
59.16843 +     */
59.16844 +    Walls.ON_CONTACT = Wall.ON_CONTACT;
59.16845 +
59.16846 +    /**
59.16847 +     * An enumeration of common types of walls
59.16848 +     *    LEFT, RIGHT, TOP, BOTTOM, FRONT, BACK
59.16849 +     *    TWO_DIMENSIONAL, THREE_DIMENSIONAL
59.16850 +     *
59.16851 +     * @property Walls.SIDES
59.16852 +     * @type Object
59.16853 +     * @final
59.16854 +     * @static
59.16855 +     */
59.16856 +    Walls.SIDES = {
59.16857 +        LEFT   : 0,
59.16858 +        RIGHT  : 1,
59.16859 +        TOP    : 2,
59.16860 +        BOTTOM : 3,
59.16861 +        FRONT  : 4,
59.16862 +        BACK   : 5,
59.16863 +        TWO_DIMENSIONAL : [0, 1, 2, 3],
59.16864 +        THREE_DIMENSIONAL : [0, 1, 2, 3, 4, 5]
59.16865 +    };
59.16866 +
59.16867 +    Walls.DEFAULT_OPTIONS = {
59.16868 +        sides : Walls.SIDES.TWO_DIMENSIONAL,
59.16869 +        size : [window.innerWidth, window.innerHeight, 0],
59.16870 +        origin : [.5, .5, .5],
59.16871 +        drift : 0.5,
59.16872 +        slop : 0,
59.16873 +        restitution : 0.5,
59.16874 +        onContact : Walls.ON_CONTACT.REFLECT
59.16875 +    };
59.16876 +
59.16877 +    var _SIDE_NORMALS = {
59.16878 +        0 : new Vector(1, 0, 0),
59.16879 +        1 : new Vector(-1, 0, 0),
59.16880 +        2 : new Vector(0, 1, 0),
59.16881 +        3 : new Vector(0,-1, 0),
59.16882 +        4 : new Vector(0, 0, 1),
59.16883 +        5 : new Vector(0, 0,-1)
59.16884 +    };
59.16885 +
59.16886 +    function _getDistance(side, size, origin) {
59.16887 +        var distance;
59.16888 +        var SIDES = Walls.SIDES;
59.16889 +        switch (parseInt(side)) {
59.16890 +            case SIDES.LEFT:
59.16891 +                distance = size[0] * origin[0];
59.16892 +                break;
59.16893 +            case SIDES.TOP:
59.16894 +                distance = size[1] * origin[1];
59.16895 +                break;
59.16896 +            case SIDES.FRONT:
59.16897 +                distance = size[2] * origin[2];
59.16898 +                break;
59.16899 +            case SIDES.RIGHT:
59.16900 +                distance = size[0] * (1 - origin[0]);
59.16901 +                break;
59.16902 +            case SIDES.BOTTOM:
59.16903 +                distance = size[1] * (1 - origin[1]);
59.16904 +                break;
59.16905 +            case SIDES.BACK:
59.16906 +                distance = size[2] * (1 - origin[2]);
59.16907 +                break;
59.16908 +        }
59.16909 +        return distance;
59.16910 +    }
59.16911 +
59.16912 +    /*
59.16913 +     * Setter for options.
59.16914 +     *
59.16915 +     * @method setOptions
59.16916 +     * @param options {Objects}
59.16917 +     */
59.16918 +    Walls.prototype.setOptions = function setOptions(options) {
59.16919 +        var resizeFlag = false;
59.16920 +        if (options.restitution !== undefined) _setOptionsForEach.call(this, {restitution : options.restitution});
59.16921 +        if (options.drift !== undefined) _setOptionsForEach.call(this, {drift : options.drift});
59.16922 +        if (options.slop !== undefined) _setOptionsForEach.call(this, {slop : options.slop});
59.16923 +        if (options.onContact !== undefined) _setOptionsForEach.call(this, {onContact : options.onContact});
59.16924 +        if (options.size !== undefined) resizeFlag = true;
59.16925 +        if (options.sides !== undefined) this.options.sides = options.sides;
59.16926 +        if (options.origin !== undefined) resizeFlag = true;
59.16927 +        if (resizeFlag) this.setSize(options.size, options.origin);
59.16928 +    };
59.16929 +
59.16930 +    function _createComponents(sides) {
59.16931 +        this.components = {};
59.16932 +        var components = this.components;
59.16933 +
59.16934 +        for (var i = 0; i < sides.length; i++) {
59.16935 +            var side = sides[i];
59.16936 +            components[i] = new Wall({
59.16937 +                normal   : _SIDE_NORMALS[side].clone(),
59.16938 +                distance : _getDistance(side, this.options.size, this.options.origin)
59.16939 +            });
59.16940 +        }
59.16941 +    }
59.16942 +
59.16943 +    /*
59.16944 +     * Setter for size.
59.16945 +     *
59.16946 +     * @method setOptions
59.16947 +     * @param options {Objects}
59.16948 +     */
59.16949 +    Walls.prototype.setSize = function setSize(size, origin) {
59.16950 +        origin = origin || this.options.origin;
59.16951 +        if (origin.length < 3) origin[2] = 0.5;
59.16952 +
59.16953 +        this.forEach(function(wall, side) {
59.16954 +            var d = _getDistance(side, size, origin);
59.16955 +            wall.setOptions({distance : d});
59.16956 +        });
59.16957 +
59.16958 +        this.options.size   = size;
59.16959 +        this.options.origin = origin;
59.16960 +    };
59.16961 +
59.16962 +    function _setOptionsForEach(options) {
59.16963 +        this.forEach(function(wall) {
59.16964 +            wall.setOptions(options);
59.16965 +        });
59.16966 +        for (var key in options) this.options[key] = options[key];
59.16967 +    }
59.16968 +
59.16969 +    /**
59.16970 +     * Adds an impulse to a physics body's velocity due to the walls constraint
59.16971 +     *
59.16972 +     * @method applyConstraint
59.16973 +     * @param targets {Array.Body}  Array of bodies to apply the constraint to
59.16974 +     * @param source {Body}         The source of the constraint
59.16975 +     * @param dt {Number}           Delta time
59.16976 +     */
59.16977 +    Walls.prototype.applyConstraint = function applyConstraint(targets, source, dt) {
59.16978 +        this.forEach(function(wall) {
59.16979 +            wall.applyConstraint(targets, source, dt);
59.16980 +        });
59.16981 +    };
59.16982 +
59.16983 +    /**
59.16984 +     * Apply a method to each wall making up the walls
59.16985 +     *
59.16986 +     * @method applyConstraint
59.16987 +     * @param fn {Function}  Function that takes in a wall as its first parameter
59.16988 +     */
59.16989 +    Walls.prototype.forEach = function forEach(fn) {
59.16990 +        for (var key in this.sides) fn(this.sides[key], key);
59.16991 +    };
59.16992 +
59.16993 +    /**
59.16994 +     * Rotates the walls by an angle in the XY-plane
59.16995 +     *
59.16996 +     * @method applyConstraint
59.16997 +     * @param angle {Function}
59.16998 +     */
59.16999 +    Walls.prototype.rotateZ = function rotateZ(angle) {
59.17000 +        this.forEach(function(wall) {
59.17001 +            var n = wall.options.normal;
59.17002 +            n.rotateZ(angle).put(n);
59.17003 +        });
59.17004 +    };
59.17005 +
59.17006 +    /**
59.17007 +     * Rotates the walls by an angle in the YZ-plane
59.17008 +     *
59.17009 +     * @method applyConstraint
59.17010 +     * @param angle {Function}
59.17011 +     */
59.17012 +    Walls.prototype.rotateX = function rotateX(angle) {
59.17013 +        this.forEach(function(wall) {
59.17014 +            var n = wall.options.normal;
59.17015 +            n.rotateX(angle).put(n);
59.17016 +        });
59.17017 +    };
59.17018 +
59.17019 +    /**
59.17020 +     * Rotates the walls by an angle in the XZ-plane
59.17021 +     *
59.17022 +     * @method applyConstraint
59.17023 +     * @param angle {Function}
59.17024 +     */
59.17025 +    Walls.prototype.rotateY = function rotateY(angle) {
59.17026 +        this.forEach(function(wall) {
59.17027 +            var n = wall.options.normal;
59.17028 +            n.rotateY(angle).put(n);
59.17029 +        });
59.17030 +    };
59.17031 +
59.17032 +    module.exports = Walls;
59.17033 +});
59.17034 +
59.17035 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.17036 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.17037 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.17038 + *
59.17039 + * Owner: david@famo.us
59.17040 + * @license MPL 2.0
59.17041 + * @copyright Famous Industries, Inc. 2014
59.17042 + */
59.17043 +
59.17044 +//TODO: test options manager
59.17045 +define('famous/physics/forces/Repulsion',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
59.17046 +    var Force = require('./Force');
59.17047 +    var Vector = require('famous/math/Vector');
59.17048 +
59.17049 +    /**
59.17050 +     *  Repulsion is a force that repels (attracts) bodies away (towards)
59.17051 +     *    each other. A repulsion of negative strength is attractive.
59.17052 +     *
59.17053 +     *  @class Repulsion
59.17054 +     *  @constructor
59.17055 +     *  @extends Force
59.17056 +     *  @param {Object} options overwrites default options
59.17057 +     */
59.17058 +    function Repulsion(options) {
59.17059 +        this.options = Object.create(Repulsion.DEFAULT_OPTIONS);
59.17060 +        if (options) this.setOptions(options);
59.17061 +
59.17062 +        //registers
59.17063 +        this.disp  = new Vector();
59.17064 +
59.17065 +        Force.call(this);
59.17066 +    }
59.17067 +
59.17068 +    Repulsion.prototype = Object.create(Force.prototype);
59.17069 +    Repulsion.prototype.constructor = Repulsion;
59.17070 +    /**
59.17071 +     * @property Repulsion.DECAY_FUNCTIONS
59.17072 +     * @type Object
59.17073 +     * @protected
59.17074 +     * @static
59.17075 +     */
59.17076 +    Repulsion.DECAY_FUNCTIONS = {
59.17077 +
59.17078 +        /**
59.17079 +         * A linear decay function
59.17080 +         * @attribute LINEAR
59.17081 +         * @type Function
59.17082 +         * @param {Number} r distance from the source body
59.17083 +         * @param {Number} cutoff the effective radius of influence
59.17084 +         */
59.17085 +        LINEAR : function(r, cutoff) {
59.17086 +            return Math.max(1 - (1 / cutoff) * r, 0);
59.17087 +        },
59.17088 +
59.17089 +        /**
59.17090 +         * A Morse potential decay function (http://en.wikipedia.org/wiki/Morse_potential)
59.17091 +         * @attribute MORSE
59.17092 +         * @type Function
59.17093 +         * @param {Number} r distance from the source body
59.17094 +         * @param {Number} cutoff the minimum radius of influence
59.17095 +         */
59.17096 +        MORSE : function(r, cutoff) {
59.17097 +            var r0 = (cutoff === 0) ? 100 : cutoff;
59.17098 +            var rShifted = r + r0 * (1 - Math.log(2)); //shift by x-intercept
59.17099 +            return Math.max(1 - Math.pow(1 - Math.exp(rShifted/r0 - 1), 2), 0);
59.17100 +        },
59.17101 +
59.17102 +        /**
59.17103 +         * An inverse distance decay function
59.17104 +         * @attribute INVERSE
59.17105 +         * @type Function
59.17106 +         * @param {Number} r distance from the source body
59.17107 +         * @param {Number} cutoff a distance shift to avoid singularities
59.17108 +         */
59.17109 +        INVERSE : function(r, cutoff) {
59.17110 +            return 1 / (1 - cutoff + r);
59.17111 +        },
59.17112 +
59.17113 +        /**
59.17114 +         * An inverse squared distance decay function
59.17115 +         * @attribute INVERSE
59.17116 +         * @type Function
59.17117 +         * @param {Number} r distance from the source body
59.17118 +         * @param {Number} cutoff a distance shift to avoid singularities
59.17119 +         */
59.17120 +        GRAVITY : function(r, cutoff) {
59.17121 +            return 1 / (1 - cutoff + r*r);
59.17122 +        }
59.17123 +    };
59.17124 +
59.17125 +    /**
59.17126 +     * @property Repulsion.DEFAULT_OPTIONS
59.17127 +     * @type Object
59.17128 +     * @protected
59.17129 +     * @static
59.17130 +     */
59.17131 +    Repulsion.DEFAULT_OPTIONS = {
59.17132 +
59.17133 +        /**
59.17134 +         * The strength of the force
59.17135 +         *    Range : [0, 100]
59.17136 +         * @attribute strength
59.17137 +         * @type Number
59.17138 +         * @default 1
59.17139 +         */
59.17140 +        strength : 1,
59.17141 +
59.17142 +        /**
59.17143 +         * The location of the force, if not another physics body
59.17144 +         *
59.17145 +         * @attribute anchor
59.17146 +         * @type Number
59.17147 +         * @default 0.01
59.17148 +         * @optional
59.17149 +         */
59.17150 +        anchor : undefined,
59.17151 +
59.17152 +        /**
59.17153 +         * The range of the repulsive force
59.17154 +         * @attribute radii
59.17155 +         * @type Array
59.17156 +         * @default [0, Infinity]
59.17157 +         */
59.17158 +        range : [0, Infinity],
59.17159 +
59.17160 +        /**
59.17161 +         * A normalization for the force to avoid singularities at the origin
59.17162 +         * @attribute cutoff
59.17163 +         * @type Number
59.17164 +         * @default 0
59.17165 +         */
59.17166 +        cutoff : 0,
59.17167 +
59.17168 +        /**
59.17169 +         * The maximum magnitude of the force
59.17170 +         *    Range : [0, Infinity]
59.17171 +         * @attribute cap
59.17172 +         * @type Number
59.17173 +         * @default Infinity
59.17174 +         */
59.17175 +        cap : Infinity,
59.17176 +
59.17177 +        /**
59.17178 +         * The type of decay the repulsive force should have
59.17179 +         * @attribute decayFunction
59.17180 +         * @type Function
59.17181 +         */
59.17182 +        decayFunction : Repulsion.DECAY_FUNCTIONS.GRAVITY
59.17183 +    };
59.17184 +
59.17185 +    /*
59.17186 +     * Setter for options.
59.17187 +     *
59.17188 +     * @method setOptions
59.17189 +     * @param {Objects} options
59.17190 +     */
59.17191 +    Repulsion.prototype.setOptions = function setOptions(options) {
59.17192 +        if (options.anchor !== undefined) {
59.17193 +            if (options.anchor.position instanceof Vector) this.options.anchor = options.anchor.position;
59.17194 +            if (options.anchor   instanceof Array)  this.options.anchor = new Vector(options.anchor);
59.17195 +            delete options.anchor;
59.17196 +        }
59.17197 +        for (var key in options) this.options[key] = options[key];
59.17198 +    };
59.17199 +
59.17200 +    /**
59.17201 +     * Adds a drag force to a physics body's force accumulator.
59.17202 +     *
59.17203 +     * @method applyForce
59.17204 +     * @param targets {Array.Body}  Array of bodies to apply force to
59.17205 +     * @param source {Body}         The source of the force
59.17206 +     */
59.17207 +    Repulsion.prototype.applyForce = function applyForce(targets, source) {
59.17208 +        var options     = this.options;
59.17209 +        var force       = this.force;
59.17210 +        var disp        = this.disp;
59.17211 +
59.17212 +        var strength    = options.strength;
59.17213 +        var anchor      = options.anchor || source.position;
59.17214 +        var cap         = options.cap;
59.17215 +        var cutoff      = options.cutoff;
59.17216 +        var rMin        = options.range[0];
59.17217 +        var rMax        = options.range[1];
59.17218 +        var decayFn     = options.decayFunction;
59.17219 +
59.17220 +        if (strength === 0) return;
59.17221 +
59.17222 +        for (var index in targets) {
59.17223 +            var particle = targets[index];
59.17224 +
59.17225 +            if (particle === source) continue;
59.17226 +
59.17227 +            var m1 = particle.mass;
59.17228 +            var p1 = particle.position;
59.17229 +
59.17230 +            disp.set(p1.sub(anchor));
59.17231 +            var r = disp.norm();
59.17232 +
59.17233 +            if (r < rMax && r > rMin) {
59.17234 +                force.set(disp.normalize(strength * m1 * decayFn(r, cutoff)).cap(cap));
59.17235 +                particle.applyForce(force);
59.17236 +            }
59.17237 +        }
59.17238 +
59.17239 +    };
59.17240 +
59.17241 +    module.exports = Repulsion;
59.17242 +});
59.17243 +
59.17244 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.17245 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.17246 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.17247 + *
59.17248 + * Owner: david@famo.us
59.17249 + * @license MPL 2.0
59.17250 + * @copyright Famous Industries, Inc. 2014
59.17251 + */
59.17252 +
59.17253 +define('famous/physics/forces/RotationalDrag',['require','exports','module','./Drag'],function(require, exports, module) {
59.17254 +    var Drag = require('./Drag');
59.17255 +
59.17256 +    /**
59.17257 +     * Rotational drag is a force that opposes angular velocity.
59.17258 +     *   Attach it to a physics body to slow down its rotation.
59.17259 +     *
59.17260 +     * @class RotationalDrag
59.17261 +     * @constructor
59.17262 +     * @extends Force
59.17263 +     * @param {Object} options options to set on drag
59.17264 +     */
59.17265 +    function RotationalDrag(options) {
59.17266 +        Drag.call(this, options);
59.17267 +    }
59.17268 +
59.17269 +    RotationalDrag.prototype = Object.create(Drag.prototype);
59.17270 +    RotationalDrag.prototype.constructor = RotationalDrag;
59.17271 +
59.17272 +    RotationalDrag.DEFAULT_OPTIONS = Drag.DEFAULT_OPTIONS;
59.17273 +    RotationalDrag.FORCE_FUNCTIONS = Drag.FORCE_FUNCTIONS;
59.17274 +
59.17275 +    /**
59.17276 +     * @property Repulsion.FORCE_FUNCTIONS
59.17277 +     * @type Object
59.17278 +     * @protected
59.17279 +     * @static
59.17280 +     */
59.17281 +    RotationalDrag.FORCE_FUNCTIONS = {
59.17282 +
59.17283 +        /**
59.17284 +         * A drag force proprtional to the angular velocity
59.17285 +         * @attribute LINEAR
59.17286 +         * @type Function
59.17287 +         * @param {Vector} angularVelocity
59.17288 +         * @return {Vector} drag force
59.17289 +         */
59.17290 +        LINEAR : function(angularVelocity) {
59.17291 +            return angularVelocity;
59.17292 +        },
59.17293 +
59.17294 +        /**
59.17295 +         * A drag force proprtional to the square of the angular velocity
59.17296 +         * @attribute QUADRATIC
59.17297 +         * @type Function
59.17298 +         * @param {Vector} angularVelocity
59.17299 +         * @return {Vector} drag force
59.17300 +         */
59.17301 +        QUADRATIC : function(angularVelocity) {
59.17302 +            return angularVelocity.mult(angularVelocity.norm());
59.17303 +        }
59.17304 +    };
59.17305 +
59.17306 +    /**
59.17307 +     * Adds a rotational drag force to a physics body's torque accumulator.
59.17308 +     *
59.17309 +     * @method applyForce
59.17310 +     * @param targets {Array.Body} Array of bodies to apply drag force to.
59.17311 +     */
59.17312 +    RotationalDrag.prototype.applyForce = function applyForce(targets) {
59.17313 +        var strength       = this.options.strength;
59.17314 +        var forceFunction  = this.options.forceFunction;
59.17315 +        var force          = this.force;
59.17316 +
59.17317 +        //TODO: rotational drag as function of inertia
59.17318 +        for (var index = 0; index < targets.length; index++) {
59.17319 +            var particle = targets[index];
59.17320 +            forceFunction(particle.angularVelocity).mult(-100*strength).put(force);
59.17321 +            particle.applyTorque(force);
59.17322 +        }
59.17323 +    };
59.17324 +
59.17325 +    /*
59.17326 +     * Setter for options.
59.17327 +     *
59.17328 +     * @method setOptions
59.17329 +     * @param {Objects} options
59.17330 +     */
59.17331 +    RotationalDrag.prototype.setOptions = function setOptions(options) {
59.17332 +        for (var key in options) this.options[key] = options[key];
59.17333 +    };
59.17334 +
59.17335 +    module.exports = RotationalDrag;
59.17336 +});
59.17337 +
59.17338 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.17339 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.17340 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.17341 + *
59.17342 + * Owner: david@famo.us
59.17343 + * @license MPL 2.0
59.17344 + * @copyright Famous Industries, Inc. 2014
59.17345 + */
59.17346 +
59.17347 +//TODO: test inheritance
59.17348 +define('famous/physics/forces/RotationalSpring',['require','exports','module','./Spring'],function(require, exports, module) {
59.17349 +    var Spring = require('./Spring');
59.17350 +
59.17351 +    /**
59.17352 +     *  A force that rotates a physics body back to target Euler angles.
59.17353 +     *  Just as a spring translates a body to a particular X, Y, Z, location,
59.17354 +     *  a rotational spring rotates a body to a particular X, Y, Z Euler angle.
59.17355 +     *      Note: there is no physical agent that does this in the "real world"
59.17356 +     *
59.17357 +     *  @class RotationalSpring
59.17358 +     *  @constructor
59.17359 +     *  @extends Spring
59.17360 +     *  @param {Object} options options to set on drag
59.17361 +     */
59.17362 +    function RotationalSpring(options) {
59.17363 +        Spring.call(this, options);
59.17364 +    }
59.17365 +
59.17366 +    RotationalSpring.prototype = Object.create(Spring.prototype);
59.17367 +    RotationalSpring.prototype.constructor = RotationalSpring;
59.17368 +
59.17369 +    RotationalSpring.DEFAULT_OPTIONS = Spring.DEFAULT_OPTIONS;
59.17370 +    RotationalSpring.FORCE_FUNCTIONS = Spring.FORCE_FUNCTIONS;
59.17371 +
59.17372 +    /**
59.17373 +     * Adds a torque force to a physics body's torque accumulator.
59.17374 +     *
59.17375 +     * @method applyForce
59.17376 +     * @param targets {Array.Body} Array of bodies to apply torque to.
59.17377 +     */
59.17378 +    RotationalSpring.prototype.applyForce = function applyForce(targets) {
59.17379 +        var force        = this.force;
59.17380 +        var options      = this.options;
59.17381 +        var disp         = this.disp;
59.17382 +
59.17383 +        var stiffness    = options.stiffness;
59.17384 +        var damping      = options.damping;
59.17385 +        var restLength   = options.length;
59.17386 +        var anchor       = options.anchor;
59.17387 +
59.17388 +        for (var i = 0; i < targets.length; i++) {
59.17389 +            var target = targets[i];
59.17390 +
59.17391 +            disp.set(anchor.sub(target.orientation));
59.17392 +            var dist = disp.norm() - restLength;
59.17393 +
59.17394 +            if (dist === 0) return;
59.17395 +
59.17396 +            //if dampingRatio specified, then override strength and damping
59.17397 +            var m      = target.mass;
59.17398 +            stiffness *= m;
59.17399 +            damping   *= m;
59.17400 +
59.17401 +            force.set(disp.normalize(stiffness * this.forceFunction(dist, this.options.lMax)));
59.17402 +
59.17403 +            if (damping) force.set(force.add(target.angularVelocity.mult(-damping)));
59.17404 +
59.17405 +            target.applyTorque(force);
59.17406 +        }
59.17407 +    };
59.17408 +
59.17409 +    /**
59.17410 +     * Calculates the potential energy of the rotational spring.
59.17411 +     *
59.17412 +     * @method getEnergy
59.17413 +     * @param {Body} target The physics body attached to the spring
59.17414 +     */
59.17415 +    RotationalSpring.prototype.getEnergy = function getEnergy(target) {
59.17416 +        var options     = this.options;
59.17417 +        var restLength  = options.length;
59.17418 +        var anchor      = options.anchor;
59.17419 +        var strength    = options.stiffness;
59.17420 +
59.17421 +        var dist = anchor.sub(target.orientation).norm() - restLength;
59.17422 +        return 0.5 * strength * dist * dist;
59.17423 +    };
59.17424 +
59.17425 +    module.exports = RotationalSpring;
59.17426 +});
59.17427 +
59.17428 +/* This Source Code Form is subject to the terms of the Mozilla Public
59.17429 + * License, v. 2.0. If a copy of the MPL was not distributed with this
59.17430 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59.17431 + *
59.17432 + * Owner: david@famo.us
59.17433 + * @license MPL 2.0
59.17434 + * @copyright Famous Industries, Inc. 2014
59.17435 + */
59.17436 +
59.17437 +define('famous/physics/forces/VectorField',['require','exports','module','./Force','famous/math/Vector'],function(require, exports, module) {
59.17438 +    var Force = require('./Force');
59.17439 +    var Vector = require('famous/math/Vector');
59.17440 +
59.17441 +    /**
59.17442 +     *  A force that moves a physics body to a location with a spring motion.
59.17443 +     *    The body can be moved to another physics body, or an anchor point.
59.17444 +     *
59.17445 +     *  @class VectorField
59.17446 +     *  @constructor
59.17447 +     *  @extends Force
59.17448 +     *  @param {Object} options options to set on drag
59.17449 +     */
59.17450 +    function VectorField(options) {
59.17451 +        this.options = Object.create(VectorField.DEFAULT_OPTIONS);
59.17452 +        if (options) this.setOptions(options);
59.17453 +
59.17454 +        _setFieldOptions.call(this, this.options.field);
59.17455 +        Force.call(this);
59.17456 +
59.17457 +        //registers
59.17458 +        this.evaluation = new Vector(0,0,0);
59.17459 +    }
59.17460 +
59.17461 +    VectorField.prototype = Object.create(Force.prototype);
59.17462 +    VectorField.prototype.constructor = VectorField;
59.17463 +
59.17464 +    /**
59.17465 +     * @property Spring.FORCE_FUNCTIONS
59.17466 +     * @type Object
59.17467 +     * @protected
59.17468 +     * @static
59.17469 +     */
59.17470 +    VectorField.FIELDS = {
59.17471 +        /**
59.17472 +         * Constant force, e.g., gravity
59.17473 +         * @attribute CONSTANT
59.17474 +         * @type Function
59.17475 +         * @param v {Vector}        Current position of physics body
59.17476 +         * @param options {Object}  The direction of the force
59.17477 +         *      Pass a {direction : Vector} into the VectorField options
59.17478 +         * @return {Number} unscaled force
59.17479 +         */
59.17480 +        CONSTANT : function(v, options) {
59.17481 +            return v.set(options.direction);
59.17482 +        },
59.17483 +
59.17484 +        /**
59.17485 +         * Linear force
59.17486 +         * @attribute LINEAR
59.17487 +         * @type Function
59.17488 +         * @param v {Vector} Current position of physics body
59.17489 +         * @return {Number} unscaled force
59.17490 +         */
59.17491 +        LINEAR : function(v) {
59.17492 +            return v;
59.17493 +        },
59.17494 +
59.17495 +        /**
59.17496 +         * Radial force, e.g., Hookean spring
59.17497 +         * @attribute RADIAL
59.17498 +         * @type Function
59.17499 +         * @param v {Vector} Current position of physics body
59.17500 +         * @return {Number} unscaled force
59.17501 +         */
59.17502 +        RADIAL : function(v) {
59.17503 +            return v.set(v.mult(-1, v));
59.17504 +        },
59.17505 +
59.17506 +        /**
59.17507 +         * Spherical force
59.17508 +         * @attribute SPHERE_ATTRACTOR
59.17509 +         * @type Function
59.17510 +         * @param v {Vector}        Current position of physics body
59.17511 +         * @param options {Object}  An object with the radius of the sphere
59.17512 +         *      Pass a {radius : Number} into the VectorField options
59.17513 +         * @return {Number} unscaled force
59.17514 +         */
59.17515 +        SPHERE_ATTRACTOR : function(v, options) {
59.17516 +            return v.set(v.mult((options.radius - v.norm()) / v.norm()));
59.17517 +        },
59.17518 +
59.17519 +        /**
59.17520 +         * Point attractor force, e.g., Hookean spring with an anchor
59.17521 +         * @attribute POINT_ATTRACTOR
59.17522 +         * @type Function
59.17523 +         * @param v {Vector}        Current position of physics body
59.17524 +         * @param options {Object}  And object with the position of the attractor
59.17525 +         *      Pass a {position : Vector} into the VectorField options
59.17526 +         * @return {Number} unscaled force
59.17527 +         */
59.17528 +        POINT_ATTRACTOR : function(v, options) {
59.17529 +            return v.set(options.position.sub(v));
59.17530 +        }
59.17531 +    };
59.17532 +
59.17533 +    /**
59.17534 +     * @property VectorField.DEFAULT_OPTIONS
59.17535 +     * @type Object
59.17536 +     * @protected
59.17537 +     * @static
59.17538 +     */
59.17539 +    VectorField.DEFAULT_OPTIONS = {
59.17540 +
59.17541 +        /**
59.17542 +         * The strength of the force
59.17543 +         *    Range : [0, 10]
59.17544 +         * @attribute strength
59.17545 +         * @type Number
59.17546 +         * @default 1
59.17547 +         */
59.17548 +        strength : 1,
59.17549 +
59.17550 +        /**
59.17551 +         * Type of vectorfield
59.17552 +         *    Range : [0, 100]
59.17553 +         * @attribute field
59.17554 +         * @type Function
59.17555 +         */
59.17556 +        field : VectorField.FIELDS.CONSTANT
59.17557 +    };
59.17558 +
59.17559 +    /**
59.17560 +     * Basic options setter
59.17561 +     *
59.17562 +     * @method setOptions
59.17563 +     * @param {Objects} options
59.17564 +     */
59.17565 +    VectorField.prototype.setOptions = function setOptions(options) {
59.17566 +        for (var key in options) this.options[key] = options[key];
59.17567 +    };
59.17568 +
59.17569 +    function _setFieldOptions(field) {
59.17570 +        var FIELDS = VectorField.FIELDS;
59.17571 +
59.17572 +        switch (field) {
59.17573 +            case FIELDS.CONSTANT:
59.17574 +                if (!this.options.direction) this.options.direction = new Vector(0,1,0);
59.17575 +                break;
59.17576 +            case FIELDS.POINT_ATTRACTOR:
59.17577 +                if (!this.options.position) this.options.position = new Vector(0,0,0);
59.17578 +                break;
59.17579 +            case FIELDS.SPHERE_ATTRACTOR:
59.17580 +                if (!this.options.radius) this.options.radius = 1;
59.17581 +                break;
59.17582 +        }
59.17583 +    }
59.17584 +
59.17585 +    function _evaluate(v) {
59.17586 +        var evaluation = this.evaluation;
59.17587 +        var field = this.options.field;
59.17588 +        evaluation.set(v);
59.17589 +        return field(evaluation, this.options);
59.17590 +    }
59.17591 +
59.17592 +    /**
59.17593 +     * Adds the vectorfield's force to a physics body's force accumulator.
59.17594 +     *
59.17595 +     * @method applyForce
59.17596 +     * @param targets {Array.body} Array of bodies to apply force to.
59.17597 +     */
59.17598 +    VectorField.prototype.applyForce = function applyForce(targets) {
59.17599 +        var force = this.force;
59.17600 +        for (var i = 0; i < targets.length; i++) {
59.17601 +            var particle = targets[i];
59.17602 +            force.set(
59.17603 +                _evaluate.call(this, particle.position)
59.17604 +                .mult(particle.mass * this.options.strength)
59.17605 +            );
59.17606 +            particle.applyForce(force);
59.17607 +        }
59.17608 +    };
59.17609 +
59.17610 +    module.exports = VectorField;
59.17611 +});
59.17612 +
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/famous_styles.css	Sun Jul 06 12:02:12 2014 -0700
    60.3 @@ -0,0 +1,163 @@
    60.4 +body {
    60.5 +  color: #404040;
    60.6 +  background-color: #f2f2f0;
    60.7 +}
    60.8 +
    60.9 +.main {
   60.10 +  background-color: white;
   60.11 +}
   60.12 +
   60.13 +a {
   60.14 +  color: #fa5c4f;
   60.15 +}
   60.16 +
   60.17 +.red {
   60.18 +  color: #fa5c4f;
   60.19 +}
   60.20 +
   60.21 +.light-grey {
   60.22 +  color: #f2f2f0;
   60.23 +}
   60.24 +
   60.25 +.medium-grey {
   60.26 +  color: #878785;
   60.27 +}
   60.28 +
   60.29 +.red-bg {
   60.30 +  color: white;
   60.31 +  background-color: #fa5c4f;
   60.32 +}
   60.33 +
   60.34 +.red-outline {
   60.35 +  border: 2px solid #fa5c4f;
   60.36 +}
   60.37 +
   60.38 +.grey-bg {
   60.39 +  background-color: #404040;
   60.40 +  color: white;
   60.41 +}
   60.42 +
   60.43 +.spacer-line {
   60.44 +  border-top: 1px solid #fa5c4f;
   60.45 +}
   60.46 +
   60.47 +.white-bg {
   60.48 +  background-color: white;
   60.49 +}
   60.50 +
   60.51 +@font-face {
   60.52 +  font-family: "Avenir Next W04 Demi";
   60.53 +  src: url("fonts/7adddd91-84e0-4423-b40e-61945189916d.eot") format("eot"), url("fonts/b0908846-3d5c-4768-af33-5f968b1da156.woff") format("woff"), url("fonts/fe1602be-28ca-467e-9cd3-7bfc586f31bc.ttf") format("truetype");
   60.54 +}
   60.55 +
   60.56 +@font-face {
   60.57 +  font-family: "AvenirNextLTW02-Regular";
   60.58 +  src: url("fonts/7a1b7ae7-5c29-481f-83ac-652e932c5509.eot") format("eot"), url("fonts/3a42a252-67ff-4186-88cf-762f56719ca1.woff") format("woff"), url("fonts/dbc39ae3-2636-4653-a23e-8938bce2cf51.ttf") format("truetype");
   60.59 +}
   60.60 +
   60.61 +input:focus {
   60.62 +  border: 1px solid #fa5c4f;
   60.63 +}
   60.64 +
   60.65 +input:hover {
   60.66 +  border: 1px solid #404040;
   60.67 +}
   60.68 +
   60.69 +input {
   60.70 +  outline: 0px;
   60.71 +  border-radius: 5px;
   60.72 +  border: 1px solid #f2f2f0;
   60.73 +  padding: 18px;
   60.74 +}
   60.75 +
   60.76 +body, input {
   60.77 +  font-family: "AvenirNextLTW02-Regular", sans-serif;
   60.78 +  font-size: 16px;
   60.79 +  line-height: 25px;
   60.80 +}
   60.81 +
   60.82 +h1 {
   60.83 +  font-size: 67px;
   60.84 +  line-height: 109px;
   60.85 +  margin-bottom: 67px;
   60.86 +}
   60.87 +
   60.88 +h2 {
   60.89 +  font-size: 41px;
   60.90 +  line-height: 67px;
   60.91 +  margin-bottom: 41px;
   60.92 +}
   60.93 +
   60.94 +h3 {
   60.95 +  font-size: 25px;
   60.96 +  line-height: 41px;
   60.97 +  margin-bottom: 25px;
   60.98 +}
   60.99 +
  60.100 +h4 {
  60.101 +  font-family: "Avenir Next W04 Demi";
  60.102 +}
  60.103 +
  60.104 +h4, h5, h6, p, li, a {
  60.105 +  font-size: 16px;
  60.106 +  line-height: 25px;
  60.107 +}
  60.108 +
  60.109 +h1, h2, h3, h4, h5, h6 {
  60.110 +  max-width: 845px;
  60.111 +}
  60.112 +
  60.113 +p {
  60.114 +  max-width: 522px;
  60.115 +}
  60.116 +
  60.117 +h5 {
  60.118 +  text-transform: uppercase;
  60.119 +}
  60.120 +
  60.121 +a {
  60.122 +  text-decoration: none;
  60.123 +}
  60.124 +
  60.125 +a:hover {
  60.126 +  text-decoration: underline;
  60.127 +}
  60.128 +
  60.129 +pre {
  60.130 +  font-family: monospace;
  60.131 +  width: 100%;
  60.132 +  background-color: #404040;
  60.133 +  border-radius: 5px;
  60.134 +  padding: 27px 18px;
  60.135 +  overflow-x: scroll;
  60.136 +}
  60.137 +
  60.138 +ul {
  60.139 +  margin-left: 25px;
  60.140 +}
  60.141 +
  60.142 +code {
  60.143 +  width: 100%;
  60.144 +}
  60.145 +
  60.146 +p, pre, ul {
  60.147 +  margin-bottom: 25px;
  60.148 +}
  60.149 +
  60.150 +small {
  60.151 +  font-size: 9px;
  60.152 +  line-height: 9px;
  60.153 +}
  60.154 +
  60.155 +.button {
  60.156 +  padding: 18px;
  60.157 +  border-radius: 3px;
  60.158 +  margin: 29px 0px;
  60.159 +}
  60.160 +
  60.161 +.backface-visible {
  60.162 +  backface-visibility: visible;
  60.163 +  -webkit-backface-visibility: visible;
  60.164 +  -moz-backface-visibility: visible;
  60.165 +  -ms-backface-visibility: visible;
  60.166 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/functionPrototypeBind.js	Sun Jul 06 12:02:12 2014 -0700
    61.3 @@ -0,0 +1,23 @@
    61.4 +if (!Function.prototype.bind) {
    61.5 +    Function.prototype.bind = function (oThis) {
    61.6 +        if (typeof this !== "function") {
    61.7 +            // closest thing possible to the ECMAScript 5 internal IsCallable function
    61.8 +            throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    61.9 +        }
   61.10 +
   61.11 +        var aArgs = Array.prototype.slice.call(arguments, 1), 
   61.12 +        fToBind = this, 
   61.13 +        fNOP = function () {},
   61.14 +        fBound = function () {
   61.15 +            return fToBind.apply(this instanceof fNOP && oThis
   61.16 +                ? this
   61.17 +                : oThis,
   61.18 +                aArgs.concat(Array.prototype.slice.call(arguments)));
   61.19 +        };
   61.20 +
   61.21 +        fNOP.prototype = this.prototype;
   61.22 +        fBound.prototype = new fNOP();
   61.23 +
   61.24 +        return fBound;
   61.25 +    };
   61.26 +}
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/requestAnimationFrame.js	Sun Jul 06 12:02:12 2014 -0700
    62.3 @@ -0,0 +1,13 @@
    62.4 +// adds requestAnimationFrame functionality
    62.5 +// Source: http://strd6.com/2011/05/better-window-requestanimationframe-shim/
    62.6 +
    62.7 +window.requestAnimationFrame || (window.requestAnimationFrame = 
    62.8 +  window.webkitRequestAnimationFrame || 
    62.9 +  window.mozRequestAnimationFrame    || 
   62.10 +  window.oRequestAnimationFrame      || 
   62.11 +  window.msRequestAnimationFrame     || 
   62.12 +  function(callback, element) {
   62.13 +    return window.setTimeout(function() {
   62.14 +      callback(+new Date());
   62.15 +  }, 1000 / 60);
   62.16 +});
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/1__Development/0__Code_Dev/Javascript_approach/lib/require.js	Sun Jul 06 12:02:12 2014 -0700
    63.3 @@ -0,0 +1,36 @@
    63.4 +/*
    63.5 + RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
    63.6 + Available via the MIT or new BSD license.
    63.7 + see: http://github.com/jrburke/requirejs for details
    63.8 +*/
    63.9 +var requirejs,require,define;
   63.10 +(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
   63.11 +RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n=
   63.12 +I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b;
   63.13 +g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0,
   63.14 +b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));
   63.15 +return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]=
   63.16 +!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+
   63.17 +f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;
   63.18 +for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?
   63.19 +a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
   63.20 +b;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
   63.21 +this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
   63.22 +(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
   63.23 +this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
   63.24 +if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
   63.25 +"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
   63.26 +a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
   63.27 +nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
   63.28 +a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
   63.29 +!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
   63.30 +d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,
   63.31 +c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0,
   63.32 +d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C("scripterror",
   63.33 +"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
   63.34 +Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};
   63.35 +h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.11";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=
   63.36 +b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
   63.37 +(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
   63.38 +Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
   63.39 +(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);
    64.1 Binary file 1__Development/9__Design_documents/0__figures__on_which_work_out_fundamentals_of_EQNLang/09_My_26___HamiltonianPath_and_Taylor_series.pdf has changed