/**
 * Load utils - BEGIN
 */
/*
 CSS Browser Selector 1.0
 Originally written by Rafael Lima (http://rafael.adm.br)
 http://rafael.adm.br/css_browser_selector
 License: http://creativecommons.org/licenses/by/2.5/

 Co-maintained by:
 https://github.com/ridjohansen/css_browser_selector
 https://github.com/wbruno/css_browser_selector
 */

"use strict";

var uaInfo = {
	ua: '',
	is: function(t) {
		return RegExp(t, "i").test(uaInfo.ua);
	},
	version: function(p, n) {
		n = n.replace(".", "_");
		var i = n.indexOf('_'),
			ver = "";
		while (i > 0) {
			ver += " " + p + n.substring(0, i);
			i = n.indexOf('_', i + 1);
		}
		ver += " " + p + n;
		return ver;
	},
	getBrowser: function() {
		var g = 'gecko',
			w = 'webkit',
			c = 'chrome',
			f = 'firefox',
			s = 'safari',
			o = 'opera',
			a = 'android',
			bb = 'blackberry',
			dv = 'device_',
			ua = uaInfo.ua,
			is = uaInfo.is;
		return [
			(!(/opera|webtv/i.test(ua)) && /msie\s(\d+)/.test(ua)) ? ('ie ie' + (/trident\/4\.0/.test(ua) ? '8' : RegExp.$1)) : is('firefox/') ? g + " " + f + (/firefox\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + f + RegExp.$2 + ' ' + f + RegExp.$2 + "_" + RegExp.$4 : '') : is('gecko/') ? g : is('opera') ? o + (/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + o + RegExp.$2 + ' ' + o + RegExp.$2 + "_" + RegExp.$4 : (/opera(\s|\/)(\d+)\.(\d+)/.test(ua) ? ' ' + o + RegExp.$2 + " " + o + RegExp.$2 + "_" + RegExp.$3 : '')) : is('konqueror') ? 'konqueror' : is('blackberry') ? (bb + (/Version\/(\d+)(\.(\d+)+)/i.test(ua) ? " " + bb + RegExp.$1 + " " + bb + RegExp.$1 + RegExp.$2.replace('.', '_') : (/Blackberry ?(([0-9]+)([a-z]?))[\/|;]/gi.test(ua) ? ' ' + bb + RegExp.$2 + (RegExp.$3 ? ' ' + bb + RegExp.$2 + RegExp.$3 : '') : ''))) // blackberry
			: is('android') ? (a + (/Version\/(\d+)(\.(\d+))+/i.test(ua) ? " " + a + RegExp.$1 + " " + a + RegExp.$1 + RegExp.$2.replace('.', '_') : '') + (/Android (.+); (.+) Build/i.test(ua) ? ' ' + dv + ((RegExp.$2).replace(/ /g, "_")).replace(/-/g, "_") : '')) //android
			: is('chrome') ? w + ' ' + c + (/chrome\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + c + RegExp.$2 + ((RegExp.$4 > 0) ? ' ' + c + RegExp.$2 + "_" + RegExp.$4 : '') : '') : is('iron') ? w + ' iron' : is('applewebkit/') ? (w + ' ' + s + (/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + s + RegExp.$2 + " " + s + RegExp.$2 + RegExp.$3.replace('.', '_') : (/ Safari\/(\d+)/i.test(ua) ? ((RegExp.$1 == "419" || RegExp.$1 == "417" || RegExp.$1 == "416" || RegExp.$1 == "412") ? ' ' + s + '2_0' : RegExp.$1 == "312" ? ' ' + s + '1_3' : RegExp.$1 == "125" ? ' ' + s + '1_2' : RegExp.$1 == "85" ? ' ' + s + '1_0' : '') : ''))) //applewebkit
			: is('mozilla/') ? g : ''
		];
	},
	getPlatform: function() {
		var ua = uaInfo.ua,
			version = uaInfo.version,
			is = uaInfo.is;
		return [
			is('j2me') ? 'j2me' : is('ipad|ipod|iphone') ? (
				(/CPU( iPhone)? OS (\d+[_|\.]\d+([_|\.]\d+)*)/i.test(ua) ? 'ios' + version('ios', RegExp.$2) : '') + ' ' + (/(ip(ad|od|hone))/gi.test(ua) ? RegExp.$1 : "")) //'iphone'
			//:is('ipod')?'ipod'
			//:is('ipad')?'ipad'
			: is('playbook') ? 'playbook' : is('kindle|silk') ? 'kindle' : is('playbook') ? 'playbook' : is('mac') ? 'mac' + (/mac os x ((\d+)[.|_](\d+))/.test(ua) ? (' mac' + (RegExp.$2) + ' mac' + (RegExp.$1).replace('.', "_")) : '') : is('win') ? 'win' + (is('windows nt 6.2') ? ' win8' : is('windows nt 6.1') ? ' win7' : is('windows nt 6.0') ? ' vista' : is('windows nt 5.2') || is('windows nt 5.1') ? ' win_xp' : is('windows nt 5.0') ? ' win_2k' : is('windows nt 4.0') || is('WinNT4.0') ? ' win_nt' : '') : is('freebsd') ? 'freebsd' : is('x11|linux') ? 'linux' : ''
		];
	},
	getMobile: function() {
		var is = uaInfo.is;
		return [
			is("android|mobi|mobile|j2me|iphone|ipod|ipad|blackberry|playbook|kindle|silk") ? 'mobile' : ''
		];
	},
	getIpadApp: function() {
		var is = uaInfo.is;
		return [
			(is('ipad|iphone|ipod') && !is('safari')) ? 'ipad_app' : ''
		];
	},
	getLang: function() {
		var ua = uaInfo.ua;
		return [/[; |\[](([a-z]{2})(\-[a-z]{2})?)[)|;|\]]/i.test(ua) ? ('lang_' + RegExp.$2).replace("-", "_") + (RegExp.$3 != '' ? (' ' + 'lang_' + RegExp.$1).replace("-", "_") : '') : ''];
	}
}
var screenInfo = {
	width: (window.outerWidth || document.documentElement.clientWidth) - 15,
	height: window.outerHeight || document.documentElement.clientHeight,
	screens: [0, 768, 980, 1200],
	screenSize: function() {
		screenInfo.width = (window.outerWidth || document.documentElement.clientWidth) - 15;
		screenInfo.height = window.outerHeight || document.documentElement.clientHeight;
		var screens = screenInfo.screens,
			i = screens.length,
			arr = [],
			maxw,
			minw;
		while (i--) {
			if (screenInfo.width >= screens[i]) {
				if (i) {
					arr.push("minw_" + screens[(i)]);
				}
				if (i <= 2) {
					arr.push("maxw_" + (screens[(i) + 1] - 1));
				}
				break;
			}
		}
		return arr;
	},
	getOrientation: function() {
		return screenInfo.width < screenInfo.height ? ["orientation_portrait"] : ["orientation_landscape"];
	},
	getInfo: function() {
		var arr = [];
		arr = arr.concat(screenInfo.screenSize());
		arr = arr.concat(screenInfo.getOrientation());
		return arr;
	},
	getPixelRatio: function() {
		var arr = [],
			pixelRatio = window.devicePixelRatio ? window.devicePixelRatio : 1;
		if (pixelRatio > 1) {
			arr.push('retina_' + parseInt(pixelRatio) + 'x');
			arr.push('hidpi');
		} else {
			arr.push('no-hidpi');
		}
		return arr;
	}
}
var dataUriInfo = {
	data: new Image(),
	div: document.createElement("div"),
	isIeLessThan9: false,
	getImg: function() {
		dataUriInfo.data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
		dataUriInfo.div.innerHTML = "<!--[if lt IE 9]><i></i><![endif]-->";
		dataUriInfo.isIeLessThan9 = dataUriInfo.div.getElementsByTagName("i").length == 1;
		return dataUriInfo.data;
	},
	checkSupport: function() {
		if (dataUriInfo.data.width != 1 || dataUriInfo.data.height != 1 || dataUriInfo.isIeLessThan9) {
			return ["no-datauri"];
		} else {
			return ["datauri"];
		}
	}
}

function css_browser_selector(u, ns) {
		var html = document.documentElement,
			b = []
		ns = ns ? ns : "";
		/* ua */
		uaInfo.ua = u.toLowerCase();
		var browser = uaInfo.getBrowser();
		if (browser == 'gecko') browser = (!(window.ActiveXObject) && "ActiveXObject" in window) ? 'ie ie11' : browser;
		var pattTouch = /no-touch/g;
		if (pattTouch.test(html.className)) b = b.concat('no-touch');
		else b = b.concat('touch');
		var pattAdmin = /admin-mode/g;
		if (pattAdmin.test(html.className)) b = b.concat('admin-mode');
		b = b.concat(browser);
		b = b.concat(uaInfo.getPlatform());
		b = b.concat(uaInfo.getMobile());
		b = b.concat(uaInfo.getIpadApp());
		b = b.concat(uaInfo.getLang());
		/* js */
		b = b.concat(['js']);
		/* pixel ratio */
		b = b.concat(screenInfo.getPixelRatio());
		/* screen */
		b = b.concat(screenInfo.getInfo());
		var updateScreen = function() {
			html.className = html.className.replace(/ ?orientation_\w+/g, "").replace(/ [min|max|cl]+[w|h]_\d+/g, "");
			html.className = html.className + ' ' + screenInfo.getInfo().join(' ');
		}
		window.addEventListener('resize', updateScreen);
		window.addEventListener('orientationchange', updateScreen);
		/* dataURI */
		var data = dataUriInfo.getImg();
		data.onload = data.onerror = function() {
				html.className += ' ' + dataUriInfo.checkSupport().join(' ');
			}
			/* removendo itens invalidos do array */
		b = b.filter(function(e) {
			return e;
		});
		/* prefixo do namespace */
		b[0] = ns ? ns + b[0] : b[0];
		html.className = b.join(' ' + ns);
		return html.className;
	}
	// define css_browser_selector_ns before loading this script to assign a namespace
var css_browser_selector_ns = css_browser_selector_ns || "";
// init
css_browser_selector(navigator.userAgent, css_browser_selector_ns);
/**
 * skip-link-focus-fix.js
 *
 * Helps with accessibility for keyboard only users.
 *
 * Learn more: https://github.com/Automattic/_s/pull/136
 */
