/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document);
/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs  */
(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this);
/*!
 * skrollr core
 *
 * Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr
 *
 * Free to use under terms of MIT license
 */
(function(window, document, undefined) {
	'use strict';
	/*
	 * Global api.
	 */
	var skrollr = window.skrollr = {
		get: function() {
			return _instance;
		},
		//Main entry point.
		init: function(options) {
			return _instance || new Skrollr(options);
		},
		VERSION: '0.6.12'
	};
	//Minify optimization.
	var hasProp = Object.prototype.hasOwnProperty;
	var Math = window.Math;
	var getStyle = window.getComputedStyle;
	//They will be filled when skrollr gets initialized.
	var documentElement;
	var body;
	var EVENT_TOUCHSTART = 'touchstart';
	var EVENT_TOUCHMOVE = 'touchmove';
	var EVENT_TOUCHCANCEL = 'touchcancel';
	var EVENT_TOUCHEND = 'touchend';
	var SKROLLABLE_CLASS = 'skrollable';
	var SKROLLABLE_BEFORE_CLASS = SKROLLABLE_CLASS + '-before';
	var SKROLLABLE_BETWEEN_CLASS = SKROLLABLE_CLASS + '-between';
	var SKROLLABLE_AFTER_CLASS = SKROLLABLE_CLASS + '-after';
	var SKROLLR_CLASS = 'skrollr';
	var NO_SKROLLR_CLASS = 'no-' + SKROLLR_CLASS;
	var SKROLLR_DESKTOP_CLASS = SKROLLR_CLASS + '-desktop';
	var SKROLLR_MOBILE_CLASS = SKROLLR_CLASS + '-mobile';
	var DEFAULT_EASING = 'linear';
	var DEFAULT_DURATION = 1000;//ms
	var DEFAULT_MOBILE_DECELERATION = 0.004;//pixel/ms²
	var DEFAULT_SMOOTH_SCROLLING_DURATION = 200;//ms
	var ANCHOR_START = 'start';
	var ANCHOR_END = 'end';
	var ANCHOR_CENTER = 'center';
	var ANCHOR_BOTTOM = 'bottom';
	//The property which will be added to the DOM element to hold the ID of the skrollable.
	var SKROLLABLE_ID_DOM_PROPERTY = '___skrollable_id';
	var rxTrim = /^\s+|\s+$/g;
	//Find all data-attributes. data-[_constant]-[offset]-[anchor]-[anchor].
	var rxKeyframeAttribute = /^data(?:-(_\w+))?(?:-?(-?\d+))?(?:-?(start|end|top|center|bottom))?(?:-?(top|center|bottom))?$/;
	var rxPropValue = /\s*([\w\-\[\]]+)\s*:\s*(.+?)\s*(?:;|$)/gi;
	//Easing function names follow the property in square brackets.
	var rxPropEasing = /^([a-z\-]+)\[(\w+)\]$/;
	var rxCamelCase = /-([a-z])/g;
	var rxCamelCaseFn = function(str, letter) {
		return letter.toUpperCase();
	};
	//Numeric values with optional sign.
	var rxNumericValue = /[\-+]?[\d]*\.?[\d]+/g;
	//Used to replace occurences of {?} with a number.
	var rxInterpolateString = /\{\?\}/g;
	//Finds rgb(a) colors, which don't use the percentage notation.
	var rxRGBAIntegerColor = /rgba?\(\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+/g;
	//Finds all gradients.
	var rxGradient = /[a-z\-]+-gradient/g;
	//Vendor prefix. Will be set once skrollr gets initialized.
	var theCSSPrefix = '';
	var theDashedCSSPrefix = '';
	//Will be called once (when skrollr gets initialized).
	var detectCSSPrefix = function() {
		//Only relevant prefixes. May be extended.
		//Could be dangerous if there will ever be a CSS property which actually starts with "ms". Don't hope so.
		var rxPrefixes = /^(?:O|Moz|webkit|ms)|(?:-(?:o|moz|webkit|ms)-)/;
		//Detect prefix for current browser by finding the first property using a prefix.
		if(!getStyle) {
			return;
		}
		var style = getStyle(body, null);
		for(var k in style) {
			//We check the key and if the key is a number, we check the value as well, because safari's getComputedStyle returns some weird array-like thingy.
			theCSSPrefix = (k.match(rxPrefixes) || (+k == k && style[k].match(rxPrefixes)));
			if(theCSSPrefix) {
				break;
			}
		}
		//Did we even detect a prefix?
		if(!theCSSPrefix) {
			theCSSPrefix = theDashedCSSPrefix = '';
			return;
		}
		theCSSPrefix = theCSSPrefix[0];
		//We could have detected either a dashed prefix or this camelCaseish-inconsistent stuff.
		if(theCSSPrefix.slice(0,1) === '-') {
			theDashedCSSPrefix = theCSSPrefix;
			//There's no logic behind these. Need a look up.
			theCSSPrefix = ({
				'-webkit-': 'webkit',
				'-moz-': 'Moz',
				'-ms-': 'ms',
				'-o-': 'O'
			})[theCSSPrefix];
		} else {
			theDashedCSSPrefix = '-' + theCSSPrefix.toLowerCase() + '-';
		}
	};
	var polyfillRAF = function() {
		var requestAnimFrame = window.requestAnimationFrame || window[theCSSPrefix.toLowerCase() + 'RequestAnimationFrame'];
		var lastTime = _now();
		if(_isMobile || !requestAnimFrame) {
			requestAnimFrame = function(callback) {
				//How long did it take to render?
				var deltaTime = _now() - lastTime;
				var delay = Math.max(0, 1000 / 60 - deltaTime);
				return window.setTimeout(function() {
					lastTime = _now();
					callback();
				}, delay);
			};
		}
		return requestAnimFrame;
	};
	var polyfillCAF = function() {
		var cancelAnimFrame = window.cancelAnimationFrame || window[theCSSPrefix.toLowerCase() + 'CancelAnimationFrame'];
		if(_isMobile || !cancelAnimFrame) {
			cancelAnimFrame = function(timeout) {
				return window.clearTimeout(timeout);
			};
		}
		return cancelAnimFrame;
	};
	//Built-in easing functions.
	var easings = {
		begin: function() {
			return 0;
		},
		end: function() {
			return 1;
		},
		linear: function(p) {
			return p;
		},
		quadratic: function(p) {
			return p * p;
		},
		cubic: function(p) {
			return p * p * p;
		},
		swing: function(p) {
			return (-Math.cos(p * Math.PI) / 2) + 0.5;
		},
		sqrt: function(p) {
			return Math.sqrt(p);
		},
		outCubic: function(p) {
			return (Math.pow((p - 1), 3) + 1);
		},
		//see https://www.desmos.com/calculator/tbr20s8vd2 for how I did this
		bounce: function(p) {
			var a;
			if(p <= 0.5083) {
				a = 3;
			} else if(p <= 0.8489) {
				a = 9;
			} else if(p <= 0.96208) {
				a = 27;
			} else if(p <= 0.99981) {
				a = 91;
			} else {
				return 1;
			}
			return 1 - Math.abs(3 * Math.cos(p * a * 1.028) / a);
		}
	};
	/**
	 * Constructor.
	 */
	function Skrollr(options) {
		documentElement = document.documentElement;
		body = document.body;
		detectCSSPrefix();
		_instance = this;
		options = options || {};
		_constants = options.constants || {};
		//We allow defining custom easings or overwrite existing.
		if(options.easing) {
			for(var e in options.easing) {
				easings[e] = options.easing[e];
			}
		}
		_edgeStrategy = options.edgeStrategy || 'set';
		_listeners = {
			//Function to be called right before rendering.
			beforerender: options.beforerender,
			//Function to be called right after finishing rendering.
			render: options.render
		};
		//forceHeight is true by default
		_forceHeight = options.forceHeight !== false;
		if(_forceHeight) {
			_scale = options.scale || 1;
		}
		_mobileDeceleration = options.mobileDeceleration || DEFAULT_MOBILE_DECELERATION;
		_smoothScrollingEnabled = options.smoothScrolling !== false;
		_smoothScrollingDuration = options.smoothScrollingDuration || DEFAULT_SMOOTH_SCROLLING_DURATION;
		//Dummy object. Will be overwritten in the _render method when smooth scrolling is calculated.
		_smoothScrolling = {
			targetTop: _instance.getScrollTop()
		};
		//A custom check function may be passed.
		_isMobile = ((options.mobileCheck || function() {
			return (/Android|iPhone|iPad|iPod|BlackBerry|Windows Phone/i).test(navigator.userAgent || navigator.vendor || window.opera);
		})());
		if(_isMobile) {
			_skrollrBody = document.getElementById('skrollr-body');
			//Detect 3d transform if there's a skrollr-body (only needed for #skrollr-body).
			if(_skrollrBody) {
				_detect3DTransforms();
			}
			//_initMobile();
			_updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_MOBILE_CLASS], [NO_SKROLLR_CLASS]);
		} else {
			_updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS], [NO_SKROLLR_CLASS]);
		}
		//Triggers parsing of elements and a first reflow.
		_instance.refresh();
		_addEvent(window, 'resize orientationchange', function() {
			var width = documentElement.clientWidth;
			var height = documentElement.clientHeight;
			//Only reflow if the size actually changed (#271).
			if(height !== _lastViewportHeight || width !== _lastViewportWidth) {
				_lastViewportHeight = height;
				_lastViewportWidth = width;
				_requestReflow = true;
			}
		});
		var requestAnimFrame = polyfillRAF();
		//Let's go.
		(function animloop(){
			_render();
			_animFrame = requestAnimFrame(animloop);
		}());
		return _instance;
	}
	/**
	 * (Re)parses some or all elements.
	 */
	Skrollr.prototype.refresh = function(elements) {
		var elementIndex;
		var elementsLength;
		var ignoreID = false;
		//Completely reparse anything without argument.
		if(elements === undefined) {
			//Ignore that some elements may already have a skrollable ID.
			ignoreID = true;
			_skrollables = [];
			_skrollableIdCounter = 0;
			elements = document.getElementsByTagName('*');
		} else {
			//We accept a single element or an array of elements.
			elements = [].concat(elements);
		}
		elementIndex = 0;
		elementsLength = elements.length;
		for(; elementIndex < elementsLength; elementIndex++) {
			var el = elements[elementIndex];
			var anchorTarget = el;
			var keyFrames = [];
			//If this particular element should be smooth scrolled.
			var smoothScrollThis = _smoothScrollingEnabled;
			//The edge strategy for this particular element.
			var edgeStrategy = _edgeStrategy;
			if(!el.attributes) {
				continue;
			}
			//Iterate over all attributes and search for key frame attributes.
			var attributeIndex = 0;
			var attributesLength = el.attributes.length;
			for (; attributeIndex < attributesLength; attributeIndex++) {
				var attr = el.attributes[attributeIndex];
				if(attr.name === 'data-anchor-target') {
					anchorTarget = document.querySelector(attr.value);
					if(anchorTarget === null) {
						throw 'Unable to find anchor target "' + attr.value + '"';
					}
					continue;
				}
				//Global smooth scrolling can be overridden by the element attribute.
				if(attr.name === 'data-smooth-scrolling') {
					smoothScrollThis = attr.value !== 'off';
					continue;
				}
				//Global edge strategy can be overridden by the element attribute.
				if(attr.name === 'data-edge-strategy') {
					edgeStrategy = attr.value;
					continue;
				}
				var match = attr.name.match(rxKeyframeAttribute);
				if(match === null) {
					continue;
				}
				var constant = match[1];
				//If there is a constant, get it's value or fall back to 0.
				constant = constant && _constants[constant.substr(1)] || 0;
				//Parse key frame offset. If undefined will be casted to 0.
				var offset = (match[2] | 0) + constant;
				var anchor1 = match[3];
				//If second anchor is not set, the first will be taken for both.
				var anchor2 = match[4] || anchor1;
				var kf = {
					offset: offset,
					props: attr.value,
					//Point back to the element as well.
					element: el
				};
				keyFrames.push(kf);
				//"absolute" (or "classic") mode, where numbers mean absolute scroll offset.
				if(!anchor1 || anchor1 === ANCHOR_START || anchor1 === ANCHOR_END) {
					kf.mode = 'absolute';
					//data-end needs to be calculated after all key frames are know.
					if(anchor1 === ANCHOR_END) {
						kf.isEnd = true;
					} else {
						//For data-start we can already set the key frame w/o calculations.
						//#59: "scale" options should only affect absolute mode.
						kf.frame = offset * _scale;
						delete kf.offset;
					}
				}
				//"relative" mode, where numbers are relative to anchors.
				else {
					kf.mode = 'relative';
					kf.anchors = [anchor1, anchor2];
				}
			}
			//Does this element have key frames?
			if(!keyFrames.length) {
				continue;
			}
			//Will hold the original style and class attributes before we controlled the element (see #80).
			var styleAttr, classAttr;
			var id;
			if(!ignoreID && SKROLLABLE_ID_DOM_PROPERTY in el) {
				//We already have this element under control. Grab the corresponding skrollable id.
				id = el[SKROLLABLE_ID_DOM_PROPERTY];
				styleAttr = _skrollables[id].styleAttr;
				classAttr = _skrollables[id].classAttr;
			} else {
				//It's an unknown element. Asign it a new skrollable id.
				id = (el[SKROLLABLE_ID_DOM_PROPERTY] = _skrollableIdCounter++);
				styleAttr = el.style.cssText;
				classAttr = _getClass(el);
			}
			_skrollables[id] = {
				element: el,
				styleAttr: styleAttr,
				classAttr: classAttr,
				anchorTarget: anchorTarget,
				keyFrames: keyFrames,
				smoothScrolling: smoothScrollThis,
				edgeStrategy: edgeStrategy
			};
			_updateClass(el, [SKROLLABLE_CLASS], []);
		}
		//Reflow for the first time.
		_reflow();
		//Now that we got all key frame numbers right, actually parse the properties.
		elementIndex = 0;
		elementsLength = elements.length;
		for(; elementIndex < elementsLength; elementIndex++) {
			var sk = _skrollables[elements[elementIndex][SKROLLABLE_ID_DOM_PROPERTY]];
			if(sk === undefined) {
				continue;
			}
			//Parse the property string to objects
			_parseProps(sk);
			//Fill key frames with missing properties from left and right
			_fillProps(sk);
		}
		return _instance;
	};
	/**
	 * Transform "relative" mode to "absolute" mode.
	 * That is, calculate anchor position and offset of element.
	 */
	Skrollr.prototype.relativeToAbsolute = function(element, viewportAnchor, elementAnchor) {
		var viewportHeight = documentElement.clientHeight;
		var box = element.getBoundingClientRect();
		var absolute = box.top;
		//#100: IE doesn't supply "height" with getBoundingClientRect.
		var boxHeight = box.bottom - box.top;
		if(viewportAnchor === ANCHOR_BOTTOM) {
			absolute -= viewportHeight;
		} else if(viewportAnchor === ANCHOR_CENTER) {
			absolute -= viewportHeight / 2;
		}
		if(elementAnchor === ANCHOR_BOTTOM) {
			absolute += boxHeight;
		} else if(elementAnchor === ANCHOR_CENTER) {
			absolute += boxHeight / 2;
		}
		//Compensate scrolling since getBoundingClientRect is relative to viewport.
		absolute += _instance.getScrollTop();
		return (absolute + 0.5) | 0;
	};
	/**
	 * Animates scroll top to new position.
	 */
	Skrollr.prototype.animateTo = function(top, options) {
		options = options || {};
		var now = _now();
		var scrollTop = _instance.getScrollTop();
		//Setting this to a new value will automatically cause the current animation to stop, if any.
		_scrollAnimation = {
			startTop: scrollTop,
			topDiff: top - scrollTop,
			targetTop: top,
			duration: options.duration || DEFAULT_DURATION,
			startTime: now,
			endTime: now + (options.duration || DEFAULT_DURATION),
			easing: easings[options.easing || DEFAULT_EASING],
			done: options.done
		};
		//Don't queue the animation if there's nothing to animate.
		if(!_scrollAnimation.topDiff) {
			if(_scrollAnimation.done) {
				_scrollAnimation.done.call(_instance, false);
			}
			_scrollAnimation = undefined;
		}
		return _instance;
	};
	/**
	 * Stops animateTo animation.
	 */
	Skrollr.prototype.stopAnimateTo = function() {
		if(_scrollAnimation && _scrollAnimation.done) {
			_scrollAnimation.done.call(_instance, true);
		}
		_scrollAnimation = undefined;
	};
	/**
	 * Returns if an animation caused by animateTo is currently running.
	 */
	Skrollr.prototype.isAnimatingTo = function() {
		return !!_scrollAnimation;
	};
	Skrollr.prototype.setScrollTop = function(top, force) {
		//Don't do smooth scrolling (last top === new top).
		if(force === true) {
			_lastTop = top;
			_forceRender = true;
		}
		if(_isMobile) {
			_mobileOffset = Math.min(Math.max(top, 0), _maxKeyFrame);
		} else {
			window.scrollTo(0, top);
		}
		return _instance;
	};
	Skrollr.prototype.getScrollTop = function() {
		if(_isMobile) {
			return _mobileOffset;
		} else {
			return window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0;
		}
	};
	Skrollr.prototype.on = function(name, fn) {
		_listeners[name] = fn;
		return _instance;
	};
	Skrollr.prototype.off = function(name) {
		delete _listeners[name];
		return _instance;
	};
	Skrollr.prototype.destroy = function() {
		var cancelAnimFrame = polyfillCAF();
		cancelAnimFrame(_animFrame);
		_removeAllEvents();
		_updateClass(documentElement, [NO_SKROLLR_CLASS], [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS, SKROLLR_MOBILE_CLASS]);
		var skrollableIndex = 0;
		var skrollablesLength = _skrollables.length;
		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			_reset(_skrollables[skrollableIndex].element);
		}
		documentElement.style.overflow = body.style.overflow = 'auto';
		documentElement.style.height = body.style.height = 'auto';
		if(_skrollrBody) {
			skrollr.setStyle(_skrollrBody, 'transform', 'none');
		}
		_instance = undefined;
		_skrollrBody = undefined;
		_listeners = undefined;
		_forceHeight = undefined;
		_maxKeyFrame = 0;
		_scale = 1;
		_constants = undefined;
		_mobileDeceleration = undefined;
		_direction = 'down';
		_lastTop = -1;
		_lastViewportWidth = 0;
		_lastViewportHeight = 0;
		_requestReflow = false;
		_scrollAnimation = undefined;
		_smoothScrollingEnabled = undefined;
		_smoothScrollingDuration = undefined;
		_smoothScrolling = undefined;
		_forceRender = undefined;
		_skrollableIdCounter = 0;
		_edgeStrategy = undefined;
		_isMobile = false;
		_mobileOffset = 0;
		_translateZ = undefined;
	};
	/*
		Private methods.
	*/
	var _initMobile = function() {
		var initialElement;
		var initialTouchY;
		var initialTouchX;
		var currentTouchY;
		var currentTouchX;
		var lastTouchY;
		var deltaY;
		var initialTouchTime;
		var currentTouchTime;
		var lastTouchTime;
		var deltaTime;
		_addEvent(documentElement, [EVENT_TOUCHSTART, EVENT_TOUCHMOVE, EVENT_TOUCHCANCEL, EVENT_TOUCHEND].join(' '), function(e) {
			e.preventDefault();
			var touch = e.changedTouches[0];
			currentTouchY = touch.clientY;
			currentTouchX = touch.clientX;
			currentTouchTime = e.timeStamp;
			switch(e.type) {
				case EVENT_TOUCHSTART:
					//The last element we tapped on.
					if(initialElement) {
						initialElement.blur();
					}
					_instance.stopAnimateTo();
					initialElement = e.target;
					initialTouchY = lastTouchY = currentTouchY;
					initialTouchX = currentTouchX;
					initialTouchTime = currentTouchTime;
					break;
				case EVENT_TOUCHMOVE:
					deltaY = currentTouchY - lastTouchY;
					deltaTime = currentTouchTime - lastTouchTime;
					_instance.setScrollTop(_mobileOffset - deltaY, true);
					lastTouchY = currentTouchY;
					lastTouchTime = currentTouchTime;
					break;
				default:
				case EVENT_TOUCHCANCEL:
				case EVENT_TOUCHEND:
					var distanceY = initialTouchY - currentTouchY;
					var distanceX = initialTouchX - currentTouchX;
					var distance2 = distanceX * distanceX + distanceY * distanceY;
					//Check if it was more like a tap (moved less than 7px).
					if(distance2 < 49) {
						//It was a tap, click the element.
						initialElement.focus();
						initialElement.click();
						return;
					}
					initialElement = undefined;
					var speed = deltaY / deltaTime;
					//Cap speed at 3 pixel/ms.
					speed = Math.max(Math.min(speed, 3), -3);
					var duration = Math.abs(speed / _mobileDeceleration);
					var targetOffset = speed * duration + 0.5 * _mobileDeceleration * duration * duration;
					var targetTop = _instance.getScrollTop() - targetOffset;
					//Relative duration change for when scrolling above bounds.
					var targetRatio = 0;
					//Change duration proportionally when scrolling would leave bounds.
					if(targetTop > _maxKeyFrame) {
						targetRatio = (_maxKeyFrame - targetTop) / targetOffset;
						targetTop = _maxKeyFrame;
					} else if(targetTop < 0) {
						targetRatio = -targetTop / targetOffset;
						targetTop = 0;
					}
					duration = duration * (1 - targetRatio);
					_instance.animateTo(targetTop, {easing: 'outCubic', duration: duration});
					break;
			}
		});
		//Just in case there has already been some native scrolling, reset it.
		window.scrollTo(0, 0);
		documentElement.style.overflow = body.style.overflow = 'hidden';
	};
	/**
	 * Updates key frames which depend on others.
	 * That is "end" in "absolute" mode and all key frames in "relative" mode.
	 */
	var _updateDependentKeyFrames = function() {
		var skrollable;
		var element;
		var anchorTarget;
		var keyFrames;
		var keyFrameIndex;
		var keyFramesLength;
		var kf;
		var skrollableIndex;
		var skrollablesLength;
		//First process all relative-mode elements and find the max key frame.
		skrollableIndex = 0;
		skrollablesLength = _skrollables.length;
		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			skrollable = _skrollables[skrollableIndex];
			element = skrollable.element;
			anchorTarget = skrollable.anchorTarget;
			keyFrames = skrollable.keyFrames;
			keyFrameIndex = 0;
			keyFramesLength = keyFrames.length;
			for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
				kf = keyFrames[keyFrameIndex];
				if(kf.mode === 'relative') {
					_reset(element);
					kf.frame = _instance.relativeToAbsolute(anchorTarget, kf.anchors[0], kf.anchors[1]) - kf.offset;
					_reset(element, true);
				}
				//Only search for max key frame when forceHeight is enabled.
				if(_forceHeight) {
					//Find the max key frame, but don't use one of the data-end ones for comparison.
					if(!kf.isEnd && kf.frame > _maxKeyFrame) {
						_maxKeyFrame = kf.frame;
					}
				}
			}
		}
		//#133: The document can be larger than the maxKeyFrame we found.
		_maxKeyFrame = Math.max(_maxKeyFrame, _getDocumentHeight());
		//Now process all data-end keyframes.
		skrollableIndex = 0;
		skrollablesLength = _skrollables.length;
		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			skrollable = _skrollables[skrollableIndex];
			keyFrames = skrollable.keyFrames;
			keyFrameIndex = 0;
			keyFramesLength = keyFrames.length;
			for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
				kf = keyFrames[keyFrameIndex];
				if(kf.isEnd) {
					kf.frame = _maxKeyFrame - kf.offset;
				}
			}
			skrollable.keyFrames.sort(_keyFrameComparator);
		}
	};
	/**
	 * Calculates and sets the style properties for the element at the given frame.
	 * @param fakeFrame The frame to render at when smooth scrolling is enabled.
	 * @param actualFrame The actual frame we are at.
	 */
	var _calcSteps = function(fakeFrame, actualFrame) {
		//Iterate over all skrollables.
		var skrollableIndex = 0;
		var skrollablesLength = _skrollables.length;
		for(; skrollableIndex < skrollablesLength; skrollableIndex++) {
			var skrollable = _skrollables[skrollableIndex];
			var element = skrollable.element;
			var frame = skrollable.smoothScrolling ? fakeFrame : actualFrame;
			var frames = skrollable.keyFrames;
			var firstFrame = frames[0].frame;
			var lastFrame = frames[frames.length - 1].frame;
			var beforeFirst = frame < firstFrame;
			var afterLast = frame > lastFrame;
			var firstOrLastFrame = frames[beforeFirst ? 0 : frames.length - 1];
			var key;
			var value;
			//If we are before/after the first/last frame, set the styles according to the given edge strategy.
			if(beforeFirst || afterLast) {
				//Check if we already handled this edge case last time.
				//Note: using setScrollTop it's possible that we jumped from one edge to the other.
				if(beforeFirst && skrollable.edge === -1 || afterLast && skrollable.edge === 1) {
					continue;
				}
				//Add the skrollr-before or -after class.
				_updateClass(element, [beforeFirst ? SKROLLABLE_BEFORE_CLASS : SKROLLABLE_AFTER_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_BETWEEN_CLASS, SKROLLABLE_AFTER_CLASS]);
				//Remember that we handled the edge case (before/after the first/last keyframe).
				skrollable.edge = beforeFirst ? -1 : 1;
				switch(skrollable.edgeStrategy) {
					case 'reset':
						_reset(element);
						continue;
					case 'ease':
						//Handle this case like it would be exactly at first/last keyframe and just pass it on.
						frame = firstOrLastFrame.frame;
						break;
					default:
					case 'set':
						var props = firstOrLastFrame.props;
						for(key in props) {
							if(hasProp.call(props, key)) {
								value = _interpolateString(props[key].value);
								skrollr.setStyle(element, key, value);
							}
						}
						continue;
				}
			} else {
				//Did we handle an edge last time?
				if(skrollable.edge !== 0) {
					_updateClass(element, [SKROLLABLE_CLASS, SKROLLABLE_BETWEEN_CLASS], [SKROLLABLE_BEFORE_CLASS, SKROLLABLE_AFTER_CLASS]);
					skrollable.edge = 0;
				}
			}
			//Find out between which two key frames we are right now.
			var keyFrameIndex = 0;
			var framesLength = frames.length - 1;
			for(; keyFrameIndex < framesLength; keyFrameIndex++) {
				if(frame >= frames[keyFrameIndex].frame && frame <= frames[keyFrameIndex + 1].frame) {
					var left = frames[keyFrameIndex];
					var right = frames[keyFrameIndex + 1];
					for(key in left.props) {
						if(hasProp.call(left.props, key)) {
							var progress = (frame - left.frame) / (right.frame - left.frame);
							//Transform the current progress using the given easing function.
							progress = left.props[key].easing(progress);
							//Interpolate between the two values
							value = _calcInterpolation(left.props[key].value, right.props[key].value, progress);
							value = _interpolateString(value);
							skrollr.setStyle(element, key, value);
						}
					}
					break;
				}
			}
		}
	};
	/**
	 * Renders all elements.
	 */
	var _render = function() {
		if(_requestReflow) {
			_requestReflow = false;
			_reflow();
		}
		//We may render something else than the actual scrollbar position.
		var renderTop = _instance.getScrollTop();
		//If there's an animation, which ends in current render call, call the callback after rendering.
		var afterAnimationCallback;
		var now = _now();
		var progress;
		//Before actually rendering handle the scroll animation, if any.
		if(_scrollAnimation) {
			//It's over
			if(now >= _scrollAnimation.endTime) {
				renderTop = _scrollAnimation.targetTop;
				afterAnimationCallback = _scrollAnimation.done;
				_scrollAnimation = undefined;
			} else {
				//Map the current progress to the new progress using given easing function.
				progress = _scrollAnimation.easing((now - _scrollAnimation.startTime) / _scrollAnimation.duration);
				renderTop = (_scrollAnimation.startTop + progress * _scrollAnimation.topDiff) | 0;
			}
			_instance.setScrollTop(renderTop, true);
		}
		//Smooth scrolling only if there's no animation running and if we're not on mobile.
		else if(!_isMobile) {
			var smoothScrollingDiff = _smoothScrolling.targetTop - renderTop;
			//The user scrolled, start new smooth scrolling.
			if(smoothScrollingDiff) {
				_smoothScrolling = {
					startTop: _lastTop,
					topDiff: renderTop - _lastTop,
					targetTop: renderTop,
					startTime: _lastRenderCall,
					endTime: _lastRenderCall + _smoothScrollingDuration
				};
			}
			//Interpolate the internal scroll position (not the actual scrollbar).
			if(now <= _smoothScrolling.endTime) {
				//Map the current progress to the new progress using easing function.
				progress = easings.sqrt((now - _smoothScrolling.startTime) / _smoothScrollingDuration);
				renderTop = (_smoothScrolling.startTop + progress * _smoothScrolling.topDiff) | 0;
			}
		}
		//That's were we actually "scroll" on mobile.
		if(_isMobile && _skrollrBody) {
			//Set the transform ("scroll it").
			skrollr.setStyle(_skrollrBody, 'transform', 'translate(0, ' + -(_mobileOffset) + 'px) ' + _translateZ);
		}
		//Did the scroll position even change?
		if(_forceRender || _lastTop !== renderTop) {
			//Remember in which direction are we scrolling?
			_direction = (renderTop >= _lastTop) ? 'down' : 'up';
			_forceRender = false;
			var listenerParams = {
				curTop: renderTop,
				lastTop: _lastTop,
				maxTop: _maxKeyFrame,
				direction: _direction
			};
			//Tell the listener we are about to render.
			var continueRendering = _listeners.beforerender && _listeners.beforerender.call(_instance, listenerParams);
			//The beforerender listener function is able the cancel rendering.
			if(continueRendering !== false) {
				//Now actually interpolate all the styles.
				_calcSteps(renderTop, _instance.getScrollTop());
				//Remember when we last rendered.
				_lastTop = renderTop;
				if(_listeners.render) {
					_listeners.render.call(_instance, listenerParams);
				}
			}
			if(afterAnimationCallback) {
				afterAnimationCallback.call(_instance, false);
			}
		}
		_lastRenderCall = now;
	};
	/**
	 * Parses the properties for each key frame of the given skrollable.
	 */
	var _parseProps = function(skrollable) {
		//Iterate over all key frames
		var keyFrameIndex = 0;
		var keyFramesLength = skrollable.keyFrames.length;
		for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
			var frame = skrollable.keyFrames[keyFrameIndex];
			var easing;
			var value;
			var prop;
			var props = {};
			var match;
			while((match = rxPropValue.exec(frame.props)) !== null) {
				prop = match[1];
				value = match[2];
				easing = prop.match(rxPropEasing);
				//Is there an easing specified for this prop?
				if(easing !== null) {
					prop = easing[1];
					easing = easing[2];
				} else {
					easing = DEFAULT_EASING;
				}
				//Exclamation point at first position forces the value to be taken literal.
				value = value.indexOf('!') ? _parseProp(value) : [value.slice(1)];
				//Save the prop for this key frame with his value and easing function
				props[prop] = {
					value: value,
					easing: easings[easing]
				};
			}
			frame.props = props;
		}
	};
	/**
	 * Parses a value extracting numeric values and generating a format string
	 * for later interpolation of the new values in old string.
	 *
	 * @param val The CSS value to be parsed.
	 * @return Something like ["rgba(?%,?%, ?%,?)", 100, 50, 0, .7]
	 * where the first element is the format string later used
	 * and all following elements are the numeric value.
	 */
	var _parseProp = function(val) {
		var numbers = [];
		//One special case, where floats don't work.
		//We replace all occurences of rgba colors
		//which don't use percentage notation with the percentage notation.
		rxRGBAIntegerColor.lastIndex = 0;
		val = val.replace(rxRGBAIntegerColor, function(rgba) {
			return rgba.replace(rxNumericValue, function(n) {
				return n / 255 * 100 + '%';
			});
		});
		//Handle prefixing of "gradient" values.
		//For now only the prefixed value will be set. Unprefixed isn't supported anyway.
		if(theDashedCSSPrefix) {
			rxGradient.lastIndex = 0;
			val = val.replace(rxGradient, function(s) {
				return theDashedCSSPrefix + s;
			});
		}
		//Now parse ANY number inside this string and create a format string.
		val = val.replace(rxNumericValue, function(n) {
			numbers.push(+n);
			return '{?}';
		});
		//Add the formatstring as first value.
		numbers.unshift(val);
		return numbers;
	};
	/**
	 * Fills the key frames with missing left and right hand properties.
	 * If key frame 1 has property X and key frame 2 is missing X,
	 * but key frame 3 has X again, then we need to assign X to key frame 2 too.
	 *
	 * @param sk A skrollable.
	 */
	var _fillProps = function(sk) {
		//Will collect the properties key frame by key frame
		var propList = {};
		var keyFrameIndex;
		var keyFramesLength;
		//Iterate over all key frames from left to right
		keyFrameIndex = 0;
		keyFramesLength = sk.keyFrames.length;
		for(; keyFrameIndex < keyFramesLength; keyFrameIndex++) {
			_fillPropForFrame(sk.keyFrames[keyFrameIndex], propList);
		}
		//Now do the same from right to fill the last gaps
		propList = {};
		//Iterate over all key frames from right to left
		keyFrameIndex = sk.keyFrames.length - 1;
		for(; keyFrameIndex >= 0; keyFrameIndex--) {
			_fillPropForFrame(sk.keyFrames[keyFrameIndex], propList);
		}
	};
	var _fillPropForFrame = function(frame, propList) {
		var key;
		//For each key frame iterate over all right hand properties and assign them,
		//but only if the current key frame doesn't have the property by itself
		for(key in propList) {
			//The current frame misses this property, so assign it.
			if(!hasProp.call(frame.props, key)) {
				frame.props[key] = propList[key];
			}
		}
		//Iterate over all props of the current frame and collect them
		for(key in frame.props) {
			propList[key] = frame.props[key];
		}
	};
	/**
	 * Calculates the new values for two given values array.
	 */
	var _calcInterpolation = function(val1, val2, progress) {
		var valueIndex;
		var val1Length = val1.length;
		//They both need to have the same length
		if(val1Length !== val2.length) {
			throw 'Can\'t interpolate between "' + val1[0] + '" and "' + val2[0] + '"';
		}
		//Add the format string as first element.
		var interpolated = [val1[0]];
		valueIndex = 1;
		for(; valueIndex < val1Length; valueIndex++) {
			//That's the line where the two numbers are actually interpolated.
			interpolated[valueIndex] = val1[valueIndex] + ((val2[valueIndex] - val1[valueIndex]) * progress);
		}
		return interpolated;
	};
	/**
	 * Interpolates the numeric values into the format string.
	 */
	var _interpolateString = function(val) {
		var valueIndex = 1;
		rxInterpolateString.lastIndex = 0;
		return val[0].replace(rxInterpolateString, function() {
			return val[valueIndex++];
		});
	};
	/**
	 * Resets the class and style attribute to what it was before skrollr manipulated the element.
	 * Also remembers the values it had before reseting, in order to undo the reset.
	 */
	var _reset = function(elements, undo) {
		//We accept a single element or an array of elements.
		elements = [].concat(elements);
		var skrollable;
		var element;
		var elementsIndex = 0;
		var elementsLength = elements.length;
		for(; elementsIndex < elementsLength; elementsIndex++) {
			element = elements[elementsIndex];
			skrollable = _skrollables[element[SKROLLABLE_ID_DOM_PROPERTY]];
			//Couldn't find the skrollable for this DOM element.
			if(!skrollable) {
				continue;
			}
			if(undo) {
				//Reset class and style to the "dirty" (set by skrollr) values.
				element.style.cssText = skrollable.dirtyStyleAttr;
				_updateClass(element, skrollable.dirtyClassAttr);
			} else {
				//Remember the "dirty" (set by skrollr) class and style.
				skrollable.dirtyStyleAttr = element.style.cssText;
				skrollable.dirtyClassAttr = _getClass(element);
				//Reset class and style to what it originally was.
				element.style.cssText = skrollable.styleAttr;
				_updateClass(element, skrollable.classAttr);
			}
		}
	};
	/**
	 * Detects support for 3d transforms by applying it to the skrollr-body.
	 */
	var _detect3DTransforms = function() {
		_translateZ = 'translateZ(0)';
		skrollr.setStyle(_skrollrBody, 'transform', _translateZ);
		var computedStyle = getStyle(_skrollrBody);
		var computedTransform = computedStyle.getPropertyValue('transform');
		var computedTransformWithPrefix = computedStyle.getPropertyValue(theDashedCSSPrefix + 'transform');
		var has3D = (computedTransform && computedTransform !== 'none') || (computedTransformWithPrefix && computedTransformWithPrefix !== 'none');
		if(!has3D) {
			_translateZ = '';
		}
	};
	/**
	 * Set the CSS property on the given element. Sets prefixed properties as well.
	 */
	skrollr.setStyle = function(el, prop, val) {
		var style = el.style;
		//Camel case.
		prop = prop.replace(rxCamelCase, rxCamelCaseFn).replace('-', '');
		//Make sure z-index gets a .
		//This is the only  case we need to handle.
		if(prop === 'zIndex') {
			//Floor
			style[prop] = '' + (val | 0);
		}
		//#64: "float" can't be set across browsers. Needs to use "cssFloat" for all except IE.
		else if(prop === 'float') {
			style.styleFloat = style.cssFloat = val;
		}
		else {
			//Need try-catch for old IE.
			try {
				//Set prefixed property if there's a prefix.
				if(theCSSPrefix) {
					style[theCSSPrefix + prop.slice(0,1).toUpperCase() + prop.slice(1)] = val;
				}
				//Set unprefixed.
				style[prop] = val;
			} catch(ignore) {}
		}
	};
	/**
	 * Cross browser event handling.
	 */
	var _addEvent = skrollr.addEvent = function(element, names, callback) {
		var intermediate = function(e) {
			//Normalize IE event stuff.
			e = e || window.event;
			if(!e.target) {
				e.target = e.srcElement;
			}
			if(!e.preventDefault) {
				e.preventDefault = function() {
					e.returnValue = false;
				};
			}
			return callback.call(this, e);
		};
		names = names.split(' ');
		var name;
		var nameCounter = 0;
		var namesLength = names.length;
		for(; nameCounter < namesLength; nameCounter++) {
			name = names[nameCounter];
			if(element.addEventListener) {
				element.addEventListener(name, callback, false);
			} else {
				element.attachEvent('on' + name, intermediate);
			}
			//Remember the events to be able to flush them later.
			_registeredEvents.push({
				element: element,
				name: name,
				listener: callback
			});
		}
	};
	var _removeEvent = skrollr.removeEvent = function(element, names, callback) {
		names = names.split(' ');
		var nameCounter = 0;
		var namesLength = names.length;
		for(; nameCounter < namesLength; nameCounter++) {
			if(element.removeEventListener) {
				element.removeEventListener(names[nameCounter], callback, false);
			} else {
				element.detachEvent('on' + names[nameCounter], callback);
			}
		}
	};
	var _removeAllEvents = function() {
		var eventData;
		var eventCounter = 0;
		var eventsLength = _registeredEvents.length;
		for(; eventCounter < eventsLength; eventCounter++) {
			eventData = _registeredEvents[eventCounter];
			_removeEvent(eventData.element, eventData.name, eventData.listener);
		}
		_registeredEvents = [];
	};
	var _reflow = function() {
		var pos = _instance.getScrollTop();
		//Will be recalculated by _updateDependentKeyFrames.
		_maxKeyFrame = 0;
		if(_forceHeight && !_isMobile) {
			//un-"force" the height to not mess with the calculations in _updateDependentKeyFrames (#216).
			body.style.height = 'auto';
		}
		_updateDependentKeyFrames();
		if(_forceHeight && !_isMobile) {
			//"force" the height.
			body.style.height = (_maxKeyFrame + documentElement.clientHeight) + 'px';
		}
		//The scroll offset may now be larger than needed (on desktop the browser/os prevents scrolling farther than the bottom).
		if(_isMobile) {
			_instance.setScrollTop(Math.min(_instance.getScrollTop(), _maxKeyFrame));
		} else {
			//Remember and reset the scroll pos (#217).
			_instance.setScrollTop(pos, true);
		}
		_forceRender = true;
	};
	/*
	 * Returns the height of the document.
	 */
	var _getDocumentHeight = function() {
		var skrollrBodyHeight = (_skrollrBody && _skrollrBody.offsetHeight || 0);
		var bodyHeight = Math.max(skrollrBodyHeight, body.scrollHeight, body.offsetHeight, documentElement.scrollHeight, documentElement.offsetHeight, documentElement.clientHeight);
		return bodyHeight - documentElement.clientHeight;
	};
	/**
	 * Returns a string of space separated classnames for the current element.
	 * Works with SVG as well.
	 */
	var _getClass = function(element) {
		var prop = 'className';
		//SVG support by using className.baseVal instead of just className.
		if(window.SVGElement && element instanceof window.SVGElement) {
			element = element[prop];
			prop = 'baseVal';
		}
		return element[prop];
	};
	/**
	 * Adds and removes a CSS classes.
	 * Works with SVG as well.
	 * add and remove are arrays of strings,
	 * or if remove is ommited add is a string and overwrites all classes.
	 */
	var _updateClass = function(element, add, remove) {
		var prop = 'className';
		//SVG support by using className.baseVal instead of just className.
		if(window.SVGElement && element instanceof window.SVGElement) {
			element = element[prop];
			prop = 'baseVal';
		}
		//When remove is ommited, we want to overwrite/set the classes.
		if(remove === undefined) {
			element[prop] = add;
			return;
		}
		//Cache current classes. We will work on a string before passing back to DOM.
		var val = element[prop];
		//All classes to be removed.
		var classRemoveIndex = 0;
		var removeLength = remove.length;
		for(; classRemoveIndex < removeLength; classRemoveIndex++) {
			val = _untrim(val).replace(_untrim(remove[classRemoveIndex]), ' ');
		}
		val = _trim(val);
		//All classes to be added.
		var classAddIndex = 0;
		var addLength = add.length;
		for(; classAddIndex < addLength; classAddIndex++) {
			//Only add if el not already has class.
			if(_untrim(val).indexOf(_untrim(add[classAddIndex])) === -1) {
				val += ' ' + add[classAddIndex];
			}
		}
		element[prop] = _trim(val);
	};
	var _trim = function(a) {
		return a.replace(rxTrim, '');
	};
	/**
	 * Adds a space before and after the string.
	 */
	var _untrim = function(a) {
		return ' ' + a + ' ';
	};
	var _now = Date.now || function() {
		return +new Date();
	};
	var _keyFrameComparator = function(a, b) {
		return a.frame - b.frame;
	};
	/*
	 * Private variables.
	 */
	//Singleton
	var _instance;
	/*
		A list of all elements which should be animated associated with their the metadata.
		Exmaple skrollable with two key frames animating from 100px width to 20px:
		skrollable = {
			element: ,
			styleAttr: ").appendTo("head"),f=b('').appendTo("html");a=f.height()===3,f.remove(),e.remove()}return a},csstransitions:function(){return!!j}},l;if(e)for(l in k)e.hasOwnProperty(l)||e.addTest(l,k[l]);else{e=a.Modernizr={_version:"1.6ish: miniModernizr for Isotope"};var m=" ",n;for(l in k)n=k[l](),e[l]=n,m+=" "+(n?"":"no-")+l;b("html").addClass(m)}if(e.csstransforms){var o=e.csstransforms3d?{translate:function(a){return"translate3d("+a[0]+"px, "+a[1]+"px, 0) "},scale:function(a){return"scale3d("+a+", "+a+", 1) "}}:{translate:function(a){return"translate("+a[0]+"px, "+a[1]+"px) "},scale:function(a){return"scale("+a+") "}},p=function(a,c,d){var e=b.data(a,"isoTransform")||{},f={},g,h={},j;f[c]=d,b.extend(e,f);for(g in e)j=e[g],h[g]=o[g](j);var k=h.translate||"",l=h.scale||"",m=k+l;b.data(a,"isoTransform",e),a.style[i]=m};b.cssNumber.scale=!0,b.cssHooks.scale={set:function(a,b){p(a,"scale",b)},get:function(a,c){var d=b.data(a,"isoTransform");return d&&d.scale?d.scale:1}},b.fx.step.scale=function(a){b.cssHooks.scale.set(a.elem,a.now+a.unit)},b.cssNumber.translate=!0,b.cssHooks.translate={set:function(a,b){p(a,"translate",b)},get:function(a,c){var d=b.data(a,"isoTransform");return d&&d.translate?d.translate:[0,0]}}}var q,r;e.csstransitions&&(q={WebkitTransitionProperty:"webkitTransitionEnd",MozTransitionProperty:"transitionend",OTransitionProperty:"oTransitionEnd otransitionend",transitionProperty:"transitionend"}[j],r=h("transitionDuration"));var s=b.event,t=b.event.handle?"handle":"dispatch",u;s.special.smartresize={setup:function(){b(this).bind("resize",s.special.smartresize.handler)},teardown:function(){b(this).unbind("resize",s.special.smartresize.handler)},handler:function(a,b){var c=this,d=arguments;a.type="smartresize",u&&clearTimeout(u),u=setTimeout(function(){s[t].apply(c,d)},b==="execAsap"?0:100)}},b.fn.smartresize=function(a){return a?this.bind("smartresize",a):this.trigger("smartresize",["execAsap"])},b.Isotope=function(a,c,d){this.element=b(c),this._create(a),this._init(d)};var v=["width","height"],w=b(a);b.Isotope.settings={resizable:!0,layoutMode:"masonry",containerClass:"isotope",itemClass:"isotope-item",hiddenClass:"isotope-hidden",hiddenStyle:{opacity:0,scale:.001},visibleStyle:{opacity:1,scale:1},containerStyle:{position:"relative",overflow:"hidden"},animationEngine:"best-available",animationOptions:{queue:!1,duration:800},sortBy:"original-order",sortAscending:!0,resizesContainer:!0,transformsEnabled:!0,itemPositionDataEnabled:!1},b.Isotope.prototype={_create:function(a){this.options=b.extend({},b.Isotope.settings,a),this.styleQueue=[],this.elemCount=0;var c=this.element[0].style;this.originalStyle={};var d=v.slice(0);for(var e in this.options.containerStyle)d.push(e);for(var f=0,g=d.length;fg?1:f0&&(i=function(a,b){b.$el[d](b.style,f).one(q,k)},j=!1)}}b.each(this.styleQueue,i),j&&k(),this.styleQueue=[]},resize:function(){this["_"+this.options.layoutMode+"ResizeChanged"]()&&this.reLayout()},reLayout:function(a){this["_"+this.options.layoutMode+"Reset"](),this.layout(this.$filteredAtoms,a)},addItems:function(a,b){var c=this._getAtoms(a);this.$allAtoms=this.$allAtoms.add(c),b&&b(c)},insert:function(a,b){this.element.append(a);var c=this;this.addItems(a,function(a){var d=c._filter(a);c._addHideAppended(d),c._sort(),c.reLayout(),c._revealAppended(d,b)})},appended:function(a,b){var c=this;this.addItems(a,function(a){c._addHideAppended(a),c.layout(a),c._revealAppended(a,b)})},_addHideAppended:function(a){this.$filteredAtoms=this.$filteredAtoms.add(a),a.addClass("no-transition"),this._isInserting=!0,this.styleQueue.push({$el:a,style:this.options.hiddenStyle})},_revealAppended:function(a,b){var c=this;setTimeout(function(){a.removeClass("no-transition"),c.styleQueue.push({$el:a,style:c.options.visibleStyle}),c._isInserting=!1,c._processStyleQueue(a,b)},10)},reloadItems:function(){this.$allAtoms=this._getAtoms(this.element.children())},remove:function(a,b){this.$allAtoms=this.$allAtoms.not(a),this.$filteredAtoms=this.$filteredAtoms.not(a);var c=this,d=function(){a.remove(),b&&b.call(c.element)};a.filter(":not(."+this.options.hiddenClass+")").length?(this.styleQueue.push({$el:a,style:this.options.hiddenStyle}),this._sort(),this.reLayout(d)):d()},shuffle:function(a){this.updateSortData(this.$allAtoms),this.options.sortBy="random",this._sort(),this.reLayout(a)},destroy:function(){var a=this.usingTransforms,b=this.options;this.$allAtoms.removeClass(b.hiddenClass+" "+b.itemClass).each(function(){var b=this.style;b.position="",b.top="",b.left="",b.opacity="",a&&(b[i]="")});var c=this.element[0].style;for(var d in this.originalStyle)c[d]=this.originalStyle[d];this.element.unbind(".isotope").undelegate("."+b.hiddenClass,"click").removeClass(b.containerClass).removeData("isotope"),w.unbind(".isotope")},_getSegments:function(a){var b=this.options.layoutMode,c=a?"rowHeight":"columnWidth",d=a?"height":"width",e=a?"rows":"cols",g=this.element[d](),h,i=this.options[b]&&this.options[b][c]||this.$filteredAtoms["outer"+f(d)](!0)||g;h=Math.floor(g/i),h=Math.max(h,1),this[b][e]=h,this[b][c]=i},_checkIfSegmentsChanged:function(a){var b=this.options.layoutMode,c=a?"rows":"cols",d=this[b][c];return this._getSegments(a),this[b][c]!==d},_masonryReset:function(){this.masonry={},this._getSegments();var a=this.masonry.cols;this.masonry.colYs=[];while(a--)this.masonry.colYs.push(0)},_masonryLayout:function(a){var c=this,d=c.masonry;a.each(function(){var a=b(this),e=Math.ceil(a.outerWidth(!0)/d.columnWidth);e=Math.min(e,d.cols);if(e===1)c._masonryPlaceBrick(a,d.colYs);else{var f=d.cols+1-e,g=[],h,i;for(i=0;id&&(e.x=0,e.y=e.height),c._pushPosition(a,e.x,e.y),e.height=Math.max(e.y+g,e.height),e.x+=f})},_fitRowsGetContainerSize:function(){return{height:this.fitRows.height}},_fitRowsResizeChanged:function(){return!0},_cellsByRowReset:function(){this.cellsByRow={index:0},this._getSegments(),this._getSegments(!0)},_cellsByRowLayout:function(a){var c=this,d=this.cellsByRow;a.each(function(){var a=b(this),e=d.index%d.cols,f=Math.floor(d.index/d.cols),g=(e+.5)*d.columnWidth-a.outerWidth(!0)/2,h=(f+.5)*d.rowHeight-a.outerHeight(!0)/2;c._pushPosition(a,g,h),d.index++})},_cellsByRowGetContainerSize:function(){return{height:Math.ceil(this.$filteredAtoms.length/this.cellsByRow.cols)*this.cellsByRow.rowHeight+this.offset.top}},_cellsByRowResizeChanged:function(){return this._checkIfSegmentsChanged()},_straightDownReset:function(){this.straightDown={y:0}},_straightDownLayout:function(a){var c=this;a.each(function(a){var d=b(this);c._pushPosition(d,0,c.straightDown.y),c.straightDown.y+=d.outerHeight(!0)})},_straightDownGetContainerSize:function(){return{height:this.straightDown.y}},_straightDownResizeChanged:function(){return!0},_masonryHorizontalReset:function(){this.masonryHorizontal={},this._getSegments(!0);var a=this.masonryHorizontal.rows;this.masonryHorizontal.rowXs=[];while(a--)this.masonryHorizontal.rowXs.push(0)},_masonryHorizontalLayout:function(a){var c=this,d=c.masonryHorizontal;a.each(function(){var a=b(this),e=Math.ceil(a.outerHeight(!0)/d.rowHeight);e=Math.min(e,d.rows);if(e===1)c._masonryHorizontalPlaceBrick(a,d.rowXs);else{var f=d.rows+1-e,g=[],h,i;for(i=0;id&&(e.x=e.width,e.y=0),c._pushPosition(a,e.x,e.y),e.width=Math.max(e.x+f,e.width),e.y+=g})},_fitColumnsGetContainerSize:function(){return{width:this.fitColumns.width}},_fitColumnsResizeChanged:function(){return!0},_cellsByColumnReset:function(){this.cellsByColumn={index:0},this._getSegments(),this._getSegments(!0)},_cellsByColumnLayout:function(a){var c=this,d=this.cellsByColumn;a.each(function(){var a=b(this),e=Math.floor(d.index/d.rows),f=d.index%d.rows,g=(e+.5)*d.columnWidth-a.outerWidth(!0)/2,h=(f+.5)*d.rowHeight-a.outerHeight(!0)/2;c._pushPosition(a,g,h),d.index++})},_cellsByColumnGetContainerSize:function(){return{width:Math.ceil(this.$filteredAtoms.length/this.cellsByColumn.rows)*this.cellsByColumn.columnWidth}},_cellsByColumnResizeChanged:function(){return this._checkIfSegmentsChanged(!0)},_straightAcrossReset:function(){this.straightAcross={x:0}},_straightAcrossLayout:function(a){var c=this;a.each(function(a){var d=b(this);c._pushPosition(d,c.straightAcross.x,0),c.straightAcross.x+=d.outerWidth(!0)})},_straightAcrossGetContainerSize:function(){return{width:this.straightAcross.x}},_straightAcrossResizeChanged:function(){return!0}},b.fn.imagesLoaded=function(a){function h(){a.call(c,d)}function i(a){var c=a.target;c.src!==f&&b.inArray(c,g)===-1&&(g.push(c),--e<=0&&(setTimeout(h),d.unbind(".imagesLoaded",i)))}var c=this,d=c.find("img").add(c.filter("img")),e=d.length,f="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",g=[];return e||h(),d.bind("load.imagesLoaded error.imagesLoaded",i).each(function(){var a=this.src;this.src=f,this.src=a}),c};var x=function(b){a.console&&a.console.error(b)};b.fn.isotope=function(a,c){if(typeof a=="string"){var d=Array.prototype.slice.call(arguments,1);this.each(function(){var c=b.data(this,"isotope");if(!c){x("cannot call methods on isotope prior to initialization; attempted to call method '"+a+"'");return}if(!b.isFunction(c[a])||a.charAt(0)==="_"){x("no such method '"+a+"' for isotope instance");return}c[a].apply(c,d)})}else this.each(function(){var d=b.data(this,"isotope");d?(d.option(a),d._init(c)):b.data(this,"isotope",new b.Isotope(a,this,c))});return this}})(window,jQuery);
var themetonmgamenu = {
	build: function(menu){
		jQuery(document).ready(function($){
			var $main_ul = $(menu + ">ul");
			var $main_li = $main_ul.find('ul').parent();
			$main_ul.find('>li').each(function(){
				jQuery(this).find('>ul').each(function(){
					jQuery(this).find('>li').eq(0).append('');
				});
			});
			$main_li.each(function(i){
				var $this = $(this);
				$this.hover(
					function(){
						var $targetul = $(this).children("ul:eq(0)");
						var target_width = parseInt($targetul.parent().outerWidth()/2);
						$targetul.parent().find('.menu_arrow').css({
							'left': target_width+'px'
						});
						if( $targetul.find('.menu_column').length > 0 ){
							$targetul.find('>li').addClass('row');
							$targetul.find('>li').css({ 'display':'block', 'width':'100%' });
							$targetul.find('.menu_column').addClass('col-lg-'+parseInt(12/$targetul.find('.menu_column').length)+' col-md-4 col-xxs-6 col-xs-12');
							$targetul.width( $targetul.find('.menu_column').length*230 );
							
							// mega menu set left pos, arrow pos
							var t_left = parseInt(($targetul.find('.menu_column').length*230-target_width)/2);
							$targetul.css({ 'left': '-'+t_left+'px' });
							$targetul.parent().find('.menu_arrow').css({
								'left': t_left+target_width+'px'
							});
							if( $targetul.parent().hasClass('fullwidth') ){
								var wpadin = parseInt(($(window).width() - $('#header > .container').width())/2);
								var lileft = $targetul.parent().offset().left;
								
								$targetul.css({
									'left': '-'+(lileft-wpadin)+'px',
									'width': $('#header > .container').width()+'px'
								});
								$targetul.parent().find('.menu_arrow').css({
									'left': parseInt(lileft-wpadin+target_width)+'px'
								});
							}
							else{
								var lileft = parseInt($targetul.parent().offset().left);
								if( $(window).width() < $targetul.width()/2+lileft ){
									var pos_dif = $targetul.width()/2+lileft - $(window).width();
									pos_dif = parseInt( pos_dif );
									$targetul.css({ 'left': '-'+(parseInt($targetul.width()/2) + pos_dif+target_width)+'px' });
									$targetul.parent().find('.menu_arrow').css({
										'left': (parseInt($targetul.width()/2) + pos_dif+target_width+target_width)+'px'
									});
								}
							}
							if( $('.wide_menu').length>0 && !$targetul.parent().hasClass('fullwidth') ){
								$targetul.css({ 'left': '0px' });
								$targetul.parent().find('.menu_arrow').css({
									'left': target_width+'px'
								});
							}
						}
						else{
							var lileft = parseInt($targetul.parent().offset().left);
							if( $(window).width() < $targetul.width()+lileft ){
								var pos_dif = $targetul.width()/2+lileft - $(window).width();
								pos_dif = parseInt( pos_dif );
								$targetul.css({ 'left': '-'+(parseInt($targetul.width()/2) + pos_dif+target_width)+'px' });
								$targetul.parent().find('.menu_arrow').css({
									'left': (parseInt($targetul.width()/2) + pos_dif+target_width+target_width)+'px'
								});
								$targetul.addClass('floar_right_menu');
							}
						}
						// calculate Submenu Padding-Top
						if( $('.wide_menu').length>0 ){ }
						else{
							var sub_top = parseInt(jQuery('#header').css('padding-bottom')) + parseInt((jQuery('#header > .container').outerHeight()-jQuery('.mainmenu').parent().outerHeight())/2+jQuery('.mainmenu').parent().outerHeight());
							jQuery('.mainmenu ul.menu > li > ul').css({
								'padding-top': sub_top+'px'
							});
							//var stuck = jQuery('#header').hasClass('stuck');
							jQuery(window).scroll(function(){
								var sub_top = parseInt(jQuery('#header').css('padding-bottom')) + parseInt((jQuery('#header > .container').outerHeight()-jQuery('.mainmenu').parent().outerHeight())/2+jQuery('.mainmenu').parent().outerHeight());
								jQuery('.mainmenu ul.menu > li > ul').css({
									'padding-top': sub_top+'px'
								});
							});
						}
						$targetul.fadeIn('fast');
					},
					function(){
						var $targetul = $(this).children("ul:eq(0)");
						$targetul.fadeOut('fast');
					}
				);
			});
		});
	}
}
themetonmgamenu.build('.mainmenu');/*global jQuery */
/*jshint multistr:true browser:true */
/*!
* FitVids 1.0
*
* Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
*
* Date: Thu Sept 01 18:00:00 2011 -0500
*/
(function( $ ){
  "use strict";
  $.fn.fitVids = function( options ) {
    var settings = {
      customSelector: null
    };
    if(!document.getElementById('fit-vids-style')) {
      var div = document.createElement('div'),
          ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0];
      div.className = 'fit-vids-style';
      div.id = 'fit-vids-style';
      div.style.display = 'none';
      div.innerHTML = '';
      ref.parentNode.insertBefore(div,ref);
    }
    if ( options ) {
      $.extend( settings, options );
    }
    return this.each(function(){
      var selectors = [
        "iframe[src*='player.vimeo.com']",
        "iframe[src*='youtube.com']",
        "iframe[src*='youtube-nocookie.com']",
        "iframe[src*='kickstarter.com'][src*='video.html']",
        "object",
        "embed"
      ];
      if (settings.customSelector) {
        selectors.push(settings.customSelector);
      }
      var $allVideos = $(this).find(selectors.join(','));
      $allVideos = $allVideos.not("object object"); // SwfObj conflict patch
      $allVideos.each(function(){
        var $this = $(this);
        if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
        var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
            width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
            aspectRatio = height / width;
        if(!$this.attr('id')){
          var videoID = 'fitvid' + Math.floor(Math.random()*999999);
          $this.attr('id', videoID);
        }
        $this.wrap('').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%");
        $this.removeAttr('height').removeAttr('width');
      });
    });
  };
})( jQuery );
function initMobileMenu(){
    // Preparing menu for mobile dropdown.
    var $mobileMenu = '';
    var hasMobileMenu = false;
    if(jQuery('#header').find('#tt-mobile-menu').length) {
        $mobileMenu = jQuery('#header').find('#tt-mobile-menu').clone().removeClass('hidden-xs hidden-sm hidden-md hidden-lg').hide();
        jQuery('#header').find('#tt-mobile-menu').remove();
        hasMobileMenu = true;
    } else if(jQuery('#header').find('.mainmenu').length) {
        $mobileMenu = jQuery('#header').find('.mainmenu').clone().removeClass('hidden-xs hidden-sm visible-md visible-lg').attr('id','tt-mobile-menu').hide();
        $mobileMenu.removeClass('mainmenu metro menu');
        hasMobileMenu = true;
    } else if(jQuery('.wide_menu ').find('.mainmenu').length) {
        $mobileMenu = jQuery('.wide_menu').find('.mainmenu').clone().removeClass('hidden-xs hidden-sm visible-md visible-lg').attr('id','tt-mobile-menu').hide();
        $mobileMenu.removeClass('mainmenu metro menu');
        hasMobileMenu = true;
    }
    
    if( jQuery('#one_page_menu').html()!='' && jQuery('#one_page_menu').length>0 ){
        $mobileMenu.find('>ul').html( jQuery('#one_page_menu').html() );
    }
    if(hasMobileMenu) {
        // Adding collapse button of Mobile menu
        jQuery('#header>.container>.row').append('');
    }
    
    $mobileMenu.find('ul').attr('style', '');
    $mobileMenu.find('li').removeClass('fullwidth megamenu light dark').attr('style', '');
    $mobileMenu.children().find('ul').addClass('sub-menu');
    $mobileMenu.find('ul.sub-menu').each(function(){
        jQuery(this).parent('li').addClass('has-children');
        jQuery(this).after(' ');
    });
    $mobileMenu.insertAfter(jQuery('#header'));
    
    // Adding expand & collapse event on Plus symbol
    jQuery('#tt-mobile-menu li.has-children span.collapse').click(function(){
        var $this = jQuery(this).closest('.has-children');
        $this.siblings('li.tt-open').removeClass('tt-open').children('.sub-menu').slideUp('fast');
        $this.toggleClass('tt-open');
        if($this.hasClass('tt-open')) {
            $this.children('.sub-menu').slideDown('fast');
        } else {
            $this.children('.sub-menu').slideUp('fast');
        }
    });
    
    // Adding expand event on links those has subs when click first time
    jQuery('#tt-mobile-menu .has-children>a').click(function(e){
        var $this = jQuery(this).closest('.has-children');
        $this.siblings('li.tt-open').removeClass('tt-open').children('.sub-menu').slideUp('fast');
        $this.toggleClass('tt-open');
        if($this.hasClass('tt-open')){
            e.preventDefault();
            $this.children('.sub-menu').slideDown('fast');
            return false;
        }
    });
    $mobileMenu.find('li a').click(function(){
        if( jQuery('#one_page_menu').html()!='' ){
            $this = jQuery(this);
            $link = $this.attr('href');
            $obj = jQuery('div[permalink="'+$link+'"],section[permalink="'+$link+'"]');
            if( $obj.length > 0 ){
                jQuery('html, body').animate({
                     scrollTop: $obj.offset().top - jQuery('.sticky-wrapper').height()
                }, 800);
                jQuery('#tt-mobile-menu').slideToggle('fast');
                return false;
            }
        }
    });
    
    // Show and Hide mobile menu
    jQuery('a#mobile-menu-expand-collapse').click(function(e){
        e.preventDefault();
        jQuery('#tt-mobile-menu').slideToggle('fast');
        jQuery("html, body").animate({ scrollTop: 0 }, "slow");
    });
    if( jQuery('#header').hasClass('header_transparent') ){
        jQuery('#tt-mobile-menu').css({
            'padding-top': '100px'
        });
        jQuery('#message_bar, #top_Bar').hide();
    }
}
function initMetroBlog(){
    jQuery('.metro-loop').isotope({
        itemSelector : 'article',
        filter: '*',
        getSortData: {
            number : function($elem){
                return parseInt($elem.attr('post-id'), 10);
            }
        },
        sortBy : 'number',
        masonry: {
            columnWidth: 1
        }
    });
	
    jQuery('.metro-loop').find('article').each(function(){
        var $current_item = jQuery(this);
        jQuery(this).find('a').unbind('click')
        .click(function(){
            metro_item_click_hook($current_item.attr('post-id'));
            return false;
        });
    });
}
function metro_item_click_hook($post_id){
    jQuery('#metro_item_content').slideUp();
    jQuery.post( metro_frontend_ajax,
    {
        action: 'get_metro_item_content', 
        post_id: $post_id
    },
    function(data){
        if( data != "-1" ){
            jQuery('#metro_item_content').html(data);
            jQuery('#metro_item_content').slideDown();
            	
            jQuery('#metro_item_content').find('.close_post_link').unbind('click')
            .click(function(){
                jQuery('#metro_item_content').slideUp();
            });
            jQuery('#metro_item_content').find('a.prev_post_link').unbind('click')
            .click(function(){
                metro_item_click_hook( jQuery(this).attr('post-id') );
                return false;
            });
            jQuery('#metro_item_content').find('a.next_post_link').unbind('click')
            .click(function(){
                metro_item_click_hook( jQuery(this).attr('post-id') );
                return false;
            });
            	
            jQuery('html, body').animate({
                scrollTop: jQuery("#metro_item_content").offset().top-286+190
            }, 800);
        }
        else{
            console.log(data);
        }
    });
}
function fix_woo_products(){
    jQuery('.products .entry_product .product_image_hover').each(function(){
        var $this = jQuery(this);
        if( $this.find('img').length>0 ){
            var wid = parseInt($this.width()*$this.find('img').eq(0).height()/$this.find('img').eq(0).width());
            $this.height( wid );
        }
    });
}
jQuery(function(){
    if(responsive) {
        initMobileMenu();
    }
    jQuery('.metro_container').isotope({
        itemSelector : 'article',
        filter: '*',
        getSortData: {
            number : function($elem){
                return parseInt($elem.attr('post-id'), 10);
            }
        },
        sortBy : 'number',
        masonry: {
            columnWidth: 1
        }
    });
	
    /* Checking non sticky option activated */
    if(typeof non_sticky_menu != 'undefined' && non_sticky_menu != true) {
        // menu fixed position
        if( jQuery('.wide_menu').length > 0 ){
            jQuery('.wide_menu').waypoint('sticky', {
                wrapper: ''
            });
        }
        else{
            if( jQuery('.icon_menu').length > 0 ){
                jQuery('.mainmenu > ul > li > a').css({
                    'height' : jQuery('#header').outerHeight()+'px',
                    'line-height': jQuery('#header').outerHeight()+'px'
                });
            }
            // check offset
            var x_offset = 0;
            if( jQuery('.header_transparent').length>0 ){
                x_offset = -30;
                jQuery('#content #primary, #content #sidebar').css({
                    'padding-top': '0px'
                });
            }
            else if( jQuery('#top_bar').length < 1 || jQuery('#message_bar').length < 1 ){
                x_offset = -30;
            }
            jQuery('#header').waypoint('sticky', {
                offset: x_offset,
                wrapper: '',
                handler: function(direction){
                            
                    if( jQuery('.icon_menu').length > 0 ){
                        if( direction=='down' ){
                            jQuery('.mainmenu > ul > li > a').attr('style', '');
                        }
                        else{
                            jQuery('.mainmenu > ul > li > a').css({
                                'height' : jQuery('#header').outerHeight()+'px',
                                'line-height': jQuery('#header').outerHeight()+'px'
                            });
                        }
                        if( jQuery('.header_transparent').length<1 ){
                            jQuery('.sticky-wrapper').css('height', '77px');
                            setTimeout(function(){
                                jQuery('.sticky-wrapper').css('height', jQuery('#header').outerHeight()+'px');
                            }, 200);
                        }
                    }
                    if( jQuery('.header_transparent').length>0 ){
                        jQuery('.sticky-wrapper').css('height', '0px');
                    }
                    
                }
            });
        }
    }
    jQuery('.mainmenu .menu').find('li').each(function(){
        var $this = jQuery(this);
        if( $this.find('ul').length > 0 ){
            $this.addClass('page_item_has_children');
        }
    });
	
    jQuery(window).resize(function(){
        $sw = 136;
        $mw = 158;
        $lw = 188;
        $metro = jQuery('.metro-loop');
        $w = jQuery(window).width();
        if( $metro.hasClass('small') ){
            $metro.width( parseInt($w/$sw)*$sw );
        }
        else if( $metro.hasClass('medium') ){
            $metro.width( parseInt($w/$mw)*$mw );
        }
        else if( $metro.hasClass('large') ){
            $metro.width( parseInt($w/$lw)*$lw );
        }
		
        jQuery('.metro_container').isotope('reLayout');
        if( jQuery('.products .entry_product .product_image_hover').length>0 ){
            fix_woo_products();
        }
    });
    if( jQuery('.products .entry_product .product_image_hover').length>0 ){
        jQuery('.products img').load(function(){
            fix_woo_products();
        });
    }
	
    
    
    
    /*
     * Footer layout color filling
     * 1 => 100%
     * 2 => 50% + 50%
     * 3 => 50% + 25% + 25%
     * 4 => 25% + 25% + 50%
     * 5 => 33% + 33% + 33%
     * 6 => 25% + 25% + 25% + 25%
     */
    if(footer == true && footer_layout != 1 && colorful_footer == true) {
        $footer_block = jQuery('#footer').find('.footer_widget_container');
        var actual_height = new Array();
        $footer_block.each(function(index){
            actual_height.push(jQuery(this).height());
            jQuery(this).height(jQuery('#footer').height()-160).css("zIndex", index+10);
            var colorful = '';
            var $colorful = jQuery(colorful).css({
                'position': 'absolute',
                'width': '50%',
                'height': '100%',
                'top': '0',
                'z-index': index + 3
            });
            if(index < 1)
                jQuery($colorful).css({
                    'left': 0
                });
            else jQuery($colorful).css({
                'right': 0
            });
            jQuery('#footer > .container').before($colorful);
        });
        
        
        /*
         * Events when Window resize
         */
        jQuery(window).resize(function(){
            $color_bg = jQuery('#footer').find('.footer_metro_bg');
            // When two columns
            if(footer_layout == 2) {
                if (jQuery(window).width() < 768) {
                    $footer_block.each(function(){
                        jQuery(this).css('height', 'auto');
                    });
                } else {
                    $footer_block.each(function(){
                        jQuery(this).height(jQuery('#footer').height()-160);
                    });
                }
            } else if(footer_layout == 3) {
                if (jQuery(window).width() < 768) {
                    $footer_block.each(function(){
                        jQuery(this).css('height', 'auto');
                    });
                } else if (jQuery(window).width() < 992) {
                    $footer_block.eq(0).css('height', 'auto');
                    max_height = actual_height[1] > actual_height[2] ? actual_height[1] : actual_height[2];
                    max_height += 160;
                    $footer_block.eq(1).css('height', max_height);
                    $footer_block.eq(2).css('height', max_height);
                    $color_bg.eq(1).css({
                        'height': max_height,
                        'left': 0,
                        'bottom':0,
                        'top' : ''
                    });
                    $color_bg.eq(2).css({
                        'height': max_height,
                        'right': 0,
                        'bottom':0,
                        'top' : ''
                    });
                } else {
                    $footer_block.each(function(){
                        jQuery(this).height(jQuery('#footer').height()-160);
                    });
                    $color_bg.eq(1).css({'left':'','right':0});
                }
            } else if(footer_layout == 4) {
                if (jQuery(window).width() < 768) {
                    $footer_block.each(function(){
                        jQuery(this).css('height', 'auto');
                    });
                } else if (jQuery(window).width() < 992) {
                    $footer_block.eq(2).css('height', 'auto');
                    max_height = actual_height[0] > actual_height[1] ? actual_height[0] : actual_height[1];
                    max_height += 160;
                    $footer_block.eq(1).css('height', max_height);
                    $footer_block.eq(0).css('height', max_height);
                    $color_bg.eq(2).css({
                        'width': '100%',
                        'zIndex': 1
                    });
                    $color_bg.eq(1).css({
                        'height': max_height
                    });
                    $color_bg.eq(0).css({
                        'height': max_height
                    });
                } else {
                    $footer_block.each(function(){
                        jQuery(this).height(jQuery('#footer').height()-160);
                    });
                    $color_bg.eq(2).css({
                        'width': '50%',
                        'zIndex': 5
                    });
                }
            } else if(footer_layout == 5) {
                if (jQuery(window).width() < 992) {
                    $footer_block.each(function(i){
                        jQuery(this).css('height', 'auto');
                        var offset = jQuery(this).position();
                        $color_bg.eq(i).css({
                            'height': jQuery(this).height()+160,
                            'width': '100%',
                            'top': offset.top
                        });
                    });
                } else {
                    $footer_block.each(function(i){
                        jQuery(this).height(jQuery('#footer').height()-160);
                        $color_bg.eq(i).css({
                            'height': '100%',
                            'width': '50%',
                            'top': ''
                        });
                    });
                }
            } else if(footer_layout == 6) {
                if (jQuery(window).width() < 768) {
                    $footer_block.each(function(){
                        jQuery(this).css('height', 'auto');
                    });
                } else if (jQuery(window).width() < 992) {                        
                    max_height = actual_height[0] > actual_height[1] ? actual_height[0] : actual_height[1];
                    max_height += 160;
                    $footer_block.eq(0).css('height', max_height);
                    $footer_block.eq(1).css('height', max_height);
                    $color_bg.eq(0).css('height', max_height);
                    $color_bg.eq(1).css('height', max_height);
                    max_height = actual_height[2] > actual_height[3] ? actual_height[2] : actual_height[3];
                    max_height += 160;
                    $footer_block.eq(2).css('height', max_height);
                    $footer_block.eq(3).css('height', max_height);
                    $color_bg.eq(2).css({
                        'height': max_height,
                        'bottom': 0,
                        'top': '',
                        'right': '',
                        'left': 0
                    });
                    $color_bg.eq(3).css({
                        'height': max_height,
                        'bottom': 0,
                        'top': ''
                    });
                } else {
                    $footer_block.each(function(){
                        jQuery(this).height(jQuery('#footer').height()-160);
                    });
                    $color_bg.eq(2).css({
                        'right': 0,
                        'left': '',
                        'height': '100%'
                    });
                }
            }
        });
        jQuery(window).trigger('resize');
    }
    
    
    // Video responsive alignment		
    jQuery("section,#footer").not('.ls-wp-container').fitVids();
    // init widget child ul li
    jQuery('.sidebar_area .widget_pages > ul, .sidebar_area .widget_nav_menu > div > ul').each(function(){
        var $this = jQuery(this);
        $this.find('ul').hide();
        $this.find('li').hover(
            function(){
                jQuery(this).find('> ul').slideDown('fast');
            },
            function(){
                jQuery(this).find('> ul').slideUp('fast');
            }
        );
    });
    
    
    // Site message button
    jQuery('#message_bar .icon-remove,#message_bar .icon-times,#message_bar .fa-times').click(function(){
        jQuery('#message_bar').slideUp();
        set_cookie('message_bar', 'hide');
    });
    
    jQuery('a[rel^="prettyPhoto"],a.prettyPhoto,.blox-element.prettyPhoto>a').prettyPhoto({deeplinking:false, social_tools:false});
   
    // Go to top arrow
    jQuery('span.gototop').click(function() {
        jQuery('body,html').animate({scrollTop: 0}, 600);
    });
    var s = skrollr.init({
        forceHeight: false
    });
    jQuery(window).scroll(function(){
        if( jQuery(window).scrollTop() > 500 ){
            jQuery('.gototop_footer').addClass('show');
        }
        else{
            jQuery('.gototop_footer').removeClass('show');
        }
    });
    new jQuery.ajax_search({scope:'.wide_menu'});
    jQuery('.add_to_cart_button').click(function(){
        var $cart = jQuery('.woocommerce_cart');
        var $item = jQuery(this);
        if($cart.length>0){
            setTimeout(function(){
                var values = 'action=tt_get_shopping_cart';
                jQuery.ajax({
                    url: metro_frontend_ajax,
                    type: "POST",
                    data:values,
                    success: function(response){
                        var $response = jQuery('').append(response);
                        $response.find('#woo_added_cart_msg').remove();
                        $cart.replaceWith($response.html());
                        var item_title = $item.parent().parent().find('h3').text();
                        jQuery('#woo_added_cart_msg').find('.item_name').html(item_title);
                        jQuery('#woo_added_cart_msg').css({ right: '-500px' });
                        jQuery('#woo_added_cart_msg').show().animate({
                            right: '0px',
                            opacity: 1
                        }, 400, function(){
                            setTimeout(function(){
                                jQuery('#woo_added_cart_msg').animate({ right:'-500px', opacity: 0 }, 400, function(){ jQuery('#woo_added_cart_msg').hide(); });
                            }, 2000);
                        });
                    }
                });
            }, 500);
        }
    });
    jQuery('.entry_content').each(function(){
        var $this = jQuery(this);
        if( $this.find('>div').length>0 && $this.find('>div').eq(0).hasClass('blox_row_fullwidth') ){
            $this.parent().parent().css('padding-top', '0px');
        }
        if( $this.find('>div').length>0 && $this.find('>div').eq($this.find('>div').length-1).hasClass('blox_row_fullwidth') ){
            $this.parent().parent().css('padding-bottom', '0px');
        }
    });
    jQuery('.entry_media .entry_hover .entry_article_title').each(function(){
        var $this = jQuery(this);
        $this.css({
            'margin-top': -parseInt($this.height()/2)
        });
    });
    
});
jQuery(window).load(function(){
    // fix primary and sidebar heights
    jQuery('.content').each(function(){
        var $this = jQuery(this);
        if( $this.parent().hasClass('pull-right') ){
                $this.parent().attr('prev_class', 'pull-right');
        }
        if( $this.parent().hasClass('pull-left') ){
            $this.parent().attr('prev_class', 'pull-left');
        }
        if( jQuery(window).width() < 768 ){
            $this.parent().removeClass('pull-right pull-left');
        }
        if( jQuery(this).parent().parent().find('.sidebar_area').length>0 ){
            var $sidebar = jQuery(this).parent().parent().find('.sidebar_area');
            if( $sidebar.length > 0 && $sidebar.outerHeight() < $this.outerHeight() ){
                if( jQuery(window).width() > 768 ){
                    $sidebar.height( $this.outerHeight()-120 );
                }
            }
            jQuery(window).resize(function(){
                if( jQuery(window).width() < 768 ){
                    $sidebar.css('height', 'auto');
                    $this.parent().removeClass('pull-right pull-left');
                }
                else{
                    $sidebar.height( $this.outerHeight()-120 );
                    $this.parent().addClass($this.parent().attr('prev_class'));
                }
            });
        }
    });
});
function set_cookie(c_name, value, exdays){
    exdays = typeof exdays !== 'undefined' ? exdays : 1;
    var exdate=new Date();
    exdate.setDate(exdate.getDate() + exdays);
    var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
    document.cookie=c_name + "=" + c_value;
}
jQuery.ajax_search  =  function(options){
   var defaults = {
        delay: 300,
        minChars: 3,
        scope: 'body'
    }
    this.options = jQuery.extend({}, defaults, options);
    this.scope   = jQuery(this.options.scope);
    this.timer   = false;
    this.lastVal = "";
    this.bind_events();
}
jQuery.ajax_search.prototype ={
    bind_events: function(){
        this.scope.on('keyup', '#s' , jQuery.proxy( this.try_search, this));
    },
    try_search: function(e){
        clearTimeout(this.timer);
        if(e.currentTarget.value.length >= this.options.minChars && this.lastVal != jQuery.trim(e.currentTarget.value)){
            this.timer = setTimeout(jQuery.proxy( this.do_search, this, e), this.options.delay);
        }
    },
    do_search: function(e){
        var obj          = this,
            currentField = jQuery(e.currentTarget).attr( "autocomplete", "off" ),
            form         = currentField.parents('form:eq(0)'),
            results      = form.find('.ajax_search_response'),
            loading      = jQuery('
'),
            action       = form.attr('action'),
            values       = form.serialize();
            values      += '&action=themeton_fajax_search';
        if(action.indexOf('?') != -1){
            action  = action.split('?');
            values += "&" + action[1];
        }
        if(!results.length) results = jQuery('').appendTo(form);
        if(results.find('.ajax_not_found').length && e.currentTarget.value.indexOf(this.lastVal) != -1) return;
        this.lastVal = e.currentTarget.value;
        jQuery.ajax({
            url: metro_frontend_ajax,
            type: "POST",
            data:values,
            beforeSend: function()
            {
                results.html('').append(loading);
            },
            success: function(response)
            {
                if(response == 0) response = "";
                results.html(response);
            },
            complete: function()
            {
                loading.remove();
            }
        });
    }
}