AI编程助手
AI免费问答

教你如何用HTML5和JS实现切水果游戏

黄舟   2018-05-22 11:18   8451浏览 原创

切水果游戏曾经是一款风靡手机的休闲游戏,今天要介绍的就是一款网页版的切水果游戏,由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:hostingdemosruit-ninjaoutputscriptscollide.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 : 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 = 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:hostingdemosruit-ninjaoutputscriptslayer.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:hostingdemosruit-ninjaoutputscriptsmain.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>Google Chrome</span> 体验本游戏";

	if( !buzz.isSupported() )
	    tip = tip.replace( "$", "您的浏览器不支持 <audio tip ucren.element return define var message exports.postmessage splitindex to messages.slice ucren.dispatch exports.addeventlistener exports.removeeventlistener ucren.dispatch.remove exports.init exports.switchsence exports.showmenu exports.hidemenu exports.shownewgame exports.hidenewgame exports.showdojo exports.hidedojo exports.showquit exports.hidequit message.addeventlistener dron>	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 'true'
	 * state( key ).isoff()			->	determine if the value of key is the boolean value 'false'
	 * 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 'true'
	 * state( key ).off()			->	set the value of key to boolean value 'false'
	 */

	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 
	// 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 )  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[0] && point[1] > origin[1] )
			return t;

		return t + PI;
	};

	return exports;
});