(function() {
	var is_webkit = navigator.userAgent.toLowerCase().indexOf('webkit') > -1,
		is_opera = navigator.userAgent.toLowerCase().indexOf('opera') > -1,
		is_ie = navigator.userAgent.toLowerCase().indexOf('msie') > -1;
	if ((is_webkit || is_opera || is_ie) && document.getElementById && window.addEventListener) {
		window.addEventListener('hashchange', function() {
			var id = location.hash.substring(1),
				element;
			if (!(/^[A-z0-9_-]+$/.test(id))) {
				return;
			}
			element = document.getElementById(id);
			if (element) {
				if (!(/^(?:a|select|input|button|textarea)$/i.test(element.tagName))) {
					element.tabIndex = -1;
				}
				element.focus();
			}
		}, false);
	}
})();
// Polyfill for creating CustomEvents on IE9/10/11
// code pulled from:
// https://github.com/d4tocchini/customevent-polyfill
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill
try {
	new CustomEvent("test");
} catch (e) {
	var CustomEvent = function(event, params) {
		var evt;
		params = params || {
			bubbles: false,
			cancelable: false,
			detail: undefined
		};
		evt = document.createEvent("CustomEvent");
		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
		return evt;
	};
	CustomEvent.prototype = window.Event.prototype;
	window.CustomEvent = CustomEvent; // expose definition to window
}
// Evento - v1.0.0
// by Erik Royall <erikroyalL@hotmail.com> (http://erikroyall.github.io)
// Dual licensed under MIT and GPL
// Array.prototype.indexOf shim
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
Array.prototype.indexOf || (Array.prototype.indexOf = function(n) {
	"use strict";
	if (null == this) throw new TypeError;
	var t, e, o = Object(this),
		r = o.length >>> 0;
	if (0 === r) return -1;
	if (t = 0, arguments.length > 1 && (t = Number(arguments[1]), t != t ? t = 0 : 0 != t && 1 / 0 != t && t != -1 / 0 && (t = (t > 0 || -1) * Math.floor(Math.abs(t)))), t >= r) return -1;
	for (e = t >= 0 ? t : Math.max(r - Math.abs(t), 0); r > e; e++)
		if (e in o && o[e] === n) return e;
	return -1
});
var evento = function(n) {
	var t, e, o, r = n,
		i = r.document,
		f = {};
	return t = function() {
		return "function" == typeof i.addEventListener ? function(n, t, e) {
			n.addEventListener(t, e, !1), f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
		} : "function" == typeof i.attachEvent ? function(n, t, e) {
			n.attachEvent(t, e), f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
		} : function(n, t, e) {
			n["on" + t] = e, f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
		}
	}(), e = function() {
		return "function" == typeof i.removeEventListener ? function(n, t, e) {
			n.removeEventListener(t, e, !1), Helio.each(f[n][t], function(o) {
				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
			})
		} : "function" == typeof i.detachEvent ? function(n, t, e) {
			n.detachEvent(t, e), Helio.each(f[n][t], function(o) {
				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
			})
		} : function(n, t, e) {
			n["on" + t] = void 0, Helio.each(f[n][t], function(o) {
				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
			})
		}
	}(), o = function(n, t) {
		f[n] = f[n] || {}, f[n][t] = f[n][t] || [];
		for (var e = 0, o = f[n][t].length; o > e; e += 1) f[n][t][e]()
	}, {
		add: t,
		remove: e,
		trigger: o,
		_handlers: f
	}
}(this);
/*
 * OKVideo by OKFocus v2.3.2
 * http://okfoc.us
 *
 * Copyright 2014, OKFocus
 * Licensed under the MIT license.
 *
 */
var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array();
// youtube player ready
function onYouTubeIframeAPIReady() {
	YTplayers = new Array();
	jQuery('.no-touch .uncode-video-container.video').each(function() {
		var playerY;
		if (jQuery(this).attr('data-provider') == 'youtube') {
			var id = jQuery(this).attr('data-id');
			options = jQuery(window).data('okoptions-' + id);
			playerY = new YT.Player('okplayer-' + id, {
				videoId: options.video ? options.video.id : null,
				playerVars: {
					'autohide': 1,
					'autoplay': 0, //options.autoplay,
					'disablekb': options.keyControls,
					'cc_load_policy': options.captions,
					'controls': options.controls,
					'enablejsapi': 1,
					'fs': 0,
					'modestbranding': 1,
					'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname),
					'iv_load_policy': options.annotations,
					'loop': options.loop,
					'showinfo': 0,
					'rel': 0,
					'wmode': 'opaque',
					'hd': options.hd
				},
				events: {
					'onReady': OKEvents.yt.ready,
					'onStateChange': OKEvents.yt.onStateChange,
					'onError': OKEvents.yt.error
				}
			});
			YTplayers[id] = playerY;
		}
	});
}
// vimeo player ready
function vimeoPlayerReady(id) {
	options = jQuery(window).data('okoptions-' + id);
	var jIframe = options.jobject,
	iframe = jIframe[0];
	jIframe.attr('src', jIframe.data('src'));
	var playerV = $f(iframe);
	// hide player until Vimeo hides controls...
	playerV.addEvent('ready', function(e) {
		OKEvents.v.onReady(iframe);
		var carouselContainer = jQuery(iframe).closest('.owl-carousel');
		if (carouselContainer.length) {
			UNCODE.owlPlayVideo(carouselContainer);
		}
		// "Do not try to add listeners or call functions before receiving this event."
		if (OKEvents.utils.isMobile()) {
			// mobile devices cannot listen for play event
			OKEvents.v.onPlay(playerV);
		} else {
			playerV.addEvent('play', OKEvents.v.onPlay(playerV));
			playerV.addEvent('pause', OKEvents.v.onPause);
			playerV.addEvent('finish', OKEvents.v.onFinish);
		}
		if (options.time != null) {
			playerV.api('seekTo', (options.time).replace('t=', ''));
		}

		playerV.api('play');
		jQuery(iframe).css({
			visibility: 'visible',
			opacity: 1
		});

	});
}
OKEvents = {
	yt: {
		ready: function(event) {
			var iframe = jQuery(event.target)[0].c,
				id = jQuery(iframe).closest('.uncode-video-container').attr('data-id');
			youtubePlayers[id] = event.target;
			event.target.setVolume(options.volume);
			if (options.autoplay === 1) {
				if (options.playlist.list) {
					player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality);
				} else {
					var inCarousel = jQuery(iframe).closest('.owl-item');
					if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) {
						event.target.playVideo();
					} else {
						event.target.pauseVideo();
					}
				}
			}
			OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target);
		},
		onStateChange: function(event) {
			switch (event.data) {
				case -1:
					OKEvents.utils.isFunction(options.unstarted) && options.unstarted();
					break;
				case 0:
					OKEvents.utils.isFunction(options.onFinished) && options.onFinished();
					options.loop && event.target.playVideo();
					break;
				case 1:
					OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
					jQuery(event.target.c).closest('.uncode-video-container').css('opacity', '1');
					break;
				case 2:
					OKEvents.utils.isFunction(options.onPause) && options.onPause();
					break;
				case 3:
					OKEvents.utils.isFunction(options.buffering) && options.buffering();
					break;
				case 5:
					OKEvents.utils.isFunction(options.cued) && options.cued();
					break;
				default:
					throw "OKVideo: received invalid data from YT player.";
			}
		},
		error: function(event) {
			throw event;
		}
	},
	v: {
		onReady: function(target) {
			OKEvents.utils.isFunction(options.onReady) && options.onReady(target);
		},
		onPlay: function(player) {
			if (!OKEvents.utils.isMobile()) player.api('setVolume', options.volume);
			OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
			jQuery(player.element).closest('.uncode-video-container').css('opacity', '1');
		},
		onPause: function() {
			OKEvents.utils.isFunction(options.onPause) && options.onPause();
		},
		onFinish: function() {
			OKEvents.utils.isFunction(options.onFinish) && options.onFinish();
		}
	},
	utils: {
		isFunction: function(func) {
			if (typeof func === 'function') {
				return true;
			} else {
				return false;
			}
		},
		isMobile: function() {
			if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
				return true;
			} else {
				return false;
			}
		}
	}
};
// DOM class helper
(function(window) {
	'use strict';
	// class helper functions from bonzo https://github.com/ded/bonzo
	function classReg(className) {
			return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
		}
		// classList support for class management
		// altho to be fair, the api sucks because it won't accept multiple classes at once
	var hasClass, addClass, removeClass;
	if ('classList' in document.documentElement) {
		hasClass = function(elem, c) {
			if (elem !== null) return elem.classList.contains(c);
		};
		addClass = function(elem, c) {
			if (elem !== null) elem.classList.add(c);
		};
		removeClass = function(elem, c) {
			if (elem !== null) elem.classList.remove(c);
		};
	} else {
		hasClass = function(elem, c) {
			if (elem !== null) return classReg(c).test(elem.className);
		};
		addClass = function(elem, c) {
			if (!hasClass(elem, c)) {
				if (elem !== null) elem.className = elem.className + ' ' + c;
			}
		};
		removeClass = function(elem, c) {
			if (elem !== null) elem.className = elem.className.replace(classReg(c), ' ');
		};
	}

	function toggleClass(elem, c) {
		var fn = hasClass(elem, c) ? removeClass : addClass;
		fn(elem, c);
	}
	var classie = {
		// full names
		hasClass: hasClass,
		addClass: addClass,
		removeClass: removeClass,
		toggleClass: toggleClass,
		// short names
		has: hasClass,
		add: addClass,
		remove: removeClass,
		toggle: toggleClass
	};
	// transport
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(classie);
	} else {
		// browser global
		window.classie = classie;
	}
})(window);
/* From Modernizr */
function whichTransitionEvent() {
		var t;
		var el = document.createElement('fakeelement');
		var transitions = {
			'transition': 'transitionend',
			'OTransition': 'oTransitionEnd',
			'MozTransition': 'transitionend',
			'WebkitTransition': 'webkitTransitionEnd'
		}
		for (t in transitions) {
			if (el.style[t] !== undefined) {
				return transitions[t];
			}
		}
	}
/**
 * Load utils - END
 */

/**
 * Start main js
 */
