/*
 * EnterFrame - A jquery extension that creates a bindable enterFrame event.
 *
 * Copyright (c) 2011 Matthew Drake (w) The Foundry Agency
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 *
 */
var parseInput=function(val,base){

	if(!isNaN(val))
		return val;
	
	
	if(val.search(/%$/g)!=-1){
		val = Number(val.replace(/[^\-\.0-9]/gi,""))/100;
		//
		return val*base;
	}
	return 0;
}


jQuery.event.special.enterFrame = {
	  setup: function( data, namespaces, eventHandle ) {
		$.enterFrame('start');
		$(this).data('enterFrame._timestart',$.enterFrame('count'));
	  },
	  
	  add: function( handleObj ) {
	      // Event code.

	      // Save a reference to the bound event handler.
	      var callback = handleObj.handler;

	      handleObj.handler = function( event ) {
	    	  if(event.target==event.currentTarget && !$(event.target).hasClass("enter-frame-pause")){	    	
	    		  return callback.apply( this, arguments );
	    	  }
	    	  return true;
	      };
	  },
	  teardown:function(obj){
		  //$.enterFrame("stop");
	  },
	  remove:function(obj){
		  $(this).removeData("enterFrame._timestart");
	  }
	};
	



( function($) {
	
	
	/*
	 * 
	 * Define Local EnterFrame
	 * 
	 */
	
	var methods = {
		    base : function( options ) { 
				
				$(this).bind("enterFrame",options);
				
				return this;
			},
			cycle:function(options,interval,namespace){
				$.enterFrame('start');
				if(!namespace)
					namespace="enterFrame.cycle";
				
				if(!interval.interval)
					interval = {interval:interval,offset:0};
				else
					interval.offset = parseInput(interval.offset,interval.interval);
				
				
				$(this).data("enterFrame.callback",{interval:interval.interval,callback:options,offset:interval.offset});
				
				
				$(this).bind(namespace,function(e,d){
					
					var data = $(this).data("enterFrame.callback");
					//console.log(d.count+":"+data.offset+":"+d.interval);
					if((d.count+data.offset)%data.interval==0){
						
						data.callback.call(this,e,d);
					}
					
					return true;
				});
				
				return this;
			},
			
			removeCycle:function(namespace){
				if(!namespace)
					namespace="enterFrame.cycle";
				
				
				$(this).unbind(namespace);
				
				return this;
			},
			resetCycle:function(namespace){
				
				var data = $(this).data("enterFrame.callback");
				if(!data)
					return;
				//console.log($.enterFrame("count")%data.interval+1);
				data.offset= 1-($.enterFrame("count")%data.interval);
				$(this).data("enterFrame.callback",data);
				
				return this;
			},
			pause:function(){
				
				
				$(this).toggleClass("enter-frame-pause",true);
				
				return this;
			},
			resume:function(){
				
				
				$(this).toggleClass("enter-frame-pause",false);
				
				return this;
			},
			remove:function(){
				$(this).unbind("enterFrame");
			},
	
		    count : function( ) { 
				return $.enterFrame('count')-$(this).data("enterFrame._timestart");
			}
	};
	
	
$.fn.extend(
{
	enterFrame: function(method)
	{
		if ( methods[method] ) {
	      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
	    } else if ( typeof method === 'object' || ! method || $.isFunction(method) ) {
	      return methods.base.apply( this, arguments );
	    } else {
	      //$.error( 'Method ' +  method + ' does not exist on enterframe' );
	    	console.log( 'Method ' +  method + ' does not exist on enterframe' );
	    }		
	}
});


	/*
	 * 
	 * Define Global EnterFrame
	 * 
	 */


	/* 
	 *Set defaults 
	 */
	var globalDefaults = {
		frameRate:30,
		calibrate:false,
		_expired:false,
		lastFrame:false,
		count:0,
		paused:false
	};
	
	/* 
	 *Define Global Methods 
	 */
	var globalMethods = {
			//recalibrates framerate and resets interval
		    start : function( options ) {
				
				//if(options.callback)
					//$.enterFrame('bind',options.callback);
				
				
				var d = $(window).data('enterFrame');
				
				//if last frame more than a second ago
				if(d&&d.lastFrame+2000<(new Date().getTime())){
					//console.log("expired fired");
					d._expired=true;
				}
				
				if(d&&!d._expired&&d.interval){					
					return this;					
				}
				
				
				if (!d)
				{
					d = $.extend(globalDefaults, options);					
				}else{
					if(d&&options&&d.frameRate!=options.frameRate)
						d.lastFrame=false;
					
					d = $.extend(d, options);
				}
				
				
				
				$(window).data('enterFrame', d );
				
				if(d.interval){
					
					$.enterFrame('reset',d);					
				}else{
					$.enterFrame('init',d);
				}
				
			
				return this;
			},
			count:function(){
				var d = $(window).data("enterFrame");
				return d.count;
			},
			
			init:function(data){
				
				if(!data)
					data = $(window).data("enterFrame");
				data._expired=false;
				if(data.interval)
					window.clearInterval(data.interval);
				data.interval = window.setInterval("$.enterFrame('frame')",$.enterFrame('getInterval',data));
				$(window).data("enterFrame",data);
			},
			getInterval:function(data){
				
				//If no calibration, try taking clock at its word
				if(!data.lastFrame)
					return Math.round(1000/data.frameRate);
				
				//Try some fancy guessing
				var now = (new Date().getTime());
				var since = now - data.lastFrame;
				
				//these should be equal
				var howOff = (1000*data.frameRate)-since;
				
				//if they're not, use them as the new base!
				return Math.round((howOff+1000)/data.frameRate);
				
			},
			reset:function(data){
				
				window.clearInterval(data.interval);				
				$.enterFrame('init',data);
				
			},
			frame:function(e){
				var d = $(window).data("enterFrame");
				if(d.paused)
					return;
				d.lastFrame = (new Date().getTime());
				d.count++;
				
				$("*").trigger("enterFrame",d);
				
				$(window).data("enterFrame",d);
				
				
			},
			pause : function( ) { 

				var d = $(window).data("enterFrame");
				d.paused=true;
				$(window).data("enterFrame",d);
			},
			unpause:function(){				
				var d = $(window).data("enterFrame");
				d.paused=false;
				$(window).data("enterFrame",d);
			},
		    stop : function(data) { 
				if(!data)
					data = $(window).data("enterFrame");
				window.clearInterval(data.interval);
				$(window).data("enterFrame",data);
			},
			bind:function(data){
				$(window).enterFrame(data);
			},
			bindAndStart:function(data){
				$(window).enterFrame(data);
				$.enterFrame('start');
			}
			
	};

	
	/* 
	 *Extend Global Methods 
	 */
$.extend(
	{
		enterFrame: function(method)
		{
			if ( globalMethods[method] ) {
		      return globalMethods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		    } else if($.isFunction(method)){
		    	return globalMethods.bindAndStart.apply( this, arguments );
		    }else if ( typeof method === 'object' || ! method ) {
		      return globalMethods.start.apply( this, arguments );
		    } else {
		    	console.log( 'Method ' +  method + ' does not exist on enterframe' );
		    }		
		}
	});


})(jQuery);