/**
 * @source D:hostingdemosruit-ninjaoutputscriptsactorydisplacement.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:hostingdemosruit-ninjaoutputscriptsactoryruit.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'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:hostingdemosruit-ninjaoutputscriptsactoryjuice.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  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 'MEDIA_ERR_ABORTED';
	                case 2:
	                    return 'MEDIA_ERR_NETWORK';
	                case 3:
	                    return 'MEDIA_ERR_DECODE';
	                case 4:
	                    return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
	                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 'HAVE_NOTHING';
	                case 1:
	                    return 'HAVE_METADATA';
	                case 2:
	                    return 'HAVE_CURRENT_DATA';
	                case 3:
	                    return 'HAVE_FUTURE_DATA';
	                case 4:
	                    return 'HAVE_ENOUGH_DATA';
	                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 'NETWORK_EMPTY';
	                case 1:
	                    return 'NETWORK_IDLE';
	                case 2:
	                    return 'NETWORK_LOADING';
	                case 3:
	                    return 'NETWORK_NO_SOURCE';
	                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( ' ' );

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

	            for( var t = 0; t  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( 'canplay.buzzwhenready', function() {
	                    func.call( that );
	                });
	            } else {
	                func.call( that );
	            }
	        };

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

	            for( var i = 0; i = 10 ) ? h : '0' + h;
	        m = withHours ? Math.floor( time / 60 % 60 ) : Math.floor( time / 60 );
	        m = isNaN( m ) ? '--' : ( m >= 10 ) ? m : '0' + m;
	        s = Math.floor( time % 60 );
	        s = isNaN( s ) ? '--' : ( s >= 10 ) ? s : '0' + s;
	        return withHours ? h + ':' + m + ':' + s : m + ':' + s;
	    },

	    fromTimer: function( time ) {
	        var splits = time.toString().split( ':' );
	        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:hostingdemosruit-ninjaoutputscriptslib
aphael.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 var return t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend" u='{mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},' n="/^s*((#[a-fd]{6})|(#[a-fd]{3})|rgba?(s*([d.]+%?s*,s*[d.]+%?s*,s*[d.]+(?:%?s*,s*[d.]+)?)%?s*)|hsba?(s*([d.]+(?:deg||%)?s*,s*[d.]+%?s*,s*[d.]+(?:%?s*,s*[d.]+)?)%?s*)|hsla?(s*([d.]+(?:deg||%)?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," v="r[e].toUpperCase," w="{" blur:0 cursor: cx:0 cy:0 fill: font: gradient:0 height:0 href: opacity:1 path: r:0 rotation:0 rx:0 ry:0 scale: src: stroke: target: title: translation: width:0 x="{" along: blur:e cx:e cy:e height:e opacity:e r:e rotation: rx:e ry:e 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 bf.innerhtml="<v:shape adj="></h>";
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((hb-d)
return c-f+b
}
return c
};
function bh(){
var a=[],b=0;
for(;b");
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;
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)
{
d1&&j--;
j*61||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;
h1&&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=j1&&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|e1){b.h=0;b.s-=0.2;b.s2){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 end: var if return x:0 a="bw(a);" for f='a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)' else d="d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]" c k switch case default: default:d e br="function(a,b,c,d){" bt="function(a,b,c,d,e,f,g,h,i,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);">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 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 x var o="[b,h],p=[a,g],q;B(l)">"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);
if(l>0&&l0&&n"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);
if(l>0&&l0&&n7)
{
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 c d i var 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){" for if return f.color='f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){' j="e" h by="function(b,c,d,e){" f="a.is(b,F)?g.getElementById(b):b;" container:f else switch case default: a a.next 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 bk>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]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]("
");
for(var j=0,k=i[w];j<k if j m e 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 bn="function(b,c){" this 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 this.next="null},bO=bN[e];" return d="S(c[1]);" this._.rt.cx="d;" this._.rt.cy="e;" this.clip bg this.node.parentnode.removechild for try b="{x:b.x,y:Infinity,width:0,height:0};">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 if for var this.attrs return this.node.parentnode.insertbefore bn b.nextsibling bd be b.attrs.blur="a;c.id=bh();bG(d,{stdDeviation:+a||1.5});" c.appendchild b._blur='c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);' delete a.canvas f.type="circle" bg g.type="ellipse" f.attrs='{x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};' this.width="a||this.width;" this.height="b||this.height;" this.canvas g.body 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 k.remove="function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);" 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;" c bh='function(a,b){var c=cd("group");' c.style.csstext="position:absolute;
left:0;
top:0;
width:" height: 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;' 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;' 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 c.setbox c.scale 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 e.cliprect='q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);' i.filter="(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);" d e="c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));" v.opacity='y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){' v.type="solid" h.fill="none" c.on='=null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);' f c.miterlimit='d["stroke-miterlimit"]||8;' c.dashstyle='G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}' h m.node.string>"));
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 d.colors d.focus="100%" 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 return c this.setbox bo.setbox="function(a,b,c){if(this.removed)return this;" var for switch case 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;" this.x="ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;" e.left else d.width d.height e.height bo.getbbox="function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);" this.group.parentnode.removechild this._.rt.deg d.gradient k i.gradient bo.toback="function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){" this.group.parentnode.insertbefore a.group.nextsibling this.group a.constructor="=cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);" 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: 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 function 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){' f.coordorigin='a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";' bk i.setbox bs='function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;' top:0 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){" f.style.csstext="position:absolute;left:0;top:0;width:" 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 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 " g.createstylesheet try cd='function(a){return g.createElement("<rvml:"+a+" class="rvml"'>")}}catch(a){cd=function(a){
return g.createElement("")}}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]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 else 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 if>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>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)":function(a){return C(a-1,3)+1},"":function(a){a=a*2;if(ad)return d;while(c<d>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 switch l if a.is for d bo.stop="function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);" this.timeouts="[];clearTimeout(this._ac);delete this._ac;return this};" bo.translate='function(a,b){return this.attr({translation:a+" "+b})};' bo var this while a 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](/[^wds+!~.:_-]/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"];' b a.ninja="function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];" i.was exports return define formats: preload: autoload: loop: function classbuzz.prototype.play s s.setpercent s.setvolume s.play classbuzz.prototype.stop this.sound.fadeout exports.create else unsupported.play unsupported.stop exports.exponential exports.exponential.co exports.bounce exports.bounce.co exports.quadratic exports.quadratic.ci exports.quadratic.co exports.quadratic.cio exports.circular exports.linear exports.back exports.back.ci exports.back.co string.prototype.trim string.prototype.format ucren.each item rtn string.prototype.htmlencode p.appendchild text p.innerhtml string.prototype.bytelength string.prototype.subbyte tail len .slice .replace function.prototype.defer me.apply function.prototype.bind function.prototype.saturate array.prototype.indexof i array.prototype.every array.prototype.filter result.push array.prototype.foreach fn.call array.prototype.map result array.prototype.some array.prototype.invoke this.foreach array.prototype.random ret.push ucren isie: isie6: isfirefox: issafari: isopera: ischrome: isstrict: tempdom: apply: to appendstyle:> 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  -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='" +
						image + "',sizingMethod='scale' );";
					/// 	_background: none;
					///  _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader( src='images/pic.png',sizingMethod='scale' );
				}else{
					dom.style.backgroundImage = "url( " + image + " )";
				}
				return this;
			},

			setAlpha: function(){
				var reOpacity = /alphas*(s*opacitys*=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:hostingdemosruit-ninjaoutputscriptsobjectackground.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:hostingdemosruit-ninjaoutputscriptsobjectconsole.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 > 0 ) );
	// };;

	return exports;
});

/**
 * @source D:hostingdemosruit-ninjaoutputscriptsobjectgame-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:hostingdemosruit-ninjaoutputscriptsobjecthome-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:hostingdemosruit-ninjaoutputscriptsobjecthome-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:hostingdemosruit-ninjaoutputscriptsobjectknife.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; i --)
			knifes[i].end();
	};;

	return exports;
});

/**
 * @source D:hostingdemosruit-ninjaoutputscriptsobjectlight.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 <p> 以上就是教你如何用HTML5和JS实现切水果游戏的内容,更多相关内容请关注PHP中文网(www.php.cn)!<br></p>
<!-- codeceo-bottom-big --><!--开源软件资源链接--><!--开源软件资源链接结束--><p class="bd_ad_bottom" style="margin:40px 0 40px 0"><br></p>
<p class="sogou_ads" style="float:left;margin-right:36px"><br></p>
<p class="baidu_ads" style="float:left"><br></p>
<p style="clear:both"><br></p></x></d></p></l></k></i></k></k></z></e></p></audio>

前端入门到VUE实战笔记:立即学习
>在学习笔记中,你将探索 前端 的入门与实战技巧!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。