(function(window, undefined) {
	'use strict';
	// Init variables
	var bodyTop,
		scrollbarWidth,
		noScroll = false,
		boxEvent = new CustomEvent('boxResized'),
		boxWidth = 0,
		boxLeft = 0,
		parallaxRows,
		parallaxCols,
		parallaxHeaders,
		headerWithOpacity,
		speedDivider = 0.25,
		pageHeader,
		masthead,
		menuwrapper,
		menuhide,
		menusticky,
		menuHeight = 0,
		mainmenu,
		secmenu,
		secmenuHeight = 0,
		transmenuHeight = 0,
		header,
		transmenuel,
		logo,
		logoel,
		logolink,
		logoMinScale,
		lastScrollValue = 0,
		deltaY,
		overHtml = true,
		wwidth = window.innerWidth || document.documentElement.clientWidth,
		wheight = window.innerHeight || document.documentElement.clientHeight,
		boxWrapper,
		docheight = 0,
		isMobile = classie.hasClass(document.documentElement, 'touch') ? true : false,
		isIE = classie.hasClass(document.documentElement, 'ie') || classie.hasClass(document.documentElement, 'opera12') ? true : false,
		isFF = classie.hasClass(document.documentElement, 'firefox') ? true : false,
		transitionEvent = whichTransitionEvent(),
		footerScroller = false,
		mediaQuery = 959,
		mediaQueryMobile = 569,
		resizeTimer,
	initBox = function() {
			if (!isMobile && scrollbarWidth == undefined) {
				// Create the measurement node
				var scrollDiv = document.createElement("div");
				scrollDiv.className = "scrollbar-measure";
				var dombody = document.body;
				if (dombody != null) {
					dombody.appendChild(scrollDiv);
					// Get the scrollbar width
					scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
					// Delete the DIV
					dombody.removeChild(scrollDiv);
				}
			}
			if (!isMobile) {
				forEachElement('.box-container', function(el, i) {
					if (!classie.hasClass(el, 'limit-width')) {
						var elWidth = outerWidth(el),
							newWidth = 12 * Math.ceil((wwidth - scrollbarWidth) / 12);
						boxWidth = newWidth;
						boxLeft = Math.ceil(((newWidth) - wwidth) / 2);
						el.style.width = boxWidth + 'px';
						el.style.marginLeft = '-' + (boxLeft + (scrollbarWidth / 2)) + 'px';
						if (mainmenu != undefined && mainmenu[0] != undefined) {
							mainmenu[0].style.width = newWidth + 'px';
						}
					}
				});
			}
		},
		fixMenuHeight = function() {
			if (!classie.hasClass(document.body, 'vmenu')) noScroll = true;
			menuwrapper = document.querySelectorAll(".menu-wrapper");
			masthead = document.getElementById("masthead");
			menuhide = document.querySelector('#masthead .menu-hide');
			menusticky = document.querySelectorAll('.menu-sticky');
			transmenuel = document.querySelectorAll('.menu-transparent:not(.vmenu-container)');
			var menuItemsButton = document.querySelectorAll('.menu-item-button .menu-btn-table');
			logo = document.querySelector('#main-logo');
			if (logo != undefined) logolink = (logo.firstElementChild || logo.firstChild);
			if (logolink != undefined) logoMinScale = logolink.getAttribute("data-minheight");
			logoel = document.querySelectorAll('.menu-shrink .logo-container');
			mainmenu = (wwidth > mediaQuery) ? document.querySelectorAll('.menu-primary .menu-container') : document.querySelectorAll('.menu-primary .menu-container, .vmenu-container .logo-container');
			secmenu = document.querySelectorAll('.menu-secondary');
			calculateMenuHeight(true);
			for (var k = 0; k < menuItemsButton.length; k++) {
				var a_item = menuItemsButton[k].parentNode,
					buttonHeight = outerHeight(menuItemsButton[k]);
				a_item.style.height = buttonHeight + 'px';
			}
		},
		calculateMenuHeight = function(first) {
			menuHeight = transmenuHeight = secmenuHeight = 0;
			for (var i = 0; i < mainmenu.length; i++) {
				menuHeight = menuHeight + outerHeight(mainmenu[i]);
				if (isIE && first) {
					getDivChildren(mainmenu[i], '.menu-horizontal-inner', function(innerMenu, i) {
						innerMenu.style.height = menuHeight + 'px';
					});
				}

				if (classie.hasClass(mainmenu[i].parentNode, 'menu-transparent')) {
					transmenuHeight += menuHeight;
				}
			}
			for (var j = 0; j < secmenu.length; j++) {
				secmenuHeight = outerHeight(secmenu[j]);
			}
			menuHeight += secmenuHeight;
			if (masthead != undefined && first) {
				if (wwidth > mediaQuery) masthead.parentNode.style.height = menuHeight + 'px';
			}
			if (classie.hasClass(document.documentElement, 'admin-mode')) menuHeight += 32;
			UNCODE.menuHeight = menuHeight;
		},
		initHeader = function() {
			UNCODE.adaptive();
			headerHeight('.header-wrapper');
			parallaxHeaders = document.querySelectorAll('.header-parallax > .header-bg-wrapper > .header-bg');
			header = document.querySelectorAll('.header-wrapper.header-uncode-block, .header-wrapper.header-revslider, .header-basic .header-wrapper, .header-uncode-block > .row-container:first-child > .row > .row-inner > .col-lg-12 > .uncol, .header-uncode-block .uncode-slider .owl-carousel > .row-container:first-child .col-lg-12 .uncoltable');
			headerWithOpacity = document.querySelectorAll('.header-scroll-opacity');
			pageHeader = document.getElementById("page-header");
			if (pageHeader != undefined) {
				var backs = pageHeader.querySelectorAll('.header-bg'),
					backsCarousel = pageHeader.querySelectorAll('.header-uncode-block .background-inner'),
					uri_pattern = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;
				if (backs.length == 0 && backsCarousel.length == 0) {
					pageHeader.setAttribute('data-imgready', 'true');
				} else {
					if (backsCarousel.length) {
						for (var j = 0; j < backsCarousel.length; j++) {
							if (j == 0) {
								if (!!backsCarousel[j].style.backgroundImage && backsCarousel[j].style.backgroundImage !== void 0) {
									var url = (backsCarousel[j].style.backgroundImage).match(uri_pattern),
										image = new Image();
									image.onload = function() {
										pageHeader.setAttribute('data-imgready', 'true');
									};
									image.src = url[0];
								} else {
									pageHeader.setAttribute('data-imgready', 'true');
								}
							}
						}
					} else {
						for (var i = 0; i < backs.length; i++) {
							if (i == 0) {
								if (!!backs[i].style.backgroundImage && backs[i].style.backgroundImage !== void 0) {
									var url = (backs[i].style.backgroundImage).match(uri_pattern),
										image = new Image();
									image.onload = function() {
										pageHeader.setAttribute('data-imgready', 'true');
									};
									image.src = url[0];
								} else {
									pageHeader.setAttribute('data-imgready', 'true');
								}
							}
						}
					}
				}
			}
			if (masthead != undefined) {
				if (header.length) {
					classie.addClass(menuwrapper[0], 'with-header');
					for (var j = 0; j < header.length; j++) {
						var headerel = header[j],
							closestStyle = getClosest(headerel, 'style-light');
						if (closestStyle != null && classie.hasClass(closestStyle, 'style-light')) switchColorsMenu(0, 'light');
						else if (getClosest(headerel, 'style-dark') != null) switchColorsMenu(0, 'dark');
						else {
							if (masthead.style.opacity !== 1) masthead.style.opacity = 1;
						}
						if (classie.hasClass(masthead, 'menu-transparent')) {
							masthead.parentNode.style.height = '0px';
							if (wwidth > mediaQuery) {
								if (classie.hasClass(masthead, 'menu-add-padding')) {
									var headerBlock = getClosest(headerel, 'header-uncode-block');
									if (headerBlock != null) {
										var innerRows = headerel.querySelectorAll('.column_parent > .uncol > .uncoltable > .uncell > .uncont, .uncode-slider .column_child > .uncol > .uncoltable > .uncell > .uncont');
										for (var k = 0; k < innerRows.length; k++) {
											if (innerRows[k] != undefined) {
												innerRows[k].style.paddingTop = transmenuHeight + 'px';
											}
										}
									} else {
										getDivChildren(headerel, '.header-content', function(headerContent, i) {
											headerContent.style.paddingTop = transmenuHeight + 'px';
										});
									}
								}
							}
						}
					}
				} else {
					classie.addClass(menuwrapper[0], 'no-header');
					classie.removeClass(masthead, 'menu-transparent');
					transmenuHeight = 0;
				}
			}
			bodyTop = document.documentElement['scrollTop'] || document.body['scrollTop'];
			if (wwidth > mediaQuery) scrollFunction();
			showHideScrollup(bodyTop);
		},
		initRow = function(currentRow) {
			UNCODE.adaptive();
			var el = currentRow.parentNode.parentNode.getAttribute("data-parent") == 'true' ? currentRow.parentNode : currentRow.parentNode.parentNode,
				rowParent = el.parentNode,
				rowInner = currentRow.parentNode,
				percentHeight = el.getAttribute("data-height-ratio"),
				minHeight = el.getAttribute("data-minheight"),
				calculateHeight,
				calculatePadding = 0,
				isHeader = false,
				isFirst = false,
				uri_pattern = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;

			/** Add class to the row when contains responsive column size */
			getDivChildren(el.parentNode, '.column_parent, .column_child', function(obj, i, total) {
				if ((obj.className).indexOf("col-md-") > - 1) classie.addClass(obj.parentNode, 'cols-md-responsive');
			});

			setRowHeight(el);

			var elements = 0;
			getDivChildren(el, '.row-internal .background-inner', function(obj, i, total) {
				elements++;
				if (i == 0) {
					if (!!obj.style.backgroundImage && obj.style.backgroundImage !== void 0) {
						var url = (obj.style.backgroundImage).match(uri_pattern),
							image = new Image();
						image.onload = function() {
							el.setAttribute('data-imgready', 'true');
							el.dispatchEvent(new CustomEvent('imgLoaded'));
						};
						image.src = url[0];
					} else {
						el.setAttribute('data-imgready', 'true');
						el.dispatchEvent(new CustomEvent('imgLoaded'));
					}
				}
			});
			if (elements == 0) {
				el.setAttribute('data-imgready', 'true');
			}

			/** init parallax is not mobile */
			if (!UNCODE.isMobile) {
				parallaxRows = el.parentNode.parentNode.querySelectorAll('.with-parallax > .row-background > .background-wrapper');
				parallaxCols = el.querySelectorAll('.with-parallax > .column-background > .background-wrapper');
				bodyTop = document.documentElement['scrollTop'] || document.body['scrollTop'];
				parallaxRowCol(bodyTop);
			}
		},
		setRowHeight = function(container, forced) {
			var currentTallest = 0,
				percentHeight = 0,
				minHeight = 0,
				el,
				child,
				hasSubCols = false;
			if (container.length == undefined) {
				container = [container];
			}
			// Loop for each container element to match their heights
			for (var i = 0; i < container.length; i++) {
				var el = container[i],
					$row = el,
					totalHeight = 0,
					colsArray = new Array(),
					calculatePadding = 0,
					$rowParent = $row.parentNode,
					isHeader = false,
					isFirst = false;
				$row.oversized = false;
				percentHeight = el.getAttribute("data-height-ratio");
				minHeight = el.getAttribute("data-minheight");
				child = (el.firstElementChild || el.firstChild);
				var childHeight = outerHeight(child);
				/** window height without header **/
				if (!!percentHeight || !!minHeight || forced || (isIE && classie.hasClass(el, 'unequal'))) {
					child.style.height = '';
					if (!!percentHeight) {
						if (percentHeight == 'full') {
							currentTallest = parseInt(wheight);
						} else {
							currentTallest = parseInt((wheight * percentHeight) / 100);
						}
					} else {
						currentTallest = el.clientHeight;
					}

					if (!!minHeight) {
						if (currentTallest < minHeight || currentTallest == undefined) currentTallest = parseInt(minHeight);
					}

					var computedStyleRow = getComputedStyle(el),
						computedStyleRowParent = getComputedStyle($rowParent);
					calculatePadding -= (parseFloat(computedStyleRow.paddingTop) + parseFloat(computedStyleRowParent.paddingTop));
					calculatePadding -= (parseFloat(computedStyleRow.paddingBottom) + parseFloat(computedStyleRowParent.paddingBottom));
					if (getClosest(el, 'header-uncode-block') != null) {
						el.setAttribute('data-row-header', 'true');
						isHeader = true;
					} else {
						if (pageHeader == null) {
							var prevRow = $rowParent.previousSibling;
							if (prevRow != null && prevRow.innerText == 'UNCODE.initHeader();') {
								isFirst = true;
							}
						}
					}

					if (classie.hasClass(el, 'row-slider')) {
						percentHeight = el.getAttribute("data-height-ratio");
						minHeight = el.getAttribute("data-minheight");
						if (percentHeight == 'full') {
							currentTallest = parseInt(wheight);
						} else {
							currentTallest = parseInt((wheight * percentHeight) / 100);
						}

						if (isHeader || isFirst) {
							if (wwidth > mediaQuery) currentTallest -= menuHeight - transmenuHeight;
							else currentTallest -= menuHeight - secmenuHeight;
							currentTallest += calculatePadding;
						} else {
							if (wwidth > mediaQuery) currentTallest += calculatePadding;
							else currentTallest = 'auto';
						}
						getDivChildren(el, '.owl-carousel', function(owl, i) {
							owl.style.height = (currentTallest == 'auto' ? 'auto' : currentTallest + 'px');
							if (isIE) {
								getDivChildren(owl, '.owl-stage', function(owlIn, i) {
									owlIn.style.height = (currentTallest == 'auto' ? '100%' : currentTallest + 'px');
								});
							}
						});
						continue;
					} else {
						if (isHeader || isFirst) {
							if (wwidth > mediaQuery) currentTallest -= menuHeight - transmenuHeight;
							else currentTallest -= menuHeight - secmenuHeight;
							currentTallest += calculatePadding;
						} else {
							if (wwidth > mediaQuery) currentTallest += calculatePadding;
							else currentTallest = 'auto';
						}
					}
					if (!!minHeight) {
						if (currentTallest < minHeight || currentTallest == 'auto') currentTallest = parseInt(minHeight);
					}

					child.style.height = (currentTallest == 'auto' ? 'auto' : currentTallest + 'px');
				} else {
					currentTallest = 0;
				}

				if (wwidth > mediaQuery) {

					getDivChildren(el, '.column_parent', function(col, i, total) {
						var $col = col,
							$colHeight = 0,
							$colDiff = 0,
							$colPercDiff = 100;
						$col.oversized = false;
						$col.forceHeight = currentTallest;
						currentTallest = child.clientHeight;
						if ((isHeader || isFirst) && currentTallest != 'auto') currentTallest -= transmenuHeight;
						var getFirstCol = null;
						var getMargin = 0;
						getDivChildren(col, '.row-child', function(obj, i, total) {
							var $colChild = obj,
								$colInner = $colChild.children[0],
								$colParent = $colChild.parentNode,
								$uncont = $colParent.parentNode;
							if (i == 0 && total > 1) getFirstCol = $colInner;
							$colChild.oversized = false;
							percentHeight = $colChild.getAttribute("data-height");
							minHeight = $colChild.getAttribute("data-minheight");
							if (percentHeight != null || minHeight != null) {
								$colInner.style.height = '';
								$colParent.style.height = 'auto';
								$uncont.style.height = '100%';
								$colChild.removeAttribute("style");
								var newHeight = (percentHeight != null) ? Math.ceil((currentTallest) * (percentHeight / 100)) : parseInt(minHeight);
								var computedStyleCol = getComputedStyle($colParent);
								parseFloat(computedStyleCol.marginTop);
								getMargin = parseFloat(computedStyleCol.marginTop);
								newHeight -= (getMargin);
								if (currentTallest > newHeight) {
									var getColHeight = outerHeight($colChild);
									if (getColHeight > newHeight) {
										$colHeight += getColHeight;
										$colDiff += getColHeight;
										$colPercDiff -= (percentHeight != null) ? percentHeight : 0;
										$colChild.oversized = true;
										$col.oversized = true;
										$row.oversized = true;
									} else {
										$colHeight += newHeight;
										$colInner.style.height = newHeight + 'px';
									}
								}
							} else {
								$colHeight += outerHeight($colChild);
							}
						});
						if (getFirstCol != null) {
							getFirstCol.style.height = (parseFloat(getFirstCol.style.height) - getMargin) + 'px';
						}
						colsArray.push({
							colHeight: $colHeight,
							colDiv: $col
						});
						$col.colDiff = $colDiff;
						$col.colPercDiff = $colPercDiff;
					});

					if ($row.oversized) {
						child.style.height = '';
						colsArray.sort(function(a, b) {
							if (a.colHeight < b.colHeight) return 1;
							if (a.colHeight > b.colHeight) return -1;
							return 0;
						});
						var $totalHeight = 0;
						colsArray.forEach(function(col) {
							var $col = col.colDiv,
								$colHeight = col.colHeight;
							getDivChildren($col, '.row-child', function(obj, i, total) {
								var $colChild = obj,
									$colInner = $colChild.children[0],
									percentHeight = $colChild.getAttribute("data-height"),
									$colParent = $colChild.parentNode,
									$uncont = $colParent.parentNode,
									newHeight;
								$colHeight = $col.forceHeight - $col.colDiff;
								if (percentHeight != null) {
									if ($colHeight > 0) {
										if ($col.oversized) {
											if (!$colChild.oversized) {
												newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
												if (i == total - 1 && total > 1) {
													$uncont.style.height = 'auto';
													$colChild.style.display = 'none';
													newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
													$uncont.style.height = '100%';
													$colChild.style.display = 'table';
												}
												if (newHeight == 0) newHeight = Math.ceil(($col.forceHeight) * (percentHeight / 100));
												$colInner.style.height = newHeight + 'px';
											}
										} else {
											if ($totalHeight == 0) newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
											else {
												newHeight = Math.ceil(($totalHeight) * (percentHeight / $col.colPercDiff));
											}
											if (i == total - 1 && total > 1) {
												$uncont.style.height = 'auto';
												$colChild.style.display = 'none';
												newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
												$uncont.style.height = '100%';
												$colChild.style.display = 'table';
											}
											$colInner.style.height = newHeight + 'px';
										}
									} else {
										if ($colChild.oversized) {
											if ($totalHeight == 0) newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
											else {
												if ($col.colPercDiff == 0) $col.colPercDiff = 100;
												newHeight = Math.ceil(($totalHeight) * (percentHeight / $col.colPercDiff));
											}
											if (i == total - 1 && total > 1) {
												$uncont.style.height = 'auto';
												$colChild.style.display = 'none';
												newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
												$uncont.style.height = '100%';
												$colChild.style.display = 'table';
											}
											$colInner.style.height = newHeight + 'px';
										}
									}
								}
							});
							var uncell = $col.getElementsByClassName('uncell');
							if (uncell[0] != undefined && $totalHeight == 0) $totalHeight = outerHeight(uncell[0]);
						});
					}
					if (isFF) {
						getDivChildren(el, '.uncoltable', function(col, i, total) {
							if (col.style.minHeight != '') {
								col.style.height = '';
							}
						});
					}
					getDivChildren(el, '.row-child > .row-inner', function(obj, k, total) {
						if (obj.style.height == '') {
							if (wwidth > mediaQueryMobile) {
								var getStyle = (window.getComputedStyle((obj.parentNode), null)),
								getInnerHeight = (parseInt(getStyle.height) - parseInt(getStyle.paddingTop) - parseInt(getStyle.paddingBottom));
								obj.style.height = getInnerHeight + 1 + 'px';
								obj.style.marginBottom = '-1px';
							}
						}
					});
				} else {
					if (isFF) {
						getDivChildren(el, '.uncoltable', function(col, i, total) {
							if (col.style.minHeight != '') {
								col.style.height = '';
								col.style.height = outerHeight(col.parentNode) + 'px';
							}
						});
					}
					if (isIE && (wwidth > mediaQueryMobile)) {
						if (child.style.height == 'auto') {
							child.style.height = outerHeight(child) + 'px';
						}
					}
				}
				if (isFF) {
					var sliderColumnFix = document.querySelector('.uncode-slider .row-inner > .column_child:only-child');
					if (sliderColumnFix != null) {
						if (wwidth > mediaQuery) {
							sliderColumnFix.style.setProperty("height", "");
						} else {
							sliderColumnFix.style.setProperty("height", "");
							sliderColumnFix.style.setProperty("height", outerHeight(sliderColumnFix.parentNode) + "px", "important");
						}
					}
				}
			};
		},
		headerHeight = function(container) {
			forEachElement(container, function(el, i) {
				var getHeight = el.getAttribute("data-height"),
					newHeight = ((wheight * getHeight) / 100);
				if (getHeight != 'fixed' && newHeight != 0) {
					if (wwidth > mediaQuery) newHeight -= menuHeight - transmenuHeight;
					else newHeight -= menuHeight - secmenuHeight;
					el.style.height = newHeight + 'px';
				}
			});
			if (masthead != undefined) {
				if (header != undefined && header.length) {
					if (classie.hasClass(masthead, 'menu-transparent')) {
						if (wwidth > mediaQuery) {
							if (classie.hasClass(masthead, 'menu-add-padding')) {
								for (var j = 0; j < header.length; j++) {
									var headerel = header[j];
									var headerBlock = getClosest(headerel, 'header-uncode-block');
									if (headerBlock != null) {
										var innerRows = headerel.querySelectorAll('.column_parent > .uncol > .uncoltable > .uncell > .uncont, .uncode-slider .column_child > .uncol > .uncoltable > .uncell > .uncont');
										for (var k = 0; k < innerRows.length; k++) {
											if (innerRows[k] != undefined) {
												innerRows[k].style.paddingTop = transmenuHeight + 'px';
											}
										}
									} else {
										getDivChildren(headerel, '.header-content', function(headerContent, i) {
											headerContent.style.paddingTop = transmenuHeight + 'px';
										});
									}
								}
							}
						}
					}
				}
			}
		},
		initVideoComponent = function(container, classTarget) {
			getDivChildren(container, classTarget, function(el, i) {
				var width = outerWidth(el),
					pWidth, // player width, to be defined
					height = outerHeight(el),
					pHeight, // player height, tbd
					$tubularPlayer = (el.getElementsByTagName('iframe').length == 1) ? el.getElementsByTagName('iframe') : el.getElementsByTagName('video'),
					ratio = (el.getAttribute("data-ratio") != null) ? Number(el.getAttribute("data-ratio")) : null,
					heightOffset = 80,
					widthOffset = heightOffset * ratio;
				// when screen aspect ratio differs from video, video must center and underlay one dimension
				if ($tubularPlayer[0] != undefined) {
					if (width / ratio < height) { // if new video height < window height (gap underneath)
						pWidth = Math.ceil((height + heightOffset) * ratio); // get new player width
						$tubularPlayer[0].style.width = pWidth + widthOffset + 'px';
						$tubularPlayer[0].style.height = height + heightOffset + 'px';
						$tubularPlayer[0].style.left = ((width - pWidth) / 2) - (widthOffset / 2) + 'px';
						$tubularPlayer[0].style.top = '-' + (heightOffset / 2) + 'px';
						$tubularPlayer[0].style.position = 'absolute';
					} else { // new video width < window width (gap to right)
						pHeight = Math.ceil(width / ratio); // get new player height
						$tubularPlayer[0].style.width = width + widthOffset + 'px';
						$tubularPlayer[0].style.height = pHeight + heightOffset + 'px';
						$tubularPlayer[0].style.left = '-' + (widthOffset / 2) + 'px';
						$tubularPlayer[0].style.top = ((height - pHeight) / 2) - (heightOffset / 2) + 'px';
						$tubularPlayer[0].style.position = 'absolute';
					}
				}
			});
		},
		init_overlay = function() {
			var triggerButton,
			closeButton;
			function toggleOverlay(btn) {
				if (!classie.hasClass(triggerButton, 'search-icon')) {
					if (classie.hasClass(triggerButton, 'close')) {
						classie.removeClass(closeButton, 'close');
						classie.removeClass(triggerButton, 'close');
						classie.addClass(closeButton, 'closing');
						classie.addClass(triggerButton, 'closing');
						setTimeout(function() {
							classie.removeClass(closeButton, 'closing');
							classie.removeClass(triggerButton, 'closing');
							triggerButton.style.opacity = 1;
							closeButton.style.opacity = 0;
						}, 800);
					} else {
						var getBtnRect = triggerButton.getBoundingClientRect();
						closeButton.parentNode.setAttribute('style', 'top:' + getBtnRect.top + 'px; left:'+getBtnRect.left + 'px !important');
						classie.addClass(closeButton, 'close');
						classie.addClass(triggerButton, 'close');
						triggerButton.style.opacity = 0;
						closeButton.style.opacity = 1;
					}
				}
				Array.prototype.forEach.call(document.querySelectorAll('div.overlay'), function(overlay) {
					if (btn.getAttribute('data-area') == overlay.getAttribute('data-area')) {
						var container = document.querySelector('div.' + btn.getAttribute('data-container')),
							inputField = overlay.querySelector('.search-field');
						if (classie.has(overlay, 'open')) {
							classie.remove(overlay, 'open');
							classie.remove(container, 'overlay-open');
							classie.add(overlay, 'close');
							classie.remove(overlay, 'open-items');
							var onEndTransitionFn = function(ev) {
								if (transitionEvent) {
									if (ev.propertyName !== 'visibility') return;
									this.removeEventListener(transitionEvent, onEndTransitionFn);
								}
								classie.remove(overlay, 'close');
							};
							if (transitionEvent) {
								overlay.addEventListener(transitionEvent, onEndTransitionFn);
							} else {
								onEndTransitionFn();
							}
						} else if (!classie.has(overlay, 'close')) {
							classie.add(overlay, 'open');
							classie.add(container, 'overlay-open');
							if (jQuery('body.menu-overlay').length == 0) {
								setTimeout(function() {
									inputField.focus();
								}, 1000);
							}
							setTimeout(function() {
								if (classie.has(overlay, 'overlay-sequential')) classie.add(overlay, 'open-items');
							}, 800);
						}
					}
				});
			}
			Array.prototype.forEach.call(document.querySelectorAll('.trigger-overlay'), function(triggerBttn) {
				triggerButton = triggerBttn;
				triggerBttn.addEventListener('click', function(e) {
					if (wwidth > mediaQuery) toggleOverlay(triggerBttn);
					e.preventDefault();
					return false;
				}, false);
			});
			Array.prototype.forEach.call(document.querySelectorAll('.overlay-close'), function(closeBttn) {
				closeButton = closeBttn;
				closeBttn.addEventListener('click', function(e) {
					if (wwidth > mediaQuery) toggleOverlay(closeBttn);
					e.preventDefault();
					return false;
				}, false);
			});
		},
		/** All scrolling functions - Begin */
		/** Shrink menu **/
		shrinkMenu = function(bodyTop) {
			var logoShrink,
				offset = 100;
			for (var i = 0; i < logoel.length; i++) {
				if (((secmenuHeight == 0) ? bodyTop > menuHeight : bodyTop > secmenuHeight + offset) && !classie.hasClass(logoel[i], 'shrinked')) {
					classie.addClass(logoel[i], 'shrinked');
					if (logoMinScale != undefined) {
						logoShrink = logolink.children;
						Array.prototype.forEach.call(logoShrink, function(singleLogo) {
							singleLogo.style.height = logoMinScale + 'px';
							singleLogo.style.lineHeight = logoMinScale + 'px';
							if (classie.hasClass(singleLogo, 'text-logo')) singleLogo.style.fontSize = logoMinScale + 'px';
						});
					}
				} else if (((secmenuHeight == 0) ? bodyTop == 0 : bodyTop <= secmenuHeight + offset) && classie.hasClass(logoel[i], 'shrinked')) {
					classie.removeClass(logoel[i], 'shrinked');
					if (logoMinScale != undefined) {
						logoShrink = logolink.children;
						Array.prototype.forEach.call(logoShrink, function(singleLogo) {
							singleLogo.style.height = singleLogo.getAttribute('data-maxheight') + 'px';
							singleLogo.style.lineHeight = singleLogo.getAttribute('data-maxheight') + 'px';
							if (classie.hasClass(singleLogo, 'text-logo')) singleLogo.style.fontSize = singleLogo.getAttribute('data-maxheight') + 'px';
						});
					}
				}
			}
		},
		/** Switch colors menu **/
		switchColorsMenu = function(bodyTop, style) {
			for (var i = 0; i < transmenuel.length; i++) {
				if (masthead.style.opacity !== 1) masthead.style.opacity = 1;
				if ((secmenuHeight == 0) ? bodyTop > menuHeight / 2 : bodyTop > secmenuHeight) {
					if (classie.hasClass(masthead, 'style-dark-original')) {
						logo.className = logo.className.replace("style-light", "style-dark");
					}
					if (classie.hasClass(masthead, 'style-light-original')) {
						logo.className = logo.className.replace("style-dark", "style-light");
					}
					if (style != undefined) {
						if (style == 'dark') {
							classie.removeClass(transmenuel[i], 'style-light-override');
						}
						if (style == 'light') {
							classie.removeClass(transmenuel[i], 'style-dark-override');
						}
						classie.addClass(transmenuel[i], 'style-' + style + '-override');
					}
				} else {
					if (style != undefined) {
						if (style == 'dark') {
							classie.removeClass(transmenuel[i], 'style-light-override');
						}
						if (style == 'light') {
							classie.removeClass(transmenuel[i], 'style-dark-override');
						}
						classie.addClass(transmenuel[i], 'style-' + style + '-override');
					}
				}
			}
			if (pageHeader != undefined) {
				if (style != undefined) {
					if (classie.hasClass(pageHeader, 'header-style-dark')) {
						classie.removeClass(pageHeader, 'header-style-dark');
					}
					if (classie.hasClass(pageHeader, 'header-style-light')) {
						classie.removeClass(pageHeader, 'header-style-light');
					}
					classie.addClass(pageHeader, 'header-style-' + style);
				}
			}
		},
		/** Parallax Rows **/
		parallaxRowCol = function(bodyTop) {
			var value;
			if (typeof parallaxRows == 'object') {
				for (var i = 0; i < parallaxRows.length; i++) {
					var section = parallaxRows[i].parentNode,
						thisHeight = outerHeight(parallaxRows[i]),
						sectionHeight = outerHeight(section),
						offSetTop = bodyTop + (section != null ? (classie.hasClass(section.parentNode.parentNode, 'owl-carousel') ? section.parentNode.parentNode.getBoundingClientRect().top : section.getBoundingClientRect().top) : 0),
						offSetPosition = wheight + bodyTop - offSetTop;
					if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
						value = ((offSetPosition - wheight) * speedDivider);
						if (Math.abs(value) < (thisHeight - sectionHeight)) {
							translateElement(parallaxRows[i], value);
						} else {
							translateElement(parallaxRows[i], thisHeight - sectionHeight);
						}
					}
				}
			}
			if (typeof parallaxCols == 'object') {
				for (var j = 0; j < parallaxCols.length; j++) {
					var section = parallaxCols[j].parentNode,
						thisHeight = outerHeight(parallaxCols[j]),
						sectionHeight = outerHeight(section),
						offSetTop = bodyTop + (section != null ? section.getBoundingClientRect().top : 0),
						offSetPosition = wheight + bodyTop - offSetTop;
					if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
						value = ((offSetPosition - wheight) * speedDivider);
						value *= .8;
						if (Math.abs(value) < (thisHeight - sectionHeight)) {
							translateElement(parallaxCols[j], value);
						} else {
							translateElement(parallaxCols[j], thisHeight - sectionHeight);
						}
					}
				}
			}
		},
		/** Parallax Headers **/
		parallaxHeader = function(bodyTop) {
			var value;
			if (typeof parallaxHeaders == 'object') {
				for (var i = 0; i < parallaxHeaders.length; i++) {
					var section = parallaxHeaders[i].parentNode,
						thisSibling = section.nextSibling,
						thisHeight,
						sectionHeight,
						offSetTop,
						offSetPosition;
					if (classie.hasClass(parallaxHeaders[i], 'header-carousel-wrapper')) {
						getDivChildren(parallaxHeaders[i], '.t-background-cover', function(item, l, total) {
							thisHeight = outerHeight(item);
							sectionHeight = outerHeight(section);
							offSetTop = bodyTop + section.getBoundingClientRect().top;
							offSetPosition = wheight + bodyTop - offSetTop;
							if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
								value = ((offSetPosition - wheight) * speedDivider);
								if (Math.abs(value) < (thisHeight - sectionHeight)) {
									translateElement(item, value);
								}
							}
						});
					} else {
						thisHeight = outerHeight(parallaxHeaders[i]);
						sectionHeight = outerHeight(section);
						offSetTop = bodyTop + section.getBoundingClientRect().top;
						offSetPosition = wheight + bodyTop - offSetTop;
						if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
							value = ((offSetPosition - wheight) * speedDivider);
							if (Math.abs(value) < (thisHeight - sectionHeight)) {
								translateElement(parallaxHeaders[i], value);
							}
						}
					}
				}
			}
		},
		/** Header opacity **/
		headerOpacity = function(bodyTop) {
			if (headerWithOpacity && headerWithOpacity.length) {
				var thisHeight = outerHeight(headerWithOpacity[0]);
				if (bodyTop > thisHeight / 8) {
					if (pageHeader != undefined) classie.addClass(pageHeader, 'header-scrolled');
				} else {
					if (pageHeader != undefined) classie.removeClass(pageHeader, 'header-scrolled');
				}
			}
		},
		/** Show hide scroll top arrow **/
		showHideScrollup = function(bodyTop) {
			if (bodyTop != 0) {
				if (bodyTop > wheight || ((bodyTop + wheight) >= docheight) && docheight > 0) {
					classie.addClass(document.body, 'window-scrolled');
					classie.removeClass(document.body, 'hide-scrollup');
					if (footerScroller && footerScroller[0] != undefined) {
						footerScroller[0].style.display = '';
					}
				} else {
					if (classie.hasClass(document.body, 'window-scrolled')) classie.addClass(document.body, 'hide-scrollup');
					classie.removeClass(document.body, 'window-scrolled');
				}
			}
		},
		/** Hide Menu **/
		hideMenu = function(bodyTop) {
			if (typeof menuhide == 'object' && menuhide != null) {
				var translate;
				if (lastScrollValue > bodyTop) {
					if (!UNCODE.scrolling) {
						if (classie.hasClass(menuhide, 'menu-hided')) {
							classie.removeClass(menuhide, 'menu-hided');
							translateElement(menuhide, 0);
							if (mainmenu[0].style.position != 'fixed') {
								classie.addClass(mainmenu[0].parentNode, 'is_stuck');
								mainmenu[0].style.position = 'fixed';
								mainmenu[0].style.top = '0';
								if (!classie.hasClass(document.body, 'boxed-width')) mainmenu[0].style.width = boxWidth + 'px';
							}
						} else {
							if ((secmenuHeight == 0) ? bodyTop == 0 : bodyTop == secmenuHeight) {
								if (mainmenu[0].style.position == 'fixed') {
									classie.removeClass(mainmenu[0].parentNode, 'is_stuck');
									mainmenu[0].style.position = '';
									mainmenu[0].style.top = '';
								}
							}
						}
					}
				} else if (lastScrollValue < bodyTop) {
					if (bodyTop > wheight / 2 || UNCODE.scrolling) {
						if (!classie.hasClass(menuhide, 'menu-hided')) {
							classie.addClass(menuhide, 'menu-hided');
							translateElement(menuhide, -menuHeight);
						}
					}
				}
				lastScrollValue = bodyTop;
			}
		},
		/** Stick Menu **/
		stickMenu = function(bodyTop) {
			if (header) {
				if ((secmenuHeight == 0) ? bodyTop > 0 : bodyTop > secmenuHeight) {
					if (mainmenu[0].style.position != 'fixed') {
						classie.addClass(mainmenu[0].parentNode, 'is_stuck');
						mainmenu[0].style.position = 'fixed';
						if (document.documentElement.style.marginTop !== '') mainmenu[0].style.top = document.documentElement.style.marginTop;
						else mainmenu[0].style.top = '0';
						if (!classie.hasClass(document.body, 'boxed-width')) mainmenu[0].style.width = boxWidth + 'px';
					}
				} else {
					if (mainmenu[0].style.position != 'absolute') {
						classie.removeClass(mainmenu[0].parentNode, 'is_stuck');
						mainmenu[0].style.position = 'absolute';
						mainmenu[0].style.top = '';
					}
				}
			}
		},
		translateElement = function(element, valueY) {
			var translate = 'translate3d(0, ' + valueY + 'px' + ', 0)';
			element.style['-webkit-transform'] = translate;
			element.style['-moz-transform'] = translate;
			element.style['-ms-transform'] = translate;
			element.style['-o-transform'] = translate;
			element.style['transform'] = translate;
		},
		scrollFunction = function() {
			if (logoel != undefined && logoel.length) shrinkMenu(bodyTop);
			if (menusticky != undefined && menusticky.length && !isMobile) stickMenu(bodyTop);
			if (!isMobile) hideMenu(bodyTop);
			if (header && menusticky != undefined && menusticky.length) switchColorsMenu(bodyTop);
			parallaxRowCol(bodyTop);
			parallaxHeader(bodyTop);
			headerOpacity(bodyTop);
		};
	if (!noScroll) {
		window.addEventListener('scroll', function(e) {
			bodyTop = document.documentElement.scrollTop || document.body.scrollTop;
			if (wwidth > mediaQuery && !isMobile) {
				scrollFunction();
			}
			showHideScrollup(bodyTop);
		}, false);
	}
	/** All scrolling functions - End */
	/** help functions */
	function getClosest(el, tag) {
		do {
			if (el.className != undefined && el.className.indexOf(tag) > -1) return el;
		} while (el = el.parentNode);
		// not found :(
		return null;
	}

	function outerHeight(el, includeMargin) {
		if (el != null) {
			var height = el.offsetHeight;
			if (includeMargin) {
				var style = el.currentStyle || getComputedStyle(el);
				height += parseInt(style.marginTop) + parseInt(style.marginBottom);
			}
			return height;
		}
	}

	function outerWidth(el, includeMargin) {
			var width = el.offsetWidth;
			if (includeMargin) {
				var style = el.currentStyle || getComputedStyle(el);
				width += parseInt(style.marginLeft) + parseInt(style.marginRight);
			}
			return width;
		}
		// Replicate jQuery .each method
	function forEachElement(selector, fn) {
		var elements = document.querySelectorAll(selector);
		for (var i = 0; i < elements.length; i++) fn(elements[i], i);
	}

	function getDivChildren(containerId, selector, fn) {
		if (containerId !== null) {
			var elements = containerId.querySelectorAll(selector);
			for (var i = 0; i < elements.length; i++) fn(elements[i], i, elements.length);
		}
	}

	function hideFooterScroll() {
		if (classie.hasClass(document.body, 'hide-scrollup')) footerScroller[0].style.display = "none";
	}
	document.addEventListener("DOMContentLoaded", function(event) {
		UNCODE.adaptive();
		boxWrapper = document.querySelectorAll('.box-wrapper');
		docheight = boxWrapper[0] != undefined ? boxWrapper[0].offsetHeight : 0;
		if (!classie.hasClass(document.body, 'vmenu') && !classie.hasClass(document.body, 'menu-offcanvas')) init_overlay();
		if (!UNCODE.isMobile) {
			parallaxRows = document.querySelectorAll('.with-parallax > .row-background > .background-wrapper');
			parallaxCols = document.querySelectorAll('.with-parallax > .column-background > .background-wrapper');
		}
		footerScroller = document.querySelectorAll('.footer-scroll-top');
		if (footerScroller && footerScroller[0] != undefined) {
			if (transitionEvent) {
				footerScroller[0].addEventListener(transitionEvent, hideFooterScroll);
			}
		}
		Array.prototype.forEach.call(document.querySelectorAll('.row-inner'), function(el) {
			el.style.height = '';
			el.style.marginBottom = '';
		});
		setRowHeight(document.querySelectorAll('.page-wrapper .row-parent'));
	});
	/** On resize events **/
	window.addEventListener("resize", function() {
		docheight = (boxWrapper != undefined && boxWrapper[0] != undefined) ? boxWrapper[0].offsetHeight : 0;
		var oldWidth = wwidth;
		wwidth = window.innerWidth || document.documentElement.clientWidth;
		wheight = window.innerHeight || document.documentElement.clientHeight;
		if (isMobile && (oldWidth == wwidth)) return false;
		initBox();
		headerHeight('.header-wrapper');
		window.dispatchEvent(boxEvent);
		clearTimeout(resizeTimer);
		resizeTimer = setTimeout(function() {
			Array.prototype.forEach.call(document.querySelectorAll('.row-inner'), function(el) {
				el.style.height = '';
				el.style.marginBottom = '';
			});
			setRowHeight(document.querySelectorAll('.page-wrapper .row-parent'));
		}, 500);

		if (!isMobile) {
			setTimeout(function() {
				initVideoComponent(document.body, '.uncode-video-container.video, .uncode-video-container.self-video');
			}, 100);
		}
		if (wwidth > mediaQuery) {
			scrollFunction();
		}
		showHideScrollup(bodyTop);
	});

	/**
	 * On DOM ready
	 */
	window.addEventListener("load", function(){
		if (!UNCODE.isMobile) {
			if (wwidth > mediaQuery) {
				scrollFunction();
			}
			setTimeout(function() {
				window.dispatchEvent(UNCODE.boxEvent);
				Waypoint.refreshAll();
			}, 2000);
		}
		showHideScrollup(bodyTop);
		calculateMenuHeight(false);
		jQuery(window).trigger('resize');
	}, false);

	var UNCODE = {
		boxEvent: boxEvent,
		initBox: initBox,
		menuHeight: 0,
		fixMenuHeight: fixMenuHeight,
		initHeader: initHeader,
		initRow: initRow,
		setRowHeight: setRowHeight,
		switchColorsMenu: switchColorsMenu,
		isMobile: isMobile,
		scrolling: false,
		mediaQuery: mediaQuery,
		initVideoComponent: initVideoComponent
	};
	// transport
	if (typeof define === 'function' && define.amd) {
		// AMD
		define(UNCODE);
	} else {
		// browser global
		window.UNCODE = UNCODE;
	}

	UNCODE.adaptive = function() {
		var images = new Array(),
			getImages = document.querySelectorAll('.adaptive-async:not(.adaptive-fetching)');
		for (var i = 0; i < getImages.length; i++) {
			var imageObj = {},
				el = getImages[i];
			classie.addClass(el, 'adaptive-fetching');
			imageObj.unique = el.getAttribute('data-uniqueid');
			imageObj.url = el.getAttribute('data-guid');
			imageObj.path = el.getAttribute('data-path');
			imageObj.singlew = el.getAttribute('data-singlew');
			imageObj.singleh = el.getAttribute('data-singleh');
			imageObj.origwidth = el.getAttribute('data-width');
			imageObj.origheight = el.getAttribute('data-height');
			imageObj.crop = el.getAttribute('data-crop');
			imageObj.screen = window.uncodeScreen;
			imageObj.images = window.uncodeImages;
			images.push(imageObj);
		}
		var jsonString = JSON.stringify(images);
		var data = new Array();
		data['action'] = 'get_adaptive_async';
		data['images'] = jsonString;
		data['cache'] = 'false';

		if (images.length > 0) {
			var xmlhttp;
			if (window.XMLHttpRequest) {
				// code for IE7+, Firefox, Chrome, Opera, Safari
				xmlhttp = new XMLHttpRequest();
			} else {
				// code for IE6, IE5
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			xmlhttp.onreadystatechange = function() {
				if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
					if(xmlhttp.status == 200){
						var images = JSON.parse(xmlhttp.responseText);
						for (var i = 0; i < images.length; i++) {
							var val = images[i],
								getImage = document.querySelectorAll('[data-uniqueid="'+val.unique+'"]');
							for (var j = 0; j < getImage.length; j++) {
								var attrScr = getImage[j].getAttribute('src'),
								replaceImg = new Image();
								replaceImg.source = attrScr;
								replaceImg.el = getImage[j];

								classie.removeClass(getImage[j], 'adaptive-async');
								classie.removeClass(getImage[j], 'adaptive-fetching');

								replaceImg.onload = function () {
									if (this.source !== null) {
										(this.el).src = this.src;
										// (this.el).removeAttribute('width');
										// (this.el).removeAttribute('height');
									} else {
										(this.el).style.backgroundImage = 'url("'+this.src+'")';
									}
									classie.addClass(this.el, 'async-done');
								}
								replaceImg.src = val.url;
							}
						}
					}
					else if(xmlhttp.status == 400) {
						console.log('There was an error 400')
					}
					else {
						console.log('something else other than 200 was returned')
					}
				}
			}
			//Serialize the data
	    var queryString = "",
	    	arrayLength = Object.keys(data).length,
	    	arrayCounter = 0;

	    for (var key in data) {
				queryString += key + "=" + data[key];
				if(arrayCounter < arrayLength - 1) {
					queryString += "&";
				}
				arrayCounter++;
			}

			xmlhttp.open("POST", SiteParameters.uncode_ajax, true);
			xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	    xmlhttp.send(queryString);

		}
	};

})(window);



