text: /**
   * jquery.elastislide.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 autoSlide = false; //set this to enable autoslide.
    var delayTime = 3000; //ms — autoslide delay.
  
    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: 150
    };
  
    // ======================= imagesLoaded Plugin ===============================
    // https://github.com/desandro/imagesloaded
  
    // $('#my-container').imagesLoaded(myFunction)
    // execute a callback when all images have loaded.
    // needed because .load() doesn't work on cached images
  
    // callback function gets image collection as argument
    //  this is the container
  
    // original: mit license. paul irish. 2010.
    // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
  
    // blank image data-uri bypasses webkit log warning (thx doug jones)
    var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
  
    $.fn.imagesLoaded = function( callback ) {
      var $this = this,
        deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
        hasNotify = $.isFunction(deferred.notify),
        $images = $this.find('img').add( $this.filter('img') ),
        loaded = [],
        proper = [],
        broken = [];
  
      // Register deferred callbacks
      if ($.isPlainObject(callback)) {
        $.each(callback, function (key, value) {
          if (key === 'callback') {
            callback = value;
          } else if (deferred) {
            deferred[key](value);
          }
        });
      }
  
      function doneLoading() {
        var $proper = $(proper),
          $broken = $(broken);
  
        if ( deferred ) {
          if ( broken.length ) {
            deferred.reject( $images, $proper, $broken );
          } else {
            deferred.resolve( $images );
          }
        }
  
        if ( $.isFunction( callback ) ) {
          callback.call( $this, $images, $proper, $broken );
        }
      }
  
      function imgLoaded( img, isBroken ) {
        // don't proceed if BLANK image, or image is already loaded
        if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {
          return;
        }
  
        // store element in loaded images array
        loaded.push( img );
  
        // keep track of broken and properly loaded images
        if ( isBroken ) {
          broken.push( img );
        } else {
          proper.push( img );
        }
  
        // cache image and its state for future calls
        $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
  
        // trigger deferred progress method if present
        if ( hasNotify ) {
          deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );
        }
  
        // call doneLoading and clean listeners if all images are loaded
        if ( $images.length === loaded.length ){
          setTimeout( doneLoading );
          $images.unbind( '.imagesLoaded' );
        }
      }
  
      // if no images, trigger immediately
      if ( !$images.length ) {
        doneLoading();
      } else {
        $images.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){
          // trigger imgLoaded
          imgLoaded( event.target, event.type === 'error' );
        }).each( function( i, el ) {
            var src = el.src;
  
            // find out if this image has been already checked for status
            // if it was, and src has not changed, call imgLoaded on it
            var cached = $.data( el, 'imagesLoaded' );
            if ( cached && cached.src === src ) {
              imgLoaded( el, cached.isBroken );
              return;
            }
  
            // if complete is true and browser supports natural sizes, try
            // to check for image status manually
            if ( el.complete && el.naturalWidth !== undefined ) {
              imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
              return;
            }
  
            // cached images don't fire load sometimes, so we reset src, but only when
            // dealing with IE, or image is complete (loaded) and failed manual check
            // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
            if ( el.readyState || el.complete ) {
              el.src = BLANK;
              el.src = src;
            }
          });
      }
  
      return deferred ? deferred.promise( $this ) : $this;
    };
  
    // global
    var $window = $( window ),
      Modernizr = window.Modernizr;
  
    $.Elastislide = function( options, element ) {
  
      this.$el = $( element );
      this._init( options );
  
    };
  
    $.Elastislide.defaults = {
      // orientation 'horizontal' || 'vertical'
      orientation : 'horizontal',
      // sliding speed
      speed : 500,
      // sliding easing
      easing : 'ease-in-out',
      // the minimum number of items to show.
      // when we resize the window, this will make sure minItems are always shown
      // (unless of course minItems is higher than the total number of elements)
      minItems : 3,
      // optionally specify a selector rather than using the img element to read the image sizes
      // (we only use the first matching element within our items)
      imgSizeItemSelector : 'img',
      // index of the current item (left most item of the carousel)
      start : 0,
      // click item callback
      onClick : function( el, position, evt ) { return false; },
      onReady : function() { return false; },
      onBeforeSlide : function() { return false; },
      onAfterSlide : function() { return false; }
    };
  
    $.Elastislide.prototype = {
  
      _init : function( options ) {
  
        // options
        this.options = $.extend( true, {}, $.Elastislide.defaults, options );
  
        // https://github.com/twitter/bootstrap/issues/2870
        var self = this,
          transEndEventNames = {
            'WebkitTransition' : 'webkitTransitionEnd',
            'MozTransition' : 'transitionend',
            'OTransition' : 'oTransitionEnd',
            'msTransition' : 'MSTransitionEnd',
            'transition' : 'transitionend'
          };
  
        this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ];
  
        // suport for css transforms and css transitions
        this.support = Modernizr.csstransitions && Modernizr.csstransforms;
  
        // current item's index
        this.current = this.options.start;
  
        // control if it's sliding
        this.isSliding = false;
  
        this.$items = this.$el.children( 'li' );
        // total number of items
        this.itemsCount = this.$items.length;
        if( this.itemsCount === 0 ) {
  
          return false;
  
        }
        this._validate();
        // remove white space
        this.$items.detach();
        this.$el.empty();
        this.$el.append( this.$items );
  
        // main wrapper
        this.$el.wrap( '<div class="elastislide-wrapper elastislide-loading elastislide-' + this.options.orientation + '"></div>' );
  
        // check if we applied a transition to the <ul>
        this.hasTransition = false;
  
        // add transition for the <ul>
        this.hasTransitionTimeout = setTimeout( function() {
  
          self._addTransition();
  
        }, 100 );
  
        // preload the images
  
        this.$el.imagesLoaded( function() {
  
          self.$el.show();
  
          self._layout();
          self._configure();
  
          if( self.hasTransition ) {
  
            // slide to current's position
            self._removeTransition();
            self._slideToItem( self.current );
  
            self.$el.on( self.transEndEventName, function() {
  
              self.$el.off( self.transEndEventName );
              self._setWrapperSize();
              // add transition for the <ul>
              self._addTransition();
              self._initEvents();
  
            } );
  
          }
          else {
  
            clearTimeout( self.hasTransitionTimeout );
            self._setWrapperSize();
            self._initEvents();
            // slide to current's position
            self._slideToItem( self.current );
            setTimeout( function() { self._addTransition(); }, 25 );
  
          }
  
          self.options.onReady();
  
        } );
  
      },
      _validate : function() {
  
  
        if( this.options.minItems instanceof Function ) {
  
          this._minItemsFn = this.options.minItems;
          this.options.minItems = this.options.minItems( document.documentElement.clientWidth );
  
        }
  
  
  
        if( this.options.speed < 0 ) {
  
          this.options.speed = 500;
  
        }
        if( this.options.minItems < 1 || this.options.minItems > this.itemsCount ) {
  
          this.options.minItems = 1;
  
        }
        if( this.options.start < 0 || this.options.start > this.itemsCount - 1 ) {
  
          this.options.start = 0;
  
        }
        if( this.options.orientation != 'horizontal' && this.options.orientation != 'vertical' ) {
  
          this.options.orientation = 'horizontal';
  
        }
  
      },
      _layout : function() {
  
        this.$el.wrap( '<div class="elastislide-carousel"></div>' );
  
        this.$carousel = this.$el.parent();
        this.$wrapper = this.$carousel.parent().removeClass( 'elastislide-loading' );
  
        // save original image sizes
        var $img = this.$items.find( this.options.imgSizeItemSelector ).first();
        this.imgSize = { width : $img.outerWidth( true ), height : $img.outerHeight( true ) };
  
        this._setItemsSize();
        this.options.orientation === 'horizontal' ? this.$el.css( 'max-height', this.imgSize.height ) : this.$el.css( 'height', this.options.minItems * this.imgSize.height );
  
        // add the controls
        this._addControls();
  
      },
      _addTransition : function() {
  
        if( this.support ) {
  
          this.$el.css( 'transition', 'all ' + this.options.speed + 'ms ' + this.options.easing );
  
        }
        this.hasTransition = true;
  
      },
      _removeTransition : function() {
  
        if( this.support ) {
  
          this.$el.css( 'transition', 'all 0s' );
  
        }
        this.hasTransition = false;
  
      },
      _addControls : function() {
  
        var self = this;
  
        // add navigation elements
        this.$navigation = $( '<nav><span class="elastislide-prev">Previous</span><span class="elastislide-next">Next</span></nav>' )
          .appendTo( this.$wrapper );
  
  
        this.$navPrev = this.$navigation.find( 'span.elastislide-prev' ).on( 'mousedown.elastislide', function( event ) {
  
          self._slide( 'next' );
          return false;
  
        } );
  
        this.$navNext = this.$navigation.find( 'span.elastislide-next' ).on( 'mousedown.elastislide', function( event ) {
  
          self._slide( 'prev' );
          return false;
  
        } );
  
      },
      _setItemsSize : function() {
  
        // width for the items (%)
        var w = this.options.orientation === 'horizontal' ? ( Math.floor( this.$carousel.width() / this.options.minItems ) * 100 ) / this.$carousel.width() : 100;
  
        this.$items.css( {
          'width' : w + '%',
          'max-width' : this.imgSize.width,
          'max-height' : this.imgSize.height
        } );
  
        if( this.options.orientation === 'vertical' ) {
  
          this.$wrapper.css( 'max-width', this.imgSize.width + parseInt( this.$wrapper.css( 'padding-left' ) ) + parseInt( this.$wrapper.css( 'padding-right' ) ) );
  
        }
  
      },
      _setWrapperSize : function() {
  
        if( this.options.orientation === 'vertical' ) {
  
          this.$wrapper.css( {
            'height' : this.options.minItems * this.imgSize.height + parseInt( this.$wrapper.css( 'padding-top' ) ) + parseInt( this.$wrapper.css( 'padding-bottom' ) )
          } );
  
        }
  
      },
      _configure : function() {
  
        // check how many items fit in the carousel (visible area -> this.$carousel.width() )
        this.fitCount = this.options.orientation === 'horizontal' ?
          this.$carousel.width() < this.options.minItems * this.imgSize.width ? this.options.minItems : Math.floor( this.$carousel.width() / this.imgSize.width ) :
          this.$carousel.height() < this.options.minItems * this.imgSize.height ? this.options.minItems : Math.floor( this.$carousel.height() / this.imgSize.height );
  
      },
      _initEvents : function() {
  
        var self = this;
        //autoslide. To enablethis, set "var autoSlide" to "true" above.
        if( autoSlide ) {
          var translation = 0;
          // width/height of an item ( <li> )
          var itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true );
          // total width/height of the <ul>
          var totalSpace = this.itemsCount * itemSpace;
          // visible width/height
          var visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height();
          window.setInterval(function(){
            //test if we should go to next slide or return to first slide
            if(totalSpace > translation + visibleSpace)
            {
              self._slide('next');
              translation += visibleSpace;
            }
            else
            {
              self._slideTo(0);
              translation = 0;
            }
          }, delayTime);
        }
  
        $window.on( 'debouncedresize.elastislide', function() {
  
          if( self._minItemsFn ) {
            self.options.minItems = self._minItemsFn( document.documentElement.clientWidth );
          }
  
  
          self._setItemsSize();
          self._configure();
          self._slideToItem( self.current );
  
        } );
  
        this.$el.on( this.transEndEventName, function() {
  
          self._onEndTransition();
  
        } );
  
        if( this.options.orientation === 'horizontal' ) {
  
          this.$el.on( {
            swipeleft : function() {
  
              self._slide( 'next' );
  
            },
            swiperight : function() {
  
              self._slide( 'prev' );
  
            }
          } );
  
        }
        else {
  
          this.$el.on( {
            swipeup : function() {
  
              self._slide( 'next' );
  
            },
            swipedown : function() {
  
              self._slide( 'prev' );
  
            }
          } );
  
        }
  
        // item click event
        this.$el.on( 'click.elastislide', 'li', function( event ) {
  
          var $item = $( this );
  
          self.options.onClick( $item, $item.index(), event );
  
        });
  
      },
      _destroy : function( callback ) {
  
        this.$el.off( this.transEndEventName ).off( 'swipeleft swiperight swipeup swipedown .elastislide' );
        $window.off( '.elastislide' );
  
        this.$el.css( {
          'max-height' : 'none',
          'transition' : 'none'
        } ).unwrap( this.$carousel ).unwrap( this.$wrapper );
  
        this.$items.css( {
          'width' : 'auto',
          'max-width' : 'none',
          'max-height' : 'none'
        } );
  
        this.$navigation.remove();
        this.$wrapper.remove();
  
        if( callback ) {
  
          callback.call();
  
        }
  
      },
      _toggleControls : function( dir, display ) {
  
        if( display ) {
  
          ( dir === 'prev' ) ? this.$navNext.show() : this.$navPrev.show();
  
        }
        else {
  
          ( dir === 'prev' ) ? this.$navNext.hide() : this.$navPrev.hide();
  
        }
  
      },
      _slide : function( dir, tvalue ) {
  
        if( this.isSliding ) {
  
          return false;
  
        }
  
        this.options.onBeforeSlide();
  
        this.isSliding = true;
  
        var self = this,
          translation = this.translation || 0,
        // width/height of an item ( <li> )
          itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ),
        // total width/height of the <ul>
          totalSpace = this.itemsCount * itemSpace,
        // visible width/height
          visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height();
  
        if( tvalue === undefined ) {
  
          var amount = this.fitCount * itemSpace;
  
          if( amount < 0 ) {
  
            return false;
  
          }
  
          if( dir === 'next' && totalSpace - ( Math.abs( translation ) + amount ) < visibleSpace ) {
  
            amount = totalSpace - ( Math.abs( translation ) + visibleSpace );
  
            // show / hide navigation buttons
            this._toggleControls( 'next', false );
            this._toggleControls( 'prev', true );
  
          }
          else if( dir === 'prev' && Math.abs( translation ) - amount < 0 ) {
  
            amount = Math.abs( translation );
  
            // show / hide navigation buttons
            this._toggleControls( 'next', true );
            this._toggleControls( 'prev', false );
  
          }
          else {
  
            // future translation value
            var ftv = dir === 'next' ? Math.abs( translation ) + Math.abs( amount ) : Math.abs( translation ) - Math.abs( amount );
  
            // show / hide navigation buttons
            ftv > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false );
            ftv < totalSpace - visibleSpace ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false );
  
          }
  
          tvalue = dir === 'next' ? translation - amount : translation + amount;
  
        }
        else {
  
          var amount = Math.abs( tvalue );
  
          if( Math.max( totalSpace, visibleSpace ) - amount < visibleSpace ) {
  
            tvalue	= - ( Math.max( totalSpace, visibleSpace ) - visibleSpace );
  
          }
  
          // show / hide navigation buttons
          amount > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false );
          Math.max( totalSpace, visibleSpace ) - visibleSpace > amount ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false );
  
        }
  
        this.translation = tvalue;
  
        if( translation === tvalue ) {
  
          this._onEndTransition();
          return false;
  
        }
  
        if( this.support ) {
  
          if (this.options.orientation === 'horizontal') {
            this.$el.css( '-webkit-transform', 'translateX(' + -tvalue + 'px)' );
            this.$el.css( '-o-transform', 'translateX(' + -tvalue + 'px)' );
            this.$el.css( '-ms-transform', 'translateX(' + -tvalue + 'px)' );
            this.$el.css( '-moz-transform', 'translateX(' + -tvalue + 'px)' );
            this.$el.css( 'transform', 'translateX(' + -tvalue + 'px)' );
          } else {
            this.$el.css( '-webkit-transform', 'translateY(' + tvalue + 'px)' );
            this.$el.css( '-o-transform', 'translateY(' + tvalue + 'px)' );
            this.$el.css( '-ms-transform', 'translateY(' + tvalue + 'px)' );
            this.$el.css( '-moz-transform', 'translateY(' + tvalue + 'px)' );
            this.$el.css( 'transform', 'translateY(' + tvalue + 'px)' );
          }
  
        }
        else {
  
          $.fn.applyStyle = this.hasTransition ? $.fn.animate : $.fn.css;
          var styleCSS = this.options.orientation === 'horizontal' ? { left : tvalue } : { top : tvalue };
  
          this.$el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : this.options.speed, complete : function() {
  
            self._onEndTransition();
  
          } } ) );
  
        }
  
        if( !this.hasTransition ) {
  
          this._onEndTransition();
  
        }
  
      },
      _onEndTransition : function() {
  
        this.isSliding = false;
        this.options.onAfterSlide();
  
      },
      _slideTo : function( pos ) {
        var pos = pos || this.current,
          translation = Math.abs( this.translation ) || 0,
          itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ),
          posR = translation + this.$carousel.width(),
          ftv = Math.abs( pos * itemSpace );
  
        if( ftv + itemSpace > posR || ftv < translation ) {
  
          this._slideToItem( pos );
  
        }
  
      },
      _slideToItem : function( pos ) {
  
        // how much to slide?
        var amount	= this.options.orientation === 'horizontal' ? pos * this.$items.outerWidth( true ) : pos * this.$items.outerHeight( true );
        this._slide( '', -amount );
  
      },
      // public method: adds new items to the carousel
      /*
  
       how to use:
       var carouselEl = $( '#carousel' ),
       carousel = carouselEl.elastislide();
       ...
  
       // append or prepend new items:
       carouselEl.prepend('<li><a href="#"><img src="images/large/2.jpg" alt="image02" /></a></li>');
  
       // call the add method:
       es.add();
  
       */
      add : function( callback ) {
  
        var self = this,
          oldcurrent = this.current,
          $currentItem = this.$items.eq( this.current );
  
        // adds new items to the carousel
        this.$items = this.$el.children( 'li' );
        this.itemsCount = this.$items.length;
        this.current = $currentItem.index();
        this._setItemsSize();
        this._configure();
        this._removeTransition();
        oldcurrent < this.current ? this._slideToItem( this.current ) : this._slide( 'next', this.translation );
        setTimeout( function() { self._addTransition(); }, 25 );
  
        if ( callback ) {
  
          callback.call();
  
        }
  
      },
      // public method: sets a new element as the current. slides to that position
      setCurrent : function( idx, callback ) {
  
        this.current = idx;
  
        this._slideTo();
  
        if ( callback ) {
  
          callback.call();
  
        }
  
      },
      // public method: slides to the next set of items
      next : function() {
  
        this._slide( 'next' );
  
      },
      // public method: slides to the previous set of items
      previous : function() {
  
        this._slide( 'prev' );
  
      },
      // public method: slides to the first item
      slideStart : function() {
  
        this._slideTo( 0 );
  
      },
      // public method: slides to the last item
      slideEnd : function() {
  
        this._slideTo( this.itemsCount - 1 );
  
      },
      // public method: destroys the elastislide instance
      destroy : function( callback ) {
  
        this._destroy( callback );
  
      }
  
    };
  
    var logError = function( message ) {
  
      if ( window.console ) {
  
        window.console.error( message );
  
      }
  
    };
  
    $.fn.elastislide = function( options ) {
  
      if ( typeof options === 'string' ) {
  
        var args = Array.prototype.slice.call( arguments, 1 );
  
        this.each(function() {
  
          var self = $.data( this, 'elastislide' );
  
          if ( !self ) {
  
            logError( "cannot call methods on elastislide prior to initialization; " +
              "attempted to call method '" + options + "'" );
            return;
  
          }
  
          if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) {
  
            logError( "no such method '" + options + "' for elastislide self" );
            return;
  
          }
  
          self[ options ].apply( self, args );
  
        });
  
      }
      else {
  
        this.each(function() {
  
          var self = $.data( this, 'elastislide' );
  
          if ( self ) {
  
            self._init();
  
          }
          else {
  
            self = $.data( this, 'elastislide', new $.Elastislide( options, this ) );
  
          }
  
        });
  
      }
  
      return self;
  
    };
  
  } )( jQuery, window );