cari
Rumahhujung hadapan webTutorial H5教你如何用HTML5和JS实现切水果游戏


切水果游戏曾经是一款风靡手机的休闲游戏,今天要介绍的就是一款网页版的切水果游戏,由JavaScript和HTML5实现,虽然功能和原版的相差很大,但是基本的功能还是具备了,还是模仿挺逼真的。有一定JavaScript水平的朋友可以看看源代码,相信你的JavaScript水平会有很大提升。

所有JavaScript代码

/**
 * this file was compiled by jsbuild 0.9.6
 * @date Fri, 20 Jul 2012 16:21:18 UTC
 * @author dron
 * @site http://ucren.com
 */

void function(global){
	var mapping = {}, cache = {};
	global.startModule = function(m){
		require(m).start();
	};
	global.define = function(id, func){
		mapping[id] = func;
	};
	global.require = function(id){
		if(!/\.js$/.test(id))
			id += '.js';
		if(cache[id])
			return cache[id];
		else
			return cache[id] = mapping[id]({});
	};
}(this);

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\collide.js
 */ 
define("scripts/collide.js", function(exports){
	var fruit = require("scripts/factory/fruit");
	var Ucren = require("scripts/lib/ucren");

	var fruits = fruit.getFruitInView();

	/**
	 * 碰撞检测
	 */

	exports.check = function( knife ){
		var ret = [], index = 0;

		fruits.forEach(function( fruit ){
		    var ck = lineInEllipse(
		    	knife.slice( 0, 2 ), 
		    	knife.slice( 2, 4 ), 
		    	[ fruit.originX, fruit.originY ],
		    	fruit.radius
		    );
		    if( ck )
		        ret[ index ++ ] = fruit;
		});
		return ret;
	};

	function sqr(x){
		return x * x;
	}

	function sign(n){
		return n < 0 ? -1 : ( n > 0 ? 1 : 0 );
	}

	function equation12( a, b, c ){
		if(a == 0)return;

		var delta = b * b - 4 * a * c;
		if(delta == 0)
			return [ -1 * b / (2 * a), -1 * b / (2 * a) ];
		else if(delta > 0)
			return [ (-1 * b + Math.sqrt(delta)) / (2 * a),  (-1 * b - Math.sqrt(delta)) / (2 * a) ];
	}

	// 返回线段和椭圆的两个交点,如果不相交,返回 null
	function lineXEllipse( p1, p2, c, r, e ){
		// 线段:p1, p2    圆心:c    半径:r    离心率:e
		if (r <= 0) return;
		e = e === undefined ? 1 : e;
		var t1 = r, t2 = r * e, k;

		a = sqr( t2) * sqr(p1[0] - p2[0]) + sqr(t1) * sqr(p1[1] - p2[1]);

		if (a <= 0) return;

		b = 2 * sqr(t2) * (p2[0] - p1[0]) * (p1[0] - c[0]) + 2 * sqr(t1) * (p2[1] - p1[1]) * (p1[1] - c[1]);
		c = sqr(t2) * sqr(p1[0] - c[0]) + sqr(t1) * sqr(p1[1] - c[1]) - sqr(t1) * sqr(t2);

		if (!( k = equation12(a, b, c, t1, t2) )) return;

		var result = [
			[ p1[0] + k[0] * (p2[0] - p1[0]), p1[1] + k[0] * (p2[1] - p1[1]) ],
			[ p1[0] + k[1] * (p2[0] - p1[0]), p1[1] + k[1] * (p2[1] - p1[1]) ]
		];

		if ( !( ( sign( result[0][0] - p1[0] ) * sign( result[0][0] - p2[0] ) <= 0 ) &&
			( sign( result[0][1] - p1[1] ) * sign( result[0][1] - p2[1] ) <= 0 ) ) )
			result[0] = null;

		if ( !( ( sign( result[1][0] - p1[0] ) * sign( result[1][0] - p2[0] ) <= 0 ) &&
			( sign( result[1][1] - p1[1] ) * sign( result[1][1] - p2[1] ) <= 0 ) ) )
			result[1] = null;

		return result;
	}

	// 判断计算线段和椭圆是否相交
	function lineInEllipse( p1, p2, c, r, e ){
		var t = lineXEllipse( p1, p2, c, r, e );
		return t && ( t[0] || t[1] );
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\control.js
 */ 
define("scripts/control.js", function(exports){
	var Ucren = require("scripts/lib/ucren");
	var knife = require("scripts/object/knife");
	var message = require("scripts/message");
	var state = require("scripts/state");

	var canvasLeft, canvasTop;

	canvasLeft = canvasTop = 0;

	exports.init = function(){
		this.fixCanvasPos();
		this.installDragger();
		this.installClicker();
	};

	exports.installDragger = function(){
	    var dragger = new Ucren.BasicDrag({ type: "calc" });

	    dragger.on( "returnValue", function( dx, dy, x, y, kf ){
	    	if( kf = knife.through( x - canvasLeft, y - canvasTop ) )
	            message.postMessage( kf, "slice" );
	    });

	    dragger.on( "startDrag", function(){
	        knife.newKnife();
	    });

	    dragger.bind( document.documentElement );
	};

	exports.installClicker = function(){
	    Ucren.addEvent( document, "click", function(){
	        if( state( "click-enable" ).ison() )
	        	message.postMessage( "click" );
	    });
	};

	exports.fixCanvasPos = function(){
		var de = document.documentElement;

		var fix = function( e ){
		    canvasLeft = ( de.clientWidth - 640 ) / 2;
		    canvasTop = ( de.clientHeight - 480 ) / 2 - 40;
		};

		fix();

		Ucren.addEvent( window, "resize", fix );
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\game.js
 */ 
define("scripts/game.js", function(exports){
	/**
	 * game logic
	 */
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");
	var sound = require("scripts/lib/sound");
	var fruit = require("scripts/factory/fruit");
	var score = require("scripts/object/score");
	var message = require("scripts/message");
	var state = require("scripts/state");
	var lose = require("scripts/object/lose");
	var gameOver = require("scripts/object/game-over");
	var knife = require("scripts/object/knife");
	// var sence = require("scripts/sence");
	var background = require("scripts/object/background");
	var light = require("scripts/object/light");

	var scoreNumber = 0;

	var random = Ucren.randomNumber;

	var volleyNum = 2, volleyMultipleNumber = 5;
	var fruits = [];
	var gameInterval;

	var snd;
	var boomSnd;

	// fruit barbette
	var barbette = function(){
	    if( fruits.length >= volleyNum )
	        return ;

	    var startX = random( 640 ), endX = random( 640 ), startY = 600;
	    var f = fruit.create( startX, startY ).shotOut( 0, endX );

	    fruits.push( f );
	    snd.play();

	    barbette();
	};

	// start game
	exports.start = function(){
	    snd = sound.create( "sound/throw" );
	    boomSnd = sound.create( "sound/boom" );
	    timeline.setTimeout(function(){
	        state( "game-state" ).set( "playing" );
	        gameInterval = timeline.setInterval( barbette, 1e3 );
	    }, 500);
	};

	exports.gameOver = function(){
	    state( "game-state" ).set( "over" );
	    gameInterval.stop();

	    gameOver.show();

	    // timeline.setTimeout(function(){
	    //     // sence.switchSence( "home-menu" );
	    //     // TODO: require 出现互相引用时,造成死循环,这个问题需要跟进,这里暂时用 postMessage 代替
	    //     message.postMessage( "home-menu", "sence.switchSence" );
	    // }, 2000);

	    scoreNumber = 0;
	    volleyNum = 2;
	    fruits.length = 0;
	};

	exports.applyScore = function( score ){
	    if( score > volleyNum * volleyMultipleNumber )
	        volleyNum ++,
	        volleyMultipleNumber += 50;
	};

	exports.sliceAt = function( fruit, angle ){
	    var index;

	    if( state( "game-state" ).isnot( "playing" ) )
	        return;

	    if( fruit.type != "boom" ){
	        fruit.broken( angle );
	        if( index = fruits.indexOf( fruit ) )
	            fruits.splice( index, 1 );
	        score.number( ++ scoreNumber );
	        this.applyScore( scoreNumber );
	    }else{
	        boomSnd.play();
	        this.pauseAllFruit();
	        background.wobble();
	        light.start( fruit );
	    }
	};

	exports.pauseAllFruit = function(){
	    gameInterval.stop();
	    knife.pause();
	    fruits.invoke( "pause" );
	};

	// message.addEventListener("fruit.fallOff", function( fruit ){
	// 	var index;
	// 	if( ( index = fruits.indexOf( fruit ) ) > -1 )
	// 	    fruits.splice( index, 1 );
	// });

	message.addEventListener("fruit.remove", function( fruit ){
	    var index;
	    if( ( index = fruits.indexOf( fruit ) ) > -1 )
	        fruits.splice( index, 1 );
	});

	var eventFruitFallOutOfViewer = function( fruit ){
	    if( fruit.type != "boom" )
	        lose.showLoseAt( fruit.originX );
	};

	state( "game-state" ).hook( function( value ){
	    if( value == "playing" )
	        message.addEventListener( "fruit.fallOutOfViewer", eventFruitFallOutOfViewer );
	    else
	        message.removeEventListener( "fruit.fallOutOfViewer", eventFruitFallOutOfViewer );
	} );

	message.addEventListener("game.over", function(){
	    exports.gameOver();
	    knife.switchOn();
	});

	message.addEventListener("overWhiteLight.show", function(){
	    knife.endAll();
	    for(var i = fruits.length - 1; i >= 0; i --)
	        fruits[i].remove();
	    background.stop();
	});

	message.addEventListener("click", function(){
	    state( "click-enable" ).off();
	    gameOver.hide();
	    message.postMessage( "home-menu", "sence.switchSence" );
	});;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\layer.js
 */ 
define("scripts/layer.js", function(exports){
	/**
	 * layer manager
	 */

	var Raphael = require("scripts/lib/raphael");
	var Ucren = require("scripts/lib/ucren");

	var layers = {};
	var zindexs = {
		"default": zi(),
		"light": zi(),
		"knife": zi(),
		"fruit": zi(),
		"juice": zi(),
		"flash": zi(),
		"mask": zi()
	};

	exports.createImage = function( layer, src, x, y, w, h ){
		layer = this.getLayer( layer );
	    return layer.image( src, x, y, w, h );
	};

	exports.createText = function( layer, text, x, y, fill, size ){
		layer = this.getLayer( layer );

		if( Ucren.isIe )
			y += 2;

		return layer.text(x, y, text).attr({
			fill: fill || "#fff",
			"font-size": size || "14px",
			"font-family": "黑体",
			"text-anchor": "start"
		});
	};

	exports.getLayer = function( name ){
		var p, layer;
		name = name || "default";

		if( p = layers[name] ){
		    return p;
		}else{
			layer = Ucren.makeElement( "p", { "class": "layer", "style": "z-index: " + ( zindexs[name] || 0 ) + ";" } );
			Ucren.Element( "extra" ).add( layer );
			p = layers[name] = Raphael( layer, 640, 480 );
			// if( Ucren.isSafari )
			//     p.safari();
			return p;
		}
	};

	function zi(){
	    return zi.num = ++ zi.num || 2;
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\main.js
 */ 
define("scripts/main.js", function(exports){
	var timeline = require("scripts/timeline");
	var tools = require("scripts/tools");
	var sence = require("scripts/sence");
	var Ucren = require("scripts/lib/ucren");
	var buzz = require("scripts/lib/buzz");
	var control = require("scripts/control");
	var csl = require("scripts/object/console");
	var message = require("scripts/message");
	var state = require("scripts/state");

	var game = require("scripts/game");

	var collide = require("scripts/collide");

	var setTimeout = timeline.setTimeout.bind( timeline );

	var log = function(){
	    var time = 1e3, add = 300, fn;
	    fn = function( text ){
	        setTimeout( function(){ csl.log( text ); }, time );
	        time += add;
	    };
	    fn.clear = function(){
	        setTimeout( csl.clear.bind( csl ), time );
	        time += add;
	    };
	    return fn;
	}();

	exports.start = function(){

	    [ timeline, sence, control ].invoke( "init" );

	    log( "正在加载鼠标控制脚本" );
	    log( "正在加载图像资源" );
		log( "正在加载游戏脚本" );
	    log( "正在加载剧情" );
	    log( "正在初始化" );
		log( "正在启动游戏..." );
	    log.clear();

	    setTimeout( sence.switchSence.saturate( sence, "home-menu" ), 3000 );
	};

	message.addEventListener("slice", function( knife ){
	    var fruits = collide.check( knife ), angle;
	    if( fruits.length )
	        angle = tools.getAngleByRadian( tools.pointToRadian( knife.slice(0, 2), knife.slice(2, 4) ) ),
	        fruits.forEach(function( fruit ){
	           message.postMessage( fruit, angle, "slice.at" );
	        });
	});

	message.addEventListener("slice.at", function( fruit, angle ){

	    if( state( "sence-state" ).isnot( "ready" ) )
	        return ;

	    if( state( "sence-name" ).is( "game-body" ) ){
	        game.sliceAt( fruit, angle );
	        return ;
	    }

	    if( state( "sence-name" ).is( "home-menu" ) ){
	        fruit.broken( angle );
	        if( fruit.isHomeMenu )
	            switch( 1 ){
	                case fruit.isDojoIcon:
	                    sence.switchSence( "dojo-body" ); break;
	                case fruit.isNewGameIcon:
	                    sence.switchSence( "game-body" ); break;
	                case fruit.isQuitIcon:
	                    sence.switchSence( "quit-body" ); break;
	            }
	        return ;
	    }
	});

	var tip = "";

	if( !Ucren.isChrome )
	    tip = "$为了获得最佳流畅度,推荐您使用 <span class=&#39;b&#39;>Google Chrome</span> 体验本游戏";

	if( !buzz.isSupported() )
	    tip = tip.replace( "$", "您的浏览器不支持 &lt;audio&gt 播放声效,且" );

	tip = tip.replace( "$", "" );

	Ucren.Element( "browser" ).html( tip );;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\message.js
 */ 
define("scripts/message.js", function(exports){
	/**
	 * a simple message manager
	 * @author dron
	 * @date 2012-06-27
	 */

	var Ucren = require("scripts/lib/ucren");

	/**
	 * send a message
	 * @param  {Any} message,message...		message contents
	 * @param  {String} to 					message address
	 */
	exports.postMessage = function( message/*, message, message... */, to ){
		var messages = [].slice.call( arguments, 0 ),
			splitIndex = messages.length - 1;

		to = messages[ splitIndex ];
		messages.slice( 0, splitIndex );

		Ucren.dispatch( to, messages );
	};

	/**
	 * bind an message handler
	 * @param {String}   from 	message address
	 * @param {Function} fn 	message handler
	 */
	exports.addEventListener = function( from, fn ){
		Ucren.dispatch( from, fn );
	};

	/**
	 * remove an message handler
	 * @param {String}   from 	message address
	 * @param {Function} fn 	message handler
	 */
	exports.removeEventListener = function( from, fn ){
		Ucren.dispatch.remove( from, fn );
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\sence.js
 */ 
define("scripts/sence.js", function(exports){
	var Ucren = require("scripts/lib/ucren");
	var sound = require("scripts/lib/sound");
	var fruit = require("scripts/factory/fruit");
	var flash = require("scripts/object/flash");

	var state = require("scripts/state");
	var message = require("scripts/message");

	// the fixed elements
	var background = require("scripts/object/background");
	var fps = require("scripts/object/fps");

	// the home page elements
	var homeMask = require("scripts/object/home-mask");
	var logo = require("scripts/object/logo");
	var ninja = require("scripts/object/ninja")
	var homeDesc = require("scripts/object/home-desc");

	var dojo = require("scripts/object/dojo");
	var newGame = require("scripts/object/new-game");
	var quit = require("scripts/object/quit");
	var newSign = require("scripts/object/new");
	var peach, sandia, boom;

	// the elements in game body
	var score = require("scripts/object/score");
	var lose = require("scripts/object/lose");

	// the game logic
	var game = require("scripts/game");

	// the elements in &#39;developing&#39; module
	var developing = require("scripts/object/developing");
	var gameOver = require("scripts/object/game-over");

	// commons
	var message = require("scripts/message");
	var timeline = require("scripts/timeline");
	var setTimeout = timeline.setTimeout.bind( timeline );
	var setInterval = timeline.setInterval.bind( timeline );

	var menuSnd;
	var gameStartSnd;

	// initialize sence
	exports.init = function(){
	    menuSnd = sound.create( "sound/menu" );
	    gameStartSnd = sound.create( "sound/start" );
		[ background, homeMask, logo, ninja, homeDesc, dojo, newSign, newGame, quit, score, lose, developing, gameOver, flash /*, fps */ ].invoke( "set" );
	    // setInterval( fps.update.bind( fps ), 500 );
	};

	// switch sence
	exports.switchSence = function( name ){
	    var curSence = state( "sence-name" );
	    var senceState = state( "sence-state" );

	    if( curSence.is( name ) )
	        return ;

	    var onHide = function(){
	        curSence.set( name );
	        senceState.set( "entering" );
	        switch( name ){
	            case "home-menu": this.showMenu( onShow ); break;
	            case "dojo-body": this.showDojo( onShow ); break;
	            case "game-body": this.showNewGame( onShow ); break;
	            case "quit-body": this.showQuit( onShow ); break;
	        }
	    }.bind( this );

	    var onShow = function(){
	        senceState.set( "ready" );

	        if( name == "dojo-body" || name == "quit-body" ){
	            exports.switchSence( "home-menu" );
	        }
	    };

	    senceState.set( "exiting" );

	    if( curSence.isunset() ) onHide();
	    else if( curSence.is( "home-menu" ) ) this.hideMenu( onHide );
	    else if( curSence.is( "dojo-body" ) ) this.hideDojo( onHide );
	    else if( curSence.is( "game-body" ) ) this.hideNewGame( onHide );
	    else if( curSence.is( "quit-body" ) ) this.hideQuit( onHide );
	};

	// to enter home page menu
	exports.showMenu = function( callback ){
	    var callee = arguments.callee;
	    var times = callee.times = ++ callee.times || 1;

	    peach = fruit.create( "peach", 137, 333, true );
	    sandia = fruit.create( "sandia", 330, 322, true );
	    boom = fruit.create( "boom", 552, 367, true, 2500 );

	    [ peach, sandia, boom ].forEach(function( f ){ f.isHomeMenu = 1; });
	    peach.isDojoIcon = sandia.isNewGameIcon = boom.isQuitIcon = 1;

	    var group = [
	    	[ homeMask, 0 ], 
	    	[ logo, 0 ], 

	    	[ ninja, 500 ], 
	    	[ homeDesc, 1500 ], 

	    	[ dojo, 2000 ], 
	    	[ newGame, 2000 ], 
	    	[ quit, 2000 ],

	        [ newSign, 2000 ],

	        [ peach, 2000 ],
	        [ sandia, 2000 ],
	        [ boom, 2000 ]
	    ];

	    group.invoke( "show" );
	    [ peach, sandia ].invoke( "rotate", 2500 );

	    menuSnd.play();
	    setTimeout( callback, 2500 );
	};

	// to exit home page menu
	exports.hideMenu = function( callback ){
	    [ newSign, dojo, newGame, quit ].invoke( "hide" );
	    [ homeMask, logo, ninja, homeDesc ].invoke( "hide" );
	    [ peach, sandia, boom ].invoke( "fallOff", 150 );

	    menuSnd.stop();
	    setTimeout( callback, fruit.getDropTimeSetting() );
	};

	// to enter game body
	exports.showNewGame = function( callback ){
	    score.show();
	    lose.show();
	    game.start();

	    gameStartSnd.play();
	    setTimeout( callback, 1000 );
	};

	// to exit game body
	exports.hideNewGame = function( callback ){
	    score.hide();
	    lose.hide();

	    gameStartSnd.stop();
	    setTimeout( callback, 1000 );
	};

	// to enter dojo mode
	exports.showDojo = function( callback ){
	    developing.show( 250 );
	    setTimeout( callback, 1500 );
	};

	// to exit dojo mode
	exports.hideDojo = function( callback ){
	    // TODO: 
	    setTimeout( callback, 1000 );
	};

	// to enter quit page
	exports.showQuit = function( callback ){
	    developing.show( 250 );
	    setTimeout( callback, 1500 );
	};

	// to exit quit page
	exports.hideQuit = function( callback ){
	    // TODO: 
	    setTimeout( callback, 1000 );
	};

	message.addEventListener("sence.switchSence", function( name ){
	    exports.switchSence( name );
	});;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\state.js
 */ 
define("scripts/state.js", function(exports){
	/**
	 * a simple state manager
	 * @author 	dron
	 * @date 	2012-06-28
	 */
	var Ucren = require("scripts/lib/ucren");
	var timeline = require("scripts/timeline");

	/**
	 * usage:
	 * state( key ).is( value )		->	determine if the value of key is the given value
	 * state( key ).isnot( value )	->	determine if the value of key is not given value
	 * state( key ).ison()			->	determine if the value of key is the boolean value &#39;true&#39;
	 * state( key ).isoff()			->	determine if the value of key is the boolean value &#39;false&#39;
	 * state( key ).isunset()		->	determine if the value of key is undefined
	 * state( key ).set( value )	->	set the value of key to a given value
	 * state( key ).get()			->	get the value of key
	 * state( key ).on()			->	set the value of key to boolean value &#39;true&#39;
	 * state( key ).off()			->	set the value of key to boolean value &#39;false&#39;
	 */

	var stack = {};
	var cache = {};
	var callbacks = {};

	exports = function( key ){

		if( cache[ key ] )
		    return cache[ key ];

		return cache[ key ] = {
			is: function( value ){
			    return stack[key] === value;
			},

			isnot: function( value ){
			    return stack[key] !== value;
			},

			ison: function(){
				return this.is( true );
			},

			isoff: function(){
				return this.isnot( true );
			},

			isunset: function(){
				return this.is( undefined );
			},

			set: function(){
				var lastValue = NaN;
				return function( value ){
				    var c;
				    stack[key] = value;
				    if( lastValue !== value && ( c = callbacks[ key ] ) )
				    	for(var i = 0, l = c.length; i < l; i ++)
				    		c[i].call( this, value );
				   	lastValue = value;
				}
			}(),

			get: function(){
			    return stack[key];
			},

			on: function(){
				var me = this;
				me.set( true );
				return {
					keep: function( time ){
						timeline.setTimeout( me.set.saturate( me, false ), time );
					}
				}
			},

			off: function(){
				var me = this;
			    me.set( false );
			    return {
			    	keep: function( time ){
			    		timeline.setTimeout( me.set.saturate( me, true ), time );
			    	}
			    }
			},

			hook: function( fn ){
				var c;
			    if( !( c = callbacks[ key ] ) )
			        callbacks[ key ] = [ fn ];
			    else
			    	c.push( fn );
			},

			unhook: function(){
			    // TODO: 
			}
		}
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\timeline.js
 */ 
define("scripts/timeline.js", function(exports){
	/**
	 * a easy timeline manager
	 * @version 1.0
	 * @author dron
	 */

	var Ucren = require("scripts/lib/ucren");
	var timerCache = {};
	var timeline = {};

	// var timer = timeline;
	// <or>
	// var timer = timeline.use( name ).init( 10 ); // to use a new timeline instance
	// 
	// var t = timer.createTask(...);
	// t.stop();
	// 
	// timer.setTimeout(...);
	// timer.setInterval(...);
	// timer.getFPS();

	function ClassTimer(){
	    this.tasks = [];
	    this.addingTasks = [];
	    this.adding = 0;
	}

	/**
	 * initialize timeline
	 */
	ClassTimer.prototype.init = function( ms ){
		var me = this;

		if( me.inited )
		    return ;
		else
			me.inited = 1;

		me.startTime = now();
		me.intervalTime = ms || 5;
		me.count = 0;

		me.intervalFn = function(){
		    me.count ++;
		    me.update( now() );
		};

		me.start();

		return me;
	};

	/**
	 * create a task
	 * @param  {Object} conf 	the config
	 * @return {Task} 			a task instance
	 */
	ClassTimer.prototype.createTask = function( conf ){
		/* e.g. timer.createTask({
			start: 500, duration: 2000, data: [a, b, c,..], object: module, 
			onTimeUpdate: fn(time, a, b, c,..), onTimeStart: fn(a, b, c,..), onTimeEnd: fn(a, b, c,..),
			recycle: []
		}); */
		var task = createTask( conf );
	    this.addingTasks.unshift( task );
	    this.adding = 1;

	    if( conf.recycle )
	    	this.taskList( conf.recycle, task );

	    this.start();

	    return task;
	};

	/**
	 * use a array to recycle the task
	 * @param  {Array} queue	be use for recycling task
	 * @param  {Task} task 		a task instance		
	 * @return {Array}			this queue
	 */
	ClassTimer.prototype.taskList = function( queue, task ){
		if( !queue.clear )
			queue.clear = function(){
				var i = this.length;
				while( i -- )
					task = this[i],
					task.stop(),
					this.splice( i, 1 );
				return this;
			};

		if( task )
		    queue.unshift( task );

		return queue;
	};

	/**
	 * create a timer for once callback
	 * @param {Function} fn 	callback function
	 * @param {Number}   time 	time, unit: ms
	 */
	ClassTimer.prototype.setTimeout = function( fn, time ){
	    // e.g. setTimeout(fn, time);
	    return this.createTask({ start: time, duration: 0, onTimeStart: fn });
	};

	/**
	 * create a timer for ongoing callback
	 * @param {Function} fn 	callback function
	 * @param {Number}   time 	time, unit: ms
	 */
	ClassTimer.prototype.setInterval = function( fn, time ){
	    // e.g. setInterval(fn, time);
	    var timer = setInterval( fn, time );
	    return {
	    	stop: function(){
	    	    clearInterval( timer );
	    	}
	    };
	};

	/**
	 * get the current fps
	 * @return {Number} fps number
	 */
	ClassTimer.prototype.getFPS = function(){
		var t = now(), c = this.count, fps = c / ( t - this.startTime ) * 1e3;
		if( c > 1e3 )
			this.count = 0,
			this.startTime = t;
		return fps;
	};

	// privates

	ClassTimer.prototype.start = function(){
		clearInterval( this.interval );
		this.interval = setInterval( this.intervalFn, this.intervalTime );
	};

	ClassTimer.prototype.stop = function(){
		clearInterval( this.interval );
	};

	ClassTimer.prototype.update = function( time ){
		var tasks = this.tasks, addingTasks = this.addingTasks, adding = this.adding;
		var i = tasks.length, t, task, start, duration, data;

		while( i -- ){
	    	task = tasks[i];
	    	start = task.start;
	    	duration = task.duration;

	    	if( time >= start ){

	    		if( task.stopped ){
	    		    tasks.splice( i, 1 );
	    		    continue;
	    		}

		    	checkStartTask( task );
		    	if( ( t = time - start ) < duration )
		    	    updateTask( task, t );
		    	else
		    		updateTask( task, duration ),
		    		task.onTimeEnd.apply( task.object, task.data.slice(1) ),
		    		tasks.splice( i, 1 );
	    	}
		}

	    if( adding )
	    	tasks.unshift.apply( tasks, addingTasks ),
	    	addingTasks.length = adding = 0;

	    if( !tasks.length )
	    	this.stop();
	};

	timeline.use = function( name ){
		var module;

		if( module = timerCache[ name ] )
		    return module;
		else
			module = timerCache[ name ] = new ClassTimer;

		return module;
	};

	/**
	 * @functions
	 */

	var now = function(){
		return new Date().getTime();
	};

	var createTask = function( conf ){
		var object = conf.object || {};
		conf.start = conf.start || 0;
		return {
			start: conf.start + now(),
			duration: conf.duration == -1 ? 86400000 : conf.duration,
			data: conf.data ? [ 0 ].concat( conf.data ) : [ 0 ],
			started: 0,
			object: object,
			onTimeStart: conf.onTimeStart || object.onTimeStart || Ucren.nul,
			onTimeUpdate: conf.onTimeUpdate || object.onTimeUpdate || Ucren.nul,
			onTimeEnd: conf.onTimeEnd || object.onTimeEnd || Ucren.nul,
			stop: function(){
			    this.stopped = 1;
			}
		}
	};

	var updateTask = function( task, time ){
		var data = task.data;
		data[0] = time;
		task.onTimeUpdate.apply( task.object, data );
	};

	var checkStartTask = function( task ){
		if( !task.started )
			task.started = 1,
		    task.onTimeStart.apply( task.object, task.data.slice(1) ),
		    updateTask( task, 0 );
	};

	/**
	 * for compatible the old version
	 */
	exports = timeline.use( "default" ).init( 10 );
	exports.use = function( name ){
		if( Ucren.isIe )
		    exports;
		return timeline.use( name );
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\tools.js
 */ 
define("scripts/tools.js", function(exports){
	exports.unsetObject = function( object ){
		for(var i in object)
		    if(object.hasOwnProperty(i) && typeof object[i] == "function")
		    	object[i] = function(){};
	};

	exports.getAngleByRadian = function( radian ){
		return radian * 180 / Math.PI;
	}

	exports.pointToRadian =	function( origin, point ){
		var PI = Math.PI;

		if( point[0] === origin[0] ){
			if ( point[1] > origin[1] )
				return PI * 0.5;
			return PI * 1.5
		}else if( point[1] === origin[1] ){
			if ( point[0] > origin[0] )
				return 0;
			return PI;
		}

		var t = Math.atan( ( origin[1] - point[1] ) / ( origin[0] - point[0] ) );

		if( point[0] > origin[0] && point[1] < origin[1] )
			return t + 2 * PI;

		if( point[0] > origin[0] && point[1] > origin[1] )
			return t;

		return t + PI;
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\factory\displacement.js
 */ 
define("scripts/factory/displacement.js", function(exports){
	var layer = require("scripts/layer");
	var timeline = require("scripts/timeline");
	var tween = require("scripts/lib/tween");

	/**
	 * 位移类模块模型
	 */

	exports.create = function( imageSrc, width, height, origX, origY, targetX, targetY, animMap, animDur ){
		var module = {};
		var image;

		var anim = {};

		if( typeof animMap === "function" )
		    anim.show = anim.hide = animMap;
		else
			anim = animMap;

		var createTask = function( start, duration, sx, sy, ex, ey, anim, mode ){
			timeline.createTask({
				start: start,
				duration: duration,
				object: module, data: [ sx, sy, ex, ey, anim, mode ],
				onTimeUpdate: module.onTimeUpdate, onTimeStart: module.onTimeStart, onTimeEnd: module.onTimeEnd,
				recycle: module.anims
			});
		};

		module.anims = [];

		module.set = function(){
			image = layer.createImage( "default", imageSrc, origX, origY, width, height );
		};

		module.show = function( start ){
			createTask(  start, animDur, origX, origY, targetX, targetY, anim.show, "show" );
		};

		module.hide = function(){
			this.anims.clear();
			createTask( 0, animDur, targetX, targetY, origX, origY, anim.hide, "hide" );
		};

		module.onTimeUpdate = function( time, sx, sy, ex, ey, anim ){
		    image.attr( {
		    	x: anim( time, sx, ex - sx, animDur ),
		    	y: anim( time, sy, ey - sy, animDur )
		    } );
		};

		module.onTimeStart = function(){

		};

		module.onTimeEnd = function( sx, sy, ex, ey, anim ){
		    if( anim === "hide" )
		    	image.hide();
		};

		return module;
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\factory\fruit.js
 */ 
define("scripts/factory/fruit.js", function(exports){
	var layer = require("scripts/layer");
	var Ucren = require("scripts/lib/ucren");
	var timeline = require("scripts/timeline").use( "fruit" ).init( 1 );
	var timeline2 = require("scripts/timeline").use( "fruit-apart" ).init( 1 );
	var tween = require("scripts/lib/tween");
	var message = require("scripts/message");
	var flame = require("scripts/object/flame");
	var flash = require("scripts/object/flash");
	var juice = require("scripts/factory/juice");

	var ie = Ucren.isIe;
	var safari = Ucren.isSafari;

	/**
	 * 水果模块模型
	 */

	var zoomAnim = tween.exponential.co;
	var rotateAnim = tween.circular;
	var linearAnim = tween.linear;
	var dropAnim = tween.quadratic.ci;
	var fallOffAnim = tween.quadratic.co;

	var random = Ucren.randomNumber;
	var min = Math.min;
	var average = function( a, b ){ return ( ( a + b ) / 2 ) >> 0; };

	var dropTime = 1200, dropXScope = 200, shadowPos = 50;

	var infos = {
		// type: [ imageSrc, width, height, radius, fixAngle, isReverse, juiceColor ]
		boom: [ "images/fruit/boom.png", 66, 68, 26, 0, 0, null ],
		peach: [ "images/fruit/peach.png", 62, 59, 37, -50, 0, "#e6c731" ],
		sandia: [ "images/fruit/sandia.png", 98, 85, 38, -100, 0, "#c00" ],
		apple: [ "images/fruit/apple.png", 66, 66, 31, -54, 0, "#c8e925" ],
		banana: [ "images/fruit/banana.png", 126, 50, 43, 90, 0, null ],
		basaha: [ "images/fruit/basaha.png", 68, 72, 32, -135, 0, "#c00" ]
	};

	// TODO: 是否水果全开?
	var types = [ "peach", "sandia", "apple", "banana", "basaha" ];
	// var types = [ "sandia", "boom" ];
	var rotateSpeed = [ 60, 50, 40, -40, -50, -60 ];

	var fruitCache = [];

	function ClassFruit(conf){
	    var info = infos[ conf.type ], radius = info[3];

		this.type = conf.type;
	    this.originX = conf.originX;
	    this.originY = conf.originY;
	    this.radius = radius;
	    this.startX = conf.originX;
	    this.startY = conf.originY;
	    this.radius = radius;

	    this.anims = [];

	    if( this.type === "boom" )
	        this.flame = flame.create( this.startX - radius + 4, this.startY - radius + 5, conf.flameStart || 0 );
	}

	ClassFruit.prototype.set = function( hide ){
		var inf = infos[ this.type ], radius = this.radius;

		this.shadow = layer.createImage( "fruit", "images/shadow.png", this.startX - radius, this.startY - radius + shadowPos, 106, 77 );
		this.image = layer.createImage( "fruit", inf[0], this.startX - radius, this.startY - radius, inf[1], inf[2] );

		if( hide )
			this.image.hide(),
			this.shadow.hide();

		return this;
	};

	ClassFruit.prototype.pos = function( x, y ){
		if( x == this.originX && y == this.originY )
		    return ;

		var r = this.radius;

		this.originX = x;
		this.originY = y;

		this.image.attr({ x: x -= r, y: y -= r });
		this.shadow.attr({ x: x, y: y + shadowPos });

		if( this.type === "boom" )
		    this.flame.pos( x + 4, y + 5 );
	};

	ClassFruit.prototype.show = function( start ){
		timeline.createTask({ 
			start: start, duration: 500, data: [ 1e-5, 1, "show" ], 
			object: this, onTimeUpdate: this.onScaling, onTimeStart: this.onShowStart,
			recycle: this.anims
		});
	};

	ClassFruit.prototype.hide = function( start ){
		if( this.type !== "boom" ) // if it is not a boom, it can&#39;t to be hide.
		    return ;

		this.anims.clear();
		this.flame.remove();
		timeline.createTask({ 
			start: start, duration: 500, data: [ 1, 1e-5, "hide" ], 
			object: this, onTimeUpdate: this.onScaling, onTimeEnd: this.onHideEnd,
			recycle: this.anims
		});	
	};

	ClassFruit.prototype.rotate = function( start, speed ){
		this.rotateSpeed = speed || rotateSpeed[ random( 6 ) ];
		this.rotateAnim = timeline.createTask({
			start: start, duration: -1, 
			object: this, onTimeUpdate: this.onRotating,
			recycle: this.anims
		});
	};

	ClassFruit.prototype.broken = function( angle ){
		if( this.brokend )return;
		this.brokend = true;

		var index;
		if( ( index = fruitCache.indexOf( this ) ) > -1 )
		    fruitCache.splice( index, 1 );

		if( this.type !== "boom" )
			flash.showAt( this.originX, this.originY, angle ),
			juice.create( this.originX, this.originY, infos[ this.type ][6] ),
		    this.apart( angle );
		else
			this.hide();
	};

	ClassFruit.prototype.pause = function(){
		if( this.brokend )
		    return;
		this.anims.clear();
		if( this.type == "boom" )
		    this.flame.remove();
	};

	// 分开
	ClassFruit.prototype.apart = function( angle ){
		this.anims.clear();
		this.image.hide();
		this.shadow.hide();
		this.aparted = true;

		var inf = infos[ this.type ], preSrc = inf[0].replace( ".png", "" ), radius = this.radius;
		var create = layer.createImage.saturate( layer, this.startX - radius, this.startY - radius, inf[1], inf[2] );

		angle = ( ( angle % 180 ) + 360 + inf[4] ) % 360;

		this.bImage1 = create( "fruit", preSrc + "-1.png" );
		this.bImage2 = create( "fruit", preSrc + "-2.png" );

		[ this.bImage1, this.bImage2 ].invoke( "rotate", angle );

		this.apartAngle = angle;
		timeline2.createTask({ 
			start: 0, duration: dropTime, object: this, 
			onTimeUpdate: this.onBrokenDropUpdate, onTimeStart: this.onBrokenDropStart, onTimeEnd: this.onBrokenDropEnd,
			recycle: this.anims
		});
	};

	// 抛出
	ClassFruit.prototype.shotOut = function(){
		var sign = [ -1, 1 ];
	    return function( start, endX ){

			this.shotOutStartX = this.originX;
			this.shotOutStartY = this.originY;
			this.shotOutEndX = average( this.originX, endX );
			this.shotOutEndY = min( this.startY - random( this.startY - 100 ), 200 );
			this.fallOffToX = endX;

			timeline.createTask({
				start: start, duration: dropTime, object: this,
				onTimeUpdate: this.onShotOuting, onTimeStart: this.onShotOutStart, onTimeEnd: this.onShotOutEnd,
				recycle: this.anims
			});

			if( this.type != "boom" )
			 	this.rotate( 0, ( random( 180 ) + 90 ) * sign[ random( 2 ) ] );

			return this;
		};
	}();

	// 掉落
	ClassFruit.prototype.fallOff = function(){
		var sign = [ -1, 1 ];
		var signIndex = 0;
	    return function( start, x ){

			if( this.aparted || this.brokend )
				return ;

			var y = 600;

			if( typeof x !== "number" )
			    x = this.originX + random( dropXScope ) * sign[ ( signIndex ++ ) % 2 ];

			this.fallTargetX = x;
			this.fallTargetY = y;

			timeline.createTask({
				start: start, duration: dropTime, object: this,
				onTimeUpdate: this.onFalling, onTimeStart: this.onFallStart, onTimeEnd: this.onFallEnd,
				recycle: this.anims
			});
		}
	}();

	ClassFruit.prototype.remove = function(){
		var index;

		this.anims.clear();

		if( this.image )
			this.image.remove(),
			this.shadow.remove();

		if( this.bImage1 )
			this.bImage1.remove(),
			this.bImage2.remove();

		if( this.type === "boom" )
		    this.flame.remove();

		if( ( index = fruitCache.indexOf( this ) ) > -1 )
		    fruitCache.splice( index, 1 );

		for(var name in this)
			if( typeof this[name] === "function" )
				this[name] = function( name ){
				    return function(){
					    throw new Error( "method " + name + " has been removed" );
					};
				}( name );
			else delete this[name];

		message.postMessage( this, "fruit.remove" );
	};

	// 显示/隐藏 相关

	ClassFruit.prototype.onShowStart = function(){
		this.image.show();
		// this.shadow.show();
	};

	ClassFruit.prototype.onScaling = function( time, a, b, z ){
		this.image.scale( z = zoomAnim( time, a, b - a, 500 ), z );
		this.shadow.scale( z, z );
	};

	ClassFruit.prototype.onHideEnd = function(){
		this.remove();
	};

	// 旋转相关

	ClassFruit.prototype.onRotateStart = function(){

	};

	ClassFruit.prototype.onRotating = function( time ){
		this.image.rotate( ( this.rotateSpeed * time / 1e3 ) % 360, true );
	};

	// 裂开相关

	ClassFruit.prototype.onBrokenDropUpdate = function( time ){
		var radius = this.radius;
		this.bImage1.attr({ 
			x: linearAnim( time, this.brokenPosX - radius, this.brokenTargetX1, dropTime ), 
			y: dropAnim( time, this.brokenPosY - radius, this.brokenTargetY1 - this.brokenPosY + radius, dropTime ) 
		}).rotate( linearAnim( time, this.apartAngle, this.bImage1RotateAngle, dropTime ), true );
		this.bImage2.attr({ 
			x: linearAnim( time, this.brokenPosX - radius, this.brokenTargetX2, dropTime ), 
			y: dropAnim( time, this.brokenPosY - radius, this.brokenTargetY2 - this.brokenPosY + radius, dropTime ) 
		}).rotate( linearAnim( time, this.apartAngle, this.bImage2RotateAngle, dropTime ), true );
	};

	ClassFruit.prototype.onBrokenDropStart = function(){
		this.brokenTargetX1 = -( random( dropXScope ) + 75 );
		this.brokenTargetX2 = random( dropXScope + 75 );
		this.brokenTargetY1 = 600;
		this.brokenTargetY2 = 600;
		this.brokenPosX = this.originX;
		this.brokenPosY = this.originY;
		this.bImage1RotateAngle = - random( 150 ) - 50;
		this.bImage2RotateAngle = random( 150 ) + 50;

		for(var f, i = fruitCache.length - 1; i >= 0; i --)
			if( fruitCache[i] === this )
				fruitCache.splice( i, 1 );
	};

	ClassFruit.prototype.onBrokenDropEnd = function(){
		this.remove();
	};

	// 抛出相关

	ClassFruit.prototype.onShotOuting = function( time ){
		this.pos(
			linearAnim( time, this.shotOutStartX, this.shotOutEndX - this.shotOutStartX, dropTime ),
			fallOffAnim( time, this.shotOutStartY, this.shotOutEndY - this.shotOutStartY, dropTime )
		);
	};

	ClassFruit.prototype.onShotOutStart = function(){
		// body...
	};

	ClassFruit.prototype.onShotOutEnd = function(){
		this.fallOff( 0, this.fallOffToX );
	};

	// 掉落相关

	ClassFruit.prototype.onFalling = function( time ){
		var y;
		this.pos( 
			linearAnim( time, this.brokenPosX, this.fallTargetX - this.brokenPosX, dropTime ), 
			y = dropAnim( time, this.brokenPosY, this.fallTargetY - this.brokenPosY, dropTime ) 
		);
		this.checkForFallOutOfViewer( y );
	};

	ClassFruit.prototype.onFallStart = function(){
		this.brokenPosX = this.originX;
		this.brokenPosY = this.originY;
	};

	ClassFruit.prototype.onFallEnd = function(){
		message.postMessage( this, "fruit.fallOff" );
		this.remove();
	};

	// privates

	ClassFruit.prototype.checkForFallOutOfViewer = function( y ){
		if( y > 480 + this.radius )
			this.checkForFallOutOfViewer = Ucren.nul,
			this.rotateAnim && this.rotateAnim.stop(),
		    message.postMessage( this, "fruit.fallOutOfViewer" );
	};

	exports.create = function( type, originX, originY, isHide, flameStart ){
		if( typeof type == "number" ) // 缺省 type
			isHide = originY,
			originY = originX,
		    originX = type,
		    type = getType();

		var fruit = new ClassFruit({ type: type, originX: originX, originY: originY, flameStart: flameStart }).set( isHide );
		fruitCache.unshift( fruit );

		return fruit;
	};

	exports.getFruitInView = function(){
	    return fruitCache;
	};

	exports.getDropTimeSetting = function(){
		return dropTime;
	};

	function getType(){
		if( random( 8 ) == 4 )
		    return "boom";
		else
	    	return types[ random( 5 ) ];
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\factory\juice.js
 */ 
define("scripts/factory/juice.js", function(exports){
	/**
	 * 果汁
	 */
	var Ucren = require("scripts/lib/ucren");
	var layer = require("scripts/layer").getLayer("juice");
	var timeline = require("scripts/timeline").use( "juice" ).init( 10 );
	var tween = require("scripts/lib/tween");
	var tools = require("scripts/tools");

	var random = Ucren.randomNumber;
	var dur = 1500;
	var anim = tween.exponential.co;
	var dropAnim = tween.quadratic.co;
	var sin = Math.sin;
	var cos = Math.cos;

	var num = 10;
	var radius = 10;

	// if( Ucren.isIe6 || Ucren.isSafari )
	//     switchOn = false;

	// if( Ucren.isIe || Ucren.isSafari )
	// 	num = 6;

	function ClassJuice( x, y, color ){
		this.originX = x;
		this.originY = y;
		this.color = color;

	    this.distance = random( 200 ) + 100;
	    this.radius = radius;
	    this.dir = random( 360 ) * Math.PI / 180;
	}

	ClassJuice.prototype.render = function(){
		this.circle = layer.circle( this.originX, this.originY, this.radius ).attr({
			fill: this.color,
			stroke: "none"
		});
	};

	ClassJuice.prototype.sputter = function(){
		timeline.createTask({
			start: 0, duration: dur,
			object: this, onTimeUpdate: this.onTimeUpdate, onTimeEnd: this.onTimeEnd
		});
	};

	ClassJuice.prototype.onTimeUpdate = function( time ){
		var distance, x, y, z;

		distance = anim( time, 0, this.distance, dur );
		x = this.originX + distance * cos( this.dir );
		y = this.originY + distance * sin( this.dir ) + dropAnim( time, 0, 200, dur );
		z = anim( time, 1, -1, dur );

		this.circle.attr({ cx: x, cy: y }).scale( z, z );
	};

	ClassJuice.prototype.onTimeEnd = function(){
		this.circle.remove();
		tools.unsetObject( this );
	};

	exports.create = function( x, y, color ){
	    for(var i = 0; i < num; i ++)
	    	this.createOne( x, y, color );
	};

	exports.createOne = function( x, y, color ){
		if( !color )
		    return;

		var juice = new ClassJuice( x, y, color );
		juice.render();
		juice.sputter();
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\factory\rotate.js
 */ 
define("scripts/factory/rotate.js", function(exports){
	var layer = require("scripts/layer");
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");

	/**
	 * 旋转类模块模型
	 */

	exports.create = function( imageSrc, x, y, w, h, z, anim, animDur ){
		var module = {}, image;
		var rotateDire = [12, -12][Ucren.randomNumber(2)];
		var defaultAngle = Ucren.randomNumber(360);

		module.anims = [];

		module.set = function(){
		    image = layer.createImage( "default", imageSrc, x, y, w, h ).scale( z, z ).rotate( defaultAngle, true );
		};

		module.show = function(start){
			timeline.createTask({ 
				start: start, 
				duration: animDur, 
				object: this, 
				data: [z, 1], 
				onTimeUpdate: this.onZooming,
				onTimeEnd: this.onShowEnd,
				recycle: this.anims
			});
		};

		module.hide = function(start){
			this.anims.clear();
			timeline.createTask({ 
				start: start, 
				duration: animDur, 
				object: this, 
				data: [ 1, z ], 
				onTimeUpdate: this.onZooming,
				recycle: this.anims
			});
		};

		module.onShowEnd = function(name){
			this.anims.clear();
			timeline.createTask({ 
				start: 0, 
				duration: -1, 
				object: this, 
				onTimeUpdate: module.onRotating,
				recycle: this.anims
			});
		};

		module.onZooming = function(){
			var z;
			return function( time, a, b ){
			    image.scale( z = anim( time, a, b - a, animDur ), z );
			}
		}();

		module.onRotating = function(){
			var lastTime = 0, an = defaultAngle;
		    return function( time, name, a, b ){
		    	an = ( an + ( time - lastTime ) / 1e3 * rotateDire ) % 360;
		    	image.rotate( an, true );
		        lastTime = time;
			}
		}();

		return module;
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\lib\buzz.js
 */ 
define("scripts/lib/buzz.js", function(exports){
	// ----------------------------------------------------------------------------
	// Buzz, a Javascript HTML5 Audio library
	// v 1.0.x beta
	// Licensed under the MIT license.
	// http://buzz.jaysalvat.com/
	// ----------------------------------------------------------------------------
	// Copyright (C) 2011 Jay Salvat
	// http://jaysalvat.com/
	// ----------------------------------------------------------------------------
	// Permission is hereby granted, free of charge, to any person obtaining a copy
	// of this software and associated documentation files ( the "Software" ), to deal
	// in the Software without restriction, including without limitation the rights
	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	// copies of the Software, and to permit persons to whom the Software is
	// furnished to do so, subject to the following conditions:
	//
	// The above copyright notice and this permission notice shall be included in
	// all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	// THE SOFTWARE.
	// ----------------------------------------------------------------------------

	var buzz = {
	    defaults: {
	        autoplay: false,
	        duration: 5000,
	        formats: [],
	        loop: false,
	        placeholder: &#39;--&#39;,
	        preload: &#39;metadata&#39;,
	        volume: 80
	    },
	    types: {
	        &#39;mp3&#39;: &#39;audio/mpeg&#39;,
	        &#39;ogg&#39;: &#39;audio/ogg&#39;,
	        &#39;wav&#39;: &#39;audio/wav&#39;,
	        &#39;aac&#39;: &#39;audio/aac&#39;,
	        &#39;m4a&#39;: &#39;audio/x-m4a&#39;
	    },
	    sounds: [],
	    el: document.createElement( &#39;audio&#39; ),

	    sound: function( src, options ) {
	        options = options || {};

	        var pid = 0,
	            events = [],
	            eventsOnce = {},
	            supported = buzz.isSupported();

	        // publics
	        this.load = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.load();
	            return this;
	        };

	        this.play = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.play();
	            return this;
	        };

	        this.togglePlay = function() {
	            if ( !supported ) {
	              return this;
	            }

	            if ( this.sound.paused ) {
	                this.sound.play();
	            } else {
	                this.sound.pause();
	            }
	            return this;
	        };

	        this.pause = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.pause();
	            return this;
	        };

	        this.isPaused = function() {
	            if ( !supported ) {
	              return null;
	            }

	            return this.sound.paused;
	        };

	        this.stop = function() {
	            if ( !supported  ) {
	              return this;
	            }

	            this.setTime( this.getDuration() );
	            this.sound.pause();
	            return this;
	        };

	        this.isEnded = function() {
	            if ( !supported ) {
	              return null;
	            }

	            return this.sound.ended;
	        };

	        this.loop = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.loop = &#39;loop&#39;;
	            this.bind( &#39;ended.buzzloop&#39;, function() {
	                this.currentTime = 0;
	                this.play();
	            });
	            return this;
	        };

	        this.unloop = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.removeAttribute( &#39;loop&#39; );
	            this.unbind( &#39;ended.buzzloop&#39; );
	            return this;
	        };

	        this.mute = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.muted = true;
	            return this;
	        };

	        this.unmute = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.muted = false;
	            return this;
	        };

	        this.toggleMute = function() {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound.muted = !this.sound.muted;
	            return this;
	        };

	        this.isMuted = function() {
	            if ( !supported ) {
	              return null;
	            }

	            return this.sound.muted;
	        };

	        this.setVolume = function( volume ) {
	            if ( !supported ) {
	              return this;
	            }

	            if ( volume < 0 ) {
	              volume = 0;
	            }
	            if ( volume > 100 ) {
	              volume = 100;
	            }

	            this.volume = volume;
	            this.sound.volume = volume / 100;
	            return this;
	        };

	        this.getVolume = function() {
	            if ( !supported ) {
	              return this;
	            }

	            return this.volume;
	        };

	        this.increaseVolume = function( value ) {
	            return this.setVolume( this.volume + ( value || 1 ) );
	        };

	        this.decreaseVolume = function( value ) {
	            return this.setVolume( this.volume - ( value || 1 ) );
	        };

	        this.setTime = function( time ) {
	            if ( !supported ) {
	              return this;
	            }

	            this.whenReady( function() {
	                this.sound.currentTime = time;
	            });
	            return this;
	        };

	        this.getTime = function() {
	            if ( !supported ) {
	              return null;
	            }

	            var time = Math.round( this.sound.currentTime * 100 ) / 100;
	            return isNaN( time ) ? buzz.defaults.placeholder : time;
	        };

	        this.setPercent = function( percent ) {
	            if ( !supported ) {
	              return this;
	            }

	            return this.setTime( buzz.fromPercent( percent, this.sound.duration ) );
	        };

	        this.getPercent = function() {
	            if ( !supported ) {
	              return null;
	            }

				var percent = Math.round( buzz.toPercent( this.sound.currentTime, this.sound.duration ) );
	            return isNaN( percent ) ? buzz.defaults.placeholder : percent;
	        };

	        this.setSpeed = function( duration ) {
				if ( !supported ) {
	              return this;
	            }

	            this.sound.playbackRate = duration;
	        };

	        this.getSpeed = function() {
				if ( !supported ) {
	              return null;
	            }

	            return this.sound.playbackRate;
	        };

	        this.getDuration = function() {
	            if ( !supported ) {
	              return null;
	            }

	            var duration = Math.round( this.sound.duration * 100 ) / 100;
	            return isNaN( duration ) ? buzz.defaults.placeholder : duration;
	        };

	        this.getPlayed = function() {
				if ( !supported ) {
	              return null;
	            }

	            return timerangeToArray( this.sound.played );
	        };

	        this.getBuffered = function() {
				if ( !supported ) {
	              return null;
	            }

	            return timerangeToArray( this.sound.buffered );
	        };

	        this.getSeekable = function() {
				if ( !supported ) {
	              return null;
	            }

	            return timerangeToArray( this.sound.seekable );
	        };

	        this.getErrorCode = function() {
	            if ( supported && this.sound.error ) {
	                return this.sound.error.code;
	            }
	            return 0;
	        };

	        this.getErrorMessage = function() {
				if ( !supported ) {
	              return null;
	            }

	            switch( this.getErrorCode() ) {
	                case 1:
	                    return &#39;MEDIA_ERR_ABORTED&#39;;
	                case 2:
	                    return &#39;MEDIA_ERR_NETWORK&#39;;
	                case 3:
	                    return &#39;MEDIA_ERR_DECODE&#39;;
	                case 4:
	                    return &#39;MEDIA_ERR_SRC_NOT_SUPPORTED&#39;;
	                default:
	                    return null;
	            }
	        };

	        this.getStateCode = function() {
				if ( !supported ) {
	              return null;
	            }

	            return this.sound.readyState;
	        };

	        this.getStateMessage = function() {
				if ( !supported ) {
	              return null;
	            }

	            switch( this.getStateCode() ) {
	                case 0:
	                    return &#39;HAVE_NOTHING&#39;;
	                case 1:
	                    return &#39;HAVE_METADATA&#39;;
	                case 2:
	                    return &#39;HAVE_CURRENT_DATA&#39;;
	                case 3:
	                    return &#39;HAVE_FUTURE_DATA&#39;;
	                case 4:
	                    return &#39;HAVE_ENOUGH_DATA&#39;;
	                default:
	                    return null;
	            }
	        };

	        this.getNetworkStateCode = function() {
				if ( !supported ) {
	              return null;
	            }

	            return this.sound.networkState;
	        };

	        this.getNetworkStateMessage = function() {
				if ( !supported ) {
	              return null;
	            }

	            switch( this.getNetworkStateCode() ) {
	                case 0:
	                    return &#39;NETWORK_EMPTY&#39;;
	                case 1:
	                    return &#39;NETWORK_IDLE&#39;;
	                case 2:
	                    return &#39;NETWORK_LOADING&#39;;
	                case 3:
	                    return &#39;NETWORK_NO_SOURCE&#39;;
	                default:
	                    return null;
	            }
	        };

	        this.set = function( key, value ) {
	            if ( !supported ) {
	              return this;
	            }

	            this.sound[ key ] = value;
	            return this;
	        };

	        this.get = function( key ) {
	            if ( !supported ) {
	              return null;
	            }

	            return key ? this.sound[ key ] : this.sound;
	        };

	        this.bind = function( types, func ) {
	            if ( !supported ) {
	              return this;
	            }

	            types = types.split( &#39; &#39; );

	            var that = this,
					efunc = function( e ) { func.call( that, e ); };

	            for( var t = 0; t < types.length; t++ ) {
	                var type = types[ t ],
	                    idx = type;
	                    type = idx.split( &#39;.&#39; )[ 0 ];

	                    events.push( { idx: idx, func: efunc } );
	                    this.sound.addEventListener( type, efunc, true );
	            }
	            return this;
	        };

	        this.unbind = function( types ) {
	            if ( !supported ) {
	              return this;
	            }

	            types = types.split( &#39; &#39; );

	            for( var t = 0; t < types.length; t++ ) {
	                var idx = types[ t ],
	                    type = idx.split( &#39;.&#39; )[ 0 ];

	                for( var i = 0; i < events.length; i++ ) {
	                    var namespace = events[ i ].idx.split( &#39;.&#39; );
	                    if ( events[ i ].idx == idx || ( namespace[ 1 ] && namespace[ 1 ] == idx.replace( &#39;.&#39;, &#39;&#39; ) ) ) {
	                        this.sound.removeEventListener( type, events[ i ].func, true );
	                        // remove event
	                        events.splice(i, 1);
	                    }
	                }
	            }
	            return this;
	        };

	        this.bindOnce = function( type, func ) {
	            if ( !supported ) {
	              return this;
	            }

	            var that = this;

	            eventsOnce[ pid++ ] = false;
	            this.bind( pid + type, function() {
	               if ( !eventsOnce[ pid ] ) {
	                   eventsOnce[ pid ] = true;
	                   func.call( that );
	               }
	               that.unbind( pid + type );
	            });
	        };

	        this.trigger = function( types ) {
	            if ( !supported ) {
	              return this;
	            }

	            types = types.split( &#39; &#39; );

	            for( var t = 0; t < types.length; t++ ) {
	                var idx = types[ t ];

	                for( var i = 0; i < events.length; i++ ) {
	                    var eventType = events[ i ].idx.split( &#39;.&#39; );
	                    if ( events[ i ].idx == idx || ( eventType[ 0 ] && eventType[ 0 ] == idx.replace( &#39;.&#39;, &#39;&#39; ) ) ) {
	                        var evt = document.createEvent(&#39;HTMLEvents&#39;);
	                        evt.initEvent( eventType[ 0 ], false, true );
	                        this.sound.dispatchEvent( evt );
	                    }
	                }
	            }
	            return this;
	        };

	        this.fadeTo = function( to, duration, callback ) {
				if ( !supported ) {
	              return this;
	            }

	            if ( duration instanceof Function ) {
	                callback = duration;
	                duration = buzz.defaults.duration;
	            } else {
	                duration = duration || buzz.defaults.duration;
	            }

	            var from = this.volume,
					delay = duration / Math.abs( from - to ),
	                that = this;
	            this.play();

	            function doFade() {
	                setTimeout( function() {
	                    if ( from < to && that.volume < to ) {
	                        that.setVolume( that.volume += 1 );
	                        doFade();
	                    } else if ( from > to && that.volume > to ) {
	                        that.setVolume( that.volume -= 1 );
	                        doFade();
	                    } else if ( callback instanceof Function ) {
	                        callback.apply( that );
	                    }
	                }, delay );
	            }
	            this.whenReady( function() {
	                doFade();
	            });

	            return this;
	        };

	        this.fadeIn = function( duration, callback ) {
	            if ( !supported ) {
	              return this;
	            }

	            return this.setVolume(0).fadeTo( 100, duration, callback );
	        };

	        this.fadeOut = function( duration, callback ) {
				if ( !supported ) {
	              return this;
	            }

	            return this.fadeTo( 0, duration, callback );
	        };

	        this.fadeWith = function( sound, duration ) {
	            if ( !supported ) {
	              return this;
	            }

	            this.fadeOut( duration, function() {
	                this.stop();
	            });

	            sound.play().fadeIn( duration );

	            return this;
	        };

	        this.whenReady = function( func ) {
	            if ( !supported ) {
	              return null;
	            }

	            var that = this;
	            if ( this.sound.readyState === 0 ) {
	                this.bind( &#39;canplay.buzzwhenready&#39;, function() {
	                    func.call( that );
	                });
	            } else {
	                func.call( that );
	            }
	        };

	        // privates
	        function timerangeToArray( timeRange ) {
	            var array = [],
	                length = timeRange.length - 1;

	            for( var i = 0; i <= length; i++ ) {
	                array.push({
	                    start: timeRange.start( length ),
	                    end: timeRange.end( length )
	                });
	            }
	            return array;
	        }

	        function getExt( filename ) {
	            return filename.split(&#39;.&#39;).pop();
	        }

	        function addSource( sound, src ) {
	            var source = document.createElement( &#39;source&#39; );
	            source.src = src;
	            if ( buzz.types[ getExt( src ) ] ) {
	                source.type = buzz.types[ getExt( src ) ];
	            }
	            sound.appendChild( source );
	        }

	        // init
	        if ( supported && src ) {

	            for(var i in buzz.defaults ) {
	              if(buzz.defaults.hasOwnProperty(i)) {
	                options[ i ] = options[ i ] || buzz.defaults[ i ];
	              }
	            }

	            this.sound = document.createElement( &#39;audio&#39; );

	            if ( src instanceof Array ) {
	                for( var j in src ) {
	                  if(src.hasOwnProperty(j)) {
	                    addSource( this.sound, src[ j ] );
	                  }
	                }
	            } else if ( options.formats.length ) {
	                for( var k in options.formats ) {
	                  if(options.formats.hasOwnProperty(k)) {
	                    addSource( this.sound, src + &#39;.&#39; + options.formats[ k ] );
	                  }
	                }
	            } else {
	                addSource( this.sound, src );
	            }

	            if ( options.loop ) {
	                this.loop();
	            }

	            if ( options.autoplay ) {
	                this.sound.autoplay = &#39;autoplay&#39;;
	            }

	            if ( options.preload === true ) {
	                this.sound.preload = &#39;auto&#39;;
	            } else if ( options.preload === false ) {
	                this.sound.preload = &#39;none&#39;;
	            } else {
	                this.sound.preload = options.preload;
	            }

	            this.setVolume( options.volume );

	            buzz.sounds.push( this );
	        }
	    },

	    group: function( sounds ) {
	        sounds = argsToArray( sounds, arguments );

	        // publics
	        this.getSounds = function() {
	            return sounds;
	        };

	        this.add = function( soundArray ) {
	            soundArray = argsToArray( soundArray, arguments );
	            for( var a = 0; a < soundArray.length; a++ ) {
	                sounds.push( soundArray[ a ] );
	            }
	        };

	        this.remove = function( soundArray ) {
	            soundArray = argsToArray( soundArray, arguments );
	            for( var a = 0; a < soundArray.length; a++ ) {
	                for( var i = 0; i < sounds.length; i++ ) {
	                    if ( sounds[ i ] == soundArray[ a ] ) {
	                        delete sounds[ i ];
	                        break;
	                    }
	                }
	            }
	        };

	        this.load = function() {
	            fn( &#39;load&#39; );
	            return this;
	        };

	        this.play = function() {
	            fn( &#39;play&#39; );
	            return this;
	        };

	        this.togglePlay = function( ) {
	            fn( &#39;togglePlay&#39; );
	            return this;
	        };

	        this.pause = function( time ) {
	            fn( &#39;pause&#39;, time );
	            return this;
	        };

	        this.stop = function() {
	            fn( &#39;stop&#39; );
	            return this;
	        };

	        this.mute = function() {
	            fn( &#39;mute&#39; );
	            return this;
	        };

	        this.unmute = function() {
	            fn( &#39;unmute&#39; );
	            return this;
	        };

	        this.toggleMute = function() {
	            fn( &#39;toggleMute&#39; );
	            return this;
	        };

	        this.setVolume = function( volume ) {
	            fn( &#39;setVolume&#39;, volume );
	            return this;
	        };

	        this.increaseVolume = function( value ) {
	            fn( &#39;increaseVolume&#39;, value );
	            return this;
	        };

	        this.decreaseVolume = function( value ) {
	            fn( &#39;decreaseVolume&#39;, value );
	            return this;
	        };

	        this.loop = function() {
	            fn( &#39;loop&#39; );
	            return this;
	        };

	        this.unloop = function() {
	            fn( &#39;unloop&#39; );
	            return this;
	        };

	        this.setTime = function( time ) {
	            fn( &#39;setTime&#39;, time );
	            return this;
	        };

	        this.setduration = function( duration ) {
	            fn( &#39;setduration&#39;, duration );
	            return this;
	        };

	        this.set = function( key, value ) {
	            fn( &#39;set&#39;, key, value );
	            return this;
	        };

	        this.bind = function( type, func ) {
	            fn( &#39;bind&#39;, type, func );
	            return this;
	        };

	        this.unbind = function( type ) {
	            fn( &#39;unbind&#39;, type );
	            return this;
	        };

	        this.bindOnce = function( type, func ) {
	            fn( &#39;bindOnce&#39;, type, func );
	            return this;
	        };

	        this.trigger = function( type ) {
	            fn( &#39;trigger&#39;, type );
	            return this;
	        };

	        this.fade = function( from, to, duration, callback ) {
	            fn( &#39;fade&#39;, from, to, duration, callback );
	            return this;
	        };

	        this.fadeIn = function( duration, callback ) {
	            fn( &#39;fadeIn&#39;, duration, callback );
	            return this;
	        };

	        this.fadeOut = function( duration, callback ) {
	            fn( &#39;fadeOut&#39;, duration, callback );
	            return this;
	        };

	        // privates
	        function fn() {
	            var args = argsToArray( null, arguments ),
	                func = args.shift();

	            for( var i = 0; i < sounds.length; i++ ) {
	                sounds[ i ][ func ].apply( sounds[ i ], args );
	            }
	        }

	        function argsToArray( array, args ) {
	            return ( array instanceof Array ) ? array : Array.prototype.slice.call( args );
	        }
	    },

	    all: function() {
	      return new buzz.group( buzz.sounds );
	    },

	    isSupported: function() {
	        return !!buzz.el.canPlayType;
	    },

	    isOGGSupported: function() {
	        return !!buzz.el.canPlayType && buzz.el.canPlayType( &#39;audio/ogg; codecs="vorbis"&#39; );
	    },

	    isWAVSupported: function() {
	        return !!buzz.el.canPlayType && buzz.el.canPlayType( &#39;audio/wav; codecs="1"&#39; );
	    },

	    isMP3Supported: function() {
	        return !!buzz.el.canPlayType && buzz.el.canPlayType( &#39;audio/mpeg;&#39; );
	    },

	    isAACSupported: function() {
	        return !!buzz.el.canPlayType && ( buzz.el.canPlayType( &#39;audio/x-m4a;&#39; ) || buzz.el.canPlayType( &#39;audio/aac;&#39; ) );
	    },

	    toTimer: function( time, withHours ) {
	        var h, m, s;
	        h = Math.floor( time / 3600 );
	        h = isNaN( h ) ? &#39;--&#39; : ( h >= 10 ) ? h : &#39;0&#39; + h;
	        m = withHours ? Math.floor( time / 60 % 60 ) : Math.floor( time / 60 );
	        m = isNaN( m ) ? &#39;--&#39; : ( m >= 10 ) ? m : &#39;0&#39; + m;
	        s = Math.floor( time % 60 );
	        s = isNaN( s ) ? &#39;--&#39; : ( s >= 10 ) ? s : &#39;0&#39; + s;
	        return withHours ? h + &#39;:&#39; + m + &#39;:&#39; + s : m + &#39;:&#39; + s;
	    },

	    fromTimer: function( time ) {
	        var splits = time.toString().split( &#39;:&#39; );
	        if ( splits && splits.length == 3 ) {
	            time = ( parseInt( splits[ 0 ], 10 ) * 3600 ) + ( parseInt(splits[ 1 ], 10 ) * 60 ) + parseInt( splits[ 2 ], 10 );
	        }
	        if ( splits && splits.length == 2 ) {
	            time = ( parseInt( splits[ 0 ], 10 ) * 60 ) + parseInt( splits[ 1 ], 10 );
	        }
	        return time;
	    },

	    toPercent: function( value, total, decimal ) {
			var r = Math.pow( 10, decimal || 0 );

			return Math.round( ( ( value * 100 ) / total ) * r ) / r;
	    },

	    fromPercent: function( percent, total, decimal ) {
			var r = Math.pow( 10, decimal || 0 );

	        return  Math.round( ( ( total / 100 ) * percent ) * r ) / r;
	    }
	};

	exports = buzz;;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\lib\raphael.js
 */ 
define("scripts/lib/raphael.js", function(exports){
	/*
	 * Raphael 1.5.2 - JavaScript Vector Library
	 *
	 * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
	 * Licensed under the MIT (http://raphaeljs.com/license.html) license.
	 */

	var Raphael;
	var window = {};
	(function(){
	function a(){
	if(a.is(arguments[0],G))
	{
	var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();
	for(var g=0,h=b[w];g<h;g++){
	var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))
	}
	return e
	}
	return bV[m](a,arguments)}a.version="1.5.2";
	var b=/[, ]+/,
	    c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},
	    d=/\{(\d+)\}/g,
	    e="prototype",
	    f="hasOwnProperty",
	    g=document,
	    h=window,
	    i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},
	    j=function(){this.customAttributes={}},
	    k,
	    l="appendChild",
	    m="apply",
	    n="concat",
	    o="createTouch"in g,
	    p="",
	    q=" ",
	    r=String,
	    s="split",
t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),
u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},
	    v="join",
	    w="length",
	    x=r[e].toLowerCase,
	    y=Math,
	    z=y.max,
	    A=y.min,
	    B=y.abs,
	    C=y.pow,
	    D=y.PI,
	    E="number",
	    F="string",
	    G="array",
	    H="toString",
	    I="fill",
	    J=Object[e][H],
	    K={},
	    L="push",
	    M=/^url\([&#39;"]?([^\)]+?)[&#39;"]?\)$/i
N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
O={"NaN":1,Infinity:1,"-Infinity":1},
P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
Q=y.round,
R="setAttribute",
S=parseFloat,
T=parseInt,
U=" progid:DXImageTransform.Microsoft",
V=r[e].toUpperCase,
W={
blur:0,
"clip-rect":"0 0 1e9 1e9",
cursor:"default",
cx:0,
cy:0,
fill:"#fff",
"fill-opacity":1,
font:"10px \"Arial\"",
"font-family":"\"Arial\"",
"font-size":"10",
"font-style":"normal",
"font-weight":400,
gradient:0,
height:0,
href:" 
opacity:1,
path:"M0,0",
r:0,
rotation:0,
rx:0,
ry:0,
scale:"1 1",
src:"",
stroke:"#000",
"stroke-dasharray":"",
"stroke-linecap":"butt",
"stroke-linejoin":"butt",
"stroke-miterlimit":0,
"stroke-opacity":1,
"stroke-width":1,
target:"_blank",
"text-anchor":"middle",
title:"Raphael",
translation:"0 0",
width:0,x:0,y:0
},
X={
along:"along",
blur:E,
"clip-rect":"csv",
cx:E,
cy:E,
fill:"colour",
"fill-opacity":E,
"font-size":E,
height:E,
opacity:E,
path:"path",
r:E,
rotation:"csv",
rx:E,
ry:E,
scale:"csv",
stroke:"colour",
"stroke-opacity":E,
"stroke-width":E,
translation:"csv",
width:E,
x:E,
y:E
},
Y="replace",
Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key
};
a.type=h.SVGAngle||g.implementation.hasFeature(" SVG11/feature#BasicStructure","1.1")="SVG":"VML";
if(a.type=="VML")
{
var bf=g.createElement("p"),bg;
bf.innerHTML="<v:shape adj=\"1\"/>";
bg=bf.firstChild;bg.style.behavior="url(#default#VML)";
if(!(bg&&typeof bg.adj=="object"))
return a.type=null;
bf=null
}
a.svg=!(a.vml=a.type=="VML");
j[e]=a[e];
k=j[e];
a._id=0;
a._oid=0;
a.fn={};
a.is=function(a,b){
b=x.call(b);
if(b=="finite")
return!O[f](+a);
return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b
};
a.angle=function(b,c,d,e,f,g){
{
if(f==null)
{
var h=b-d,i=c-e;
if(!h&&!i)return 0;
return((h<0)*180+y.atan(-i/-h)*180/D+360)%360
}
return a.angle(b,c,f,g)-a.angle(d,e,f,g)
}
};
a.rad=function(a){
return a%360*D/180};
a.deg=function(a){
return a*180/D%360
};
a.snapTo=function(b,c,d){
d=a.is(d,"finite")?d:10;
if(a.is(b,G)){
var e=b.length;
while(e--)
if(B(b[e]-c)<=d)
return b[e]
}
else{
b=+b;
var f=c%b;
if(f<d)
return c-f;
if(f>b-d)
return c-f+b
}
return c
};
function bh(){
var a=[],b=0;
for(;b<32;b++)
a[b]=(~(~(y.random()*16)))[H](16);
a[12]=4;
a[16]=(a[16]&3|8)[H](16);
return"r-"+a[v]("")
}
a.setWindow=function(a){
h=a;
g=h.document};
var bi=function(b){
if(a.vml)
{
var c=/^\s+|\s+$/g,d;
try{
var e=new ActiveXObject("htmlfile");
e.write("<body>");
e.close();
d=e.body
}
catch(a){
d=createPopup().document.body
}
var f=d.createTextRange();
bi=bm(function(a){
try{
d.style.color=r(a)[Y](c,p);
var b=f.queryCommandValue("ForeColor");
b=(b&255)<<16|b&65280|(b&16711680)>>>16;
return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");
h.title="Raphaël Colour Picker";
h.style.display="none";
g.body[l](h);
bi=bm(function(a){
h.style.color=a;
return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){
return"hsb("+[this.h,this.s,this.b]+")"
},
bk=function(){
return"hsl("+[this.h,this.s,this.l]+")"
},
bl=function(){
return this.hex
};
a.hsb2rgb=function(b,c,d,e){
if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b)
{
d=b.b;
c=b.s;
b=b.h;
e=b.o
}
return a.hsl2rgb(b,c,d/2,e)
};
a.hsl2rgb=function(b,c,d,e){
if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b)
{
d=b.l;
c=b.s;
b=b.h
}
if(b>1||c>1||d>1)
{
b/=360;
c/=100;
d/=100
}
var f={},g=["r","g","b"],h,i,j,k,l,m;
if(c)
{
d<0.5?h=d*(1+c):h=d+c-d*c;
i=2*d-h;
for(var n=0;n<3;n++){
j=b+1/3*-(n-1);
j<0&&j++;
j>1&&j--;
j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i
}
}
else f={r:d,g:d,b:d};
f.r*=255;
f.g*=255;
f.b*=255;
f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);
a.is(e,"finite")&&(f.opacity=e);
f.toString=bl;
return f
};
a.rgb2hsb=function(b,c,d){
if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b)
{d=b.b;c=b.g;b=b.r}
if(c==null&&a.is(b,F)){
var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1)
{b/=255;c/=255;d/=255}
var f=z(b,c,d),g=A(b,c,d),h,i,j=f;
{
if(g==f)return{h:0,s:0,b:f,toString:bj
};
var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;
h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};
a.rgb2hsl=function(b,c,d){
if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b)
{
d=b.b;c=b.g;b=b.r
}
if(c==null&&a.is(b,F))
{
var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255
}
var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;
if(g==f)k={h:0,s:0,l:j};
else{
var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;
k={h:h,s:i,l:j}}k.toString=bk;return k
};
a._path2string=function(){
return this.join(",")[Y](ba,"$1")
};
function bm(a,b,c){
function d(){
var g=Array[e].slice.call(arguments,0),h=g[v]("►"),i=d.cache=d.cache||{},j=d.count=d.count||[];
if(i[f](h))
return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];
j[L](h);i[h]=a[m](b,g);
return c?c(i[h]):i[h]
}
return d
}
a.getRGB=bm(
function(b){
if(!b||!(!((b=r(b)).indexOf("-")+1)))
return{r:-1,g:-1,b:-1,hex:"none",error:1};
if(b=="none")
return{r:-1,g:-1,b:-1,hex:"none"};
!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));
var c,d,e,g,h,i,j,k=b.match(N);
if(k){if(k[2]){g=T(k[2].substring(5),16);
e=T(k[2].substring(3,5),16);
d=T(k[2].substring(1,3),16)}
if(k[3]){
g=T((i=k[3].charAt(3))+i,16);
e=T((i=k[3].charAt(2))+i,16);
d=T((i=k[3].charAt(1))+i,16)
}
if(k[4]){j=k[4][s]($);
d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);
e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);
g=S(j[2]);
j[2].slice(-1)=="%"&&(g*=2.55);
k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));
j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);
d=S(j[0]);
j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);
g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);
(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));
j[3]&&j[3].slice(-1)=="%"&&(h/=100);
return a.hsb2rgb(d,e,g,h)
}
if(k[6])
{
j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);
j[2].slice(-1)=="%"&&(g*=2.55);
(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));
j[3]&&j[3].slice(-1)=="%"&&(h/=100);
return a.hsl2rgb(d,e,g,h)
}
k={
r:d,g:e,b:g
};
k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);
a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);
a.getColor=function(a){
var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);
b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})
}
return c.hex
};
a.getColor.reset=function(){
delete this.start
};
a.parsePathString=bm(function(b){
if(!b)
return null;
var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));
d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);
e[Y](bc,function(a,b){
b&&f[L](+b)});
if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));
g="l";b=b=="m"?"l":"L"
}
while(f[w]>=c[g]){
d[L]([b][n](f.splice(0,c[g])));
if(!c[g])break}});
d[H]=a._path2string;
return d
});
a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){
var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,
m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),
p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,
u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},
end:{x:s,y:t},alpha:u}};
var bn=bm(function(a){
if(!a)
return{
x:0,y:0,width:0,height:0
};
a=bw(a);
var b=0,c=0,d=[],e=[],f;
for(var g=0,h=a[w];g<h;g++){
f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)
}
else{
var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);
d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]
}
}
var j=A[m](0,d),k=A[m](0,e);
return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){
var c=[];
if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);
for(var d=0,e=b[w];d<e;d++){
c[d]=[];
for(var f=0,g=b[d][w];f<g;f++)
c[d][f]=b[d][f]}c[H]=a._path2string;
return c},bp=bm(function(b){
if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);
var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){
d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])
}
for(var i=h,j=b[w];i<j;i++){
var k=c[i]=[],l=b[i];
if(l[0]!=x.call(l[0]))
{
k[0]=x.call(l[0]);
switch(k[0]){
case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);
k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];
default:
for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)
}
}else{
k=c[i]=[];
if(l[0]=="m"){
f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]
}
var q=c[i][w];
switch(c[i][0]){
case"z":d=f;e=g;break;
case"h":d+=+c[i][q-1];break;
case"v":e+=+c[i][q-1];break;
default:d+=+c[i][q-2];
e+=+c[i][q-1]
}
}c[H]=a._path2string;
return c
},0,bo),bq=bm(function(b){
if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);
var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){
d=+b[0][1];e=+b[0][2];
f=d;g=e;h++;c[0]=["M",d,e]
}
for(var i=h,j=b[w];i<j;i++){
var k=c[i]=[],l=b[i];
if(l[0]!=V.call(l[0])){
k[0]=V.call(l[0]);
switch(k[0]){
case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;
case"V":k[1]=+l[1]+e;break;
case"H":k[1]=+l[1]+d;break;
case"M":f=+l[1]+d;g=+l[2]+e;
default:
for(var m=1,n=l[w];m<n;m++)
k[m]=+l[m]+(m%2?d:e)
}
}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];
switch(k[0]){
case"Z":d=f;e=g;break;
case"H":d=k[1];break;
case"V":e=k[1];break;
case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];
default:
d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;
return c},null,bo
),
br=function(a,b,c,d){
return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){
var g=1/3,h=2/3;
return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]
},
bt=function(a,b,c,d,e,f,g,h,i,j){
var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);
return{x:d,y:e}});
if(j){
G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);
h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);
if(x>1)
{
x=y.sqrt(x);c=x*c;
d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,
F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));
G=a<E?D-G:G;H=h<E?D-H:H;
G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}
var I=H-G;
if(B(I)>k)
{
var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])
}
I=H-G;
var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,
T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{
if(j)
return[U,V,W][n](m);
m=[U,V,W][n](m)[v]()[s](",");
var X=[];
for(var Y=0,Z=m[w];Y<Z;Y++)
X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){
var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h
}
},bv=bm(function(a,b,c,d,e,f,g,h){
var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,
o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);
if(l>0&&l<1)
{
q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)
}
if(n>0&&n<1)
{
q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;
l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);
if(l>0&&l<1)
{
q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)
}
return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),
d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},
f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},
g=function(a,b){
var c,d;
if(!a)
return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);
switch(a[0]){
case"M":b.X=a[1];b.Y=a[2];break;
case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;
case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;
case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;
case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;
case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;
case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;
case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;
case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break
}
return a
},
h=function(a,b){
if(a[b][w]>7)
{
a[b].shift();
var e=a[b];
while(e[w])
a.splice(b++,0,["C"][n](e.splice(0,6)));
a.splice(b,1);
k=z(c[w],d&&d[w]||0)}},
i=function(a,b,e,f,g){
if(a&&b&&a[g][0]=="M"&&b[g][0]!="M")
{
b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};
for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++)
{
c[j]=g(c[j],e);h(c,j);
d&&(d[j]=g(d[j],f));
d&&h(d,j);i(c,d,e,f,j);
i(d,c,f,e,j);
var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];
e.x=l[p-2];e.y=l[p-1];
e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;
f.bx=d&&(S(o[q-4])||f.x);
f.by=d&&(S(o[q-3])||f.y);
f.x=d&&o[q-2];
f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),
bx=bm(function(b){
var c=[];
for(var d=0,e=b[w];d<e;d++){
var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);
if(f.color.error)
return null;
f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){
if(!c[d].offset)
{
var h=S(c[d-1].offset||0),i=0;
for(var j=d+1;j<e;j++){
if(c[j].offset)
{
i=c[j].offset;break
}
}
if(!i)
{
i=100;
j=e
}
i=S(i);
var k=(i-h)/(j-d+1);
for(;d<j;d++)
{
h+=k;c[d].offset=h+"%"
}
}
}
return c
}),
by=function(b,c,d,e){
var f;
if(a.is(b,F)||a.is(b,"object")){
f=a.is(b,F)?g.getElementById(b):b;
if(f.tagName)
return c==null?{
container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}
else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){
var c=this;for(var d in b){
if(b[f](d)&&!(d in a))
switch(typeof b[d]){
case"function":(function(b){a[d]=a===c?b:function(){
return b[m](c,arguments)}})(b[d]);break;
case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;
default:
a[d]=b[d];break
}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);
a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){
if(b.top===a)
return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){
if(b.bottom===a)
return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},
bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},
bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},
bF=function(a){return function(){
throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};a.pathToRelative=bp;
if(a.svg){k.svgns=" 
return+a+(~(~a)===a)*0.5};var bG=function(a,b){
if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));
else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};
a[H]=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};
var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";
bK(d,{fill:"none",stroke:"#000",path:a});
return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";
if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;
C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});
b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);
if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);
j[2]*=k;j[3]*=k;
if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);
if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);
n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();
bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);
for(var q=0,t=m[w];q<t;q++){var u=bG("stop");
bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});
o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;
return 1},
bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},
bK=function(c,d){
var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],
"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},
h=c.node,i=c.attrs,j=c.rotate(),
k=function(a,b){b=e[x.call(b)];
if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})
[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;
bG(h,{"stroke-dasharray":g[v](",")})}};
d[f]("rotation")&&(j=d.rotation);
var m=r(j)[s](b);
if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);
for(var n in d){if(d[f](n)){
if(!W[f](n))continue;var o=d[n];i[n]=o;
switch(n){case"blur":c.blur(o);break;
case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;
if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);
t=u}
n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);
break;
case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);
if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);
var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);
c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}
if(!o){
var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));
B&&B.parentNode.removeChild(B);
bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;
case"width":h[R](n,o);
if(i.fx){
n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));
case"rx":if(n=="rx"&&c.type=="rect")break;
case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);
c.pattern&&bJ(c);break;
case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;
case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;
case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;
case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;
case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;
case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;
case"stroke-dasharray":k(c,o);break;
case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;
case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;
case I:var D=r(o).match(M);
if(D){z=bG("pattern");
var E=bG("image");z.id=bh();
bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});
bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);
var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";
F.onload=function(){
bG(z,{width:this.offsetWidth,height:this.offsetHeight});
bG(E,{width:this.offsetWidth,height:this.offsetHeight});
g.body.removeChild(this);
c.paper.safari()};
g.body[l](F);F.src=D[1];
c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";
bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}
var G=a.getRGB(o);
if(G.error)
if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){
i.gradient=o;i.fill="none";break}
else{
delete d.gradient;
delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});
!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{
"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});
case"stroke":G=a.getRGB(o);h[R](n,G.hex);
n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;
case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;
case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});
case"fill-opacity":if(i.gradient){
var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));
if(H){
var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}
break}
default:
n=="font-size"&&(o=T(o,10)+"px");
var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);
break}}}
bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){
if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;
var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue(
"font-size"),10):10;if(c[f]("text")){
d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);
var i=r(c.text)[s]("\n");
for(var j=0,k=i[w];j<k;j++)
if(i[j]){var m=bG("tspan");
j&&bG(m,{dy:h*bL,x:d.x});
m[l](g.createTextNode(i[j]));
e[l](m)}
}else{
i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});
var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},
bN=function(b,c){
var d=0,e=0;
this[0]=b;
this.id=a._oid++;
this.node=b;b.raphael=this;
this.paper=c;
this.attrs=this.attrs||{};
this.transformations=[];
this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);
this.prev=c.top;
c.top&&(c.top.next=this);
c.top=this;
this.next=null},bO=bN[e];
bN[e].rotate=function(c,d,e){
if(this.removed)return this;
if(c==null){
if(this._.rt.cx)
return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);
return this._.rt.deg
}var f=this.getBBox();c=r(c)[s](b);
if(c[w]-1){
d=S(c[1]);
e=S(c[2])}c=S(c[0]);
d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;
e==null&&(d=null);
this._.rt.cx=d;
this._.rt.cy=e;
d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;
if(this._.rt.deg){
this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);
this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})
}else{
this.transformations[0]=p;
this.clip&&bG(this.clip,{transform:p})}
bG(this.node,{transform:this.transformations[v](q)});
return this
};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");
return this};
bN[e].show=function(){!this.removed&&(this.node.style.display="");
return this};
bN[e].remove=function(){
if(this.removed)return;bA(this,this.paper);
this.node.parentNode.removeChild(this.node);
for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){
if(this.removed)return this;
if(this.type=="path")return bn(this.attrs.path);
if(this.node.style.display=="none"){this.show();var a=true}var b={};
try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}
if(this.type=="text"){
b={x:b.x,y:Infinity,width:0,height:0};
for(var c=0,d=this.node.getNumberOfChars();c<d;c++){
var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);
e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();
return b};
bN[e].attr=function(b,c){
if(this.removed)return this;
if(b==null){
var d={};
for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);
this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());
d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}
if(c==null&&a.is(b,F)){
if(b=="translation")return cz.call(this);
if(b=="rotation")return this.rotate();
if(b=="scale")return this.scale();
if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}
if(c==null&&a.is(b,G)){var g={};
for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}
if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);
for(var k in this.paper.customAttributes)
if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){
var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));
this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);
return this};bN[e].toFront=function(){
if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);
return this};bN[e].toBack=function(){
if(this.removed)return this;
if(this.node.parentNode.firstChild!=this.node){
this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);
var a=this.paper}
return this};
bN[e].insertAfter=function(a){
if(this.removed)return this;
var b=a.node||a[a.length-1].node;
b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);
bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){
if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);
bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){
var c=bG("filter"),d=bG("feGaussianBlur");
b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});
c.appendChild(d);b.paper.defs.appendChild(c);
b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);
delete b._blur;
delete b.attrs.blur}b.node.removeAttribute("filter")}};
var bP=function(a,b,c,d){var e=bG("circle");
a.canvas&&a.canvas[l](e);
var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};
f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);
var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";
bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");
a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};
g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");
bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);
a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";
return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});
a.canvas&&a.canvas[l](e);var f=new bN(e,a);
f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};
f.type="text";bK(f,f.attrs);
return f},bU=function(a,b){
this.width=a||this.width;
this.height=b||this.height;
this.canvas[R]("width",this.width);
this.canvas[R]("height",this.height);
return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;
if(!c)throw new Error("SVG container not found.");
var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;
bG(i,{xmlns:" 
if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";
g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;
c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};
k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);
this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Raphaël"));
a[l](this.desc);a[l](this.defs=bG("defs"))};
k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);
for(var a in this)this[a]=bF(a)}}
if(a.vml){
var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},
bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,
ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;
if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];
c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});
return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");
for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};
a[H]=function(){
return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};
bH=function(a,b){var c=cd("group");
c.style.cssText="position:absolute;
left:0;
top:0;
width:"+b.width+"px;
height:"+b.height+"px";
c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";
e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;
c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};
a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);
return f};bK=function(c,d){c.attrs=c.attrs||{};
var e=c.node,h=c.attrs,i=e.style,j,
k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;
for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);
c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);
d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);
if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);
if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);
if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];
c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);
c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){
var o=r(d["clip-rect"])[s](b);
if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];
var q=e.clipRect||g.createElement("p"),t=q.style,u=e.parentNode;
t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";
t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";
u.parentNode.insertBefore(q,u);q[l](u);
e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);
if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";
i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);
d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^[&#39;"]+|[&#39;"]+$/g,p)+"\"");
d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);
d["font-style"]&&(i.fontStyle=d["font-style"]);
if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||
d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||
d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){
e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));
if("fill-opacity"in d||"opacity"in d){
var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);
v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){
var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;
v.type="solid";
if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){
h.fill="none";h.gradient=d.fill}}}x&&e[l](v);
var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));
if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||
d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||
C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);
C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);
var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);
d["stroke-width"]&&(C.weight=F);
F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");
C.miterlimit=d["stroke-miterlimit"]||8;
d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");
if(d["stroke-dasharray"]){
var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":
"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};
C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}
if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);
h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);
h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);
m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"<")[Y](/&/g,"&")[Y](/\n/g,"<br>"));
m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);
switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;
case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;
default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};
var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){
e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);
f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);
if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;
d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);
if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];
for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);
d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";
d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};
bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;
this.Y=0;this.attrs={};this.Group=c;
this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);
this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];
bO.rotate=function(a,c,d){
if(this.removed)return this;if(a==null){
if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);
return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);
c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;
this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};
bO.setBox=function(a,b,c){if(this.removed)return this;
var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};
for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;
var h=this.attrs,i,j,k,l;
switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;
case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;
case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;
case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);
j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);
i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;
default:i=0;j=0;k=this.paper.width;
l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;
var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);
this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;
if(ca[f](this.type)){
e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}
else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)
}else{
d.width!=(q=this.paper.width+"px")&&(d.width=q);
d.height!=(q=this.paper.height+"px")&&(d.height=q);
e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);
e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");
return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};
bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);
return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){
if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);
this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);
for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;
if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);
this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());
d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){
if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")
return this.scale();
if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]
}
if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);
return h}var i;
if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);
if(i){for(var j in this.paper.customAttributes)
if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){
var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];
for(var l in k)
k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);
i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);
(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){
!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};
bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){
this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}
return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);
a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](
this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;
a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);
return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){
this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";
c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};
bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;
width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);
var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});
h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});
a.canvas[l](e);return h};
function cc(b,c,d,e,f){
return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},
{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}
bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;
h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){
var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;
width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;
f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";
bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;
i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};
bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;
top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;
h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;
i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){
var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");
f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";
f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);
i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);
f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;
m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};
bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;
c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;
g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");
try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");
cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){
return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){
var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;
if(!c)
throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("p"),o=n.style;h=h||0;i=i||0;
f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;
k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;
top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);
o.cssText=a.format("top:0;left:0;width:{0};height:{1};
display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);
if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}
else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);
return k};k.clear=function(){
this.canvas.innerHTML=p;this.span=g.createElement("span");
this.span.style.cssText="position:absolute;left:-9999em;
top:-9999em;padding:0;margin:0;line-height:1;display:inline;";
this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){
this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);
return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);
navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){
var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});
h.setTimeout(function(){a.remove()})}:k.safari=function(){};
var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){
if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;
return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];
if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};
for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);
bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};
bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();
var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;
c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};
k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){
if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;
if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;
else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;
f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");
this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod=&#39;auto expand&#39;, filtertype=&#39;bilinear&#39;)");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);
if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);
n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};
bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};
bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};
a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);
k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);
k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();
cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};
this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){
for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);
return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;
if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};
for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;
break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);
switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];
l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}
if(k){var G=a.easing_formulas[e];
if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});
a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});
for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;
D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};
bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);
for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);
this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};
bO.translate=function(a,b){return this.attr({translation:a+" "+b})};
bO[H]=function(){return"Raphaël’s object"};a.ae=cv;
var cC=function(a){this.items=[];this[w]=0;this.type="set";
if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;
this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);
while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();
a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";
c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};
k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];
var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;
b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};
a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];
i.was?h.Raphael=a:Raphael=a})();
	exports = Raphael;;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\lib\sound.js
 */ 