/**
 * vivus - JavaScript library to make drawing animation on SVG
 * @version v0.3.0
 * @link https://github.com/maxwellito/vivus
 * @license MIT
 */

'use strict';

(function (window, document) {

  'use strict';

/**
 * Pathformer
 * Beta version
 *
 * Take any SVG version 1.1 and transform
 * child elements to 'path' elements
 *
 * This code is purely forked from
 * https://github.com/Waest/SVGPathConverter
 */

/**
 * Class constructor
 *
 * @param {DOM|String} element Dom element of the SVG or id of it
 */
function Pathformer(element) {
  // Test params
  if (typeof element === 'undefined') {
    throw new Error('Pathformer [constructor]: "element" parameter is required');
  }

  // Set the element
  if (element.constructor === String) {
    element = document.getElementById(element);
    if (!element) {
      throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
    }
  }
  if (element.constructor instanceof window.SVGElement || /^svg$/i.test(element.nodeName)) {
    this.el = element;
  } else {
    throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
  }

  // Start
  this.scan(element);
}

/**
 * List of tags which can be transformed
 * to path elements
 *
 * @type {Array}
 */
Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect'];

/**
 * List of attribute names which contain
 * data. This array list them to check if
 * they contain bad values, like percentage. 
 *
 * @type {Array}
 */
Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', 'y1', 'y2'];

/**
 * Finds the elements compatible for transform
 * and apply the liked method
 *
 * @param  {object} options Object from the constructor
 */
Pathformer.prototype.scan = function (svg) {
  var fn, element, pathData, pathDom,
    elements = svg.querySelectorAll(this.TYPES.join(','));
  for (var i = 0; i < elements.length; i++) {
    element = elements[i];
    fn = this[element.tagName.toLowerCase() + 'ToPath'];
    pathData = fn(this.parseAttr(element.attributes));
    pathDom = this.pathMaker(element, pathData);
    element.parentNode.replaceChild(pathDom, element);
  }
};


/**
 * Read `line` element to extract and transform
 * data, to make it ready for a `path` object.
 *
 * @param  {DOMelement} element Line element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.lineToPath = function (element) {
  var newElement = {};
  newElement.d = 'M' + element.x1 + ',' + element.y1 + 'L' + element.x2 + ',' + element.y2;
  return newElement;
};

/**
 * Read `rect` element to extract and transform
 * data, to make it ready for a `path` object.
 * The radius-border is not taken in charge yet.
 * (your help is more than welcomed)
 *
 * @param  {DOMelement} element Rect element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.rectToPath = function (element) {
  var newElement = {},
    x = parseFloat(element.x) || 0,
    y = parseFloat(element.y) || 0,
    width = parseFloat(element.width) || 0,
    height = parseFloat(element.height) || 0;
  newElement.d  = 'M' + x + ' ' + y + ' ';
  newElement.d += 'L' + (x + width) + ' ' + y + ' ';
  newElement.d += 'L' + (x + width) + ' ' + (y + height) + ' ';
  newElement.d += 'L' + x + ' ' + (y + height) + ' Z';
  return newElement;
};

/**
 * Read `polyline` element to extract and transform
 * data, to make it ready for a `path` object.
 *
 * @param  {DOMelement} element Polyline element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.polylineToPath = function (element) {
  var i, path;
  var newElement = {};
  var points = element.points.trim().split(' ');
  
  // Reformatting if points are defined without commas
  if (element.points.indexOf(',') === -1) {
    var formattedPoints = [];
    for (i = 0; i < points.length; i+=2) {
      formattedPoints.push(points[i] + ',' + points[i+1]);
    }
    points = formattedPoints;
  }

  // Generate the path.d value
  path = 'M' + points[0];
  for(i = 1; i < points.length; i++) {
    if (points[i].indexOf(',') !== -1) {
      path += 'L' + points[i];
    }
  }
  newElement.d = path;
  return newElement;
};

/**
 * Read `polygon` element to extract and transform
 * data, to make it ready for a `path` object.
 * This method rely on polylineToPath, because the
 * logic is similar. The path created is just closed,
 * so it needs an 'Z' at the end.
 *
 * @param  {DOMelement} element Polygon element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.polygonToPath = function (element) {
  var newElement = Pathformer.prototype.polylineToPath(element);
  newElement.d += 'Z';
  return newElement;
};

/**
 * Read `ellipse` element to extract and transform
 * data, to make it ready for a `path` object.
 *
 * @param  {DOMelement} element ellipse element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.ellipseToPath = function (element) {
  var startX = element.cx - element.rx,
      startY = element.cy;
  var endX = parseFloat(element.cx) + parseFloat(element.rx),
      endY = element.cy;

  var newElement = {};
  newElement.d = 'M' + startX + ',' + startY +
                 'A' + element.rx + ',' + element.ry + ' 0,1,1 ' + endX + ',' + endY +
                 'A' + element.rx + ',' + element.ry + ' 0,1,1 ' + startX + ',' + endY;
  return newElement;
};

/**
 * Read `circle` element to extract and transform
 * data, to make it ready for a `path` object.
 *
 * @param  {DOMelement} element Circle element to transform
 * @return {object}             Data for a `path` element
 */
Pathformer.prototype.circleToPath = function (element) {
  var newElement = {};
  var startX = element.cx - element.r,
      startY = element.cy;
  var endX = parseFloat(element.cx) + parseFloat(element.r),
      endY = element.cy;
  newElement.d =  'M' + startX + ',' + startY +
                  'A' + element.r + ',' + element.r + ' 0,1,1 ' + endX + ',' + endY +
                  'A' + element.r + ',' + element.r + ' 0,1,1 ' + startX + ',' + endY;
  return newElement;
};

/**
 * Create `path` elements form original element
 * and prepared objects
 *
 * @param  {DOMelement} element  Original element to transform
 * @param  {object} pathData     Path data (from `toPath` methods)
 * @return {DOMelement}          Path element
 */
Pathformer.prototype.pathMaker = function (element, pathData) {
  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
  for(i = 0; i < element.attributes.length; i++) {
    attr = element.attributes[i];
    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
      pathTag.setAttribute(attr.name, attr.value);
    }
  }
  for(i in pathData) {
    pathTag.setAttribute(i, pathData[i]);
  }
  return pathTag;
};

/**
 * Parse attributes of a DOM element to
 * get an object of attribute => value
 *
 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
 * @return {object}                  Object of attributes
 */
Pathformer.prototype.parseAttr = function (element) {
  var attr, output = {};
  for (var i = 0; i < element.length; i++) {
    attr = element[i];
    // Check if no data attribute contains '%', or the transformation is impossible
    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
    }
    output[attr.name] = attr.value;
  }
  return output;
};

  'use strict';