/*
 * Tween - A jquery extension that creates a tween enterFrame event.
 *
 * Copyright (c) 2011 Matthew Drake (w) The Foundry Agency
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 *
 */

( function($) {
	
	
	/*
	 * 
	 * Define Local Tween
	 * 
	 */
	var defaults = {
		frame:function(){},
		oncomplete:function(){},
		_timestart:0,
		length:100,
		start:0,
		end:1,
		css:false,
		completed:0,
		ease:false
	};
	
	var methods = {
		    base : function( options ) { 
				$.enterFrame('start');
				if($.isFunction(options)){
					options = {frame:options};
					if(arguments.length>1)
						options = $.extend({},options,arguments[1]);
				}
				//$(this).bind("enterFrame",options);
				if(options.ease){
					if(!isNaN(options.ease)||options.ease===true){
						options.ease="inOutQuad";
					}					
				}
				

				
				options = $.extend({},defaults, options);
				
				if(options.css&&!options.start&&$(this).css(options.css))
					options.start = Number($(this).css(options.css).replace(/[^0-9\.\-]/g,""));
				
				options._timestart = $.enterFrame('count');
				  
				
				$(this).tween('remove');
				$(this).data("foundryTween",options);
				
				
				$(this).toggleClass("in-tween",true);
				$(this).bind("enterFrame.tween",function(e,d){
					

					
					var tweenData = $(this).data("foundryTween");
					
					var span = d.count-tweenData._timestart;
					var length = tweenData.length;
					
					if(span>length){
						$(this).tween('remove');
						tweenData.completed=1;
						tweenData.oncomplete.call(this,e,$.extend({},d,tweenData));
						return true;
					}
						
					tweenData.completed = span/length;
					var dist =tweenData.end-tweenData.start; 
					tweenData.pos = tweenData.completed*dist+tweenData.start;
					
					
					if(tweenData.ease){
					
						/*
						 * 
						 * Ease 
						 */
						var ease = tweenData.ease.charAt(0).toUpperCase() + tweenData.ease.slice(1);
						
						tweenData.tcompleted = $.easing["ease"+ease](null,tweenData.completed,0,1,1);
						//console.log(tweenData.completed+":"+(1/length)+":"+
							//	tweenData.tcompleted);
					}
					
					if(tweenData.tcompleted){
						tweenData.tpos = tweenData.tcompleted*dist+tweenData.start;
					}else{						
						tweenData.tpos=tweenData.pos;
						tweenData.tcompleted=tweenData.completed;
					}
					
					tweenData.frame.call(this,e,$.extend({},d,tweenData));
					
				});
				
				return this;
			},
			remove:function(){
				$(this).toggleClass("in-tween",false);
				$(this).unbind("enterFrame.tween");
				$(this).removeData("foundryTween");
			},
			
			restart:function(){
				var d = $(this).data("foundryTween");
				d._timestart=$.enterFrame('count');
				$(this).data("foundryTween",d);
			},
	
		    frame : function( ) { 
				//pass
			},
			
		    start : function( ) { 
				//pass
			},
		    moveto : function( options ) { 
				//pass
			}
	};
	
	
$.fn.extend(
{
	tween: function(method)
	{
		if ( methods[method] ) {
	      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
	    } else if ( typeof method === 'object' || ! method || $.isFunction(method) ) {
	      return methods.base.apply( this, arguments );
	    } else {
	      //$.error( 'Method ' +  method + ' does not exist on enterframe' );
	    	console.log( 'Method ' +  method + ' does not exist on enterframe' );
	    }		
	}
});


		
	/* 
	 *Extend Global Methods 
	 */
$.extend(
	{
		tween: function(method)
		{
			return $("body").tween(method);		
		}
	});


})(jQuery);