define("scripts/lib/sound.js", function(exports){
	/**
	 * 简易声效控制
	 */

	/**
	 * 使用方法:
	 * 
	 * var sound = require("scripts/lib/sound/main");
	 * 
	 * var snd = sound.create("sounds/myfile");
	 * snd.play();
	 */

	var buzz = require("scripts/lib/buzz");
	var supported = buzz.isSupported();

	var config = { 
		formats: [ "ogg", "mp3" ], 
		preload: true, 
		autoload: true, 
		loop: false 
	};

	function ClassBuzz( src ){
	    this.sound = new buzz.sound( src, config );
	}

	ClassBuzz.prototype.play = function( s ){
		s = this.sound;
		s.setPercent( 0 );
		s.setVolume( 100 );
		s.play();
	};

	ClassBuzz.prototype.stop = function(){
		this.sound.fadeOut( 1e3, function(){
		    this.pause();
		} );
	};

	exports.create = function( src ){
		if( !supported )
		    return unSupported;
		else
	    	return new ClassBuzz( src );
	}

	function unSupported(){
		// TODO: 
	}

	unSupported.play =
	unSupported.stop = function(){
		// TODO: 
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\lib\tween.js
 */ 
define("scripts/lib/tween.js", function(exports){
	exports.exponential = function(){};
	exports.exponential.co = function(index, offset, target, framesNum){ 
	return (index == framesNum) ? offset + target : target * (-Math.pow(2, -10 * index / framesNum) + 1) + offset; };
	// exports.exponential.ci = function(index, offset, target, framesNum){ 
	return (index == 0) ? offset : target * Math.pow(2, 10 * (index / framesNum - 1)) + offset; 
	}

	exports.bounce = function(){};
	exports.bounce.co = function(index, offset, target, framesNum){ 
	if((index /= framesNum) < (1 / 2.75)) 
	return target * (7.5625 * index * index) + offset; 
	else if(index < (2 / 2.75)) 
	return target * (7.5625 * (index -= (1.5 / 2.75)) * index + .75) + offset; 
	else if(index < (2.5 / 2.75)) 
	return target * (7.5625 * (index -= (2.25 / 2.75)) * index + .9375) + offset; 
	else return target * (7.5625 * (index -= (2.625 / 2.75)) * index + .984375) + offset; 
	};

	exports.quadratic = function(){};
	exports.quadratic.ci = function(index, offset, target, framesNum){ 
	return target * (index /= framesNum) * index + offset; 
	};
	exports.quadratic.co = function(index, offset, target, framesNum){ 
	return - target * (index /= framesNum) * (index - 2) + offset; 
	}
	exports.quadratic.cio = function(index, offset, target, framesNum){ 
	if((index /= framesNum / 2) < 1) 
	return target / 2 * index * index + offset; else return - target / 2 * ((-- index) * (index - 2) - 1) + offset; };

	exports.circular = function(index, offset, target, framesNum){ 
	if((index /= framesNum / 2) < 1) return - target / 2 * (Math.sqrt(1 - index * index) - 1) + offset; 
	else return target / 2 * (Math.sqrt(1 - (index -= 2) * index) + 1) + offset; 
	}

	exports.linear = function(index, offset, target, framesNum){ 
	return target * index / framesNum + offset; 
	};

	exports.back = function(){};
	exports.back.ci = function(index, offset, target, framesNum, s){ 
	s = 1.70158; 
	return target * (index /= framesNum) * index * ((s + 1) * index - s) + offset; 
	};
	exports.back.co = function(index, offset, target, framesNum, s){ 
	s = 1.70158; 
	return target * ((index = index / framesNum - 1) * index * ((s + 1) * index + s) + 1) + offset; 
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\lib\ucren.js
 */ 
define("scripts/lib/ucren.js", function(exports){
	/**
	 * ucren-lite
	 * filename: boot.js
	 * author: dron
	 * version: 5.0.2.20120628
	 * date: 2009-03-15
	 * contact: ucren.com
	 */

	var Ucren;

	var blankArray = [];
	var slice = blankArray.slice;
	var join = blankArray.join;

	//
	// [基本数据类型扩展]
	//

	// String.prototype.trim
	if( !String.prototype.trim )
		String.prototype.trim = function(){
			return this.replace( /^\s+|\s+$/, "" );
		};

	// String.prototype.format
	String.prototype.format = function( conf ){
		var rtn = this, blank = {};
		Ucren.each( conf, function( item, key ){
			item = item.toString().replace( /\$/g, "$$$$" );
			rtn = rtn.replace( RegExp( "@{" + key + "}", "g" ), item );
		});
		return rtn.toString();
	};

	// String.prototype.htmlEncode
	String.prototype.htmlEncode = function(){
		var p = document.createElement( "p" );
		return function(){
			var text;
			p.appendChild( document.createTextNode( this ));
			text = p.innerHTML;
			p.innerHTML = "";
			return text;
		};
	}();

	// String.prototype.byteLength
	String.prototype.byteLength = function(){
		return this.replace( /[^\x00-\xff]/g, "  " ).length;
	};

	// String.prototype.subByte
	String.prototype.subByte = function( len, tail ){
		var s = this;
		if( s.byteLength() <= len )
			return s;
		tail = tail || "";
		len -= tail.byteLength();
		return s = s.slice( 0, len ).replace( /( [^\x00-\xff] )/g, "$1 " )
			.slice( 0, len )
			.replace( /[^\x00-\xff]$/, "" )
			.replace( /( [^\x00-\xff] ) /g, "$1" ) + tail;
	}

	// Function.prototype.defer
	Function.prototype.defer = function( scope, timeout ){
		var me = this;
		var fn = function(){
			me.apply( scope, arguments );
		};
		return setTimeout( fn, timeout );
	};

	// Function.prototype.bind
	if( !Function.prototype.bind )
		Function.prototype.bind = function( scope ){
			var me = this;
			return function(){
				return me.apply( scope, arguments );
			}
		};

	// Function.prototype.saturate
	Function.prototype.saturate = function( scope/*, args */ ){
		var fn = this, afters = slice.call( arguments, 1 );
		return function(){
			return fn.apply( scope, slice.call( arguments, 0 ).concat( afters ) );
		}
	};

	// Array.prototype.indexOf
	// if( !Array.prototype.indexOf )
		Array.prototype.indexOf = function( item, i ){
			var length = this.length;

			if( !i )
			    i = 0;

			if( i < 0 )
				i = length + i;
			for( ; i < length; i ++ )
				if( this[i] === item )
					return i;
			return -1;
		};

	// Array.prototype.every
	// if( !Array.prototype.every )
		Array.prototype.every = function( fn, context ) {
			for ( var i = 0, len = this.length; i < len; i ++ )
				if ( !fn.call( context, this[i], i, this ) )
					return false;
			return true;
		};

	// Array.prototype.filter
	// if( !Array.prototype.filter )
		Array.prototype.filter = function( fn, context ) {
			var result = [], val;
			for ( var i = 0, len = this.length; i < len; i ++ )
				if ( val = this[i], fn.call( context, val, i, this ) )
					result.push( val );
			return result;
		};

	// Array.prototype.forEach
	// if( !Array.prototype.forEach )
		Array.prototype.forEach = function( fn, context ) {
			for ( var i = 0, len = this.length; i < len; i ++ )
				fn.call( context, this[i], i, this );
		};

	// Array.prototype.map
	// if( !Array.prototype.map )
		Array.prototype.map = function( fn, context ) {
			var result = [];
			for ( var i = 0, len = this.length; i < len; i ++ )
				result[i] = fn.call( context, this[i], i, this );
			return result;
		};

	// Array.prototype.some
	// if( !Array.prototype.some )
		Array.prototype.some = function( fn, context ) {
			for ( var i = 0, len = this.length; i < len; i ++ )
				if ( fn.call( context, this[i], i, this ) )
					return true;
			return false;
		};

		Array.prototype.invoke = function( method /*, args */ ){
		    var args = slice.call( arguments, 1 );
	    	this.forEach( function( item ){
		    	if( item instanceof Array )
		    	    item[0][method].apply( item[0], item.slice( 1 ) );
		    	else
		    		item[method].apply( item, args );
		    });
		    return this;
		};

		Array.prototype.random = function(){
			var arr = this.slice( 0 ), ret = [], i = arr.length;
			while( i -- )
				ret.push( arr.splice( Ucren.randomNumber( i + 1 ), 1 )[0] );
			return ret;
		};

	Ucren = {

		//
		// [全局属性]
		//

		// Ucren.isIe
		isIe: /msie/i.test( navigator.userAgent ),

		// Ucren.isIe6
		isIe6: /msie 6/i.test( navigator.userAgent ),

		// Ucren.isFirefox
		isFirefox: /firefox/i.test( navigator.userAgent ),

		// Ucren.isSafari
		isSafari: /version\/[\d\.]+\s+safari/i.test( navigator.userAgent ),

		// Ucren.isOpera
		isOpera: /opera/i.test( navigator.userAgent ),

		// Ucren.isChrome
		isChrome: /chrome/i.test( navigator.userAgent ), //todo isChrome = true, isSafari = true

		// Ucren.isStrict
		isStrict: document.compatMode == "CSS1Compat",

		// Ucren.tempDom
		tempDom: document.createElement( "p" ),

		//
		// [全局方法]
		//

		// Ucren.apply
		apply: function( form, to, except ){
			if( !to )to = {};
			if( except ){
				Ucren.each( form, function( item, key ){
					if( key in except )
						return ;
					to[key] = item;
				});
			}else{
				Ucren.each( form, function( item, key ){
					to[key] = item;
				});
			}
			return to;
		},

		// Ucren.appendStyle
		appendStyle: function( text ){
			var style;

			if( arguments.length > 1 )
				text = join.call( arguments, "" );

			if( document.createStyleSheet ){
				style = document.createStyleSheet();
				style.cssText = text;
			}else{
				style = document.createElement( "style" );
				style.type = "text/css";
				//style.innerHTML = text; fix Chrome bug
				style.appendChild( document.createTextNode( text ));
				document.getElementsByTagName( "head" )[0].appendChild( style );
			}
		},

		// for copy : )
		//
		// var addEvent = function( target, name, fn ){
		// 	var call = function(){
		// 		fn.apply( target, arguments );
		// 	};
		// 	if( window.attachEvent )
		// 		target.attachEvent( "on" + name, call );
		// 	else if( window.addEventListener )
		// 		target.addEventListener( name, call, false );
		// 	else
		// 		target["on" + name] = call;
		// 	return call;
		// }

		// Ucren.addEvent
		addEvent: function( target, name, fn ){
			var call = function(){
				fn.apply( target, arguments );
			};
			if( target.dom ){
				target = target.dom;
			}
			if( window.attachEvent ){
				target.attachEvent( "on" + name, call );
			}else if( window.addEventListener ){
				target.addEventListener( name, call, false );
			}else{
				target["on" + name] = call;
			}
			return call;
		},

		// Ucren.delEvent
		delEvent: function( target, name, fn ){
			if( window.detachEvent ){
				target.detachEvent( "on" + name, fn );
			}else if( window.removeEventListener ){
				target.removeEventListener( name, fn, false );
			}else if( target["on" + name] == fn ){
				target["on" + name] = null;
			}
		},

		// Ucren.Class
		Class: function( initialize, methods, befores, afters ){
			var fn, prototype, blank;
			initialize = initialize || function(){};
			methods = methods || {};
			blank = {};
			fn = function(){
				this.instanceId = Ucren.id();
				initialize.apply( this, arguments );
			};
			prototype = fn.prototype;
			Ucren.registerClassEvent.call( prototype );
			Ucren.each( methods, function( item, key ){
				prototype[key] = function( method, name ){
					if( typeof( method ) == "function" ){
						return function(){
							var args, rtn;
							args = slice.call( arguments, 0 );
							if( befores &&
								befores.apply( this, [name].concat( args )) === false ){
								return ;
							}
							this.fireEvent( "before" + name, args );
							rtn = method.apply( this, args );
							if( afters )
								afters.apply( this, [name].concat( args ));
							this.fireEvent( name, args );
							return rtn;
						};
					}else{
						return method;
					}
				}( item, key );
			});
			prototype.getOriginMethod = function( name ){
				return methods[name];
			};
			return fn;
		},

		//private
		registerClassEvent: function(){
			this.on = function( name, fn ){
				var instanceId = this.instanceId;
				Ucren.dispatch( instanceId + name, fn.bind( this ));
			};
			this.onbefore = function( name, fn ){
				var instanceId = this.instanceId;
				Ucren.dispatch( instanceId + "before" + name, fn.bind( this ));
			};
			this.un = function( name, fn ){
				//todo
			};
			this.fireEvent = function( name, args ){
				var instanceId = this.instanceId;
				Ucren.dispatch( instanceId + name, args );
			};
		},

		// Ucren.createFuze
		createFuze: function(){
			var queue, fn, infire;
			queue = [];
			fn = function( process ){
				if( infire ){
					process();
				}else{
					queue.push( process );
				}
			};
			fn.fire = function(){
				while( queue.length ){
					queue.shift()();
				}
				infire = true;
			};
			fn.extinguish = function(){
				infire = false;
			};
			fn.wettish = function(){
				if( queue.length ){
					queue.shift()();
				}
			};
			return fn;
		},

		// Ucren.createIf
		// createIf: function( expressionFunction ){
		// 	return function( callback ){
		// 		var expression = expressionFunction();
		// 		var returnValue = {
		// 			Else: function( callback ){
		// 				callback = callback || nul;
		// 				expression || callback();
		// 			}
		// 		};
		// 		callback = callback || nul;
		// 		expression && callback();
		// 		return returnValue;
		// 	};
		// },

		// Ucren.dispatch
		dispatch: function(){
			var map = {}, send, incept, ret;

			send = function( processId, args, scope ){
				var processItems;
				if( processItems = map[ processId ] )
					Ucren.each( processItems, function( item ){
						item.apply( scope, args );
					});
			};

			incept = function( processId, fn ){
				var m;
				if( !( m = map[ processId ] ) )
					map[processId] = [ fn ];
				else
					m.push( fn );
			};

			ret = function( arg1, arg2, arg3 ){
				if( typeof( arg2 ) === "undefined" )
					arg2 = [];

				if( arg2 instanceof Array )
				    send.apply( this, arguments );
				else if( typeof( arg2 ) === "function" )
				    incept.apply( this, arguments );
			};

			ret.remove = function( processId, fn ){
			    var m, i;
			    if( ( m = map[ processId ] ) && ~( i = m.indexOf( fn ) ) )
			    	m.splice( i, 1 );
			};

			return ret;
		}(),

		// Ucren.each ( not recommended )
		each: function( unknown, fn ){
			/// unknown 是 array 的,会慢慢退化,建议用 Array.prototype.forEach 替代
			/// unknown 为其它类似的,短期内将暂时支持
			if( unknown instanceof Array || ( typeof unknown == "object" &&
				typeof unknown[0] != "undefined" && unknown.length )){
				if( typeof unknown == "object" && Ucren.isSafari )
					unknown = slice.call( unknown );
	//				for( var i = 0, l = unknown.length; i < l; i ++ ){
	//					if( fn( unknown[i], i ) === false ){
	//						break;
	//					}
	//				}
				unknown.forEach( fn );
			}else if( typeof( unknown ) == "object" ){
				var blank = {};
				for( var i in unknown ){
					if( blank[i] ){
						continue;
					}
					if( fn( unknown[i], i ) === false ){
						break;
					}
				}
			}else if( typeof( unknown ) == "number" ){
				for( var i = 0; i < unknown; i ++ ){
					if( fn( i, i ) === false ){
						break;
					}
				}
			}else if( typeof( unknown ) == "string" ){
				for( var i = 0, l = unknown.length; i < l; i ++ ){
					if( fn( unknown.charAt( i ), i ) === false ){
						break;
					}
				}
			}
		},

		// Ucren.Element
		Element: function( el, returnDom ){
			var rtn, handleId;
			if( el && el.isUcrenElement ){
				return returnDom ? el.dom : el;
			}
			el = typeof( el ) == "string" ? document.getElementById( el ) : el;

			if( !el )
				return null;

			if( returnDom )
				return el;

			handleId = el.getAttribute( "handleId" );
			if( typeof handleId == "string" ){
				return Ucren.handle( handleId - 0 );
			}else{
				rtn = new Ucren.BasicElement( el );
				handleId = Ucren.handle( rtn );
				el.setAttribute( "handleId", handleId + "" );
				return rtn;
			}
		},

		// Ucren.Event
		Event: function( e ){
			e = e || window.event;

			if( !e ){
				var c = arguments.callee.caller;
				while( c ){
					e = c.arguments[0];
					if( e && typeof( e.altKey ) == "boolean" ){ // duck typing
						break;
					}
					c = c.caller;
					e = null;
				}
			}

			return e;
		},

		// Ucren.fixNumber
		fixNumber: function( unknown, defaultValue ){
			return typeof( unknown ) == "number" ? unknown : defaultValue;
		},

		// Ucren.fixString
		fixString: function( unknown, defaultValue ){
			return typeof( unknown ) == "string" ? unknown : defaultValue;
		},

		// Ucren.fixConfig
		fixConfig: function( conf ){
			var defaultConf;
			defaultConf = {};
			if( typeof conf == "undefined" ){
				return defaultConf;
			}else if( typeof conf == "function" ){
				return new conf;
			}else{
				return conf;
			}
		},

		// Ucren.handle
		handle: function( unknown ){
			var fn, type, number;
			fn = arguments.callee;
			if( !fn.cache ){
				fn.cache = {};
			}
			if( typeof( fn.number ) == "undefined" ){
				fn.number = 0;
			}
			type = typeof( unknown );
			if( type == "number" ){
				return fn.cache[unknown.toString()];
			}else if( type == "object" || type == "function" ){
				number = fn.number ++;
				fn.cache[number.toString()] = unknown;
				return number;
			}
		},

		// Ucren.id
		id: function(){
			var id = arguments.callee;
			id.number = ++ id.number || 0;
			return "_" + id.number;
		},

		// Ucren.loadImage
		loadImage: function( urls, onLoadComplete ){
			var length = urls.length;
			var loaded = 0;
			var check = function(){
				if( loaded == length )
					onLoadComplete && onLoadComplete();
			};
			Ucren.each( urls, function( url ){
				var img = document.createElement( "img" );
				img.onload = img.onerror = function(){
					this.onload = this.onerror = null;
					loaded ++;
					check();
				};
				Ucren.tempDom.appendChild( img );
				img.src = url;
			});
		},

		// Ucren.loadScript
		loadScript: function( src, callback ){
			Ucren.request( src, function( text ){
				eval( text );
				callback && callback( text );
			});
		},

		// Ucren.makeElement
		makeElement: function( tagName, attributes ){
			var el = document.createElement( tagName );
			var setStyle = function( unknown ){
				if( typeof unknown == "string" )
					el.style.cssText = unknown;
				else
					Ucren.apply( unknown, el.style );
			};

			for ( var prop in attributes ) {
				if ( prop === "class" )
					el.className = attributes[prop];
				else if ( prop === "for" )
					el.htmlFor = attributes[prop];
				else if( prop === "style" )
					setStyle( attributes[prop] );
				else
					el.setAttribute( prop, attributes[prop] );
			}

			return el;
		},

		// Ucren.nul
		nul: function(){
			return false;
		},

		// Ucren.queryString
		// queryString: function( name, sourceString ){
		// 	var source, pattern, result;
		// 	source = sourceString || location.href;
		// 	pattern = new RegExp( "( \\?|& )" + name + "=( [^&#]* )( #|&|$ )", "i" );
		// 	result = source.match( pattern );
		// 	return result ? result[2] : "";
		// },

		// Ucren.randomNumber
		randomNumber: function( num ){
			return Math.floor( Math.random() * num );
		},

		// Ucren.randomWord
		randomWord: function(){
			var cw = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
			return function( length, sourceString ){
				var words, re = [];
				words = sourceString || cw;
				Ucren.each( length, function( index ){
					re[index] = words.charAt( this.randomNumber( words.length ));
				}.bind( this ));
				return re.join( "" );
			}
		}(),

		// Ucren.request
		request: function( url, callback ){
			request = Ucren.request;
			var xhr = request.xhr;
			if( !request.xhr ){
				if( window.XMLHttpRequest ){
					xhr = request.xhr = new XMLHttpRequest();
				}else{
					xhr = request.xhr = new ActiveXObject( "Microsoft.XMLHTTP" );
				}
			}
			xhr.open( "GET", url, true );
			xhr.onreadystatechange = function(){
				if( xhr.readyState == 4 && xhr.status == 200 ){
					callback( xhr.responseText );
				}
			};
			xhr.send( null );
		}

		// // Ucren.decodeColor
		// decodeColor: function(){
		// 	var r = /^\#?( \w{2})( \w{2})( \w{2})$/;
		// 	var x = function( x ){
		// 		return parseInt( x, 16 );
		// 	};
		// 	return function( color ){
		// 		r.test( color );
		// 		return {
		// 			red: x( RegExp.$1 ),
		// 			green: x( RegExp.$2 ),
		// 			blue: x( RegExp.$3 )
		// 		};
		// 	}
		// }(),

		// // Ucren.encodeColor
		// encodeColor: function(){
		// 	var x = function( x ){
		// 		return x.toString( 16 ).split( "." )[0];
		// 	};
		// 	x = x.improve( function( origin, x ){
		// 		x = origin( x );
		// 		return x.length == 1 ? "0" + x : x;
		// 	});
		// 	return function( data ){
		// 		return ["#", x( data.red ), x( data.green ), x( data.blue )].join( "" );
		// 	}
		// }()
	};

	//
	// [底层操作类]
	//

	// Ucren.BasicDrag
	Ucren.BasicDrag = Ucren.Class( 
		/* constructor */ function( conf ){
			conf = Ucren.fixConfig( conf );
			this.type = Ucren.fixString( conf.type, "normal" );

			var isTouch = this.isTouch = "ontouchstart" in window;

			this.TOUCH_START = isTouch ? "touchstart" : "mousedown",
			this.TOUCH_MOVE = isTouch ? "touchmove" : "mousemove",
			this.TOUCH_END = isTouch ? "touchend" : "mouseup";
		},

		/* methods */ {
			bind: function( el, handle ){
				el = Ucren.Element( el );
				handle = Ucren.Element( handle ) || el;

				var evt = {};

				evt[this.TOUCH_START] = function( e ){
					e = Ucren.Event( e );
					this.startDrag();
					e.cancelBubble = true;
					e.stopPropagation && e.stopPropagation();
					return e.returnValue = false;
				}.bind( this );

				handle.addEvents( evt );
				this.target = el;
			},

			//private
			getCoors: function( e ){
				var coors = [];
				if ( e.targetTouches && e.targetTouches.length ) { 	// iPhone
					var thisTouch = e.targetTouches[0];
					coors[0] = thisTouch.clientX;
					coors[1] = thisTouch.clientY;
				}else{ 								// all others
					coors[0] = e.clientX;
					coors[1] = e.clientY;
				}
				return coors;
			},

			//private
			startDrag: function(){
				var target, draging, e;
				target = this.target;
				draging = target.draging = {};

				this.isDraging = true;

				draging.x = parseInt( target.style( "left" ), 10 ) || 0;
				draging.y = parseInt( target.style( "top" ), 10 ) || 0;

				e = Ucren.Event();
				var coors = this.getCoors( e );
				draging.mouseX = coors[0];
				draging.mouseY = coors[1];

				this.registerDocumentEvent();
			},

			//private
			endDrag: function(){
				this.isDraging = false;
				this.unRegisterDocumentEvent();
			},

			//private
			registerDocumentEvent: function(){
				var target, draging;
				target = this.target;
				draging = target.draging;

				draging.documentSelectStart =
					Ucren.addEvent( document, "selectstart", function( e ){
						e = e || event;
						e.stopPropagation && e.stopPropagation();
						e.cancelBubble = true;
						return e.returnValue = false;
					});

				draging.documentMouseMove =
					Ucren.addEvent( document, this.TOUCH_MOVE, function( e ){
						var ie, nie;
						e = e || event;
						ie = Ucren.isIe && e.button != 1;
						nie = !Ucren.isIe && e.button != 0;
						if( (ie || nie ) && !this.isTouch )
							this.endDrag();
						var coors = this.getCoors( e );
						draging.newMouseX = coors[0];
						draging.newMouseY = coors[1];
						e.stopPropagation && e.stopPropagation();
						return e.returnValue = false;
					}.bind( this ));

				draging.documentMouseUp =
					Ucren.addEvent( document, this.TOUCH_END, function(){
						this.endDrag();
					}.bind( this ));

				var lx, ly;

				clearInterval( draging.timer );
				draging.timer = setInterval( function(){
					var x, y, dx, dy;
					if( draging.newMouseX != lx && draging.newMouseY != ly ){
						lx = draging.newMouseX;
						ly = draging.newMouseY;
						dx = draging.newMouseX - draging.mouseX;
						dy = draging.newMouseY - draging.mouseY;
						x = draging.x + dx;
						y = draging.y + dy;
						if( this.type == "calc" ){
							this.returnValue( dx, dy, draging.newMouseX, draging.newMouseY );
						}else{
							target.left( x ).top( y );
						}
					}
				}.bind( this ), 10 );
			},

			//private
			unRegisterDocumentEvent: function(){
				var draging = this.target.draging;
				Ucren.delEvent( document, this.TOUCH_MOVE, draging.documentMouseMove );
				Ucren.delEvent( document, this.TOUCH_END, draging.documentMouseUp );
				Ucren.delEvent( document, "selectstart", draging.documentSelectStart );
				clearInterval( draging.timer );
			},

			//private
			returnValue: function( dx, dy, x, y ){
				//todo something
			}
		}
	 );

	// Ucren.Template
	Ucren.Template = Ucren.Class( 
		/* constructor */ function(){
			this.string = join.call( arguments, "" );
		},

		/* methods */ {
			apply: function( conf ){
				return this.string.format( conf );
			}
		}
	 );

	// Ucren.BasicElement
	Ucren.BasicElement = Ucren.Class( 
		/* constructor */ function( el ){
			this.dom = el;
		this.countMapping = {};
		},

		/* methods */ {
			isUcrenElement: true,

			attr: function( name, value ){
				if( typeof value == "string" ){
					this.dom.setAttribute( name, value );
				}else{
					return this.dom.getAttribute( name );
				}
				return this;
			},

			style: function( /* unknown1, unknown2 */ ){
				var getStyle = Ucren.isIe ?
					function( name ){
						return this.dom.currentStyle[name];
					} :

					function( name ){
						var style;
						style = document.defaultView.getComputedStyle( this.dom, null );
						return style.getPropertyValue( name );
					};

				return function( unknown1, unknown2 ){
					if( typeof unknown1 == "object" ){
						Ucren.each( unknown1, function( value, key ){
							this[key] = value;
						}.bind( this.dom.style ));
					}else if( typeof unknown1 == "string" && typeof unknown2 == "undefined" ){
						return getStyle.call( this, unknown1 );
					}else if( typeof unknown1 == "string" && typeof unknown2 != "undefined" ){
						this.dom.style[unknown1] = unknown2;
					}
					return this;
				};
			}(),

			hasClass: function( name ){
				var className = " " + this.dom.className + " ";
				return className.indexOf( " " + name + " " ) > -1;
			},

			setClass: function( name ){
				if( typeof( name ) == "string" )
					this.dom.className = name.trim();
				return this;
			},

			addClass: function( name ){
				var el, className;
				el = this.dom;
				className = " " + el.className + " ";
				if( className.indexOf( " " + name + " " ) == -1 ){
					className += name;
					className = className.trim();
					className = className.replace( / +/g, " " );
					el.className = className;
				}
				return this;
			},

			delClass: function( name ){
				var el, className;
				el = this.dom;
				className = " " + el.className + " ";
				if( className.indexOf( " " + name + " " ) > -1 ){
					className = className.replace( " " + name + " ", " " );
					className = className.trim();
					className = className.replace( / +/g, " " );
					el.className = className;
				}
				return this;
			},

			html: function( html ){
				var el = this.dom;

				if( typeof html == "string" ){
					el.innerHTML = html;
				}else if( html instanceof Array ){
					el.innerHTML = html.join( "" );
				}else{
					return el.innerHTML;
				}
				return this;
			},

			left: function( number ){
				var el = this.dom;
				if( typeof( number ) == "number" ){
					el.style.left = number + "px";
					this.fireEvent( "infect", [{ left: number }] );
				}else{
					return this.getPos().x;
				}
				return this;
			},

			top: function( number ){
				var el = this.dom;
				if( typeof( number ) == "number" ){
					el.style.top = number + "px";
					this.fireEvent( "infect", [{ top: number }] );
				}else{
					return this.getPos().y;
				}
				return this;
			},

			width: function( unknown ){
				var el = this.dom;
				if( typeof unknown == "number" ){
					el.style.width = unknown + "px";
					this.fireEvent( "infect", [{ width: unknown }] );
				}else if( typeof unknown == "string" ){
					el.style.width = unknown;
					this.fireEvent( "infect", [{ width: unknown }] );
					}else{
					return this.getSize().width;
					}
					return this;
				},

			height: function( unknown ){
					var el = this.dom;
				if( typeof unknown == "number" ){
					el.style.height = unknown + "px";
					this.fireEvent( "infect", [{ height: unknown }] );
				}else if( typeof unknown == "string" ){
					el.style.height = unknown;
					this.fireEvent( "infect", [{ height: unknown }] );
					}else{
					return this.getSize().height;
					}
					return this;
				},

			count: function( name ){
				return this.countMapping[name] = ++ this.countMapping[name] || 1;
			},

			display: function( bool ){
				var dom = this.dom;
				if( typeof( bool ) == "boolean" ){
					dom.style.display = bool ? "block" : "none";
					this.fireEvent( "infect", [{ display: bool }] );
				}else{
					return this.style( "display" ) != "none";
				}
				return this;
			},

			first: function(){
				var c = this.dom.firstChild;
				while( c && !c.tagName && c.nextSibling ){
					c = c.nextSibling;
				}
				return c;
			},

			add: function( dom ){
				var el;
				el = Ucren.Element( dom );
				this.dom.appendChild( el.dom );
				return this;
			},

			remove: function( dom ){
				var el;
				if( dom ){
					el = Ucren.Element( dom );
					el.html( "" );
					this.dom.removeChild( el.dom );
				}else{
					el = Ucren.Element( this.dom.parentNode );
					el.remove( this );
				}
				return this;
			},

			insert: function( dom ){
				var tdom;
				tdom = this.dom;
				if( tdom.firstChild ){
					tdom.insertBefore( dom, tdom.firstChild );
				}else{
					this.add( dom );
				}
				return this;
			},

			addEvents: function( conf ){
				var blank, el, rtn;
				blank = {};
				rtn = {};
				el = this.dom;
				Ucren.each( conf, function( item, key ){
					rtn[key] = Ucren.addEvent( el, key, item );
				});
				return rtn;
			},

			removeEvents: function( conf ){
				var blank, el;
				blank = {};
				el = this.dom;
				Ucren.each( conf, function( item, key ){
					Ucren.delEvent( el, key, item );
				});
				return this;
			},

			getPos: function(){
				var el, parentNode, pos, box, offset;
				el = this.dom;
				pos = {};

				if( el.getBoundingClientRect ){
					box = el.getBoundingClientRect();
					offset = Ucren.isIe ? 2 : 0;
					var doc = document;
					var scrollTop = Math.max( doc.documentElement.scrollTop,
						doc.body.scrollTop );
					var scrollLeft = Math.max( doc.documentElement.scrollLeft,
						doc.body.scrollLeft );
					return {
						x: box.left + scrollLeft - offset,
						y: box.top + scrollTop - offset
					};
				}else{
					pos = {
						x: el.offsetLeft,
						y: el.offsetTop
					};
					parentNode = el.offsetParent;
					if( parentNode != el ){
						while( parentNode ){
							pos.x += parentNode.offsetLeft;
							pos.y += parentNode.offsetTop;
							parentNode = parentNode.offsetParent;
						}
					}
					if( Ucren.isSafari && this.style( "position" ) == "absolute" ){ // safari doubles in some cases
						pos.x -= document.body.offsetLeft;
						pos.y -= document.body.offsetTop;
					}
				}

				if( el.parentNode ){
					parentNode = el.parentNode;
				}else{
					parentNode = null;
				}

				while( parentNode && parentNode.tagName.toUpperCase() != "BODY" &&
					parentNode.tagName.toUpperCase() != "HTML" ){ // account for any scrolled ancestors
					pos.x -= parentNode.scrollLeft;
					pos.y -= parentNode.scrollTop;
					if( parentNode.parentNode ){
						parentNode = parentNode.parentNode;
					}else{
						parentNode = null;
					}
				}

				return pos;
			},

			getSize: function(){
				var dom = this.dom;
				var display = this.style( "display" );

				if ( display && display !== "none" ) {
					return { width: dom.offsetWidth, height: dom.offsetHeight };
					}

				var style = dom.style;
				var originalStyles = {
					visibility: style.visibility,
					position:   style.position,
					display:    style.display
				};

				var newStyles = {
					visibility: "hidden",
					display:    "block"
				};

				if ( originalStyles.position !== "fixed" )
				  newStyles.position = "absolute";

				this.style( newStyles );

				var dimensions = {
					width:  dom.offsetWidth,
					height: dom.offsetHeight
				};

				this.style( originalStyles );

				return dimensions;
			},

			observe: function( el, fn ){
				el = Ucren.Element( el );
				el.on( "infect", fn.bind( this ));
				return this;
			},

			usePNGbackground: function( image ){
				var dom;
				dom = this.dom;
				if( /\.png$/i.test( image ) && Ucren.isIe6 ){
					dom.style.filter =
						"progid:DXImageTransform.Microsoft.AlphaImageLoader( src=&#39;" +
						image + "&#39;,sizingMethod=&#39;scale&#39; );";
					/// 	_background: none;
					///  _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader( src=&#39;images/pic.png&#39;,sizingMethod=&#39;scale&#39; );
				}else{
					dom.style.backgroundImage = "url( " + image + " )";
				}
				return this;
			},

			setAlpha: function(){
				var reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/;
				return function( value ){
					var element = this.dom, es = element.style;
					if( !Ucren.isIe ){
						es.opacity = value / 100;
					/* }else if( es.filter === "string" ){ */
					}else{
						if ( element.currentStyle && !element.currentStyle.hasLayout )
							es.zoom = 1;

						if ( reOpacity.test( es.filter )) {
							value = value >= 99.99 ? "" : ( "alpha( opacity=" + value + " )" );
							es.filter = es.filter.replace( reOpacity, value );
						} else {
							es.filter += " alpha( opacity=" + value + " )";
						}
					}
					return this;
				};
			}(),

			fadeIn: function( callback ){
				if( typeof this.fadingNumber == "undefined" )
					this.fadingNumber = 0;
				this.setAlpha( this.fadingNumber );

				var fading = function(){
					this.setAlpha( this.fadingNumber );
					if( this.fadingNumber == 100 ){
						clearInterval( this.fadingInterval );
						callback && callback();
					}else
						this.fadingNumber += 10;
				}.bind( this );

				this.display( true );
				clearInterval( this.fadingInterval );
				this.fadingInterval = setInterval( fading, Ucren.isIe ? 20 : 30 );

				return this;
			},

			fadeOut: function( callback ){
				if( typeof this.fadingNumber == "undefined" )
					this.fadingNumber = 100;
				this.setAlpha( this.fadingNumber );

				var fading = function(){
					this.setAlpha( this.fadingNumber );
					if( this.fadingNumber == 0 ){
						clearInterval( this.fadingInterval );
						this.display( false );
						callback && callback();
					}else
						this.fadingNumber -= 10;
				}.bind( this );

				clearInterval( this.fadingInterval );
				this.fadingInterval = setInterval( fading, Ucren.isIe ? 20 : 30 );

				return this;
			},

			useMouseAction: function( className, actions ){
				/**
				 *  调用示例:  el.useMouseAction( "xbutton", "over,out,down,up" );
				 *  使用效果:  el 会在 "xbutton xbutton-over","xbutton xbutton-out","xbutton xbutton-down","xbutton xbutton-up"
				 *             等四个 className 中根据相应的鼠标事件来进行切换。
				 *  特别提示:  useMouseAction 可使用不同参数多次调用。
				 */
				if( !this.MouseAction )
					this.MouseAction = new Ucren.MouseAction({ element: this });
				this.MouseAction.use( className, actions );
				return this;
			}
		}
	 );

	if( Ucren.isIe )
		document.execCommand( "BackgroundImageCache", false, true );

	for( var i in Ucren ){
	    exports[i] = Ucren[i];
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\background.js
 */ 
define("scripts/object/background.js", function(exports){
	var Ucren = require("scripts/lib/ucren");
	var layer = require("scripts/layer");
	var timeline = require("scripts/timeline");
	var image, time;

	var random = Ucren.randomNumber;

	exports.set = function(){
		image = layer.createImage( "default", "images/background.jpg", 0, 0, 640, 480 );
	};

	exports.wobble = function(){
		time = timeline.setInterval( wobble, 50 );
	};

	exports.stop = function(){
	    time.stop();
	    image.attr({ x: 0, y: 0 });
	};

	function wobble(){
	    var x, y;
	    x = random( 12 ) - 6;
	    y = random( 12 ) - 6;
	    image.attr({ x: x, y: y });
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\console.js
 */ 
define("scripts/object/console.js", function(exports){
	var layer = require("scripts/layer");

	var x = 16, y = 0;
	var texts = [];

	exports.set = function(){

	};

	exports.clear = function(){
	    for(var i = 0, l = texts.length; i < l; i ++)
	    	texts[i].remove();
	    texts.length = y = 0;
	};

	exports.log = function(text){
		y += 20;
	    texts.push( layer.createText( "default", text, x, y ) );
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\developing.js
 */ 
define("scripts/object/developing.js", function(exports){
	var layer = require("scripts/layer");
	var tween = require("scripts/lib/tween");
	var timeline = require("scripts/timeline");
	var message = require("scripts/message");

	var exponential = tween.exponential.co;

	/**
	 * "coming soon" 模块
	 */

	exports.anims = [];

	exports.set = function(){
		this.image = layer.createImage( "default", "images/developing.png", 103, 218, 429, 53 ).hide().scale( 1e-5, 1e-5 );
	};

	exports.show = function( start ){
	    timeline.createTask({
			start: start, duration: 500, data: [ 1e-5, 1, "show" ],
			object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd,
			recycle: this.anims
		});

		this.hide( 2000 );
	};

	exports.hide = function( start ){
	    timeline.createTask({
			start: start, duration: 500, data: [ 1, 1e-5, "hide" ],
			object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd,
			recycle: this.anims
		});
	};

	// 显示/隐藏 相关

	exports.onZoomStart = function(){
		this.image.show();
	};

	exports.onZooming = function( time, sz, ez, z ){
		this.image.scale( z = exponential( time, sz, ez - sz, 500 ), z );
	};

	exports.onZoomEnd = function( sz, ez, mode ){
	    if( mode === "hide" )
	        this.image.hide();
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\dojo.js
 */ 
define("scripts/object/dojo.js", function(exports){
	var rotate = require("scripts/factory/rotate");
	var tween = require("scripts/lib/tween");

	exports = rotate.create("images/dojo.png", 41, 240, 175, 175, 1e-5, tween.exponential.co, 500);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\flame.js
 */ 
define("scripts/object/flame.js", function(exports){

	/**
	 * 火焰模块
	 * @author zswang, dron
	 */

	var layer = require("scripts/layer").getLayer( "fruit" );
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");

	/*
	raphael.path(&#39;M 27,122 Q 9,42 27,21 45,42 27,122&#39;)
		.attr({
			stroke: &#39;none&#39;,
			fill: &#39;180-#D8D380-#EDED7A-#D8D380&#39;
		});
	*/

	// 缩写
	var math = Math, cos = math.cos, sin = math.sin,
		trunc = parseInt,
		random = math.random,
		PI = math.PI;

	var guid = 0;

	/**
	 * 添加一个火苗
	 * @param{Array} center 中心位置 单位像素
	 * @param{Number} angle 运动方向 单位幅度
	 * @param{Number} length 运动长度 单位像素
	 * @param{Number} life 存活时间 单位毫秒
	 */
	function appendFlame( center, angle, length, life, flames ){
		return flames[guid] = {
			id: guid ++,
			birthday: new Date,
			center: center,
			angle: angle,
			length: length,
			life: life,
			path: layer.path().attr({ stroke: &#39;none&#39;, fill: trunc( angle * 180 / PI ) + &#39;-#fafad9-#f0ef9c&#39; })
		};
	}

	var radius = 15;

	function updateFlame( flames, n ){
		var item = flames[n];

		if ( !item ) 
			return;

		var age, center, p1, p2, p3, p4;

		age = 1 - (new Date - item.birthday) / item.life;

		if ( age <= 0 ){
			item.path.remove();
			delete flames[item.id];
			return;
		}

		var ia, ic, il;

		ia = item.angle;
		ic = item.center;
		il = item.length;

		center = [ trunc(ic[0] + cos(ia) * il * (1 - age)), trunc(ic[1] + sin(ia) * il * (1 - age)) ];
		p1 = [ trunc(center[0] - cos(ia) * radius * age), trunc(center[1] - sin(ia) * radius * age) ];
		p2 = [ trunc(center[0] + cos(ia) * radius * age), trunc(center[1] + sin(ia) * radius * age) ];
		p3 = [ trunc(center[0] - cos(ia + .5 * PI) * radius * .4 * age), trunc(center[1] - sin(ia + .5 * PI) * radius * .4 * age) ];
		p4 = [ trunc(center[0] - cos(ia - .5 * PI) * radius * .4 * age), trunc(center[1] - sin(ia - .5 * PI) * radius * .4 * age) ];

		item.path.attr({ path: &#39;M&#39; + p1 + &#39; Q&#39; + [ p3, p2, p4, p1 ].join(&#39; &#39;) });
	};

	function removeFlame( flames, n ){
	    var item = flames[n];

	    if( !item )
	    	return;

	    item.path.remove();
	    delete flames[ n ];
	};

	exports.create = function( ox, oy, start ){
		var timer1, timer2;

	  	var object = {
	  		pos: function( x, y ){
	  		    nx = x;
	  		    ny = y;
	  		    image.attr( "x", nx - 21 ).attr( "y", ny - 21 );
	  		},

	  		remove: function(){
	  		    [ timer1, timer2 ].invoke( "stop" );
	  		    image.remove();

	  		    for (var p in flames)
					removeFlame( flames, p );
	  		}
	  	};

		var nx = ox, ny = oy;
		var image = layer.image("images/smoke.png", nx - 21, ny - 21, 43, 43).hide();
		var flames = {};

		timer1 = timeline.setTimeout(function(){
			image.show();
			timer2 = timeline.setInterval(function(){
				if(random() < 0.9)
					appendFlame( [ nx, ny ], PI * 2 * random(), 60, 200 + 500 * random(), flames );

				for (var p in flames)
					updateFlame( flames, p );

			}, Ucren.isIe ? 20 : 40);

		}, start || 0);

		return object;
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\flash.js
 */ 
define("scripts/object/flash.js", function(exports){
	/**
	 *
	 */

	var layer = require("scripts/layer");
	var timeline = require("scripts/timeline").use( "flash" ).init( 10 );
	var tween = require("scripts/lib/tween");
	var sound = require("scripts/lib/sound");

	var image, snd, xDiff = 0, yDiff = 0;

	var anim = tween.quadratic.cio;
	var anims = [];
	var dur = 100;

	exports.set = function(){
		image = layer.createImage( "flash", "images/flash.png", 0, 0, 358, 20 ).hide();
		snd = sound.create( "sound/splatter" );
	};

	exports.showAt = function( x, y, an ){
	    image.rotate( an, true ).scale( 1e-5, 1e-5 ).attr({
	        x: x + xDiff,
	        y: y + yDiff
	    }).show();

	    anims.clear && anims.clear();

	    snd.play();

	    timeline.createTask({
	        start: 0, duration: dur, data: [ 1e-5, 1 ],
	        object: this, onTimeUpdate: this.onTimeUpdate,
	        recycle: anims
	    });

	    timeline.createTask({
	        start: dur, duration: dur, data: [ 1, 1e-5 ],
	        object: this, onTimeUpdate: this.onTimeUpdate,
	        recycle: anims
	    });
	};

	exports.onTimeUpdate = function( time, a, b, z ){
	    image.scale( z = anim( time, a, b - a, dur ), z );
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\fps.js
 */ 
define("scripts/object/fps.js", function(exports){
	// var layer = require("scripts/layer");
	// var timeline =require("scripts/timeline");

	// var text, fps = "fps: ";

	// exports.set = function(){
	// 	text = layer.createText( "default", fps + "0", 4, 470 ).attr( "fill", "#ccc" );
	// };

	// exports.update = function(){
	// 	text.attr( "text", fps + ( timeline.getFPS() >> 0 ) );
	// };;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\game-over.js
 */ 
define("scripts/object/game-over.js", function(exports){
	var layer = require("scripts/layer");
	var tween = require("scripts/lib/tween");
	var timeline = require("scripts/timeline");
	var message = require("scripts/message");
	var state = require("scripts/state");

	var exponential = tween.exponential.co;

	/**
	 * "game-over"模块
	 */

	exports.anims = [];

	exports.set = function(){
		this.image = layer.createImage( "default", "images/game-over.png", 75, 198, 490, 85 ).hide().scale( 1e-5, 1e-5 );
	};

	exports.show = function( start ){
	    timeline.createTask({
			start: start, duration: 500, data: [ 1e-5, 1, "show" ],
			object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd,
			recycle: this.anims
		});
	};

	exports.hide = function( start ){
	    timeline.createTask({
			start: start, duration: 500, data: [ 1, 1e-5, "hide" ],
			object: this, onTimeUpdate: this.onZooming, onTimeStart: this.onZoomStart, onTimeEnd: this.onZoomEnd,
			recycle: this.anims
		});
	};

	// 显示/隐藏 相关

	exports.onZoomStart = function( sz, ez, mode ){
		if( mode == "show" )
			this.image.show();
	};

	exports.onZooming = function( time, sz, ez, z ){
		this.image.scale( z = exponential( time, sz, ez - sz, 500 ), z );
	};

	exports.onZoomEnd = function( sz, ez, mode ){
		if( mode == "show" )
			state( "click-enable" ).on();
	    else if( mode === "hide" )
	        this.image.hide();
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\home-desc.js
 */ 
define("scripts/object/home-desc.js", function(exports){
	var displacement = require("scripts/factory/displacement");
	var tween = require("scripts/lib/tween");

	exports = displacement.create("images/home-desc.png", 161, 91, -161, 140, 7, 127, tween.exponential.co, 500);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\home-mask.js
 */ 
define("scripts/object/home-mask.js", function(exports){
	var displacement = require("scripts/factory/displacement");
	var tween = require("scripts/lib/tween");

	exports = displacement.create("images/home-mask.png", 640, 183, 0, -183, 0, 0, tween.exponential.co, 1e3);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\knife.js
 */ 
define("scripts/object/knife.js", function(exports){
	var timeline = require("scripts/timeline");
	var layer = require("scripts/layer").getLayer( "knife" );
	var Ucren = require("scripts/lib/ucren");

	/**
	 * 刀光模块
	 */

	var lastX = null, lastY = null;
	var abs = Math.abs;

	var life = 200;
	var stroke = 10;
	var color = "#cbd3db";
	var anims = [];
	var switchState = true;
	var knifes = [];

	function ClassKnifePart( conf ){
	    this.sx = conf.sx;
	    this.sy = conf.sy;
	    this.ex = conf.ex;
	    this.ey = conf.ey;

	    knifes.push( this );
	}

	ClassKnifePart.prototype.set = function(){
		var sx, sy, ex, ey, dx, dy, ax, ay;

		sx = this.sx;
		sy = this.sy;
		ex = this.ex;
		ey = this.ey;

		dx = sx - ex;
		dy = sy - ey;
		ax = abs(dx);
		ay = abs(dy);

		if(ax > ay)
		    sx += dx < 0 ? -1 : 1,
		    sy += dy < 0 ? -( 1 * ay / ax ) : 1 * ay / ax;
		else
		    sx += dx < 0 ? -( 1 * ax / ay ) : 1 * ax / ay,
		    sy += dy < 0 ? -1 : 1;

		this.line = layer.path( "M" + sx + "," + sy + "L" + ex + "," + ey ).attr({
			"stroke": color,
			"stroke-width": stroke + "px"
		});

		timeline.createTask({ start: 0, duration: life, object: this, onTimeUpdate: this.update, onTimeEnd: this.end, recycle: anims });
		return this;
	};

	ClassKnifePart.prototype.update = function( time ){
		this.line.attr( "stroke-width", stroke * (1 - time / life) + "px" );
	};

	ClassKnifePart.prototype.end = function(){
		this.line.remove();

		var index;
		if( index = knifes.indexOf( this ) )
		    knifes.splice( index, 1 );
	};

	exports.newKnife = function(){
	    lastX = lastY = null;
	};

	exports.through = function( x, y ){
		if( !switchState )
			return ;
		var ret = null;
		if( lastX !== null && ( lastX != x || lastY != y ) )
		    new ClassKnifePart({ sx: lastX, sy: lastY, ex: x, ey: y }).set(),
			ret = [ lastX, lastY, x, y ];

		lastX = x;
		lastY = y;
		return ret;
	};

	exports.pause = function(){
	    anims.clear();
	    this.switchOff();
	};

	exports.switchOff = function(){
	    switchState = false;
	};

	exports.switchOn = function(){
		switchState = true;
		this.endAll();
	};

	exports.endAll = function(){
	    for(var i = knifes.length - 1; i >= 0; i --)
			knifes[i].end();
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\light.js
 */ 
define("scripts/object/light.js", function(exports){
	/**
	 * 炸弹爆炸时的光线
	 */

	var layer = require("scripts/layer");

	var maskLayer = layer.getLayer( "mask" );
		layer = layer.getLayer( "light" );

	var Ucren = require("scripts/lib/ucren");
	var timeline = require("scripts/timeline");
	var message = require("scripts/message");

	var random = Ucren.randomNumber;
	var pi = Math.PI;
	var sin = Math.sin;
	var cos = Math.cos;

	var lights = [];
	var indexs = [];
	var lightsNum = 10;

	for(var i = 0; i < lightsNum; i ++)
		indexs[i] = i;

	exports.start = function( boom ){
		var x = boom.originX, y = boom.originY, time = 0, idx = indexs.random();

		var i = lightsNum, b = function(){
		    build( x, y, idx[ this ] );
		};

		while( i -- )
			timeline.setTimeout( b.bind( i ), time += 100 );

		timeline.setTimeout(function(){
		    this.overWhiteLight();
		}.bind( this ), time + 100);
	};

	exports.overWhiteLight = function(){
	    message.postMessage( "overWhiteLight.show" );
	    this.removeLights();

	    var dur = 4e3;
	    var mask = maskLayer.rect( 0, 0, 640, 480 ).attr({ fill: "#fff", stroke: "none" });
	    var control = {
	    	onTimeUpdate: function( time ){
	    		mask.attr( "opacity", 1 - time / dur );
	    	},

	    	onTimeEnd: function(){
	    	    mask.remove();
	    	    message.postMessage( "game.over" );
	    	}
	    };

	    timeline.createTask({
			start: 0, duration: dur,
			object: control, onTimeUpdate: control.onTimeUpdate, onTimeEnd: control.onTimeEnd
		});

	};

	exports.removeLights = function(){
	    for(var i = 0, l = lights.length; i < l; i ++)
	    	lights[i].remove();
	    lights.length = 0;
	};

	function build( x, y, r ){
	    var a1, a2, x1, y1, x2, y2;

	    a1 = r * 36 + random( 10 );
	    a2 = a1 + 5;

	    a1 = pi * a1 / 180;
	    a2 = pi * a2 / 180;

	    x1 = x + 640 * cos( a1 );
	    y1 = y + 640 * sin( a1 );

	    x2 = x + 640 * cos( a2 );
	    y2 = y + 640 * sin( a2 );

	    var light = layer.path( [ "M", x, y, "L", x1, y1, "L", x2, y2, "Z" ] ).attr({
	    	stroke: "none",
	    	fill: "#fff"
	    });

	    lights.push( light );
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\logo.js
 */ 
define("scripts/object/logo.js", function(exports){
	var displacement = require("scripts/factory/displacement");
	var tween = require("scripts/lib/tween");

	exports = displacement.create("images/logo.png", 288, 135, 17, -182, 17, 1, tween.exponential.co, 1e3);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\lose.js
 */ 
define("scripts/object/lose.js", function(exports){
	var layer = require("scripts/layer");
	var tween = require("scripts/lib/tween");
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");
	var message = require("scripts/message");

	var anim = tween.exponential.co;
	var back = tween.back.co;

	/**
	 * 
	 */

	var o1, o2, o3, animLength = 500;

	var conf1 = { src: "images/x.png", sx: 650, ex: 561, y: 5, w: 22, h: 19 };
	var conf2 = { src: "images/xx.png", sx: 671, ex: 582, y: 5, w: 27, h: 26 };
	var conf3 = { src: "images/xxx.png", sx: 697, ex: 608, y: 6, w: 31, h: 32 };

	var number = 0;

	exports.anims = [];

	exports.set = function(){
	    o1 = layer.createImage( "default", conf1.src, conf1.sx, conf1.y, conf1.w, conf1.h ).hide();
	    o2 = layer.createImage( "default", conf2.src, conf2.sx, conf2.y, conf2.w, conf2.h ).hide();
	    o3 = layer.createImage( "default", conf3.src, conf3.sx, conf3.y, conf3.w, conf3.h ).hide();
	};

	exports.reset = function(){
	    number = 0;
	    [ [ o1, conf1 ], [ o2, conf2 ], [ o3, conf3 ] ].forEach(function( infx ){
	        infx[0].attr( "src", infx[1].src.replace( "xf.png", "x.png" ) );
	    })
	};

	exports.show = function( start ){
	    timeline.createTask({
			start: start, duration: animLength, data: [ 
			"show", conf1.sx, conf1.ex, conf2.sx, conf2.ex, conf3.sx, conf3.ex ],
			object: this, onTimeUpdate: this.onTimeUpdate, onTimeStart: this.onTimeStart, onTimeEnd: this.onTimeEnd,
			recycle: this.anims
		});
	};

	exports.hide = function( start ){
	    timeline.createTask({
			start: start, duration: animLength, data: [ "hide", conf1.ex, conf1.sx, conf2.ex, conf2.sx, conf3.ex, conf3.sx ],
			object: this, onTimeUpdate: this.onTimeUpdate, onTimeStart: this.onTimeStart, onTimeEnd: this.onTimeEnd,
			recycle: this.anims
		});  
	};

	exports.showLoseAt = function( x ){

	    var infx, inf = [
	        [ o1, conf1 ],
	        [ o2, conf2 ],
	        [ o3, conf3 ]
	    ];

	    createPosShow( x );

	    infx = inf[ ( ++ number ) - 1 ];
	    infx[0].attr( "src", infx[1].src.replace( "x.png", "xf.png" ) ).scale( 1e-5, 1e-5 );
	    this.scaleImage( infx[0] );

	    if( number == 3 )
	        message.postMessage( "game.over" );
	};

	exports.scaleImage = function( image ){
	    var dur = 500;

	    image.myOnScaling = image.myOnScaling || function( time, z ){
	        this.scale( z = back( time, 1e-5, 1 - 1e-5, dur ), z );
	    };

	    image.myOnScaleEnd = image.myOnScaleEnd || function(){
	        this.scale( 1, 1 );
	    };

	    timeline.createTask({
	        start: 0, duration: dur,
	        object: image, onTimeUpdate: image.myOnScaling, onTimeEnd: image.myOnScaleEnd,
	        recycle: this.anims
	    });
	};

	// 显示/隐藏 相关

	exports.onTimeUpdate = function( time, mode, x1s, x1e, x2s, x2e, x3s, x3e ){
	    o1.attr( "x", anim( time, x1s, x1e - x1s, animLength ) );
	    o2.attr( "x", anim( time, x2s, x2e - x2s, animLength ) );
	    o3.attr( "x", anim( time, x3s, x3e - x3s, animLength ) );
	};

	exports.onTimeStart = function( mode ){
	    if( mode == "show" )
	        [ o1, o2, o3 ].invoke( "show" );
	};

	exports.onTimeEnd = function( mode ){
	    if( mode == "hide" )
	        [ o1, o2, o3 ].invoke( "hide" ),
	        this.reset();
	};

	function createPosShow( x ){
	    var image = layer.createImage( "default", "images/lose.png", x - 27, 406, 54, 50 ).scale( 1e-5, 1e-5 );
	    var duration = 500;

	    var control = {
	        show: function( start ){
	            timeline.createTask({
	                start: start, duration: duration, data: [ tween.back.co, 1e-5, 1 ],
	                object: this, onTimeUpdate: this.onScaling, onTimeEnd: this.onShowEnd
	                // recycle: anims
	            });
	        },

	        hide: function( start ){
	            timeline.createTask({
	                start: start, duration: duration, data: [ tween.back.ci, 1, 1e-5 ],
	                object: this, onTimeUpdate: this.onScaling, onTimeEnd: this.onHideEnd
	                // recycle: anims
	            });
	        },

	        onScaling: function( time, anim, a, b, z ){
	            image.scale( z = anim( time, a, b - a, duration ), z );
	        },

	        onShowEnd: function(){
	            this.hide( 1500 );
	        },

	        onHideEnd: function(){
	            image.remove();
	        }
	    };

	    control.show( 200 );
	};

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\new-game.js
 */ 
define("scripts/object/new-game.js", function(exports){
	var rotate = require("scripts/factory/rotate");
	var tween = require("scripts/lib/tween");

	exports = rotate.create("images/new-game.png", 244, 231, 195, 195, 1e-5, tween.exponential.co, 500);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\new.js
 */ 
define("scripts/object/new.js", function(exports){
	var layer = require("scripts/layer");
	var tween = require("scripts/lib/tween");
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");

	var image;
	var cycleTime = 300;

	var sx = 129, sy = 328, ex = 170, ey = 221, sw = 0, sh = 0, ew = 70, eh = 42, dy = 8;

	var showAnim = tween.exponential.co;
	var jumpAnim = tween.quadratic.ci;

	exports.anims = [];

	exports.set = function(){
	    image = layer.createImage( "default", "images/new.png", sx, sy, sw, sh );
	};

	exports.unset = function(){

	};

	exports.show = function( start ){
		timeline.createTask({ 
	        start: start, duration: 500,
	        data: [ sx, ex, sy, ey, sw, ew, sh, eh ],
	        object: this, onTimeUpdate: this.onShowing, onTimeStart: this.onShowStart, onTimeEnd: this.onShowEnd, 
	        recycle: this.anims 
	    });
	};

	exports.hide = function( start ){
	    this.anims.clear();
	    timeline.createTask({ 
	        start: start, duration: 500,
	        data: [ ex, sx, ey, sy, ew, sw, eh, sh ],
	        object: this, onTimeUpdate: this.onShowing, 
	        recycle: this.anims 
	    });
	};

	exports.jump = function(){
	    this.anims.clear();
	    timeline.createTask({ start: 0, duration: -1, object: this, onTimeUpdate: this.onJumping, recycle: this.anims });
	};

	// 显示相关

	exports.onShowStart = function(){
	};

	exports.onShowing = function( time, sx, ex, sy, ey, sw, ew, sh, eh ){
	    image.attr({ 
	    	x: showAnim( time, sx, ex - sx, 500 ), 
	    	y: showAnim( time, sy, ey - sy, 500 ),
	    	width: showAnim( time, sw, ew - sw, 500 ),
	    	height: showAnim( time, sh, eh - sh, 500 )
	    });
	};

	exports.onShowEnd = function(){
	    this.jump();
	};

	// 跳跃相关

	exports.onJumping = function(time){
		var t = parseInt(time / cycleTime);

		time = time % cycleTime;
		if( t % 2 ) time = cycleTime - time;

		image.attr("y", jumpAnim( time, ey, dy, cycleTime ));
	};;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\ninja.js
 */ 
define("scripts/object/ninja.js", function(exports){
	var displacement = require("scripts/factory/displacement");
	var tween = require("scripts/lib/tween");

	exports = displacement.create("images/ninja.png", 244, 81, 315, -140, 315, 43, {
		show: tween.bounce.co,
		hide: tween.exponential.co
	}, 1e3);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\quit.js
 */ 
define("scripts/object/quit.js", function(exports){
	var rotate = require("scripts/factory/rotate");
	var tween = require("scripts/lib/tween");

	exports = rotate.create("images/quit.png", 493, 311, 141, 141, 1e-5, tween.exponential.co, 500);;

	return exports;
});

/**
 * @source D:\hosting\demos\fruit-ninja\output\scripts\object\score.js
 */ 
define("scripts/object/score.js", function(exports){
	var layer = require("scripts/layer");
	var tween = require("scripts/lib/tween");
	var timeline = require("scripts/timeline");
	var Ucren = require("scripts/lib/ucren");

	var setTimeout = timeline.setTimeout.bind( timeline );
	var anim = tween.exponential.co;

	var message = require("scripts/message");

	/**
	 * 分数模块
	 */

	var image, text1, text2, animLength = 500;;

	var imageSx = -94, imageEx = 6;
	var text1Sx = -59, text1Ex = 41;
	var text2Sx = -93, text2Ex = 7;

	exports.anims = [];

	exports.set = function(){
	    image = layer.createImage( "default", "images/score.png", imageSx, 8, 29, 31 ).hide();
	    text1 = layer.createText( "default", "0", text1Sx, 24, "90-#fc7f0c-#ffec53", "30px" ).hide();
	    text2 = layer.createText( "default", "BEST 999", text2Sx, 48, "#af7c05", "14px" ).hide();
	};

	exports.show = function( start ){
		timeline.createTask({
			start: start, duration: animLength, data: [ "show", imageSx, imageEx, text1Sx, text1Ex, text2Sx, text2Ex ],
			object: this, onTimeUpdate: this.onTimeUpdate, onTimeStart: this.onTimeStart, onTimeEnd: this.onTimeEnd,
			recycle: this.anims
		});
	};

	exports.hide = function( start ){
		timeline.createTask({
			start: start, duration: animLength, data: [ "hide", imageEx, imageSx, text1Ex, text1Sx, text2Ex, text2Sx ],
			object: this, onTimeUpdate: this.onTimeUpdate, onTimeStart: this.onTimeStart, onTimeEnd: this.onTimeEnd,
			recycle: this.anims
		});
	};

	exports.number = function( number ){
	    text1.attr( "text", number || 0 );
	    image.scale( 1.2, 1.2 );
	    setTimeout(function(){
	        image.scale( 1, 1 );
	    }, 60);
	    // message.postMessage( number, "score.change" );
	};

	// 显示/隐藏 相关

	exports.onTimeUpdate = function( time, mode, isx, iex, t1sx, t1ex, t2sx, t2ex ){
	    image.attr( "x", anim( time, isx, iex - isx, animLength ) );
	    text1.attr( "x", anim( time, t1sx, t1ex - t1sx, animLength ) );
	    text2.attr( "x", anim( time, t2sx, t2ex - t2sx, animLength ) );
	};

	exports.onTimeStart = function( mode ){
		if( mode === "show" )
			[ image, text1, text2 ].invoke( "show" );
	};

	exports.onTimeEnd = function( mode ){
	    if( mode === "hide" )
	        [ image, text1, text2 ].invoke( "hide" ),
	        text1.attr( "text", 0 );
	};;

	return exports;
});

startModule("scripts/main");

 以上就是教你如何用HTML5和JS实现切水果游戏的内容,更多相关内容请关注PHP中文网(www.php.cn)!











Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Memahami Kod H5: Asas HTML5Memahami Kod H5: Asas HTML5Apr 17, 2025 am 12:08 AM

HTML5 adalah teknologi utama untuk membina laman web moden, menyediakan banyak elemen dan ciri -ciri baru. 1. HTML5 memperkenalkan unsur -unsur semantik seperti, dan lain -lain, yang meningkatkan struktur laman web dan SEO. 2. Sokongan unsur multimedia dan menanamkan media tanpa pemalam. 3. Borang meningkatkan jenis input baru dan sifat pengesahan, memudahkan proses pengesahan. 4. Menawarkan fungsi storan luar talian dan tempatan untuk meningkatkan prestasi laman web dan pengalaman pengguna.

Kod H5: Amalan Terbaik untuk Pemaju WebKod H5: Amalan Terbaik untuk Pemaju WebApr 16, 2025 am 12:14 AM

Amalan terbaik untuk kod H5 termasuk: 1. Gunakan pengisytiharan dan pengekodan watak yang betul; 2. Gunakan tag semantik; 3. Mengurangkan permintaan HTTP; 4. Gunakan pemuatan asynchronous; 5. Mengoptimumkan imej. Amalan ini dapat meningkatkan kecekapan, penyelenggaraan dan pengalaman pengguna halaman web.

H5: Evolusi piawaian dan teknologi webH5: Evolusi piawaian dan teknologi webApr 15, 2025 am 12:12 AM

Piawaian dan teknologi web telah berkembang dari HTML4, CSS2 dan JavaScript mudah setakat ini dan telah menjalani perkembangan yang ketara. 1) HTML5 memperkenalkan API seperti kanvas dan webstorage, yang meningkatkan kerumitan dan interaktiviti aplikasi web. 2) CSS3 menambah fungsi animasi dan peralihan untuk menjadikan halaman lebih berkesan. 3) JavaScript meningkatkan kecekapan pembangunan dan kebolehbacaan kod melalui sintaks moden node.js dan ES6, seperti fungsi anak panah dan kelas. Perubahan ini telah mempromosikan pembangunan pengoptimuman prestasi dan amalan terbaik aplikasi web.

Adakah H5 adalah singkat untuk HTML5? Meneroka butiranAdakah H5 adalah singkat untuk HTML5? Meneroka butiranApr 14, 2025 am 12:05 AM

H5 bukan sekadar singkatan HTML5, ia mewakili ekosistem teknologi pembangunan web moden yang lebih luas: 1. H5 termasuk HTML5, CSS3, JavaScript dan API dan Teknologi yang berkaitan; 2. Ia menyediakan pengalaman pengguna yang lebih kaya, interaktif dan lancar, dan boleh berjalan dengan lancar pada pelbagai peranti; 3. Menggunakan timbunan teknologi H5, anda boleh membuat laman web responsif dan fungsi interaktif yang kompleks.

H5 dan HTML5: Istilah yang biasa digunakan dalam pembangunan webH5 dan HTML5: Istilah yang biasa digunakan dalam pembangunan webApr 13, 2025 am 12:01 AM

H5 dan HTML5 merujuk kepada perkara yang sama, iaitu HTML5. HTML5 adalah versi kelima HTML, membawa ciri -ciri baru seperti tag semantik, sokongan multimedia, kanvas dan grafik, penyimpanan luar talian dan penyimpanan tempatan, meningkatkan ekspresi dan interaktiviti laman web.

Apa yang dirujuk oleh H5? Meneroka konteksApa yang dirujuk oleh H5? Meneroka konteksApr 12, 2025 am 12:03 AM

H5referstohtml5, apivotaltechnologyinwebdevelopment.1) html5introducesnewelementsandapisforrich, dynamicwebapplications.2) itsupp ortsmultimediawithoutplugins, enhancusexperienceaceacrossdevices.3) SemantikelementsImproveContentstructureandseo.4) H5'srespo

H5: Alat, Rangka Kerja, dan Amalan TerbaikH5: Alat, Rangka Kerja, dan Amalan TerbaikApr 11, 2025 am 12:11 AM

Alat dan kerangka yang perlu dikuasai dalam pembangunan H5 termasuk Vue.js, React dan Webpack. 1.vue.js sesuai untuk membina antara muka pengguna dan menyokong pembangunan komponen. 2. Leact mengoptimumkan rendering halaman melalui DOM maya, sesuai untuk aplikasi yang kompleks. 3.WebPack digunakan untuk pembungkusan modul dan mengoptimumkan beban sumber.

Warisan HTML5: Memahami H5 pada masa kiniWarisan HTML5: Memahami H5 pada masa kiniApr 10, 2025 am 09:28 AM

Html5hassignificlylylectransformedwebdevelopmentbyintroducingsemanticelements, enhancingmultimediasupport, andimprovingperformance.1) itmadewebebsitesmoreaccessibleandseo-friendlywithSemhyViVeShive, dan

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)