var requestAnimFrame, cancelAnimFrame, parsePositiveInt;

/**
 * Vivus
 * Beta version
 *
 * Take any SVG and make the animation
 * to give give the impression of live drawing
 *
 * This in more than just inspired from codrops
 * At that point, it's a pure fork.
 */

/**
 * Class constructor
 * option structure
 *   type: 'delayed'|'async'|'oneByOne'|'script' (to know if the item must be drawn asynchronously or not, default: delayed)
 *   duration: <int> (in frames)
 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
 *   delay: <int> (delay between the drawing of first and last path)
 *   dashGap <integer> whitespace extra margin between dashes
 *   pathTimingFunction <function> timing animation function for each path element of the SVG
 *   animTimingFunction <function> timing animation function for the complete SVG
 *   forceRender <boolean> force the browser to re-render all updated path items
 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
 *
 * The attribute 'type' is by default on 'delayed'.
 *  - 'delayed'
 *    all paths are draw at the same time but with a
 *    little delay between them before start
 *  - 'async'
 *    all path are start and finish at the same time
 *  - 'oneByOne'
 *    only one path is draw at the time
 *    the end of the first one will trigger the draw
 *    of the next one
 *
 * All these values can be overwritten individually
 * for each path item in the SVG
 * The value of frames will always take the advantage of
 * the duration value.
 * If you fail somewhere, an error will be thrown.
 * Good luck.
 *
 * @constructor
 * @this {Vivus}
 * @param {DOM|String}   element  Dom element of the SVG or id of it
 * @param {Object}       options  Options about the animation
 * @param {Function}     callback Callback for the end of the animation
 */
function Vivus (element, options, callback) {

  // Setup
  this.isReady = false;
  this.setElement(element, options);
  this.setOptions(options);
  this.setCallback(callback);

  if (this.isReady) {
    this.init();
  }
}

/**
 * Timing functions
 ************************************** 
 * 
 * Default functions to help developers.
 * It always take a number as parameter (between 0 to 1) then
 * return a number (between 0 and 1)
 */
Vivus.LINEAR          = function (x) {return x;};
Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
Vivus.EASE_OUT_BOUNCE = function (x) {
  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
    rate = Math.pow(base,1.5),
    rateR = Math.pow(1 - x, 2),
    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
  return (1- rateR) + (progress * rateR);
};


/**
 * Setters
 **************************************
 */

/**
 * Check and set the element in the instance
 * The method will not return anything, but will throw an
 * error if the parameter is invalid
 *
 * @param {DOM|String}   element  SVG Dom element or id of it
 */
Vivus.prototype.setElement = function (element, options) {
  // Basic check
  if (typeof element === 'undefined') {
    throw new Error('Vivus [constructor]: "element" parameter is required');
  }

  // Set the element
  if (element.constructor === String) {
    element = document.getElementById(element);
    if (!element) {
      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
    }
  }
  this.parentEl = element;

  // Create the object element if the property `file` exists in the options object
  if (options && options.file) {
    var objElm = document.createElement('object');
    objElm.setAttribute('type', 'image/svg+xml');
    objElm.setAttribute('data', options.file);
    objElm.setAttribute('built-by-vivus', 'true');
    element.appendChild(objElm);
    element = objElm;
  }

  switch (element.constructor) {
  case window.SVGSVGElement:
  case window.SVGElement:
    this.el = element;
    this.isReady = true;
    break;

  case window.HTMLObjectElement:
    // If we have to wait for it
    var onLoad, self;
    
    self = this;
    onLoad = function (e) {
      if (self.isReady) {
        return;
      }
      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
      if (!self.el && e) {
        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
      }
      else if (self.el) {
        if (element.getAttribute('built-by-vivus')) {
          self.parentEl.insertBefore(self.el, element);
          self.parentEl.removeChild(element);
          self.el.setAttribute('width', '100%');
          self.el.setAttribute('height', '100%');
        }
        self.isReady = true;
        self.init();
        return true;
      }
    };

    if (!onLoad()) {
      element.addEventListener('load', onLoad);
    }
    break;

  default:
    throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)');
  }
};

/**
 * Set up user option to the instance
 * The method will not return anything, but will throw an
 * error if the parameter is invalid
 *
 * @param  {object} options Object from the constructor
 */
Vivus.prototype.setOptions = function (options) {
  var allowedTypes = ['delayed', 'async', 'oneByOne', 'scenario', 'scenario-sync'];
  var allowedStarts =  ['inViewport', 'manual', 'autostart'];

  // Basic check
  if (options !== undefined && options.constructor !== Object) {
    throw new Error('Vivus [constructor]: "options" parameter must be an object');
  }
  else {
    options = options || {};
  }

  // Set the animation type
  if (options.type && allowedTypes.indexOf(options.type) === -1) {
    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
  }
  else {
    this.type = options.type || allowedTypes[0];
  }

  // Set the start type
  if (options.start && allowedStarts.indexOf(options.start) === -1) {
    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
  }
  else {
    this.start = options.start || allowedStarts[0];
  }

  this.isIE        = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 );
  this.duration    = parsePositiveInt(options.duration, 120);
  this.delay       = parsePositiveInt(options.delay, null);
  this.delayStart  = parsePositiveInt(options.delayStart, null);
  this.dashGap     = parsePositiveInt(options.dashGap, 1);
  this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
  this.selfDestroy = !!options.selfDestroy;
  this.onReady     = options.onReady;
  this.frameLength = this.currentFrame = this.map = this.delayUnit = this.speed = this.handle = null;

  this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false;

  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;

  if (this.delay >= this.duration) {
    throw new Error('Vivus [constructor]: delay must be shorter than duration');
  }
};

/**
 * Set up callback to the instance
 * The method will not return enything, but will throw an
 * error if the parameter is invalid
 *
 * @param  {Function} callback Callback for the animation end
 */
Vivus.prototype.setCallback = function (callback) {
  // Basic check
  if (!!callback && callback.constructor !== Function) {
    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
  }
  this.callback = callback || function () {};
};


/**
 * Core
 **************************************
 */

/**
 * Map the svg, path by path.
 * The method return nothing, it just fill the
 * `map` array. Each item in this array represent
 * a path element from the SVG, with informations for
 * the animation.
 *
 * ```
 * [
 *   {
 *     el: <DOMobj> the path element
 *     length: <number> length of the path line
 *     startAt: <number> time start of the path animation (in frames)
 *     duration: <number> path animation duration (in frames)
 *   },
 *   ...
 * ]
 * ```
 *
 */
