text: /**
   * animOnScroll.js v1.0.0
   * http://www.codrops.com
   *
   * Licensed under the MIT license.
   * http://www.opensource.org/licenses/mit-license.php
   * 
   * Copyright 2013, Codrops
   * http://www.codrops.com
   */
  ;( function( window ) {
  	
  	'use strict';
  	
  	var docElem = window.document.documentElement;
  
  	function getViewportH() {
  		var client = docElem['clientHeight'],
  			inner = window['innerHeight'];
  		
  		if( client < inner )
  			return inner;
  		else
  			return client;
  	}
  
  	function scrollY() {
  		return window.pageYOffset || docElem.scrollTop;
  	}
  
  	// http://stackoverflow.com/a/5598797/989439
  	function getOffset( el ) {
  		var offsetTop = 0, offsetLeft = 0;
  		do {
  			if ( !isNaN( el.offsetTop ) ) {
  				offsetTop += el.offsetTop;
  			}
  			if ( !isNaN( el.offsetLeft ) ) {
  				offsetLeft += el.offsetLeft;
  			}
  		} while( el = el.offsetParent )
  
  		return {
  			top : offsetTop,
  			left : offsetLeft
  		}
  	}
  
  	function inViewport( el, h ) {
  		var elH = el.offsetHeight,
  			scrolled = scrollY(),
  			viewed = scrolled + getViewportH(),
  			elTop = getOffset(el).top,
  			elBottom = elTop + elH,
  			// if 0, the element is considered in the viewport as soon as it enters.
  			// if 1, the element is considered in the viewport only when it's fully inside
  			// value in percentage (1 >= h >= 0)
  			h = h || 0;
  
  		return (elTop + elH * h) <= viewed && (elBottom - elH * h) >= scrolled;
  	}
  
  	function extend( a, b ) {
  		for( var key in b ) { 
  			if( b.hasOwnProperty( key ) ) {
  				a[key] = b[key];
  			}
  		}
  		return a;
  	}
  
  	function AnimOnScroll( el, options ) {	
  		this.el = el;
  		this.options = extend( this.defaults, options );
  		this._init();
  	}
  
  	AnimOnScroll.prototype = {
  		defaults : {
  			// Minimum and a maximum duration of the animation (random value is chosen)
  			minDuration : 0,
  			maxDuration : 0,
  			// The viewportFactor defines how much of the appearing item has to be visible in order to trigger the animation
  			// if we'd use a value of 0, this would mean that it would add the animation class as soon as the item is in the viewport. 
  			// If we were to use the value of 1, the animation would only be triggered when we see all of the item in the viewport (100% of it)
  			viewportFactor : 0
  		},
  		_init : function() {
  			this.items = Array.prototype.slice.call( document.querySelectorAll( '#' + this.el.id + ' > li' ) );
  			this.itemsCount = this.items.length;
  			this.itemsRenderedCount = 0;
  			this.didScroll = false;
  
  			var self = this;
  
  			imagesLoaded( this.el, function() {
  				
  				// initialize masonry
  				new Masonry( self.el, {
  					itemSelector: 'li',
  					transitionDuration : 0
  				} );
  				
  				if( Modernizr.cssanimations ) {
  					// the items already shown...
  					self.items.forEach( function( el, i ) {
  						if( inViewport( el ) ) {
  							self._checkTotalRendered();
  							classie.add( el, 'shown' );
  						}
  					} );
  
  					// animate on scroll the items inside the viewport
  					window.addEventListener( 'scroll', function() {
  						self._onScrollFn();
  					}, false );
  					window.addEventListener( 'resize', function() {
  						self._resizeHandler();
  					}, false );
  				}
  
  			});
  		},
  		_onScrollFn : function() {
  			var self = this;
  			if( !this.didScroll ) {
  				this.didScroll = true;
  				setTimeout( function() { self._scrollPage(); }, 60 );
  			}
  		},
  		_scrollPage : function() {
  			var self = this;
  			this.items.forEach( function( el, i ) {
  				if( !classie.has( el, 'shown' ) && !classie.has( el, 'animate' ) && inViewport( el, self.options.viewportFactor ) ) {
  					setTimeout( function() {
  						var perspY = scrollY() + getViewportH() / 2;
  						self.el.style.WebkitPerspectiveOrigin = '50% ' + perspY + 'px';
  						self.el.style.MozPerspectiveOrigin = '50% ' + perspY + 'px';
  						self.el.style.perspectiveOrigin = '50% ' + perspY + 'px';
  
  						self._checkTotalRendered();
  
  						if( self.options.minDuration && self.options.maxDuration ) {
  							var randDuration = ( Math.random() * ( self.options.maxDuration - self.options.minDuration ) + self.options.minDuration ) + 's';
  							el.style.WebkitAnimationDuration = randDuration;
  							el.style.MozAnimationDuration = randDuration;
  							el.style.animationDuration = randDuration;
  						}
  						
  						classie.add( el, 'animate' );
  					}, 25 );
  				}
  			});
  			this.didScroll = false;
  		},
  		_resizeHandler : function() {
  			var self = this;
  			function delayed() {
  				self._scrollPage();
  				self.resizeTimeout = null;
  			}
  			if ( this.resizeTimeout ) {
  				clearTimeout( this.resizeTimeout );
  			}
  			this.resizeTimeout = setTimeout( delayed, 1000 );
  		},
  		_checkTotalRendered : function() {
  			++this.itemsRenderedCount;
  			if( this.itemsRenderedCount === this.itemsCount ) {
  				window.removeEventListener( 'scroll', this._onScrollFn );
  			}
  		}
  	}
  
  	// add to global namespace
  	window.AnimOnScroll = AnimOnScroll;
  
  } )( window );