text: /**
   * jquery.slitslider.js v1.1.0
   * http://www.codrops.com
   *
   * Licensed under the MIT license.
   * http://www.opensource.org/licenses/mit-license.php
   * 
   * Copyright 2012, Codrops
   * http://www.codrops.com
   */
  
  ;( function( $, window, undefined ) {
  	
  	'use strict';
  
  	/*
  	* debouncedresize: special jQuery event that happens once after a window resize
  	*
  	* latest version and complete README available on Github:
  	* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js
  	*
  	* Copyright 2011 @louis_remi
  	* Licensed under the MIT license.
  	*/
  	var $event = $.event,
  	$special,
  	resizeTimeout;
  
  	$special = $event.special.debouncedresize = {
  		setup: function() {
  			$( this ).on( "resize", $special.handler );
  		},
  		teardown: function() {
  			$( this ).off( "resize", $special.handler );
  		},
  		handler: function( event, execAsap ) {
  			// Save the context
  			var context = this,
  				args = arguments,
  				dispatch = function() {
  					// set correct event type
  					event.type = "debouncedresize";
  					$event.dispatch.apply( context, args );
  				};
  
  			if ( resizeTimeout ) {
  				clearTimeout( resizeTimeout );
  			}
  
  			execAsap ?
  				dispatch() :
  				resizeTimeout = setTimeout( dispatch, $special.threshold );
  		},
  		threshold: 20
  	};
  
  	// global
  	var $window = $( window ),
  		$document = $( document ),
  		Modernizr = window.Modernizr;
  
  	$.Slitslider = function( options, element ) {
  		
  		this.$elWrapper = $( element );
  		this._init( options );
  		
  	};
  
  	$.Slitslider.defaults = {
  		// transitions speed
  		speed : 800,
  		// if true the item's slices will also animate the opacity value
  		optOpacity : false,
  		// amount (%) to translate both slices - adjust as necessary
  		translateFactor : 230,
  		// maximum possible angle
  		maxAngle : 25,
  		// maximum possible scale
  		maxScale : 2,
  		// slideshow on / off
  		autoplay : false,
  		// keyboard navigation
  		keyboard : true,
  		// time between transitions
  		interval : 9000,
  		// callbacks
  		onBeforeChange : function( slide, idx ) { return false; },
  		onAfterChange : function( slide, idx ) { return false; }
  	};
  
  	$.Slitslider.prototype = {
  
  		_init : function( options ) {
  			
  			// options
  			this.options = $.extend( true, {}, $.Slitslider.defaults, options );
  
  			// https://github.com/twitter/bootstrap/issues/2870
  			this.transEndEventNames = {
  				'WebkitTransition' : 'webkitTransitionEnd',
  				'MozTransition' : 'transitionend',
  				'OTransition' : 'oTransitionEnd',
  				'msTransition' : 'MSTransitionEnd',
  				'transition' : 'transitionend'
  			};
  			this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ];
  			// suport for css 3d transforms and css transitions
  			this.support = Modernizr.csstransitions && Modernizr.csstransforms3d;
  			// the slider
  			this.$el = this.$elWrapper.children( '.sl-slider' );
  			// the slides
  			this.$slides = this.$el.children( '.sl-slide' ).hide();
  			// total slides
  			this.slidesCount = this.$slides.length;
  			// current slide
  			this.current = 0;
  			// control if it's animating
  			this.isAnimating = false;
  			// get container size
  			this._getSize();
  			// layout
  			this._layout();
  			// load some events
  			this._loadEvents();
  			// slideshow
  			if( this.options.autoplay ) {
  			
  				this._startSlideshow();
  			
  			}
  
  		},
  		// gets the current container width & height
  		_getSize : function() {
  
  			this.size = {
  				width : this.$elWrapper.outerWidth( true ),
  				height : this.$elWrapper.outerHeight( true )
  			};
  
  		},
  		_layout : function() {
  			
  			this.$slideWrapper = $( '<div class="sl-slides-wrapper" />' );
  			
  			// wrap the slides
  			this.$slides.wrapAll( this.$slideWrapper ).each( function( i ) {
  				
  				var $slide = $( this ),
  					// vertical || horizontal
  					orientation = $slide.data( 'orientation' );
  					
  				$slide.addClass( 'sl-slide-' + orientation )
  					  .children()
  					  .wrapAll( '<div class="sl-content-wrapper" />' )
  					  .wrapAll( '<div class="sl-content" />' );
  			
  			} );
  			
  			// set the right size of the slider/slides for the current window size
  			this._setSize();
  			// show first slide
  			this.$slides.eq( this.current ).show();
  			
  		},
  		_navigate : function( dir, pos ) {
  			
  			if( this.isAnimating || this.slidesCount < 2 ) {
  			
  				return false;
  			
  			}
  
  			this.isAnimating = true;
  
  			var self = this,
  				$currentSlide = this.$slides.eq( this.current );
  
  			// if position is passed
  			if( pos !== undefined ) {
  
  				this.current = pos;
  
  			}
  			// if not check the boundaries
  			else if( dir === 'next' ) {
  
  				this.current = this.current < this.slidesCount - 1 ? ++this.current : 0;
  
  			}
  			else if( dir === 'prev' ) {
  
  				this.current = this.current > 0 ? --this.current : this.slidesCount - 1;
  
  			}
  
  			this.options.onBeforeChange( $currentSlide, this.current );
  			
  			// next slide to be shown
  			var $nextSlide = this.$slides.eq( this.current ),
  				// the slide we want to cut and animate
  				$movingSlide = ( dir === 'next' ) ? $currentSlide : $nextSlide,
  				
  				// the following are the data attrs set for each slide
  				configData = $movingSlide.data(),
  				config = {};
  			
  			config.orientation = configData.orientation || 'horizontal',
  			config.slice1angle = configData.slice1Rotation || 0,
  			config.slice1scale = configData.slice1Scale || 1,
  			config.slice2angle = configData.slice2Rotation || 0,
  			config.slice2scale = configData.slice2Scale || 1;
  				
  			this._validateValues( config );
  			
  			var cssStyle = config.orientation === 'horizontal' ? {
  					marginTop : -this.size.height / 2
  				} : {
  					marginLeft : -this.size.width / 2
  				},
  				// default slide's slices style
  				resetStyle = {
  					'transform' : 'translate(0%,0%) rotate(0deg) scale(1)',
  					opacity : 1 
  				},
  				// slice1 style
  				slice1Style	= config.orientation === 'horizontal' ? {
  					'transform' : 'translateY(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')'
  				} : {
  					'transform' : 'translateX(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')'
  				},
  				// slice2 style
  				slice2Style	= config.orientation === 'horizontal' ? {
  					'transform' : 'translateY(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')'
  				} : {
  					'transform' : 'translateX(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')'
  				};
  			
  			if( this.options.optOpacity ) {
  			
  				slice1Style.opacity = 0;
  				slice2Style.opacity = 0;
  			
  			}
  			
  			// we are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is either coming "next"
  			// or going "prev" according to the direction.
  			// the idea is to make it more interesting by giving some animations to the respective slide's elements
  			//( dir === 'next' ) ? $nextSlide.addClass( 'sl-trans-elems' ) : $currentSlide.addClass( 'sl-trans-back-elems' );
  			
  			$currentSlide.removeClass( 'sl-trans-elems' );
  
  			var transitionProp = {
  				'transition' : 'all ' + this.options.speed + 'ms ease-in-out'
  			};
  
  			// add the 2 slices and animate them
  			$movingSlide.css( 'z-index', this.slidesCount )
  						.find( 'div.sl-content-wrapper' )
  						.wrap( $( '<div class="sl-content-slice" />' ).css( transitionProp ) )
  						.parent()
  						.cond(
  							dir === 'prev', 
  							function() {
  							
  								var slice = this;
  								this.css( slice1Style );
  								setTimeout( function() {
  									
  									slice.css( resetStyle );
  
  								}, 50 );
  										 
  							}, 
  							function() {
  								
  								var slice = this;
  								setTimeout( function() {
  									
  									slice.css( slice1Style );
  
  								}, 50 );
  						
  							}
  						)
  						.clone()
  						.appendTo( $movingSlide )
  						.cond(
  							dir === 'prev', 
  							function() {
  								
  								var slice = this;
  								this.css( slice2Style );
  								setTimeout( function() {
  
  									$currentSlide.addClass( 'sl-trans-back-elems' );
  
  									if( self.support ) {
  
  										slice.css( resetStyle ).on( self.transEndEventName, function() {
  
  											self._onEndNavigate( slice, $currentSlide, dir );
  
  										} );
  
  									}
  									else {
  
  										self._onEndNavigate( slice, $currentSlide, dir );
  
  									}
  
  								}, 50 );
  						
  							},
  							function() {
  								
  								var slice = this;
  								setTimeout( function() {
  
  									$nextSlide.addClass( 'sl-trans-elems' );
  									
  									if( self.support ) {
  
  										slice.css( slice2Style ).on( self.transEndEventName, function() {
  
  											self._onEndNavigate( slice, $currentSlide, dir );
  
  										} );
  
  									}
  									else {
  
  										self._onEndNavigate( slice, $currentSlide, dir );
  
  									}
  
  								}, 50 );
  								
  							}
  						)
  						.find( 'div.sl-content-wrapper' )
  						.css( cssStyle );
  			
  			$nextSlide.show();
  			
  		},
  		_validateValues : function( config ) {
  			
  			// OK, so we are restricting the angles and scale values here.
  			// This is to avoid the slices wrong sides to be shown.
  			// you can adjust these values as you wish but make sure you also ajust the
  			// paddings of the slides and also the options.translateFactor value and scale data attrs
  			if( config.slice1angle > this.options.maxAngle || config.slice1angle < -this.options.maxAngle ) {
  				
  				config.slice1angle = this.options.maxAngle;
  			
  			}
  			if( config.slice2angle > this.options.maxAngle  || config.slice2angle < -this.options.maxAngle ) {
  				
  				config.slice2angle = this.options.maxAngle;
  			
  			}
  			if( config.slice1scale > this.options.maxScale || config.slice1scale <= 0 ) {
  			
  				config.slice1scale = this.options.maxScale;
  			
  			}
  			if( config.slice2scale > this.options.maxScale || config.slice2scale <= 0 ) {
  				
  				config.slice2scale = this.options.maxScale;
  			
  			}
  			if( config.orientation !== 'vertical' && config.orientation !== 'horizontal' ) {
  			
  				config.orientation = 'horizontal'
  			
  			}
  			
  		},
  		_onEndNavigate : function( $slice, $oldSlide, dir ) {
  			
  			// reset previous slide's style after next slide is shown
  			var $slide = $slice.parent(),
  				removeClasses = 'sl-trans-elems sl-trans-back-elems';
  			
  			// remove second slide's slice
  			$slice.remove();
  			// unwrap..
  			$slide.css( 'z-index', 1 )
  				  .find( 'div.sl-content-wrapper' )
  				  .unwrap();
  			
  			// hide previous current slide
  			$oldSlide.hide().removeClass( removeClasses );
  			$slide.removeClass( removeClasses );
  			// now we can navigate again..
  			this.isAnimating = false;
  			this.options.onAfterChange( $slide, this.current );
  			
  		},
  		_setSize : function() {
  		
  			// the slider and content wrappers will have the window's width and height
  			var cssStyle = {
  				width : this.size.width,
  				height : this.size.height
  			};
  			
  			this.$el.css( cssStyle ).find( 'div.sl-content-wrapper' ).css( cssStyle );
  		
  		},
  		_loadEvents : function() {
  			
  			var self = this;
  			
  			$window.on( 'debouncedresize.slitslider', function( event ) {
  				
  				// update size values
  				self._getSize();
  				// set the sizes again
  				self._setSize();
  				
  			} );
  
  			if ( this.options.keyboard ) {
  				
  				$document.on( 'keydown.slitslider', function(e) {
  
  					var keyCode = e.keyCode || e.which,
  						arrow = {
  							left: 37,
  							up: 38,
  							right: 39,
  							down: 40
  						};
  
  					switch (keyCode) {
  						
  						case arrow.left :
  
  							self._stopSlideshow();
  							self._navigate( 'prev' );
  							break;
  						
  						case arrow.right :
  							
  							self._stopSlideshow();
  							self._navigate( 'next' );
  							break;
  
  					}
  
  				} );
  
  			}
  		
  		},
  		_startSlideshow: function() {
  
  			var self = this;
  
  			this.slideshow = setTimeout( function() {
  
  				self._navigate( 'next' );
  
  				if ( self.options.autoplay ) {
  
  					self._startSlideshow();
  
  				}
  
  			}, this.options.interval );
  
  		},
  		_stopSlideshow: function() {
  
  			if ( this.options.autoplay ) {
  
  				clearTimeout( this.slideshow );
  				this.isPlaying = false;
  				this.options.autoplay = false;
  
  			}
  
  		},
  		_destroy : function( callback ) {
  			
  			this.$el.off( '.slitslider' ).removeData( 'slitslider' );
  			$window.off( '.slitslider' );
  			$document.off( '.slitslider' );
  			this.$slides.each( function( i ) {
  
  				var $slide = $( this ),
  					$content = $slide.find( 'div.sl-content' ).children();
  
  				$content.appendTo( $slide );
  				$slide.children( 'div.sl-content-wrapper' ).remove();
  
  			} );
  			this.$slides.unwrap( this.$slideWrapper ).hide();
  			this.$slides.eq( 0 ).show();
  			if( callback ) {
  
  				callback.call();
  
  			}
  
  		},
  		// public methos: adds more slides to the slider
  		add : function( $slides, callback ) {
  
  			this.$slides = this.$slides.add( $slides );
  
  			var self = this;
  			
  			
  			$slides.each( function( i ) {
  
  				var $slide = $( this ),
  					// vertical || horizontal
  					orientation = $slide.data( 'orientation' );
  
  				$slide.hide().addClass( 'sl-slide-' + orientation )
  					  .children()
  					  .wrapAll( '<div class="sl-content-wrapper" />' )
  					  .wrapAll( '<div class="sl-content" />' )
  					  .end()
  					  .appendTo( self.$el.find( 'div.sl-slides-wrapper' ) );
  
  			} );
  
  			this._setSize();
  
  			this.slidesCount = this.$slides.length;
  			
  			if ( callback ) {
  
  				callback.call( $items );
  
  			}
  
  		},
  		// public method: shows next slide
  		next : function() {
  
  			this._stopSlideshow();
  			this._navigate( 'next' );
  
  		},
  		// public method: shows previous slide
  		previous : function() {
  
  			this._stopSlideshow();
  			this._navigate( 'prev' );
  
  		},
  		// public method: goes to a specific slide
  		jump : function( pos ) {
  
  			pos -= 1;
  
  			if( pos === this.current || pos >= this.slidesCount || pos < 0 ) {
  
  				return false;
  
  			}
  
  			this._stopSlideshow();
  			this._navigate( pos > this.current ? 'next' : 'prev', pos );
  
  		},
  		// public method: starts the slideshow
  		// any call to next(), previous() or jump() will stop the slideshow
  		play : function() {
  
  			if( !this.isPlaying ) {
  
  				this.isPlaying = true;
  
  				this._navigate( 'next' );
  				this.options.autoplay = true;
  				this._startSlideshow();
  
  			}
  
  		},
  		// public method: pauses the slideshow
  		pause : function() {
  
  			if( this.isPlaying ) {
  
  				this._stopSlideshow();
  
  			}
  
  		},
  		// public method: check if isAnimating is true
  		isActive : function() {
  
  			return this.isAnimating;
  
  		},
  		// publicc methos: destroys the slicebox instance
  		destroy : function( callback ) {
  
  			this._destroy( callback );
  		
  		}
  
  	};
  	
  	var logError = function( message ) {
  
  		if ( window.console ) {
  
  			window.console.error( message );
  		
  		}
  
  	};
  	
  	$.fn.slitslider = function( options ) {
  
  		var self = $.data( this, 'slitslider' );
  		
  		if ( typeof options === 'string' ) {
  			
  			var args = Array.prototype.slice.call( arguments, 1 );
  			
  			this.each(function() {
  			
  				if ( !self ) {
  
  					logError( "cannot call methods on slitslider prior to initialization; " +
  					"attempted to call method '" + options + "'" );
  					return;
  				
  				}
  				
  				if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) {
  
  					logError( "no such method '" + options + "' for slitslider self" );
  					return;
  				
  				}
  				
  				self[ options ].apply( self, args );
  			
  			});
  		
  		} 
  		else {
  		
  			this.each(function() {
  				
  				if ( self ) {
  
  					self._init();
  				
  				}
  				else {
  
  					self = $.data( this, 'slitslider', new $.Slitslider( options, this ) );
  				
  				}
  
  			});
  		
  		}
  		
  		return self;
  		
  	};
  	
  } )( jQuery, window );
  