Vivus.prototype.mapping = function () {
  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
  timePoint = totalLength = lengthMeter = 0;
  paths = this.el.querySelectorAll('path');

  for (i = 0; i < paths.length; i++) {
    path = paths[i];
    if (this.isInvisible(path)) {
      continue;
    }
    pathObj = {
      el: path,
      length: Math.ceil(path.getTotalLength())
    };
    // Test if the path length is correct
    if (isNaN(pathObj.length)) {
      if (window.console && console.warn) {
        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
      }
      continue;
    }
    this.map.push(pathObj);
    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2);
    path.style.strokeDashoffset = pathObj.length + this.dashGap;
    pathObj.length += this.dashGap;
    totalLength += pathObj.length;

    this.renderPath(i);
  }

  totalLength = totalLength === 0 ? 1 : totalLength;
  this.delay = this.delay === null ? this.duration / 3 : this.delay;
  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);

  for (i = 0; i < this.map.length; i++) {
    pathObj = this.map[i];

    switch (this.type) {
    case 'delayed':
      pathObj.startAt = this.delayUnit * i;
      pathObj.duration = this.duration - this.delay;
      break;

    case 'oneByOne':
      pathObj.startAt = lengthMeter / totalLength * this.duration;
      pathObj.duration = pathObj.length / totalLength * this.duration;
      break;

    case 'async':
      pathObj.startAt = 0;
      pathObj.duration = this.duration;
      break;

    case 'scenario-sync':
      path = paths[i];
      pAttrs = this.parseAttr(path);
      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
      break;

    case 'scenario':
      path = paths[i];
      pAttrs = this.parseAttr(path);
      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
      break;
    }
    lengthMeter += pathObj.length;
    this.frameLength = this.frameLength || this.duration;
  }
};

/**
 * Interval method to draw the SVG from current
 * position of the animation. It update the value of
 * `currentFrame` and re-trace the SVG.
 *
 * It use this.handle to store the requestAnimationFrame
 * and clear it one the animation is stopped. So this
 * attribute can be used to know if the animation is
 * playing.
 *
 * Once the animation at the end, this method will
 * trigger the Vivus callback.
 *
 */
Vivus.prototype.drawer = function () {
  var self = this;
  this.currentFrame += this.speed;

  if (this.currentFrame <= 0) {
    this.stop();
    this.reset();
    this.callback(this);
  } else if (this.currentFrame >= this.frameLength) {
    this.stop();
    this.currentFrame = this.frameLength;
    this.trace();
    if (this.selfDestroy) {
      this.destroy();
    }
    this.callback(this);
  } else {
    this.trace();
    this.handle = requestAnimFrame(function () {
      self.drawer();
    });
  }
};

/**
 * Draw the SVG at the current instant from the
 * `currentFrame` value. Here is where most of the magic is.
 * The trick is to use the `strokeDashoffset` style property.
 *
 * For optimisation reasons, a new property called `progress`
 * is added in each item of `map`. This one contain the current
 * progress of the path element. Only if the new value is different
 * the new value will be applied to the DOM element. This
 * method save a lot of resources to re-render the SVG. And could
 * be improved if the animation couldn't be played forward.
 *
 */
Vivus.prototype.trace = function () {
  var i, progress, path, currentFrame;
  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
  for (i = 0; i < this.map.length; i++) {
    path = this.map[i];
    progress = (currentFrame - path.startAt) / path.duration;
    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
    if (path.progress !== progress) {
      path.progress = progress;
      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
      this.renderPath(i);
    }
  }
};

/**
 * Method forcing the browser to re-render a path element
 * from it's index in the map. Depending on the `forceRender`
 * value.
 * The trick is to replace the path element by it's clone.
 * This practice is not recommended because it's asking more
 * ressources, too much DOM manupulation..
 * but it's the only way to let the magic happen on IE.
 * By default, this fallback is only applied on IE.
 * 
 * @param  {Number} index Path index
 */
Vivus.prototype.renderPath = function (index) {
  if (this.forceRender && this.map && this.map[index]) {
    var pathObj = this.map[index],
        newPath = pathObj.el.cloneNode(true);
    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
    pathObj.el = newPath;
  }
};

/**
 * When the SVG object is loaded and ready,
 * this method will continue the initialisation.
 *
 * This this mainly due to the case of passing an
 * object tag in the constructor. It will wait
 * the end of the loading to initialise.
 * 
 */
Vivus.prototype.init = function () {
  // Set object variables
  this.frameLength = 0;
  this.currentFrame = 0;
  this.map = [];

  // Start
  new Pathformer(this.el);
  this.mapping();
  this.starter();

  if (this.onReady) {
    this.onReady(this);
  }
};

/**
 * Trigger to start of the animation.
 * Depending on the `start` value, a different script
 * will be applied.
 *
 * If the `start` value is not valid, an error will be thrown.
 * Even if technically, this is impossible.
 *
 */
Vivus.prototype.starter = function () {
  switch (this.start) {
  case 'manual':
    return;

  case 'autostart':
    this.play();
    break;

  case 'inViewport':
    var self = this,
    listener = function () {
      if (self.isInViewport(self.parentEl, 1)) {
        if (self.delayStart != null) {
        	setTimeout(function() {
        		self.play();
        	}, self.delayStart);
        } else self.play();
        window.removeEventListener('scroll', listener);
      }
    };
    window.addEventListener('scroll', listener);
    listener();
    break;
  }
};


/**
 * Controls
 **************************************
 */

/**
 * Get the current status of the animation between
 * three different states: 'start', 'progress', 'end'.
 * @return {string} Instance status
 */
Vivus.prototype.getStatus = function () {
  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
};

/**
 * Reset the instance to the initial state : undraw
 * Be careful, it just reset the animation, if you're
 * playing the animation, this won't stop it. But just
 * make it start from start.
 *
 */
Vivus.prototype.reset = function () {
  return this.setFrameProgress(0);
};

/**
 * Set the instance to the final state : drawn
 * Be careful, it just set the animation, if you're
 * playing the animation on rewind, this won't stop it.
 * But just make it start from the end.
 *
 */
Vivus.prototype.finish = function () {
  return this.setFrameProgress(1);
};

/**
 * Set the level of progress of the drawing.
 * 
 * @param {number} progress Level of progress to set
 */
Vivus.prototype.setFrameProgress = function (progress) {
  progress = Math.min(1, Math.max(0, progress));
  this.currentFrame = Math.round(this.frameLength * progress);
  this.trace();
  return this;
};

/**
 * Play the animation at the desired speed.
 * Speed must be a valid number (no zero).
 * By default, the speed value is 1.
 * But a negative value is accepted to go forward.
 *
 * And works with float too.
 * But don't forget we are in JavaScript, se be nice
 * with him and give him a 1/2^x value.
 *
 * @param  {number} speed Animation speed [optional]
 */
Vivus.prototype.play = function (speed) {
  if (speed && typeof speed !== 'number') {
    throw new Error('Vivus [play]: invalid speed');
  }
  this.speed = speed || 1;
  if (!this.handle) {
    this.drawer();
  }
  return this;
};

/**
 * Stop the current animation, if on progress.
 * Should not trigger any error.
 *
 */
Vivus.prototype.stop = function () {
  if (this.handle) {
    cancelAnimFrame(this.handle);
    this.handle = null;
  }
  return this;
};

/**
 * Destroy the instance.
 * Remove all bad styling attributes on all
 * path tags
 *
 */
Vivus.prototype.destroy = function () {
  var i, path;
  for (i = 0; i < this.map.length; i++) {
    path = this.map[i];
    path.el.style.strokeDashoffset = null;
    path.el.style.strokeDasharray = null;
    this.renderPath(i);
  }
};


/**
 * Utils methods
 * include methods from Codrops
 **************************************
 */

/**
 * Method to best guess if a path should added into
 * the animation or not.
 *
 * 1. Use the `data-vivus-ignore` attribute if set
 * 2. Check if the instance must ignore invisible paths
 * 3. Check if the path is visible
 *
 * For now the visibility checking is unstable.
 * It will be used for a beta phase.
 *
 * Other improvments are planned. Like detecting
 * is the path got a stroke or a valid opacity.
 */
Vivus.prototype.isInvisible = function (el) {
  var rect,
    ignoreAttr = el.getAttribute('data-ignore');

  if (ignoreAttr !== null) {
    return ignoreAttr !== 'false';
  }

  if (this.ignoreInvisible) {
    rect = el.getBoundingClientRect();
    return !rect.width && !rect.height;
  }
  else {
    return false;
  }
};

/**
 * Parse attributes of a DOM element to
 * get an object of {attributeName => attributeValue}
 *
 * @param  {object} element DOM element to parse
 * @return {object}         Object of attributes
 */
Vivus.prototype.parseAttr = function (element) {
  var attr, output = {};
  if (element && element.attributes) {
    for (var i = 0; i < element.attributes.length; i++) {
      attr = element.attributes[i];
      output[attr.name] = attr.value;
    }
  }
  return output;
};

/**
 * Reply if an element is in the page viewport
 *
 * @param  {object} el Element to observe
 * @param  {number} h  Percentage of height
 * @return {boolean}
 */
Vivus.prototype.isInViewport = function (el, h) {
  var scrolled   = this.scrollY(),
    viewed       = scrolled + this.getViewportH(),
    elBCR        = el.getBoundingClientRect(),
    elHeight     = elBCR.height,
    elTop        = scrolled + elBCR.top,
    elBottom     = elTop + elHeight;

  // 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 + elHeight * h) <= viewed && (elBottom) >= scrolled;
};

/**
 * Alias for document element
 *
 * @type {DOMelement}
 */
Vivus.prototype.docElem = window.document.documentElement;

/**
 * Get the viewport height in pixels
 *
 * @return {integer} Viewport height
 */
Vivus.prototype.getViewportH = function () {
  var client = this.docElem.clientHeight,
    inner = window.innerHeight;

  if (client < inner) {
    return inner;
  }
  else {
    return client;
  }
};

/**
 * Get the page Y offset
 *
 * @return {integer} Page Y offset
 */
Vivus.prototype.scrollY = function () {
  return window.pageYOffset || this.docElem.scrollTop;
};

/**
 * Alias for `requestAnimationFrame` or
 * `setTimeout` function for deprecated browsers.
 *
 */
requestAnimFrame = (function () {
  return (
    window.requestAnimationFrame       ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame    ||
    window.oRequestAnimationFrame      ||
    window.msRequestAnimationFrame     ||
    function(/* function */ callback){
      return window.setTimeout(callback, 1000 / 60);
    }
  );
})();

/**
 * Alias for `cancelAnimationFrame` or
 * `cancelTimeout` function for deprecated browsers.
 *
 */
cancelAnimFrame = (function () {
  return (
    window.cancelAnimationFrame       ||
    window.webkitCancelAnimationFrame ||
    window.mozCancelAnimationFrame    ||
    window.oCancelAnimationFrame      ||
    window.msCancelAnimationFrame     ||
    function(id){
      return window.clearTimeout(id);
    }
  );
})();

/**
 * Parse string to integer.
 * If the number is not positive or null
 * the method will return the default value
 * or 0 if undefined
 *
 * @param {string} value String to parse
 * @param {*} defaultValue Value to return if the result parsed is invalid
 * @return {number}
 *
 */
parsePositiveInt = function (value, defaultValue) {
  var output = parseInt(value, 10);
  return (output >= 0) ? output : defaultValue;
};


  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], function() {
      return Vivus;
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = Vivus;
  } else {
    // Browser globals
    window.Vivus = Vivus;
  }

}(window, document));