/*
 * Wait - A jquery extension that creates a wait enterFrame event.
 *
 * Copyright (c) 2011 Matthew Drake (w) The Foundry Agency
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 *
 */

( function($) {
	
	
	/*
	 * 
	 * Define Local Wait
	 * 
	 */
	var defaults = {
		oncancel:function(){},
		oncomplete:function(){},
		_timestart:0,
		length:90
		
	};
	
	var methods = {
		    base : function( options ) { 
				$.enterFrame('start');
				if($.isFunction(options)){
					options = {oncomplete:options};
					if(arguments.length>1){
						if(typeof arguments[1] === 'object' )
							options = $.extend({},options,arguments[1]);
						else
							options.length=arguments[1];
					}
				}
				
				  
				
				$(this).wait('remove');
				options._timestart=$.enterFrame('count');
				options = $.extend({},defaults, options);
				$(this).data("foundryWait",options);
				
				
				$(this).toggleClass("in-wait",true);
				$(this).bind("enterFrame.wait",function(e,d){
					

					
					var waitData = $(this).data("foundryWait");
					
					var span = d.count-waitData._timestart;
					var length = waitData.length;
					
					if(span>length){
						$(this).wait('remove',true);
						
						waitData.oncomplete.call(this,e,d);
						return true;
					}
						
					
					
				});
				
				return this;
			},
			remove:function(skipcancel){
				if(!skipcancel){
					var data = $(this).data("foundryWait");
					
					if(data){
						data.oncancel.call(this);
					}
				}
				
				$(this).toggleClass("in-wait",false);
				$(this).unbind("enterFrame.wait");
				$(this).removeData("foundryWait");
			},
			
			restart:function(){
				var d = $(this).data("foundryWait");
				d._timestart=$.enterFrame('count');
				$(this).data("foundryWait",d);
			},
			cancel:function(){
				$(this).wait('remove');
				
			},
			
			fire:function(){
				var d = $(this).data("foundryWait");
				d._timestart=$.enterFrame('count')-d.length;
				$(this).data("foundryWait",d);
			},
	
		    frame : function( ) { 
				//pass
			},
			
		    start : function( ) { 
				//pass
			},
		    moveto : function( options ) { 
				//pass
			}
	};
	
	
$.fn.extend(
{
	wait: function(method)
	{
		if ( methods[method] ) {
	      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
	    } else if ( typeof method === 'object' || ! method || $.isFunction(method) ) {
	      return methods.base.apply( this, arguments );
	    } else {
	      //$.error( 'Method ' +  method + ' does not exist on enterframe' );
	    	console.log( 'Method ' +  method + ' does not exist on enterframe' );
	    }		
	}
});


		
	/* 
	 *Extend Global Methods 
	 */
$.extend(
	{
		wait: function(method)
		{
			return $("body").tween(method);		
		}
	});


})(jQuery);



/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */
