/* Minification failed. Returning unminified contents.
(10176,39-40): run-time error JS1195: Expected expression: >
(10178,22-23): run-time error JS1195: Expected expression: )
(10178,39-40): run-time error JS1195: Expected expression: >
(10180,22-23): run-time error JS1195: Expected expression: )
(10188,13-18): run-time error JS1195: Expected expression: catch
(10190,13-14): run-time error JS1002: Syntax error: }
(10194,5-6): run-time error JS1002: Syntax error: }
(10196,12-13): run-time error JS1195: Expected expression: )
(10196,14-15): run-time error JS1004: Expected ';': {
(11202,3-4): run-time error JS1195: Expected expression: )
(11202,4-5): run-time error JS1004: Expected ';': )
(11204,78-79): run-time error JS1004: Expected ';': {
(11207,3-9): run-time error JS1018: 'return' statement outside of function: return
 */
if (!Function.prototype.bind) {
	Function.prototype.bind = function (oThis) {
		if (typeof this !== 'function') {
			// closest thing possible to the ECMAScript 5
			// internal IsCallable function
			throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
		}

		var aArgs = Array.prototype.slice.call(arguments, 1),
			fToBind = this,
			fNOP = function () { },
			fBound = function () {
				return fToBind.apply(this instanceof fNOP
					   ? this
					   : oThis,
					   aArgs.concat(Array.prototype.slice.call(arguments)));
			};

		fNOP.prototype = this.prototype;
		fBound.prototype = new fNOP();

		return fBound;
	};
};
/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
//@ sourceMappingURL=jquery.min.map
*/
(function (e, undefined) {
	var t, n, r = typeof undefined, i = e.location, o = e.document, s = o.documentElement, a = e.jQuery, u = e.$, l = {}, c = [], p = "2.0.3", f = c.concat, h = c.push, d = c.slice, g = c.indexOf, m = l.toString, y = l.hasOwnProperty, v = p.trim, x = function (e, n) { return new x.fn.init(e, n, t) }, b = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, w = /\S+/g, T = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, C = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, k = /^-ms-/, N = /-([\da-z])/gi, E = function (e, t) { return t.toUpperCase() }, S = function () { o.removeEventListener("DOMContentLoaded", S, !1), e.removeEventListener("load", S, !1), x.ready() }; x.fn = x.prototype = { jquery: p, constructor: x, init: function (e, t, n) { var r, i; if (!e) return this; if ("string" == typeof e) { if (r = "<" === e.charAt(0) && ">" === e.charAt(e.length - 1) && e.length >= 3 ? [null, e, null] : T.exec(e), !r || !r[1] && t) return !t || t.jquery ? (t || n).find(e) : this.constructor(t).find(e); if (r[1]) { if (t = t instanceof x ? t[0] : t, x.merge(this, x.parseHTML(r[1], t && t.nodeType ? t.ownerDocument || t : o, !0)), C.test(r[1]) && x.isPlainObject(t)) for (r in t) x.isFunction(this[r]) ? this[r](t[r]) : this.attr(r, t[r]); return this } return i = o.getElementById(r[2]), i && i.parentNode && (this.length = 1, this[0] = i), this.context = o, this.selector = e, this } return e.nodeType ? (this.context = this[0] = e, this.length = 1, this) : x.isFunction(e) ? n.ready(e) : (e.selector !== undefined && (this.selector = e.selector, this.context = e.context), x.makeArray(e, this)) }, selector: "", length: 0, toArray: function () { return d.call(this) }, get: function (e) { return null == e ? this.toArray() : 0 > e ? this[this.length + e] : this[e] }, pushStack: function (e) { var t = x.merge(this.constructor(), e); return t.prevObject = this, t.context = this.context, t }, each: function (e, t) { return x.each(this, e, t) }, ready: function (e) { return x.ready.promise().done(e), this }, slice: function () { return this.pushStack(d.apply(this, arguments)) }, first: function () { return this.eq(0) }, last: function () { return this.eq(-1) }, eq: function (e) { var t = this.length, n = +e + (0 > e ? t : 0); return this.pushStack(n >= 0 && t > n ? [this[n]] : []) }, map: function (e) { return this.pushStack(x.map(this, function (t, n) { return e.call(t, n, t) })) }, end: function () { return this.prevObject || this.constructor(null) }, push: h, sort: [].sort, splice: [].splice }, x.fn.init.prototype = x.fn, x.extend = x.fn.extend = function () { var e, t, n, r, i, o, s = arguments[0] || {}, a = 1, u = arguments.length, l = !1; for ("boolean" == typeof s && (l = s, s = arguments[1] || {}, a = 2), "object" == typeof s || x.isFunction(s) || (s = {}), u === a && (s = this, --a) ; u > a; a++) if (null != (e = arguments[a])) for (t in e) n = s[t], r = e[t], s !== r && (l && r && (x.isPlainObject(r) || (i = x.isArray(r))) ? (i ? (i = !1, o = n && x.isArray(n) ? n : []) : o = n && x.isPlainObject(n) ? n : {}, s[t] = x.extend(l, o, r)) : r !== undefined && (s[t] = r)); return s }, x.extend({ expando: "jQuery" + (p + Math.random()).replace(/\D/g, ""), noConflict: function (t) { return e.$ === x && (e.$ = u), t && e.jQuery === x && (e.jQuery = a), x }, isReady: !1, readyWait: 1, holdReady: function (e) { e ? x.readyWait++ : x.ready(!0) }, ready: function (e) { (e === !0 ? --x.readyWait : x.isReady) || (x.isReady = !0, e !== !0 && --x.readyWait > 0 || (n.resolveWith(o, [x]), x.fn.trigger && x(o).trigger("ready").off("ready"))) }, isFunction: function (e) { return "function" === x.type(e) }, isArray: Array.isArray, isWindow: function (e) { return null != e && e === e.window }, isNumeric: function (e) { return !isNaN(parseFloat(e)) && isFinite(e) }, type: function (e) { return null == e ? e + "" : "object" == typeof e || "function" == typeof e ? l[m.call(e)] || "object" : typeof e }, isPlainObject: function (e) { if ("object" !== x.type(e) || e.nodeType || x.isWindow(e)) return !1; try { if (e.constructor && !y.call(e.constructor.prototype, "isPrototypeOf")) return !1 } catch (t) { return !1 } return !0 }, isEmptyObject: function (e) { var t; for (t in e) return !1; return !0 }, error: function (e) { throw Error(e) }, parseHTML: function (e, t, n) { if (!e || "string" != typeof e) return null; "boolean" == typeof t && (n = t, t = !1), t = t || o; var r = C.exec(e), i = !n && []; return r ? [t.createElement(r[1])] : (r = x.buildFragment([e], t, i), i && x(i).remove(), x.merge([], r.childNodes)) }, parseJSON: JSON.parse, parseXML: function (e) { var t, n; if (!e || "string" != typeof e) return null; try { n = new DOMParser, t = n.parseFromString(e, "text/xml") } catch (r) { t = undefined } return (!t || t.getElementsByTagName("parsererror").length) && x.error("Invalid XML: " + e), t }, noop: function () { }, globalEval: function (e) { var t, n = eval; e = x.trim(e), e && (1 === e.indexOf("use strict") ? (t = o.createElement("script"), t.text = e, o.head.appendChild(t).parentNode.removeChild(t)) : n(e)) }, camelCase: function (e) { return e.replace(k, "ms-").replace(N, E) }, nodeName: function (e, t) { return e.nodeName && e.nodeName.toLowerCase() === t.toLowerCase() }, each: function (e, t, n) { var r, i = 0, o = e.length, s = j(e); if (n) { if (s) { for (; o > i; i++) if (r = t.apply(e[i], n), r === !1) break } else for (i in e) if (r = t.apply(e[i], n), r === !1) break } else if (s) { for (; o > i; i++) if (r = t.call(e[i], i, e[i]), r === !1) break } else for (i in e) if (r = t.call(e[i], i, e[i]), r === !1) break; return e }, trim: function (e) { return null == e ? "" : v.call(e) }, makeArray: function (e, t) { var n = t || []; return null != e && (j(Object(e)) ? x.merge(n, "string" == typeof e ? [e] : e) : h.call(n, e)), n }, inArray: function (e, t, n) { return null == t ? -1 : g.call(t, e, n) }, merge: function (e, t) { var n = t.length, r = e.length, i = 0; if ("number" == typeof n) for (; n > i; i++) e[r++] = t[i]; else while (t[i] !== undefined) e[r++] = t[i++]; return e.length = r, e }, grep: function (e, t, n) { var r, i = [], o = 0, s = e.length; for (n = !!n; s > o; o++) r = !!t(e[o], o), n !== r && i.push(e[o]); return i }, map: function (e, t, n) { var r, i = 0, o = e.length, s = j(e), a = []; if (s) for (; o > i; i++) r = t(e[i], i, n), null != r && (a[a.length] = r); else for (i in e) r = t(e[i], i, n), null != r && (a[a.length] = r); return f.apply([], a) }, guid: 1, proxy: function (e, t) { var n, r, i; return "string" == typeof t && (n = e[t], t = e, e = n), x.isFunction(e) ? (r = d.call(arguments, 2), i = function () { return e.apply(t || this, r.concat(d.call(arguments))) }, i.guid = e.guid = e.guid || x.guid++, i) : undefined }, access: function (e, t, n, r, i, o, s) { var a = 0, u = e.length, l = null == n; if ("object" === x.type(n)) { i = !0; for (a in n) x.access(e, t, a, n[a], !0, o, s) } else if (r !== undefined && (i = !0, x.isFunction(r) || (s = !0), l && (s ? (t.call(e, r), t = null) : (l = t, t = function (e, t, n) { return l.call(x(e), n) })), t)) for (; u > a; a++) t(e[a], n, s ? r : r.call(e[a], a, t(e[a], n))); return i ? e : l ? t.call(e) : u ? t(e[0], n) : o }, now: Date.now, swap: function (e, t, n, r) { var i, o, s = {}; for (o in t) s[o] = e.style[o], e.style[o] = t[o]; i = n.apply(e, r || []); for (o in t) e.style[o] = s[o]; return i } }), x.ready.promise = function (t) { return n || (n = x.Deferred(), "complete" === o.readyState ? setTimeout(x.ready) : (o.addEventListener("DOMContentLoaded", S, !1), e.addEventListener("load", S, !1))), n.promise(t) }, x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (e, t) { l["[object " + t + "]"] = t.toLowerCase() }); function j(e) { var t = e.length, n = x.type(e); return x.isWindow(e) ? !1 : 1 === e.nodeType && t ? !0 : "array" === n || "function" !== n && (0 === t || "number" == typeof t && t > 0 && t - 1 in e) } t = x(o), function (e, undefined) { var t, n, r, i, o, s, a, u, l, c, p, f, h, d, g, m, y, v = "sizzle" + -new Date, b = e.document, w = 0, T = 0, C = st(), k = st(), N = st(), E = !1, S = function (e, t) { return e === t ? (E = !0, 0) : 0 }, j = typeof undefined, D = 1 << 31, A = {}.hasOwnProperty, L = [], q = L.pop, H = L.push, O = L.push, F = L.slice, P = L.indexOf || function (e) { var t = 0, n = this.length; for (; n > t; t++) if (this[t] === e) return t; return -1 }, R = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", M = "[\\x20\\t\\r\\n\\f]", W = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", $ = W.replace("w", "w#"), B = "\\[" + M + "*(" + W + ")" + M + "*(?:([*^$|!~]?=)" + M + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + $ + ")|)|)" + M + "*\\]", I = ":(" + W + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + B.replace(3, 8) + ")*)|.*)\\)|)", z = RegExp("^" + M + "+|((?:^|[^\\\\])(?:\\\\.)*)" + M + "+$", "g"), _ = RegExp("^" + M + "*," + M + "*"), X = RegExp("^" + M + "*([>+~]|" + M + ")" + M + "*"), U = RegExp(M + "*[+~]"), Y = RegExp("=" + M + "*([^\\]'\"]*)" + M + "*\\]", "g"), V = RegExp(I), G = RegExp("^" + $ + "$"), J = { ID: RegExp("^#(" + W + ")"), CLASS: RegExp("^\\.(" + W + ")"), TAG: RegExp("^(" + W.replace("w", "w*") + ")"), ATTR: RegExp("^" + B), PSEUDO: RegExp("^" + I), CHILD: RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + M + "*(even|odd|(([+-]|)(\\d*)n|)" + M + "*(?:([+-]|)" + M + "*(\\d+)|))" + M + "*\\)|)", "i"), bool: RegExp("^(?:" + R + ")$", "i"), needsContext: RegExp("^" + M + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + M + "*((?:-\\d)?\\d*)" + M + "*\\)|)(?=[^-]|$)", "i") }, Q = /^[^{]+\{\s*\[native \w/, K = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, Z = /^(?:input|select|textarea|button)$/i, et = /^h\d$/i, tt = /'|\\/g, nt = RegExp("\\\\([\\da-f]{1,6}" + M + "?|(" + M + ")|.)", "ig"), rt = function (e, t, n) { var r = "0x" + t - 65536; return r !== r || n ? t : 0 > r ? String.fromCharCode(r + 65536) : String.fromCharCode(55296 | r >> 10, 56320 | 1023 & r) }; try { O.apply(L = F.call(b.childNodes), b.childNodes), L[b.childNodes.length].nodeType } catch (it) { O = { apply: L.length ? function (e, t) { H.apply(e, F.call(t)) } : function (e, t) { var n = e.length, r = 0; while (e[n++] = t[r++]); e.length = n - 1 } } } function ot(e, t, r, i) { var o, s, a, u, l, f, g, m, x, w; if ((t ? t.ownerDocument || t : b) !== p && c(t), t = t || p, r = r || [], !e || "string" != typeof e) return r; if (1 !== (u = t.nodeType) && 9 !== u) return []; if (h && !i) { if (o = K.exec(e)) if (a = o[1]) { if (9 === u) { if (s = t.getElementById(a), !s || !s.parentNode) return r; if (s.id === a) return r.push(s), r } else if (t.ownerDocument && (s = t.ownerDocument.getElementById(a)) && y(t, s) && s.id === a) return r.push(s), r } else { if (o[2]) return O.apply(r, t.getElementsByTagName(e)), r; if ((a = o[3]) && n.getElementsByClassName && t.getElementsByClassName) return O.apply(r, t.getElementsByClassName(a)), r } if (n.qsa && (!d || !d.test(e))) { if (m = g = v, x = t, w = 9 === u && e, 1 === u && "object" !== t.nodeName.toLowerCase()) { f = gt(e), (g = t.getAttribute("id")) ? m = g.replace(tt, "\\$&") : t.setAttribute("id", m), m = "[id='" + m + "'] ", l = f.length; while (l--) f[l] = m + mt(f[l]); x = U.test(e) && t.parentNode || t, w = f.join(",") } if (w) try { return O.apply(r, x.querySelectorAll(w)), r } catch (T) { } finally { g || t.removeAttribute("id") } } } return kt(e.replace(z, "$1"), t, r, i) } function st() { var e = []; function t(n, r) { return e.push(n += " ") > i.cacheLength && delete t[e.shift()], t[n] = r } return t } function at(e) { return e[v] = !0, e } function ut(e) { var t = p.createElement("div"); try { return !!e(t) } catch (n) { return !1 } finally { t.parentNode && t.parentNode.removeChild(t), t = null } } function lt(e, t) { var n = e.split("|"), r = e.length; while (r--) i.attrHandle[n[r]] = t } function ct(e, t) { var n = t && e, r = n && 1 === e.nodeType && 1 === t.nodeType && (~t.sourceIndex || D) - (~e.sourceIndex || D); if (r) return r; if (n) while (n = n.nextSibling) if (n === t) return -1; return e ? 1 : -1 } function pt(e) { return function (t) { var n = t.nodeName.toLowerCase(); return "input" === n && t.type === e } } function ft(e) { return function (t) { var n = t.nodeName.toLowerCase(); return ("input" === n || "button" === n) && t.type === e } } function ht(e) { return at(function (t) { return t = +t, at(function (n, r) { var i, o = e([], n.length, t), s = o.length; while (s--) n[i = o[s]] && (n[i] = !(r[i] = n[i])) }) }) } s = ot.isXML = function (e) { var t = e && (e.ownerDocument || e).documentElement; return t ? "HTML" !== t.nodeName : !1 }, n = ot.support = {}, c = ot.setDocument = function (e) { var t = e ? e.ownerDocument || e : b, r = t.defaultView; return t !== p && 9 === t.nodeType && t.documentElement ? (p = t, f = t.documentElement, h = !s(t), r && r.attachEvent && r !== r.top && r.attachEvent("onbeforeunload", function () { c() }), n.attributes = ut(function (e) { return e.className = "i", !e.getAttribute("className") }), n.getElementsByTagName = ut(function (e) { return e.appendChild(t.createComment("")), !e.getElementsByTagName("*").length }), n.getElementsByClassName = ut(function (e) { return e.innerHTML = "<div class='a'></div><div class='a i'></div>", e.firstChild.className = "i", 2 === e.getElementsByClassName("i").length }), n.getById = ut(function (e) { return f.appendChild(e).id = v, !t.getElementsByName || !t.getElementsByName(v).length }), n.getById ? (i.find.ID = function (e, t) { if (typeof t.getElementById !== j && h) { var n = t.getElementById(e); return n && n.parentNode ? [n] : [] } }, i.filter.ID = function (e) { var t = e.replace(nt, rt); return function (e) { return e.getAttribute("id") === t } }) : (delete i.find.ID, i.filter.ID = function (e) { var t = e.replace(nt, rt); return function (e) { var n = typeof e.getAttributeNode !== j && e.getAttributeNode("id"); return n && n.value === t } }), i.find.TAG = n.getElementsByTagName ? function (e, t) { return typeof t.getElementsByTagName !== j ? t.getElementsByTagName(e) : undefined } : function (e, t) { var n, r = [], i = 0, o = t.getElementsByTagName(e); if ("*" === e) { while (n = o[i++]) 1 === n.nodeType && r.push(n); return r } return o }, i.find.CLASS = n.getElementsByClassName && function (e, t) { return typeof t.getElementsByClassName !== j && h ? t.getElementsByClassName(e) : undefined }, g = [], d = [], (n.qsa = Q.test(t.querySelectorAll)) && (ut(function (e) { e.innerHTML = "<select><option selected=''></option></select>", e.querySelectorAll("[selected]").length || d.push("\\[" + M + "*(?:value|" + R + ")"), e.querySelectorAll(":checked").length || d.push(":checked") }), ut(function (e) { var n = t.createElement("input"); n.setAttribute("type", "hidden"), e.appendChild(n).setAttribute("t", ""), e.querySelectorAll("[t^='']").length && d.push("[*^$]=" + M + "*(?:''|\"\")"), e.querySelectorAll(":enabled").length || d.push(":enabled", ":disabled"), e.querySelectorAll("*,:x"), d.push(",.*:") })), (n.matchesSelector = Q.test(m = f.webkitMatchesSelector || f.mozMatchesSelector || f.oMatchesSelector || f.msMatchesSelector)) && ut(function (e) { n.disconnectedMatch = m.call(e, "div"), m.call(e, "[s!='']:x"), g.push("!=", I) }), d = d.length && RegExp(d.join("|")), g = g.length && RegExp(g.join("|")), y = Q.test(f.contains) || f.compareDocumentPosition ? function (e, t) { var n = 9 === e.nodeType ? e.documentElement : e, r = t && t.parentNode; return e === r || !(!r || 1 !== r.nodeType || !(n.contains ? n.contains(r) : e.compareDocumentPosition && 16 & e.compareDocumentPosition(r))) } : function (e, t) { if (t) while (t = t.parentNode) if (t === e) return !0; return !1 }, S = f.compareDocumentPosition ? function (e, r) { if (e === r) return E = !0, 0; var i = r.compareDocumentPosition && e.compareDocumentPosition && e.compareDocumentPosition(r); return i ? 1 & i || !n.sortDetached && r.compareDocumentPosition(e) === i ? e === t || y(b, e) ? -1 : r === t || y(b, r) ? 1 : l ? P.call(l, e) - P.call(l, r) : 0 : 4 & i ? -1 : 1 : e.compareDocumentPosition ? -1 : 1 } : function (e, n) { var r, i = 0, o = e.parentNode, s = n.parentNode, a = [e], u = [n]; if (e === n) return E = !0, 0; if (!o || !s) return e === t ? -1 : n === t ? 1 : o ? -1 : s ? 1 : l ? P.call(l, e) - P.call(l, n) : 0; if (o === s) return ct(e, n); r = e; while (r = r.parentNode) a.unshift(r); r = n; while (r = r.parentNode) u.unshift(r); while (a[i] === u[i]) i++; return i ? ct(a[i], u[i]) : a[i] === b ? -1 : u[i] === b ? 1 : 0 }, t) : p }, ot.matches = function (e, t) { return ot(e, null, null, t) }, ot.matchesSelector = function (e, t) { if ((e.ownerDocument || e) !== p && c(e), t = t.replace(Y, "='$1']"), !(!n.matchesSelector || !h || g && g.test(t) || d && d.test(t))) try { var r = m.call(e, t); if (r || n.disconnectedMatch || e.document && 11 !== e.document.nodeType) return r } catch (i) { } return ot(t, p, null, [e]).length > 0 }, ot.contains = function (e, t) { return (e.ownerDocument || e) !== p && c(e), y(e, t) }, ot.attr = function (e, t) { (e.ownerDocument || e) !== p && c(e); var r = i.attrHandle[t.toLowerCase()], o = r && A.call(i.attrHandle, t.toLowerCase()) ? r(e, t, !h) : undefined; return o === undefined ? n.attributes || !h ? e.getAttribute(t) : (o = e.getAttributeNode(t)) && o.specified ? o.value : null : o }, ot.error = function (e) { throw Error("Syntax error, unrecognized expression: " + e) }, ot.uniqueSort = function (e) { var t, r = [], i = 0, o = 0; if (E = !n.detectDuplicates, l = !n.sortStable && e.slice(0), e.sort(S), E) { while (t = e[o++]) t === e[o] && (i = r.push(o)); while (i--) e.splice(r[i], 1) } return e }, o = ot.getText = function (e) { var t, n = "", r = 0, i = e.nodeType; if (i) { if (1 === i || 9 === i || 11 === i) { if ("string" == typeof e.textContent) return e.textContent; for (e = e.firstChild; e; e = e.nextSibling) n += o(e) } else if (3 === i || 4 === i) return e.nodeValue } else for (; t = e[r]; r++) n += o(t); return n }, i = ot.selectors = { cacheLength: 50, createPseudo: at, match: J, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: !0 }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: !0 }, "~": { dir: "previousSibling" } }, preFilter: { ATTR: function (e) { return e[1] = e[1].replace(nt, rt), e[3] = (e[4] || e[5] || "").replace(nt, rt), "~=" === e[2] && (e[3] = " " + e[3] + " "), e.slice(0, 4) }, CHILD: function (e) { return e[1] = e[1].toLowerCase(), "nth" === e[1].slice(0, 3) ? (e[3] || ot.error(e[0]), e[4] = +(e[4] ? e[5] + (e[6] || 1) : 2 * ("even" === e[3] || "odd" === e[3])), e[5] = +(e[7] + e[8] || "odd" === e[3])) : e[3] && ot.error(e[0]), e }, PSEUDO: function (e) { var t, n = !e[5] && e[2]; return J.CHILD.test(e[0]) ? null : (e[3] && e[4] !== undefined ? e[2] = e[4] : n && V.test(n) && (t = gt(n, !0)) && (t = n.indexOf(")", n.length - t) - n.length) && (e[0] = e[0].slice(0, t), e[2] = n.slice(0, t)), e.slice(0, 3)) } }, filter: { TAG: function (e) { var t = e.replace(nt, rt).toLowerCase(); return "*" === e ? function () { return !0 } : function (e) { return e.nodeName && e.nodeName.toLowerCase() === t } }, CLASS: function (e) { var t = C[e + " "]; return t || (t = RegExp("(^|" + M + ")" + e + "(" + M + "|$)")) && C(e, function (e) { return t.test("string" == typeof e.className && e.className || typeof e.getAttribute !== j && e.getAttribute("class") || "") }) }, ATTR: function (e, t, n) { return function (r) { var i = ot.attr(r, e); return null == i ? "!=" === t : t ? (i += "", "=" === t ? i === n : "!=" === t ? i !== n : "^=" === t ? n && 0 === i.indexOf(n) : "*=" === t ? n && i.indexOf(n) > -1 : "$=" === t ? n && i.slice(-n.length) === n : "~=" === t ? (" " + i + " ").indexOf(n) > -1 : "|=" === t ? i === n || i.slice(0, n.length + 1) === n + "-" : !1) : !0 } }, CHILD: function (e, t, n, r, i) { var o = "nth" !== e.slice(0, 3), s = "last" !== e.slice(-4), a = "of-type" === t; return 1 === r && 0 === i ? function (e) { return !!e.parentNode } : function (t, n, u) { var l, c, p, f, h, d, g = o !== s ? "nextSibling" : "previousSibling", m = t.parentNode, y = a && t.nodeName.toLowerCase(), x = !u && !a; if (m) { if (o) { while (g) { p = t; while (p = p[g]) if (a ? p.nodeName.toLowerCase() === y : 1 === p.nodeType) return !1; d = g = "only" === e && !d && "nextSibling" } return !0 } if (d = [s ? m.firstChild : m.lastChild], s && x) { c = m[v] || (m[v] = {}), l = c[e] || [], h = l[0] === w && l[1], f = l[0] === w && l[2], p = h && m.childNodes[h]; while (p = ++h && p && p[g] || (f = h = 0) || d.pop()) if (1 === p.nodeType && ++f && p === t) { c[e] = [w, h, f]; break } } else if (x && (l = (t[v] || (t[v] = {}))[e]) && l[0] === w) f = l[1]; else while (p = ++h && p && p[g] || (f = h = 0) || d.pop()) if ((a ? p.nodeName.toLowerCase() === y : 1 === p.nodeType) && ++f && (x && ((p[v] || (p[v] = {}))[e] = [w, f]), p === t)) break; return f -= i, f === r || 0 === f % r && f / r >= 0 } } }, PSEUDO: function (e, t) { var n, r = i.pseudos[e] || i.setFilters[e.toLowerCase()] || ot.error("unsupported pseudo: " + e); return r[v] ? r(t) : r.length > 1 ? (n = [e, e, "", t], i.setFilters.hasOwnProperty(e.toLowerCase()) ? at(function (e, n) { var i, o = r(e, t), s = o.length; while (s--) i = P.call(e, o[s]), e[i] = !(n[i] = o[s]) }) : function (e) { return r(e, 0, n) }) : r } }, pseudos: { not: at(function (e) { var t = [], n = [], r = a(e.replace(z, "$1")); return r[v] ? at(function (e, t, n, i) { var o, s = r(e, null, i, []), a = e.length; while (a--) (o = s[a]) && (e[a] = !(t[a] = o)) }) : function (e, i, o) { return t[0] = e, r(t, null, o, n), !n.pop() } }), has: at(function (e) { return function (t) { return ot(e, t).length > 0 } }), contains: at(function (e) { return function (t) { return (t.textContent || t.innerText || o(t)).indexOf(e) > -1 } }), lang: at(function (e) { return G.test(e || "") || ot.error("unsupported lang: " + e), e = e.replace(nt, rt).toLowerCase(), function (t) { var n; do if (n = h ? t.lang : t.getAttribute("xml:lang") || t.getAttribute("lang")) return n = n.toLowerCase(), n === e || 0 === n.indexOf(e + "-"); while ((t = t.parentNode) && 1 === t.nodeType); return !1 } }), target: function (t) { var n = e.location && e.location.hash; return n && n.slice(1) === t.id }, root: function (e) { return e === f }, focus: function (e) { return e === p.activeElement && (!p.hasFocus || p.hasFocus()) && !!(e.type || e.href || ~e.tabIndex) }, enabled: function (e) { return e.disabled === !1 }, disabled: function (e) { return e.disabled === !0 }, checked: function (e) { var t = e.nodeName.toLowerCase(); return "input" === t && !!e.checked || "option" === t && !!e.selected }, selected: function (e) { return e.parentNode && e.parentNode.selectedIndex, e.selected === !0 }, empty: function (e) { for (e = e.firstChild; e; e = e.nextSibling) if (e.nodeName > "@" || 3 === e.nodeType || 4 === e.nodeType) return !1; return !0 }, parent: function (e) { return !i.pseudos.empty(e) }, header: function (e) { return et.test(e.nodeName) }, input: function (e) { return Z.test(e.nodeName) }, button: function (e) { var t = e.nodeName.toLowerCase(); return "input" === t && "button" === e.type || "button" === t }, text: function (e) { var t; return "input" === e.nodeName.toLowerCase() && "text" === e.type && (null == (t = e.getAttribute("type")) || t.toLowerCase() === e.type) }, first: ht(function () { return [0] }), last: ht(function (e, t) { return [t - 1] }), eq: ht(function (e, t, n) { return [0 > n ? n + t : n] }), even: ht(function (e, t) { var n = 0; for (; t > n; n += 2) e.push(n); return e }), odd: ht(function (e, t) { var n = 1; for (; t > n; n += 2) e.push(n); return e }), lt: ht(function (e, t, n) { var r = 0 > n ? n + t : n; for (; --r >= 0;) e.push(r); return e }), gt: ht(function (e, t, n) { var r = 0 > n ? n + t : n; for (; t > ++r;) e.push(r); return e }) } }, i.pseudos.nth = i.pseudos.eq; for (t in { radio: !0, checkbox: !0, file: !0, password: !0, image: !0 }) i.pseudos[t] = pt(t); for (t in { submit: !0, reset: !0 }) i.pseudos[t] = ft(t); function dt() { } dt.prototype = i.filters = i.pseudos, i.setFilters = new dt; function gt(e, t) { var n, r, o, s, a, u, l, c = k[e + " "]; if (c) return t ? 0 : c.slice(0); a = e, u = [], l = i.preFilter; while (a) { (!n || (r = _.exec(a))) && (r && (a = a.slice(r[0].length) || a), u.push(o = [])), n = !1, (r = X.exec(a)) && (n = r.shift(), o.push({ value: n, type: r[0].replace(z, " ") }), a = a.slice(n.length)); for (s in i.filter) !(r = J[s].exec(a)) || l[s] && !(r = l[s](r)) || (n = r.shift(), o.push({ value: n, type: s, matches: r }), a = a.slice(n.length)); if (!n) break } return t ? a.length : a ? ot.error(e) : k(e, u).slice(0) } function mt(e) { var t = 0, n = e.length, r = ""; for (; n > t; t++) r += e[t].value; return r } function yt(e, t, n) { var i = t.dir, o = n && "parentNode" === i, s = T++; return t.first ? function (t, n, r) { while (t = t[i]) if (1 === t.nodeType || o) return e(t, n, r) } : function (t, n, a) { var u, l, c, p = w + " " + s; if (a) { while (t = t[i]) if ((1 === t.nodeType || o) && e(t, n, a)) return !0 } else while (t = t[i]) if (1 === t.nodeType || o) if (c = t[v] || (t[v] = {}), (l = c[i]) && l[0] === p) { if ((u = l[1]) === !0 || u === r) return u === !0 } else if (l = c[i] = [p], l[1] = e(t, n, a) || r, l[1] === !0) return !0 } } function vt(e) { return e.length > 1 ? function (t, n, r) { var i = e.length; while (i--) if (!e[i](t, n, r)) return !1; return !0 } : e[0] } function xt(e, t, n, r, i) { var o, s = [], a = 0, u = e.length, l = null != t; for (; u > a; a++) (o = e[a]) && (!n || n(o, r, i)) && (s.push(o), l && t.push(a)); return s } function bt(e, t, n, r, i, o) { return r && !r[v] && (r = bt(r)), i && !i[v] && (i = bt(i, o)), at(function (o, s, a, u) { var l, c, p, f = [], h = [], d = s.length, g = o || Ct(t || "*", a.nodeType ? [a] : a, []), m = !e || !o && t ? g : xt(g, f, e, a, u), y = n ? i || (o ? e : d || r) ? [] : s : m; if (n && n(m, y, a, u), r) { l = xt(y, h), r(l, [], a, u), c = l.length; while (c--) (p = l[c]) && (y[h[c]] = !(m[h[c]] = p)) } if (o) { if (i || e) { if (i) { l = [], c = y.length; while (c--) (p = y[c]) && l.push(m[c] = p); i(null, y = [], l, u) } c = y.length; while (c--) (p = y[c]) && (l = i ? P.call(o, p) : f[c]) > -1 && (o[l] = !(s[l] = p)) } } else y = xt(y === s ? y.splice(d, y.length) : y), i ? i(null, s, y, u) : O.apply(s, y) }) } function wt(e) { var t, n, r, o = e.length, s = i.relative[e[0].type], a = s || i.relative[" "], l = s ? 1 : 0, c = yt(function (e) { return e === t }, a, !0), p = yt(function (e) { return P.call(t, e) > -1 }, a, !0), f = [function (e, n, r) { return !s && (r || n !== u) || ((t = n).nodeType ? c(e, n, r) : p(e, n, r)) }]; for (; o > l; l++) if (n = i.relative[e[l].type]) f = [yt(vt(f), n)]; else { if (n = i.filter[e[l].type].apply(null, e[l].matches), n[v]) { for (r = ++l; o > r; r++) if (i.relative[e[r].type]) break; return bt(l > 1 && vt(f), l > 1 && mt(e.slice(0, l - 1).concat({ value: " " === e[l - 2].type ? "*" : "" })).replace(z, "$1"), n, r > l && wt(e.slice(l, r)), o > r && wt(e = e.slice(r)), o > r && mt(e)) } f.push(n) } return vt(f) } function Tt(e, t) { var n = 0, o = t.length > 0, s = e.length > 0, a = function (a, l, c, f, h) { var d, g, m, y = [], v = 0, x = "0", b = a && [], T = null != h, C = u, k = a || s && i.find.TAG("*", h && l.parentNode || l), N = w += null == C ? 1 : Math.random() || .1; for (T && (u = l !== p && l, r = n) ; null != (d = k[x]) ; x++) { if (s && d) { g = 0; while (m = e[g++]) if (m(d, l, c)) { f.push(d); break } T && (w = N, r = ++n) } o && ((d = !m && d) && v--, a && b.push(d)) } if (v += x, o && x !== v) { g = 0; while (m = t[g++]) m(b, y, l, c); if (a) { if (v > 0) while (x--) b[x] || y[x] || (y[x] = q.call(f)); y = xt(y) } O.apply(f, y), T && !a && y.length > 0 && v + t.length > 1 && ot.uniqueSort(f) } return T && (w = N, u = C), b }; return o ? at(a) : a } a = ot.compile = function (e, t) { var n, r = [], i = [], o = N[e + " "]; if (!o) { t || (t = gt(e)), n = t.length; while (n--) o = wt(t[n]), o[v] ? r.push(o) : i.push(o); o = N(e, Tt(i, r)) } return o }; function Ct(e, t, n) { var r = 0, i = t.length; for (; i > r; r++) ot(e, t[r], n); return n } function kt(e, t, r, o) { var s, u, l, c, p, f = gt(e); if (!o && 1 === f.length) { if (u = f[0] = f[0].slice(0), u.length > 2 && "ID" === (l = u[0]).type && n.getById && 9 === t.nodeType && h && i.relative[u[1].type]) { if (t = (i.find.ID(l.matches[0].replace(nt, rt), t) || [])[0], !t) return r; e = e.slice(u.shift().value.length) } s = J.needsContext.test(e) ? 0 : u.length; while (s--) { if (l = u[s], i.relative[c = l.type]) break; if ((p = i.find[c]) && (o = p(l.matches[0].replace(nt, rt), U.test(u[0].type) && t.parentNode || t))) { if (u.splice(s, 1), e = o.length && mt(u), !e) return O.apply(r, o), r; break } } } return a(e, f)(o, t, !h, r, U.test(e)), r } n.sortStable = v.split("").sort(S).join("") === v, n.detectDuplicates = E, c(), n.sortDetached = ut(function (e) { return 1 & e.compareDocumentPosition(p.createElement("div")) }), ut(function (e) { return e.innerHTML = "<a href='#'></a>", "#" === e.firstChild.getAttribute("href") }) || lt("type|href|height|width", function (e, t, n) { return n ? undefined : e.getAttribute(t, "type" === t.toLowerCase() ? 1 : 2) }), n.attributes && ut(function (e) { return e.innerHTML = "<input/>", e.firstChild.setAttribute("value", ""), "" === e.firstChild.getAttribute("value") }) || lt("value", function (e, t, n) { return n || "input" !== e.nodeName.toLowerCase() ? undefined : e.defaultValue }), ut(function (e) { return null == e.getAttribute("disabled") }) || lt(R, function (e, t, n) { var r; return n ? undefined : (r = e.getAttributeNode(t)) && r.specified ? r.value : e[t] === !0 ? t.toLowerCase() : null }), x.find = ot, x.expr = ot.selectors, x.expr[":"] = x.expr.pseudos, x.unique = ot.uniqueSort, x.text = ot.getText, x.isXMLDoc = ot.isXML, x.contains = ot.contains }(e); var D = {}; function A(e) { var t = D[e] = {}; return x.each(e.match(w) || [], function (e, n) { t[n] = !0 }), t } x.Callbacks = function (e) { e = "string" == typeof e ? D[e] || A(e) : x.extend({}, e); var t, n, r, i, o, s, a = [], u = !e.once && [], l = function (p) { for (t = e.memory && p, n = !0, s = i || 0, i = 0, o = a.length, r = !0; a && o > s; s++) if (a[s].apply(p[0], p[1]) === !1 && e.stopOnFalse) { t = !1; break } r = !1, a && (u ? u.length && l(u.shift()) : t ? a = [] : c.disable()) }, c = { add: function () { if (a) { var n = a.length; (function s(t) { x.each(t, function (t, n) { var r = x.type(n); "function" === r ? e.unique && c.has(n) || a.push(n) : n && n.length && "string" !== r && s(n) }) })(arguments), r ? o = a.length : t && (i = n, l(t)) } return this }, remove: function () { return a && x.each(arguments, function (e, t) { var n; while ((n = x.inArray(t, a, n)) > -1) a.splice(n, 1), r && (o >= n && o--, s >= n && s--) }), this }, has: function (e) { return e ? x.inArray(e, a) > -1 : !(!a || !a.length) }, empty: function () { return a = [], o = 0, this }, disable: function () { return a = u = t = undefined, this }, disabled: function () { return !a }, lock: function () { return u = undefined, t || c.disable(), this }, locked: function () { return !u }, fireWith: function (e, t) { return !a || n && !u || (t = t || [], t = [e, t.slice ? t.slice() : t], r ? u.push(t) : l(t)), this }, fire: function () { return c.fireWith(this, arguments), this }, fired: function () { return !!n } }; return c }, x.extend({ Deferred: function (e) { var t = [["resolve", "done", x.Callbacks("once memory"), "resolved"], ["reject", "fail", x.Callbacks("once memory"), "rejected"], ["notify", "progress", x.Callbacks("memory")]], n = "pending", r = { state: function () { return n }, always: function () { return i.done(arguments).fail(arguments), this }, then: function () { var e = arguments; return x.Deferred(function (n) { x.each(t, function (t, o) { var s = o[0], a = x.isFunction(e[t]) && e[t]; i[o[1]](function () { var e = a && a.apply(this, arguments); e && x.isFunction(e.promise) ? e.promise().done(n.resolve).fail(n.reject).progress(n.notify) : n[s + "With"](this === r ? n.promise() : this, a ? [e] : arguments) }) }), e = null }).promise() }, promise: function (e) { return null != e ? x.extend(e, r) : r } }, i = {}; return r.pipe = r.then, x.each(t, function (e, o) { var s = o[2], a = o[3]; r[o[1]] = s.add, a && s.add(function () { n = a }, t[1 ^ e][2].disable, t[2][2].lock), i[o[0]] = function () { return i[o[0] + "With"](this === i ? r : this, arguments), this }, i[o[0] + "With"] = s.fireWith }), r.promise(i), e && e.call(i, i), i }, when: function (e) { var t = 0, n = d.call(arguments), r = n.length, i = 1 !== r || e && x.isFunction(e.promise) ? r : 0, o = 1 === i ? e : x.Deferred(), s = function (e, t, n) { return function (r) { t[e] = this, n[e] = arguments.length > 1 ? d.call(arguments) : r, n === a ? o.notifyWith(t, n) : --i || o.resolveWith(t, n) } }, a, u, l; if (r > 1) for (a = Array(r), u = Array(r), l = Array(r) ; r > t; t++) n[t] && x.isFunction(n[t].promise) ? n[t].promise().done(s(t, l, n)).fail(o.reject).progress(s(t, u, a)) : --i; return i || o.resolveWith(l, n), o.promise() } }), x.support = function (t) { var n = o.createElement("input"), r = o.createDocumentFragment(), i = o.createElement("div"), s = o.createElement("select"), a = s.appendChild(o.createElement("option")); return n.type ? (n.type = "checkbox", t.checkOn = "" !== n.value, t.optSelected = a.selected, t.reliableMarginRight = !0, t.boxSizingReliable = !0, t.pixelPosition = !1, n.checked = !0, t.noCloneChecked = n.cloneNode(!0).checked, s.disabled = !0, t.optDisabled = !a.disabled, n = o.createElement("input"), n.value = "t", n.type = "radio", t.radioValue = "t" === n.value, n.setAttribute("checked", "t"), n.setAttribute("name", "t"), r.appendChild(n), t.checkClone = r.cloneNode(!0).cloneNode(!0).lastChild.checked, t.focusinBubbles = "onfocusin" in e, i.style.backgroundClip = "content-box", i.cloneNode(!0).style.backgroundClip = "", t.clearCloneStyle = "content-box" === i.style.backgroundClip, x(function () { var n, r, s = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box", a = o.getElementsByTagName("body")[0]; a && (n = o.createElement("div"), n.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", a.appendChild(n).appendChild(i), i.innerHTML = "", i.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%", x.swap(a, null != a.style.zoom ? { zoom: 1 } : {}, function () { t.boxSizing = 4 === i.offsetWidth }), e.getComputedStyle && (t.pixelPosition = "1%" !== (e.getComputedStyle(i, null) || {}).top, t.boxSizingReliable = "4px" === (e.getComputedStyle(i, null) || { width: "4px" }).width, r = i.appendChild(o.createElement("div")), r.style.cssText = i.style.cssText = s, r.style.marginRight = r.style.width = "0", i.style.width = "1px", t.reliableMarginRight = !parseFloat((e.getComputedStyle(r, null) || {}).marginRight)), a.removeChild(n)) }), t) : t }({}); var L, q, H = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, O = /([A-Z])/g; function F() { Object.defineProperty(this.cache = {}, 0, { get: function () { return {} } }), this.expando = x.expando + Math.random() } F.uid = 1, F.accepts = function (e) { return e.nodeType ? 1 === e.nodeType || 9 === e.nodeType : !0 }, F.prototype = { key: function (e) { if (!F.accepts(e)) return 0; var t = {}, n = e[this.expando]; if (!n) { n = F.uid++; try { t[this.expando] = { value: n }, Object.defineProperties(e, t) } catch (r) { t[this.expando] = n, x.extend(e, t) } } return this.cache[n] || (this.cache[n] = {}), n }, set: function (e, t, n) { var r, i = this.key(e), o = this.cache[i]; if ("string" == typeof t) o[t] = n; else if (x.isEmptyObject(o)) x.extend(this.cache[i], t); else for (r in t) o[r] = t[r]; return o }, get: function (e, t) { var n = this.cache[this.key(e)]; return t === undefined ? n : n[t] }, access: function (e, t, n) { var r; return t === undefined || t && "string" == typeof t && n === undefined ? (r = this.get(e, t), r !== undefined ? r : this.get(e, x.camelCase(t))) : (this.set(e, t, n), n !== undefined ? n : t) }, remove: function (e, t) { var n, r, i, o = this.key(e), s = this.cache[o]; if (t === undefined) this.cache[o] = {}; else { x.isArray(t) ? r = t.concat(t.map(x.camelCase)) : (i = x.camelCase(t), t in s ? r = [t, i] : (r = i, r = r in s ? [r] : r.match(w) || [])), n = r.length; while (n--) delete s[r[n]] } }, hasData: function (e) { return !x.isEmptyObject(this.cache[e[this.expando]] || {}) }, discard: function (e) { e[this.expando] && delete this.cache[e[this.expando]] } }, L = new F, q = new F, x.extend({ acceptData: F.accepts, hasData: function (e) { return L.hasData(e) || q.hasData(e) }, data: function (e, t, n) { return L.access(e, t, n) }, removeData: function (e, t) { L.remove(e, t) }, _data: function (e, t, n) { return q.access(e, t, n) }, _removeData: function (e, t) { q.remove(e, t) } }), x.fn.extend({ data: function (e, t) { var n, r, i = this[0], o = 0, s = null; if (e === undefined) { if (this.length && (s = L.get(i), 1 === i.nodeType && !q.get(i, "hasDataAttrs"))) { for (n = i.attributes; n.length > o; o++) r = n[o].name, 0 === r.indexOf("data-") && (r = x.camelCase(r.slice(5)), P(i, r, s[r])); q.set(i, "hasDataAttrs", !0) } return s } return "object" == typeof e ? this.each(function () { L.set(this, e) }) : x.access(this, function (t) { var n, r = x.camelCase(e); if (i && t === undefined) { if (n = L.get(i, e), n !== undefined) return n; if (n = L.get(i, r), n !== undefined) return n; if (n = P(i, r, undefined), n !== undefined) return n } else this.each(function () { var n = L.get(this, r); L.set(this, r, t), -1 !== e.indexOf("-") && n !== undefined && L.set(this, e, t) }) }, null, t, arguments.length > 1, null, !0) }, removeData: function (e) { return this.each(function () { L.remove(this, e) }) } }); function P(e, t, n) { var r; if (n === undefined && 1 === e.nodeType) if (r = "data-" + t.replace(O, "-$1").toLowerCase(), n = e.getAttribute(r), "string" == typeof n) { try { n = "true" === n ? !0 : "false" === n ? !1 : "null" === n ? null : +n + "" === n ? +n : H.test(n) ? JSON.parse(n) : n } catch (i) { } L.set(e, t, n) } else n = undefined; return n } x.extend({
		queue: function (e, t, n) { var r; return e ? (t = (t || "fx") + "queue", r = q.get(e, t), n && (!r || x.isArray(n) ? r = q.access(e, t, x.makeArray(n)) : r.push(n)), r || []) : undefined }, dequeue: function (e, t) {
			t = t || "fx"; var n = x.queue(e, t), r = n.length, i = n.shift(), o = x._queueHooks(e, t), s = function () {
				x.dequeue(e, t)
			}; "inprogress" === i && (i = n.shift(), r--), i && ("fx" === t && n.unshift("inprogress"), delete o.stop, i.call(e, s, o)), !r && o && o.empty.fire()
		}, _queueHooks: function (e, t) { var n = t + "queueHooks"; return q.get(e, n) || q.access(e, n, { empty: x.Callbacks("once memory").add(function () { q.remove(e, [t + "queue", n]) }) }) }
	}), x.fn.extend({ queue: function (e, t) { var n = 2; return "string" != typeof e && (t = e, e = "fx", n--), n > arguments.length ? x.queue(this[0], e) : t === undefined ? this : this.each(function () { var n = x.queue(this, e, t); x._queueHooks(this, e), "fx" === e && "inprogress" !== n[0] && x.dequeue(this, e) }) }, dequeue: function (e) { return this.each(function () { x.dequeue(this, e) }) }, delay: function (e, t) { return e = x.fx ? x.fx.speeds[e] || e : e, t = t || "fx", this.queue(t, function (t, n) { var r = setTimeout(t, e); n.stop = function () { clearTimeout(r) } }) }, clearQueue: function (e) { return this.queue(e || "fx", []) }, promise: function (e, t) { var n, r = 1, i = x.Deferred(), o = this, s = this.length, a = function () { --r || i.resolveWith(o, [o]) }; "string" != typeof e && (t = e, e = undefined), e = e || "fx"; while (s--) n = q.get(o[s], e + "queueHooks"), n && n.empty && (r++, n.empty.add(a)); return a(), i.promise(t) } }); var R, M, W = /[\t\r\n\f]/g, $ = /\r/g, B = /^(?:input|select|textarea|button)$/i; x.fn.extend({ attr: function (e, t) { return x.access(this, x.attr, e, t, arguments.length > 1) }, removeAttr: function (e) { return this.each(function () { x.removeAttr(this, e) }) }, prop: function (e, t) { return x.access(this, x.prop, e, t, arguments.length > 1) }, removeProp: function (e) { return this.each(function () { delete this[x.propFix[e] || e] }) }, addClass: function (e) { var t, n, r, i, o, s = 0, a = this.length, u = "string" == typeof e && e; if (x.isFunction(e)) return this.each(function (t) { x(this).addClass(e.call(this, t, this.className)) }); if (u) for (t = (e || "").match(w) || []; a > s; s++) if (n = this[s], r = 1 === n.nodeType && (n.className ? (" " + n.className + " ").replace(W, " ") : " ")) { o = 0; while (i = t[o++]) 0 > r.indexOf(" " + i + " ") && (r += i + " "); n.className = x.trim(r) } return this }, removeClass: function (e) { var t, n, r, i, o, s = 0, a = this.length, u = 0 === arguments.length || "string" == typeof e && e; if (x.isFunction(e)) return this.each(function (t) { x(this).removeClass(e.call(this, t, this.className)) }); if (u) for (t = (e || "").match(w) || []; a > s; s++) if (n = this[s], r = 1 === n.nodeType && (n.className ? (" " + n.className + " ").replace(W, " ") : "")) { o = 0; while (i = t[o++]) while (r.indexOf(" " + i + " ") >= 0) r = r.replace(" " + i + " ", " "); n.className = e ? x.trim(r) : "" } return this }, toggleClass: function (e, t) { var n = typeof e; return "boolean" == typeof t && "string" === n ? t ? this.addClass(e) : this.removeClass(e) : x.isFunction(e) ? this.each(function (n) { x(this).toggleClass(e.call(this, n, this.className, t), t) }) : this.each(function () { if ("string" === n) { var t, i = 0, o = x(this), s = e.match(w) || []; while (t = s[i++]) o.hasClass(t) ? o.removeClass(t) : o.addClass(t) } else (n === r || "boolean" === n) && (this.className && q.set(this, "__className__", this.className), this.className = this.className || e === !1 ? "" : q.get(this, "__className__") || "") }) }, hasClass: function (e) { var t = " " + e + " ", n = 0, r = this.length; for (; r > n; n++) if (1 === this[n].nodeType && (" " + this[n].className + " ").replace(W, " ").indexOf(t) >= 0) return !0; return !1 }, val: function (e) { var t, n, r, i = this[0]; { if (arguments.length) return r = x.isFunction(e), this.each(function (n) { var i; 1 === this.nodeType && (i = r ? e.call(this, n, x(this).val()) : e, null == i ? i = "" : "number" == typeof i ? i += "" : x.isArray(i) && (i = x.map(i, function (e) { return null == e ? "" : e + "" })), t = x.valHooks[this.type] || x.valHooks[this.nodeName.toLowerCase()], t && "set" in t && t.set(this, i, "value") !== undefined || (this.value = i)) }); if (i) return t = x.valHooks[i.type] || x.valHooks[i.nodeName.toLowerCase()], t && "get" in t && (n = t.get(i, "value")) !== undefined ? n : (n = i.value, "string" == typeof n ? n.replace($, "") : null == n ? "" : n) } } }), x.extend({ valHooks: { option: { get: function (e) { var t = e.attributes.value; return !t || t.specified ? e.value : e.text } }, select: { get: function (e) { var t, n, r = e.options, i = e.selectedIndex, o = "select-one" === e.type || 0 > i, s = o ? null : [], a = o ? i + 1 : r.length, u = 0 > i ? a : o ? i : 0; for (; a > u; u++) if (n = r[u], !(!n.selected && u !== i || (x.support.optDisabled ? n.disabled : null !== n.getAttribute("disabled")) || n.parentNode.disabled && x.nodeName(n.parentNode, "optgroup"))) { if (t = x(n).val(), o) return t; s.push(t) } return s }, set: function (e, t) { var n, r, i = e.options, o = x.makeArray(t), s = i.length; while (s--) r = i[s], (r.selected = x.inArray(x(r).val(), o) >= 0) && (n = !0); return n || (e.selectedIndex = -1), o } } }, attr: function (e, t, n) { var i, o, s = e.nodeType; if (e && 3 !== s && 8 !== s && 2 !== s) return typeof e.getAttribute === r ? x.prop(e, t, n) : (1 === s && x.isXMLDoc(e) || (t = t.toLowerCase(), i = x.attrHooks[t] || (x.expr.match.bool.test(t) ? M : R)), n === undefined ? i && "get" in i && null !== (o = i.get(e, t)) ? o : (o = x.find.attr(e, t), null == o ? undefined : o) : null !== n ? i && "set" in i && (o = i.set(e, n, t)) !== undefined ? o : (e.setAttribute(t, n + ""), n) : (x.removeAttr(e, t), undefined)) }, removeAttr: function (e, t) { var n, r, i = 0, o = t && t.match(w); if (o && 1 === e.nodeType) while (n = o[i++]) r = x.propFix[n] || n, x.expr.match.bool.test(n) && (e[r] = !1), e.removeAttribute(n) }, attrHooks: { type: { set: function (e, t) { if (!x.support.radioValue && "radio" === t && x.nodeName(e, "input")) { var n = e.value; return e.setAttribute("type", t), n && (e.value = n), t } } } }, propFix: { "for": "htmlFor", "class": "className" }, prop: function (e, t, n) { var r, i, o, s = e.nodeType; if (e && 3 !== s && 8 !== s && 2 !== s) return o = 1 !== s || !x.isXMLDoc(e), o && (t = x.propFix[t] || t, i = x.propHooks[t]), n !== undefined ? i && "set" in i && (r = i.set(e, n, t)) !== undefined ? r : e[t] = n : i && "get" in i && null !== (r = i.get(e, t)) ? r : e[t] }, propHooks: { tabIndex: { get: function (e) { return e.hasAttribute("tabindex") || B.test(e.nodeName) || e.href ? e.tabIndex : -1 } } } }), M = { set: function (e, t, n) { return t === !1 ? x.removeAttr(e, n) : e.setAttribute(n, n), n } }, x.each(x.expr.match.bool.source.match(/\w+/g), function (e, t) { var n = x.expr.attrHandle[t] || x.find.attr; x.expr.attrHandle[t] = function (e, t, r) { var i = x.expr.attrHandle[t], o = r ? undefined : (x.expr.attrHandle[t] = undefined) != n(e, t, r) ? t.toLowerCase() : null; return x.expr.attrHandle[t] = i, o } }), x.support.optSelected || (x.propHooks.selected = { get: function (e) { var t = e.parentNode; return t && t.parentNode && t.parentNode.selectedIndex, null } }), x.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { x.propFix[this.toLowerCase()] = this }), x.each(["radio", "checkbox"], function () { x.valHooks[this] = { set: function (e, t) { return x.isArray(t) ? e.checked = x.inArray(x(e).val(), t) >= 0 : undefined } }, x.support.checkOn || (x.valHooks[this].get = function (e) { return null === e.getAttribute("value") ? "on" : e.value }) }); var I = /^key/, z = /^(?:mouse|contextmenu)|click/, _ = /^(?:focusinfocus|focusoutblur)$/, X = /^([^.]*)(?:\.(.+)|)$/; function U() { return !0 } function Y() { return !1 } function V() { try { return o.activeElement } catch (e) { } } x.event = { global: {}, add: function (e, t, n, i, o) { var s, a, u, l, c, p, f, h, d, g, m, y = q.get(e); if (y) { n.handler && (s = n, n = s.handler, o = s.selector), n.guid || (n.guid = x.guid++), (l = y.events) || (l = y.events = {}), (a = y.handle) || (a = y.handle = function (e) { return typeof x === r || e && x.event.triggered === e.type ? undefined : x.event.dispatch.apply(a.elem, arguments) }, a.elem = e), t = (t || "").match(w) || [""], c = t.length; while (c--) u = X.exec(t[c]) || [], d = m = u[1], g = (u[2] || "").split(".").sort(), d && (f = x.event.special[d] || {}, d = (o ? f.delegateType : f.bindType) || d, f = x.event.special[d] || {}, p = x.extend({ type: d, origType: m, data: i, handler: n, guid: n.guid, selector: o, needsContext: o && x.expr.match.needsContext.test(o), namespace: g.join(".") }, s), (h = l[d]) || (h = l[d] = [], h.delegateCount = 0, f.setup && f.setup.call(e, i, g, a) !== !1 || e.addEventListener && e.addEventListener(d, a, !1)), f.add && (f.add.call(e, p), p.handler.guid || (p.handler.guid = n.guid)), o ? h.splice(h.delegateCount++, 0, p) : h.push(p), x.event.global[d] = !0); e = null } }, remove: function (e, t, n, r, i) { var o, s, a, u, l, c, p, f, h, d, g, m = q.hasData(e) && q.get(e); if (m && (u = m.events)) { t = (t || "").match(w) || [""], l = t.length; while (l--) if (a = X.exec(t[l]) || [], h = g = a[1], d = (a[2] || "").split(".").sort(), h) { p = x.event.special[h] || {}, h = (r ? p.delegateType : p.bindType) || h, f = u[h] || [], a = a[2] && RegExp("(^|\\.)" + d.join("\\.(?:.*\\.|)") + "(\\.|$)"), s = o = f.length; while (o--) c = f[o], !i && g !== c.origType || n && n.guid !== c.guid || a && !a.test(c.namespace) || r && r !== c.selector && ("**" !== r || !c.selector) || (f.splice(o, 1), c.selector && f.delegateCount--, p.remove && p.remove.call(e, c)); s && !f.length && (p.teardown && p.teardown.call(e, d, m.handle) !== !1 || x.removeEvent(e, h, m.handle), delete u[h]) } else for (h in u) x.event.remove(e, h + t[l], n, r, !0); x.isEmptyObject(u) && (delete m.handle, q.remove(e, "events")) } }, trigger: function (t, n, r, i) { var s, a, u, l, c, p, f, h = [r || o], d = y.call(t, "type") ? t.type : t, g = y.call(t, "namespace") ? t.namespace.split(".") : []; if (a = u = r = r || o, 3 !== r.nodeType && 8 !== r.nodeType && !_.test(d + x.event.triggered) && (d.indexOf(".") >= 0 && (g = d.split("."), d = g.shift(), g.sort()), c = 0 > d.indexOf(":") && "on" + d, t = t[x.expando] ? t : new x.Event(d, "object" == typeof t && t), t.isTrigger = i ? 2 : 3, t.namespace = g.join("."), t.namespace_re = t.namespace ? RegExp("(^|\\.)" + g.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, t.result = undefined, t.target || (t.target = r), n = null == n ? [t] : x.makeArray(n, [t]), f = x.event.special[d] || {}, i || !f.trigger || f.trigger.apply(r, n) !== !1)) { if (!i && !f.noBubble && !x.isWindow(r)) { for (l = f.delegateType || d, _.test(l + d) || (a = a.parentNode) ; a; a = a.parentNode) h.push(a), u = a; u === (r.ownerDocument || o) && h.push(u.defaultView || u.parentWindow || e) } s = 0; while ((a = h[s++]) && !t.isPropagationStopped()) t.type = s > 1 ? l : f.bindType || d, p = (q.get(a, "events") || {})[t.type] && q.get(a, "handle"), p && p.apply(a, n), p = c && a[c], p && x.acceptData(a) && p.apply && p.apply(a, n) === !1 && t.preventDefault(); return t.type = d, i || t.isDefaultPrevented() || f._default && f._default.apply(h.pop(), n) !== !1 || !x.acceptData(r) || c && x.isFunction(r[d]) && !x.isWindow(r) && (u = r[c], u && (r[c] = null), x.event.triggered = d, r[d](), x.event.triggered = undefined, u && (r[c] = u)), t.result } }, dispatch: function (e) { e = x.event.fix(e); var t, n, r, i, o, s = [], a = d.call(arguments), u = (q.get(this, "events") || {})[e.type] || [], l = x.event.special[e.type] || {}; if (a[0] = e, e.delegateTarget = this, !l.preDispatch || l.preDispatch.call(this, e) !== !1) { s = x.event.handlers.call(this, e, u), t = 0; while ((i = s[t++]) && !e.isPropagationStopped()) { e.currentTarget = i.elem, n = 0; while ((o = i.handlers[n++]) && !e.isImmediatePropagationStopped()) (!e.namespace_re || e.namespace_re.test(o.namespace)) && (e.handleObj = o, e.data = o.data, r = ((x.event.special[o.origType] || {}).handle || o.handler).apply(i.elem, a), r !== undefined && (e.result = r) === !1 && (e.preventDefault(), e.stopPropagation())) } return l.postDispatch && l.postDispatch.call(this, e), e.result } }, handlers: function (e, t) { var n, r, i, o, s = [], a = t.delegateCount, u = e.target; if (a && u.nodeType && (!e.button || "click" !== e.type)) for (; u !== this; u = u.parentNode || this) if (u.disabled !== !0 || "click" !== e.type) { for (r = [], n = 0; a > n; n++) o = t[n], i = o.selector + " ", r[i] === undefined && (r[i] = o.needsContext ? x(i, this).index(u) >= 0 : x.find(i, this, null, [u]).length), r[i] && r.push(o); r.length && s.push({ elem: u, handlers: r }) } return t.length > a && s.push({ elem: this, handlers: t.slice(a) }), s }, props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split(" "), filter: function (e, t) { return null == e.which && (e.which = null != t.charCode ? t.charCode : t.keyCode), e } }, mouseHooks: { props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function (e, t) { var n, r, i, s = t.button; return null == e.pageX && null != t.clientX && (n = e.target.ownerDocument || o, r = n.documentElement, i = n.body, e.pageX = t.clientX + (r && r.scrollLeft || i && i.scrollLeft || 0) - (r && r.clientLeft || i && i.clientLeft || 0), e.pageY = t.clientY + (r && r.scrollTop || i && i.scrollTop || 0) - (r && r.clientTop || i && i.clientTop || 0)), e.which || s === undefined || (e.which = 1 & s ? 1 : 2 & s ? 3 : 4 & s ? 2 : 0), e } }, fix: function (e) { if (e[x.expando]) return e; var t, n, r, i = e.type, s = e, a = this.fixHooks[i]; a || (this.fixHooks[i] = a = z.test(i) ? this.mouseHooks : I.test(i) ? this.keyHooks : {}), r = a.props ? this.props.concat(a.props) : this.props, e = new x.Event(s), t = r.length; while (t--) n = r[t], e[n] = s[n]; return e.target || (e.target = o), 3 === e.target.nodeType && (e.target = e.target.parentNode), a.filter ? a.filter(e, s) : e }, special: { load: { noBubble: !0 }, focus: { trigger: function () { return this !== V() && this.focus ? (this.focus(), !1) : undefined }, delegateType: "focusin" }, blur: { trigger: function () { return this === V() && this.blur ? (this.blur(), !1) : undefined }, delegateType: "focusout" }, click: { trigger: function () { return "checkbox" === this.type && this.click && x.nodeName(this, "input") ? (this.click(), !1) : undefined }, _default: function (e) { return x.nodeName(e.target, "a") } }, beforeunload: { postDispatch: function (e) { e.result !== undefined && (e.originalEvent.returnValue = e.result) } } }, simulate: function (e, t, n, r) { var i = x.extend(new x.Event, n, { type: e, isSimulated: !0, originalEvent: {} }); r ? x.event.trigger(i, null, t) : x.event.dispatch.call(t, i), i.isDefaultPrevented() && n.preventDefault() } }, x.removeEvent = function (e, t, n) { e.removeEventListener && e.removeEventListener(t, n, !1) }, x.Event = function (e, t) { return this instanceof x.Event ? (e && e.type ? (this.originalEvent = e, this.type = e.type, this.isDefaultPrevented = e.defaultPrevented || e.getPreventDefault && e.getPreventDefault() ? U : Y) : this.type = e, t && x.extend(this, t), this.timeStamp = e && e.timeStamp || x.now(), this[x.expando] = !0, undefined) : new x.Event(e, t) }, x.Event.prototype = { isDefaultPrevented: Y, isPropagationStopped: Y, isImmediatePropagationStopped: Y, preventDefault: function () { var e = this.originalEvent; this.isDefaultPrevented = U, e && e.preventDefault && e.preventDefault() }, stopPropagation: function () { var e = this.originalEvent; this.isPropagationStopped = U, e && e.stopPropagation && e.stopPropagation() }, stopImmediatePropagation: function () { this.isImmediatePropagationStopped = U, this.stopPropagation() } }, x.each({ mouseenter: "mouseover", mouseleave: "mouseout" }, function (e, t) { x.event.special[e] = { delegateType: t, bindType: t, handle: function (e) { var n, r = this, i = e.relatedTarget, o = e.handleObj; return (!i || i !== r && !x.contains(r, i)) && (e.type = o.origType, n = o.handler.apply(this, arguments), e.type = t), n } } }), x.support.focusinBubbles || x.each({ focus: "focusin", blur: "focusout" }, function (e, t) { var n = 0, r = function (e) { x.event.simulate(t, e.target, x.event.fix(e), !0) }; x.event.special[t] = { setup: function () { 0 === n++ && o.addEventListener(e, r, !0) }, teardown: function () { 0 === --n && o.removeEventListener(e, r, !0) } } }), x.fn.extend({ on: function (e, t, n, r, i) { var o, s; if ("object" == typeof e) { "string" != typeof t && (n = n || t, t = undefined); for (s in e) this.on(s, t, n, e[s], i); return this } if (null == n && null == r ? (r = t, n = t = undefined) : null == r && ("string" == typeof t ? (r = n, n = undefined) : (r = n, n = t, t = undefined)), r === !1) r = Y; else if (!r) return this; return 1 === i && (o = r, r = function (e) { return x().off(e), o.apply(this, arguments) }, r.guid = o.guid || (o.guid = x.guid++)), this.each(function () { x.event.add(this, e, r, n, t) }) }, one: function (e, t, n, r) { return this.on(e, t, n, r, 1) }, off: function (e, t, n) { var r, i; if (e && e.preventDefault && e.handleObj) return r = e.handleObj, x(e.delegateTarget).off(r.namespace ? r.origType + "." + r.namespace : r.origType, r.selector, r.handler), this; if ("object" == typeof e) { for (i in e) this.off(i, t, e[i]); return this } return (t === !1 || "function" == typeof t) && (n = t, t = undefined), n === !1 && (n = Y), this.each(function () { x.event.remove(this, e, n, t) }) }, trigger: function (e, t) { return this.each(function () { x.event.trigger(e, t, this) }) }, triggerHandler: function (e, t) { var n = this[0]; return n ? x.event.trigger(e, t, n, !0) : undefined } }); var G = /^.[^:#\[\.,]*$/, J = /^(?:parents|prev(?:Until|All))/, Q = x.expr.match.needsContext, K = { children: !0, contents: !0, next: !0, prev: !0 }; x.fn.extend({ find: function (e) { var t, n = [], r = this, i = r.length; if ("string" != typeof e) return this.pushStack(x(e).filter(function () { for (t = 0; i > t; t++) if (x.contains(r[t], this)) return !0 })); for (t = 0; i > t; t++) x.find(e, r[t], n); return n = this.pushStack(i > 1 ? x.unique(n) : n), n.selector = this.selector ? this.selector + " " + e : e, n }, has: function (e) { var t = x(e, this), n = t.length; return this.filter(function () { var e = 0; for (; n > e; e++) if (x.contains(this, t[e])) return !0 }) }, not: function (e) { return this.pushStack(et(this, e || [], !0)) }, filter: function (e) { return this.pushStack(et(this, e || [], !1)) }, is: function (e) { return !!et(this, "string" == typeof e && Q.test(e) ? x(e) : e || [], !1).length }, closest: function (e, t) { var n, r = 0, i = this.length, o = [], s = Q.test(e) || "string" != typeof e ? x(e, t || this.context) : 0; for (; i > r; r++) for (n = this[r]; n && n !== t; n = n.parentNode) if (11 > n.nodeType && (s ? s.index(n) > -1 : 1 === n.nodeType && x.find.matchesSelector(n, e))) { n = o.push(n); break } return this.pushStack(o.length > 1 ? x.unique(o) : o) }, index: function (e) { return e ? "string" == typeof e ? g.call(x(e), this[0]) : g.call(this, e.jquery ? e[0] : e) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 }, add: function (e, t) { var n = "string" == typeof e ? x(e, t) : x.makeArray(e && e.nodeType ? [e] : e), r = x.merge(this.get(), n); return this.pushStack(x.unique(r)) }, addBack: function (e) { return this.add(null == e ? this.prevObject : this.prevObject.filter(e)) } }); function Z(e, t) { while ((e = e[t]) && 1 !== e.nodeType); return e } x.each({ parent: function (e) { var t = e.parentNode; return t && 11 !== t.nodeType ? t : null }, parents: function (e) { return x.dir(e, "parentNode") }, parentsUntil: function (e, t, n) { return x.dir(e, "parentNode", n) }, next: function (e) { return Z(e, "nextSibling") }, prev: function (e) { return Z(e, "previousSibling") }, nextAll: function (e) { return x.dir(e, "nextSibling") }, prevAll: function (e) { return x.dir(e, "previousSibling") }, nextUntil: function (e, t, n) { return x.dir(e, "nextSibling", n) }, prevUntil: function (e, t, n) { return x.dir(e, "previousSibling", n) }, siblings: function (e) { return x.sibling((e.parentNode || {}).firstChild, e) }, children: function (e) { return x.sibling(e.firstChild) }, contents: function (e) { return e.contentDocument || x.merge([], e.childNodes) } }, function (e, t) { x.fn[e] = function (n, r) { var i = x.map(this, t, n); return "Until" !== e.slice(-5) && (r = n), r && "string" == typeof r && (i = x.filter(r, i)), this.length > 1 && (K[e] || x.unique(i), J.test(e) && i.reverse()), this.pushStack(i) } }), x.extend({ filter: function (e, t, n) { var r = t[0]; return n && (e = ":not(" + e + ")"), 1 === t.length && 1 === r.nodeType ? x.find.matchesSelector(r, e) ? [r] : [] : x.find.matches(e, x.grep(t, function (e) { return 1 === e.nodeType })) }, dir: function (e, t, n) { var r = [], i = n !== undefined; while ((e = e[t]) && 9 !== e.nodeType) if (1 === e.nodeType) { if (i && x(e).is(n)) break; r.push(e) } return r }, sibling: function (e, t) { var n = []; for (; e; e = e.nextSibling) 1 === e.nodeType && e !== t && n.push(e); return n } }); function et(e, t, n) { if (x.isFunction(t)) return x.grep(e, function (e, r) { return !!t.call(e, r, e) !== n }); if (t.nodeType) return x.grep(e, function (e) { return e === t !== n }); if ("string" == typeof t) { if (G.test(t)) return x.filter(t, e, n); t = x.filter(t, e) } return x.grep(e, function (e) { return g.call(t, e) >= 0 !== n }) } var tt = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, nt = /<([\w:]+)/, rt = /<|&#?\w+;/, it = /<(?:script|style|link)/i, ot = /^(?:checkbox|radio)$/i, st = /checked\s*(?:[^=]|=\s*.checked.)/i, at = /^$|\/(?:java|ecma)script/i, ut = /^true\/(.*)/, lt = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, ct = { option: [1, "<select multiple='multiple'>", "</select>"], thead: [1, "<table>", "</table>"], col: [2, "<table><colgroup>", "</colgroup></table>"], tr: [2, "<table><tbody>", "</tbody></table>"], td: [3, "<table><tbody><tr>", "</tr></tbody></table>"], _default: [0, "", ""] }; ct.optgroup = ct.option, ct.tbody = ct.tfoot = ct.colgroup = ct.caption = ct.thead, ct.th = ct.td, x.fn.extend({ text: function (e) { return x.access(this, function (e) { return e === undefined ? x.text(this) : this.empty().append((this[0] && this[0].ownerDocument || o).createTextNode(e)) }, null, e, arguments.length) }, append: function () { return this.domManip(arguments, function (e) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var t = pt(this, e); t.appendChild(e) } }) }, prepend: function () { return this.domManip(arguments, function (e) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var t = pt(this, e); t.insertBefore(e, t.firstChild) } }) }, before: function () { return this.domManip(arguments, function (e) { this.parentNode && this.parentNode.insertBefore(e, this) }) }, after: function () { return this.domManip(arguments, function (e) { this.parentNode && this.parentNode.insertBefore(e, this.nextSibling) }) }, remove: function (e, t) { var n, r = e ? x.filter(e, this) : this, i = 0; for (; null != (n = r[i]) ; i++) t || 1 !== n.nodeType || x.cleanData(mt(n)), n.parentNode && (t && x.contains(n.ownerDocument, n) && dt(mt(n, "script")), n.parentNode.removeChild(n)); return this }, empty: function () { var e, t = 0; for (; null != (e = this[t]) ; t++) 1 === e.nodeType && (x.cleanData(mt(e, !1)), e.textContent = ""); return this }, clone: function (e, t) { return e = null == e ? !1 : e, t = null == t ? e : t, this.map(function () { return x.clone(this, e, t) }) }, html: function (e) { return x.access(this, function (e) { var t = this[0] || {}, n = 0, r = this.length; if (e === undefined && 1 === t.nodeType) return t.innerHTML; if ("string" == typeof e && !it.test(e) && !ct[(nt.exec(e) || ["", ""])[1].toLowerCase()]) { e = e.replace(tt, "<$1></$2>"); try { for (; r > n; n++) t = this[n] || {}, 1 === t.nodeType && (x.cleanData(mt(t, !1)), t.innerHTML = e); t = 0 } catch (i) { } } t && this.empty().append(e) }, null, e, arguments.length) }, replaceWith: function () { var e = x.map(this, function (e) { return [e.nextSibling, e.parentNode] }), t = 0; return this.domManip(arguments, function (n) { var r = e[t++], i = e[t++]; i && (r && r.parentNode !== i && (r = this.nextSibling), x(this).remove(), i.insertBefore(n, r)) }, !0), t ? this : this.remove() }, detach: function (e) { return this.remove(e, !0) }, domManip: function (e, t, n) { e = f.apply([], e); var r, i, o, s, a, u, l = 0, c = this.length, p = this, h = c - 1, d = e[0], g = x.isFunction(d); if (g || !(1 >= c || "string" != typeof d || x.support.checkClone) && st.test(d)) return this.each(function (r) { var i = p.eq(r); g && (e[0] = d.call(this, r, i.html())), i.domManip(e, t, n) }); if (c && (r = x.buildFragment(e, this[0].ownerDocument, !1, !n && this), i = r.firstChild, 1 === r.childNodes.length && (r = i), i)) { for (o = x.map(mt(r, "script"), ft), s = o.length; c > l; l++) a = r, l !== h && (a = x.clone(a, !0, !0), s && x.merge(o, mt(a, "script"))), t.call(this[l], a, l); if (s) for (u = o[o.length - 1].ownerDocument, x.map(o, ht), l = 0; s > l; l++) a = o[l], at.test(a.type || "") && !q.access(a, "globalEval") && x.contains(u, a) && (a.src ? x._evalUrl(a.src) : x.globalEval(a.textContent.replace(lt, ""))) } return this } }), x.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (e, t) { x.fn[e] = function (e) { var n, r = [], i = x(e), o = i.length - 1, s = 0; for (; o >= s; s++) n = s === o ? this : this.clone(!0), x(i[s])[t](n), h.apply(r, n.get()); return this.pushStack(r) } }), x.extend({ clone: function (e, t, n) { var r, i, o, s, a = e.cloneNode(!0), u = x.contains(e.ownerDocument, e); if (!(x.support.noCloneChecked || 1 !== e.nodeType && 11 !== e.nodeType || x.isXMLDoc(e))) for (s = mt(a), o = mt(e), r = 0, i = o.length; i > r; r++) yt(o[r], s[r]); if (t) if (n) for (o = o || mt(e), s = s || mt(a), r = 0, i = o.length; i > r; r++) gt(o[r], s[r]); else gt(e, a); return s = mt(a, "script"), s.length > 0 && dt(s, !u && mt(e, "script")), a }, buildFragment: function (e, t, n, r) { var i, o, s, a, u, l, c = 0, p = e.length, f = t.createDocumentFragment(), h = []; for (; p > c; c++) if (i = e[c], i || 0 === i) if ("object" === x.type(i)) x.merge(h, i.nodeType ? [i] : i); else if (rt.test(i)) { o = o || f.appendChild(t.createElement("div")), s = (nt.exec(i) || ["", ""])[1].toLowerCase(), a = ct[s] || ct._default, o.innerHTML = a[1] + i.replace(tt, "<$1></$2>") + a[2], l = a[0]; while (l--) o = o.lastChild; x.merge(h, o.childNodes), o = f.firstChild, o.textContent = "" } else h.push(t.createTextNode(i)); f.textContent = "", c = 0; while (i = h[c++]) if ((!r || -1 === x.inArray(i, r)) && (u = x.contains(i.ownerDocument, i), o = mt(f.appendChild(i), "script"), u && dt(o), n)) { l = 0; while (i = o[l++]) at.test(i.type || "") && n.push(i) } return f }, cleanData: function (e) { var t, n, r, i, o, s, a = x.event.special, u = 0; for (; (n = e[u]) !== undefined; u++) { if (F.accepts(n) && (o = n[q.expando], o && (t = q.cache[o]))) { if (r = Object.keys(t.events || {}), r.length) for (s = 0; (i = r[s]) !== undefined; s++) a[i] ? x.event.remove(n, i) : x.removeEvent(n, i, t.handle); q.cache[o] && delete q.cache[o] } delete L.cache[n[L.expando]] } }, _evalUrl: function (e) { return x.ajax({ url: e, type: "GET", dataType: "script", async: !1, global: !1, "throws": !0 }) } }); function pt(e, t) { return x.nodeName(e, "table") && x.nodeName(1 === t.nodeType ? t : t.firstChild, "tr") ? e.getElementsByTagName("tbody")[0] || e.appendChild(e.ownerDocument.createElement("tbody")) : e } function ft(e) { return e.type = (null !== e.getAttribute("type")) + "/" + e.type, e } function ht(e) { var t = ut.exec(e.type); return t ? e.type = t[1] : e.removeAttribute("type"), e } function dt(e, t) { var n = e.length, r = 0; for (; n > r; r++) q.set(e[r], "globalEval", !t || q.get(t[r], "globalEval")) } function gt(e, t) { var n, r, i, o, s, a, u, l; if (1 === t.nodeType) { if (q.hasData(e) && (o = q.access(e), s = q.set(t, o), l = o.events)) { delete s.handle, s.events = {}; for (i in l) for (n = 0, r = l[i].length; r > n; n++) x.event.add(t, i, l[i][n]) } L.hasData(e) && (a = L.access(e), u = x.extend({}, a), L.set(t, u)) } } function mt(e, t) { var n = e.getElementsByTagName ? e.getElementsByTagName(t || "*") : e.querySelectorAll ? e.querySelectorAll(t || "*") : []; return t === undefined || t && x.nodeName(e, t) ? x.merge([e], n) : n } function yt(e, t) { var n = t.nodeName.toLowerCase(); "input" === n && ot.test(e.type) ? t.checked = e.checked : ("input" === n || "textarea" === n) && (t.defaultValue = e.defaultValue) } x.fn.extend({ wrapAll: function (e) { var t; return x.isFunction(e) ? this.each(function (t) { x(this).wrapAll(e.call(this, t)) }) : (this[0] && (t = x(e, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && t.insertBefore(this[0]), t.map(function () { var e = this; while (e.firstElementChild) e = e.firstElementChild; return e }).append(this)), this) }, wrapInner: function (e) { return x.isFunction(e) ? this.each(function (t) { x(this).wrapInner(e.call(this, t)) }) : this.each(function () { var t = x(this), n = t.contents(); n.length ? n.wrapAll(e) : t.append(e) }) }, wrap: function (e) { var t = x.isFunction(e); return this.each(function (n) { x(this).wrapAll(t ? e.call(this, n) : e) }) }, unwrap: function () { return this.parent().each(function () { x.nodeName(this, "body") || x(this).replaceWith(this.childNodes) }).end() } }); var vt, xt, bt = /^(none|table(?!-c[ea]).+)/, wt = /^margin/, Tt = RegExp("^(" + b + ")(.*)$", "i"), Ct = RegExp("^(" + b + ")(?!px)[a-z%]+$", "i"), kt = RegExp("^([+-])=(" + b + ")", "i"), Nt = { BODY: "block" }, Et = { position: "absolute", visibility: "hidden", display: "block" }, St = { letterSpacing: 0, fontWeight: 400 }, jt = ["Top", "Right", "Bottom", "Left"], Dt = ["Webkit", "O", "Moz", "ms"]; function At(e, t) { if (t in e) return t; var n = t.charAt(0).toUpperCase() + t.slice(1), r = t, i = Dt.length; while (i--) if (t = Dt[i] + n, t in e) return t; return r } function Lt(e, t) { return e = t || e, "none" === x.css(e, "display") || !x.contains(e.ownerDocument, e) } function qt(t) { return e.getComputedStyle(t, null) } function Ht(e, t) { var n, r, i, o = [], s = 0, a = e.length; for (; a > s; s++) r = e[s], r.style && (o[s] = q.get(r, "olddisplay"), n = r.style.display, t ? (o[s] || "none" !== n || (r.style.display = ""), "" === r.style.display && Lt(r) && (o[s] = q.access(r, "olddisplay", Rt(r.nodeName)))) : o[s] || (i = Lt(r), (n && "none" !== n || !i) && q.set(r, "olddisplay", i ? n : x.css(r, "display")))); for (s = 0; a > s; s++) r = e[s], r.style && (t && "none" !== r.style.display && "" !== r.style.display || (r.style.display = t ? o[s] || "" : "none")); return e } x.fn.extend({ css: function (e, t) { return x.access(this, function (e, t, n) { var r, i, o = {}, s = 0; if (x.isArray(t)) { for (r = qt(e), i = t.length; i > s; s++) o[t[s]] = x.css(e, t[s], !1, r); return o } return n !== undefined ? x.style(e, t, n) : x.css(e, t) }, e, t, arguments.length > 1) }, show: function () { return Ht(this, !0) }, hide: function () { return Ht(this) }, toggle: function (e) { return "boolean" == typeof e ? e ? this.show() : this.hide() : this.each(function () { Lt(this) ? x(this).show() : x(this).hide() }) } }), x.extend({ cssHooks: { opacity: { get: function (e, t) { if (t) { var n = vt(e, "opacity"); return "" === n ? "1" : n } } } }, cssNumber: { columnCount: !0, fillOpacity: !0, fontWeight: !0, lineHeight: !0, opacity: !0, order: !0, orphans: !0, widows: !0, zIndex: !0, zoom: !0 }, cssProps: { "float": "cssFloat" }, style: function (e, t, n, r) { if (e && 3 !== e.nodeType && 8 !== e.nodeType && e.style) { var i, o, s, a = x.camelCase(t), u = e.style; return t = x.cssProps[a] || (x.cssProps[a] = At(u, a)), s = x.cssHooks[t] || x.cssHooks[a], n === undefined ? s && "get" in s && (i = s.get(e, !1, r)) !== undefined ? i : u[t] : (o = typeof n, "string" === o && (i = kt.exec(n)) && (n = (i[1] + 1) * i[2] + parseFloat(x.css(e, t)), o = "number"), null == n || "number" === o && isNaN(n) || ("number" !== o || x.cssNumber[a] || (n += "px"), x.support.clearCloneStyle || "" !== n || 0 !== t.indexOf("background") || (u[t] = "inherit"), s && "set" in s && (n = s.set(e, n, r)) === undefined || (u[t] = n)), undefined) } }, css: function (e, t, n, r) { var i, o, s, a = x.camelCase(t); return t = x.cssProps[a] || (x.cssProps[a] = At(e.style, a)), s = x.cssHooks[t] || x.cssHooks[a], s && "get" in s && (i = s.get(e, !0, n)), i === undefined && (i = vt(e, t, r)), "normal" === i && t in St && (i = St[t]), "" === n || n ? (o = parseFloat(i), n === !0 || x.isNumeric(o) ? o || 0 : i) : i } }), vt = function (e, t, n) { var r, i, o, s = n || qt(e), a = s ? s.getPropertyValue(t) || s[t] : undefined, u = e.style; return s && ("" !== a || x.contains(e.ownerDocument, e) || (a = x.style(e, t)), Ct.test(a) && wt.test(t) && (r = u.width, i = u.minWidth, o = u.maxWidth, u.minWidth = u.maxWidth = u.width = a, a = s.width, u.width = r, u.minWidth = i, u.maxWidth = o)), a }; function Ot(e, t, n) { var r = Tt.exec(t); return r ? Math.max(0, r[1] - (n || 0)) + (r[2] || "px") : t } function Ft(e, t, n, r, i) { var o = n === (r ? "border" : "content") ? 4 : "width" === t ? 1 : 0, s = 0; for (; 4 > o; o += 2) "margin" === n && (s += x.css(e, n + jt[o], !0, i)), r ? ("content" === n && (s -= x.css(e, "padding" + jt[o], !0, i)), "margin" !== n && (s -= x.css(e, "border" + jt[o] + "Width", !0, i))) : (s += x.css(e, "padding" + jt[o], !0, i), "padding" !== n && (s += x.css(e, "border" + jt[o] + "Width", !0, i))); return s } function Pt(e, t, n) { var r = !0, i = "width" === t ? e.offsetWidth : e.offsetHeight, o = qt(e), s = x.support.boxSizing && "border-box" === x.css(e, "boxSizing", !1, o); if (0 >= i || null == i) { if (i = vt(e, t, o), (0 > i || null == i) && (i = e.style[t]), Ct.test(i)) return i; r = s && (x.support.boxSizingReliable || i === e.style[t]), i = parseFloat(i) || 0 } return i + Ft(e, t, n || (s ? "border" : "content"), r, o) + "px" } function Rt(e) { var t = o, n = Nt[e]; return n || (n = Mt(e, t), "none" !== n && n || (xt = (xt || x("<iframe frameborder='0' width='0' height='0'/>").css("cssText", "display:block !important")).appendTo(t.documentElement), t = (xt[0].contentWindow || xt[0].contentDocument).document, t.write("<!doctype html><html><body>"), t.close(), n = Mt(e, t), xt.detach()), Nt[e] = n), n } function Mt(e, t) { var n = x(t.createElement(e)).appendTo(t.body), r = x.css(n[0], "display"); return n.remove(), r } x.each(["height", "width"], function (e, t) { x.cssHooks[t] = { get: function (e, n, r) { return n ? 0 === e.offsetWidth && bt.test(x.css(e, "display")) ? x.swap(e, Et, function () { return Pt(e, t, r) }) : Pt(e, t, r) : undefined }, set: function (e, n, r) { var i = r && qt(e); return Ot(e, n, r ? Ft(e, t, r, x.support.boxSizing && "border-box" === x.css(e, "boxSizing", !1, i), i) : 0) } } }), x(function () { x.support.reliableMarginRight || (x.cssHooks.marginRight = { get: function (e, t) { return t ? x.swap(e, { display: "inline-block" }, vt, [e, "marginRight"]) : undefined } }), !x.support.pixelPosition && x.fn.position && x.each(["top", "left"], function (e, t) { x.cssHooks[t] = { get: function (e, n) { return n ? (n = vt(e, t), Ct.test(n) ? x(e).position()[t] + "px" : n) : undefined } } }) }), x.expr && x.expr.filters && (x.expr.filters.hidden = function (e) { return 0 >= e.offsetWidth && 0 >= e.offsetHeight }, x.expr.filters.visible = function (e) { return !x.expr.filters.hidden(e) }), x.each({ margin: "", padding: "", border: "Width" }, function (e, t) { x.cssHooks[e + t] = { expand: function (n) { var r = 0, i = {}, o = "string" == typeof n ? n.split(" ") : [n]; for (; 4 > r; r++) i[e + jt[r] + t] = o[r] || o[r - 2] || o[0]; return i } }, wt.test(e) || (x.cssHooks[e + t].set = Ot) }); var Wt = /%20/g, $t = /\[\]$/, Bt = /\r?\n/g, It = /^(?:submit|button|image|reset|file)$/i, zt = /^(?:input|select|textarea|keygen)/i; x.fn.extend({ serialize: function () { return x.param(this.serializeArray()) }, serializeArray: function () { return this.map(function () { var e = x.prop(this, "elements"); return e ? x.makeArray(e) : this }).filter(function () { var e = this.type; return this.name && !x(this).is(":disabled") && zt.test(this.nodeName) && !It.test(e) && (this.checked || !ot.test(e)) }).map(function (e, t) { var n = x(this).val(); return null == n ? null : x.isArray(n) ? x.map(n, function (e) { return { name: t.name, value: e.replace(Bt, "\r\n") } }) : { name: t.name, value: n.replace(Bt, "\r\n") } }).get() } }), x.param = function (e, t) { var n, r = [], i = function (e, t) { t = x.isFunction(t) ? t() : null == t ? "" : t, r[r.length] = encodeURIComponent(e) + "=" + encodeURIComponent(t) }; if (t === undefined && (t = x.ajaxSettings && x.ajaxSettings.traditional), x.isArray(e) || e.jquery && !x.isPlainObject(e)) x.each(e, function () { i(this.name, this.value) }); else for (n in e) _t(n, e[n], t, i); return r.join("&").replace(Wt, "+") }; function _t(e, t, n, r) { var i; if (x.isArray(t)) x.each(t, function (t, i) { n || $t.test(e) ? r(e, i) : _t(e + "[" + ("object" == typeof i ? t : "") + "]", i, n, r) }); else if (n || "object" !== x.type(t)) r(e, t); else for (i in t) _t(e + "[" + i + "]", t[i], n, r) } x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function (e, t) { x.fn[t] = function (e, n) { return arguments.length > 0 ? this.on(t, null, e, n) : this.trigger(t) } }), x.fn.extend({
		hover: function (e, t) { return this.mouseenter(e).mouseleave(t || e) }, bind: function (e, t, n) { return this.on(e, null, t, n) }, unbind: function (e, t) {
			return this.off(e, null, t)
		}, delegate: function (e, t, n, r) { return this.on(t, e, n, r) }, undelegate: function (e, t, n) { return 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n) }
	}); var Xt, Ut, Yt = x.now(), Vt = /\?/, Gt = /#.*$/, Jt = /([?&])_=[^&]*/, Qt = /^(.*?):[ \t]*([^\r\n]*)$/gm, Kt = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, Zt = /^(?:GET|HEAD)$/, en = /^\/\//, tn = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, nn = x.fn.load, rn = {}, on = {}, sn = "*/".concat("*"); try { Ut = i.href } catch (an) { Ut = o.createElement("a"), Ut.href = "", Ut = Ut.href } Xt = tn.exec(Ut.toLowerCase()) || []; function un(e) { return function (t, n) { "string" != typeof t && (n = t, t = "*"); var r, i = 0, o = t.toLowerCase().match(w) || []; if (x.isFunction(n)) while (r = o[i++]) "+" === r[0] ? (r = r.slice(1) || "*", (e[r] = e[r] || []).unshift(n)) : (e[r] = e[r] || []).push(n) } } function ln(e, t, n, r) { var i = {}, o = e === on; function s(a) { var u; return i[a] = !0, x.each(e[a] || [], function (e, a) { var l = a(t, n, r); return "string" != typeof l || o || i[l] ? o ? !(u = l) : undefined : (t.dataTypes.unshift(l), s(l), !1) }), u } return s(t.dataTypes[0]) || !i["*"] && s("*") } function cn(e, t) { var n, r, i = x.ajaxSettings.flatOptions || {}; for (n in t) t[n] !== undefined && ((i[n] ? e : r || (r = {}))[n] = t[n]); return r && x.extend(!0, e, r), e } x.fn.load = function (e, t, n) { if ("string" != typeof e && nn) return nn.apply(this, arguments); var r, i, o, s = this, a = e.indexOf(" "); return a >= 0 && (r = e.slice(a), e = e.slice(0, a)), x.isFunction(t) ? (n = t, t = undefined) : t && "object" == typeof t && (i = "POST"), s.length > 0 && x.ajax({ url: e, type: i, dataType: "html", data: t }).done(function (e) { o = arguments, s.html(r ? x("<div>").append(x.parseHTML(e)).find(r) : e) }).complete(n && function (e, t) { s.each(n, o || [e.responseText, t, e]) }), this }, x.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (e, t) { x.fn[t] = function (e) { return this.on(t, e) } }), x.extend({ active: 0, lastModified: {}, etag: {}, ajaxSettings: { url: Ut, type: "GET", isLocal: Kt.test(Xt[1]), global: !0, processData: !0, async: !0, contentType: "application/x-www-form-urlencoded; charset=UTF-8", accepts: { "*": sn, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /xml/, html: /html/, json: /json/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, converters: { "* text": String, "text html": !0, "text json": x.parseJSON, "text xml": x.parseXML }, flatOptions: { url: !0, context: !0 } }, ajaxSetup: function (e, t) { return t ? cn(cn(e, x.ajaxSettings), t) : cn(x.ajaxSettings, e) }, ajaxPrefilter: un(rn), ajaxTransport: un(on), ajax: function (e, t) { "object" == typeof e && (t = e, e = undefined), t = t || {}; var n, r, i, o, s, a, u, l, c = x.ajaxSetup({}, t), p = c.context || c, f = c.context && (p.nodeType || p.jquery) ? x(p) : x.event, h = x.Deferred(), d = x.Callbacks("once memory"), g = c.statusCode || {}, m = {}, y = {}, v = 0, b = "canceled", T = { readyState: 0, getResponseHeader: function (e) { var t; if (2 === v) { if (!o) { o = {}; while (t = Qt.exec(i)) o[t[1].toLowerCase()] = t[2] } t = o[e.toLowerCase()] } return null == t ? null : t }, getAllResponseHeaders: function () { return 2 === v ? i : null }, setRequestHeader: function (e, t) { var n = e.toLowerCase(); return v || (e = y[n] = y[n] || e, m[e] = t), this }, overrideMimeType: function (e) { return v || (c.mimeType = e), this }, statusCode: function (e) { var t; if (e) if (2 > v) for (t in e) g[t] = [g[t], e[t]]; else T.always(e[T.status]); return this }, abort: function (e) { var t = e || b; return n && n.abort(t), k(0, t), this } }; if (h.promise(T).complete = d.add, T.success = T.done, T.error = T.fail, c.url = ((e || c.url || Ut) + "").replace(Gt, "").replace(en, Xt[1] + "//"), c.type = t.method || t.type || c.method || c.type, c.dataTypes = x.trim(c.dataType || "*").toLowerCase().match(w) || [""], null == c.crossDomain && (a = tn.exec(c.url.toLowerCase()), c.crossDomain = !(!a || a[1] === Xt[1] && a[2] === Xt[2] && (a[3] || ("http:" === a[1] ? "80" : "443")) === (Xt[3] || ("http:" === Xt[1] ? "80" : "443")))), c.data && c.processData && "string" != typeof c.data && (c.data = x.param(c.data, c.traditional)), ln(rn, c, t, T), 2 === v) return T; u = c.global, u && 0 === x.active++ && x.event.trigger("ajaxStart"), c.type = c.type.toUpperCase(), c.hasContent = !Zt.test(c.type), r = c.url, c.hasContent || (c.data && (r = c.url += (Vt.test(r) ? "&" : "?") + c.data, delete c.data), c.cache === !1 && (c.url = Jt.test(r) ? r.replace(Jt, "$1_=" + Yt++) : r + (Vt.test(r) ? "&" : "?") + "_=" + Yt++)), c.ifModified && (x.lastModified[r] && T.setRequestHeader("If-Modified-Since", x.lastModified[r]), x.etag[r] && T.setRequestHeader("If-None-Match", x.etag[r])), (c.data && c.hasContent && c.contentType !== !1 || t.contentType) && T.setRequestHeader("Content-Type", c.contentType), T.setRequestHeader("Accept", c.dataTypes[0] && c.accepts[c.dataTypes[0]] ? c.accepts[c.dataTypes[0]] + ("*" !== c.dataTypes[0] ? ", " + sn + "; q=0.01" : "") : c.accepts["*"]); for (l in c.headers) T.setRequestHeader(l, c.headers[l]); if (c.beforeSend && (c.beforeSend.call(p, T, c) === !1 || 2 === v)) return T.abort(); b = "abort"; for (l in { success: 1, error: 1, complete: 1 }) T[l](c[l]); if (n = ln(on, c, t, T)) { T.readyState = 1, u && f.trigger("ajaxSend", [T, c]), c.async && c.timeout > 0 && (s = setTimeout(function () { T.abort("timeout") }, c.timeout)); try { v = 1, n.send(m, k) } catch (C) { if (!(2 > v)) throw C; k(-1, C) } } else k(-1, "No Transport"); function k(e, t, o, a) { var l, m, y, b, w, C = t; 2 !== v && (v = 2, s && clearTimeout(s), n = undefined, i = a || "", T.readyState = e > 0 ? 4 : 0, l = e >= 200 && 300 > e || 304 === e, o && (b = pn(c, T, o)), b = fn(c, b, T, l), l ? (c.ifModified && (w = T.getResponseHeader("Last-Modified"), w && (x.lastModified[r] = w), w = T.getResponseHeader("etag"), w && (x.etag[r] = w)), 204 === e || "HEAD" === c.type ? C = "nocontent" : 304 === e ? C = "notmodified" : (C = b.state, m = b.data, y = b.error, l = !y)) : (y = C, (e || !C) && (C = "error", 0 > e && (e = 0))), T.status = e, T.statusText = (t || C) + "", l ? h.resolveWith(p, [m, C, T]) : h.rejectWith(p, [T, C, y]), T.statusCode(g), g = undefined, u && f.trigger(l ? "ajaxSuccess" : "ajaxError", [T, c, l ? m : y]), d.fireWith(p, [T, C]), u && (f.trigger("ajaxComplete", [T, c]), --x.active || x.event.trigger("ajaxStop"))) } return T }, getJSON: function (e, t, n) { return x.get(e, t, n, "json") }, getScript: function (e, t) { return x.get(e, undefined, t, "script") } }), x.each(["get", "post"], function (e, t) { x[t] = function (e, n, r, i) { return x.isFunction(n) && (i = i || r, r = n, n = undefined), x.ajax({ url: e, type: t, dataType: i, data: n, success: r }) } }); function pn(e, t, n) { var r, i, o, s, a = e.contents, u = e.dataTypes; while ("*" === u[0]) u.shift(), r === undefined && (r = e.mimeType || t.getResponseHeader("Content-Type")); if (r) for (i in a) if (a[i] && a[i].test(r)) { u.unshift(i); break } if (u[0] in n) o = u[0]; else { for (i in n) { if (!u[0] || e.converters[i + " " + u[0]]) { o = i; break } s || (s = i) } o = o || s } return o ? (o !== u[0] && u.unshift(o), n[o]) : undefined } function fn(e, t, n, r) { var i, o, s, a, u, l = {}, c = e.dataTypes.slice(); if (c[1]) for (s in e.converters) l[s.toLowerCase()] = e.converters[s]; o = c.shift(); while (o) if (e.responseFields[o] && (n[e.responseFields[o]] = t), !u && r && e.dataFilter && (t = e.dataFilter(t, e.dataType)), u = o, o = c.shift()) if ("*" === o) o = u; else if ("*" !== u && u !== o) { if (s = l[u + " " + o] || l["* " + o], !s) for (i in l) if (a = i.split(" "), a[1] === o && (s = l[u + " " + a[0]] || l["* " + a[0]])) { s === !0 ? s = l[i] : l[i] !== !0 && (o = a[0], c.unshift(a[1])); break } if (s !== !0) if (s && e["throws"]) t = s(t); else try { t = s(t) } catch (p) { return { state: "parsererror", error: s ? p : "No conversion from " + u + " to " + o } } } return { state: "success", data: t } } x.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, contents: { script: /(?:java|ecma)script/ }, converters: { "text script": function (e) { return x.globalEval(e), e } } }), x.ajaxPrefilter("script", function (e) { e.cache === undefined && (e.cache = !1), e.crossDomain && (e.type = "GET") }), x.ajaxTransport("script", function (e) { if (e.crossDomain) { var t, n; return { send: function (r, i) { t = x("<script>").prop({ async: !0, charset: e.scriptCharset, src: e.url }).on("load error", n = function (e) { t.remove(), n = null, e && i("error" === e.type ? 404 : 200, e.type) }), o.head.appendChild(t[0]) }, abort: function () { n && n() } } } }); var hn = [], dn = /(=)\?(?=&|$)|\?\?/; x.ajaxSetup({ jsonp: "callback", jsonpCallback: function () { var e = hn.pop() || x.expando + "_" + Yt++; return this[e] = !0, e } }), x.ajaxPrefilter("json jsonp", function (t, n, r) { var i, o, s, a = t.jsonp !== !1 && (dn.test(t.url) ? "url" : "string" == typeof t.data && !(t.contentType || "").indexOf("application/x-www-form-urlencoded") && dn.test(t.data) && "data"); return a || "jsonp" === t.dataTypes[0] ? (i = t.jsonpCallback = x.isFunction(t.jsonpCallback) ? t.jsonpCallback() : t.jsonpCallback, a ? t[a] = t[a].replace(dn, "$1" + i) : t.jsonp !== !1 && (t.url += (Vt.test(t.url) ? "&" : "?") + t.jsonp + "=" + i), t.converters["script json"] = function () { return s || x.error(i + " was not called"), s[0] }, t.dataTypes[0] = "json", o = e[i], e[i] = function () { s = arguments }, r.always(function () { e[i] = o, t[i] && (t.jsonpCallback = n.jsonpCallback, hn.push(i)), s && x.isFunction(o) && o(s[0]), s = o = undefined }), "script") : undefined }), x.ajaxSettings.xhr = function () { try { return new XMLHttpRequest } catch (e) { } }; var gn = x.ajaxSettings.xhr(), mn = { 0: 200, 1223: 204 }, yn = 0, vn = {}; e.ActiveXObject && x(e).on("unload", function () { for (var e in vn) vn[e](); vn = undefined }), x.support.cors = !!gn && "withCredentials" in gn, x.support.ajax = gn = !!gn, x.ajaxTransport(function (e) { var t; return x.support.cors || gn && !e.crossDomain ? { send: function (n, r) { var i, o, s = e.xhr(); if (s.open(e.type, e.url, e.async, e.username, e.password), e.xhrFields) for (i in e.xhrFields) s[i] = e.xhrFields[i]; e.mimeType && s.overrideMimeType && s.overrideMimeType(e.mimeType), e.crossDomain || n["X-Requested-With"] || (n["X-Requested-With"] = "XMLHttpRequest"); for (i in n) s.setRequestHeader(i, n[i]); t = function (e) { return function () { t && (delete vn[o], t = s.onload = s.onerror = null, "abort" === e ? s.abort() : "error" === e ? r(s.status || 404, s.statusText) : r(mn[s.status] || s.status, s.statusText, "string" == typeof s.responseText ? { text: s.responseText } : undefined, s.getAllResponseHeaders())) } }, s.onload = t(), s.onerror = t("error"), t = vn[o = yn++] = t("abort"), s.send(e.hasContent && e.data || null) }, abort: function () { t && t() } } : undefined }); var xn, bn, wn = /^(?:toggle|show|hide)$/, Tn = RegExp("^(?:([+-])=|)(" + b + ")([a-z%]*)$", "i"), Cn = /queueHooks$/, kn = [An], Nn = { "*": [function (e, t) { var n = this.createTween(e, t), r = n.cur(), i = Tn.exec(t), o = i && i[3] || (x.cssNumber[e] ? "" : "px"), s = (x.cssNumber[e] || "px" !== o && +r) && Tn.exec(x.css(n.elem, e)), a = 1, u = 20; if (s && s[3] !== o) { o = o || s[3], i = i || [], s = +r || 1; do a = a || ".5", s /= a, x.style(n.elem, e, s + o); while (a !== (a = n.cur() / r) && 1 !== a && --u) } return i && (s = n.start = +s || +r || 0, n.unit = o, n.end = i[1] ? s + (i[1] + 1) * i[2] : +i[2]), n }] }; function En() { return setTimeout(function () { xn = undefined }), xn = x.now() } function Sn(e, t, n) { var r, i = (Nn[t] || []).concat(Nn["*"]), o = 0, s = i.length; for (; s > o; o++) if (r = i[o].call(n, t, e)) return r } function jn(e, t, n) { var r, i, o = 0, s = kn.length, a = x.Deferred().always(function () { delete u.elem }), u = function () { if (i) return !1; var t = xn || En(), n = Math.max(0, l.startTime + l.duration - t), r = n / l.duration || 0, o = 1 - r, s = 0, u = l.tweens.length; for (; u > s; s++) l.tweens[s].run(o); return a.notifyWith(e, [l, o, n]), 1 > o && u ? n : (a.resolveWith(e, [l]), !1) }, l = a.promise({ elem: e, props: x.extend({}, t), opts: x.extend(!0, { specialEasing: {} }, n), originalProperties: t, originalOptions: n, startTime: xn || En(), duration: n.duration, tweens: [], createTween: function (t, n) { var r = x.Tween(e, l.opts, t, n, l.opts.specialEasing[t] || l.opts.easing); return l.tweens.push(r), r }, stop: function (t) { var n = 0, r = t ? l.tweens.length : 0; if (i) return this; for (i = !0; r > n; n++) l.tweens[n].run(1); return t ? a.resolveWith(e, [l, t]) : a.rejectWith(e, [l, t]), this } }), c = l.props; for (Dn(c, l.opts.specialEasing) ; s > o; o++) if (r = kn[o].call(l, e, c, l.opts)) return r; return x.map(c, Sn, l), x.isFunction(l.opts.start) && l.opts.start.call(e, l), x.fx.timer(x.extend(u, { elem: e, anim: l, queue: l.opts.queue })), l.progress(l.opts.progress).done(l.opts.done, l.opts.complete).fail(l.opts.fail).always(l.opts.always) } function Dn(e, t) { var n, r, i, o, s; for (n in e) if (r = x.camelCase(n), i = t[r], o = e[n], x.isArray(o) && (i = o[1], o = e[n] = o[0]), n !== r && (e[r] = o, delete e[n]), s = x.cssHooks[r], s && "expand" in s) { o = s.expand(o), delete e[r]; for (n in o) n in e || (e[n] = o[n], t[n] = i) } else t[r] = i } x.Animation = x.extend(jn, { tweener: function (e, t) { x.isFunction(e) ? (t = e, e = ["*"]) : e = e.split(" "); var n, r = 0, i = e.length; for (; i > r; r++) n = e[r], Nn[n] = Nn[n] || [], Nn[n].unshift(t) }, prefilter: function (e, t) { t ? kn.unshift(e) : kn.push(e) } }); function An(e, t, n) { var r, i, o, s, a, u, l = this, c = {}, p = e.style, f = e.nodeType && Lt(e), h = q.get(e, "fxshow"); n.queue || (a = x._queueHooks(e, "fx"), null == a.unqueued && (a.unqueued = 0, u = a.empty.fire, a.empty.fire = function () { a.unqueued || u() }), a.unqueued++, l.always(function () { l.always(function () { a.unqueued--, x.queue(e, "fx").length || a.empty.fire() }) })), 1 === e.nodeType && ("height" in t || "width" in t) && (n.overflow = [p.overflow, p.overflowX, p.overflowY], "inline" === x.css(e, "display") && "none" === x.css(e, "float") && (p.display = "inline-block")), n.overflow && (p.overflow = "hidden", l.always(function () { p.overflow = n.overflow[0], p.overflowX = n.overflow[1], p.overflowY = n.overflow[2] })); for (r in t) if (i = t[r], wn.exec(i)) { if (delete t[r], o = o || "toggle" === i, i === (f ? "hide" : "show")) { if ("show" !== i || !h || h[r] === undefined) continue; f = !0 } c[r] = h && h[r] || x.style(e, r) } if (!x.isEmptyObject(c)) { h ? "hidden" in h && (f = h.hidden) : h = q.access(e, "fxshow", {}), o && (h.hidden = !f), f ? x(e).show() : l.done(function () { x(e).hide() }), l.done(function () { var t; q.remove(e, "fxshow"); for (t in c) x.style(e, t, c[t]) }); for (r in c) s = Sn(f ? h[r] : 0, r, l), r in h || (h[r] = s.start, f && (s.end = s.start, s.start = "width" === r || "height" === r ? 1 : 0)) } } function Ln(e, t, n, r, i) { return new Ln.prototype.init(e, t, n, r, i) } x.Tween = Ln, Ln.prototype = { constructor: Ln, init: function (e, t, n, r, i, o) { this.elem = e, this.prop = n, this.easing = i || "swing", this.options = t, this.start = this.now = this.cur(), this.end = r, this.unit = o || (x.cssNumber[n] ? "" : "px") }, cur: function () { var e = Ln.propHooks[this.prop]; return e && e.get ? e.get(this) : Ln.propHooks._default.get(this) }, run: function (e) { var t, n = Ln.propHooks[this.prop]; return this.pos = t = this.options.duration ? x.easing[this.easing](e, this.options.duration * e, 0, 1, this.options.duration) : e, this.now = (this.end - this.start) * t + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), n && n.set ? n.set(this) : Ln.propHooks._default.set(this), this } }, Ln.prototype.init.prototype = Ln.prototype, Ln.propHooks = { _default: { get: function (e) { var t; return null == e.elem[e.prop] || e.elem.style && null != e.elem.style[e.prop] ? (t = x.css(e.elem, e.prop, ""), t && "auto" !== t ? t : 0) : e.elem[e.prop] }, set: function (e) { x.fx.step[e.prop] ? x.fx.step[e.prop](e) : e.elem.style && (null != e.elem.style[x.cssProps[e.prop]] || x.cssHooks[e.prop]) ? x.style(e.elem, e.prop, e.now + e.unit) : e.elem[e.prop] = e.now } } }, Ln.propHooks.scrollTop = Ln.propHooks.scrollLeft = { set: function (e) { e.elem.nodeType && e.elem.parentNode && (e.elem[e.prop] = e.now) } }, x.each(["toggle", "show", "hide"], function (e, t) { var n = x.fn[t]; x.fn[t] = function (e, r, i) { return null == e || "boolean" == typeof e ? n.apply(this, arguments) : this.animate(qn(t, !0), e, r, i) } }), x.fn.extend({ fadeTo: function (e, t, n, r) { return this.filter(Lt).css("opacity", 0).show().end().animate({ opacity: t }, e, n, r) }, animate: function (e, t, n, r) { var i = x.isEmptyObject(e), o = x.speed(t, n, r), s = function () { var t = jn(this, x.extend({}, e), o); (i || q.get(this, "finish")) && t.stop(!0) }; return s.finish = s, i || o.queue === !1 ? this.each(s) : this.queue(o.queue, s) }, stop: function (e, t, n) { var r = function (e) { var t = e.stop; delete e.stop, t(n) }; return "string" != typeof e && (n = t, t = e, e = undefined), t && e !== !1 && this.queue(e || "fx", []), this.each(function () { var t = !0, i = null != e && e + "queueHooks", o = x.timers, s = q.get(this); if (i) s[i] && s[i].stop && r(s[i]); else for (i in s) s[i] && s[i].stop && Cn.test(i) && r(s[i]); for (i = o.length; i--;) o[i].elem !== this || null != e && o[i].queue !== e || (o[i].anim.stop(n), t = !1, o.splice(i, 1)); (t || !n) && x.dequeue(this, e) }) }, finish: function (e) { return e !== !1 && (e = e || "fx"), this.each(function () { var t, n = q.get(this), r = n[e + "queue"], i = n[e + "queueHooks"], o = x.timers, s = r ? r.length : 0; for (n.finish = !0, x.queue(this, e, []), i && i.stop && i.stop.call(this, !0), t = o.length; t--;) o[t].elem === this && o[t].queue === e && (o[t].anim.stop(!0), o.splice(t, 1)); for (t = 0; s > t; t++) r[t] && r[t].finish && r[t].finish.call(this); delete n.finish }) } }); function qn(e, t) { var n, r = { height: e }, i = 0; for (t = t ? 1 : 0; 4 > i; i += 2 - t) n = jt[i], r["margin" + n] = r["padding" + n] = e; return t && (r.opacity = r.width = e), r } x.each({ slideDown: qn("show"), slideUp: qn("hide"), slideToggle: qn("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function (e, t) { x.fn[e] = function (e, n, r) { return this.animate(t, e, n, r) } }), x.speed = function (e, t, n) { var r = e && "object" == typeof e ? x.extend({}, e) : { complete: n || !n && t || x.isFunction(e) && e, duration: e, easing: n && t || t && !x.isFunction(t) && t }; return r.duration = x.fx.off ? 0 : "number" == typeof r.duration ? r.duration : r.duration in x.fx.speeds ? x.fx.speeds[r.duration] : x.fx.speeds._default, (null == r.queue || r.queue === !0) && (r.queue = "fx"), r.old = r.complete, r.complete = function () { x.isFunction(r.old) && r.old.call(this), r.queue && x.dequeue(this, r.queue) }, r }, x.easing = { linear: function (e) { return e }, swing: function (e) { return .5 - Math.cos(e * Math.PI) / 2 } }, x.timers = [], x.fx = Ln.prototype.init, x.fx.tick = function () { var e, t = x.timers, n = 0; for (xn = x.now() ; t.length > n; n++) e = t[n], e() || t[n] !== e || t.splice(n--, 1); t.length || x.fx.stop(), xn = undefined }, x.fx.timer = function (e) { e() && x.timers.push(e) && x.fx.start() }, x.fx.interval = 13, x.fx.start = function () { bn || (bn = setInterval(x.fx.tick, x.fx.interval)) }, x.fx.stop = function () { clearInterval(bn), bn = null }, x.fx.speeds = { slow: 600, fast: 200, _default: 400 }, x.fx.step = {}, x.expr && x.expr.filters && (x.expr.filters.animated = function (e) { return x.grep(x.timers, function (t) { return e === t.elem }).length }), x.fn.offset = function (e) { if (arguments.length) return e === undefined ? this : this.each(function (t) { x.offset.setOffset(this, e, t) }); var t, n, i = this[0], o = { top: 0, left: 0 }, s = i && i.ownerDocument; if (s) return t = s.documentElement, x.contains(t, i) ? (typeof i.getBoundingClientRect !== r && (o = i.getBoundingClientRect()), n = Hn(s), { top: o.top + n.pageYOffset - t.clientTop, left: o.left + n.pageXOffset - t.clientLeft }) : o }, x.offset = { setOffset: function (e, t, n) { var r, i, o, s, a, u, l, c = x.css(e, "position"), p = x(e), f = {}; "static" === c && (e.style.position = "relative"), a = p.offset(), o = x.css(e, "top"), u = x.css(e, "left"), l = ("absolute" === c || "fixed" === c) && (o + u).indexOf("auto") > -1, l ? (r = p.position(), s = r.top, i = r.left) : (s = parseFloat(o) || 0, i = parseFloat(u) || 0), x.isFunction(t) && (t = t.call(e, n, a)), null != t.top && (f.top = t.top - a.top + s), null != t.left && (f.left = t.left - a.left + i), "using" in t ? t.using.call(e, f) : p.css(f) } }, x.fn.extend({ position: function () { if (this[0]) { var e, t, n = this[0], r = { top: 0, left: 0 }; return "fixed" === x.css(n, "position") ? t = n.getBoundingClientRect() : (e = this.offsetParent(), t = this.offset(), x.nodeName(e[0], "html") || (r = e.offset()), r.top += x.css(e[0], "borderTopWidth", !0), r.left += x.css(e[0], "borderLeftWidth", !0)), { top: t.top - r.top - x.css(n, "marginTop", !0), left: t.left - r.left - x.css(n, "marginLeft", !0) } } }, offsetParent: function () { return this.map(function () { var e = this.offsetParent || s; while (e && !x.nodeName(e, "html") && "static" === x.css(e, "position")) e = e.offsetParent; return e || s }) } }), x.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (t, n) { var r = "pageYOffset" === n; x.fn[t] = function (i) { return x.access(this, function (t, i, o) { var s = Hn(t); return o === undefined ? s ? s[n] : t[i] : (s ? s.scrollTo(r ? e.pageXOffset : o, r ? o : e.pageYOffset) : t[i] = o, undefined) }, t, i, arguments.length, null) } }); function Hn(e) { return x.isWindow(e) ? e : 9 === e.nodeType && e.defaultView } x.each({ Height: "height", Width: "width" }, function (e, t) { x.each({ padding: "inner" + e, content: t, "": "outer" + e }, function (n, r) { x.fn[r] = function (r, i) { var o = arguments.length && (n || "boolean" != typeof r), s = n || (r === !0 || i === !0 ? "margin" : "border"); return x.access(this, function (t, n, r) { var i; return x.isWindow(t) ? t.document.documentElement["client" + e] : 9 === t.nodeType ? (i = t.documentElement, Math.max(t.body["scroll" + e], i["scroll" + e], t.body["offset" + e], i["offset" + e], i["client" + e])) : r === undefined ? x.css(t, n, s) : x.style(t, n, r, s) }, t, o ? r : undefined, o, null) } }) }), x.fn.size = function () { return this.length }, x.fn.andSelf = x.fn.addBack, "object" == typeof module && module && "object" == typeof module.exports ? module.exports = x : "function" == typeof define && define.amd && define("jquery", [], function () { return x }), "object" == typeof e && "object" == typeof e.document && (e.jQuery = e.$ = x)
})(window);;
/*!
 * Flickity PACKAGED v2.2.1
 * Touch, responsive, flickable carousels
 *
 * Licensed GPLv3 for open source use
 * or Flickity Commercial License for commercial use
 *
 * https://flickity.metafizzy.co
 * Copyright 2015-2019 Metafizzy
 */

/**
 * Bridget makes jQuery widgets
 * v2.0.1
 * MIT license
 */

/* jshint browser: true, strict: true, undef: true, unused: true */

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /* globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
      return factory( window, jQuery );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('jquery')
    );
  } else {
    // browser global
    window.jQueryBridget = factory(
      window,
      window.jQuery
    );
  }

}( window, function factory( window, jQuery ) {
'use strict';

// ----- utils ----- //

var arraySlice = Array.prototype.slice;

// helper function for logging errors
// $.error breaks jQuery chaining
var console = window.console;
var logError = typeof console == 'undefined' ? function() {} :
  function( message ) {
    console.error( message );
  };

// ----- jQueryBridget ----- //

function jQueryBridget( namespace, PluginClass, $ ) {
  $ = $ || jQuery || window.jQuery;
  if ( !$ ) {
    return;
  }

  // add option method -> $().plugin('option', {...})
  if ( !PluginClass.prototype.option ) {
    // option setter
    PluginClass.prototype.option = function( opts ) {
      // bail out if not an object
      if ( !$.isPlainObject( opts ) ){
        return;
      }
      this.options = $.extend( true, this.options, opts );
    };
  }

  // make jQuery plugin
  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
    if ( typeof arg0 == 'string' ) {
      // method call $().plugin( 'methodName', { options } )
      // shift arguments by 1
      var args = arraySlice.call( arguments, 1 );
      return methodCall( this, arg0, args );
    }
    // just $().plugin({ options })
    plainCall( this, arg0 );
    return this;
  };

  // $().plugin('methodName')
  function methodCall( $elems, methodName, args ) {
    var returnValue;
    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';

    $elems.each( function( i, elem ) {
      // get instance
      var instance = $.data( elem, namespace );
      if ( !instance ) {
        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
          pluginMethodStr );
        return;
      }

      var method = instance[ methodName ];
      if ( !method || methodName.charAt(0) == '_' ) {
        logError( pluginMethodStr + ' is not a valid method' );
        return;
      }

      // apply method, get return value
      var value = method.apply( instance, args );
      // set return value if value is returned, use only first value
      returnValue = returnValue === undefined ? value : returnValue;
    });

    return returnValue !== undefined ? returnValue : $elems;
  }

  function plainCall( $elems, options ) {
    $elems.each( function( i, elem ) {
      var instance = $.data( elem, namespace );
      if ( instance ) {
        // set options & init
        instance.option( options );
        instance._init();
      } else {
        // initialize new instance
        instance = new PluginClass( elem, options );
        $.data( elem, namespace, instance );
      }
    });
  }

  updateJQuery( $ );

}

// ----- updateJQuery ----- //

// set $.bridget for v1 backwards compatibility
function updateJQuery( $ ) {
  if ( !$ || ( $ && $.bridget ) ) {
    return;
  }
  $.bridget = jQueryBridget;
}

updateJQuery( jQuery || window.jQuery );

// -----  ----- //

return jQueryBridget;

}));

/**
 * EvEmitter v1.1.0
 * Lil' event emitter
 * MIT License
 */

/* jshint unused: true, undef: true, strict: true */

( function( global, factory ) {
  // universal module definition
  /* jshint strict: false */ /* globals define, module, window */
  if ( typeof define == 'function' && define.amd ) {
    // AMD - RequireJS
    define( 'ev-emitter/ev-emitter',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS - Browserify, Webpack
    module.exports = factory();
  } else {
    // Browser globals
    global.EvEmitter = factory();
  }

}( typeof window != 'undefined' ? window : this, function() {



function EvEmitter() {}

var proto = EvEmitter.prototype;

proto.on = function( eventName, listener ) {
  if ( !eventName || !listener ) {
    return;
  }
  // set events hash
  var events = this._events = this._events || {};
  // set listeners array
  var listeners = events[ eventName ] = events[ eventName ] || [];
  // only add once
  if ( listeners.indexOf( listener ) == -1 ) {
    listeners.push( listener );
  }

  return this;
};

proto.once = function( eventName, listener ) {
  if ( !eventName || !listener ) {
    return;
  }
  // add event
  this.on( eventName, listener );
  // set once flag
  // set onceEvents hash
  var onceEvents = this._onceEvents = this._onceEvents || {};
  // set onceListeners object
  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
  // set flag
  onceListeners[ listener ] = true;

  return this;
};

proto.off = function( eventName, listener ) {
  var listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) {
    return;
  }
  var index = listeners.indexOf( listener );
  if ( index != -1 ) {
    listeners.splice( index, 1 );
  }

  return this;
};

proto.emitEvent = function( eventName, args ) {
  var listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) {
    return;
  }
  // copy over to avoid interference if .off() in listener
  listeners = listeners.slice(0);
  args = args || [];
  // once stuff
  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];

  for ( var i=0; i < listeners.length; i++ ) {
    var listener = listeners[i]
    var isOnce = onceListeners && onceListeners[ listener ];
    if ( isOnce ) {
      // remove listener
      // remove before trigger to prevent recursion
      this.off( eventName, listener );
      // unset once flag
      delete onceListeners[ listener ];
    }
    // trigger listener
    listener.apply( this, args );
  }

  return this;
};

proto.allOff = function() {
  delete this._events;
  delete this._onceEvents;
};

return EvEmitter;

}));

/*!
 * getSize v2.0.3
 * measure size of elements
 * MIT license
 */

/* jshint browser: true, strict: true, undef: true, unused: true */
/* globals console: false */

( function( window, factory ) {
  /* jshint strict: false */ /* globals define, module */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'get-size/get-size',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory();
  } else {
    // browser global
    window.getSize = factory();
  }

})( window, function factory() {
'use strict';

// -------------------------- helpers -------------------------- //

// get a number from a string, not a percentage
function getStyleSize( value ) {
  var num = parseFloat( value );
  // not a percent like '100%', and a number
  var isValid = value.indexOf('%') == -1 && !isNaN( num );
  return isValid && num;
}

function noop() {}

var logError = typeof console == 'undefined' ? noop :
  function( message ) {
    console.error( message );
  };

// -------------------------- measurements -------------------------- //

var measurements = [
  'paddingLeft',
  'paddingRight',
  'paddingTop',
  'paddingBottom',
  'marginLeft',
  'marginRight',
  'marginTop',
  'marginBottom',
  'borderLeftWidth',
  'borderRightWidth',
  'borderTopWidth',
  'borderBottomWidth'
];

var measurementsLength = measurements.length;

function getZeroSize() {
  var size = {
    width: 0,
    height: 0,
    innerWidth: 0,
    innerHeight: 0,
    outerWidth: 0,
    outerHeight: 0
  };
  for ( var i=0; i < measurementsLength; i++ ) {
    var measurement = measurements[i];
    size[ measurement ] = 0;
  }
  return size;
}

// -------------------------- getStyle -------------------------- //

/**
 * getStyle, get style of element, check for Firefox bug
 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
 */
function getStyle( elem ) {
  var style = getComputedStyle( elem );
  if ( !style ) {
    logError( 'Style returned ' + style +
      '. Are you running this code in a hidden iframe on Firefox? ' +
      'See https://bit.ly/getsizebug1' );
  }
  return style;
}

// -------------------------- setup -------------------------- //

var isSetup = false;

var isBoxSizeOuter;

/**
 * setup
 * check isBoxSizerOuter
 * do on first getSize() rather than on page load for Firefox bug
 */
function setup() {
  // setup once
  if ( isSetup ) {
    return;
  }
  isSetup = true;

  // -------------------------- box sizing -------------------------- //

  /**
   * Chrome & Safari measure the outer-width on style.width on border-box elems
   * IE11 & Firefox<29 measures the inner-width
   */
  var div = document.createElement('div');
  div.style.width = '200px';
  div.style.padding = '1px 2px 3px 4px';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px 2px 3px 4px';
  div.style.boxSizing = 'border-box';

  var body = document.body || document.documentElement;
  body.appendChild( div );
  var style = getStyle( div );
  // round value for browser zoom. desandro/masonry#928
  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
  getSize.isBoxSizeOuter = isBoxSizeOuter;

  body.removeChild( div );
}

// -------------------------- getSize -------------------------- //

function getSize( elem ) {
  setup();

  // use querySeletor if elem is string
  if ( typeof elem == 'string' ) {
    elem = document.querySelector( elem );
  }

  // do not proceed on non-objects
  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
    return;
  }

  var style = getStyle( elem );

  // if hidden, everything is 0
  if ( style.display == 'none' ) {
    return getZeroSize();
  }

  var size = {};
  size.width = elem.offsetWidth;
  size.height = elem.offsetHeight;

  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';

  // get all measurements
  for ( var i=0; i < measurementsLength; i++ ) {
    var measurement = measurements[i];
    var value = style[ measurement ];
    var num = parseFloat( value );
    // any 'auto', 'medium' value will be 0
    size[ measurement ] = !isNaN( num ) ? num : 0;
  }

  var paddingWidth = size.paddingLeft + size.paddingRight;
  var paddingHeight = size.paddingTop + size.paddingBottom;
  var marginWidth = size.marginLeft + size.marginRight;
  var marginHeight = size.marginTop + size.marginBottom;
  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
  var borderHeight = size.borderTopWidth + size.borderBottomWidth;

  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;

  // overwrite width and height if we can get it from style
  var styleWidth = getStyleSize( style.width );
  if ( styleWidth !== false ) {
    size.width = styleWidth +
      // add padding and border unless it's already including it
      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
  }

  var styleHeight = getStyleSize( style.height );
  if ( styleHeight !== false ) {
    size.height = styleHeight +
      // add padding and border unless it's already including it
      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
  }

  size.innerWidth = size.width - ( paddingWidth + borderWidth );
  size.innerHeight = size.height - ( paddingHeight + borderHeight );

  size.outerWidth = size.width + marginWidth;
  size.outerHeight = size.height + marginHeight;

  return size;
}

return getSize;

});

/**
 * matchesSelector v2.0.2
 * matchesSelector( element, '.selector' )
 * MIT license
 */

/*jshint browser: true, strict: true, undef: true, unused: true */

( function( window, factory ) {
  /*global define: false, module: false */
  'use strict';
  // universal module definition
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'desandro-matches-selector/matches-selector',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory();
  } else {
    // browser global
    window.matchesSelector = factory();
  }

}( window, function factory() {
  'use strict';

  var matchesMethod = ( function() {
    var ElemProto = window.Element.prototype;
    // check for the standard method name first
    if ( ElemProto.matches ) {
      return 'matches';
    }
    // check un-prefixed
    if ( ElemProto.matchesSelector ) {
      return 'matchesSelector';
    }
    // check vendor prefixes
    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];

    for ( var i=0; i < prefixes.length; i++ ) {
      var prefix = prefixes[i];
      var method = prefix + 'MatchesSelector';
      if ( ElemProto[ method ] ) {
        return method;
      }
    }
  })();

  return function matchesSelector( elem, selector ) {
    return elem[ matchesMethod ]( selector );
  };

}));

/**
 * Fizzy UI utils v2.0.7
 * MIT license
 */

/*jshint browser: true, undef: true, unused: true, strict: true */

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'fizzy-ui-utils/utils',[
      'desandro-matches-selector/matches-selector'
    ], function( matchesSelector ) {
      return factory( window, matchesSelector );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('desandro-matches-selector')
    );
  } else {
    // browser global
    window.fizzyUIUtils = factory(
      window,
      window.matchesSelector
    );
  }

}( window, function factory( window, matchesSelector ) {



var utils = {};

// ----- extend ----- //

// extends objects
utils.extend = function( a, b ) {
  for ( var prop in b ) {
    a[ prop ] = b[ prop ];
  }
  return a;
};

// ----- modulo ----- //

utils.modulo = function( num, div ) {
  return ( ( num % div ) + div ) % div;
};

// ----- makeArray ----- //

var arraySlice = Array.prototype.slice;

// turn element or nodeList into an array
utils.makeArray = function( obj ) {
  if ( Array.isArray( obj ) ) {
    // use object if already an array
    return obj;
  }
  // return empty array if undefined or null. #6
  if ( obj === null || obj === undefined ) {
    return [];
  }

  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  if ( isArrayLike ) {
    // convert nodeList to array
    return arraySlice.call( obj );
  }

  // array of single index
  return [ obj ];
};

// ----- removeFrom ----- //

utils.removeFrom = function( ary, obj ) {
  var index = ary.indexOf( obj );
  if ( index != -1 ) {
    ary.splice( index, 1 );
  }
};

// ----- getParent ----- //

utils.getParent = function( elem, selector ) {
  while ( elem.parentNode && elem != document.body ) {
    elem = elem.parentNode;
    if ( matchesSelector( elem, selector ) ) {
      return elem;
    }
  }
};

// ----- getQueryElement ----- //

// use element as selector string
utils.getQueryElement = function( elem ) {
  if ( typeof elem == 'string' ) {
    return document.querySelector( elem );
  }
  return elem;
};

// ----- handleEvent ----- //

// enable .ontype to trigger from .addEventListener( elem, 'type' )
utils.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

// ----- filterFindElements ----- //

utils.filterFindElements = function( elems, selector ) {
  // make array of elems
  elems = utils.makeArray( elems );
  var ffElems = [];

  elems.forEach( function( elem ) {
    // check that elem is an actual element
    if ( !( elem instanceof HTMLElement ) ) {
      return;
    }
    // add elem if no selector
    if ( !selector ) {
      ffElems.push( elem );
      return;
    }
    // filter & find items if we have a selector
    // filter
    if ( matchesSelector( elem, selector ) ) {
      ffElems.push( elem );
    }
    // find children
    var childElems = elem.querySelectorAll( selector );
    // concat childElems to filterFound array
    for ( var i=0; i < childElems.length; i++ ) {
      ffElems.push( childElems[i] );
    }
  });

  return ffElems;
};

// ----- debounceMethod ----- //

utils.debounceMethod = function( _class, methodName, threshold ) {
  threshold = threshold || 100;
  // original method
  var method = _class.prototype[ methodName ];
  var timeoutName = methodName + 'Timeout';

  _class.prototype[ methodName ] = function() {
    var timeout = this[ timeoutName ];
    clearTimeout( timeout );

    var args = arguments;
    var _this = this;
    this[ timeoutName ] = setTimeout( function() {
      method.apply( _this, args );
      delete _this[ timeoutName ];
    }, threshold );
  };
};

// ----- docReady ----- //

utils.docReady = function( callback ) {
  var readyState = document.readyState;
  if ( readyState == 'complete' || readyState == 'interactive' ) {
    // do async to allow for other scripts to run. metafizzy/flickity#441
    setTimeout( callback );
  } else {
    document.addEventListener( 'DOMContentLoaded', callback );
  }
};

// ----- htmlInit ----- //

// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
utils.toDashed = function( str ) {
  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
    return $1 + '-' + $2;
  }).toLowerCase();
};

var console = window.console;
/**
 * allow user to initialize classes via [data-namespace] or .js-namespace class
 * htmlInit( Widget, 'widgetName' )
 * options are parsed from data-namespace-options
 */
utils.htmlInit = function( WidgetClass, namespace ) {
  utils.docReady( function() {
    var dashedNamespace = utils.toDashed( namespace );
    var dataAttr = 'data-' + dashedNamespace;
    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
    var elems = utils.makeArray( dataAttrElems )
      .concat( utils.makeArray( jsDashElems ) );
    var dataOptionsAttr = dataAttr + '-options';
    var jQuery = window.jQuery;

    elems.forEach( function( elem ) {
      var attr = elem.getAttribute( dataAttr ) ||
        elem.getAttribute( dataOptionsAttr );
      var options;
      try {
        options = attr && JSON.parse( attr );
      } catch ( error ) {
        // log error, do not initialize
        if ( console ) {
          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
          ': ' + error );
        }
        return;
      }
      // initialize
      var instance = new WidgetClass( elem, options );
      // make available via $().data('namespace')
      if ( jQuery ) {
        jQuery.data( elem, namespace, instance );
      }
    });

  });
};

// -----  ----- //

return utils;

}));

// Flickity.Cell
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/cell',[
      'get-size/get-size'
    ], function( getSize ) {
      return factory( window, getSize );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('get-size')
    );
  } else {
    // browser global
    window.Flickity = window.Flickity || {};
    window.Flickity.Cell = factory(
      window,
      window.getSize
    );
  }

}( window, function factory( window, getSize ) {



function Cell( elem, parent ) {
  this.element = elem;
  this.parent = parent;

  this.create();
}

var proto = Cell.prototype;

proto.create = function() {
  this.element.style.position = 'absolute';
  this.element.setAttribute( 'aria-hidden', 'true' );
  this.x = 0;
  this.shift = 0;
};

proto.destroy = function() {
  // reset style
  this.unselect();
  this.element.style.position = '';
  var side = this.parent.originSide;
  this.element.style[ side ] = '';
};

proto.getSize = function() {
  this.size = getSize( this.element );
};

proto.setPosition = function( x ) {
  this.x = x;
  this.updateTarget();
  this.renderPosition( x );
};

// setDefaultTarget v1 method, backwards compatibility, remove in v3
proto.updateTarget = proto.setDefaultTarget = function() {
  var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight';
  this.target = this.x + this.size[ marginProperty ] +
    this.size.width * this.parent.cellAlign;
};

proto.renderPosition = function( x ) {
  // render position of cell with in slider
  var side = this.parent.originSide;
  this.element.style[ side ] = this.parent.getPositionValue( x );
};

proto.select = function() {
  this.element.classList.add('is-selected');
  this.element.removeAttribute('aria-hidden');
};

proto.unselect = function() {
  this.element.classList.remove('is-selected');
  this.element.setAttribute( 'aria-hidden', 'true' );
};

/**
 * @param {Integer} factor - 0, 1, or -1
**/
proto.wrapShift = function( shift ) {
  this.shift = shift;
  this.renderPosition( this.x + this.parent.slideableWidth * shift );
};

proto.remove = function() {
  this.element.parentNode.removeChild( this.element );
};

return Cell;

}));

// slide
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/slide',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory();
  } else {
    // browser global
    window.Flickity = window.Flickity || {};
    window.Flickity.Slide = factory();
  }

}( window, function factory() {
'use strict';

function Slide( parent ) {
  this.parent = parent;
  this.isOriginLeft = parent.originSide == 'left';
  this.cells = [];
  this.outerWidth = 0;
  this.height = 0;
}

var proto = Slide.prototype;

proto.addCell = function( cell ) {
  this.cells.push( cell );
  this.outerWidth += cell.size.outerWidth;
  this.height = Math.max( cell.size.outerHeight, this.height );
  // first cell stuff
  if ( this.cells.length == 1 ) {
    this.x = cell.x; // x comes from first cell
    var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight';
    this.firstMargin = cell.size[ beginMargin ];
  }
};

proto.updateTarget = function() {
  var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft';
  var lastCell = this.getLastCell();
  var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0;
  var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin );
  this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign;
};

proto.getLastCell = function() {
  return this.cells[ this.cells.length - 1 ];
};

proto.select = function() {
  this.cells.forEach( function( cell ) {
    cell.select();
  });
};

proto.unselect = function() {
  this.cells.forEach( function( cell ) {
    cell.unselect();
  });
};

proto.getCellElements = function() {
  return this.cells.map( function( cell ) {
    return cell.element;
  });
};

return Slide;

}));

// animate
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/animate',[
      'fizzy-ui-utils/utils'
    ], function( utils ) {
      return factory( window, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    window.Flickity = window.Flickity || {};
    window.Flickity.animatePrototype = factory(
      window,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, utils ) {



// -------------------------- animate -------------------------- //

var proto = {};

proto.startAnimation = function() {
  if ( this.isAnimating ) {
    return;
  }

  this.isAnimating = true;
  this.restingFrames = 0;
  this.animate();
};

proto.animate = function() {
  this.applyDragForce();
  this.applySelectedAttraction();

  var previousX = this.x;

  this.integratePhysics();
  this.positionSlider();
  this.settle( previousX );
  // animate next frame
  if ( this.isAnimating ) {
    var _this = this;
    requestAnimationFrame( function animateFrame() {
      _this.animate();
    });
  }
};

proto.positionSlider = function() {
  var x = this.x;
  // wrap position around
  if ( this.options.wrapAround && this.cells.length > 1 ) {
    x = utils.modulo( x, this.slideableWidth );
    x = x - this.slideableWidth;
    this.shiftWrapCells( x );
  }

  this.setTranslateX( x, this.isAnimating );
  this.dispatchScrollEvent();
};

proto.setTranslateX = function( x, is3d ) {
  x += this.cursorPosition;
  // reverse if right-to-left and using transform
  x = this.options.rightToLeft ? -x : x;
  var translateX = this.getPositionValue( x );
  // use 3D tranforms for hardware acceleration on iOS
  // but use 2D when settled, for better font-rendering
  this.slider.style.transform = is3d ?
    'translate3d(' + translateX + ',0,0)' : 'translateX(' + translateX + ')';
};

proto.dispatchScrollEvent = function() {
  var firstSlide = this.slides[0];
  if ( !firstSlide ) {
    return;
  }
  var positionX = -this.x - firstSlide.target;
  var progress = positionX / this.slidesWidth;
  this.dispatchEvent( 'scroll', null, [ progress, positionX ] );
};

proto.positionSliderAtSelected = function() {
  if ( !this.cells.length ) {
    return;
  }
  this.x = -this.selectedSlide.target;
  this.velocity = 0; // stop wobble
  this.positionSlider();
};

proto.getPositionValue = function( position ) {
  if ( this.options.percentPosition ) {
    // percent position, round to 2 digits, like 12.34%
    return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%';
  } else {
    // pixel positioning
    return Math.round( position ) + 'px';
  }
};

proto.settle = function( previousX ) {
  // keep track of frames where x hasn't moved
  if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) {
    this.restingFrames++;
  }
  // stop animating if resting for 3 or more frames
  if ( this.restingFrames > 2 ) {
    this.isAnimating = false;
    delete this.isFreeScrolling;
    // render position with translateX when settled
    this.positionSlider();
    this.dispatchEvent( 'settle', null, [ this.selectedIndex ] );
  }
};

proto.shiftWrapCells = function( x ) {
  // shift before cells
  var beforeGap = this.cursorPosition + x;
  this._shiftCells( this.beforeShiftCells, beforeGap, -1 );
  // shift after cells
  var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition );
  this._shiftCells( this.afterShiftCells, afterGap, 1 );
};

proto._shiftCells = function( cells, gap, shift ) {
  for ( var i=0; i < cells.length; i++ ) {
    var cell = cells[i];
    var cellShift = gap > 0 ? shift : 0;
    cell.wrapShift( cellShift );
    gap -= cell.size.outerWidth;
  }
};

proto._unshiftCells = function( cells ) {
  if ( !cells || !cells.length ) {
    return;
  }
  for ( var i=0; i < cells.length; i++ ) {
    cells[i].wrapShift( 0 );
  }
};

// -------------------------- physics -------------------------- //

proto.integratePhysics = function() {
  this.x += this.velocity;
  this.velocity *= this.getFrictionFactor();
};

proto.applyForce = function( force ) {
  this.velocity += force;
};

proto.getFrictionFactor = function() {
  return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ];
};

proto.getRestingPosition = function() {
  // my thanks to Steven Wittens, who simplified this math greatly
  return this.x + this.velocity / ( 1 - this.getFrictionFactor() );
};

proto.applyDragForce = function() {
  if ( !this.isDraggable || !this.isPointerDown ) {
    return;
  }
  // change the position to drag position by applying force
  var dragVelocity = this.dragX - this.x;
  var dragForce = dragVelocity - this.velocity;
  this.applyForce( dragForce );
};

proto.applySelectedAttraction = function() {
  // do not attract if pointer down or no slides
  var dragDown = this.isDraggable && this.isPointerDown;
  if ( dragDown || this.isFreeScrolling || !this.slides.length ) {
    return;
  }
  var distance = this.selectedSlide.target * -1 - this.x;
  var force = distance * this.options.selectedAttraction;
  this.applyForce( force );
};

return proto;

}));

// Flickity main
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/flickity',[
      'ev-emitter/ev-emitter',
      'get-size/get-size',
      'fizzy-ui-utils/utils',
      './cell',
      './slide',
      './animate'
    ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {
      return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('ev-emitter'),
      require('get-size'),
      require('fizzy-ui-utils'),
      require('./cell'),
      require('./slide'),
      require('./animate')
    );
  } else {
    // browser global
    var _Flickity = window.Flickity;

    window.Flickity = factory(
      window,
      window.EvEmitter,
      window.getSize,
      window.fizzyUIUtils,
      _Flickity.Cell,
      _Flickity.Slide,
      _Flickity.animatePrototype
    );
  }

}( window, function factory( window, EvEmitter, getSize,
  utils, Cell, Slide, animatePrototype ) {



// vars
var jQuery = window.jQuery;
var getComputedStyle = window.getComputedStyle;
var console = window.console;

function moveElements( elems, toElem ) {
  elems = utils.makeArray( elems );
  while ( elems.length ) {
    toElem.appendChild( elems.shift() );
  }
}

// -------------------------- Flickity -------------------------- //

// globally unique identifiers
var GUID = 0;
// internal store of all Flickity intances
var instances = {};

function Flickity( element, options ) {
  var queryElement = utils.getQueryElement( element );
  if ( !queryElement ) {
    if ( console ) {
      console.error( 'Bad element for Flickity: ' + ( queryElement || element ) );
    }
    return;
  }
  this.element = queryElement;
  // do not initialize twice on same element
  if ( this.element.flickityGUID ) {
    var instance = instances[ this.element.flickityGUID ];
    instance.option( options );
    return instance;
  }

  // add jQuery
  if ( jQuery ) {
    this.$element = jQuery( this.element );
  }
  // options
  this.options = utils.extend( {}, this.constructor.defaults );
  this.option( options );

  // kick things off
  this._create();
}

Flickity.defaults = {
  accessibility: true,
  // adaptiveHeight: false,
  cellAlign: 'center',
  // cellSelector: undefined,
  // contain: false,
  freeScrollFriction: 0.075, // friction when free-scrolling
  friction: 0.28, // friction when selecting
  namespaceJQueryEvents: true,
  // initialIndex: 0,
  percentPosition: true,
  resize: true,
  selectedAttraction: 0.025,
  setGallerySize: true
  // watchCSS: false,
  // wrapAround: false
};

// hash of methods triggered on _create()
Flickity.createMethods = [];

var proto = Flickity.prototype;
// inherit EventEmitter
utils.extend( proto, EvEmitter.prototype );

proto._create = function() {
  // add id for Flickity.data
  var id = this.guid = ++GUID;
  this.element.flickityGUID = id; // expando
  instances[ id ] = this; // associate via id
  // initial properties
  this.selectedIndex = 0;
  // how many frames slider has been in same position
  this.restingFrames = 0;
  // initial physics properties
  this.x = 0;
  this.velocity = 0;
  this.originSide = this.options.rightToLeft ? 'right' : 'left';
  // create viewport & slider
  this.viewport = document.createElement('div');
  this.viewport.className = 'flickity-viewport';
  this._createSlider();

  if ( this.options.resize || this.options.watchCSS ) {
    window.addEventListener( 'resize', this );
  }

  // add listeners from on option
  for ( var eventName in this.options.on ) {
    var listener = this.options.on[ eventName ];
    this.on( eventName, listener );
  }

  Flickity.createMethods.forEach( function( method ) {
    this[ method ]();
  }, this );

  if ( this.options.watchCSS ) {
    this.watchCSS();
  } else {
    this.activate();
  }

};

/**
 * set options
 * @param {Object} opts
 */
proto.option = function( opts ) {
  utils.extend( this.options, opts );
};

proto.activate = function() {
  if ( this.isActive ) {
    return;
  }
  this.isActive = true;
  this.element.classList.add('flickity-enabled');
  if ( this.options.rightToLeft ) {
    this.element.classList.add('flickity-rtl');
  }

  this.getSize();
  // move initial cell elements so they can be loaded as cells
  var cellElems = this._filterFindCellElements( this.element.children );
  moveElements( cellElems, this.slider );
  this.viewport.appendChild( this.slider );
  this.element.appendChild( this.viewport );
  // get cells from children
  this.reloadCells();

  if ( this.options.accessibility ) {
    // allow element to focusable
    this.element.tabIndex = 0;
    // listen for key presses
    this.element.addEventListener( 'keydown', this );
  }

  this.emitEvent('activate');
  this.selectInitialIndex();
  // flag for initial activation, for using initialIndex
  this.isInitActivated = true;
  // ready event. #493
  this.dispatchEvent('ready');
};

// slider positions the cells
proto._createSlider = function() {
  // slider element does all the positioning
  var slider = document.createElement('div');
  slider.className = 'flickity-slider';
  slider.style[ this.originSide ] = 0;
  this.slider = slider;
};

proto._filterFindCellElements = function( elems ) {
  return utils.filterFindElements( elems, this.options.cellSelector );
};

// goes through all children
proto.reloadCells = function() {
  // collection of item elements
  this.cells = this._makeCells( this.slider.children );
  this.positionCells();
  this._getWrapShiftCells();
  this.setGallerySize();
};

/**
 * turn elements into Flickity.Cells
 * @param {Array or NodeList or HTMLElement} elems
 * @returns {Array} items - collection of new Flickity Cells
 */
proto._makeCells = function( elems ) {
  var cellElems = this._filterFindCellElements( elems );

  // create new Flickity for collection
  var cells = cellElems.map( function( cellElem ) {
    return new Cell( cellElem, this );
  }, this );

  return cells;
};

proto.getLastCell = function() {
  return this.cells[ this.cells.length - 1 ];
};

proto.getLastSlide = function() {
  return this.slides[ this.slides.length - 1 ];
};

// positions all cells
proto.positionCells = function() {
  // size all cells
  this._sizeCells( this.cells );
  // position all cells
  this._positionCells( 0 );
};

/**
 * position certain cells
 * @param {Integer} index - which cell to start with
 */
proto._positionCells = function( index ) {
  index = index || 0;
  // also measure maxCellHeight
  // start 0 if positioning all cells
  this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;
  var cellX = 0;
  // get cellX
  if ( index > 0 ) {
    var startCell = this.cells[ index - 1 ];
    cellX = startCell.x + startCell.size.outerWidth;
  }
  var len = this.cells.length;
  for ( var i=index; i < len; i++ ) {
    var cell = this.cells[i];
    cell.setPosition( cellX );
    cellX += cell.size.outerWidth;
    this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );
  }
  // keep track of cellX for wrap-around
  this.slideableWidth = cellX;
  // slides
  this.updateSlides();
  // contain slides target
  this._containSlides();
  // update slidesWidth
  this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0;
};

/**
 * cell.getSize() on multiple cells
 * @param {Array} cells
 */
proto._sizeCells = function( cells ) {
  cells.forEach( function( cell ) {
    cell.getSize();
  });
};

// --------------------------  -------------------------- //

proto.updateSlides = function() {
  this.slides = [];
  if ( !this.cells.length ) {
    return;
  }

  var slide = new Slide( this );
  this.slides.push( slide );
  var isOriginLeft = this.originSide == 'left';
  var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft';

  var canCellFit = this._getCanCellFit();

  this.cells.forEach( function( cell, i ) {
    // just add cell if first cell in slide
    if ( !slide.cells.length ) {
      slide.addCell( cell );
      return;
    }

    var slideWidth = ( slide.outerWidth - slide.firstMargin ) +
      ( cell.size.outerWidth - cell.size[ nextMargin ] );

    if ( canCellFit.call( this, i, slideWidth ) ) {
      slide.addCell( cell );
    } else {
      // doesn't fit, new slide
      slide.updateTarget();

      slide = new Slide( this );
      this.slides.push( slide );
      slide.addCell( cell );
    }
  }, this );
  // last slide
  slide.updateTarget();
  // update .selectedSlide
  this.updateSelectedSlide();
};

proto._getCanCellFit = function() {
  var groupCells = this.options.groupCells;
  if ( !groupCells ) {
    return function() {
      return false;
    };
  } else if ( typeof groupCells == 'number' ) {
    // group by number. 3 -> [0,1,2], [3,4,5], ...
    var number = parseInt( groupCells, 10 );
    return function( i ) {
      return ( i % number ) !== 0;
    };
  }
  // default, group by width of slide
  // parse '75%
  var percentMatch = typeof groupCells == 'string' &&
    groupCells.match(/^(\d+)%$/);
  var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1;
  return function( i, slideWidth ) {
    return slideWidth <= ( this.size.innerWidth + 1 ) * percent;
  };
};

// alias _init for jQuery plugin .flickity()
proto._init =
proto.reposition = function() {
  this.positionCells();
  this.positionSliderAtSelected();
};

proto.getSize = function() {
  this.size = getSize( this.element );
  this.setCellAlign();
  this.cursorPosition = this.size.innerWidth * this.cellAlign;
};

var cellAlignShorthands = {
  // cell align, then based on origin side
  center: {
    left: 0.5,
    right: 0.5
  },
  left: {
    left: 0,
    right: 1
  },
  right: {
    right: 0,
    left: 1
  }
};

proto.setCellAlign = function() {
  var shorthand = cellAlignShorthands[ this.options.cellAlign ];
  this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign;
};

proto.setGallerySize = function() {
  if ( this.options.setGallerySize ) {
    var height = this.options.adaptiveHeight && this.selectedSlide ?
      this.selectedSlide.height : this.maxCellHeight;
    this.viewport.style.height = height + 'px';
  }
};

proto._getWrapShiftCells = function() {
  // only for wrap-around
  if ( !this.options.wrapAround ) {
    return;
  }
  // unshift previous cells
  this._unshiftCells( this.beforeShiftCells );
  this._unshiftCells( this.afterShiftCells );
  // get before cells
  // initial gap
  var gapX = this.cursorPosition;
  var cellIndex = this.cells.length - 1;
  this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 );
  // get after cells
  // ending gap between last cell and end of gallery viewport
  gapX = this.size.innerWidth - this.cursorPosition;
  // start cloning at first cell, working forwards
  this.afterShiftCells = this._getGapCells( gapX, 0, 1 );
};

proto._getGapCells = function( gapX, cellIndex, increment ) {
  // keep adding cells until the cover the initial gap
  var cells = [];
  while ( gapX > 0 ) {
    var cell = this.cells[ cellIndex ];
    if ( !cell ) {
      break;
    }
    cells.push( cell );
    cellIndex += increment;
    gapX -= cell.size.outerWidth;
  }
  return cells;
};

// ----- contain ----- //

// contain cell targets so no excess sliding
proto._containSlides = function() {
  if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) {
    return;
  }
  var isRightToLeft = this.options.rightToLeft;
  var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft';
  var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight';
  var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ];
  // content is less than gallery size
  var isContentSmaller = contentWidth < this.size.innerWidth;
  // bounds
  var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ];
  var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );
  // contain each cell target
  this.slides.forEach( function( slide ) {
    if ( isContentSmaller ) {
      // all cells fit inside gallery
      slide.target = contentWidth * this.cellAlign;
    } else {
      // contain to bounds
      slide.target = Math.max( slide.target, beginBound );
      slide.target = Math.min( slide.target, endBound );
    }
  }, this );
};

// -----  ----- //

/**
 * emits events via eventEmitter and jQuery events
 * @param {String} type - name of event
 * @param {Event} event - original event
 * @param {Array} args - extra arguments
 */
proto.dispatchEvent = function( type, event, args ) {
  var emitArgs = event ? [ event ].concat( args ) : args;
  this.emitEvent( type, emitArgs );

  if ( jQuery && this.$element ) {
    // default trigger with type if no event
    type += this.options.namespaceJQueryEvents ? '.flickity' : '';
    var $event = type;
    if ( event ) {
      // create jQuery event
      var jQEvent = jQuery.Event( event );
      jQEvent.type = type;
      $event = jQEvent;
    }
    this.$element.trigger( $event, args );
  }
};

// -------------------------- select -------------------------- //

/**
 * @param {Integer} index - index of the slide
 * @param {Boolean} isWrap - will wrap-around to last/first if at the end
 * @param {Boolean} isInstant - will immediately set position at selected cell
 */
proto.select = function( index, isWrap, isInstant ) {
  if ( !this.isActive ) {
    return;
  }
  index = parseInt( index, 10 );
  this._wrapSelect( index );

  if ( this.options.wrapAround || isWrap ) {
    index = utils.modulo( index, this.slides.length );
  }
  // bail if invalid index
  if ( !this.slides[ index ] ) {
    return;
  }
  var prevIndex = this.selectedIndex;
  this.selectedIndex = index;
  this.updateSelectedSlide();
  if ( isInstant ) {
    this.positionSliderAtSelected();
  } else {
    this.startAnimation();
  }
  if ( this.options.adaptiveHeight ) {
    this.setGallerySize();
  }
  // events
  this.dispatchEvent( 'select', null, [ index ] );
  // change event if new index
  if ( index != prevIndex ) {
    this.dispatchEvent( 'change', null, [ index ] );
  }
  // old v1 event name, remove in v3
  this.dispatchEvent('cellSelect');
};

// wraps position for wrapAround, to move to closest slide. #113
proto._wrapSelect = function( index ) {
  var len = this.slides.length;
  var isWrapping = this.options.wrapAround && len > 1;
  if ( !isWrapping ) {
    return index;
  }
  var wrapIndex = utils.modulo( index, len );
  // go to shortest
  var delta = Math.abs( wrapIndex - this.selectedIndex );
  var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex );
  var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex );
  if ( !this.isDragSelect && backWrapDelta < delta ) {
    index += len;
  } else if ( !this.isDragSelect && forewardWrapDelta < delta ) {
    index -= len;
  }
  // wrap position so slider is within normal area
  if ( index < 0 ) {
    this.x -= this.slideableWidth;
  } else if ( index >= len ) {
    this.x += this.slideableWidth;
  }
};

proto.previous = function( isWrap, isInstant ) {
  this.select( this.selectedIndex - 1, isWrap, isInstant );
};

proto.next = function( isWrap, isInstant ) {
  this.select( this.selectedIndex + 1, isWrap, isInstant );
};

proto.updateSelectedSlide = function() {
  var slide = this.slides[ this.selectedIndex ];
  // selectedIndex could be outside of slides, if triggered before resize()
  if ( !slide ) {
    return;
  }
  // unselect previous selected slide
  this.unselectSelectedSlide();
  // update new selected slide
  this.selectedSlide = slide;
  slide.select();
  this.selectedCells = slide.cells;
  this.selectedElements = slide.getCellElements();
  // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility
  // Remove in v3?
  this.selectedCell = slide.cells[0];
  this.selectedElement = this.selectedElements[0];
};

proto.unselectSelectedSlide = function() {
  if ( this.selectedSlide ) {
    this.selectedSlide.unselect();
  }
};

proto.selectInitialIndex = function() {
  var initialIndex = this.options.initialIndex;
  // already activated, select previous selectedIndex
  if ( this.isInitActivated ) {
    this.select( this.selectedIndex, false, true );
    return;
  }
  // select with selector string
  if ( initialIndex && typeof initialIndex == 'string' ) {
    var cell = this.queryCell( initialIndex );
    if ( cell ) {
      this.selectCell( initialIndex, false, true );
      return;
    }
  }

  var index = 0;
  // select with number
  if ( initialIndex && this.slides[ initialIndex ] ) {
    index = initialIndex;
  }
  // select instantly
  this.select( index, false, true );
};

/**
 * select slide from number or cell element
 * @param {Element or Number} elem
 */
proto.selectCell = function( value, isWrap, isInstant ) {
  // get cell
  var cell = this.queryCell( value );
  if ( !cell ) {
    return;
  }

  var index = this.getCellSlideIndex( cell );
  this.select( index, isWrap, isInstant );
};

proto.getCellSlideIndex = function( cell ) {
  // get index of slides that has cell
  for ( var i=0; i < this.slides.length; i++ ) {
    var slide = this.slides[i];
    var index = slide.cells.indexOf( cell );
    if ( index != -1 ) {
      return i;
    }
  }
};

// -------------------------- get cells -------------------------- //

/**
 * get Flickity.Cell, given an Element
 * @param {Element} elem
 * @returns {Flickity.Cell} item
 */
proto.getCell = function( elem ) {
  // loop through cells to get the one that matches
  for ( var i=0; i < this.cells.length; i++ ) {
    var cell = this.cells[i];
    if ( cell.element == elem ) {
      return cell;
    }
  }
};

/**
 * get collection of Flickity.Cells, given Elements
 * @param {Element, Array, NodeList} elems
 * @returns {Array} cells - Flickity.Cells
 */
proto.getCells = function( elems ) {
  elems = utils.makeArray( elems );
  var cells = [];
  elems.forEach( function( elem ) {
    var cell = this.getCell( elem );
    if ( cell ) {
      cells.push( cell );
    }
  }, this );
  return cells;
};

/**
 * get cell elements
 * @returns {Array} cellElems
 */
proto.getCellElements = function() {
  return this.cells.map( function( cell ) {
    return cell.element;
  });
};

/**
 * get parent cell from an element
 * @param {Element} elem
 * @returns {Flickit.Cell} cell
 */
proto.getParentCell = function( elem ) {
  // first check if elem is cell
  var cell = this.getCell( elem );
  if ( cell ) {
    return cell;
  }
  // try to get parent cell elem
  elem = utils.getParent( elem, '.flickity-slider > *' );
  return this.getCell( elem );
};

/**
 * get cells adjacent to a slide
 * @param {Integer} adjCount - number of adjacent slides
 * @param {Integer} index - index of slide to start
 * @returns {Array} cells - array of Flickity.Cells
 */
proto.getAdjacentCellElements = function( adjCount, index ) {
  if ( !adjCount ) {
    return this.selectedSlide.getCellElements();
  }
  index = index === undefined ? this.selectedIndex : index;

  var len = this.slides.length;
  if ( 1 + ( adjCount * 2 ) >= len ) {
    return this.getCellElements();
  }

  var cellElems = [];
  for ( var i = index - adjCount; i <= index + adjCount ; i++ ) {
    var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i;
    var slide = this.slides[ slideIndex ];
    if ( slide ) {
      cellElems = cellElems.concat( slide.getCellElements() );
    }
  }
  return cellElems;
};

/**
 * select slide from number or cell element
 * @param {Element, Selector String, or Number} selector
 */
proto.queryCell = function( selector ) {
  if ( typeof selector == 'number' ) {
    // use number as index
    return this.cells[ selector ];
  }
  if ( typeof selector == 'string' ) {
    // do not select invalid selectors from hash: #123, #/. #791
    if ( selector.match(/^[#\.]?[\d\/]/) ) {
      return;
    }
    // use string as selector, get element
    selector = this.element.querySelector( selector );
  }
  // get cell from element
  return this.getCell( selector );
};

// -------------------------- events -------------------------- //

proto.uiChange = function() {
  this.emitEvent('uiChange');
};

// keep focus on element when child UI elements are clicked
proto.childUIPointerDown = function( event ) {
  // HACK iOS does not allow touch events to bubble up?!
  if ( event.type != 'touchstart' ) {
    event.preventDefault();
  }
  this.focus();
};

// ----- resize ----- //

proto.onresize = function() {
  this.watchCSS();
  this.resize();
};

utils.debounceMethod( Flickity, 'onresize', 150 );

proto.resize = function() {
  if ( !this.isActive ) {
    return;
  }
  this.getSize();
  // wrap values
  if ( this.options.wrapAround ) {
    this.x = utils.modulo( this.x, this.slideableWidth );
  }
  this.positionCells();
  this._getWrapShiftCells();
  this.setGallerySize();
  this.emitEvent('resize');
  // update selected index for group slides, instant
  // TODO: position can be lost between groups of various numbers
  var selectedElement = this.selectedElements && this.selectedElements[0];
  this.selectCell( selectedElement, false, true );
};

// watches the :after property, activates/deactivates
proto.watchCSS = function() {
  var watchOption = this.options.watchCSS;
  if ( !watchOption ) {
    return;
  }

  var afterContent = getComputedStyle( this.element, ':after' ).content;
  // activate if :after { content: 'flickity' }
  if ( afterContent.indexOf('flickity') != -1 ) {
    this.activate();
  } else {
    this.deactivate();
  }
};

// ----- keydown ----- //

// go previous/next if left/right keys pressed
proto.onkeydown = function( event ) {
  // only work if element is in focus
  var isNotFocused = document.activeElement && document.activeElement != this.element;
  if ( !this.options.accessibility ||isNotFocused ) {
    return;
  }

  var handler = Flickity.keyboardHandlers[ event.keyCode ];
  if ( handler ) {
    handler.call( this );
  }
};

Flickity.keyboardHandlers = {
  // left arrow
  37: function() {
    var leftMethod = this.options.rightToLeft ? 'next' : 'previous';
    this.uiChange();
    this[ leftMethod ]();
  },
  // right arrow
  39: function() {
    var rightMethod = this.options.rightToLeft ? 'previous' : 'next';
    this.uiChange();
    this[ rightMethod ]();
  },
};

// ----- focus ----- //

proto.focus = function() {
  // TODO remove scrollTo once focus options gets more support
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility
  var prevScrollY = window.pageYOffset;
  this.element.focus({ preventScroll: true });
  // hack to fix scroll jump after focus, #76
  if ( window.pageYOffset != prevScrollY ) {
    window.scrollTo( window.pageXOffset, prevScrollY );
  }
};

// -------------------------- destroy -------------------------- //

// deactivate all Flickity functionality, but keep stuff available
proto.deactivate = function() {
  if ( !this.isActive ) {
    return;
  }
  this.element.classList.remove('flickity-enabled');
  this.element.classList.remove('flickity-rtl');
  this.unselectSelectedSlide();
  // destroy cells
  this.cells.forEach( function( cell ) {
    cell.destroy();
  });
  this.element.removeChild( this.viewport );
  // move child elements back into element
  moveElements( this.slider.children, this.element );
  if ( this.options.accessibility ) {
    this.element.removeAttribute('tabIndex');
    this.element.removeEventListener( 'keydown', this );
  }
  // set flags
  this.isActive = false;
  this.emitEvent('deactivate');
};

proto.destroy = function() {
  this.deactivate();
  window.removeEventListener( 'resize', this );
  this.allOff();
  this.emitEvent('destroy');
  if ( jQuery && this.$element ) {
    jQuery.removeData( this.element, 'flickity' );
  }
  delete this.element.flickityGUID;
  delete instances[ this.guid ];
};

// -------------------------- prototype -------------------------- //

utils.extend( proto, animatePrototype );

// -------------------------- extras -------------------------- //

/**
 * get Flickity instance from element
 * @param {Element} elem
 * @returns {Flickity}
 */
Flickity.data = function( elem ) {
  elem = utils.getQueryElement( elem );
  var id = elem && elem.flickityGUID;
  return id && instances[ id ];
};

utils.htmlInit( Flickity, 'flickity' );

if ( jQuery && jQuery.bridget ) {
  jQuery.bridget( 'flickity', Flickity );
}

// set internal jQuery, for Webpack + jQuery v3, #478
Flickity.setJQuery = function( jq ) {
  jQuery = jq;
};

Flickity.Cell = Cell;
Flickity.Slide = Slide;

return Flickity;

}));

/*!
 * Unipointer v2.3.0
 * base class for doing one thing with pointer event
 * MIT license
 */

/*jshint browser: true, undef: true, unused: true, strict: true */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*global define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'unipointer/unipointer',[
      'ev-emitter/ev-emitter'
    ], function( EvEmitter ) {
      return factory( window, EvEmitter );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('ev-emitter')
    );
  } else {
    // browser global
    window.Unipointer = factory(
      window,
      window.EvEmitter
    );
  }

}( window, function factory( window, EvEmitter ) {



function noop() {}

function Unipointer() {}

// inherit EvEmitter
var proto = Unipointer.prototype = Object.create( EvEmitter.prototype );

proto.bindStartEvent = function( elem ) {
  this._bindStartEvent( elem, true );
};

proto.unbindStartEvent = function( elem ) {
  this._bindStartEvent( elem, false );
};

/**
 * Add or remove start event
 * @param {Boolean} isAdd - remove if falsey
 */
proto._bindStartEvent = function( elem, isAdd ) {
  // munge isAdd, default to true
  isAdd = isAdd === undefined ? true : isAdd;
  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';

  // default to mouse events
  var startEvent = 'mousedown';
  if ( window.PointerEvent ) {
    // Pointer Events
    startEvent = 'pointerdown';
  } else if ( 'ontouchstart' in window ) {
    // Touch Events. iOS Safari
    startEvent = 'touchstart';
  }
  elem[ bindMethod ]( startEvent, this );
};

// trigger handler methods for events
proto.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

// returns the touch that we're keeping track of
proto.getTouch = function( touches ) {
  for ( var i=0; i < touches.length; i++ ) {
    var touch = touches[i];
    if ( touch.identifier == this.pointerIdentifier ) {
      return touch;
    }
  }
};

// ----- start event ----- //

proto.onmousedown = function( event ) {
  // dismiss clicks from right or middle buttons
  var button = event.button;
  if ( button && ( button !== 0 && button !== 1 ) ) {
    return;
  }
  this._pointerDown( event, event );
};

proto.ontouchstart = function( event ) {
  this._pointerDown( event, event.changedTouches[0] );
};

proto.onpointerdown = function( event ) {
  this._pointerDown( event, event );
};

/**
 * pointer start
 * @param {Event} event
 * @param {Event or Touch} pointer
 */
proto._pointerDown = function( event, pointer ) {
  // dismiss right click and other pointers
  // button = 0 is okay, 1-4 not
  if ( event.button || this.isPointerDown ) {
    return;
  }

  this.isPointerDown = true;
  // save pointer identifier to match up touch events
  this.pointerIdentifier = pointer.pointerId !== undefined ?
    // pointerId for pointer events, touch.indentifier for touch events
    pointer.pointerId : pointer.identifier;

  this.pointerDown( event, pointer );
};

proto.pointerDown = function( event, pointer ) {
  this._bindPostStartEvents( event );
  this.emitEvent( 'pointerDown', [ event, pointer ] );
};

// hash of events to be bound after start event
var postStartEvents = {
  mousedown: [ 'mousemove', 'mouseup' ],
  touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
  pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
};

proto._bindPostStartEvents = function( event ) {
  if ( !event ) {
    return;
  }
  // get proper events to match start event
  var events = postStartEvents[ event.type ];
  // bind events to node
  events.forEach( function( eventName ) {
    window.addEventListener( eventName, this );
  }, this );
  // save these arguments
  this._boundPointerEvents = events;
};

proto._unbindPostStartEvents = function() {
  // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
  if ( !this._boundPointerEvents ) {
    return;
  }
  this._boundPointerEvents.forEach( function( eventName ) {
    window.removeEventListener( eventName, this );
  }, this );

  delete this._boundPointerEvents;
};

// ----- move event ----- //

proto.onmousemove = function( event ) {
  this._pointerMove( event, event );
};

proto.onpointermove = function( event ) {
  if ( event.pointerId == this.pointerIdentifier ) {
    this._pointerMove( event, event );
  }
};

proto.ontouchmove = function( event ) {
  var touch = this.getTouch( event.changedTouches );
  if ( touch ) {
    this._pointerMove( event, touch );
  }
};

/**
 * pointer move
 * @param {Event} event
 * @param {Event or Touch} pointer
 * @private
 */
proto._pointerMove = function( event, pointer ) {
  this.pointerMove( event, pointer );
};

// public
proto.pointerMove = function( event, pointer ) {
  this.emitEvent( 'pointerMove', [ event, pointer ] );
};

// ----- end event ----- //


proto.onmouseup = function( event ) {
  this._pointerUp( event, event );
};

proto.onpointerup = function( event ) {
  if ( event.pointerId == this.pointerIdentifier ) {
    this._pointerUp( event, event );
  }
};

proto.ontouchend = function( event ) {
  var touch = this.getTouch( event.changedTouches );
  if ( touch ) {
    this._pointerUp( event, touch );
  }
};

/**
 * pointer up
 * @param {Event} event
 * @param {Event or Touch} pointer
 * @private
 */
proto._pointerUp = function( event, pointer ) {
  this._pointerDone();
  this.pointerUp( event, pointer );
};

// public
proto.pointerUp = function( event, pointer ) {
  this.emitEvent( 'pointerUp', [ event, pointer ] );
};

// ----- pointer done ----- //

// triggered on pointer up & pointer cancel
proto._pointerDone = function() {
  this._pointerReset();
  this._unbindPostStartEvents();
  this.pointerDone();
};

proto._pointerReset = function() {
  // reset properties
  this.isPointerDown = false;
  delete this.pointerIdentifier;
};

proto.pointerDone = noop;

// ----- pointer cancel ----- //

proto.onpointercancel = function( event ) {
  if ( event.pointerId == this.pointerIdentifier ) {
    this._pointerCancel( event, event );
  }
};

proto.ontouchcancel = function( event ) {
  var touch = this.getTouch( event.changedTouches );
  if ( touch ) {
    this._pointerCancel( event, touch );
  }
};

/**
 * pointer cancel
 * @param {Event} event
 * @param {Event or Touch} pointer
 * @private
 */
proto._pointerCancel = function( event, pointer ) {
  this._pointerDone();
  this.pointerCancel( event, pointer );
};

// public
proto.pointerCancel = function( event, pointer ) {
  this.emitEvent( 'pointerCancel', [ event, pointer ] );
};

// -----  ----- //

// utility function for getting x/y coords from event
Unipointer.getPointerPoint = function( pointer ) {
  return {
    x: pointer.pageX,
    y: pointer.pageY
  };
};

// -----  ----- //

return Unipointer;

}));

/*!
 * Unidragger v2.3.0
 * Draggable base class
 * MIT license
 */

/*jshint browser: true, unused: true, undef: true, strict: true */

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'unidragger/unidragger',[
      'unipointer/unipointer'
    ], function( Unipointer ) {
      return factory( window, Unipointer );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('unipointer')
    );
  } else {
    // browser global
    window.Unidragger = factory(
      window,
      window.Unipointer
    );
  }

}( window, function factory( window, Unipointer ) {



// -------------------------- Unidragger -------------------------- //

function Unidragger() {}

// inherit Unipointer & EvEmitter
var proto = Unidragger.prototype = Object.create( Unipointer.prototype );

// ----- bind start ----- //

proto.bindHandles = function() {
  this._bindHandles( true );
};

proto.unbindHandles = function() {
  this._bindHandles( false );
};

/**
 * Add or remove start event
 * @param {Boolean} isAdd
 */
proto._bindHandles = function( isAdd ) {
  // munge isAdd, default to true
  isAdd = isAdd === undefined ? true : isAdd;
  // bind each handle
  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
  var touchAction = isAdd ? this._touchActionValue : '';
  for ( var i=0; i < this.handles.length; i++ ) {
    var handle = this.handles[i];
    this._bindStartEvent( handle, isAdd );
    handle[ bindMethod ]( 'click', this );
    // touch-action: none to override browser touch gestures. metafizzy/flickity#540
    if ( window.PointerEvent ) {
      handle.style.touchAction = touchAction;
    }
  }
};

// prototype so it can be overwriteable by Flickity
proto._touchActionValue = 'none';

// ----- start event ----- //

/**
 * pointer start
 * @param {Event} event
 * @param {Event or Touch} pointer
 */
proto.pointerDown = function( event, pointer ) {
  var isOkay = this.okayPointerDown( event );
  if ( !isOkay ) {
    return;
  }
  // track start event position
  this.pointerDownPointer = pointer;

  event.preventDefault();
  this.pointerDownBlur();
  // bind move and end events
  this._bindPostStartEvents( event );
  this.emitEvent( 'pointerDown', [ event, pointer ] );
};

// nodes that have text fields
var cursorNodes = {
  TEXTAREA: true,
  INPUT: true,
  SELECT: true,
  OPTION: true,
};

// input types that do not have text fields
var clickTypes = {
  radio: true,
  checkbox: true,
  button: true,
  submit: true,
  image: true,
  file: true,
};

// dismiss inputs with text fields. flickity#403, flickity#404
proto.okayPointerDown = function( event ) {
  var isCursorNode = cursorNodes[ event.target.nodeName ];
  var isClickType = clickTypes[ event.target.type ];
  var isOkay = !isCursorNode || isClickType;
  if ( !isOkay ) {
    this._pointerReset();
  }
  return isOkay;
};

// kludge to blur previously focused input
proto.pointerDownBlur = function() {
  var focused = document.activeElement;
  // do not blur body for IE10, metafizzy/flickity#117
  var canBlur = focused && focused.blur && focused != document.body;
  if ( canBlur ) {
    focused.blur();
  }
};

// ----- move event ----- //

/**
 * drag move
 * @param {Event} event
 * @param {Event or Touch} pointer
 */
proto.pointerMove = function( event, pointer ) {
  var moveVector = this._dragPointerMove( event, pointer );
  this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
  this._dragMove( event, pointer, moveVector );
};

// base pointer move logic
proto._dragPointerMove = function( event, pointer ) {
  var moveVector = {
    x: pointer.pageX - this.pointerDownPointer.pageX,
    y: pointer.pageY - this.pointerDownPointer.pageY
  };
  // start drag if pointer has moved far enough to start drag
  if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
    this._dragStart( event, pointer );
  }
  return moveVector;
};

// condition if pointer has moved far enough to start drag
proto.hasDragStarted = function( moveVector ) {
  return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
};

// ----- end event ----- //

/**
 * pointer up
 * @param {Event} event
 * @param {Event or Touch} pointer
 */
proto.pointerUp = function( event, pointer ) {
  this.emitEvent( 'pointerUp', [ event, pointer ] );
  this._dragPointerUp( event, pointer );
};

proto._dragPointerUp = function( event, pointer ) {
  if ( this.isDragging ) {
    this._dragEnd( event, pointer );
  } else {
    // pointer didn't move enough for drag to start
    this._staticClick( event, pointer );
  }
};

// -------------------------- drag -------------------------- //

// dragStart
proto._dragStart = function( event, pointer ) {
  this.isDragging = true;
  // prevent clicks
  this.isPreventingClicks = true;
  this.dragStart( event, pointer );
};

proto.dragStart = function( event, pointer ) {
  this.emitEvent( 'dragStart', [ event, pointer ] );
};

// dragMove
proto._dragMove = function( event, pointer, moveVector ) {
  // do not drag if not dragging yet
  if ( !this.isDragging ) {
    return;
  }

  this.dragMove( event, pointer, moveVector );
};

proto.dragMove = function( event, pointer, moveVector ) {
  event.preventDefault();
  this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
};

// dragEnd
proto._dragEnd = function( event, pointer ) {
  // set flags
  this.isDragging = false;
  // re-enable clicking async
  setTimeout( function() {
    delete this.isPreventingClicks;
  }.bind( this ) );

  this.dragEnd( event, pointer );
};

proto.dragEnd = function( event, pointer ) {
  this.emitEvent( 'dragEnd', [ event, pointer ] );
};

// ----- onclick ----- //

// handle all clicks and prevent clicks when dragging
proto.onclick = function( event ) {
  if ( this.isPreventingClicks ) {
    event.preventDefault();
  }
};

// ----- staticClick ----- //

// triggered after pointer down & up with no/tiny movement
proto._staticClick = function( event, pointer ) {
  // ignore emulated mouse up clicks
  if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
    return;
  }

  this.staticClick( event, pointer );

  // set flag for emulated clicks 300ms after touchend
  if ( event.type != 'mouseup' ) {
    this.isIgnoringMouseUp = true;
    // reset flag after 300ms
    setTimeout( function() {
      delete this.isIgnoringMouseUp;
    }.bind( this ), 400 );
  }
};

proto.staticClick = function( event, pointer ) {
  this.emitEvent( 'staticClick', [ event, pointer ] );
};

// ----- utils ----- //

Unidragger.getPointerPoint = Unipointer.getPointerPoint;

// -----  ----- //

return Unidragger;

}));

// drag
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/drag',[
      './flickity',
      'unidragger/unidragger',
      'fizzy-ui-utils/utils'
    ], function( Flickity, Unidragger, utils ) {
      return factory( window, Flickity, Unidragger, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('./flickity'),
      require('unidragger'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    window.Flickity = factory(
      window,
      window.Flickity,
      window.Unidragger,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, Flickity, Unidragger, utils ) {



// ----- defaults ----- //

utils.extend( Flickity.defaults, {
  draggable: '>1',
  dragThreshold: 3,
});

// ----- create ----- //

Flickity.createMethods.push('_createDrag');

// -------------------------- drag prototype -------------------------- //

var proto = Flickity.prototype;
utils.extend( proto, Unidragger.prototype );
proto._touchActionValue = 'pan-y';

// --------------------------  -------------------------- //

var isTouch = 'createTouch' in document;
var isTouchmoveScrollCanceled = false;

proto._createDrag = function() {
  this.on( 'activate', this.onActivateDrag );
  this.on( 'uiChange', this._uiChangeDrag );
  this.on( 'deactivate', this.onDeactivateDrag );
  this.on( 'cellChange', this.updateDraggable );
  // TODO updateDraggable on resize? if groupCells & slides change
  // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior
  // #457, RubaXa/Sortable#973
  if ( isTouch && !isTouchmoveScrollCanceled ) {
    window.addEventListener( 'touchmove', function() {});
    isTouchmoveScrollCanceled = true;
  }
};

proto.onActivateDrag = function() {
  this.handles = [ this.viewport ];
  this.bindHandles();
  this.updateDraggable();
};

proto.onDeactivateDrag = function() {
  this.unbindHandles();
  this.element.classList.remove('is-draggable');
};

proto.updateDraggable = function() {
  // disable dragging if less than 2 slides. #278
  if ( this.options.draggable == '>1' ) {
    this.isDraggable = this.slides.length > 1;
  } else {
    this.isDraggable = this.options.draggable;
  }
  if ( this.isDraggable ) {
    this.element.classList.add('is-draggable');
  } else {
    this.element.classList.remove('is-draggable');
  }
};

// backwards compatibility
proto.bindDrag = function() {
  this.options.draggable = true;
  this.updateDraggable();
};

proto.unbindDrag = function() {
  this.options.draggable = false;
  this.updateDraggable();
};

proto._uiChangeDrag = function() {
  delete this.isFreeScrolling;
};

// -------------------------- pointer events -------------------------- //

proto.pointerDown = function( event, pointer ) {
  if ( !this.isDraggable ) {
    this._pointerDownDefault( event, pointer );
    return;
  }
  var isOkay = this.okayPointerDown( event );
  if ( !isOkay ) {
    return;
  }

  this._pointerDownPreventDefault( event );
  this.pointerDownFocus( event );
  // blur
  if ( document.activeElement != this.element ) {
    // do not blur if already focused
    this.pointerDownBlur();
  }

  // stop if it was moving
  this.dragX = this.x;
  this.viewport.classList.add('is-pointer-down');
  // track scrolling
  this.pointerDownScroll = getScrollPosition();
  window.addEventListener( 'scroll', this );

  this._pointerDownDefault( event, pointer );
};

// default pointerDown logic, used for staticClick
proto._pointerDownDefault = function( event, pointer ) {
  // track start event position
  // Safari 9 overrides pageX and pageY. These values needs to be copied. #779
  this.pointerDownPointer = {
    pageX: pointer.pageX,
    pageY: pointer.pageY,
  };
  // bind move and end events
  this._bindPostStartEvents( event );
  this.dispatchEvent( 'pointerDown', event, [ pointer ] );
};

var focusNodes = {
  INPUT: true,
  TEXTAREA: true,
  SELECT: true,
};

proto.pointerDownFocus = function( event ) {
  var isFocusNode = focusNodes[ event.target.nodeName ];
  if ( !isFocusNode ) {
    this.focus();
  }
};

proto._pointerDownPreventDefault = function( event ) {
  var isTouchStart = event.type == 'touchstart';
  var isTouchPointer = event.pointerType == 'touch';
  var isFocusNode = focusNodes[ event.target.nodeName ];
  if ( !isTouchStart && !isTouchPointer && !isFocusNode ) {
    event.preventDefault();
  }
};

// ----- move ----- //

proto.hasDragStarted = function( moveVector ) {
  return Math.abs( moveVector.x ) > this.options.dragThreshold;
};

// ----- up ----- //

proto.pointerUp = function( event, pointer ) {
  delete this.isTouchScrolling;
  this.viewport.classList.remove('is-pointer-down');
  this.dispatchEvent( 'pointerUp', event, [ pointer ] );
  this._dragPointerUp( event, pointer );
};

proto.pointerDone = function() {
  window.removeEventListener( 'scroll', this );
  delete this.pointerDownScroll;
};

// -------------------------- dragging -------------------------- //

proto.dragStart = function( event, pointer ) {
  if ( !this.isDraggable ) {
    return;
  }
  this.dragStartPosition = this.x;
  this.startAnimation();
  window.removeEventListener( 'scroll', this );
  this.dispatchEvent( 'dragStart', event, [ pointer ] );
};

proto.pointerMove = function( event, pointer ) {
  var moveVector = this._dragPointerMove( event, pointer );
  this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] );
  this._dragMove( event, pointer, moveVector );
};

proto.dragMove = function( event, pointer, moveVector ) {
  if ( !this.isDraggable ) {
    return;
  }
  event.preventDefault();

  this.previousDragX = this.dragX;
  // reverse if right-to-left
  var direction = this.options.rightToLeft ? -1 : 1;
  if ( this.options.wrapAround ) {
    // wrap around move. #589
    moveVector.x = moveVector.x % this.slideableWidth;
  }
  var dragX = this.dragStartPosition + moveVector.x * direction;

  if ( !this.options.wrapAround && this.slides.length ) {
    // slow drag
    var originBound = Math.max( -this.slides[0].target, this.dragStartPosition );
    dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX;
    var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition );
    dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX;
  }

  this.dragX = dragX;

  this.dragMoveTime = new Date();
  this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] );
};

proto.dragEnd = function( event, pointer ) {
  if ( !this.isDraggable ) {
    return;
  }
  if ( this.options.freeScroll ) {
    this.isFreeScrolling = true;
  }
  // set selectedIndex based on where flick will end up
  var index = this.dragEndRestingSelect();

  if ( this.options.freeScroll && !this.options.wrapAround ) {
    // if free-scroll & not wrap around
    // do not free-scroll if going outside of bounding slides
    // so bounding slides can attract slider, and keep it in bounds
    var restingX = this.getRestingPosition();
    this.isFreeScrolling = -restingX > this.slides[0].target &&
      -restingX < this.getLastSlide().target;
  } else if ( !this.options.freeScroll && index == this.selectedIndex ) {
    // boost selection if selected index has not changed
    index += this.dragEndBoostSelect();
  }
  delete this.previousDragX;
  // apply selection
  // TODO refactor this, selecting here feels weird
  // HACK, set flag so dragging stays in correct direction
  this.isDragSelect = this.options.wrapAround;
  this.select( index );
  delete this.isDragSelect;
  this.dispatchEvent( 'dragEnd', event, [ pointer ] );
};

proto.dragEndRestingSelect = function() {
  var restingX = this.getRestingPosition();
  // how far away from selected slide
  var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) );
  // get closet resting going up and going down
  var positiveResting = this._getClosestResting( restingX, distance, 1 );
  var negativeResting = this._getClosestResting( restingX, distance, -1 );
  // use closer resting for wrap-around
  var index = positiveResting.distance < negativeResting.distance ?
    positiveResting.index : negativeResting.index;
  return index;
};

/**
 * given resting X and distance to selected cell
 * get the distance and index of the closest cell
 * @param {Number} restingX - estimated post-flick resting position
 * @param {Number} distance - distance to selected cell
 * @param {Integer} increment - +1 or -1, going up or down
 * @returns {Object} - { distance: {Number}, index: {Integer} }
 */
proto._getClosestResting = function( restingX, distance, increment ) {
  var index = this.selectedIndex;
  var minDistance = Infinity;
  var condition = this.options.contain && !this.options.wrapAround ?
    // if contain, keep going if distance is equal to minDistance
    function( d, md ) { return d <= md; } : function( d, md ) { return d < md; };
  while ( condition( distance, minDistance ) ) {
    // measure distance to next cell
    index += increment;
    minDistance = distance;
    distance = this.getSlideDistance( -restingX, index );
    if ( distance === null ) {
      break;
    }
    distance = Math.abs( distance );
  }
  return {
    distance: minDistance,
    // selected was previous index
    index: index - increment
  };
};

/**
 * measure distance between x and a slide target
 * @param {Number} x
 * @param {Integer} index - slide index
 */
proto.getSlideDistance = function( x, index ) {
  var len = this.slides.length;
  // wrap around if at least 2 slides
  var isWrapAround = this.options.wrapAround && len > 1;
  var slideIndex = isWrapAround ? utils.modulo( index, len ) : index;
  var slide = this.slides[ slideIndex ];
  if ( !slide ) {
    return null;
  }
  // add distance for wrap-around slides
  var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0;
  return x - ( slide.target + wrap );
};

proto.dragEndBoostSelect = function() {
  // do not boost if no previousDragX or dragMoveTime
  if ( this.previousDragX === undefined || !this.dragMoveTime ||
    // or if drag was held for 100 ms
    new Date() - this.dragMoveTime > 100 ) {
    return 0;
  }

  var distance = this.getSlideDistance( -this.dragX, this.selectedIndex );
  var delta = this.previousDragX - this.dragX;
  if ( distance > 0 && delta > 0 ) {
    // boost to next if moving towards the right, and positive velocity
    return 1;
  } else if ( distance < 0 && delta < 0 ) {
    // boost to previous if moving towards the left, and negative velocity
    return -1;
  }
  return 0;
};

// ----- staticClick ----- //

proto.staticClick = function( event, pointer ) {
  // get clickedCell, if cell was clicked
  var clickedCell = this.getParentCell( event.target );
  var cellElem = clickedCell && clickedCell.element;
  var cellIndex = clickedCell && this.cells.indexOf( clickedCell );
  this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] );
};

// ----- scroll ----- //

proto.onscroll = function() {
  var scroll = getScrollPosition();
  var scrollMoveX = this.pointerDownScroll.x - scroll.x;
  var scrollMoveY = this.pointerDownScroll.y - scroll.y;
  // cancel click/tap if scroll is too much
  if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) {
    this._pointerDone();
  }
};

// ----- utils ----- //

function getScrollPosition() {
  return {
    x: window.pageXOffset,
    y: window.pageYOffset
  };
}

// -----  ----- //

return Flickity;

}));

// prev/next buttons
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/prev-next-button',[
      './flickity',
      'unipointer/unipointer',
      'fizzy-ui-utils/utils'
    ], function( Flickity, Unipointer, utils ) {
      return factory( window, Flickity, Unipointer, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('./flickity'),
      require('unipointer'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    factory(
      window,
      window.Flickity,
      window.Unipointer,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, Flickity, Unipointer, utils ) {
'use strict';

var svgURI = 'http://www.w3.org/2000/svg';

// -------------------------- PrevNextButton -------------------------- //

function PrevNextButton( direction, parent ) {
  this.direction = direction;
  this.parent = parent;
  this._create();
}

PrevNextButton.prototype = Object.create( Unipointer.prototype );

PrevNextButton.prototype._create = function() {
  // properties
  this.isEnabled = true;
  this.isPrevious = this.direction == -1;
  var leftDirection = this.parent.options.rightToLeft ? 1 : -1;
  this.isLeft = this.direction == leftDirection;

  var element = this.element = document.createElement('button');
  element.className = 'flickity-button flickity-prev-next-button';
  element.className += this.isPrevious ? ' previous' : ' next';
  // prevent button from submitting form http://stackoverflow.com/a/10836076/182183
  element.setAttribute( 'type', 'button' );
  // init as disabled
  this.disable();

  element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' );

  // create arrow
  var svg = this.createSVG();
  element.appendChild( svg );
  // events
  this.parent.on( 'select', this.update.bind( this ) );
  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
};

PrevNextButton.prototype.activate = function() {
  this.bindStartEvent( this.element );
  this.element.addEventListener( 'click', this );
  // add to DOM
  this.parent.element.appendChild( this.element );
};

PrevNextButton.prototype.deactivate = function() {
  // remove from DOM
  this.parent.element.removeChild( this.element );
  // click events
  this.unbindStartEvent( this.element );
  this.element.removeEventListener( 'click', this );
};

PrevNextButton.prototype.createSVG = function() {
  var svg = document.createElementNS( svgURI, 'svg');
  svg.setAttribute( 'class', 'flickity-button-icon' );
  svg.setAttribute( 'viewBox', '0 0 100 100' );
  var path = document.createElementNS( svgURI, 'path');
  var pathMovements = getArrowMovements( this.parent.options.arrowShape );
  path.setAttribute( 'd', pathMovements );
  path.setAttribute( 'class', 'arrow' );
  // rotate arrow
  if ( !this.isLeft ) {
    path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' );
  }
  svg.appendChild( path );
  return svg;
};

// get SVG path movmement
function getArrowMovements( shape ) {
  // use shape as movement if string
  if ( typeof shape == 'string' ) {
    return shape;
  }
  // create movement string
  return 'M ' + shape.x0 + ',50' +
    ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) +
    ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) +
    ' L ' + shape.x3 + ',50 ' +
    ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) +
    ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) +
    ' Z';
}

PrevNextButton.prototype.handleEvent = utils.handleEvent;

PrevNextButton.prototype.onclick = function() {
  if ( !this.isEnabled ) {
    return;
  }
  this.parent.uiChange();
  var method = this.isPrevious ? 'previous' : 'next';
  this.parent[ method ]();
};

// -----  ----- //

PrevNextButton.prototype.enable = function() {
  if ( this.isEnabled ) {
    return;
  }
  this.element.disabled = false;
  this.isEnabled = true;
};

PrevNextButton.prototype.disable = function() {
  if ( !this.isEnabled ) {
    return;
  }
  this.element.disabled = true;
  this.isEnabled = false;
};

PrevNextButton.prototype.update = function() {
  // index of first or last slide, if previous or next
  var slides = this.parent.slides;
  // enable is wrapAround and at least 2 slides
  if ( this.parent.options.wrapAround && slides.length > 1 ) {
    this.enable();
    return;
  }
  var lastIndex = slides.length ? slides.length - 1 : 0;
  var boundIndex = this.isPrevious ? 0 : lastIndex;
  var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable';
  this[ method ]();
};

PrevNextButton.prototype.destroy = function() {
  this.deactivate();
  this.allOff();
};

// -------------------------- Flickity prototype -------------------------- //

utils.extend( Flickity.defaults, {
  prevNextButtons: true,
  arrowShape: {
    x0: 10,
    x1: 60, y1: 50,
    x2: 70, y2: 40,
    x3: 30
  }
});

Flickity.createMethods.push('_createPrevNextButtons');
var proto = Flickity.prototype;

proto._createPrevNextButtons = function() {
  if ( !this.options.prevNextButtons ) {
    return;
  }

  this.prevButton = new PrevNextButton( -1, this );
  this.nextButton = new PrevNextButton( 1, this );

  this.on( 'activate', this.activatePrevNextButtons );
};

proto.activatePrevNextButtons = function() {
  this.prevButton.activate();
  this.nextButton.activate();
  this.on( 'deactivate', this.deactivatePrevNextButtons );
};

proto.deactivatePrevNextButtons = function() {
  this.prevButton.deactivate();
  this.nextButton.deactivate();
  this.off( 'deactivate', this.deactivatePrevNextButtons );
};

// --------------------------  -------------------------- //

Flickity.PrevNextButton = PrevNextButton;

return Flickity;

}));

// page dots
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/page-dots',[
      './flickity',
      'unipointer/unipointer',
      'fizzy-ui-utils/utils'
    ], function( Flickity, Unipointer, utils ) {
      return factory( window, Flickity, Unipointer, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('./flickity'),
      require('unipointer'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    factory(
      window,
      window.Flickity,
      window.Unipointer,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, Flickity, Unipointer, utils ) {

// -------------------------- PageDots -------------------------- //



function PageDots( parent ) {
  this.parent = parent;
  this._create();
}

PageDots.prototype = Object.create( Unipointer.prototype );

PageDots.prototype._create = function() {
  // create holder element
  this.holder = document.createElement('ol');
  this.holder.className = 'flickity-page-dots';
  // create dots, array of elements
  this.dots = [];
  // events
  this.handleClick = this.onClick.bind( this );
  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
};

PageDots.prototype.activate = function() {
  this.setDots();
  this.holder.addEventListener( 'click', this.handleClick );
  this.bindStartEvent( this.holder );
  // add to DOM
  this.parent.element.appendChild( this.holder );
};

PageDots.prototype.deactivate = function() {
  this.holder.removeEventListener( 'click', this.handleClick );
  this.unbindStartEvent( this.holder );
  // remove from DOM
  this.parent.element.removeChild( this.holder );
};

PageDots.prototype.setDots = function() {
  // get difference between number of slides and number of dots
  var delta = this.parent.slides.length - this.dots.length;
  if ( delta > 0 ) {
    this.addDots( delta );
  } else if ( delta < 0 ) {
    this.removeDots( -delta );
  }
};

PageDots.prototype.addDots = function( count ) {
  var fragment = document.createDocumentFragment();
  var newDots = [];
  var length = this.dots.length;
  var max = length + count;

  for ( var i = length; i < max; i++ ) {
    var dot = document.createElement('li');
    dot.className = 'dot';
    dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) );
    fragment.appendChild( dot );
    newDots.push( dot );
  }

  this.holder.appendChild( fragment );
  this.dots = this.dots.concat( newDots );
};

PageDots.prototype.removeDots = function( count ) {
  // remove from this.dots collection
  var removeDots = this.dots.splice( this.dots.length - count, count );
  // remove from DOM
  removeDots.forEach( function( dot ) {
    this.holder.removeChild( dot );
  }, this );
};

PageDots.prototype.updateSelected = function() {
  // remove selected class on previous
  if ( this.selectedDot ) {
    this.selectedDot.className = 'dot';
    this.selectedDot.removeAttribute('aria-current');
  }
  // don't proceed if no dots
  if ( !this.dots.length ) {
    return;
  }
  this.selectedDot = this.dots[ this.parent.selectedIndex ];
  this.selectedDot.className = 'dot is-selected';
  this.selectedDot.setAttribute( 'aria-current', 'step' );
};

PageDots.prototype.onTap = // old method name, backwards-compatible
PageDots.prototype.onClick = function( event ) {
  var target = event.target;
  // only care about dot clicks
  if ( target.nodeName != 'LI' ) {
    return;
  }

  this.parent.uiChange();
  var index = this.dots.indexOf( target );
  this.parent.select( index );
};

PageDots.prototype.destroy = function() {
  this.deactivate();
  this.allOff();
};

Flickity.PageDots = PageDots;

// -------------------------- Flickity -------------------------- //

utils.extend( Flickity.defaults, {
  pageDots: true
});

Flickity.createMethods.push('_createPageDots');

var proto = Flickity.prototype;

proto._createPageDots = function() {
  if ( !this.options.pageDots ) {
    return;
  }
  this.pageDots = new PageDots( this );
  // events
  this.on( 'activate', this.activatePageDots );
  this.on( 'select', this.updateSelectedPageDots );
  this.on( 'cellChange', this.updatePageDots );
  this.on( 'resize', this.updatePageDots );
  this.on( 'deactivate', this.deactivatePageDots );
};

proto.activatePageDots = function() {
  this.pageDots.activate();
};

proto.updateSelectedPageDots = function() {
  this.pageDots.updateSelected();
};

proto.updatePageDots = function() {
  this.pageDots.setDots();
};

proto.deactivatePageDots = function() {
  this.pageDots.deactivate();
};

// -----  ----- //

Flickity.PageDots = PageDots;

return Flickity;

}));

// player & autoPlay
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/player',[
      'ev-emitter/ev-emitter',
      'fizzy-ui-utils/utils',
      './flickity'
    ], function( EvEmitter, utils, Flickity ) {
      return factory( EvEmitter, utils, Flickity );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('ev-emitter'),
      require('fizzy-ui-utils'),
      require('./flickity')
    );
  } else {
    // browser global
    factory(
      window.EvEmitter,
      window.fizzyUIUtils,
      window.Flickity
    );
  }

}( window, function factory( EvEmitter, utils, Flickity ) {



// -------------------------- Player -------------------------- //

function Player( parent ) {
  this.parent = parent;
  this.state = 'stopped';
  // visibility change event handler
  this.onVisibilityChange = this.visibilityChange.bind( this );
  this.onVisibilityPlay = this.visibilityPlay.bind( this );
}

Player.prototype = Object.create( EvEmitter.prototype );

// start play
Player.prototype.play = function() {
  if ( this.state == 'playing' ) {
    return;
  }
  // do not play if page is hidden, start playing when page is visible
  var isPageHidden = document.hidden;
  if ( isPageHidden ) {
    document.addEventListener( 'visibilitychange', this.onVisibilityPlay );
    return;
  }

  this.state = 'playing';
  // listen to visibility change
  document.addEventListener( 'visibilitychange', this.onVisibilityChange );
  // start ticking
  this.tick();
};

Player.prototype.tick = function() {
  // do not tick if not playing
  if ( this.state != 'playing' ) {
    return;
  }

  var time = this.parent.options.autoPlay;
  // default to 3 seconds
  time = typeof time == 'number' ? time : 3000;
  var _this = this;
  // HACK: reset ticks if stopped and started within interval
  this.clear();
  this.timeout = setTimeout( function() {
    _this.parent.next( true );
    _this.tick();
  }, time );
};

Player.prototype.stop = function() {
  this.state = 'stopped';
  this.clear();
  // remove visibility change event
  document.removeEventListener( 'visibilitychange', this.onVisibilityChange );
};

Player.prototype.clear = function() {
  clearTimeout( this.timeout );
};

Player.prototype.pause = function() {
  if ( this.state == 'playing' ) {
    this.state = 'paused';
    this.clear();
  }
};

Player.prototype.unpause = function() {
  // re-start play if paused
  if ( this.state == 'paused' ) {
    this.play();
  }
};

// pause if page visibility is hidden, unpause if visible
Player.prototype.visibilityChange = function() {
  var isPageHidden = document.hidden;
  this[ isPageHidden ? 'pause' : 'unpause' ]();
};

Player.prototype.visibilityPlay = function() {
  this.play();
  document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );
};

// -------------------------- Flickity -------------------------- //

utils.extend( Flickity.defaults, {
  pauseAutoPlayOnHover: true
});

Flickity.createMethods.push('_createPlayer');
var proto = Flickity.prototype;

proto._createPlayer = function() {
  this.player = new Player( this );

  this.on( 'activate', this.activatePlayer );
  this.on( 'uiChange', this.stopPlayer );
  this.on( 'pointerDown', this.stopPlayer );
  this.on( 'deactivate', this.deactivatePlayer );
};

proto.activatePlayer = function() {
  if ( !this.options.autoPlay ) {
    return;
  }
  this.player.play();
  this.element.addEventListener( 'mouseenter', this );
};

// Player API, don't hate the ... thanks I know where the door is

proto.playPlayer = function() {
  this.player.play();
};

proto.stopPlayer = function() {
  this.player.stop();
};

proto.pausePlayer = function() {
  this.player.pause();
};

proto.unpausePlayer = function() {
  this.player.unpause();
};

proto.deactivatePlayer = function() {
  this.player.stop();
  this.element.removeEventListener( 'mouseenter', this );
};

// ----- mouseenter/leave ----- //

// pause auto-play on hover
proto.onmouseenter = function() {
  if ( !this.options.pauseAutoPlayOnHover ) {
    return;
  }
  this.player.pause();
  this.element.addEventListener( 'mouseleave', this );
};

// resume auto-play on hover off
proto.onmouseleave = function() {
  this.player.unpause();
  this.element.removeEventListener( 'mouseleave', this );
};

// -----  ----- //

Flickity.Player = Player;

return Flickity;

}));

// add, remove cell
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/add-remove-cell',[
      './flickity',
      'fizzy-ui-utils/utils'
    ], function( Flickity, utils ) {
      return factory( window, Flickity, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('./flickity'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    factory(
      window,
      window.Flickity,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, Flickity, utils ) {



// append cells to a document fragment
function getCellsFragment( cells ) {
  var fragment = document.createDocumentFragment();
  cells.forEach( function( cell ) {
    fragment.appendChild( cell.element );
  });
  return fragment;
}

// -------------------------- add/remove cell prototype -------------------------- //

var proto = Flickity.prototype;

/**
 * Insert, prepend, or append cells
 * @param {Element, Array, NodeList} elems
 * @param {Integer} index
 */
proto.insert = function( elems, index ) {
  var cells = this._makeCells( elems );
  if ( !cells || !cells.length ) {
    return;
  }
  var len = this.cells.length;
  // default to append
  index = index === undefined ? len : index;
  // add cells with document fragment
  var fragment = getCellsFragment( cells );
  // append to slider
  var isAppend = index == len;
  if ( isAppend ) {
    this.slider.appendChild( fragment );
  } else {
    var insertCellElement = this.cells[ index ].element;
    this.slider.insertBefore( fragment, insertCellElement );
  }
  // add to this.cells
  if ( index === 0 ) {
    // prepend, add to start
    this.cells = cells.concat( this.cells );
  } else if ( isAppend ) {
    // append, add to end
    this.cells = this.cells.concat( cells );
  } else {
    // insert in this.cells
    var endCells = this.cells.splice( index, len - index );
    this.cells = this.cells.concat( cells ).concat( endCells );
  }

  this._sizeCells( cells );
  this.cellChange( index, true );
};

proto.append = function( elems ) {
  this.insert( elems, this.cells.length );
};

proto.prepend = function( elems ) {
  this.insert( elems, 0 );
};

/**
 * Remove cells
 * @param {Element, Array, NodeList} elems
 */
proto.remove = function( elems ) {
  var cells = this.getCells( elems );
  if ( !cells || !cells.length ) {
    return;
  }

  var minCellIndex = this.cells.length - 1;
  // remove cells from collection & DOM
  cells.forEach( function( cell ) {
    cell.remove();
    var index = this.cells.indexOf( cell );
    minCellIndex = Math.min( index, minCellIndex );
    utils.removeFrom( this.cells, cell );
  }, this );

  this.cellChange( minCellIndex, true );
};

/**
 * logic to be run after a cell's size changes
 * @param {Element} elem - cell's element
 */
proto.cellSizeChange = function( elem ) {
  var cell = this.getCell( elem );
  if ( !cell ) {
    return;
  }
  cell.getSize();

  var index = this.cells.indexOf( cell );
  this.cellChange( index );
};

/**
 * logic any time a cell is changed: added, removed, or size changed
 * @param {Integer} changedCellIndex - index of the changed cell, optional
 */
proto.cellChange = function( changedCellIndex, isPositioningSlider ) {
  var prevSelectedElem = this.selectedElement;
  this._positionCells( changedCellIndex );
  this._getWrapShiftCells();
  this.setGallerySize();
  // update selectedIndex
  // try to maintain position & select previous selected element
  var cell = this.getCell( prevSelectedElem );
  if ( cell ) {
    this.selectedIndex = this.getCellSlideIndex( cell );
  }
  this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );

  this.emitEvent( 'cellChange', [ changedCellIndex ] );
  // position slider
  this.select( this.selectedIndex );
  // do not position slider after lazy load
  if ( isPositioningSlider ) {
    this.positionSliderAtSelected();
  }
};

// -----  ----- //

return Flickity;

}));

// lazyload
( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/lazyload',[
      './flickity',
      'fizzy-ui-utils/utils'
    ], function( Flickity, utils ) {
      return factory( window, Flickity, utils );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('./flickity'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    factory(
      window,
      window.Flickity,
      window.fizzyUIUtils
    );
  }

}( window, function factory( window, Flickity, utils ) {
'use strict';

Flickity.createMethods.push('_createLazyload');
var proto = Flickity.prototype;

proto._createLazyload = function() {
  this.on( 'select', this.lazyLoad );
};

proto.lazyLoad = function() {
  var lazyLoad = this.options.lazyLoad;
  if ( !lazyLoad ) {
    return;
  }
  // get adjacent cells, use lazyLoad option for adjacent count
  var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0;
  var cellElems = this.getAdjacentCellElements( adjCount );
  // get lazy images in those cells
  var lazyImages = [];
  cellElems.forEach( function( cellElem ) {
    var lazyCellImages = getCellLazyImages( cellElem );
    lazyImages = lazyImages.concat( lazyCellImages );
  });
  // load lazy images
  lazyImages.forEach( function( img ) {
    new LazyLoader( img, this );
  }, this );
};

function getCellLazyImages( cellElem ) {
  // check if cell element is lazy image
  if ( cellElem.nodeName == 'IMG' ) {
    var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload');
    var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src');
    var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset');
    if ( lazyloadAttr || srcAttr || srcsetAttr ) {
      return [ cellElem ];
    }
  }
  // select lazy images in cell
  var lazySelector = 'img[data-flickity-lazyload], ' +
    'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]';
  var imgs = cellElem.querySelectorAll( lazySelector );
  return utils.makeArray( imgs );
}

// -------------------------- LazyLoader -------------------------- //

/**
 * class to handle loading images
 */
function LazyLoader( img, flickity ) {
  this.img = img;
  this.flickity = flickity;
  this.load();
}

LazyLoader.prototype.handleEvent = utils.handleEvent;

LazyLoader.prototype.load = function() {
  this.img.addEventListener( 'load', this );
  this.img.addEventListener( 'error', this );
  // get src & srcset
  var src = this.img.getAttribute('data-flickity-lazyload') ||
    this.img.getAttribute('data-flickity-lazyload-src');
  var srcset = this.img.getAttribute('data-flickity-lazyload-srcset');
  // set src & serset
  this.img.src = src;
  if ( srcset ) {
    this.img.setAttribute( 'srcset', srcset );
  }
  // remove attr
  this.img.removeAttribute('data-flickity-lazyload');
  this.img.removeAttribute('data-flickity-lazyload-src');
  this.img.removeAttribute('data-flickity-lazyload-srcset');
};

LazyLoader.prototype.onload = function( event ) {
  this.complete( event, 'flickity-lazyloaded' );
};

LazyLoader.prototype.onerror = function( event ) {
  this.complete( event, 'flickity-lazyerror' );
};

LazyLoader.prototype.complete = function( event, className ) {
  // unbind events
  this.img.removeEventListener( 'load', this );
  this.img.removeEventListener( 'error', this );

  var cell = this.flickity.getParentCell( this.img );
  var cellElem = cell && cell.element;
  this.flickity.cellSizeChange( cellElem );

  this.img.classList.add( className );
  this.flickity.dispatchEvent( 'lazyLoad', event, cellElem );
};

// -----  ----- //

Flickity.LazyLoader = LazyLoader;

return Flickity;

}));

/*!
 * Flickity v2.2.1
 * Touch, responsive, flickable carousels
 *
 * Licensed GPLv3 for open source use
 * or Flickity Commercial License for commercial use
 *
 * https://flickity.metafizzy.co
 * Copyright 2015-2019 Metafizzy
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity/js/index',[
      './flickity',
      './drag',
      './prev-next-button',
      './page-dots',
      './player',
      './add-remove-cell',
      './lazyload'
    ], factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('./flickity'),
      require('./drag'),
      require('./prev-next-button'),
      require('./page-dots'),
      require('./player'),
      require('./add-remove-cell'),
      require('./lazyload')
    );
  }

})( window, function factory( Flickity ) {
  /*jshint strict: false*/
  return Flickity;
});

/*!
 * Flickity asNavFor v2.0.2
 * enable asNavFor for Flickity
 */

/*jshint browser: true, undef: true, unused: true, strict: true*/

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'flickity-as-nav-for/as-nav-for',[
      'flickity/js/index',
      'fizzy-ui-utils/utils'
    ], factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('flickity'),
      require('fizzy-ui-utils')
    );
  } else {
    // browser global
    window.Flickity = factory(
      window.Flickity,
      window.fizzyUIUtils
    );
  }

}( window, function factory( Flickity, utils ) {



// -------------------------- asNavFor prototype -------------------------- //

// Flickity.defaults.asNavFor = null;

Flickity.createMethods.push('_createAsNavFor');

var proto = Flickity.prototype;

proto._createAsNavFor = function() {
  this.on( 'activate', this.activateAsNavFor );
  this.on( 'deactivate', this.deactivateAsNavFor );
  this.on( 'destroy', this.destroyAsNavFor );

  var asNavForOption = this.options.asNavFor;
  if ( !asNavForOption ) {
    return;
  }
  // HACK do async, give time for other flickity to be initalized
  var _this = this;
  setTimeout( function initNavCompanion() {
    _this.setNavCompanion( asNavForOption );
  });
};

proto.setNavCompanion = function( elem ) {
  elem = utils.getQueryElement( elem );
  var companion = Flickity.data( elem );
  // stop if no companion or companion is self
  if ( !companion || companion == this ) {
    return;
  }

  this.navCompanion = companion;
  // companion select
  var _this = this;
  this.onNavCompanionSelect = function() {
    _this.navCompanionSelect();
  };
  companion.on( 'select', this.onNavCompanionSelect );
  // click
  this.on( 'staticClick', this.onNavStaticClick );

  this.navCompanionSelect( true );
};

proto.navCompanionSelect = function( isInstant ) {
  // wait for companion & selectedCells first. #8
  var companionCells = this.navCompanion && this.navCompanion.selectedCells;
  if ( !companionCells ) {
    return;
  }
  // select slide that matches first cell of slide
  var selectedCell = companionCells[0];
  var firstIndex = this.navCompanion.cells.indexOf( selectedCell );
  var lastIndex = firstIndex + companionCells.length - 1;
  var selectIndex = Math.floor( lerp( firstIndex, lastIndex,
    this.navCompanion.cellAlign ) );
  this.selectCell( selectIndex, false, isInstant );
  // set nav selected class
  this.removeNavSelectedElements();
  // stop if companion has more cells than this one
  if ( selectIndex >= this.cells.length ) {
    return;
  }

  var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 );
  this.navSelectedElements = selectedCells.map( function( cell ) {
    return cell.element;
  });
  this.changeNavSelectedClass('add');
};

function lerp( a, b, t ) {
  return ( b - a ) * t + a;
}

proto.changeNavSelectedClass = function( method ) {
  this.navSelectedElements.forEach( function( navElem ) {
    navElem.classList[ method ]('is-nav-selected');
  });
};

proto.activateAsNavFor = function() {
  this.navCompanionSelect( true );
};

proto.removeNavSelectedElements = function() {
  if ( !this.navSelectedElements ) {
    return;
  }
  this.changeNavSelectedClass('remove');
  delete this.navSelectedElements;
};

proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) {
  if ( typeof cellIndex == 'number' ) {
    this.navCompanion.selectCell( cellIndex );
  }
};

proto.deactivateAsNavFor = function() {
  this.removeNavSelectedElements();
};

proto.destroyAsNavFor = function() {
  if ( !this.navCompanion ) {
    return;
  }
  this.navCompanion.off( 'select', this.onNavCompanionSelect );
  this.off( 'staticClick', this.onNavStaticClick );
  delete this.navCompanion;
};

// -----  ----- //

return Flickity;

}));

/*!
 * imagesLoaded v4.1.4
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) { 'use strict';
  // universal module definition

  /*global define: false, module: false, require: false */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'imagesloaded/imagesloaded',[
      'ev-emitter/ev-emitter'
    ], function( EvEmitter ) {
      return factory( window, EvEmitter );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('ev-emitter')
    );
  } else {
    // browser global
    window.imagesLoaded = factory(
      window,
      window.EvEmitter
    );
  }

})( typeof window !== 'undefined' ? window : this,

// --------------------------  factory -------------------------- //

function factory( window, EvEmitter ) {



var $ = window.jQuery;
var console = window.console;

// -------------------------- helpers -------------------------- //

// extend objects
function extend( a, b ) {
  for ( var prop in b ) {
    a[ prop ] = b[ prop ];
  }
  return a;
}

var arraySlice = Array.prototype.slice;

// turn element or nodeList into an array
function makeArray( obj ) {
  if ( Array.isArray( obj ) ) {
    // use object if already an array
    return obj;
  }

  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  if ( isArrayLike ) {
    // convert nodeList to array
    return arraySlice.call( obj );
  }

  // array of single index
  return [ obj ];
}

// -------------------------- imagesLoaded -------------------------- //

/**
 * @param {Array, Element, NodeList, String} elem
 * @param {Object or Function} options - if function, use as callback
 * @param {Function} onAlways - callback function
 */
function ImagesLoaded( elem, options, onAlways ) {
  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
  if ( !( this instanceof ImagesLoaded ) ) {
    return new ImagesLoaded( elem, options, onAlways );
  }
  // use elem as selector string
  var queryElem = elem;
  if ( typeof elem == 'string' ) {
    queryElem = document.querySelectorAll( elem );
  }
  // bail if bad element
  if ( !queryElem ) {
    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
    return;
  }

  this.elements = makeArray( queryElem );
  this.options = extend( {}, this.options );
  // shift arguments if no options set
  if ( typeof options == 'function' ) {
    onAlways = options;
  } else {
    extend( this.options, options );
  }

  if ( onAlways ) {
    this.on( 'always', onAlways );
  }

  this.getImages();

  if ( $ ) {
    // add jQuery Deferred object
    this.jqDeferred = new $.Deferred();
  }

  // HACK check async to allow time to bind listeners
  setTimeout( this.check.bind( this ) );
}

ImagesLoaded.prototype = Object.create( EvEmitter.prototype );

ImagesLoaded.prototype.options = {};

ImagesLoaded.prototype.getImages = function() {
  this.images = [];

  // filter & find items if we have an item selector
  this.elements.forEach( this.addElementImages, this );
};

/**
 * @param {Node} element
 */
ImagesLoaded.prototype.addElementImages = function( elem ) {
  // filter siblings
  if ( elem.nodeName == 'IMG' ) {
    this.addImage( elem );
  }
  // get background image on element
  if ( this.options.background === true ) {
    this.addElementBackgroundImages( elem );
  }

  // find children
  // no non-element nodes, #143
  var nodeType = elem.nodeType;
  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
    return;
  }
  var childImgs = elem.querySelectorAll('img');
  // concat childElems to filterFound array
  for ( var i=0; i < childImgs.length; i++ ) {
    var img = childImgs[i];
    this.addImage( img );
  }

  // get child background images
  if ( typeof this.options.background == 'string' ) {
    var children = elem.querySelectorAll( this.options.background );
    for ( i=0; i < children.length; i++ ) {
      var child = children[i];
      this.addElementBackgroundImages( child );
    }
  }
};

var elementNodeTypes = {
  1: true,
  9: true,
  11: true
};

ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
  var style = getComputedStyle( elem );
  if ( !style ) {
    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
    return;
  }
  // get url inside url("...")
  var reURL = /url\((['"])?(.*?)\1\)/gi;
  var matches = reURL.exec( style.backgroundImage );
  while ( matches !== null ) {
    var url = matches && matches[2];
    if ( url ) {
      this.addBackground( url, elem );
    }
    matches = reURL.exec( style.backgroundImage );
  }
};

/**
 * @param {Image} img
 */
ImagesLoaded.prototype.addImage = function( img ) {
  var loadingImage = new LoadingImage( img );
  this.images.push( loadingImage );
};

ImagesLoaded.prototype.addBackground = function( url, elem ) {
  var background = new Background( url, elem );
  this.images.push( background );
};

ImagesLoaded.prototype.check = function() {
  var _this = this;
  this.progressedCount = 0;
  this.hasAnyBroken = false;
  // complete if no images
  if ( !this.images.length ) {
    this.complete();
    return;
  }

  function onProgress( image, elem, message ) {
    // HACK - Chrome triggers event before object properties have changed. #83
    setTimeout( function() {
      _this.progress( image, elem, message );
    });
  }

  this.images.forEach( function( loadingImage ) {
    loadingImage.once( 'progress', onProgress );
    loadingImage.check();
  });
};

ImagesLoaded.prototype.progress = function( image, elem, message ) {
  this.progressedCount++;
  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
  // progress event
  this.emitEvent( 'progress', [ this, image, elem ] );
  if ( this.jqDeferred && this.jqDeferred.notify ) {
    this.jqDeferred.notify( this, image );
  }
  // check if completed
  if ( this.progressedCount == this.images.length ) {
    this.complete();
  }

  if ( this.options.debug && console ) {
    console.log( 'progress: ' + message, image, elem );
  }
};

ImagesLoaded.prototype.complete = function() {
  var eventName = this.hasAnyBroken ? 'fail' : 'done';
  this.isComplete = true;
  this.emitEvent( eventName, [ this ] );
  this.emitEvent( 'always', [ this ] );
  if ( this.jqDeferred ) {
    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
    this.jqDeferred[ jqMethod ]( this );
  }
};

// --------------------------  -------------------------- //

function LoadingImage( img ) {
  this.img = img;
}

LoadingImage.prototype = Object.create( EvEmitter.prototype );

LoadingImage.prototype.check = function() {
  // If complete is true and browser supports natural sizes,
  // try to check for image status manually.
  var isComplete = this.getIsImageComplete();
  if ( isComplete ) {
    // report based on naturalWidth
    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
    return;
  }

  // If none of the checks above matched, simulate loading on detached element.
  this.proxyImage = new Image();
  this.proxyImage.addEventListener( 'load', this );
  this.proxyImage.addEventListener( 'error', this );
  // bind to image as well for Firefox. #191
  this.img.addEventListener( 'load', this );
  this.img.addEventListener( 'error', this );
  this.proxyImage.src = this.img.src;
};

LoadingImage.prototype.getIsImageComplete = function() {
  // check for non-zero, non-undefined naturalWidth
  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
  return this.img.complete && this.img.naturalWidth;
};

LoadingImage.prototype.confirm = function( isLoaded, message ) {
  this.isLoaded = isLoaded;
  this.emitEvent( 'progress', [ this, this.img, message ] );
};

// ----- events ----- //

// trigger specified handler for event type
LoadingImage.prototype.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

LoadingImage.prototype.onload = function() {
  this.confirm( true, 'onload' );
  this.unbindEvents();
};

LoadingImage.prototype.onerror = function() {
  this.confirm( false, 'onerror' );
  this.unbindEvents();
};

LoadingImage.prototype.unbindEvents = function() {
  this.proxyImage.removeEventListener( 'load', this );
  this.proxyImage.removeEventListener( 'error', this );
  this.img.removeEventListener( 'load', this );
  this.img.removeEventListener( 'error', this );
};

// -------------------------- Background -------------------------- //

function Background( url, element ) {
  this.url = url;
  this.element = element;
  this.img = new Image();
}

// inherit LoadingImage prototype
Background.prototype = Object.create( LoadingImage.prototype );

Background.prototype.check = function() {
  this.img.addEventListener( 'load', this );
  this.img.addEventListener( 'error', this );
  this.img.src = this.url;
  // check if image is already complete
  var isComplete = this.getIsImageComplete();
  if ( isComplete ) {
    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
    this.unbindEvents();
  }
};

Background.prototype.unbindEvents = function() {
  this.img.removeEventListener( 'load', this );
  this.img.removeEventListener( 'error', this );
};

Background.prototype.confirm = function( isLoaded, message ) {
  this.isLoaded = isLoaded;
  this.emitEvent( 'progress', [ this, this.element, message ] );
};

// -------------------------- jQuery -------------------------- //

ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
  jQuery = jQuery || window.jQuery;
  if ( !jQuery ) {
    return;
  }
  // set local variable
  $ = jQuery;
  // $().imagesLoaded()
  $.fn.imagesLoaded = function( options, callback ) {
    var instance = new ImagesLoaded( this, options, callback );
    return instance.jqDeferred.promise( $(this) );
  };
};
// try making plugin
ImagesLoaded.makeJQueryPlugin();

// --------------------------  -------------------------- //

return ImagesLoaded;

});

/*!
 * Flickity imagesLoaded v2.0.0
 * enables imagesLoaded option for Flickity
 */

/*jshint browser: true, strict: true, undef: true, unused: true */

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( [
      'flickity/js/index',
      'imagesloaded/imagesloaded'
    ], function( Flickity, imagesLoaded ) {
      return factory( window, Flickity, imagesLoaded );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('flickity'),
      require('imagesloaded')
    );
  } else {
    // browser global
    window.Flickity = factory(
      window,
      window.Flickity,
      window.imagesLoaded
    );
  }

}( window, function factory( window, Flickity, imagesLoaded ) {
'use strict';

Flickity.createMethods.push('_createImagesLoaded');

var proto = Flickity.prototype;

proto._createImagesLoaded = function() {
  this.on( 'activate', this.imagesLoaded );
};

proto.imagesLoaded = function() {
  if ( !this.options.imagesLoaded ) {
    return;
  }
  var _this = this;
  function onImagesLoadedProgress( instance, image ) {
    var cell = _this.getParentCell( image.img );
    _this.cellSizeChange( cell && cell.element );
    if ( !_this.options.freeScroll ) {
      _this.positionSliderAtSelected();
    }
  }
  imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress );
};

return Flickity;

}));

;
//! moment.js
//! version : 2.9.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

(function (undefined) {
	/************************************
        Constants
    ************************************/

	var moment,
        VERSION = '2.9.0',
        // the global-scope this is NOT the global object in Node.js
        globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,
        oldGlobalMoment,
        round = Math.round,
        hasOwnProperty = Object.prototype.hasOwnProperty,
        i,

        YEAR = 0,
        MONTH = 1,
        DATE = 2,
        HOUR = 3,
        MINUTE = 4,
        SECOND = 5,
        MILLISECOND = 6,

        // internal storage for locale config files
        locales = {},

        // extra moment internal properties (plugins register props here)
        momentProperties = [],

        // check for nodeJS
        hasModule = (typeof module !== 'undefined' && module && module.exports),

        // ASP.NET json date format regex
        aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
        aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,

        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
        isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,

        // format tokens
        formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,
        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,

        // parsing token regexes
        parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
        parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
        parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
        parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
        parseTokenDigits = /\d+/, // nonzero number of digits
        parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
        parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
        parseTokenT = /T/i, // T (ISO separator)
        parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123
        parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123

        //strict parsing regexes
        parseTokenOneDigit = /\d/, // 0 - 9
        parseTokenTwoDigits = /\d\d/, // 00 - 99
        parseTokenThreeDigits = /\d{3}/, // 000 - 999
        parseTokenFourDigits = /\d{4}/, // 0000 - 9999
        parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
        parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf

        // iso 8601 regex
        // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
        isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,

        isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',

        isoDates = [
            ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
            ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
            ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
            ['GGGG-[W]WW', /\d{4}-W\d{2}/],
            ['YYYY-DDD', /\d{4}-\d{3}/]
        ],

        // iso time formats and regexes
        isoTimes = [
            ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
            ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
            ['HH:mm', /(T| )\d\d:\d\d/],
            ['HH', /(T| )\d\d/]
        ],

        // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']
        parseTimezoneChunker = /([\+\-]|\d\d)/gi,

        // getter and setter names
        proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
        unitMillisecondFactors = {
        	'Milliseconds': 1,
        	'Seconds': 1e3,
        	'Minutes': 6e4,
        	'Hours': 36e5,
        	'Days': 864e5,
        	'Months': 2592e6,
        	'Years': 31536e6
        },

        unitAliases = {
        	ms: 'millisecond',
        	s: 'second',
        	m: 'minute',
        	h: 'hour',
        	d: 'day',
        	D: 'date',
        	w: 'week',
        	W: 'isoWeek',
        	M: 'month',
        	Q: 'quarter',
        	y: 'year',
        	DDD: 'dayOfYear',
        	e: 'weekday',
        	E: 'isoWeekday',
        	gg: 'weekYear',
        	GG: 'isoWeekYear'
        },

        camelFunctions = {
        	dayofyear: 'dayOfYear',
        	isoweekday: 'isoWeekday',
        	isoweek: 'isoWeek',
        	weekyear: 'weekYear',
        	isoweekyear: 'isoWeekYear'
        },

        // format function strings
        formatFunctions = {},

        // default relative time thresholds
        relativeTimeThresholds = {
        	s: 45,  // seconds to minute
        	m: 45,  // minutes to hour
        	h: 22,  // hours to day
        	d: 26,  // days to month
        	M: 11   // months to year
        },

        // tokens to ordinalize and pad
        ordinalizeTokens = 'DDD w W M D d'.split(' '),
        paddedTokens = 'M D H h m s w W'.split(' '),

        formatTokenFunctions = {
        	M: function () {
        		return this.month() + 1;
        	},
        	MMM: function (format) {
        		return this.localeData().monthsShort(this, format);
        	},
        	MMMM: function (format) {
        		return this.localeData().months(this, format);
        	},
        	D: function () {
        		return this.date();
        	},
        	DDD: function () {
        		return this.dayOfYear();
        	},
        	d: function () {
        		return this.day();
        	},
        	dd: function (format) {
        		return this.localeData().weekdaysMin(this, format);
        	},
        	ddd: function (format) {
        		return this.localeData().weekdaysShort(this, format);
        	},
        	dddd: function (format) {
        		return this.localeData().weekdays(this, format);
        	},
        	w: function () {
        		return this.week();
        	},
        	W: function () {
        		return this.isoWeek();
        	},
        	YY: function () {
        		return leftZeroFill(this.year() % 100, 2);
        	},
        	YYYY: function () {
        		return leftZeroFill(this.year(), 4);
        	},
        	YYYYY: function () {
        		return leftZeroFill(this.year(), 5);
        	},
        	YYYYYY: function () {
        		var y = this.year(), sign = y >= 0 ? '+' : '-';
        		return sign + leftZeroFill(Math.abs(y), 6);
        	},
        	gg: function () {
        		return leftZeroFill(this.weekYear() % 100, 2);
        	},
        	gggg: function () {
        		return leftZeroFill(this.weekYear(), 4);
        	},
        	ggggg: function () {
        		return leftZeroFill(this.weekYear(), 5);
        	},
        	GG: function () {
        		return leftZeroFill(this.isoWeekYear() % 100, 2);
        	},
        	GGGG: function () {
        		return leftZeroFill(this.isoWeekYear(), 4);
        	},
        	GGGGG: function () {
        		return leftZeroFill(this.isoWeekYear(), 5);
        	},
        	e: function () {
        		return this.weekday();
        	},
        	E: function () {
        		return this.isoWeekday();
        	},
        	a: function () {
        		return this.localeData().meridiem(this.hours(), this.minutes(), true);
        	},
        	A: function () {
        		return this.localeData().meridiem(this.hours(), this.minutes(), false);
        	},
        	H: function () {
        		return this.hours();
        	},
        	h: function () {
        		return this.hours() % 12 || 12;
        	},
        	m: function () {
        		return this.minutes();
        	},
        	s: function () {
        		return this.seconds();
        	},
        	S: function () {
        		return toInt(this.milliseconds() / 100);
        	},
        	SS: function () {
        		return leftZeroFill(toInt(this.milliseconds() / 10), 2);
        	},
        	SSS: function () {
        		return leftZeroFill(this.milliseconds(), 3);
        	},
        	SSSS: function () {
        		return leftZeroFill(this.milliseconds(), 3);
        	},
        	Z: function () {
        		var a = this.utcOffset(),
                    b = '+';
        		if (a < 0) {
        			a = -a;
        			b = '-';
        		}
        		return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
        	},
        	ZZ: function () {
        		var a = this.utcOffset(),
                    b = '+';
        		if (a < 0) {
        			a = -a;
        			b = '-';
        		}
        		return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
        	},
        	z: function () {
        		return this.zoneAbbr();
        	},
        	zz: function () {
        		return this.zoneName();
        	},
        	x: function () {
        		return this.valueOf();
        	},
        	X: function () {
        		return this.unix();
        	},
        	Q: function () {
        		return this.quarter();
        	}
        },

        deprecations = {},

        lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],

        updateInProgress = false;

	// Pick the first defined of two or three arguments. dfl comes from
	// default.
	function dfl(a, b, c) {
		switch (arguments.length) {
			case 2: return a != null ? a : b;
			case 3: return a != null ? a : b != null ? b : c;
			default: throw new Error('Implement me');
		}
	}

	function hasOwnProp(a, b) {
		return hasOwnProperty.call(a, b);
	}

	function defaultParsingFlags() {
		// We need to deep clone this object, and es5 standard is not very
		// helpful.
		return {
			empty: false,
			unusedTokens: [],
			unusedInput: [],
			overflow: -2,
			charsLeftOver: 0,
			nullInput: false,
			invalidMonth: null,
			invalidFormat: false,
			userInvalidated: false,
			iso: false
		};
	}

	function printMsg(msg) {
		if (moment.suppressDeprecationWarnings === false &&
                typeof console !== 'undefined' && console.warn) {
			console.warn('Deprecation warning: ' + msg);
		}
	}

	function deprecate(msg, fn) {
		var firstTime = true;
		return extend(function () {
			if (firstTime) {
				printMsg(msg);
				firstTime = false;
			}
			return fn.apply(this, arguments);
		}, fn);
	}

	function deprecateSimple(name, msg) {
		if (!deprecations[name]) {
			printMsg(msg);
			deprecations[name] = true;
		}
	}

	function padToken(func, count) {
		return function (a) {
			return leftZeroFill(func.call(this, a), count);
		};
	}
	function ordinalizeToken(func, period) {
		return function (a) {
			return this.localeData().ordinal(func.call(this, a), period);
		};
	}

	function monthDiff(a, b) {
		// difference in months
		var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2, adjust;

		if (b - anchor < 0) {
			anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
			// linear across the month
			adjust = (b - anchor) / (anchor - anchor2);
		} else {
			anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
			// linear across the month
			adjust = (b - anchor) / (anchor2 - anchor);
		}

		return -(wholeMonthDiff + adjust);
	}

	while (ordinalizeTokens.length) {
		i = ordinalizeTokens.pop();
		formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
	}
	while (paddedTokens.length) {
		i = paddedTokens.pop();
		formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
	}
	formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);


	function meridiemFixWrap(locale, hour, meridiem) {
		var isPm;

		if (meridiem == null) {
			// nothing to do
			return hour;
		}
		if (locale.meridiemHour != null) {
			return locale.meridiemHour(hour, meridiem);
		} else if (locale.isPM != null) {
			// Fallback
			isPm = locale.isPM(meridiem);
			if (isPm && hour < 12) {
				hour += 12;
			}
			if (!isPm && hour === 12) {
				hour = 0;
			}
			return hour;
		} else {
			// thie is not supposed to happen
			return hour;
		}
	}

	/************************************
        Constructors
    ************************************/

	function Locale() {
	}

	// Moment prototype object
	function Moment(config, skipOverflow) {
		if (skipOverflow !== false) {
			checkOverflow(config);
		}
		copyConfig(this, config);
		this._d = new Date(+config._d);
		// Prevent infinite loop in case updateOffset creates new moment
		// objects.
		if (updateInProgress === false) {
			updateInProgress = true;
			moment.updateOffset(this);
			updateInProgress = false;
		}
	}

	// Duration Constructor
	function Duration(duration) {
		var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;

		// representation for dateAddRemove
		this._milliseconds = +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 36e5; // 1000 * 60 * 60
		// Because of dateAddRemove treats 24 hours as different from a
		// day when working around DST, we need to store them separately
		this._days = +days +
            weeks * 7;
		// It is impossible translate months into days without knowing
		// which months you are are talking about, so we have to store
		// it separately.
		this._months = +months +
            quarters * 3 +
            years * 12;

		this._data = {};

		this._locale = moment.localeData();

		this._bubble();
	}

	/************************************
        Helpers
    ************************************/


	function extend(a, b) {
		for (var i in b) {
			if (hasOwnProp(b, i)) {
				a[i] = b[i];
			}
		}

		if (hasOwnProp(b, 'toString')) {
			a.toString = b.toString;
		}

		if (hasOwnProp(b, 'valueOf')) {
			a.valueOf = b.valueOf;
		}

		return a;
	}

	function copyConfig(to, from) {
		var i, prop, val;

		if (typeof from._isAMomentObject !== 'undefined') {
			to._isAMomentObject = from._isAMomentObject;
		}
		if (typeof from._i !== 'undefined') {
			to._i = from._i;
		}
		if (typeof from._f !== 'undefined') {
			to._f = from._f;
		}
		if (typeof from._l !== 'undefined') {
			to._l = from._l;
		}
		if (typeof from._strict !== 'undefined') {
			to._strict = from._strict;
		}
		if (typeof from._tzm !== 'undefined') {
			to._tzm = from._tzm;
		}
		if (typeof from._isUTC !== 'undefined') {
			to._isUTC = from._isUTC;
		}
		if (typeof from._offset !== 'undefined') {
			to._offset = from._offset;
		}
		if (typeof from._pf !== 'undefined') {
			to._pf = from._pf;
		}
		if (typeof from._locale !== 'undefined') {
			to._locale = from._locale;
		}

		if (momentProperties.length > 0) {
			for (i in momentProperties) {
				prop = momentProperties[i];
				val = from[prop];
				if (typeof val !== 'undefined') {
					to[prop] = val;
				}
			}
		}

		return to;
	}

	function absRound(number) {
		if (number < 0) {
			return Math.ceil(number);
		} else {
			return Math.floor(number);
		}
	}

	// left zero fill a number
	// see http://jsperf.com/left-zero-filling for performance comparison
	function leftZeroFill(number, targetLength, forceSign) {
		var output = '' + Math.abs(number),
            sign = number >= 0;

		while (output.length < targetLength) {
			output = '0' + output;
		}
		return (sign ? (forceSign ? '+' : '') : '-') + output;
	}

	function positiveMomentsDifference(base, other) {
		var res = { milliseconds: 0, months: 0 };

		res.months = other.month() - base.month() +
            (other.year() - base.year()) * 12;
		if (base.clone().add(res.months, 'M').isAfter(other)) {
			--res.months;
		}

		res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

		return res;
	}

	function momentsDifference(base, other) {
		var res;
		other = makeAs(other, base);
		if (base.isBefore(other)) {
			res = positiveMomentsDifference(base, other);
		} else {
			res = positiveMomentsDifference(other, base);
			res.milliseconds = -res.milliseconds;
			res.months = -res.months;
		}

		return res;
	}

	// TODO: remove 'name' arg after deprecation is removed
	function createAdder(direction, name) {
		return function (val, period) {
			var dur, tmp;
			//invert the arguments, but complain about it
			if (period !== null && !isNaN(+period)) {
				deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
				tmp = val; val = period; period = tmp;
			}

			val = typeof val === 'string' ? +val : val;
			dur = moment.duration(val, period);
			addOrSubtractDurationFromMoment(this, dur, direction);
			return this;
		};
	}

	function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
		var milliseconds = duration._milliseconds,
            days = duration._days,
            months = duration._months;
		updateOffset = updateOffset == null ? true : updateOffset;

		if (milliseconds) {
			mom._d.setTime(+mom._d + milliseconds * isAdding);
		}
		if (days) {
			rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
		}
		if (months) {
			rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
		}
		if (updateOffset) {
			moment.updateOffset(mom, days || months);
		}
	}

	// check if is an array
	function isArray(input) {
		return Object.prototype.toString.call(input) === '[object Array]';
	}

	function isDate(input) {
		return Object.prototype.toString.call(input) === '[object Date]' ||
            input instanceof Date;
	}

	// compare two arrays, return the number of differences
	function compareArrays(array1, array2, dontConvert) {
		var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
		for (i = 0; i < len; i++) {
			if ((dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
				diffs++;
			}
		}
		return diffs + lengthDiff;
	}

	function normalizeUnits(units) {
		if (units) {
			var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
			units = unitAliases[units] || camelFunctions[lowered] || lowered;
		}
		return units;
	}

	function normalizeObjectUnits(inputObject) {
		var normalizedInput = {},
            normalizedProp,
            prop;

		for (prop in inputObject) {
			if (hasOwnProp(inputObject, prop)) {
				normalizedProp = normalizeUnits(prop);
				if (normalizedProp) {
					normalizedInput[normalizedProp] = inputObject[prop];
				}
			}
		}

		return normalizedInput;
	}

	function makeList(field) {
		var count, setter;

		if (field.indexOf('week') === 0) {
			count = 7;
			setter = 'day';
		}
		else if (field.indexOf('month') === 0) {
			count = 12;
			setter = 'month';
		}
		else {
			return;
		}

		moment[field] = function (format, index) {
			var i, getter,
                method = moment._locale[field],
                results = [];

			if (typeof format === 'number') {
				index = format;
				format = undefined;
			}

			getter = function (i) {
				var m = moment().utc().set(setter, i);
				return method.call(moment._locale, m, format || '');
			};

			if (index != null) {
				return getter(index);
			}
			else {
				for (i = 0; i < count; i++) {
					results.push(getter(i));
				}
				return results;
			}
		};
	}

	function toInt(argumentForCoercion) {
		var coercedNumber = +argumentForCoercion,
            value = 0;

		if (coercedNumber !== 0 && isFinite(coercedNumber)) {
			if (coercedNumber >= 0) {
				value = Math.floor(coercedNumber);
			} else {
				value = Math.ceil(coercedNumber);
			}
		}

		return value;
	}

	function daysInMonth(year, month) {
		return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
	}

	function weeksInYear(year, dow, doy) {
		return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
	}

	function daysInYear(year) {
		return isLeapYear(year) ? 366 : 365;
	}

	function isLeapYear(year) {
		return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
	}

	function checkOverflow(m) {
		var overflow;
		if (m._a && m._pf.overflow === -2) {
			overflow =
                m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
                m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
                m._a[HOUR] < 0 || m._a[HOUR] > 24 ||
                    (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||
                                           m._a[SECOND] !== 0 ||
                                           m._a[MILLISECOND] !== 0)) ? HOUR :
                m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
                m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
                m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
                -1;

			if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
				overflow = DATE;
			}

			m._pf.overflow = overflow;
		}
	}

	function isValid(m) {
		if (m._isValid == null) {
			m._isValid = !isNaN(m._d.getTime()) &&
                m._pf.overflow < 0 &&
                !m._pf.empty &&
                !m._pf.invalidMonth &&
                !m._pf.nullInput &&
                !m._pf.invalidFormat &&
                !m._pf.userInvalidated;

			if (m._strict) {
				m._isValid = m._isValid &&
                    m._pf.charsLeftOver === 0 &&
                    m._pf.unusedTokens.length === 0 &&
                    m._pf.bigHour === undefined;
			}
		}
		return m._isValid;
	}

	function normalizeLocale(key) {
		return key ? key.toLowerCase().replace('_', '-') : key;
	}

	// pick the locale from the array
	// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
	// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
	function chooseLocale(names) {
		var i = 0, j, next, locale, split;

		while (i < names.length) {
			split = normalizeLocale(names[i]).split('-');
			j = split.length;
			next = normalizeLocale(names[i + 1]);
			next = next ? next.split('-') : null;
			while (j > 0) {
				locale = loadLocale(split.slice(0, j).join('-'));
				if (locale) {
					return locale;
				}
				if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
					//the next array item is better than a shallower substring of this one
					break;
				}
				j--;
			}
			i++;
		}
		return null;
	}

	function loadLocale(name) {
		var oldLocale = null;
		if (!locales[name] && hasModule) {
			try {
				oldLocale = moment.locale();
				require('./locale/' + name);
				// because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
				moment.locale(oldLocale);
			} catch (e) { }
		}
		return locales[name];
	}

	// Return a moment from input, that is local/utc/utcOffset equivalent to
	// model.
	function makeAs(input, model) {
		var res, diff;
		if (model._isUTC) {
			res = model.clone();
			diff = (moment.isMoment(input) || isDate(input) ?
                    +input : +moment(input)) - (+res);
			// Use low-level api, because this fn is low-level api.
			res._d.setTime(+res._d + diff);
			moment.updateOffset(res, false);
			return res;
		} else {
			return moment(input).local();
		}
	}

	/************************************
        Locale
    ************************************/


	extend(Locale.prototype, {

		set: function (config) {
			var prop, i;
			for (i in config) {
				prop = config[i];
				if (typeof prop === 'function') {
					this[i] = prop;
				} else {
					this['_' + i] = prop;
				}
			}
			// Lenient ordinal parsing accepts just a number in addition to
			// number + (possibly) stuff coming from _ordinalParseLenient.
			this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source);
		},

		_months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
		months: function (m) {
			return this._months[m.month()];
		},

		_monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
		monthsShort: function (m) {
			return this._monthsShort[m.month()];
		},

		monthsParse: function (monthName, format, strict) {
			var i, mom, regex;

			if (!this._monthsParse) {
				this._monthsParse = [];
				this._longMonthsParse = [];
				this._shortMonthsParse = [];
			}

			for (i = 0; i < 12; i++) {
				// make the regex if we don't have it already
				mom = moment.utc([2000, i]);
				if (strict && !this._longMonthsParse[i]) {
					this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
					this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
				}
				if (!strict && !this._monthsParse[i]) {
					regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
					this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
				}
				// test the regex
				if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
					return i;
				} else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
					return i;
				} else if (!strict && this._monthsParse[i].test(monthName)) {
					return i;
				}
			}
		},

		_weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
		weekdays: function (m) {
			return this._weekdays[m.day()];
		},

		_weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
		weekdaysShort: function (m) {
			return this._weekdaysShort[m.day()];
		},

		_weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
		weekdaysMin: function (m) {
			return this._weekdaysMin[m.day()];
		},

		weekdaysParse: function (weekdayName) {
			var i, mom, regex;

			if (!this._weekdaysParse) {
				this._weekdaysParse = [];
			}

			for (i = 0; i < 7; i++) {
				// make the regex if we don't have it already
				if (!this._weekdaysParse[i]) {
					mom = moment([2000, 1]).day(i);
					regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
					this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
				}
				// test the regex
				if (this._weekdaysParse[i].test(weekdayName)) {
					return i;
				}
			}
		},

		_longDateFormat: {
			LTS: 'h:mm:ss A',
			LT: 'h:mm A',
			L: 'MM/DD/YYYY',
			LL: 'MMMM D, YYYY',
			LLL: 'MMMM D, YYYY LT',
			LLLL: 'dddd, MMMM D, YYYY LT'
		},
		longDateFormat: function (key) {
			var output = this._longDateFormat[key];
			if (!output && this._longDateFormat[key.toUpperCase()]) {
				output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
					return val.slice(1);
				});
				this._longDateFormat[key] = output;
			}
			return output;
		},

		isPM: function (input) {
			// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
			// Using charAt should be more compatible.
			return ((input + '').toLowerCase().charAt(0) === 'p');
		},

		_meridiemParse: /[ap]\.?m?\.?/i,
		meridiem: function (hours, minutes, isLower) {
			if (hours > 11) {
				return isLower ? 'pm' : 'PM';
			} else {
				return isLower ? 'am' : 'AM';
			}
		},


		_calendar: {
			sameDay: '[Today at] LT',
			nextDay: '[Tomorrow at] LT',
			nextWeek: 'dddd [at] LT',
			lastDay: '[Yesterday at] LT',
			lastWeek: '[Last] dddd [at] LT',
			sameElse: 'L'
		},
		calendar: function (key, mom, now) {
			var output = this._calendar[key];
			return typeof output === 'function' ? output.apply(mom, [now]) : output;
		},

		_relativeTime: {
			future: 'in %s',
			past: '%s ago',
			s: 'a few seconds',
			m: 'a minute',
			mm: '%d minutes',
			h: 'an hour',
			hh: '%d hours',
			d: 'a day',
			dd: '%d days',
			M: 'a month',
			MM: '%d months',
			y: 'a year',
			yy: '%d years'
		},

		relativeTime: function (number, withoutSuffix, string, isFuture) {
			var output = this._relativeTime[string];
			return (typeof output === 'function') ?
                output(number, withoutSuffix, string, isFuture) :
                output.replace(/%d/i, number);
		},

		pastFuture: function (diff, output) {
			var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
			return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
		},

		ordinal: function (number) {
			return this._ordinal.replace('%d', number);
		},
		_ordinal: '%d',
		_ordinalParse: /\d{1,2}/,

		preparse: function (string) {
			return string;
		},

		postformat: function (string) {
			return string;
		},

		week: function (mom) {
			return weekOfYear(mom, this._week.dow, this._week.doy).week;
		},

		_week: {
			dow: 0, // Sunday is the first day of the week.
			doy: 6  // The week that contains Jan 1st is the first week of the year.
		},

		firstDayOfWeek: function () {
			return this._week.dow;
		},

		firstDayOfYear: function () {
			return this._week.doy;
		},

		_invalidDate: 'Invalid date',
		invalidDate: function () {
			return this._invalidDate;
		}
	});

	/************************************
        Formatting
    ************************************/


	function removeFormattingTokens(input) {
		if (input.match(/\[[\s\S]/)) {
			return input.replace(/^\[|\]$/g, '');
		}
		return input.replace(/\\/g, '');
	}

	function makeFormatFunction(format) {
		var array = format.match(formattingTokens), i, length;

		for (i = 0, length = array.length; i < length; i++) {
			if (formatTokenFunctions[array[i]]) {
				array[i] = formatTokenFunctions[array[i]];
			} else {
				array[i] = removeFormattingTokens(array[i]);
			}
		}

		return function (mom) {
			var output = '';
			for (i = 0; i < length; i++) {
				output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
			}
			return output;
		};
	}

	// format date using native date object
	function formatMoment(m, format) {
		if (!m.isValid()) {
			return m.localeData().invalidDate();
		}

		format = expandFormat(format, m.localeData());

		if (!formatFunctions[format]) {
			formatFunctions[format] = makeFormatFunction(format);
		}

		return formatFunctions[format](m);
	}

	function expandFormat(format, locale) {
		var i = 5;

		function replaceLongDateFormatTokens(input) {
			return locale.longDateFormat(input) || input;
		}

		localFormattingTokens.lastIndex = 0;
		while (i >= 0 && localFormattingTokens.test(format)) {
			format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
			localFormattingTokens.lastIndex = 0;
			i -= 1;
		}

		return format;
	}


	/************************************
        Parsing
    ************************************/


	// get the regex to find the next token
	function getParseRegexForToken(token, config) {
		var a, strict = config._strict;
		switch (token) {
			case 'Q':
				return parseTokenOneDigit;
			case 'DDDD':
				return parseTokenThreeDigits;
			case 'YYYY':
			case 'GGGG':
			case 'gggg':
				return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
			case 'Y':
			case 'G':
			case 'g':
				return parseTokenSignedNumber;
			case 'YYYYYY':
			case 'YYYYY':
			case 'GGGGG':
			case 'ggggg':
				return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
			case 'S':
				if (strict) {
					return parseTokenOneDigit;
				}
				/* falls through */
			case 'SS':
				if (strict) {
					return parseTokenTwoDigits;
				}
				/* falls through */
			case 'SSS':
				if (strict) {
					return parseTokenThreeDigits;
				}
				/* falls through */
			case 'DDD':
				return parseTokenOneToThreeDigits;
			case 'MMM':
			case 'MMMM':
			case 'dd':
			case 'ddd':
			case 'dddd':
				return parseTokenWord;
			case 'a':
			case 'A':
				return config._locale._meridiemParse;
			case 'x':
				return parseTokenOffsetMs;
			case 'X':
				return parseTokenTimestampMs;
			case 'Z':
			case 'ZZ':
				return parseTokenTimezone;
			case 'T':
				return parseTokenT;
			case 'SSSS':
				return parseTokenDigits;
			case 'MM':
			case 'DD':
			case 'YY':
			case 'GG':
			case 'gg':
			case 'HH':
			case 'hh':
			case 'mm':
			case 'ss':
			case 'ww':
			case 'WW':
				return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
			case 'M':
			case 'D':
			case 'd':
			case 'H':
			case 'h':
			case 'm':
			case 's':
			case 'w':
			case 'W':
			case 'e':
			case 'E':
				return parseTokenOneOrTwoDigits;
			case 'Do':
				return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;
			default:
				a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
				return a;
		}
	}

	function utcOffsetFromString(string) {
		string = string || '';
		var possibleTzMatches = (string.match(parseTokenTimezone) || []),
            tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
            parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
            minutes = +(parts[1] * 60) + toInt(parts[2]);

		return parts[0] === '+' ? minutes : -minutes;
	}

	// function to convert string input to date
	function addTimeToArrayFromToken(token, input, config) {
		var a, datePartArray = config._a;

		switch (token) {
			// QUARTER
			case 'Q':
				if (input != null) {
					datePartArray[MONTH] = (toInt(input) - 1) * 3;
				}
				break;
				// MONTH
			case 'M': // fall through to MM
			case 'MM':
				if (input != null) {
					datePartArray[MONTH] = toInt(input) - 1;
				}
				break;
			case 'MMM': // fall through to MMMM
			case 'MMMM':
				a = config._locale.monthsParse(input, token, config._strict);
				// if we didn't find a month name, mark the date as invalid.
				if (a != null) {
					datePartArray[MONTH] = a;
				} else {
					config._pf.invalidMonth = input;
				}
				break;
				// DAY OF MONTH
			case 'D': // fall through to DD
			case 'DD':
				if (input != null) {
					datePartArray[DATE] = toInt(input);
				}
				break;
			case 'Do':
				if (input != null) {
					datePartArray[DATE] = toInt(parseInt(
								input.match(/\d{1,2}/)[0], 10));
				}
				break;
				// DAY OF YEAR
			case 'DDD': // fall through to DDDD
			case 'DDDD':
				if (input != null) {
					config._dayOfYear = toInt(input);
				}

				break;
				// YEAR
			case 'YY':
				datePartArray[YEAR] = moment.parseTwoDigitYear(input);
				break;
			case 'YYYY':
			case 'YYYYY':
			case 'YYYYYY':
				datePartArray[YEAR] = toInt(input);
				break;
				// AM / PM
			case 'a': // fall through to A
			case 'A':
				config._meridiem = input;
				// config._isPm = config._locale.isPM(input);
				break;
				// HOUR
			case 'h': // fall through to hh
			case 'hh':
				config._pf.bigHour = true;
				/* falls through */
			case 'H': // fall through to HH
			case 'HH':
				datePartArray[HOUR] = toInt(input);
				break;
				// MINUTE
			case 'm': // fall through to mm
			case 'mm':
				datePartArray[MINUTE] = toInt(input);
				break;
				// SECOND
			case 's': // fall through to ss
			case 'ss':
				datePartArray[SECOND] = toInt(input);
				break;
				// MILLISECOND
			case 'S':
			case 'SS':
			case 'SSS':
			case 'SSSS':
				datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
				break;
				// UNIX OFFSET (MILLISECONDS)
			case 'x':
				config._d = new Date(toInt(input));
				break;
				// UNIX TIMESTAMP WITH MS
			case 'X':
				config._d = new Date(parseFloat(input) * 1000);
				break;
				// TIMEZONE
			case 'Z': // fall through to ZZ
			case 'ZZ':
				config._useUTC = true;
				config._tzm = utcOffsetFromString(input);
				break;
				// WEEKDAY - human
			case 'dd':
			case 'ddd':
			case 'dddd':
				a = config._locale.weekdaysParse(input);
				// if we didn't get a weekday name, mark the date as invalid
				if (a != null) {
					config._w = config._w || {};
					config._w['d'] = a;
				} else {
					config._pf.invalidWeekday = input;
				}
				break;
				// WEEK, WEEK DAY - numeric
			case 'w':
			case 'ww':
			case 'W':
			case 'WW':
			case 'd':
			case 'e':
			case 'E':
				token = token.substr(0, 1);
				/* falls through */
			case 'gggg':
			case 'GGGG':
			case 'GGGGG':
				token = token.substr(0, 2);
				if (input) {
					config._w = config._w || {};
					config._w[token] = toInt(input);
				}
				break;
			case 'gg':
			case 'GG':
				config._w = config._w || {};
				config._w[token] = moment.parseTwoDigitYear(input);
		}
	}

	function dayOfYearFromWeekInfo(config) {
		var w, weekYear, week, weekday, dow, doy, temp;

		w = config._w;
		if (w.GG != null || w.W != null || w.E != null) {
			dow = 1;
			doy = 4;

			// TODO: We need to take the current isoWeekYear, but that depends on
			// how we interpret now (local, utc, fixed offset). So create
			// a now version of current config (take local/utc/offset flags, and
			// create now).
			weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
			week = dfl(w.W, 1);
			weekday = dfl(w.E, 1);
		} else {
			dow = config._locale._week.dow;
			doy = config._locale._week.doy;

			weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
			week = dfl(w.w, 1);

			if (w.d != null) {
				// weekday -- low day numbers are considered next week
				weekday = w.d;
				if (weekday < dow) {
					++week;
				}
			} else if (w.e != null) {
				// local weekday -- counting starts from begining of week
				weekday = w.e + dow;
			} else {
				// default to begining of week
				weekday = dow;
			}
		}
		temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);

		config._a[YEAR] = temp.year;
		config._dayOfYear = temp.dayOfYear;
	}

	// convert an array to a date.
	// the array should mirror the parameters below
	// note: all values past the year are optional and will default to the lowest possible value.
	// [year, month, day , hour, minute, second, millisecond]
	function dateFromConfig(config) {
		var i, date, input = [], currentDate, yearToUse;

		if (config._d) {
			return;
		}

		currentDate = currentDateArray(config);

		//compute day of the year from weeks and weekdays
		if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
			dayOfYearFromWeekInfo(config);
		}

		//if the day of the year is set, figure out what it is
		if (config._dayOfYear) {
			yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);

			if (config._dayOfYear > daysInYear(yearToUse)) {
				config._pf._overflowDayOfYear = true;
			}

			date = makeUTCDate(yearToUse, 0, config._dayOfYear);
			config._a[MONTH] = date.getUTCMonth();
			config._a[DATE] = date.getUTCDate();
		}

		// Default to current date.
		// * if no year, month, day of month are given, default to today
		// * if day of month is given, default month and year
		// * if month is given, default only year
		// * if year is given, don't default anything
		for (i = 0; i < 3 && config._a[i] == null; ++i) {
			config._a[i] = input[i] = currentDate[i];
		}

		// Zero out whatever was not defaulted, including time
		for (; i < 7; i++) {
			config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
		}

		// Check for 24:00:00.000
		if (config._a[HOUR] === 24 &&
                config._a[MINUTE] === 0 &&
                config._a[SECOND] === 0 &&
                config._a[MILLISECOND] === 0) {
			config._nextDay = true;
			config._a[HOUR] = 0;
		}

		config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
		// Apply timezone offset from input. The actual utcOffset can be changed
		// with parseZone.
		if (config._tzm != null) {
			config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
		}

		if (config._nextDay) {
			config._a[HOUR] = 24;
		}
	}

	function dateFromObject(config) {
		var normalizedInput;

		if (config._d) {
			return;
		}

		normalizedInput = normalizeObjectUnits(config._i);
		config._a = [
            normalizedInput.year,
            normalizedInput.month,
            normalizedInput.day || normalizedInput.date,
            normalizedInput.hour,
            normalizedInput.minute,
            normalizedInput.second,
            normalizedInput.millisecond
		];

		dateFromConfig(config);
	}

	function currentDateArray(config) {
		var now = new Date();
		if (config._useUTC) {
			return [
                now.getUTCFullYear(),
                now.getUTCMonth(),
                now.getUTCDate()
			];
		} else {
			return [now.getFullYear(), now.getMonth(), now.getDate()];
		}
	}

	// date from string and format string
	function makeDateFromStringAndFormat(config) {
		if (config._f === moment.ISO_8601) {
			parseISO(config);
			return;
		}

		config._a = [];
		config._pf.empty = true;

		// This array is used to make a Date, either with `new Date` or `Date.UTC`
		var string = '' + config._i,
            i, parsedInput, tokens, token, skipped,
            stringLength = string.length,
            totalParsedInputLength = 0;

		tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

		for (i = 0; i < tokens.length; i++) {
			token = tokens[i];
			parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
			if (parsedInput) {
				skipped = string.substr(0, string.indexOf(parsedInput));
				if (skipped.length > 0) {
					config._pf.unusedInput.push(skipped);
				}
				string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
				totalParsedInputLength += parsedInput.length;
			}
			// don't parse if it's not a known token
			if (formatTokenFunctions[token]) {
				if (parsedInput) {
					config._pf.empty = false;
				}
				else {
					config._pf.unusedTokens.push(token);
				}
				addTimeToArrayFromToken(token, parsedInput, config);
			}
			else if (config._strict && !parsedInput) {
				config._pf.unusedTokens.push(token);
			}
		}

		// add remaining unparsed input length to the string
		config._pf.charsLeftOver = stringLength - totalParsedInputLength;
		if (string.length > 0) {
			config._pf.unusedInput.push(string);
		}

		// clear _12h flag if hour is <= 12
		if (config._pf.bigHour === true && config._a[HOUR] <= 12) {
			config._pf.bigHour = undefined;
		}
		// handle meridiem
		config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],
                config._meridiem);
		dateFromConfig(config);
		checkOverflow(config);
	}

	function unescapeFormat(s) {
		return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
			return p1 || p2 || p3 || p4;
		});
	}

	// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
	function regexpEscape(s) {
		return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
	}

	// date from string and array of format strings
	function makeDateFromStringAndArray(config) {
		var tempConfig,
            bestMoment,

            scoreToBeat,
            i,
            currentScore;

		if (config._f.length === 0) {
			config._pf.invalidFormat = true;
			config._d = new Date(NaN);
			return;
		}

		for (i = 0; i < config._f.length; i++) {
			currentScore = 0;
			tempConfig = copyConfig({}, config);
			if (config._useUTC != null) {
				tempConfig._useUTC = config._useUTC;
			}
			tempConfig._pf = defaultParsingFlags();
			tempConfig._f = config._f[i];
			makeDateFromStringAndFormat(tempConfig);

			if (!isValid(tempConfig)) {
				continue;
			}

			// if there is any input that was not parsed add a penalty for that format
			currentScore += tempConfig._pf.charsLeftOver;

			//or tokens
			currentScore += tempConfig._pf.unusedTokens.length * 10;

			tempConfig._pf.score = currentScore;

			if (scoreToBeat == null || currentScore < scoreToBeat) {
				scoreToBeat = currentScore;
				bestMoment = tempConfig;
			}
		}

		extend(config, bestMoment || tempConfig);
	}

	// date from iso format
	function parseISO(config) {
		var i, l,
            string = config._i,
            match = isoRegex.exec(string);

		if (match) {
			config._pf.iso = true;
			for (i = 0, l = isoDates.length; i < l; i++) {
				if (isoDates[i][1].exec(string)) {
					// match[5] should be 'T' or undefined
					config._f = isoDates[i][0] + (match[6] || ' ');
					break;
				}
			}
			for (i = 0, l = isoTimes.length; i < l; i++) {
				if (isoTimes[i][1].exec(string)) {
					config._f += isoTimes[i][0];
					break;
				}
			}
			if (string.match(parseTokenTimezone)) {
				config._f += 'Z';
			}
			makeDateFromStringAndFormat(config);
		} else {
			config._isValid = false;
		}
	}

	// date from iso format or fallback
	function makeDateFromString(config) {
		parseISO(config);
		if (config._isValid === false) {
			delete config._isValid;
			moment.createFromInputFallback(config);
		}
	}

	function map(arr, fn) {
		var res = [], i;
		for (i = 0; i < arr.length; ++i) {
			res.push(fn(arr[i], i));
		}
		return res;
	}

	function makeDateFromInput(config) {
		var input = config._i, matched;
		if (input === undefined) {
			config._d = new Date();
		} else if (isDate(input)) {
			config._d = new Date(+input);
		} else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
			config._d = new Date(+matched[1]);
		} else if (typeof input === 'string') {
			makeDateFromString(config);
		} else if (isArray(input)) {
			config._a = map(input.slice(0), function (obj) {
				return parseInt(obj, 10);
			});
			dateFromConfig(config);
		} else if (typeof (input) === 'object') {
			dateFromObject(config);
		} else if (typeof (input) === 'number') {
			// from milliseconds
			config._d = new Date(input);
		} else {
			moment.createFromInputFallback(config);
		}
	}

	function makeDate(y, m, d, h, M, s, ms) {
		//can't just apply() to create a date:
		//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
		var date = new Date(y, m, d, h, M, s, ms);

		//the date constructor doesn't accept years < 1970
		if (y < 1970) {
			date.setFullYear(y);
		}
		return date;
	}

	function makeUTCDate(y) {
		var date = new Date(Date.UTC.apply(null, arguments));
		if (y < 1970) {
			date.setUTCFullYear(y);
		}
		return date;
	}

	function parseWeekday(input, locale) {
		if (typeof input === 'string') {
			if (!isNaN(input)) {
				input = parseInt(input, 10);
			}
			else {
				input = locale.weekdaysParse(input);
				if (typeof input !== 'number') {
					return null;
				}
			}
		}
		return input;
	}

	/************************************
        Relative Time
    ************************************/


	// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
	function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
		return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
	}

	function relativeTime(posNegDuration, withoutSuffix, locale) {
		var duration = moment.duration(posNegDuration).abs(),
            seconds = round(duration.as('s')),
            minutes = round(duration.as('m')),
            hours = round(duration.as('h')),
            days = round(duration.as('d')),
            months = round(duration.as('M')),
            years = round(duration.as('y')),

            args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
                minutes === 1 && ['m'] ||
                minutes < relativeTimeThresholds.m && ['mm', minutes] ||
                hours === 1 && ['h'] ||
                hours < relativeTimeThresholds.h && ['hh', hours] ||
                days === 1 && ['d'] ||
                days < relativeTimeThresholds.d && ['dd', days] ||
                months === 1 && ['M'] ||
                months < relativeTimeThresholds.M && ['MM', months] ||
                years === 1 && ['y'] || ['yy', years];

		args[2] = withoutSuffix;
		args[3] = +posNegDuration > 0;
		args[4] = locale;
		return substituteTimeAgo.apply({}, args);
	}


	/************************************
        Week of Year
    ************************************/


	// firstDayOfWeek       0 = sun, 6 = sat
	//                      the day of the week that starts the week
	//                      (usually sunday or monday)
	// firstDayOfWeekOfYear 0 = sun, 6 = sat
	//                      the first week is the week that contains the first
	//                      of this day of the week
	//                      (eg. ISO weeks use thursday (4))
	function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
		var end = firstDayOfWeekOfYear - firstDayOfWeek,
            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
            adjustedMoment;


		if (daysToDayOfWeek > end) {
			daysToDayOfWeek -= 7;
		}

		if (daysToDayOfWeek < end - 7) {
			daysToDayOfWeek += 7;
		}

		adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
		return {
			week: Math.ceil(adjustedMoment.dayOfYear() / 7),
			year: adjustedMoment.year()
		};
	}

	//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
	function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
		var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;

		d = d === 0 ? 7 : d;
		weekday = weekday != null ? weekday : firstDayOfWeek;
		daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
		dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;

		return {
			year: dayOfYear > 0 ? year : year - 1,
			dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
		};
	}

	/************************************
        Top Level Functions
    ************************************/

	function makeMoment(config) {
		var input = config._i,
            format = config._f,
            res;

		config._locale = config._locale || moment.localeData(config._l);

		if (input === null || (format === undefined && input === '')) {
			return moment.invalid({ nullInput: true });
		}

		if (typeof input === 'string') {
			config._i = input = config._locale.preparse(input);
		}

		if (moment.isMoment(input)) {
			return new Moment(input, true);
		} else if (format) {
			if (isArray(format)) {
				makeDateFromStringAndArray(config);
			} else {
				makeDateFromStringAndFormat(config);
			}
		} else {
			makeDateFromInput(config);
		}

		res = new Moment(config);
		if (res._nextDay) {
			// Adding is smart enough around DST
			res.add(1, 'd');
			res._nextDay = undefined;
		}

		return res;
	}

	moment = function (input, format, locale, strict) {
		var c;

		if (typeof (locale) === 'boolean') {
			strict = locale;
			locale = undefined;
		}
		// object construction must be done this way.
		// https://github.com/moment/moment/issues/1423
		c = {};
		c._isAMomentObject = true;
		c._i = input;
		c._f = format;
		c._l = locale;
		c._strict = strict;
		c._isUTC = false;
		c._pf = defaultParsingFlags();

		return makeMoment(c);
	};

	moment.suppressDeprecationWarnings = false;

	moment.createFromInputFallback = deprecate(
        'moment construction falls back to js Date. This is ' +
        'discouraged and will be removed in upcoming major ' +
        'release. Please refer to ' +
        'https://github.com/moment/moment/issues/1407 for more info.',
        function (config) {
        	config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

	// Pick a moment m from moments so that m[fn](other) is true for all
	// other. This relies on the function fn to be transitive.
	//
	// moments should either be an array of moment objects or an array, whose
	// first element is an array of moment objects.
	function pickBy(fn, moments) {
		var res, i;
		if (moments.length === 1 && isArray(moments[0])) {
			moments = moments[0];
		}
		if (!moments.length) {
			return moment();
		}
		res = moments[0];
		for (i = 1; i < moments.length; ++i) {
			if (moments[i][fn](res)) {
				res = moments[i];
			}
		}
		return res;
	}

	moment.min = function () {
		var args = [].slice.call(arguments, 0);

		return pickBy('isBefore', args);
	};

	moment.max = function () {
		var args = [].slice.call(arguments, 0);

		return pickBy('isAfter', args);
	};

	// creating with utc
	moment.utc = function (input, format, locale, strict) {
		var c;

		if (typeof (locale) === 'boolean') {
			strict = locale;
			locale = undefined;
		}
		// object construction must be done this way.
		// https://github.com/moment/moment/issues/1423
		c = {};
		c._isAMomentObject = true;
		c._useUTC = true;
		c._isUTC = true;
		c._l = locale;
		c._i = input;
		c._f = format;
		c._strict = strict;
		c._pf = defaultParsingFlags();

		return makeMoment(c).utc();
	};

	// creating with unix timestamp (in seconds)
	moment.unix = function (input) {
		return moment(input * 1000);
	};

	// duration
	moment.duration = function (input, key) {
		var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            parseIso,
            diffRes;

		if (moment.isDuration(input)) {
			duration = {
				ms: input._milliseconds,
				d: input._days,
				M: input._months
			};
		} else if (typeof input === 'number') {
			duration = {};
			if (key) {
				duration[key] = input;
			} else {
				duration.milliseconds = input;
			}
		} else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
			sign = (match[1] === '-') ? -1 : 1;
			duration = {
				y: 0,
				d: toInt(match[DATE]) * sign,
				h: toInt(match[HOUR]) * sign,
				m: toInt(match[MINUTE]) * sign,
				s: toInt(match[SECOND]) * sign,
				ms: toInt(match[MILLISECOND]) * sign
			};
		} else if (!!(match = isoDurationRegex.exec(input))) {
			sign = (match[1] === '-') ? -1 : 1;
			parseIso = function (inp) {
				// We'd normally use ~~inp for this, but unfortunately it also
				// converts floats to ints.
				// inp may be undefined, so careful calling replace on it.
				var res = inp && parseFloat(inp.replace(',', '.'));
				// apply sign while we're at it
				return (isNaN(res) ? 0 : res) * sign;
			};
			duration = {
				y: parseIso(match[2]),
				M: parseIso(match[3]),
				d: parseIso(match[4]),
				h: parseIso(match[5]),
				m: parseIso(match[6]),
				s: parseIso(match[7]),
				w: parseIso(match[8])
			};
		} else if (duration == null) {// checks for null or undefined
			duration = {};
		} else if (typeof duration === 'object' &&
                ('from' in duration || 'to' in duration)) {
			diffRes = momentsDifference(moment(duration.from), moment(duration.to));

			duration = {};
			duration.ms = diffRes.milliseconds;
			duration.M = diffRes.months;
		}

		ret = new Duration(duration);

		if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
			ret._locale = input._locale;
		}

		return ret;
	};

	// version number
	moment.version = VERSION;

	// default format
	moment.defaultFormat = isoFormat;

	// constant that refers to the ISO standard
	moment.ISO_8601 = function () { };

	// Plugins that add properties should also add the key here (null value),
	// so we can properly clone ourselves.
	moment.momentProperties = momentProperties;

	// This function will be called whenever a moment is mutated.
	// It is intended to keep the offset in sync with the timezone.
	moment.updateOffset = function () { };

	// This function allows you to set a threshold for relative time strings
	moment.relativeTimeThreshold = function (threshold, limit) {
		if (relativeTimeThresholds[threshold] === undefined) {
			return false;
		}
		if (limit === undefined) {
			return relativeTimeThresholds[threshold];
		}
		relativeTimeThresholds[threshold] = limit;
		return true;
	};

	moment.lang = deprecate(
        'moment.lang is deprecated. Use moment.locale instead.',
        function (key, value) {
        	return moment.locale(key, value);
        }
    );

	// This function will load locale and then set the global locale.  If
	// no arguments are passed in, it will simply return the current global
	// locale key.
	moment.locale = function (key, values) {
		var data;
		if (key) {
			if (typeof (values) !== 'undefined') {
				data = moment.defineLocale(key, values);
			}
			else {
				data = moment.localeData(key);
			}

			if (data) {
				moment.duration._locale = moment._locale = data;
			}
		}

		return moment._locale._abbr;
	};

	moment.defineLocale = function (name, values) {
		if (values !== null) {
			values.abbr = name;
			if (!locales[name]) {
				locales[name] = new Locale();
			}
			locales[name].set(values);

			// backwards compat for now: also set the locale
			moment.locale(name);

			return locales[name];
		} else {
			// useful for testing
			delete locales[name];
			return null;
		}
	};

	moment.langData = deprecate(
        'moment.langData is deprecated. Use moment.localeData instead.',
        function (key) {
        	return moment.localeData(key);
        }
    );

	// returns locale data
	moment.localeData = function (key) {
		var locale;

		if (key && key._locale && key._locale._abbr) {
			key = key._locale._abbr;
		}

		if (!key) {
			return moment._locale;
		}

		if (!isArray(key)) {
			//short-circuit everything else
			locale = loadLocale(key);
			if (locale) {
				return locale;
			}
			key = [key];
		}

		return chooseLocale(key);
	};

	// compare moment object
	moment.isMoment = function (obj) {
		return obj instanceof Moment ||
            (obj != null && hasOwnProp(obj, '_isAMomentObject'));
	};

	// for typechecking Duration objects
	moment.isDuration = function (obj) {
		return obj instanceof Duration;
	};

	for (i = lists.length - 1; i >= 0; --i) {
		makeList(lists[i]);
	}

	moment.normalizeUnits = function (units) {
		return normalizeUnits(units);
	};

	moment.invalid = function (flags) {
		var m = moment.utc(NaN);
		if (flags != null) {
			extend(m._pf, flags);
		}
		else {
			m._pf.userInvalidated = true;
		}

		return m;
	};

	moment.parseZone = function () {
		return moment.apply(null, arguments).parseZone();
	};

	moment.parseTwoDigitYear = function (input) {
		return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
	};

	moment.isDate = isDate;

	/************************************
        Moment Prototype
    ************************************/


	extend(moment.fn = Moment.prototype, {

		clone: function () {
			return moment(this);
		},

		valueOf: function () {
			return +this._d - ((this._offset || 0) * 60000);
		},

		unix: function () {
			return Math.floor(+this / 1000);
		},

		toString: function () {
			return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
		},

		toDate: function () {
			return this._offset ? new Date(+this) : this._d;
		},

		toISOString: function () {
			var m = moment(this).utc();
			if (0 < m.year() && m.year() <= 9999) {
				if ('function' === typeof Date.prototype.toISOString) {
					// native implementation is ~50x faster, use it when we can
					return this.toDate().toISOString();
				} else {
					return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
				}
			} else {
				return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
			}
		},

		toArray: function () {
			var m = this;
			return [
                m.year(),
                m.month(),
                m.date(),
                m.hours(),
                m.minutes(),
                m.seconds(),
                m.milliseconds()
			];
		},

		isValid: function () {
			return isValid(this);
		},

		isDSTShifted: function () {
			if (this._a) {
				return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
			}

			return false;
		},

		parsingFlags: function () {
			return extend({}, this._pf);
		},

		invalidAt: function () {
			return this._pf.overflow;
		},

		utc: function (keepLocalTime) {
			return this.utcOffset(0, keepLocalTime);
		},

		local: function (keepLocalTime) {
			if (this._isUTC) {
				this.utcOffset(0, keepLocalTime);
				this._isUTC = false;

				if (keepLocalTime) {
					this.subtract(this._dateUtcOffset(), 'm');
				}
			}
			return this;
		},

		format: function (inputString) {
			var output = formatMoment(this, inputString || moment.defaultFormat);
			return this.localeData().postformat(output);
		},

		add: createAdder(1, 'add'),

		subtract: createAdder(-1, 'subtract'),

		diff: function (input, units, asFloat) {
			var that = makeAs(input, this),
                zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,
                anchor, diff, output, daysAdjust;

			units = normalizeUnits(units);

			if (units === 'year' || units === 'month' || units === 'quarter') {
				output = monthDiff(this, that);
				if (units === 'quarter') {
					output = output / 3;
				} else if (units === 'year') {
					output = output / 12;
				}
			} else {
				diff = this - that;
				output = units === 'second' ? diff / 1e3 : // 1000
                    units === 'minute' ? diff / 6e4 : // 1000 * 60
                    units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
                    units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
                    units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
                    diff;
			}
			return asFloat ? output : absRound(output);
		},

		from: function (time, withoutSuffix) {
			return moment.duration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix);
		},

		fromNow: function (withoutSuffix) {
			return this.from(moment(), withoutSuffix);
		},

		calendar: function (time) {
			// We want to compare the start of today, vs this.
			// Getting start-of-today depends on whether we're locat/utc/offset
			// or not.
			var now = time || moment(),
                sod = makeAs(now, this).startOf('day'),
                diff = this.diff(sod, 'days', true),
                format = diff < -6 ? 'sameElse' :
                    diff < -1 ? 'lastWeek' :
                    diff < 0 ? 'lastDay' :
                    diff < 1 ? 'sameDay' :
                    diff < 2 ? 'nextDay' :
                    diff < 7 ? 'nextWeek' : 'sameElse';
			return this.format(this.localeData().calendar(format, this, moment(now)));
		},

		isLeapYear: function () {
			return isLeapYear(this.year());
		},

		isDST: function () {
			return (this.utcOffset() > this.clone().month(0).utcOffset() ||
                this.utcOffset() > this.clone().month(5).utcOffset());
		},

		day: function (input) {
			var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
			if (input != null) {
				input = parseWeekday(input, this.localeData());
				return this.add(input - day, 'd');
			} else {
				return day;
			}
		},

		month: makeAccessor('Month', true),

		startOf: function (units) {
			units = normalizeUnits(units);
			// the following switch intentionally omits break keywords
			// to utilize falling through the cases.
			switch (units) {
				case 'year':
					this.month(0);
					/* falls through */
				case 'quarter':
				case 'month':
					this.date(1);
					/* falls through */
				case 'week':
				case 'isoWeek':
				case 'day':
					this.hours(0);
					/* falls through */
				case 'hour':
					this.minutes(0);
					/* falls through */
				case 'minute':
					this.seconds(0);
					/* falls through */
				case 'second':
					this.milliseconds(0);
					/* falls through */
			}

			// weeks are a special case
			if (units === 'week') {
				this.weekday(0);
			} else if (units === 'isoWeek') {
				this.isoWeekday(1);
			}

			// quarters are also special
			if (units === 'quarter') {
				this.month(Math.floor(this.month() / 3) * 3);
			}

			return this;
		},

		endOf: function (units) {
			units = normalizeUnits(units);
			if (units === undefined || units === 'millisecond') {
				return this;
			}
			return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
		},

		isAfter: function (input, units) {
			var inputMs;
			units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
			if (units === 'millisecond') {
				input = moment.isMoment(input) ? input : moment(input);
				return +this > +input;
			} else {
				inputMs = moment.isMoment(input) ? +input : +moment(input);
				return inputMs < +this.clone().startOf(units);
			}
		},

		isBefore: function (input, units) {
			var inputMs;
			units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
			if (units === 'millisecond') {
				input = moment.isMoment(input) ? input : moment(input);
				return +this < +input;
			} else {
				inputMs = moment.isMoment(input) ? +input : +moment(input);
				return +this.clone().endOf(units) < inputMs;
			}
		},

		isBetween: function (from, to, units) {
			return this.isAfter(from, units) && this.isBefore(to, units);
		},

		isSame: function (input, units) {
			var inputMs;
			units = normalizeUnits(units || 'millisecond');
			if (units === 'millisecond') {
				input = moment.isMoment(input) ? input : moment(input);
				return +this === +input;
			} else {
				inputMs = +moment(input);
				return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
			}
		},

		min: deprecate(
                 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
                 function (other) {
                 	other = moment.apply(null, arguments);
                 	return other < this ? this : other;
                 }
         ),

		max: deprecate(
                'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
                function (other) {
                	other = moment.apply(null, arguments);
                	return other > this ? this : other;
                }
        ),

		zone: deprecate(
                'moment().zone is deprecated, use moment().utcOffset instead. ' +
                'https://github.com/moment/moment/issues/1779',
                function (input, keepLocalTime) {
                	if (input != null) {
                		if (typeof input !== 'string') {
                			input = -input;
                		}

                		this.utcOffset(input, keepLocalTime);

                		return this;
                	} else {
                		return -this.utcOffset();
                	}
                }
        ),

		// keepLocalTime = true means only change the timezone, without
		// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
		// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
		// +0200, so we adjust the time as needed, to be valid.
		//
		// Keeping the time actually adds/subtracts (one hour)
		// from the actual represented time. That is why we call updateOffset
		// a second time. In case it wants us to change the offset again
		// _changeInProgress == true case, then we have to adjust, because
		// there is no such time in the given timezone.
		utcOffset: function (input, keepLocalTime) {
			var offset = this._offset || 0,
                localAdjust;
			if (input != null) {
				if (typeof input === 'string') {
					input = utcOffsetFromString(input);
				}
				if (Math.abs(input) < 16) {
					input = input * 60;
				}
				if (!this._isUTC && keepLocalTime) {
					localAdjust = this._dateUtcOffset();
				}
				this._offset = input;
				this._isUTC = true;
				if (localAdjust != null) {
					this.add(localAdjust, 'm');
				}
				if (offset !== input) {
					if (!keepLocalTime || this._changeInProgress) {
						addOrSubtractDurationFromMoment(this,
                                moment.duration(input - offset, 'm'), 1, false);
					} else if (!this._changeInProgress) {
						this._changeInProgress = true;
						moment.updateOffset(this, true);
						this._changeInProgress = null;
					}
				}

				return this;
			} else {
				return this._isUTC ? offset : this._dateUtcOffset();
			}
		},

		isLocal: function () {
			return !this._isUTC;
		},

		isUtcOffset: function () {
			return this._isUTC;
		},

		isUtc: function () {
			return this._isUTC && this._offset === 0;
		},

		zoneAbbr: function () {
			return this._isUTC ? 'UTC' : '';
		},

		zoneName: function () {
			return this._isUTC ? 'Coordinated Universal Time' : '';
		},

		parseZone: function () {
			if (this._tzm) {
				this.utcOffset(this._tzm);
			} else if (typeof this._i === 'string') {
				this.utcOffset(utcOffsetFromString(this._i));
			}
			return this;
		},

		hasAlignedHourOffset: function (input) {
			if (!input) {
				input = 0;
			}
			else {
				input = moment(input).utcOffset();
			}

			return (this.utcOffset() - input) % 60 === 0;
		},

		daysInMonth: function () {
			return daysInMonth(this.year(), this.month());
		},

		dayOfYear: function (input) {
			var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
			return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
		},

		quarter: function (input) {
			return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
		},

		weekYear: function (input) {
			var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
			return input == null ? year : this.add((input - year), 'y');
		},

		isoWeekYear: function (input) {
			var year = weekOfYear(this, 1, 4).year;
			return input == null ? year : this.add((input - year), 'y');
		},

		week: function (input) {
			var week = this.localeData().week(this);
			return input == null ? week : this.add((input - week) * 7, 'd');
		},

		isoWeek: function (input) {
			var week = weekOfYear(this, 1, 4).week;
			return input == null ? week : this.add((input - week) * 7, 'd');
		},

		weekday: function (input) {
			var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
			return input == null ? weekday : this.add(input - weekday, 'd');
		},

		isoWeekday: function (input) {
			// behaves the same as moment#day except
			// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
			// as a setter, sunday should belong to the previous week.
			return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
		},

		isoWeeksInYear: function () {
			return weeksInYear(this.year(), 1, 4);
		},

		weeksInYear: function () {
			var weekInfo = this.localeData()._week;
			return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
		},

		get: function (units) {
			units = normalizeUnits(units);
			return this[units]();
		},

		set: function (units, value) {
			var unit;
			if (typeof units === 'object') {
				for (unit in units) {
					this.set(unit, units[unit]);
				}
			}
			else {
				units = normalizeUnits(units);
				if (typeof this[units] === 'function') {
					this[units](value);
				}
			}
			return this;
		},

		// If passed a locale key, it will set the locale for this
		// instance.  Otherwise, it will return the locale configuration
		// variables for this instance.
		locale: function (key) {
			var newLocaleData;

			if (key === undefined) {
				return this._locale._abbr;
			} else {
				newLocaleData = moment.localeData(key);
				if (newLocaleData != null) {
					this._locale = newLocaleData;
				}
				return this;
			}
		},

		lang: deprecate(
            'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
            function (key) {
            	if (key === undefined) {
            		return this.localeData();
            	} else {
            		return this.locale(key);
            	}
            }
        ),

		localeData: function () {
			return this._locale;
		},

		_dateUtcOffset: function () {
			// On Firefox.24 Date#getTimezoneOffset returns a floating point.
			// https://github.com/moment/moment/pull/1871
			return -Math.round(this._d.getTimezoneOffset() / 15) * 15;
		}

	});

	function rawMonthSetter(mom, value) {
		var dayOfMonth;

		// TODO: Move this out of here!
		if (typeof value === 'string') {
			value = mom.localeData().monthsParse(value);
			// TODO: Another silent failure?
			if (typeof value !== 'number') {
				return mom;
			}
		}

		dayOfMonth = Math.min(mom.date(),
                daysInMonth(mom.year(), value));
		mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
		return mom;
	}

	function rawGetter(mom, unit) {
		return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
	}

	function rawSetter(mom, unit, value) {
		if (unit === 'Month') {
			return rawMonthSetter(mom, value);
		} else {
			return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
		}
	}

	function makeAccessor(unit, keepTime) {
		return function (value) {
			if (value != null) {
				rawSetter(this, unit, value);
				moment.updateOffset(this, keepTime);
				return this;
			} else {
				return rawGetter(this, unit);
			}
		};
	}

	moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
	moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
	moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
	// Setting the hour should keep the time, because the user explicitly
	// specified which hour he wants. So trying to maintain the same hour (in
	// a new timezone) makes sense. Adding/subtracting hours does not follow
	// this rule.
	moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
	// moment.fn.month is defined separately
	moment.fn.date = makeAccessor('Date', true);
	moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
	moment.fn.year = makeAccessor('FullYear', true);
	moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));

	// add plural methods
	moment.fn.days = moment.fn.day;
	moment.fn.months = moment.fn.month;
	moment.fn.weeks = moment.fn.week;
	moment.fn.isoWeeks = moment.fn.isoWeek;
	moment.fn.quarters = moment.fn.quarter;

	// add aliased format methods
	moment.fn.toJSON = moment.fn.toISOString;

	// alias isUtc for dev-friendliness
	moment.fn.isUTC = moment.fn.isUtc;

	/************************************
        Duration Prototype
    ************************************/


	function daysToYears(days) {
		// 400 years have 146097 days (taking into account leap year rules)
		return days * 400 / 146097;
	}

	function yearsToDays(years) {
		// years * 365 + absRound(years / 4) -
		//     absRound(years / 100) + absRound(years / 400);
		return years * 146097 / 400;
	}

	extend(moment.duration.fn = Duration.prototype, {

		_bubble: function () {
			var milliseconds = this._milliseconds,
                days = this._days,
                months = this._months,
                data = this._data,
                seconds, minutes, hours, years = 0;

			// The following code bubbles up values, see the tests for
			// examples of what that means.
			data.milliseconds = milliseconds % 1000;

			seconds = absRound(milliseconds / 1000);
			data.seconds = seconds % 60;

			minutes = absRound(seconds / 60);
			data.minutes = minutes % 60;

			hours = absRound(minutes / 60);
			data.hours = hours % 24;

			days += absRound(hours / 24);

			// Accurately convert days to years, assume start from year 0.
			years = absRound(daysToYears(days));
			days -= absRound(yearsToDays(years));

			// 30 days to a month
			// TODO (iskren): Use anchor date (like 1st Jan) to compute this.
			months += absRound(days / 30);
			days %= 30;

			// 12 months -> 1 year
			years += absRound(months / 12);
			months %= 12;

			data.days = days;
			data.months = months;
			data.years = years;
		},

		abs: function () {
			this._milliseconds = Math.abs(this._milliseconds);
			this._days = Math.abs(this._days);
			this._months = Math.abs(this._months);

			this._data.milliseconds = Math.abs(this._data.milliseconds);
			this._data.seconds = Math.abs(this._data.seconds);
			this._data.minutes = Math.abs(this._data.minutes);
			this._data.hours = Math.abs(this._data.hours);
			this._data.months = Math.abs(this._data.months);
			this._data.years = Math.abs(this._data.years);

			return this;
		},

		weeks: function () {
			return absRound(this.days() / 7);
		},

		valueOf: function () {
			return this._milliseconds +
              this._days * 864e5 +
              (this._months % 12) * 2592e6 +
              toInt(this._months / 12) * 31536e6;
		},

		humanize: function (withSuffix) {
			var output = relativeTime(this, !withSuffix, this.localeData());

			if (withSuffix) {
				output = this.localeData().pastFuture(+this, output);
			}

			return this.localeData().postformat(output);
		},

		add: function (input, val) {
			// supports only 2.0-style add(1, 's') or add(moment)
			var dur = moment.duration(input, val);

			this._milliseconds += dur._milliseconds;
			this._days += dur._days;
			this._months += dur._months;

			this._bubble();

			return this;
		},

		subtract: function (input, val) {
			var dur = moment.duration(input, val);

			this._milliseconds -= dur._milliseconds;
			this._days -= dur._days;
			this._months -= dur._months;

			this._bubble();

			return this;
		},

		get: function (units) {
			units = normalizeUnits(units);
			return this[units.toLowerCase() + 's']();
		},

		as: function (units) {
			var days, months;
			units = normalizeUnits(units);

			if (units === 'month' || units === 'year') {
				days = this._days + this._milliseconds / 864e5;
				months = this._months + daysToYears(days) * 12;
				return units === 'month' ? months : months / 12;
			} else {
				// handle milliseconds separately because of floating point math errors (issue #1867)
				days = this._days + Math.round(yearsToDays(this._months / 12));
				switch (units) {
					case 'week': return days / 7 + this._milliseconds / 6048e5;
					case 'day': return days + this._milliseconds / 864e5;
					case 'hour': return days * 24 + this._milliseconds / 36e5;
					case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;
					case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;
						// Math.floor prevents floating point math errors here
					case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;
					default: throw new Error('Unknown unit ' + units);
				}
			}
		},

		lang: moment.fn.lang,
		locale: moment.fn.locale,

		toIsoString: deprecate(
            'toIsoString() is deprecated. Please use toISOString() instead ' +
            '(notice the capitals)',
            function () {
            	return this.toISOString();
            }
        ),

		toISOString: function () {
			// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
			var years = Math.abs(this.years()),
                months = Math.abs(this.months()),
                days = Math.abs(this.days()),
                hours = Math.abs(this.hours()),
                minutes = Math.abs(this.minutes()),
                seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);

			if (!this.asSeconds()) {
				// this is the same as C#'s (Noda) and python (isodate)...
				// but not other JS (goog.date)
				return 'P0D';
			}

			return (this.asSeconds() < 0 ? '-' : '') +
                'P' +
                (years ? years + 'Y' : '') +
                (months ? months + 'M' : '') +
                (days ? days + 'D' : '') +
                ((hours || minutes || seconds) ? 'T' : '') +
                (hours ? hours + 'H' : '') +
                (minutes ? minutes + 'M' : '') +
                (seconds ? seconds + 'S' : '');
		},

		localeData: function () {
			return this._locale;
		},

		toJSON: function () {
			return this.toISOString();
		}
	});

	moment.duration.fn.toString = moment.duration.fn.toISOString;

	function makeDurationGetter(name) {
		moment.duration.fn[name] = function () {
			return this._data[name];
		};
	}

	for (i in unitMillisecondFactors) {
		if (hasOwnProp(unitMillisecondFactors, i)) {
			makeDurationGetter(i.toLowerCase());
		}
	}

	moment.duration.fn.asMilliseconds = function () {
		return this.as('ms');
	};
	moment.duration.fn.asSeconds = function () {
		return this.as('s');
	};
	moment.duration.fn.asMinutes = function () {
		return this.as('m');
	};
	moment.duration.fn.asHours = function () {
		return this.as('h');
	};
	moment.duration.fn.asDays = function () {
		return this.as('d');
	};
	moment.duration.fn.asWeeks = function () {
		return this.as('weeks');
	};
	moment.duration.fn.asMonths = function () {
		return this.as('M');
	};
	moment.duration.fn.asYears = function () {
		return this.as('y');
	};

	/************************************
        Default Locale
    ************************************/


	// Set default locale, other locale will inherit from English.
	moment.locale('en', {
		ordinalParse: /\d{1,2}(th|st|nd|rd)/,
		ordinal: function (number) {
			var b = number % 10,
                output = (toInt(number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
			return number + output;
		}
	});

	/* EMBED_LOCALES */

	/************************************
        Exposing Moment
    ************************************/

	function makeGlobal(shouldDeprecate) {
		/*global ender:false */
		if (typeof ender !== 'undefined') {
			return;
		}
		oldGlobalMoment = globalScope.moment;
		if (shouldDeprecate) {
			globalScope.moment = deprecate(
                    'Accessing Moment through the global scope is ' +
                    'deprecated, and will be removed in an upcoming ' +
                    'release.',
                    moment);
		} else {
			globalScope.moment = moment;
		}
	}

	// CommonJS module is defined
	if (hasModule) {
		module.exports = moment;
	} else if (typeof define === 'function' && define.amd) {
		define(function (require, exports, module) {
			if (module.config && module.config() && module.config().noGlobal === true) {
				// release the global variable
				globalScope.moment = oldGlobalMoment;
			}

			return moment;
		});
		makeGlobal(true);
	} else {
		makeGlobal();
	}
}).call(this);;
/*!
 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2006, 2014 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD (Register as an anonymous module)
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		// Node/CommonJS
		module.exports = factory(require('jquery'));
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {

	var pluses = /\+/g;

	function encode(s) {
		return config.raw ? s : encodeURIComponent(s);
	}

	function decode(s) {
		return config.raw ? s : decodeURIComponent(s);
	}

	function stringifyCookieValue(value) {
		return encode(config.json ? JSON.stringify(value) : String(value));
	}

	function parseCookieValue(s) {
		if (s.indexOf('"') === 0) {
			// This is a quoted cookie as according to RFC2068, unescape...
			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
		}

		try {
			// Replace server-side written pluses with spaces.
			// If we can't decode the cookie, ignore it, it's unusable.
			// If we can't parse the cookie, ignore it, it's unusable.
			s = decodeURIComponent(s.replace(pluses, ' '));
			return config.json ? JSON.parse(s) : s;
		} catch (e) { }
	}

	function read(s, converter) {
		var value = config.raw ? s : parseCookieValue(s);
		return $.isFunction(converter) ? converter(value) : value;
	}

	var config = $.cookie = function (key, value, options) {

		// Write

		if (arguments.length > 1 && !$.isFunction(value)) {
			options = $.extend({}, config.defaults, options);

			if (typeof options.expires === 'number') {
				var days = options.expires, t = options.expires = new Date();
				t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
			}

			return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path ? '; path=' + options.path : '',
				options.domain ? '; domain=' + options.domain : '',
				options.secure ? '; secure' : ''
			].join(''));
		}

		// Read

		var result = key ? undefined : {},
			// To prevent the for loop in the first place assign an empty array
			// in case there are no cookies at all. Also prevents odd result when
			// calling $.cookie().
			cookies = document.cookie ? document.cookie.split('; ') : [],
			i = 0,
			l = cookies.length;

		for (; i < l; i++) {
			var parts = cookies[i].split('='),
				name = decode(parts.shift()),
				cookie = parts.join('=');

			if (key === name) {
				// If second argument (value) is a function it's a converter...
				result = read(cookie, value);
				break;
			}

			// Prevent storing a cookie that we couldn't decode.
			if (!key && (cookie = read(cookie)) !== undefined) {
				result[name] = cookie;
			}
		}

		return result;
	};

	config.defaults = {};

	$.removeCookie = function (key, options) {
		// Must not alter options, thus extending a fresh object...
		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
		return !$.cookie(key);
	};

}));;
/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

(function (root, factory) {
	if (typeof exports === "object" && exports) {
		factory(exports); // CommonJS
	} else {
		var mustache = {};
		factory(mustache);
		if (typeof define === "function" && define.amd) {
			define(mustache); // AMD
		} else {
			root.Mustache = mustache; // <script>
		}
	}
}(this, function (mustache) {

	var whiteRe = /\s*/;
	var spaceRe = /\s+/;
	var nonSpaceRe = /\S/;
	var eqRe = /\s*=/;
	var curlyRe = /\s*\}/;
	var tagRe = /#|\^|\/|>|\{|&|=|!/;

	// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
	// See https://github.com/janl/mustache.js/issues/189
	var RegExp_test = RegExp.prototype.test;
	function testRegExp(re, string) {
		return RegExp_test.call(re, string);
	}

	function isWhitespace(string) {
		return !testRegExp(nonSpaceRe, string);
	}

	var Object_toString = Object.prototype.toString;
	var isArray = Array.isArray || function (object) {
		return Object_toString.call(object) === '[object Array]';
	};

	function isFunction(object) {
		return typeof object === 'function';
	}

	function escapeRegExp(string) {
		return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
	}

	var entityMap = {
		"&": "&amp;",
		"<": "&lt;",
		">": "&gt;",
		'"': '&quot;',
		"'": '&#39;',
		"/": '&#x2F;'
	};

	function escapeHtml(string) {
		return String(string).replace(/[&<>"'\/]/g, function (s) {
			return entityMap[s];
		});
	}

	function escapeTags(tags) {
		if (!isArray(tags) || tags.length !== 2) {
			throw new Error('Invalid tags: ' + tags);
		}

		return [
		  new RegExp(escapeRegExp(tags[0]) + "\\s*"),
		  new RegExp("\\s*" + escapeRegExp(tags[1]))
		];
	}

	/**
	 * Breaks up the given `template` string into a tree of tokens. If the `tags`
	 * argument is given here it must be an array with two string values: the
	 * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
	 * course, the default is to use mustaches (i.e. mustache.tags).
	 *
	 * A token is an array with at least 4 elements. The first element is the
	 * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
	 * did not contain a symbol (i.e. {{myValue}}) this element is "name". For
	 * all template text that appears outside a symbol this element is "text".
	 *
	 * The second element of a token is its "value". For mustache tags this is
	 * whatever else was inside the tag besides the opening symbol. For text tokens
	 * this is the text itself.
	 *
	 * The third and fourth elements of the token are the start and end indices
	 * in the original template of the token, respectively.
	 *
	 * Tokens that are the root node of a subtree contain two more elements: an
	 * array of tokens in the subtree and the index in the original template at which
	 * the closing tag for that section begins.
	 */
	function parseTemplate(template, tags) {
		tags = tags || mustache.tags;
		template = template || '';

		if (typeof tags === 'string') {
			tags = tags.split(spaceRe);
		}

		var tagRes = escapeTags(tags);
		var scanner = new Scanner(template);

		var sections = [];     // Stack to hold section tokens
		var tokens = [];       // Buffer to hold the tokens
		var spaces = [];       // Indices of whitespace tokens on the current line
		var hasTag = false;    // Is there a {{tag}} on the current line?
		var nonSpace = false;  // Is there a non-space char on the current line?

		// Strips all whitespace tokens array for the current line
		// if there was a {{#tag}} on it and otherwise only space.
		function stripSpace() {
			if (hasTag && !nonSpace) {
				while (spaces.length) {
					delete tokens[spaces.pop()];
				}
			} else {
				spaces = [];
			}

			hasTag = false;
			nonSpace = false;
		}

		var start, type, value, chr, token, openSection;
		while (!scanner.eos()) {
			start = scanner.pos;

			// Match any text between tags.
			value = scanner.scanUntil(tagRes[0]);
			if (value) {
				for (var i = 0, len = value.length; i < len; ++i) {
					chr = value.charAt(i);

					if (isWhitespace(chr)) {
						spaces.push(tokens.length);
					} else {
						nonSpace = true;
					}

					tokens.push(['text', chr, start, start + 1]);
					start += 1;

					// Check for whitespace on the current line.
					if (chr === '\n') {
						stripSpace();
					}
				}
			}

			// Match the opening tag.
			if (!scanner.scan(tagRes[0])) break;
			hasTag = true;

			// Get the tag type.
			type = scanner.scan(tagRe) || 'name';
			scanner.scan(whiteRe);

			// Get the tag value.
			if (type === '=') {
				value = scanner.scanUntil(eqRe);
				scanner.scan(eqRe);
				scanner.scanUntil(tagRes[1]);
			} else if (type === '{') {
				value = scanner.scanUntil(new RegExp('\\s*' + escapeRegExp('}' + tags[1])));
				scanner.scan(curlyRe);
				scanner.scanUntil(tagRes[1]);
				type = '&';
			} else {
				value = scanner.scanUntil(tagRes[1]);
			}

			// Match the closing tag.
			if (!scanner.scan(tagRes[1])) {
				throw new Error('Unclosed tag at ' + scanner.pos);
			}

			token = [type, value, start, scanner.pos];
			tokens.push(token);

			if (type === '#' || type === '^') {
				sections.push(token);
			} else if (type === '/') {
				// Check section nesting.
				openSection = sections.pop();

				if (!openSection) {
					throw new Error('Unopened section "' + value + '" at ' + start);
				}
				if (openSection[1] !== value) {
					throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
				}
			} else if (type === 'name' || type === '{' || type === '&') {
				nonSpace = true;
			} else if (type === '=') {
				// Set the tags for the next time around.
				tagRes = escapeTags(tags = value.split(spaceRe));
			}
		}

		// Make sure there are no open sections when we're done.
		openSection = sections.pop();
		if (openSection) {
			throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
		}

		return nestTokens(squashTokens(tokens));
	}

	/**
	 * Combines the values of consecutive text tokens in the given `tokens` array
	 * to a single token.
	 */
	function squashTokens(tokens) {
		var squashedTokens = [];

		var token, lastToken;
		for (var i = 0, len = tokens.length; i < len; ++i) {
			token = tokens[i];

			if (token) {
				if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
					lastToken[1] += token[1];
					lastToken[3] = token[3];
				} else {
					squashedTokens.push(token);
					lastToken = token;
				}
			}
		}

		return squashedTokens;
	}

	/**
	 * Forms the given array of `tokens` into a nested tree structure where
	 * tokens that represent a section have two additional items: 1) an array of
	 * all tokens that appear in that section and 2) the index in the original
	 * template that represents the end of that section.
	 */
	function nestTokens(tokens) {
		var nestedTokens = [];
		var collector = nestedTokens;
		var sections = [];

		var token, section;
		for (var i = 0, len = tokens.length; i < len; ++i) {
			token = tokens[i];

			switch (token[0]) {
				case '#':
				case '^':
					collector.push(token);
					sections.push(token);
					collector = token[4] = [];
					break;
				case '/':
					section = sections.pop();
					section[5] = token[2];
					collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
					break;
				default:
					collector.push(token);
			}
		}

		return nestedTokens;
	}

	/**
	 * A simple string scanner that is used by the template parser to find
	 * tokens in template strings.
	 */
	function Scanner(string) {
		this.string = string;
		this.tail = string;
		this.pos = 0;
	}

	/**
	 * Returns `true` if the tail is empty (end of string).
	 */
	Scanner.prototype.eos = function () {
		return this.tail === "";
	};

	/**
	 * Tries to match the given regular expression at the current position.
	 * Returns the matched text if it can match, the empty string otherwise.
	 */
	Scanner.prototype.scan = function (re) {
		var match = this.tail.match(re);

		if (match && match.index === 0) {
			var string = match[0];
			this.tail = this.tail.substring(string.length);
			this.pos += string.length;
			return string;
		}

		return "";
	};

	/**
	 * Skips all text until the given regular expression can be matched. Returns
	 * the skipped string, which is the entire tail if no match can be made.
	 */
	Scanner.prototype.scanUntil = function (re) {
		var index = this.tail.search(re), match;

		switch (index) {
			case -1:
				match = this.tail;
				this.tail = "";
				break;
			case 0:
				match = "";
				break;
			default:
				match = this.tail.substring(0, index);
				this.tail = this.tail.substring(index);
		}

		this.pos += match.length;

		return match;
	};

	/**
	 * Represents a rendering context by wrapping a view object and
	 * maintaining a reference to the parent context.
	 */
	function Context(view, parentContext) {
		this.view = view == null ? {} : view;
		this.cache = { '.': this.view };
		this.parent = parentContext;
	}

	/**
	 * Creates a new context using the given view with this context
	 * as the parent.
	 */
	Context.prototype.push = function (view) {
		return new Context(view, this);
	};

	/**
	 * Returns the value of the given name in this context, traversing
	 * up the context hierarchy if the value is absent in this context's view.
	 */
	Context.prototype.lookup = function (name) {
		var value;
		if (name in this.cache) {
			value = this.cache[name];
		} else {
			var context = this;

			while (context) {
				if (name.indexOf('.') > 0) {
					value = context.view;

					var names = name.split('.'), i = 0;
					while (value != null && i < names.length) {
						value = value[names[i++]];
					}
				} else {
					value = context.view[name];
				}

				if (value != null) break;

				context = context.parent;
			}

			this.cache[name] = value;
		}

		if (isFunction(value)) {
			value = value.call(this.view);
		}

		return value;
	};

	/**
	 * A Writer knows how to take a stream of tokens and render them to a
	 * string, given a context. It also maintains a cache of templates to
	 * avoid the need to parse the same template twice.
	 */
	function Writer() {
		this.cache = {};
	}

	/**
	 * Clears all cached templates in this writer.
	 */
	Writer.prototype.clearCache = function () {
		this.cache = {};
	};

	/**
	 * Parses and caches the given `template` and returns the array of tokens
	 * that is generated from the parse.
	 */
	Writer.prototype.parse = function (template, tags) {
		if (!(template in this.cache)) {
			this.cache[template] = parseTemplate(template, tags);
		}

		return this.cache[template];
	};

	/**
	 * High-level method that is used to render the given `template` with
	 * the given `view`.
	 *
	 * The optional `partials` argument may be an object that contains the
	 * names and templates of partials that are used in the template. It may
	 * also be a function that is used to load partial templates on the fly
	 * that takes a single argument: the name of the partial.
	 */
	Writer.prototype.render = function (template, view, partials) {
		var tokens = this.parse(template);
		var context = (view instanceof Context) ? view : new Context(view);
		return this.renderTokens(tokens, context, partials, template);
	};

	/**
	 * Low-level method that renders the given array of `tokens` using
	 * the given `context` and `partials`.
	 *
	 * Note: The `originalTemplate` is only ever used to extract the portion
	 * of the original template that was contained in a higher-order section.
	 * If the template doesn't use higher-order sections, this argument may
	 * be omitted.
	 */
	Writer.prototype.renderTokens = function (tokens, context, partials, originalTemplate) {
		var buffer = '';

		// This function is used to render an arbitrary template
		// in the current context by higher-order sections.
		var self = this;
		function subRender(template) {
			return self.render(template, context, partials);
		}

		var token, value;
		for (var i = 0, len = tokens.length; i < len; ++i) {
			token = tokens[i];

			switch (token[0]) {
				case '#':
					value = context.lookup(token[1]);
					if (!value) continue;

					if (isArray(value)) {
						for (var j = 0, jlen = value.length; j < jlen; ++j) {
							buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
						}
					} else if (typeof value === 'object' || typeof value === 'string') {
						buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
					} else if (isFunction(value)) {
						if (typeof originalTemplate !== 'string') {
							throw new Error('Cannot use higher-order sections without the original template');
						}

						// Extract the portion of the original template that the section contains.
						value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);

						if (value != null) buffer += value;
					} else {
						buffer += this.renderTokens(token[4], context, partials, originalTemplate);
					}

					break;
				case '^':
					value = context.lookup(token[1]);

					// Use JavaScript's definition of falsy. Include empty arrays.
					// See https://github.com/janl/mustache.js/issues/186
					if (!value || (isArray(value) && value.length === 0)) {
						buffer += this.renderTokens(token[4], context, partials, originalTemplate);
					}

					break;
				case '>':
					if (!partials) continue;
					value = this.parse(isFunction(partials) ? partials(token[1]) : partials[token[1]]);
					if (value != null) buffer += this.renderTokens(value, context, partials, originalTemplate);
					break;
				case '&':
					value = context.lookup(token[1]);
					if (value != null) buffer += value;
					break;
				case 'name':
					value = context.lookup(token[1]);
					if (value != null) buffer += mustache.escape(value);
					break;
				case 'text':
					buffer += token[1];
					break;
			}
		}

		return buffer;
	};

	mustache.name = "mustache.js";
	mustache.version = "0.8.0";
	mustache.tags = ["{{", "}}"];

	// All high-level mustache.* functions use this writer.
	var defaultWriter = new Writer();

	/**
	 * Clears all cached templates in the default writer.
	 */
	mustache.clearCache = function () {
		return defaultWriter.clearCache();
	};

	/**
	 * Parses and caches the given template in the default writer and returns the
	 * array of tokens it contains. Doing this ahead of time avoids the need to
	 * parse templates on the fly as they are rendered.
	 */
	mustache.parse = function (template, tags) {
		return defaultWriter.parse(template, tags);
	};

	/**
	 * Renders the `template` with the given `view` and `partials` using the
	 * default writer.
	 */
	mustache.render = function (template, view, partials) {
		return defaultWriter.render(template, view, partials);
	};

	// This is here for backwards compatibility with 0.4.x.
	mustache.to_html = function (template, view, partials, send) {
		var result = mustache.render(template, view, partials);

		if (isFunction(send)) {
			send(result);
		} else {
			return result;
		}
	};

	// Export the escaping function so that the user may override it.
	// See https://github.com/janl/mustache.js/issues/244
	mustache.escape = escapeHtml;

	// Export these mainly for testing, but also for advanced usage.
	mustache.Scanner = Scanner;
	mustache.Context = Context;
	mustache.Writer = Writer;

}));;
/**
 *               ~ CLNDR v1.4.1 ~
 * ==============================================
 *       https://github.com/kylestetz/CLNDR
 * ==============================================
 *  Created by kyle stetz (github.com/kylestetz)
 *       & available under the MIT license
 * http://opensource.org/licenses/mit-license.php
 * ==============================================
 *
 * This is the fully-commented development version of CLNDR.
 * For the production version, check out clndr.min.js
 * at https://github.com/kylestetz/CLNDR
 *
 * This work is based on the
 * jQuery lightweight plugin boilerplate
 * Original author: @ajpiano
 * Further changes, comments: @addyosmani
 * Licensed under the MIT license
 */
(function (factory) {
	// Multiple loading methods are supported depending on
	// what is available globally. While moment is loaded
	// here, the instance can be passed in at config time.
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['jquery', 'moment'], factory);
	}
	else if (typeof exports === 'object') {
		// Node/CommonJS
		factory(require('jquery'), require('moment'));
	}
	else {
		// Browser globals
		factory(jQuery, moment);
	}
}(function ($, moment) {
	// Namespace
	var pluginName = 'clndr';

	// This is the default calendar template. This can be overridden.
	var clndrTemplate =
        "<div class='clndr-controls'>" +
            "<div class='clndr-control-button'>" +
                "<span class='clndr-previous-button'>previous</span>" +
            "</div>" +
            "<div class='month'><%= month %> <%= year %></div>" +
            "<div class='clndr-control-button rightalign'>" +
                "<span class='clndr-next-button'>next</span>" +
            "</div>" +
        "</div>" +
        "<table class='clndr-table' border='0' cellspacing='0' cellpadding='0'>" +
            "<thead>" +
                "<tr class='header-days'>" +
                "<% for(var i = 0; i < daysOfTheWeek.length; i++) { %>" +
                    "<td class='header-day'><%= daysOfTheWeek[i] %></td>" +
                "<% } %>" +
                "</tr>" +
            "</thead>" +
            "<tbody>" +
            "<% for(var i = 0; i < numberOfRows; i++){ %>" +
                "<tr>" +
                "<% for(var j = 0; j < 7; j++){ %>" +
                "<% var d = j + i * 7; %>" +
                    "<td class='<%= days[d].classes %>'>" +
                        "<div class='day-contents'><%= days[d].day %></div>" +
                    "</td>" +
                "<% } %>" +
                "</tr>" +
            "<% } %>" +
            "</tbody>" +
        "</table>";

	// Defaults used throughout the application, see docs.
	var defaults = {
		events: [],
		ready: null,
		extras: null,
		render: null,
		moment: null,
		weekOffset: 0,
		constraints: null,
		forceSixRows: null,
		selectedDate: null,
		doneRendering: null,
		daysOfTheWeek: null,
		multiDayEvents: null,
		startWithMonth: null,
		dateParameter: 'date',
		template: clndrTemplate,
		showAdjacentMonths: true,
		trackSelectedDate: false,
		adjacentDaysChangeMonth: false,
		ignoreInactiveDaysInSelection: null,
		lengthOfTime: {
			days: null,
			interval: 1,
			months: null
		},
		clickEvents: {
			click: null,
			today: null,
			nextYear: null,
			nextMonth: null,
			nextInterval: null,
			previousYear: null,
			onYearChange: null,
			previousMonth: null,
			onMonthChange: null,
			previousInterval: null,
			onIntervalChange: null
		},
		targets: {
			day: 'day',
			empty: 'empty',
			nextButton: 'clndr-next-button',
			todayButton: 'clndr-today-button',
			previousButton: 'clndr-previous-button',
			nextYearButton: 'clndr-next-year-button',
			previousYearButton: 'clndr-previous-year-button'
		},
		classes: {
			past: "past",
			today: "today",
			event: "event",
			inactive: "inactive",
			selected: "selected",
			lastMonth: "last-month",
			nextMonth: "next-month",
			adjacentMonth: "adjacent-month"
		},
	};

	/**
     * The actual plugin constructor.
     * Parses the events and lengthOfTime options to build a calendar of day
     * objects containing event information from the events array.
     */
	function Clndr(element, options) {
		this.element = element;

		// Merge the default options with user-provided options
		this.options = $.extend(true, {}, defaults, options);

		// Check if moment was passed in as a dependency
		if (this.options.moment) {
			moment = this.options.moment;
		}

		// Boolean values used to log if any contraints are met
		this.constraints = {
			next: true,
			today: true,
			previous: true,
			nextYear: true,
			previousYear: true
		};

		// If there are events, we should run them through our
		// addMomentObjectToEvents function which will add a date object that
		// we can use to make life easier. This is only necessarywhen events
		// are provided on instantiation, since our setEvents function uses
		// addMomentObjectToEvents.
		if (this.options.events.length) {
			if (this.options.multiDayEvents) {
				this.options.events =
                    this.addMultiDayMomentObjectsToEvents(this.options.events);
			} else {
				this.options.events =
                    this.addMomentObjectToEvents(this.options.events);
			}
		}

		// This used to be a place where we'd figure out the current month,
		// but since we want to open up support for arbitrary lengths of time
		// we're going to store the current range in addition to the current
		// month.
		if (this.options.lengthOfTime.months || this.options.lengthOfTime.days) {
			// We want to establish intervalStart and intervalEnd, which will
			// keep track of our boundaries. Let's look at the possibilities...
			if (this.options.lengthOfTime.months) {
				// Gonna go right ahead and annihilate any chance for bugs here
				this.options.lengthOfTime.days = null;
				// The length is specified in months. Is there a start date?
				if (this.options.lengthOfTime.startDate) {
					this.intervalStart =
                        moment(this.options.lengthOfTime.startDate)
                            .startOf('month');
				} else if (this.options.startWithMonth) {
					this.intervalStart =
                        moment(this.options.startWithMonth)
                            .startOf('month');
				} else {
					this.intervalStart = moment().startOf('month');
				}
				// Subtract a day so that we are at the end of the interval. We
				// always want intervalEnd to be inclusive.
				this.intervalEnd = moment(this.intervalStart)
                    .add(this.options.lengthOfTime.months, 'months')
                    .subtract(1, 'days');
				this.month = this.intervalStart.clone();
			}
			else if (this.options.lengthOfTime.days) {
				// The length is specified in days. Start date?
				if (this.options.lengthOfTime.startDate) {
					this.intervalStart =
                        moment(this.options.lengthOfTime.startDate)
                            .startOf('day');
				} else {
					this.intervalStart = moment().weekday(0).startOf('day');
				}
				this.intervalEnd = moment(this.intervalStart)
                    .add(this.options.lengthOfTime.days - 1, 'days')
                    .endOf('day');
				this.month = this.intervalStart.clone();
			}
			// No length of time specified so we're going to default into using the
			// current month as the time period.
		} else {
			this.month = moment().startOf('month');
			this.intervalStart = moment(this.month);
			this.intervalEnd = moment(this.month).endOf('month');
		}

		if (this.options.startWithMonth) {
			this.month = moment(this.options.startWithMonth).startOf('month');
			this.intervalStart = moment(this.month);
			this.intervalEnd = moment(this.month).endOf('month');
		}

		// If we've got constraints set, make sure the interval is within them.
		if (this.options.constraints) {
			// First check if the start date exists & is later than now.
			if (this.options.constraints.startDate) {
				var startMoment = moment(this.options.constraints.startDate);

				if (this.intervalStart.isBefore(startMoment, 'month')) {
					// Try to preserve the date by moving only the month...
					this.intervalStart
                        .set('month', startMoment.month())
                        .set('year', startMoment.year());
					this.month
                        .set('month', startMoment.month())
                        .set('year', startMoment.year());
				}
			}
			// Make sure the intervalEnd is before the endDate
			if (this.options.constraints.endDate) {
				var endMoment = moment(this.options.constraints.endDate);

				if (this.intervalEnd.isAfter(endMoment, 'month')) {
					this.intervalEnd
                        .set('month', endMoment.month())
                        .set('year', endMoment.year());
					this.month
                        .set('month', endMoment.month())
                        .set('year', endMoment.year());
				}
			}
		}

		this._defaults = defaults;
		this._name = pluginName;

		// Some first-time initialization -> day of the week offset, template
		// compiling, making and storing some elements we'll need later, and
		// event handling for the controller.
		this.init();
	}

	/**
     * Calendar initialization.
     * Sets up the days of the week, the rendering function, binds all of the
     * events to the rendered calendar, and then stores the node locally.
     */
	Clndr.prototype.init = function () {
		// Create the days of the week using moment's current language setting
		this.daysOfTheWeek = this.options.daysOfTheWeek || [];

		if (!this.options.daysOfTheWeek) {
			this.daysOfTheWeek = [];

			for (var i = 0; i < 7; i++) {
				this.daysOfTheWeek.push(
                    moment().weekday(i).format('dd').charAt(0));
			}
		}

		// Shuffle the week if there's an offset
		if (this.options.weekOffset) {
			this.daysOfTheWeek = this.shiftWeekdayLabels(this.options.weekOffset);
		}

		// Quick and dirty test to make sure rendering is possible.
		if (!$.isFunction(this.options.render)) {
			this.options.render = null;

			if (typeof _ === 'undefined') {
				throw new Error(
                    "Underscore was not found. Please include underscore.js " +
                    "OR provide a custom render function.");
			} else {
				// We're just going ahead and using underscore here if no
				// render method has been supplied.
				this.compiledClndrTemplate = _.template(this.options.template);
			}
		}

		// Create the parent element that will hold the plugin and save it
		// for later
		$(this.element).html("<div class='clndr'></div>");
		this.calendarContainer = $('.clndr', this.element);

		// Attach event handlers for clicks on buttons/cells
		this.bindEvents();

		// Do a normal render of the calendar template
		this.render();

		// If a ready callback has been provided, call it.
		if (this.options.ready) {
			this.options.ready.apply(this, []);
		}
	};

	Clndr.prototype.shiftWeekdayLabels = function (offset) {
		var days = this.daysOfTheWeek;

		for (var i = 0; i < offset; i++) {
			days.push(days.shift());
		}

		return days;
	};

	/**
     * This is where the magic happens. Given a starting date and ending date,
     * an array of calendarDay objects is constructed that contains appropriate
     * events and classes depending on the circumstance.
     */
	Clndr.prototype.createDaysObject = function (startDate, endDate) {
		// This array will hold numbers for the entire grid (even the blank
		// spaces).
		var daysArray = [],
            date = startDate.clone(),
            lengthOfInterval = endDate.diff(startDate, 'days'),
            startOfLastMonth, endOfLastMonth, startOfNextMonth,
            endOfNextMonth, diff, dateIterator;

		// This is a helper object so that days can resolve their classes
		// correctly. Don't use it for anything please.
		this._currentIntervalStart = startDate.clone();

		// Filter the events list (if it exists) to events that are happening
		// last month, this month and next month (within the current grid view).
		this.eventsLastMonth = [];
		this.eventsNextMonth = [];
		this.eventsThisInterval = [];

		// Event parsing
		if (this.options.events.length) {
			// Here are the only two cases where we don't get an event in our
			// interval:
			//   startDate | endDate | e.start   | e.end
			//   e.start   | e.end   | startDate | endDate
			this.eventsThisInterval = $(this.options.events).filter(
                function () {
                	var afterEnd = this._clndrStartDateObject.isAfter(endDate),
                        beforeStart = this._clndrEndDateObject.isBefore(startDate);

                	if (beforeStart || afterEnd) {
                		return false;
                	} else {
                		return true;
                	}
                }).toArray();

			if (this.options.showAdjacentMonths) {
				startOfLastMonth = startDate.clone()
                    .subtract(1, 'months')
                    .startOf('month');
				endOfLastMonth = startOfLastMonth.clone().endOf('month');
				startOfNextMonth = endDate.clone()
                    .add(1, 'months')
                    .startOf('month');
				endOfNextMonth = startOfNextMonth.clone().endOf('month');

				this.eventsLastMonth = $(this.options.events).filter(
                    function () {
                    	var beforeStart = this._clndrEndDateObject
                            .isBefore(startOfLastMonth);
                    	var afterEnd = this._clndrStartDateObject
                            .isAfter(endOfLastMonth);

                    	if (beforeStart || afterEnd) {
                    		return false;
                    	} else {
                    		return true;
                    	}
                    }).toArray();

				this.eventsNextMonth = $(this.options.events).filter(
                    function () {
                    	var beforeStart = this._clndrEndDateObject
                            .isBefore(startOfNextMonth);
                    	var afterEnd = this._clndrStartDateObject
                            .isAfter(endOfNextMonth);

                    	if (beforeStart || afterEnd) {
                    		return false;
                    	} else {
                    		return true;
                    	}
                    }).toArray();
			}
		}

		// If diff is greater than 0, we'll have to fill in last days of the
		// previous month to account for the empty boxes in the grid. We also
		// need to take into account the weekOffset parameter. None of this
		// needs to happen if the interval is being specified in days rather
		// than months.
		if (!this.options.lengthOfTime.days) {
			diff = date.weekday() - this.options.weekOffset;

			if (diff < 0) {
				diff += 7;
			}

			if (this.options.showAdjacentMonths) {
				for (var i = 0; i < diff; i++) {
					var day = moment([
                        startDate.year(),
                        startDate.month(),
                        i - diff + 1
					]);
					daysArray.push(
                        this.createDayObject(
                            day,
                            this.eventsLastMonth
                        ));
				}
			} else {
				for (var i = 0; i < diff; i++) {
					daysArray.push(
                        this.calendarDay({
                        	classes: this.options.targets.empty +
                                " " + this.options.classes.lastMonth
                        }));
				}
			}
		}

		// Now we push all of the days in the interval
		dateIterator = startDate.clone();

		while (dateIterator.isBefore(endDate) || dateIterator.isSame(endDate, 'day')) {
			daysArray.push(
                this.createDayObject(
                    dateIterator.clone(),
                    this.eventsThisInterval
                ));
			dateIterator.add(1, 'days');
		}

		// ...and if there are any trailing blank boxes, fill those in with the
		// next month first days. Again, we can ignore this if the interval is
		// specified in days.
		if (!this.options.lengthOfTime.days) {
			while (daysArray.length % 7 !== 0) {
				if (this.options.showAdjacentMonths) {
					daysArray.push(
                        this.createDayObject(
                            dateIterator.clone(),
                            this.eventsNextMonth
                        ));
				} else {
					daysArray.push(
                        this.calendarDay({
                        	classes: this.options.targets.empty + " " +
                                this.options.classes.nextMonth
                        }));
				}
				dateIterator.add(1, 'days');
			}
		}

		// If we want to force six rows of calendar, now's our Last Chance to
		// add another row. If the 42 seems explicit it's because we're
		// creating a 7-row grid and 6 rows of 7 is always 42!
		if (this.options.forceSixRows && daysArray.length !== 42) {
			while (daysArray.length < 42) {
				if (this.options.showAdjacentMonths) {
					daysArray.push(
                        this.createDayObject(
                            dateIterator.clone(),
                            this.eventsNextMonth
                        ));
					dateIterator.add(1, 'days');
				} else {
					daysArray.push(
                        this.calendarDay({
                        	classes: this.options.targets.empty + " " +
                                this.options.classes.nextMonth
                        }));
				}
			}
		}

		return daysArray;
	};

	Clndr.prototype.createDayObject = function (day, monthEvents) {
		var j = 0,
            self = this,
            now = moment(),
            eventsToday = [],
            extraClasses = "",
            properties = {
            	isToday: false,
            	isInactive: false,
            	isAdjacentMonth: false
            },
            startMoment, endMoment, selectedMoment;

		// Validate moment date
		if (!day.isValid() && day.hasOwnProperty('_d') && day._d != undefined) {
			day = moment(day._d);
		}

		for (j; j < monthEvents.length; j++) {
			// Keep in mind that the events here already passed the month/year
			// test. Now all we have to compare is the moment.date(), which
			// returns the day of the month.
			var start = monthEvents[j]._clndrStartDateObject,
                end = monthEvents[j]._clndrEndDateObject;
			// If today is the same day as start or is after the start, and
			// if today is the same day as the end or before the end ...
			// woohoo semantics!
			if ((day.isSame(start, 'day') || day.isAfter(start, 'day'))
                && (day.isSame(end, 'day') || day.isBefore(end, 'day'))) {
				eventsToday.push(monthEvents[j]);
			}
		}

		if (now.format("YYYY-MM-DD") == day.format("YYYY-MM-DD")) {
			extraClasses += (" " + this.options.classes.today);
			properties.isToday = true;
		}

		if (day.isBefore(now, 'day')) {
			extraClasses += (" " + this.options.classes.past);
		}

		if (eventsToday.length) {
			extraClasses += (" " + this.options.classes.event);
		}

		if (!this.options.lengthOfTime.days) {
			if (this._currentIntervalStart.month() > day.month()) {
				extraClasses += (" " + this.options.classes.adjacentMonth);
				properties.isAdjacentMonth = true;

				this._currentIntervalStart.year() === day.year()
                    ? extraClasses += (" " + this.options.classes.lastMonth)
                    : extraClasses += (" " + this.options.classes.nextMonth);
			}
			else if (this._currentIntervalStart.month() < day.month()) {
				extraClasses += (" " + this.options.classes.adjacentMonth);
				properties.isAdjacentMonth = true;

				this._currentIntervalStart.year() === day.year()
                    ? extraClasses += (" " + this.options.classes.nextMonth)
                    : extraClasses += (" " + this.options.classes.lastMonth);
			}
		}

		// If there are constraints, we need to add the inactive class to the
		// days outside of them
		if (this.options.constraints) {
			endMoment = moment(this.options.constraints.endDate);
			startMoment = moment(this.options.constraints.startDate);

			if (this.options.constraints.startDate && day.isBefore(startMoment)) {
				extraClasses += (" " + this.options.classes.inactive);
				properties.isInactive = true;
			}

			if (this.options.constraints.endDate && day.isAfter(endMoment)) {
				extraClasses += (" " + this.options.classes.inactive);
				properties.isInactive = true;
			}
		}

		// Validate moment date
		if (!day.isValid() && day.hasOwnProperty('_d') && day._d != undefined) {
			day = moment(day._d);
		}

		// Check whether the day is "selected"
		selectedMoment = moment(this.options.selectedDate);

		if (this.options.selectedDate && day.isSame(selectedMoment, 'day')) {
			extraClasses += (" " + this.options.classes.selected);
		}

		// We're moving away from using IDs in favor of classes, since when
		// using multiple calendars on a page we are technically violating the
		// uniqueness of IDs.
		extraClasses += " calendar-day-" + day.format("YYYY-MM-DD");
		// Day of week
		extraClasses += " calendar-dow-" + day.weekday();

		return this.calendarDay({
			date: day,
			day: day.date(),
			events: eventsToday,
			properties: properties,
			classes: this.options.targets.day + extraClasses
		});
	};

	Clndr.prototype.render = function () {
		// Get rid of the previous set of calendar parts. This should handle garbage
		// collection according to jQuery's docs:
		//   http://api.jquery.com/empty/
		//   To avoid memory leaks, jQuery removes other constructs such as
		//   data and event handlers from the child elements before removing
		//   the elements themselves.
		var data = {},
            end = null,
            start = null,
            oneYearFromEnd = this.intervalEnd.clone().add(1, 'years'),
            oneYearAgo = this.intervalStart.clone().subtract(1, 'years'),
            days, months, currentMonth, eventsThisInterval,
            numberOfRows;
		this.calendarContainer.empty();

		if (this.options.lengthOfTime.days) {
			days = this.createDaysObject(
                this.intervalStart.clone(),
                this.intervalEnd.clone());
			data = {
				days: days,
				months: [],
				year: null,
				month: null,
				eventsLastMonth: [],
				eventsNextMonth: [],
				eventsThisMonth: [],
				extras: this.options.extras,
				daysOfTheWeek: this.daysOfTheWeek,
				intervalEnd: this.intervalEnd.clone(),
				numberOfRows: Math.ceil(days.length / 7),
				intervalStart: this.intervalStart.clone(),
				eventsThisInterval: this.eventsThisInterval
			};
		}
		else if (this.options.lengthOfTime.months) {
			months = [];
			numberOfRows = 0;
			eventsThisInterval = [];

			for (i = 0; i < this.options.lengthOfTime.months; i++) {
				var currentIntervalStart = this.intervalStart
                    .clone()
                    .add(i, 'months');
				var currentIntervalEnd = currentIntervalStart
                    .clone()
                    .endOf('month');
				var days = this.createDaysObject(
                    currentIntervalStart,
                    currentIntervalEnd);
				// Save events processed for each month into a master array of
				// events for this interval
				eventsThisInterval.push(this.eventsThisInterval);
				months.push({
					days: days,
					month: currentIntervalStart
				});
			}

			// Get the total number of rows across all months
			for (i in months) {
				numberOfRows += Math.ceil(months[i].days.length / 7);
			}

			data = {
				days: [],
				year: null,
				month: null,
				months: months,
				eventsThisMonth: [],
				numberOfRows: numberOfRows,
				extras: this.options.extras,
				intervalEnd: this.intervalEnd,
				intervalStart: this.intervalStart,
				daysOfTheWeek: this.daysOfTheWeek,
				eventsLastMonth: this.eventsLastMonth,
				eventsNextMonth: this.eventsNextMonth,
				eventsThisInterval: eventsThisInterval,
			};
		}
		else {
			// Get an array of days and blank spaces
			days = this.createDaysObject(
                this.month.clone().startOf('month'),
                this.month.clone().endOf('month'));
			// This is to prevent a scope/naming issue between this.month and
			// data.month
			currentMonth = this.month;

			data = {
				days: days,
				months: [],
				intervalEnd: null,
				intervalStart: null,
				year: this.month.year(),
				eventsThisInterval: null,
				extras: this.options.extras,
				month: this.month.format('MMMM'),
				daysOfTheWeek: this.daysOfTheWeek,
				eventsLastMonth: this.eventsLastMonth,
				eventsNextMonth: this.eventsNextMonth,
				numberOfRows: Math.ceil(days.length / 7),
				eventsThisMonth: this.eventsThisInterval
			};
		}

		// Render the calendar with the data above & bind events to its
		// elements
		if (!this.options.render) {
			this.calendarContainer.html(
                this.compiledClndrTemplate(data));
		} else {
			this.calendarContainer.html(
                this.options.render.apply(this, [data]));
		}

		// If there are constraints, we need to add the 'inactive' class to
		// the controls.
		if (this.options.constraints) {
			// In the interest of clarity we're just going to remove all
			// inactive classes and re-apply them each render.
			for (var target in this.options.targets) {
				if (target != this.options.targets.day) {
					this.element.find('.' + this.options.targets[target])
                        .toggleClass(
                            this.options.classes.inactive,
                            false);
				}
			}

			// Just like the classes we'll set this internal state to true and
			// handle the disabling below.
			for (var i in this.constraints) {
				this.constraints[i] = true;
			}

			if (this.options.constraints.startDate) {
				start = moment(this.options.constraints.startDate);
			}

			if (this.options.constraints.endDate) {
				end = moment(this.options.constraints.endDate);
			}

			// Deal with the month controls first. Do we have room to go back?
			if (start
                && (start.isAfter(this.intervalStart)
                    || start.isSame(this.intervalStart, 'day'))) {
				this.element.find('.' + this.options.targets.previousButton)
                    .toggleClass(this.options.classes.inactive, true);
				this.constraints.previous = !this.constraints.previous;
			}

			// Do we have room to go forward?
			if (end
                && (end.isBefore(this.intervalEnd)
                    || end.isSame(this.intervalEnd, 'day'))) {
				this.element.find('.' + this.options.targets.nextButton)
                    .toggleClass(this.options.classes.inactive, true);
				this.constraints.next = !this.constraints.next;
			}

			// What's last year looking like?
			if (start && start.isAfter(oneYearAgo)) {
				this.element.find('.' + this.options.targets.previousYearButton)
                    .toggleClass(this.options.classes.inactive, true);
				this.constraints.previousYear = !this.constraints.previousYear;
			}

			// How about next year?
			if (end && end.isBefore(oneYearFromEnd)) {
				this.element.find('.' + this.options.targets.nextYearButton)
                    .toggleClass(this.options.classes.inactive, true);
				this.constraints.nextYear = !this.constraints.nextYear;
			}

			// Today? We could put this in init(), but we want to support the
			// user changing the constraints on a living instance.
			if ((start && start.isAfter(moment(), 'month'))
                || (end && end.isBefore(moment(), 'month'))) {
				this.element.find('.' + this.options.targets.today)
                    .toggleClass(this.options.classes.inactive, true);
				this.constraints.today = !this.constraints.today;
			}
		}

		if (this.options.doneRendering) {
			this.options.doneRendering.apply(this, []);
		}
	};

	Clndr.prototype.bindEvents = function () {
		var self = this,
            $container = $(this.element),
            targets = this.options.targets,
            classes = self.options.classes,
            eventType = (this.options.useTouchEvents === true)
                ? 'touchstart'
                : 'click',
            eventName = eventType + '.clndr';

		// Make sure we don't already have events
		$container
            .off(eventName, '.' + targets.day)
            .off(eventName, '.' + targets.empty)
            .off(eventName, '.' + targets.nextButton)
            .off(eventName, '.' + targets.todayButton)
            .off(eventName, '.' + targets.previousButton)
            .off(eventName, '.' + targets.nextYearButton)
            .off(eventName, '.' + targets.previousYearButton);

		// Target the day elements and give them click events
		$container.on(eventName, '.' + targets.day, function (event) {
			var $currentTarget = $(event.currentTarget),
                target;

			if (self.options.clickEvents.click) {
				target = self.buildTargetObject(event.currentTarget, true);
				self.options.clickEvents.click.apply(self, [target]);
			}

			// If adjacentDaysChangeMonth is on, we need to change the
			// month here.
			if (self.options.adjacentDaysChangeMonth) {
				if ($currentTarget.is('.' + classes.lastMonth)) {
					self.backActionWithContext(self);
				}
				else if ($currentTarget.is('.' + classes.nextMonth)) {
					self.forwardActionWithContext(self);
				}
			}

			// if trackSelectedDate is on, we need to handle click on a new day
			if (self.options.trackSelectedDate) {
				if (self.options.ignoreInactiveDaysInSelection
                    && $currentTarget.hasClass(classes.inactive)) {
					return;
				}

				// Remember new selected date
				self.options.selectedDate =
                    self.getTargetDateString(event.currentTarget);
				// Handle "selected" class
				$currentTarget
                    .siblings().removeClass(classes.selected).end()
                    .addClass(classes.selected);
			}
		});

		// Target the empty calendar boxes as well
		$container.on(eventName, '.' + targets.empty, function (event) {
			var $eventTarget = $(event.currentTarget),
                target;

			if (self.options.clickEvents.click) {
				target = self.buildTargetObject(event.currentTarget, false);
				self.options.clickEvents.click.apply(self, [target]);
			}

			if (self.options.adjacentDaysChangeMonth) {
				if ($eventTarget.is('.' + classes.lastMonth)) {
					self.backActionWithContext(self);
				}
				else if ($eventTarget.is('.' + classes.nextMonth)) {
					self.forwardActionWithContext(self);
				}
			}
		});

		// Bind the previous, next and today buttons. We pass the current
		// context along with the event so that it can update this instance.
		data = {
			context: this
		};

		$container
            .on(eventName, '.' + targets.todayButton, data, this.todayAction)
            .on(eventName, '.' + targets.nextButton, data, this.forwardAction)
            .on(eventName, '.' + targets.previousButton, data, this.backAction)
            .on(eventName, '.' + targets.nextYearButton, data, this.nextYearAction)
            .on(eventName, '.' + targets.previousYearButton, data, this.previousYearAction);
	};

	/**
     * If the user provided a click callback we'd like to give them something
     * nice to work with. buildTargetObject takes the DOM element that was
     * clicked and returns an object with the DOM element, events, and the date
     * (if the latter two exist). Currently it is based on the id, however it'd
     * be nice to use a data- attribute in the future.
     */
	Clndr.prototype.buildTargetObject = function (currentTarget, targetWasDay) {
		// This is our default target object, assuming we hit an empty day
		// with no events.
		var target = {
			date: null,
			events: [],
			element: currentTarget
		};
		var dateString, filterFn;

		// Did we click on a day or just an empty box?
		if (targetWasDay) {
			dateString = this.getTargetDateString(currentTarget);
			target.date = (dateString)
                ? moment(dateString)
                : null;

			// Do we have events?
			if (this.options.events) {
				// Are any of the events happening today?
				if (this.options.multiDayEvents) {
					filterFn = function () {
						var isSameStart = target.date.isSame(
                            this._clndrStartDateObject,
                            'day');
						var isAfterStart = target.date.isAfter(
                            this._clndrStartDateObject,
                            'day');
						var isSameEnd = target.date.isSame(
                            this._clndrEndDateObject,
                            'day');
						var isBeforeEnd = target.date.isBefore(
                            this._clndrEndDateObject,
                            'day');
						return (isSameStart || isAfterStart)
                            && (isSameEnd || isBeforeEnd);
					};
				}
				else {
					filterFn = function () {
						var startString = this._clndrStartDateObject
                            .format('YYYY-MM-DD');
						return startString == dateString;
					};
				}

				// Filter the dates down to the ones that match.
				target.events = $.makeArray(
                    $(this.options.events).filter(filterFn));
			}
		}

		return target;
	};

	/**
     * Get moment date object of the date associated with the given target.
     * This method is meant to be called on ".day" elements.
     */
	Clndr.prototype.getTargetDateString = function (target) {
		// Our identifier is in the list of classNames. Find it!
		var classNameIndex = target.className.indexOf('calendar-day-');

		if (classNameIndex !== -1) {
			// Our unique identifier is always 23 characters long.
			// If this feels a little wonky, that's probably because it is.
			// Open to suggestions on how to improve this guy.
			return target.className.substring(
                classNameIndex + 13,
                classNameIndex + 23);
		}

		return null;
	};

	/**
     * Triggers any applicable events given a change in the calendar's start
     * and end dates. ctx contains the current (changed) start and end date,
     * orig contains the original start and end dates.
     */
	Clndr.prototype.triggerEvents = function (ctx, orig) {
		var timeOpt = ctx.options.lengthOfTime,
            eventsOpt = ctx.options.clickEvents,
            newInt = {
            	end: ctx.intervalEnd,
            	start: ctx.intervalStart
            },
            intervalArg = [
                moment(ctx.intervalStart),
                moment(ctx.intervalEnd)
            ],
            monthArg = [moment(ctx.month)],
            nextYear, prevYear, yearChanged,
            nextMonth, prevMonth, monthChanged,
            nextInterval, prevInterval, intervalChanged;

		// We want to determine if any of the change conditions have been
		// hit and then trigger our events based off that.
		nextMonth = newInt.start.isAfter(orig.start)
            && (Math.abs(newInt.start.month() - orig.start.month()) == 1
                || orig.start.month() === 11 && newInt.start.month() === 0);
		prevMonth = newInt.start.isBefore(orig.start)
            && (Math.abs(orig.start.month() - newInt.start.month()) == 1
                || orig.start.month() === 0 && newInt.start.month() === 11);
		monthChanged = newInt.start.month() !== orig.start.month()
            || newInt.start.year() !== orig.start.year();
		nextYear = newInt.start.year() - orig.start.year() === 1
            || newInt.end.year() - orig.end.year() === 1;
		prevYear = orig.start.year() - newInt.start.year() === 1
            || orig.end.year() - newInt.end.year() === 1;
		yearChanged = newInt.start.year() !== orig.start.year();

		// Only configs with a time period will get the interval change event
		if (timeOpt.days || timeOpt.months) {
			nextInterval = newInt.start.isAfter(orig.start);
			prevInterval = newInt.start.isBefore(orig.start);
			intervalChanged = nextInterval || prevInterval;

			if (nextInterval && eventsOpt.nextInterval) {
				eventsOpt.nextInterval.apply(ctx, intervalArg);
			}

			if (prevInterval && eventsOpt.previousInterval) {
				eventsOpt.previousInterval.apply(ctx, intervalArg);
			}

			if (intervalChanged && eventsOpt.onIntervalChange) {
				eventsOpt.onIntervalChange.apply(ctx, intervalArg);
			}
		}
			// @V2-todo see https://github.com/kylestetz/CLNDR/issues/225
		else {
			if (nextMonth && eventsOpt.nextMonth) {
				eventsOpt.nextMonth.apply(ctx, monthArg);
			}

			if (prevMonth && eventsOpt.previousMonth) {
				eventsOpt.previousMonth.apply(ctx, monthArg);
			}

			if (monthChanged && eventsOpt.onMonthChange) {
				eventsOpt.onMonthChange.apply(ctx, monthArg);
			}

			if (nextYear && eventsOpt.nextYear) {
				eventsOpt.nextYear.apply(ctx, monthArg);
			}

			if (prevYear && eventsOpt.previousYear) {
				eventsOpt.previousYear.apply(ctx, monthArg);
			}

			if (yearChanged && eventsOpt.onYearChange) {
				eventsOpt.onYearChange.apply(ctx, monthArg);
			}
		}
	};

	/**
     * Main action to go backward one period. Other methods call these, like
     * backAction which proxies jQuery events, and backActionWithContext which
     * is an internal method that this library uses.
     */
	Clndr.prototype.back = function (options /*, ctx */) {
		var yearChanged = null,
            ctx = (arguments.length > 1)
                ? arguments[1]
                : this,
            timeOpt = ctx.options.lengthOfTime,
            defaults = {
            	withCallbacks: false
            },
            orig = {
            	end: ctx.intervalEnd.clone(),
            	start: ctx.intervalStart.clone()
            };

		// Extend any options
		options = $.extend(true, {}, defaults, options);

		// Before we do anything, check if any constraints are limiting this
		if (!ctx.constraints.previous) {
			return ctx;
		}

		if (!timeOpt.days) {
			// Shift the interval by a month (or several months)
			ctx.intervalStart
                .subtract(timeOpt.interval, 'months')
                .startOf('month');
			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.months || timeOpt.interval, 'months')
                .subtract(1, 'days')
                .endOf('month');
			ctx.month = ctx.intervalStart.clone();
		}
		else {
			// Shift the interval in days
			ctx.intervalStart
                .subtract(timeOpt.interval, 'days')
                .startOf('day');
			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.days - 1, 'days')
                .endOf('day');
			// @V2-todo Useless, but consistent with API
			ctx.month = ctx.intervalStart.clone();
		}

		ctx.render();

		if (options.withCallbacks) {
			ctx.triggerEvents(ctx, orig);
		}

		return ctx;
	};

	Clndr.prototype.backAction = function (event) {
		var ctx = event.data.context;
		ctx.backActionWithContext(ctx);
	};

	Clndr.prototype.backActionWithContext = function (ctx) {
		ctx.back({
			withCallbacks: true
		}, ctx);
	};

	Clndr.prototype.previous = function (options) {
		// Alias
		return this.back(options);
	};

	/**
     * Main action to go forward one period. Other methods call these, like
     * forwardAction which proxies jQuery events, and backActionWithContext
     * which is an internal method that this library uses.
     */
	Clndr.prototype.forward = function (options /*, ctx */) {
		var ctx = (arguments.length > 1)
                ? arguments[1]
                : this,
            timeOpt = ctx.options.lengthOfTime,
            defaults = {
            	withCallbacks: false
            },
            orig = {
            	end: ctx.intervalEnd.clone(),
            	start: ctx.intervalStart.clone()
            };

		// Extend any options
		options = $.extend(true, {}, defaults, options);

		// Before we do anything, check if any constraints are limiting this
		if (!ctx.constraints.next) {
			return ctx;
		}

		if (ctx.options.lengthOfTime.days) {
			// Shift the interval in days
			ctx.intervalStart
                .add(timeOpt.interval, 'days')
                .startOf('day');
			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.days - 1, 'days')
                .endOf('day');
			// @V2-todo Useless, but consistent with API
			ctx.month = ctx.intervalStart.clone();
		}
		else {
			// Shift the interval by a month (or several months)
			ctx.intervalStart
                .add(timeOpt.interval, 'months')
                .startOf('month');
			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.months || timeOpt.interval, 'months')
                .subtract(1, 'days')
                .endOf('month');
			ctx.month = ctx.intervalStart.clone();
		}

		ctx.render();

		if (options.withCallbacks) {
			ctx.triggerEvents(ctx, orig);
		}

		return ctx;
	};

	Clndr.prototype.forwardAction = function (event) {
		var ctx = event.data.context;
		ctx.forwardActionWithContext(ctx);
	};

	Clndr.prototype.forwardActionWithContext = function (ctx) {
		ctx.forward({
			withCallbacks: true
		}, ctx);
	};

	Clndr.prototype.next = function (options) {
		// Alias
		return this.forward(options);
	};

	/**
     * Main action to go back one year.
     */
	Clndr.prototype.previousYear = function (options /*, ctx */) {
		var ctx = (arguments.length > 1)
                ? arguments[1]
                : this,
            defaults = {
            	withCallbacks: false
            },
            orig = {
            	end: ctx.intervalEnd.clone(),
            	start: ctx.intervalStart.clone()
            };

		// Extend any options
		options = $.extend(true, {}, defaults, options);

		// Before we do anything, check if any constraints are limiting this
		if (!ctx.constraints.previousYear) {
			return ctx;
		}

		ctx.month.subtract(1, 'year');
		ctx.intervalStart.subtract(1, 'year');
		ctx.intervalEnd.subtract(1, 'year');
		ctx.render();

		if (options.withCallbacks) {
			ctx.triggerEvents(ctx, orig);
		}

		return ctx;
	};

	Clndr.prototype.previousYearAction = function (event) {
		var ctx = event.data.context;
		ctx.previousYear({
			withCallbacks: true
		}, ctx);
	};

	/**
     * Main action to go forward one year.
     */
	Clndr.prototype.nextYear = function (options /*, ctx */) {
		var ctx = (arguments.length > 1)
                ? arguments[1]
                : this,
            defaults = {
            	withCallbacks: false
            },
            orig = {
            	end: ctx.intervalEnd.clone(),
            	start: ctx.intervalStart.clone()
            };

		// Extend any options
		options = $.extend(true, {}, defaults, options);

		// Before we do anything, check if any constraints are limiting this
		if (!ctx.constraints.nextYear) {
			return ctx;
		}

		ctx.month.add(1, 'year');
		ctx.intervalStart.add(1, 'year');
		ctx.intervalEnd.add(1, 'year');
		ctx.render();

		if (options.withCallbacks) {
			ctx.triggerEvents(ctx, orig);
		}

		return ctx;
	};

	Clndr.prototype.nextYearAction = function (event) {
		var ctx = event.data.context;
		ctx.nextYear({
			withCallbacks: true
		}, ctx);
	};

	Clndr.prototype.today = function (options /*, ctx */) {
		var ctx = (arguments.length > 1)
                ? arguments[1]
                : this,
            timeOpt = ctx.options.lengthOfTime,
            defaults = {
            	withCallbacks: false
            },
            orig = {
            	end: ctx.intervalEnd.clone(),
            	start: ctx.intervalStart.clone()
            };

		// Extend any options
		options = $.extend(true, {}, defaults, options);
		// @V2-todo Only used for legacy month view
		ctx.month = moment().startOf('month');

		if (timeOpt.days) {
			// If there was a startDate specified, we should figure out what
			// the weekday is and use that as the starting point of our
			// interval. If not, go to today.weekday(0).
			if (timeOpt.startDate) {
				ctx.intervalStart = moment()
                    .weekday(timeOpt.startDate.weekday())
                    .startOf('day');
			} else {
				ctx.intervalStart = moment().weekday(0).startOf('day');
			}

			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.days - 1, 'days')
                .endOf('day');
		}
		else {
			// Set the intervalStart to this month.
			ctx.intervalStart = moment().startOf('month');
			ctx.intervalEnd = ctx.intervalStart.clone()
                .add(timeOpt.months || timeOpt.interval, 'months')
                .subtract(1, 'days')
                .endOf('month');
		}

		// No need to re-render if we didn't change months.
		if (!ctx.intervalStart.isSame(orig.start)
            || !ctx.intervalEnd.isSame(orig.end)) {
			ctx.render();
		}

		// Fire the today event handler regardless of any change
		if (options.withCallbacks) {
			if (ctx.options.clickEvents.today) {
				ctx.options.clickEvents.today.apply(ctx, [moment(ctx.month)]);
			}

			ctx.triggerEvents(ctx, orig);
		}
	};

	Clndr.prototype.todayAction = function (event) {
		var ctx = event.data.context;
		ctx.today({
			withCallbacks: true
		}, ctx);
	};

	/**
     * Changes the month. Accepts 0-11 or a full/partial month name e.g. "Jan",
     * "February", "Mar", etc.
     */
	Clndr.prototype.setMonth = function (newMonth, options) {
		var timeOpt = this.options.lengthOfTime,
            orig = {
            	end: this.intervalEnd.clone(),
            	start: this.intervalStart.clone()
            };

		if (timeOpt.days || timeOpt.months) {
			console.log(
                'You are using a custom date interval. Use ' +
                'Clndr.setIntervalStart(startDate) instead.');
			return this;
		}

		this.month.month(newMonth);
		this.intervalStart = this.month.clone().startOf('month');
		this.intervalEnd = this.intervalStart.clone().endOf('month');
		this.render();

		if (options && options.withCallbacks) {
			this.triggerEvents(this, orig);
		}

		return this;
	};

	Clndr.prototype.setYear = function (newYear, options) {
		var orig = {
			end: this.intervalEnd.clone(),
			start: this.intervalStart.clone()
		};

		this.month.year(newYear);
		this.intervalEnd.year(newYear);
		this.intervalStart.year(newYear);
		this.render();

		if (options && options.withCallbacks) {
			this.triggerEvents(this, orig);
		}

		return this;
	};

	/**
     * Sets the start of the time period according to newDate. newDate can be
     * a string or a moment object.
     */
	Clndr.prototype.setIntervalStart = function (newDate, options) {
		var timeOpt = this.options.lengthOfTime,
            orig = {
            	end: this.intervalEnd.clone(),
            	start: this.intervalStart.clone()
            };

		if (!timeOpt.days && !timeOpt.months) {
			console.log(
                'You are using a custom date interval. Use ' +
                'Clndr.setIntervalStart(startDate) instead.');
			return this;
		}

		if (timeOpt.days) {
			this.intervalStart = moment(newDate).startOf('day');
			this.intervalEnd = this.intervalStart.clone()
                .add(timeOpt - 1, 'days')
                .endOf('day');
		} else {
			this.intervalStart = moment(newDate).startOf('month');
			this.intervalEnd = this.intervalStart.clone()
                .add(timeOpt.months || timeOpt.interval, 'months')
                .subtract(1, 'days')
                .endOf('month');
		}

		this.month = this.intervalStart.clone();
		this.render();

		if (options && options.withCallbacks) {
			this.triggerEvents(this, orig);
		}

		return this;
	};

	/**
     * Overwrites events in the calendar and triggers a render.
     */
	Clndr.prototype.setEvents = function (events) {
		// Go through each event and add a moment object
		if (this.options.multiDayEvents) {
			this.options.events = this.addMultiDayMomentObjectsToEvents(events);
		} else {
			this.options.events = this.addMomentObjectToEvents(events);
		}

		this.render();
		return this;
	};

	/**
     * Adds additional events to the calendar and triggers a render.
     */
	Clndr.prototype.addEvents = function (events) {
		// Go through each event and add a moment object
		if (this.options.multiDayEvents) {
			this.options.events = $.merge(
                this.options.events,
                this.addMultiDayMomentObjectsToEvents(events));
		} else {
			this.options.events = $.merge(
                this.options.events,
                this.addMomentObjectToEvents(events));
		}

		this.render();
		return this;
	};

	/**
     * Passes all events through a matching function. Any that pass a truth
     * test will be removed from the calendar's events. This triggers a render.
     */
	Clndr.prototype.removeEvents = function (matchingFn) {
		for (var i = this.options.events.length - 1; i >= 0; i--) {
			if (matchingFn(this.options.events[i]) == true) {
				this.options.events.splice(i, 1);
			}
		}

		this.render();
		return this;
	};

	Clndr.prototype.addMomentObjectToEvents = function (events) {
		var i = 0,
            self = this;

		for (i; i < events.length; i++) {
			// Add the date as both start and end, since it's a single-day
			// event by default
			events[i]._clndrStartDateObject =
                moment(events[i][self.options.dateParameter]);
			events[i]._clndrEndDateObject =
                moment(events[i][self.options.dateParameter]);
		}

		return events;
	};

	Clndr.prototype.addMultiDayMomentObjectsToEvents = function (events) {
		var i = 0,
            self = this,
            multiEvents = self.options.multiDayEvents;

		for (i; i < events.length; i++) {
			var end = events[i][multiEvents.endDate],
                start = events[i][multiEvents.startDate];
			// If we don't find the startDate OR endDate fields, look for
			// singleDay
			if (!end && !start) {
				events[i]._clndrEndDateObject =
                    moment(events[i][multiEvents.singleDay]);
				events[i]._clndrStartDateObject =
                    moment(events[i][multiEvents.singleDay]);
			}
				// Otherwise use startDate and endDate, or whichever one is present
			else {
				events[i]._clndrEndDateObject = moment(end || start);
				events[i]._clndrStartDateObject = moment(start || end);
			}
		}

		return events;
	};

	Clndr.prototype.calendarDay = function (options) {
		var defaults = {
			day: "",
			date: null,
			events: [],
			classes: this.options.targets.empty
		};

		return $.extend({}, defaults, options);
	};

	Clndr.prototype.destroy = function () {
		var $container = $(this.calendarContainer);
		$container.parent().data('plugin_clndr', null);
		this.options = defaults;
		$container.empty().remove();
		this.element = null;
	};

	$.fn.clndr = function (options) {
		var clndrInstance;

		if (this.length > 1) {
			throw new Error(
                "CLNDR does not support multiple elements yet. Make sure " +
                "your clndr selector returns only one element.");
		}

		if (!this.length) {
			throw new Error(
                "CLNDR cannot be instantiated on an empty selector.");
		}

		if (!this.data('plugin_clndr')) {
			clndrInstance = new Clndr(this, options);
			this.data('plugin_clndr', clndrInstance);
			return clndrInstance;
		}

		return this.data('plugin_clndr');
	};
}));;
/*! lozad.js - v1.15.0 - 2020-05-23
* https://github.com/ApoorvSaxena/lozad.js
* Copyright (c) 2020 Apoorv Saxena; Licensed MIT */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.lozad=e()}(this,function(){"use strict";
/**
   * Detect IE browser
   * @const {boolean}
   * @private
   */var u="undefined"!=typeof document&&document.documentMode,c={rootMargin:"0px",threshold:0,load:function(t){if("picture"===t.nodeName.toLowerCase()){var e=document.createElement("img");u&&t.getAttribute("data-iesrc")&&(e.src=t.getAttribute("data-iesrc")),t.getAttribute("data-alt")&&(e.alt=t.getAttribute("data-alt")),t.append(e)}if("video"===t.nodeName.toLowerCase()&&!t.getAttribute("data-src")&&t.children){for(var r=t.children,a=void 0,i=0;i<=r.length-1;i++)(a=r[i].getAttribute("data-src"))&&(r[i].src=a);t.load()}t.getAttribute("data-poster")&&(t.poster=t.getAttribute("data-poster")),t.getAttribute("data-src")&&(t.src=t.getAttribute("data-src")),t.getAttribute("data-srcset")&&t.setAttribute("srcset",t.getAttribute("data-srcset"));var o=",";if(t.getAttribute("data-background-delimiter")&&(o=t.getAttribute("data-background-delimiter")),t.getAttribute("data-background-image"))t.style.backgroundImage="url('"+t.getAttribute("data-background-image").split(o).join("'),url('")+"')";else if(t.getAttribute("data-background-image-set")){var n=t.getAttribute("data-background-image-set").split(o),d=n[0].substr(0,n[0].indexOf(" "))||n[0];// Substring before ... 1x
d=-1===d.indexOf("url(")?"url("+d+")":d,1===n.length?t.style.backgroundImage=d:t.setAttribute("style",(t.getAttribute("style")||"")+"background-image: "+d+"; background-image: -webkit-image-set("+n+"); background-image: image-set("+n+")")}t.getAttribute("data-toggle-class")&&t.classList.toggle(t.getAttribute("data-toggle-class"))},loaded:function(){}};function l(t){t.setAttribute("data-loaded",!0)}var b=function(t){return"true"===t.getAttribute("data-loaded")};return function(){var r,a,i=0<arguments.length&&void 0!==arguments[0]?arguments[0]:".lozad",t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=Object.assign({},c,t),o=e.root,n=e.rootMargin,d=e.threshold,u=e.load,g=e.loaded,s=void 0;return"undefined"!=typeof window&&window.IntersectionObserver&&(s=new IntersectionObserver((r=u,a=g,function(t,e){t.forEach(function(t){(0<t.intersectionRatio||t.isIntersecting)&&(e.unobserve(t.target),b(t.target)||(r(t.target),l(t.target),a(t.target)))})}),{root:o,rootMargin:n,threshold:d})),{observe:function(){for(var t=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:document;return t instanceof Element?[t]:t instanceof NodeList?t:e.querySelectorAll(t)}(i,o),e=0;e<t.length;e++)b(t[e])||(s?s.observe(t[e]):(u(t[e]),l(t[e]),g(t[e])))},triggerLoad:function(t){b(t)||(u(t),l(t),g(t))},observer:s}}});
;
var HVG;
(function (HVG) {
    var AdverticumAwareCustomAdvertisementRenderer;
    (function (AdverticumAwareCustomAdvertisementRenderer) {
        function Render() {
            var $ = window["goAdverticum3"].getjQuery();
            var adverticumIds = [];
            $("div[id*='zone']").each(function () {
                adverticumIds.push($(this).attr("id").replace("zone", ''));
            });
            $("div[data-customhtml]").each(function () {
                var zoneIds = $(this).attr("data-zoneids").replace(/\s+/g, '').split(',');
                var resultIds = [];
                $.grep(zoneIds, function (e) {
                    if ($.inArray(e, adverticumIds) !== -1) {
                        resultIds.push(e);
                    }
                });
                var isCustomHtmlVisible = true;
                for (var i = 0; i < resultIds.length; i++) {
                    var zone = window["goAdverticum3"].getZone(resultIds[i]);
                    if (zone !== null && !zone.empty) {
                        isCustomHtmlVisible = false;
                        break;
                    }
                }
                if (isCustomHtmlVisible) {
                    var base64Str = $(this).attr("data-customhtml");
                    var customHtml = !!Base64 ? Base64.Decode(base64Str) : atob(base64Str);
                    $(this).html(customHtml);
                }
            });
            $(".cimlap-ajanlat, .sidebar-ajanlat, .hide-empty-banners").each(function (i, adbox) {
                var hasActiveAdv = false;
                $(adbox).find("div[id^='zone']").map(function (i, element) {
                    var zoneId = $(element).attr("id").replace("zone", '');
                    var zone = window["goAdverticum3"].getZone(zoneId);
                    if (zone !== null && !zone.empty) {
                        hasActiveAdv = true;
                    }
                });
                if (hasActiveAdv) {
                    $(adbox).show();
                }
                else {
                    $(adbox).hide();
                }
            });
        }
        AdverticumAwareCustomAdvertisementRenderer.Render = Render;
    })(AdverticumAwareCustomAdvertisementRenderer = HVG.AdverticumAwareCustomAdvertisementRenderer || (HVG.AdverticumAwareCustomAdvertisementRenderer = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=adverticumawarecustomadvertisement.js.map;
var HVG;
(function (HVG) {
    var AdverticumService = (function () {
        function AdverticumService() {
        }
        AdverticumService.Initialize = function () {
            if (document.querySelectorAll("div[class*='goAdverticum']").length === 0) {
                AdverticumService.AfterAdvertisementsRendered();
            }
            else {
                AdverticumService.AddOnGoa3Invocation(AdverticumService.AfterAdvertisementsRendered);
                window["onGoa3Invocation"] = HVG.AdverticumService.OnGoa3Invocation;
            }
        };
        AdverticumService.AddOnGoa3Invocation = function (f) {
            AdverticumService.goa3InvocationEventHandlers.push(f);
        };
        AdverticumService.AddAfterAdvertisementsRendered = function (f) {
            AdverticumService.afterAdvertisementsRenderedEventHandlers.push(f);
        };
        AdverticumService.AfterAdvertisementsRendered = function () {
            for (var i = 0; i < AdverticumService.afterAdvertisementsRenderedEventHandlers.length; i++) {
                AdverticumService.afterAdvertisementsRenderedEventHandlers[i]();
            }
        };
        AdverticumService.OnGoa3Invocation = function (response) {
            for (var i = 0; i < AdverticumService.goa3InvocationEventHandlers.length; i++) {
                AdverticumService.goa3InvocationEventHandlers[i](response);
            }
        };
        AdverticumService.goa3InvocationEventHandlers = [];
        AdverticumService.afterAdvertisementsRenderedEventHandlers = [];
        return AdverticumService;
    }());
    HVG.AdverticumService = AdverticumService;
})(HVG || (HVG = {}));
//# sourceMappingURL=adverticumservice.js.map;
var ApplicationEvent = (function () {
    function ApplicationEvent() {
        this.invocationList = [];
    }
    ApplicationEvent.prototype.bind = function (eventHandler) {
        this.invocationList.push(eventHandler);
    };
    ApplicationEvent.prototype.unbind = function (eventHandler) {
        var eventHandlerIndex = this.invocationList.indexOf(eventHandler);
        if (eventHandlerIndex === -1) {
            return;
        }
        this.invocationList.splice(this.invocationList.indexOf(eventHandler), 1);
    };
    ApplicationEvent.prototype.fire = function (e) {
        for (var i = 0; i < this.invocationList.length; i++) {
            this.invocationList[i](e);
        }
    };
    return ApplicationEvent;
}());
//# sourceMappingURL=applicationevent.js.map;
var Base64 = (function () {
    function Base64() {
    }
    Base64._utf8_encode = function (input) {
        var utftext = "", c, n;
        input = input.replace(/\r\n/g, "\n");
        for (n = 0; n < input.length; n++) {
            c = input.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if ((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    };
    Base64._utf8_decode = function (utftext) {
        var string = "", i = 0, c = 0, c1 = 0, c2 = 0;
        while (i < utftext.length) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if ((c > 191) && (c < 224)) {
                c1 = utftext.charCodeAt(i + 1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;
            }
            else {
                c1 = utftext.charCodeAt(i + 1);
                c2 = utftext.charCodeAt(i + 2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;
            }
        }
        return string;
    };
    Base64.Decode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
        if (input != undefined) {
            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
            while (i < input.length) {
                enc1 = this._keyStr.indexOf(input.charAt(i++));
                enc2 = this._keyStr.indexOf(input.charAt(i++));
                enc3 = this._keyStr.indexOf(input.charAt(i++));
                enc4 = this._keyStr.indexOf(input.charAt(i++));
                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;
                output += String.fromCharCode(chr1);
                if (enc3 !== 64) {
                    output += String.fromCharCode(chr2);
                }
                if (enc4 !== 64) {
                    output += String.fromCharCode(chr3);
                }
            }
        }
        return this._utf8_decode(output);
    };
    Base64.Encode = function (input) {
        var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
        input = this._utf8_encode(input);
        while (i < input.length) {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            }
            else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output += this._keyStr.charAt(enc1);
            output += this._keyStr.charAt(enc2);
            output += this._keyStr.charAt(enc3);
            output += this._keyStr.charAt(enc4);
        }
        return output;
    };
    Base64._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    return Base64;
}());
//# sourceMappingURL=Base64.js.map;
function deferredVoteInit(voteId, currentVoteJson) {
    if (window.jQuery) {
        $(document).ready(function () {
            try {
                if ($.cookie('UserVote') == null) {
                    // nincs cookie, rendereljük a szavazást
                    $("#votecontainer-" + voteId).html(Mustache.to_html($("#votecontrol-mustache-template").html(), { "vote": currentVoteJson }));
                }
                else if ($.cookie('UserVote').includes(voteId)) {
                    // már szavazott, kérjük az eredményt
                    $.ajax({
                        type: 'GET',
                        url: '/vote/vote/' + voteId + '/result'
                    }).done((result) => {
                        $("#votecontainer-" + voteId).html(Mustache.to_html($("#voteresult-mustache-template").html(), { "vote": result }));
                    }).fail((result) => {
                        console.log('error while fetching result for vote: ' + voteId + result);
                    });

                }
                else {
                    // van cookie, de nem szavazott még erre, megjelenítjük a szavazást
                    $("#votecontainer-" + voteId).html(Mustache.to_html($("#votecontrol-mustache-template").html(), { "vote": currentVoteJson }));
                }
            }
            catch (err) {
                console.log('error while rendering vote control: ' + voteId + err.message);
            }
        });
    } else {
        setTimeout(function () { deferredVoteInit(voteId, currentVoteJson) }, 50);
    }
};
(function () {
    'use strict';

    if (!Object.assign) {
        Object.defineProperty(Object, 'assign', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function(target) {
                var arguments$1 = arguments;

                if (target === undefined || target === null) {
                    throw new TypeError('Cannot convert first argument to object');
                }

                var to = Object(target);
                for (var i = 1; i < arguments.length; i++) {
                    var nextSource = arguments$1[i];
                    if (nextSource === undefined || nextSource === null) {
                        continue;
                    }
                    nextSource = Object(nextSource);

                    var keysArray = Object.keys(Object(nextSource));
                    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
                        var nextKey = keysArray[nextIndex];
                        var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
                        if (desc !== undefined && desc.enumerable) {
                            to[nextKey] = nextSource[nextKey];
                        }
                    }
                }
                return to;
            }
        });
    }

    /**
     * @this {Promise}
     */
    function finallyConstructor(callback) {
      var constructor = this.constructor;
      return this.then(
        function(value) {
          // @ts-ignore
          return constructor.resolve(callback()).then(function() {
            return value;
          });
        },
        function(reason) {
          // @ts-ignore
          return constructor.resolve(callback()).then(function() {
            // @ts-ignore
            return constructor.reject(reason);
          });
        }
      );
    }

    // Store setTimeout reference so promise-polyfill will be unaffected by
    // other code modifying setTimeout (like sinon.useFakeTimers())
    var setTimeoutFunc = setTimeout;

    function isArray(x) {
      return Boolean(x && typeof x.length !== 'undefined');
    }

    function noop() {}

    // Polyfill for Function.prototype.bind
    function bind(fn, thisArg) {
      return function() {
        fn.apply(thisArg, arguments);
      };
    }

    /**
     * @constructor
     * @param {Function} fn
     */
    function Promise$1(fn) {
      if (!(this instanceof Promise$1))
        { throw new TypeError('Promises must be constructed via new'); }
      if (typeof fn !== 'function') { throw new TypeError('not a function'); }
      /** @type {!number} */
      this._state = 0;
      /** @type {!boolean} */
      this._handled = false;
      /** @type {Promise|undefined} */
      this._value = undefined;
      /** @type {!Array<!Function>} */
      this._deferreds = [];

      doResolve(fn, this);
    }

    function handle(self, deferred) {
      while (self._state === 3) {
        self = self._value;
      }
      if (self._state === 0) {
        self._deferreds.push(deferred);
        return;
      }
      self._handled = true;
      Promise$1._immediateFn(function() {
        var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
        if (cb === null) {
          (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
          return;
        }
        var ret;
        try {
          ret = cb(self._value);
        } catch (e) {
          reject(deferred.promise, e);
          return;
        }
        resolve(deferred.promise, ret);
      });
    }

    function resolve(self, newValue) {
      try {
        // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
        if (newValue === self)
          { throw new TypeError('A promise cannot be resolved with itself.'); }
        if (
          newValue &&
          (typeof newValue === 'object' || typeof newValue === 'function')
        ) {
          var then = newValue.then;
          if (newValue instanceof Promise$1) {
            self._state = 3;
            self._value = newValue;
            finale(self);
            return;
          } else if (typeof then === 'function') {
            doResolve(bind(then, newValue), self);
            return;
          }
        }
        self._state = 1;
        self._value = newValue;
        finale(self);
      } catch (e) {
        reject(self, e);
      }
    }

    function reject(self, newValue) {
      self._state = 2;
      self._value = newValue;
      finale(self);
    }

    function finale(self) {
      if (self._state === 2 && self._deferreds.length === 0) {
        Promise$1._immediateFn(function() {
          if (!self._handled) {
            Promise$1._unhandledRejectionFn(self._value);
          }
        });
      }

      for (var i = 0, len = self._deferreds.length; i < len; i++) {
        handle(self, self._deferreds[i]);
      }
      self._deferreds = null;
    }

    /**
     * @constructor
     */
    function Handler(onFulfilled, onRejected, promise) {
      this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
      this.onRejected = typeof onRejected === 'function' ? onRejected : null;
      this.promise = promise;
    }

    /**
     * Take a potentially misbehaving resolver function and make sure
     * onFulfilled and onRejected are only called once.
     *
     * Makes no guarantees about asynchrony.
     */
    function doResolve(fn, self) {
      var done = false;
      try {
        fn(
          function(value) {
            if (done) { return; }
            done = true;
            resolve(self, value);
          },
          function(reason) {
            if (done) { return; }
            done = true;
            reject(self, reason);
          }
        );
      } catch (ex) {
        if (done) { return; }
        done = true;
        reject(self, ex);
      }
    }

    Promise$1.prototype['catch'] = function(onRejected) {
      return this.then(null, onRejected);
    };

    Promise$1.prototype.then = function(onFulfilled, onRejected) {
      // @ts-ignore
      var prom = new this.constructor(noop);

      handle(this, new Handler(onFulfilled, onRejected, prom));
      return prom;
    };

    Promise$1.prototype['finally'] = finallyConstructor;

    Promise$1.all = function(arr) {
      return new Promise$1(function(resolve, reject) {
        if (!isArray(arr)) {
          return reject(new TypeError('Promise.all accepts an array'));
        }

        var args = Array.prototype.slice.call(arr);
        if (args.length === 0) { return resolve([]); }
        var remaining = args.length;

        function res(i, val) {
          try {
            if (val && (typeof val === 'object' || typeof val === 'function')) {
              var then = val.then;
              if (typeof then === 'function') {
                then.call(
                  val,
                  function(val) {
                    res(i, val);
                  },
                  reject
                );
                return;
              }
            }
            args[i] = val;
            if (--remaining === 0) {
              resolve(args);
            }
          } catch (ex) {
            reject(ex);
          }
        }

        for (var i = 0; i < args.length; i++) {
          res(i, args[i]);
        }
      });
    };

    Promise$1.resolve = function(value) {
      if (value && typeof value === 'object' && value.constructor === Promise$1) {
        return value;
      }

      return new Promise$1(function(resolve) {
        resolve(value);
      });
    };

    Promise$1.reject = function(value) {
      return new Promise$1(function(resolve, reject) {
        reject(value);
      });
    };

    Promise$1.race = function(arr) {
      return new Promise$1(function(resolve, reject) {
        if (!isArray(arr)) {
          return reject(new TypeError('Promise.race accepts an array'));
        }

        for (var i = 0, len = arr.length; i < len; i++) {
          Promise$1.resolve(arr[i]).then(resolve, reject);
        }
      });
    };

    // Use polyfill for setImmediate for performance gains
    Promise$1._immediateFn =
      // @ts-ignore
      (typeof setImmediate === 'function' &&
        function(fn) {
          // @ts-ignore
          setImmediate(fn);
        }) ||
      function(fn) {
        setTimeoutFunc(fn, 0);
      };

    Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) {
      if (typeof console !== 'undefined' && console) {
        console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
      }
    };

    /** @suppress {undefinedVars} */
    var globalNS = (function() {
      // the only reliable means to get the global object is
      // `Function('return this')()`
      // However, this causes CSP violations in Chrome apps.
      if (typeof self !== 'undefined') {
        return self;
      }
      if (typeof window !== 'undefined') {
        return window;
      }
      if (typeof global !== 'undefined') {
        return global;
      }
      throw new Error('unable to locate global object');
    })();

    if (!('Promise' in globalNS)) {
      globalNS['Promise'] = Promise$1;
    } else if (!globalNS.Promise.prototype['finally']) {
      globalNS.Promise.prototype['finally'] = finallyConstructor;
    }

    var support = {
      searchParams: 'URLSearchParams' in self,
      iterable: 'Symbol' in self && 'iterator' in Symbol,
      blob:
        'FileReader' in self &&
        'Blob' in self &&
        (function() {
          try {
            new Blob();
            return true
          } catch (e) {
            return false
          }
        })(),
      formData: 'FormData' in self,
      arrayBuffer: 'ArrayBuffer' in self
    };

    function isDataView(obj) {
      return obj && DataView.prototype.isPrototypeOf(obj)
    }

    if (support.arrayBuffer) {
      var viewClasses = [
        '[object Int8Array]',
        '[object Uint8Array]',
        '[object Uint8ClampedArray]',
        '[object Int16Array]',
        '[object Uint16Array]',
        '[object Int32Array]',
        '[object Uint32Array]',
        '[object Float32Array]',
        '[object Float64Array]'
      ];

      var isArrayBufferView =
        ArrayBuffer.isView ||
        function(obj) {
          return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
        };
    }

    function normalizeName(name) {
      if (typeof name !== 'string') {
        name = String(name);
      }
      if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
        throw new TypeError('Invalid character in header field name')
      }
      return name.toLowerCase()
    }

    function normalizeValue(value) {
      if (typeof value !== 'string') {
        value = String(value);
      }
      return value
    }

    // Build a destructive iterator for the value list
    function iteratorFor(items) {
      var iterator = {
        next: function() {
          var value = items.shift();
          return {done: value === undefined, value: value}
        }
      };

      if (support.iterable) {
        iterator[Symbol.iterator] = function() {
          return iterator
        };
      }

      return iterator
    }

    function Headers(headers) {
      this.map = {};

      if (headers instanceof Headers) {
        headers.forEach(function(value, name) {
          this.append(name, value);
        }, this);
      } else if (Array.isArray(headers)) {
        headers.forEach(function(header) {
          this.append(header[0], header[1]);
        }, this);
      } else if (headers) {
        Object.getOwnPropertyNames(headers).forEach(function(name) {
          this.append(name, headers[name]);
        }, this);
      }
    }

    Headers.prototype.append = function(name, value) {
      name = normalizeName(name);
      value = normalizeValue(value);
      var oldValue = this.map[name];
      this.map[name] = oldValue ? oldValue + ', ' + value : value;
    };

    Headers.prototype['delete'] = function(name) {
      delete this.map[normalizeName(name)];
    };

    Headers.prototype.get = function(name) {
      name = normalizeName(name);
      return this.has(name) ? this.map[name] : null
    };

    Headers.prototype.has = function(name) {
      return this.map.hasOwnProperty(normalizeName(name))
    };

    Headers.prototype.set = function(name, value) {
      this.map[normalizeName(name)] = normalizeValue(value);
    };

    Headers.prototype.forEach = function(callback, thisArg) {
      for (var name in this.map) {
        if (this.map.hasOwnProperty(name)) {
          callback.call(thisArg, this.map[name], name, this);
        }
      }
    };

    Headers.prototype.keys = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push(name);
      });
      return iteratorFor(items)
    };

    Headers.prototype.values = function() {
      var items = [];
      this.forEach(function(value) {
        items.push(value);
      });
      return iteratorFor(items)
    };

    Headers.prototype.entries = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push([name, value]);
      });
      return iteratorFor(items)
    };

    if (support.iterable) {
      Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
    }

    function consumed(body) {
      if (body.bodyUsed) {
        return Promise.reject(new TypeError('Already read'))
      }
      body.bodyUsed = true;
    }

    function fileReaderReady(reader) {
      return new Promise(function(resolve, reject) {
        reader.onload = function() {
          resolve(reader.result);
        };
        reader.onerror = function() {
          reject(reader.error);
        };
      })
    }

    function readBlobAsArrayBuffer(blob) {
      var reader = new FileReader();
      var promise = fileReaderReady(reader);
      reader.readAsArrayBuffer(blob);
      return promise
    }

    function readBlobAsText(blob) {
      var reader = new FileReader();
      var promise = fileReaderReady(reader);
      reader.readAsText(blob);
      return promise
    }

    function readArrayBufferAsText(buf) {
      var view = new Uint8Array(buf);
      var chars = new Array(view.length);

      for (var i = 0; i < view.length; i++) {
        chars[i] = String.fromCharCode(view[i]);
      }
      return chars.join('')
    }

    function bufferClone(buf) {
      if (buf.slice) {
        return buf.slice(0)
      } else {
        var view = new Uint8Array(buf.byteLength);
        view.set(new Uint8Array(buf));
        return view.buffer
      }
    }

    function Body() {
      this.bodyUsed = false;

      this._initBody = function(body) {
        this._bodyInit = body;
        if (!body) {
          this._bodyText = '';
        } else if (typeof body === 'string') {
          this._bodyText = body;
        } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
          this._bodyBlob = body;
        } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
          this._bodyFormData = body;
        } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
          this._bodyText = body.toString();
        } else if (support.arrayBuffer && support.blob && isDataView(body)) {
          this._bodyArrayBuffer = bufferClone(body.buffer);
          // IE 10-11 can't handle a DataView body.
          this._bodyInit = new Blob([this._bodyArrayBuffer]);
        } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
          this._bodyArrayBuffer = bufferClone(body);
        } else {
          this._bodyText = body = Object.prototype.toString.call(body);
        }

        if (!this.headers.get('content-type')) {
          if (typeof body === 'string') {
            this.headers.set('content-type', 'text/plain;charset=UTF-8');
          } else if (this._bodyBlob && this._bodyBlob.type) {
            this.headers.set('content-type', this._bodyBlob.type);
          } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
            this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
          }
        }
      };

      if (support.blob) {
        this.blob = function() {
          var rejected = consumed(this);
          if (rejected) {
            return rejected
          }

          if (this._bodyBlob) {
            return Promise.resolve(this._bodyBlob)
          } else if (this._bodyArrayBuffer) {
            return Promise.resolve(new Blob([this._bodyArrayBuffer]))
          } else if (this._bodyFormData) {
            throw new Error('could not read FormData body as blob')
          } else {
            return Promise.resolve(new Blob([this._bodyText]))
          }
        };

        this.arrayBuffer = function() {
          if (this._bodyArrayBuffer) {
            return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
          } else {
            return this.blob().then(readBlobAsArrayBuffer)
          }
        };
      }

      this.text = function() {
        var rejected = consumed(this);
        if (rejected) {
          return rejected
        }

        if (this._bodyBlob) {
          return readBlobAsText(this._bodyBlob)
        } else if (this._bodyArrayBuffer) {
          return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
        } else if (this._bodyFormData) {
          throw new Error('could not read FormData body as text')
        } else {
          return Promise.resolve(this._bodyText)
        }
      };

      if (support.formData) {
        this.formData = function() {
          return this.text().then(decode)
        };
      }

      this.json = function() {
        return this.text().then(JSON.parse)
      };

      return this
    }

    // HTTP methods whose capitalization should be normalized
    var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];

    function normalizeMethod(method) {
      var upcased = method.toUpperCase();
      return methods.indexOf(upcased) > -1 ? upcased : method
    }

    function Request(input, options) {
      options = options || {};
      var body = options.body;

      if (input instanceof Request) {
        if (input.bodyUsed) {
          throw new TypeError('Already read')
        }
        this.url = input.url;
        this.credentials = input.credentials;
        if (!options.headers) {
          this.headers = new Headers(input.headers);
        }
        this.method = input.method;
        this.mode = input.mode;
        this.signal = input.signal;
        if (!body && input._bodyInit != null) {
          body = input._bodyInit;
          input.bodyUsed = true;
        }
      } else {
        this.url = String(input);
      }

      this.credentials = options.credentials || this.credentials || 'same-origin';
      if (options.headers || !this.headers) {
        this.headers = new Headers(options.headers);
      }
      this.method = normalizeMethod(options.method || this.method || 'GET');
      this.mode = options.mode || this.mode || null;
      this.signal = options.signal || this.signal;
      this.referrer = null;

      if ((this.method === 'GET' || this.method === 'HEAD') && body) {
        throw new TypeError('Body not allowed for GET or HEAD requests')
      }
      this._initBody(body);
    }

    Request.prototype.clone = function() {
      return new Request(this, {body: this._bodyInit})
    };

    function decode(body) {
      var form = new FormData();
      body
        .trim()
        .split('&')
        .forEach(function(bytes) {
          if (bytes) {
            var split = bytes.split('=');
            var name = split.shift().replace(/\+/g, ' ');
            var value = split.join('=').replace(/\+/g, ' ');
            form.append(decodeURIComponent(name), decodeURIComponent(value));
          }
        });
      return form
    }

    function parseHeaders(rawHeaders) {
      var headers = new Headers();
      // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
      // https://tools.ietf.org/html/rfc7230#section-3.2
      var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
      preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
        var parts = line.split(':');
        var key = parts.shift().trim();
        if (key) {
          var value = parts.join(':').trim();
          headers.append(key, value);
        }
      });
      return headers
    }

    Body.call(Request.prototype);

    function Response(bodyInit, options) {
      if (!options) {
        options = {};
      }

      this.type = 'default';
      this.status = options.status === undefined ? 200 : options.status;
      this.ok = this.status >= 200 && this.status < 300;
      this.statusText = 'statusText' in options ? options.statusText : 'OK';
      this.headers = new Headers(options.headers);
      this.url = options.url || '';
      this._initBody(bodyInit);
    }

    Body.call(Response.prototype);

    Response.prototype.clone = function() {
      return new Response(this._bodyInit, {
        status: this.status,
        statusText: this.statusText,
        headers: new Headers(this.headers),
        url: this.url
      })
    };

    Response.error = function() {
      var response = new Response(null, {status: 0, statusText: ''});
      response.type = 'error';
      return response
    };

    var redirectStatuses = [301, 302, 303, 307, 308];

    Response.redirect = function(url, status) {
      if (redirectStatuses.indexOf(status) === -1) {
        throw new RangeError('Invalid status code')
      }

      return new Response(null, {status: status, headers: {location: url}})
    };

    var DOMException = self.DOMException;
    try {
      new DOMException();
    } catch (err) {
      DOMException = function(message, name) {
        this.message = message;
        this.name = name;
        var error = Error(message);
        this.stack = error.stack;
      };
      DOMException.prototype = Object.create(Error.prototype);
      DOMException.prototype.constructor = DOMException;
    }

    function fetch$1(input, init) {
      return new Promise(function(resolve, reject) {
        var request = new Request(input, init);

        if (request.signal && request.signal.aborted) {
          return reject(new DOMException('Aborted', 'AbortError'))
        }

        var xhr = new XMLHttpRequest();

        function abortXhr() {
          xhr.abort();
        }

        xhr.onload = function() {
          var options = {
            status: xhr.status,
            statusText: xhr.statusText,
            headers: parseHeaders(xhr.getAllResponseHeaders() || '')
          };
          options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
          var body = 'response' in xhr ? xhr.response : xhr.responseText;
          resolve(new Response(body, options));
        };

        xhr.onerror = function() {
          reject(new TypeError('Network request failed'));
        };

        xhr.ontimeout = function() {
          reject(new TypeError('Network request failed'));
        };

        xhr.onabort = function() {
          reject(new DOMException('Aborted', 'AbortError'));
        };

        xhr.open(request.method, request.url, true);

        if (request.credentials === 'include') {
          xhr.withCredentials = true;
        } else if (request.credentials === 'omit') {
          xhr.withCredentials = false;
        }

        if ('responseType' in xhr && support.blob) {
          xhr.responseType = 'blob';
        }

        request.headers.forEach(function(value, name) {
          xhr.setRequestHeader(name, value);
        });

        if (request.signal) {
          request.signal.addEventListener('abort', abortXhr);

          xhr.onreadystatechange = function() {
            // DONE (success or failure)
            if (xhr.readyState === 4) {
              request.signal.removeEventListener('abort', abortXhr);
            }
          };
        }

        xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
      })
    }

    fetch$1.polyfill = true;

    if (!self.fetch) {
      self.fetch = fetch$1;
      self.Headers = Headers;
      self.Request = Request;
      self.Response = Response;
    }

    window.HVGRecommendationEvents = {
        url: null,
        init: function init (url) {
            this.url = url;
        },
        login: {
            send: function send (ref) {
                var browserId = ref.browserId;
                var accountId = ref.accountId;

                return HVGRecommendationEvents._sendEvent({
                    event: 'login',
                    browserId: browserId,
                    payload: {accountId: accountId}
                })
            }
        },
        article: {
            read: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var articleId = ref.articleId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'article.read',
                        browserId: browserId,
                        payload: { articleId: articleId, accountId: accountId }
                    })
                }
            },
            followup: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var articleId = ref.articleId;
                    var length = ref.length;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'article.followup',
                        browserId: browserId,
                        payload: { articleId: articleId, length: length, accountId: accountId }
                    })
                }
            },
            share: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var articleId = ref.articleId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'article.share',
                        browserId: browserId,
                        payload: { articleId: articleId, accountId: accountId }
                    })
                }
            },
            thumbup: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var articleId = ref.articleId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'article.thumbup',
                        browserId: browserId,
                        payload: { articleId: articleId, accountId: accountId }
                    })
                }
            },
            thumbdown: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var articleId = ref.articleId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'article.thumbdown',
                        browserId: browserId,
                        payload: { articleId: articleId, accountId: accountId }
                    })
                }
            }
        },
        author: {
            follow: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var authorId = ref.authorId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'author.follow',
                        browserId: browserId,
                        payload: { authorId: authorId, accountId: accountId }
                    })
                }
            },
            unfollow: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var authorId = ref.authorId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'author.unfollow',
                        browserId: browserId,
                        payload: { authorId: authorId, accountId: accountId }
                    })
                }
            }
        },
        tag: {
            follow: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var tagId = ref.tagId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'tag.follow',
                        browserId: browserId,
                        payload: { tagId: tagId, accountId: accountId }
                    })
                }
            },
            unfollow: {
                send: function send (ref) {
                    var browserId = ref.browserId;
                    var tagId = ref.tagId;
                    var accountId = ref.accountId;

                    return HVGRecommendationEvents._sendEvent({
                        event: 'tag.unfollow',
                        browserId: browserId,
                        payload: { tagId: tagId, accountId: accountId }
                    })
                }
            }
        },
        _sendEvent: function _sendEvent (ref) {
            var event = ref.event;
            var browserId = ref.browserId;
            var payload = ref.payload;

            return fetch(this.url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ event: event, browserId: browserId, timestamp: Date.now(), payload: payload })
            }).then(function (response) {
                return response.status === 201 ? Promise.resolve(response) : Promise.reject(response)
            })
        }
    };

}());
;
function fetchAndSendGa4UserDataIfRequired(ga4ApiBaseUrl, completedCallback) {
	if (window.ga4UserData) {
		console.log('ga4 user data already fetched');
		return;
	}

	$.ajax(ga4ApiBaseUrl + "/ga4/userdata/me",
				{
					type: 'GET',
					contentType: "application/json; charset=utf-8",
					dataType: 'json',
					crossDomain: true,
					xhrFields: {
						withCredentials: true
					}
				})
				.done(function (data, statusText, xhr) {
					try {
						if (xhr.status === 200) {

							if (window.ga4UserData) {
								return;
							}

							window.ga4UserData = data;

							console.log('pushing new user data into ga4 datalayer');
							dataLayer.push({
								'event': data.event,
								'newsletter_status': data.newsletter_status,
								'login_status': data.login_status,
								'subscription': data.subscription
							});
						}
						else if (xhr.status === '304') {
							window.ga4UserData = data;
							console.log('ga user data unchanged');
						}
					}
					catch (err) {
						console.log(err.message);
					}
					finally {
						if (completedCallback) {
							completedCallback();
						}
					}

				});
}

function sendGa4UserId(ga4ApiBaseUrl) {
	$.ajax(ga4ApiBaseUrl + "/ga4/userstatus/me",
				{
					type: 'GET',
					contentType: "application/json; charset=utf-8",
					dataType: 'json',
					crossDomain: true,
					xhrFields: {
						withCredentials: true
					}
				})
				.done(function (data, statusText, xhr) {
					try {
						if (data.isGuest === false) {
							console.log('pushing user id into ga4 datalayer');
							dataLayer.push({
								'event': 'user_id_data',
								'user_id': data.ga4UserId
							});
						}
					}
					catch (err) {
						console.log(err.message);
					}

				});
};
var HVG;
(function (HVG) {
    var ResizeAdvertisements;
    (function (ResizeAdvertisements) {
        function Resize() {
            $(".html5banner").each(function () {
                if ($(window).width() > $(this).data('width')) {
                    $(this).parents(".wrap-ad").css("display", "inline-block");
                }
                else {
                    $(this).parents(".wrap-ad").css("display", "block");
                }
            });
        }
        ResizeAdvertisements.Resize = Resize;
        $(window).resize(function () {
            Resize();
        });
    })(ResizeAdvertisements = HVG.ResizeAdvertisements || (HVG.ResizeAdvertisements = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=resizeadvertisements.js.map;
var CMS;
(function (CMS) {
    var Advertisement;
    (function (Advertisement) {
        var needInit = true;
        function ManageViewPortAwareBanners() {
            if (isBannersVisible()) {
                showBanners();
            }
            window.addEventListener("orientationchange", function () {
                if (isBannersVisible()) {
                    showBanners();
                }
                else {
                    hideBanners();
                }
            }, false);
        }
        Advertisement.ManageViewPortAwareBanners = ManageViewPortAwareBanners;
        ;
        function showBanners() {
            $("div[data-type='ViewportAwareBannerControl']").each(function (i, e) {
                var $control = $(this);
                var zoneId = $control.data("zoneid");
                if (needInit) {
                    $control.attr("id", "zone" + zoneId);
                    $control.addClass("goAdverticum");
                    var g$ = window["goAdverticum3"].getjQuery();
                    g$(this).goa(parseInt(zoneId), {}, function () {
                        HVG.BannerControlManager.HideBannerIfZoneIsEmpty(zoneId);
                    });
                }
                $(".placeholder-ad[data-zoneid='" + zoneId + "']").show();
            });
            needInit = false;
        }
        function hideBanners() {
            $("div[data-type='ViewportAwareBannerControl']").each(function (i, e) {
                var $control = $(this);
                var zoneId = $control.data("zoneid");
                $(".placeholder-ad[data-zoneid='" + zoneId + "']").hide();
            });
        }
        function isBannersVisible() {
            return window.innerWidth > 767;
        }
    })(Advertisement = CMS.Advertisement || (CMS.Advertisement = {}));
})(CMS || (CMS = {}));
//# sourceMappingURL=viewportawarebannercontrol.js.map;
!function (e) { function t() { this.removeEventListener("touchmove", n), this.removeEventListener("touchend", t), c = !1 } function n(n) { if (e.detectSwipe.preventDefault && n.preventDefault(), c) { var i, s = n.touches[0].pageX, u = n.touches[0].pageY, r = o - s, a = h - u; Math.abs(r) >= e.detectSwipe.threshold ? i = r > 0 ? "left" : "right" : Math.abs(a) >= e.detectSwipe.threshold && (i = a > 0 ? "down" : "up"), i && (t.call(this), e(this).trigger("swipe", i).trigger("swipe" + i)) } } function i(e) { 1 == e.touches.length && (o = e.touches[0].pageX, h = e.touches[0].pageY, c = !0, this.addEventListener("touchmove", n, !1), this.addEventListener("touchend", t, !1)) } function s() { this.addEventListener("touchstart", i, !1) } e.detectSwipe = { version: "2.1.1", enabled: "ontouchstart" in document.documentElement, preventDefault: !0, threshold: 20 }; var o, h, c = !1; e.event.special.swipe = { setup: s }, e.each(["left", "up", "down", "right"], function () { e.event.special["swipe" + this] = { setup: function () { e(this).on("swipe", e.noop) } } }) }(jQuery);;
/* 
 * Perspective ad v1.1 beta
 * @author MĂśbius <http://mobiusmobilemarketing.com/>
 * @author AL
 */



/* Modernizr 2.7.1 (Custom Build) | MIT & BSD
 * Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes-load
 */
; window.Modernizr = function (a, b, c) { function z(a) { j.cssText = a } function A(a, b) { return z(m.join(a + ";") + (b || "")) } function B(a, b) { return typeof a === b } function C(a, b) { return !!~("" + a).indexOf(b) } function D(a, b) { for (var d in a) { var e = a[d]; if (!C(e, "-") && j[e] !== c) return b == "pfx" ? e : !0 } return !1 } function E(a, b, d) { for (var e in a) { var f = b[a[e]]; if (f !== c) return d === !1 ? a[e] : B(f, "function") ? f.bind(d || b) : f } return !1 } function F(a, b, c) { var d = a.charAt(0).toUpperCase() + a.slice(1), e = (a + " " + o.join(d + " ") + d).split(" "); return B(b, "string") || B(b, "undefined") ? D(e, b) : (e = (a + " " + p.join(d + " ") + d).split(" "), E(e, b, c)) } var d = "2.7.1", e = {}, f = !0, g = b.documentElement, h = "modernizr", i = b.createElement(h), j = i.style, k, l = {}.toString, m = " -webkit- -moz- -o- -ms- ".split(" "), n = "Webkit Moz O ms", o = n.split(" "), p = n.toLowerCase().split(" "), q = {}, r = {}, s = {}, t = [], u = t.slice, v, w = function (a, c, d, e) { var f, i, j, k, l = b.createElement("div"), m = b.body, n = m || b.createElement("body"); if (parseInt(d, 10)) while (d--) j = b.createElement("div"), j.id = e ? e[d] : h + (d + 1), l.appendChild(j); return f = ["&#173;", '<style id="s', h, '">', a, "</style>"].join(""), l.id = h, (m ? l : n).innerHTML += f, n.appendChild(l), m || (n.style.background = "", n.style.overflow = "hidden", k = g.style.overflow, g.style.overflow = "hidden", g.appendChild(n)), i = c(l, a), m ? l.parentNode.removeChild(l) : (n.parentNode.removeChild(n), g.style.overflow = k), !!i }, x = {}.hasOwnProperty, y; !B(x, "undefined") && !B(x.call, "undefined") ? y = function (a, b) { return x.call(a, b) } : y = function (a, b) { return b in a && B(a.constructor.prototype[b], "undefined") }, Function.prototype.bind || (Function.prototype.bind = function (b) { var c = this; if (typeof c != "function") throw new TypeError; var d = u.call(arguments, 1), e = function () { if (this instanceof e) { var a = function () { }; a.prototype = c.prototype; var f = new a, g = c.apply(f, d.concat(u.call(arguments))); return Object(g) === g ? g : f } return c.apply(b, d.concat(u.call(arguments))) }; return e }), q.csstransforms3d = function () { var a = !!F("perspective"); return a && "webkitPerspective" in g.style && w("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}", function (b, c) { a = b.offsetLeft === 9 && b.offsetHeight === 3 }), a }, q.csstransitions = function () { return F("transition") }; for (var G in q) y(q, G) && (v = G.toLowerCase(), e[v] = q[G](), t.push((e[v] ? "" : "no-") + v)); return e.addTest = function (a, b) { if (typeof a == "object") for (var d in a) y(a, d) && e.addTest(d, a[d]); else { a = a.toLowerCase(); if (e[a] !== c) return e; b = typeof b == "function" ? b() : b, typeof f != "undefined" && f && (g.className += " " + (b ? "" : "no-") + a), e[a] = b } return e }, z(""), i = k = null, function (a, b) { function l(a, b) { var c = a.createElement("p"), d = a.getElementsByTagName("head")[0] || a.documentElement; return c.innerHTML = "x<style>" + b + "</style>", d.insertBefore(c.lastChild, d.firstChild) } function m() { var a = s.elements; return typeof a == "string" ? a.split(" ") : a } function n(a) { var b = j[a[h]]; return b || (b = {}, i++, a[h] = i, j[i] = b), b } function o(a, c, d) { c || (c = b); if (k) return c.createElement(a); d || (d = n(c)); var g; return d.cache[a] ? g = d.cache[a].cloneNode() : f.test(a) ? g = (d.cache[a] = d.createElem(a)).cloneNode() : g = d.createElem(a), g.canHaveChildren && !e.test(a) && !g.tagUrn ? d.frag.appendChild(g) : g } function p(a, c) { a || (a = b); if (k) return a.createDocumentFragment(); c = c || n(a); var d = c.frag.cloneNode(), e = 0, f = m(), g = f.length; for (; e < g; e++) d.createElement(f[e]); return d } function q(a, b) { b.cache || (b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()), a.createElement = function (c) { return s.shivMethods ? o(c, a, b) : b.createElem(c) }, a.createDocumentFragment = Function("h,f", "return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(" + m().join().replace(/[\w\-]+/g, function (a) { return b.createElem(a), b.frag.createElement(a), 'c("' + a + '")' }) + ");return n}")(s, b.frag) } function r(a) { a || (a = b); var c = n(a); return s.shivCSS && !g && !c.hasCSS && (c.hasCSS = !!l(a, "article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")), k || q(a, c), a } var c = "3.7.0", d = a.html5 || {}, e = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, f = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, g, h = "_html5shiv", i = 0, j = {}, k; (function () { try { var a = b.createElement("a"); a.innerHTML = "<xyz></xyz>", g = "hidden" in a, k = a.childNodes.length == 1 || function () { b.createElement("a"); var a = b.createDocumentFragment(); return typeof a.cloneNode == "undefined" || typeof a.createDocumentFragment == "undefined" || typeof a.createElement == "undefined" }() } catch (c) { g = !0, k = !0 } })(); var s = { elements: d.elements || "abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video", version: c, shivCSS: d.shivCSS !== !1, supportsUnknownElements: k, shivMethods: d.shivMethods !== !1, type: "default", shivDocument: r, createElement: o, createDocumentFragment: p }; a.html5 = s, r(b) }(this, b), e._version = d, e._prefixes = m, e._domPrefixes = p, e._cssomPrefixes = o, e.testProp = function (a) { return D([a]) }, e.testAllProps = F, e.testStyles = w, e.prefixed = function (a, b, c) { return b ? F(a, b, c) : F(a, "pfx") }, g.className = g.className.replace(/(^|\s)no-js(\s|$)/, "$1$2") + (f ? " js " + t.join(" ") : ""), e }(this, this.document), function (a, b, c) { function d(a) { return "[object Function]" == o.call(a) } function e(a) { return "string" == typeof a } function f() { } function g(a) { return !a || "loaded" == a || "complete" == a || "uninitialized" == a } function h() { var a = p.shift(); q = 1, a ? a.t ? m(function () { ("c" == a.t ? B.injectCss : B.injectJs)(a.s, 0, a.a, a.x, a.e, 1) }, 0) : (a(), h()) : q = 0 } function i(a, c, d, e, f, i, j) { function k(b) { if (!o && g(l.readyState) && (u.r = o = 1, !q && h(), l.onload = l.onreadystatechange = null, b)) { "img" != a && m(function () { t.removeChild(l) }, 50); for (var d in y[c]) y[c].hasOwnProperty(d) && y[c][d].onload() } } var j = j || B.errorTimeout, l = b.createElement(a), o = 0, r = 0, u = { t: d, s: c, e: f, a: i, x: j }; 1 === y[c] && (r = 1, y[c] = []), "object" == a ? l.data = c : (l.src = c, l.type = a), l.width = l.height = "0", l.onerror = l.onload = l.onreadystatechange = function () { k.call(this, r) }, p.splice(e, 0, u), "img" != a && (r || 2 === y[c] ? (t.insertBefore(l, s ? null : n), m(k, j)) : y[c].push(l)) } function j(a, b, c, d, f) { return q = 0, b = b || "j", e(a) ? i("c" == b ? v : u, a, b, this.i++, c, d, f) : (p.splice(this.i++, 0, a), 1 == p.length && h()), this } function k() { var a = B; return a.loader = { load: j, i: 0 }, a } var l = b.documentElement, m = a.setTimeout, n = b.getElementsByTagName("script")[0], o = {}.toString, p = [], q = 0, r = "MozAppearance" in l.style, s = r && !!b.createRange().compareNode, t = s ? l : n.parentNode, l = a.opera && "[object Opera]" == o.call(a.opera), l = !!b.attachEvent && !l, u = r ? "object" : l ? "script" : "img", v = l ? "script" : u, w = Array.isArray || function (a) { return "[object Array]" == o.call(a) }, x = [], y = {}, z = { timeout: function (a, b) { return b.length && (a.timeout = b[0]), a } }, A, B; B = function (a) { function b(a) { var a = a.split("!"), b = x.length, c = a.pop(), d = a.length, c = { url: c, origUrl: c, prefixes: a }, e, f, g; for (f = 0; f < d; f++) g = a[f].split("="), (e = z[g.shift()]) && (c = e(c, g)); for (f = 0; f < b; f++) c = x[f](c); return c } function g(a, e, f, g, h) { var i = b(a), j = i.autoCallback; i.url.split(".").pop().split("?").shift(), i.bypass || (e && (e = d(e) ? e : e[a] || e[g] || e[a.split("/").pop().split("?")[0]]), i.instead ? i.instead(a, e, f, g, h) : (y[i.url] ? i.noexec = !0 : y[i.url] = 1, f.load(i.url, i.forceCSS || !i.forceJS && "css" == i.url.split(".").pop().split("?").shift() ? "c" : c, i.noexec, i.attrs, i.timeout), (d(e) || d(j)) && f.load(function () { k(), e && e(i.origUrl, h, g), j && j(i.origUrl, h, g), y[i.url] = 2 }))) } function h(a, b) { function c(a, c) { if (a) { if (e(a)) c || (j = function () { var a = [].slice.call(arguments); k.apply(this, a), l() }), g(a, j, b, 0, h); else if (Object(a) === a) for (n in m = function () { var b = 0, c; for (c in a) a.hasOwnProperty(c) && b++; return b }(), a) a.hasOwnProperty(n) && (!c && !--m && (d(j) ? j = function () { var a = [].slice.call(arguments); k.apply(this, a), l() } : j[n] = function (a) { return function () { var b = [].slice.call(arguments); a && a.apply(this, b), l() } }(k[n])), g(a[n], j, b, n, h)) } else !c && l() } var h = !!a.test, i = a.load || a.both, j = a.callback || f, k = j, l = a.complete || f, m, n; c(h ? a.yep : a.nope, !!i), i && c(i) } var i, j, l = this.yepnope.loader; if (e(a)) g(a, 0, l, 0); else if (w(a)) for (i = 0; i < a.length; i++) j = a[i], e(j) ? g(j, 0, l, 0) : w(j) ? B(j) : Object(j) === j && h(j, l); else Object(a) === a && h(a, l) }, B.addPrefix = function (a, b) { z[a] = b }, B.addFilter = function (a) { x.push(a) }, B.errorTimeout = 1e4, null == b.readyState && b.addEventListener && (b.readyState = "loading", b.addEventListener("DOMContentLoaded", A = function () { b.removeEventListener("DOMContentLoaded", A, 0), b.readyState = "complete" }, 0)), a.yepnope = k(), a.yepnope.executeStack = h, a.yepnope.injectJs = function (a, c, d, e, i, j) { var k = b.createElement("script"), l, o, e = e || B.errorTimeout; k.src = a; for (o in d) k.setAttribute(o, d[o]); c = j ? h : c || f, k.onreadystatechange = k.onload = function () { !l && g(k.readyState) && (l = 1, c(), k.onload = k.onreadystatechange = null) }, m(function () { l || (l = 1, c(1)) }, e), i ? k.onload() : n.parentNode.insertBefore(k, n) }, a.yepnope.injectCss = function (a, c, d, e, g, i) { var e = b.createElement("link"), j, c = i ? h : c || f; e.href = a, e.rel = "stylesheet", e.type = "text/css"; for (j in d) e.setAttribute(j, d[j]); g || (n.parentNode.insertBefore(e, n), m(c, 0)) } }(this, document), Modernizr.load = function () { yepnope.apply(window, [].slice.call(arguments, 0)) };



/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject = function () { var D = "undefined", r = "object", S = "Shockwave Flash", W = "ShockwaveFlash.ShockwaveFlash", q = "application/x-shockwave-flash", R = "SWFObjectExprInst", x = "onreadystatechange", O = window, j = document, t = navigator, T = false, U = [h], o = [], N = [], I = [], l, Q, E, B, J = false, a = false, n, G, m = true, M = function () { var aa = typeof j.getElementById != D && typeof j.getElementsByTagName != D && typeof j.createElement != D, ah = t.userAgent.toLowerCase(), Y = t.platform.toLowerCase(), ae = Y ? /win/.test(Y) : /win/.test(ah), ac = Y ? /mac/.test(Y) : /mac/.test(ah), af = /webkit/.test(ah) ? parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, X = !+"\v1", ag = [0, 0, 0], ab = null; if (typeof t.plugins != D && typeof t.plugins[S] == r) { ab = t.plugins[S].description; if (ab && !(typeof t.mimeTypes != D && t.mimeTypes[q] && !t.mimeTypes[q].enabledPlugin)) { T = true; X = false; ab = ab.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); ag[0] = parseInt(ab.replace(/^(.*)\..*$/, "$1"), 10); ag[1] = parseInt(ab.replace(/^.*\.(.*)\s.*$/, "$1"), 10); ag[2] = /[a-zA-Z]/.test(ab) ? parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0 } } else { if (typeof O.ActiveXObject != D) { try { var ad = new ActiveXObject(W); if (ad) { ab = ad.GetVariable("$version"); if (ab) { X = true; ab = ab.split(" ")[1].split(","); ag = [parseInt(ab[0], 10), parseInt(ab[1], 10), parseInt(ab[2], 10)] } } } catch (Z) { } } } return { w3: aa, pv: ag, wk: af, ie: X, win: ae, mac: ac } }(), k = function () { if (!M.w3) { return } if ((typeof j.readyState != D && j.readyState == "complete") || (typeof j.readyState == D && (j.getElementsByTagName("body")[0] || j.body))) { f() } if (!J) { if (typeof j.addEventListener != D) { j.addEventListener("DOMContentLoaded", f, false) } if (M.ie && M.win) { j.attachEvent(x, function () { if (j.readyState == "complete") { j.detachEvent(x, arguments.callee); f() } }); if (O == top) { (function () { if (J) { return } try { j.documentElement.doScroll("left") } catch (X) { setTimeout(arguments.callee, 0); return } f() })() } } if (M.wk) { (function () { if (J) { return } if (!/loaded|complete/.test(j.readyState)) { setTimeout(arguments.callee, 0); return } f() })() } s(f) } }(); function f() { if (J) { return } try { var Z = j.getElementsByTagName("body")[0].appendChild(C("span")); Z.parentNode.removeChild(Z) } catch (aa) { return } J = true; var X = U.length; for (var Y = 0; Y < X; Y++) { U[Y]() } } function K(X) { if (J) { X() } else { U[U.length] = X } } function s(Y) { if (typeof O.addEventListener != D) { O.addEventListener("load", Y, false) } else { if (typeof j.addEventListener != D) { j.addEventListener("load", Y, false) } else { if (typeof O.attachEvent != D) { i(O, "onload", Y) } else { if (typeof O.onload == "function") { var X = O.onload; O.onload = function () { X(); Y() } } else { O.onload = Y } } } } } function h() { if (T) { V() } else { H() } } function V() { var X = j.getElementsByTagName("body")[0]; var aa = C(r); aa.setAttribute("type", q); var Z = X.appendChild(aa); if (Z) { var Y = 0; (function () { if (typeof Z.GetVariable != D) { var ab = Z.GetVariable("$version"); if (ab) { ab = ab.split(" ")[1].split(","); M.pv = [parseInt(ab[0], 10), parseInt(ab[1], 10), parseInt(ab[2], 10)] } } else { if (Y < 10) { Y++; setTimeout(arguments.callee, 10); return } } X.removeChild(aa); Z = null; H() })() } else { H() } } function H() { var ag = o.length; if (ag > 0) { for (var af = 0; af < ag; af++) { var Y = o[af].id; var ab = o[af].callbackFn; var aa = { success: false, id: Y }; if (M.pv[0] > 0) { var ae = c(Y); if (ae) { if (F(o[af].swfVersion) && !(M.wk && M.wk < 312)) { w(Y, true); if (ab) { aa.success = true; aa.ref = z(Y); ab(aa) } } else { if (o[af].expressInstall && A()) { var ai = {}; ai.data = o[af].expressInstall; ai.width = ae.getAttribute("width") || "0"; ai.height = ae.getAttribute("height") || "0"; if (ae.getAttribute("class")) { ai.styleclass = ae.getAttribute("class") } if (ae.getAttribute("align")) { ai.align = ae.getAttribute("align") } var ah = {}; var X = ae.getElementsByTagName("param"); var ac = X.length; for (var ad = 0; ad < ac; ad++) { if (X[ad].getAttribute("name").toLowerCase() != "movie") { ah[X[ad].getAttribute("name")] = X[ad].getAttribute("value") } } P(ai, ah, Y, ab) } else { p(ae); if (ab) { ab(aa) } } } } } else { w(Y, true); if (ab) { var Z = z(Y); if (Z && typeof Z.SetVariable != D) { aa.success = true; aa.ref = Z } ab(aa) } } } } } function z(aa) { var X = null; var Y = c(aa); if (Y && Y.nodeName == "OBJECT") { if (typeof Y.SetVariable != D) { X = Y } else { var Z = Y.getElementsByTagName(r)[0]; if (Z) { X = Z } } } return X } function A() { return !a && F("6.0.65") && (M.win || M.mac) && !(M.wk && M.wk < 312) } function P(aa, ab, X, Z) { a = true; E = Z || null; B = { success: false, id: X }; var ae = c(X); if (ae) { if (ae.nodeName == "OBJECT") { l = g(ae); Q = null } else { l = ae; Q = X } aa.id = R; if (typeof aa.width == D || (!/%$/.test(aa.width) && parseInt(aa.width, 10) < 310)) { aa.width = "310" } if (typeof aa.height == D || (!/%$/.test(aa.height) && parseInt(aa.height, 10) < 137)) { aa.height = "137" } j.title = j.title.slice(0, 47) + " - Flash Player Installation"; var ad = M.ie && M.win ? "ActiveX" : "PlugIn", ac = "MMredirectURL=" + O.location.toString().replace(/&/g, "%26") + "&MMplayerType=" + ad + "&MMdoctitle=" + j.title; if (typeof ab.flashvars != D) { ab.flashvars += "&" + ac } else { ab.flashvars = ac } if (M.ie && M.win && ae.readyState != 4) { var Y = C("div"); X += "SWFObjectNew"; Y.setAttribute("id", X); ae.parentNode.insertBefore(Y, ae); ae.style.display = "none"; (function () { if (ae.readyState == 4) { ae.parentNode.removeChild(ae) } else { setTimeout(arguments.callee, 10) } })() } u(aa, ab, X) } } function p(Y) { if (M.ie && M.win && Y.readyState != 4) { var X = C("div"); Y.parentNode.insertBefore(X, Y); X.parentNode.replaceChild(g(Y), X); Y.style.display = "none"; (function () { if (Y.readyState == 4) { Y.parentNode.removeChild(Y) } else { setTimeout(arguments.callee, 10) } })() } else { Y.parentNode.replaceChild(g(Y), Y) } } function g(ab) { var aa = C("div"); if (M.win && M.ie) { aa.innerHTML = ab.innerHTML } else { var Y = ab.getElementsByTagName(r)[0]; if (Y) { var ad = Y.childNodes; if (ad) { var X = ad.length; for (var Z = 0; Z < X; Z++) { if (!(ad[Z].nodeType == 1 && ad[Z].nodeName == "PARAM") && !(ad[Z].nodeType == 8)) { aa.appendChild(ad[Z].cloneNode(true)) } } } } } return aa } function u(ai, ag, Y) { var X, aa = c(Y); if (M.wk && M.wk < 312) { return X } if (aa) { if (typeof ai.id == D) { ai.id = Y } if (M.ie && M.win) { var ah = ""; for (var ae in ai) { if (ai[ae] != Object.prototype[ae]) { if (ae.toLowerCase() == "data") { ag.movie = ai[ae] } else { if (ae.toLowerCase() == "styleclass") { ah += ' class="' + ai[ae] + '"' } else { if (ae.toLowerCase() != "classid") { ah += " " + ae + '="' + ai[ae] + '"' } } } } } var af = ""; for (var ad in ag) { if (ag[ad] != Object.prototype[ad]) { af += '<param name="' + ad + '" value="' + ag[ad] + '" />' } } aa.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + ah + ">" + af + "</object>"; N[N.length] = ai.id; X = c(ai.id) } else { var Z = C(r); Z.setAttribute("type", q); for (var ac in ai) { if (ai[ac] != Object.prototype[ac]) { if (ac.toLowerCase() == "styleclass") { Z.setAttribute("class", ai[ac]) } else { if (ac.toLowerCase() != "classid") { Z.setAttribute(ac, ai[ac]) } } } } for (var ab in ag) { if (ag[ab] != Object.prototype[ab] && ab.toLowerCase() != "movie") { e(Z, ab, ag[ab]) } } aa.parentNode.replaceChild(Z, aa); X = Z } } return X } function e(Z, X, Y) { var aa = C("param"); aa.setAttribute("name", X); aa.setAttribute("value", Y); Z.appendChild(aa) } function y(Y) { var X = c(Y); if (X && X.nodeName == "OBJECT") { if (M.ie && M.win) { X.style.display = "none"; (function () { if (X.readyState == 4) { b(Y) } else { setTimeout(arguments.callee, 10) } })() } else { X.parentNode.removeChild(X) } } } function b(Z) { var Y = c(Z); if (Y) { for (var X in Y) { if (typeof Y[X] == "function") { Y[X] = null } } Y.parentNode.removeChild(Y) } } function c(Z) { var X = null; try { X = j.getElementById(Z) } catch (Y) { } return X } function C(X) { return j.createElement(X) } function i(Z, X, Y) { Z.attachEvent(X, Y); I[I.length] = [Z, X, Y] } function F(Z) { var Y = M.pv, X = Z.split("."); X[0] = parseInt(X[0], 10); X[1] = parseInt(X[1], 10) || 0; X[2] = parseInt(X[2], 10) || 0; return (Y[0] > X[0] || (Y[0] == X[0] && Y[1] > X[1]) || (Y[0] == X[0] && Y[1] == X[1] && Y[2] >= X[2])) ? true : false } function v(ac, Y, ad, ab) { if (M.ie && M.mac) { return } var aa = j.getElementsByTagName("head")[0]; if (!aa) { return } var X = (ad && typeof ad == "string") ? ad : "screen"; if (ab) { n = null; G = null } if (!n || G != X) { var Z = C("style"); Z.setAttribute("type", "text/css"); Z.setAttribute("media", X); n = aa.appendChild(Z); if (M.ie && M.win && typeof j.styleSheets != D && j.styleSheets.length > 0) { n = j.styleSheets[j.styleSheets.length - 1] } G = X } if (M.ie && M.win) { if (n && typeof n.addRule == r) { n.addRule(ac, Y) } } else { if (n && typeof j.createTextNode != D) { n.appendChild(j.createTextNode(ac + " {" + Y + "}")) } } } function w(Z, X) { if (!m) { return } var Y = X ? "visible" : "hidden"; if (J && c(Z)) { c(Z).style.visibility = Y } else { v("#" + Z, "visibility:" + Y) } } function L(Y) { var Z = /[\\\"<>\.;]/; var X = Z.exec(Y) != null; return X && typeof encodeURIComponent != D ? encodeURIComponent(Y) : Y } var d = function () { if (M.ie && M.win) { window.attachEvent("onunload", function () { var ac = I.length; for (var ab = 0; ab < ac; ab++) { I[ab][0].detachEvent(I[ab][1], I[ab][2]) } var Z = N.length; for (var aa = 0; aa < Z; aa++) { y(N[aa]) } for (var Y in M) { M[Y] = null } M = null; for (var X in swfobject) { swfobject[X] = null } swfobject = null }) } }(); return { registerObject: function (ab, X, aa, Z) { if (M.w3 && ab && X) { var Y = {}; Y.id = ab; Y.swfVersion = X; Y.expressInstall = aa; Y.callbackFn = Z; o[o.length] = Y; w(ab, false) } else { if (Z) { Z({ success: false, id: ab }) } } }, getObjectById: function (X) { if (M.w3) { return z(X) } }, embedSWF: function (ab, ah, ae, ag, Y, aa, Z, ad, af, ac) { var X = { success: false, id: ah }; if (M.w3 && !(M.wk && M.wk < 312) && ab && ah && ae && ag && Y) { w(ah, false); K(function () { ae += ""; ag += ""; var aj = {}; if (af && typeof af === r) { for (var al in af) { aj[al] = af[al] } } aj.data = ab; aj.width = ae; aj.height = ag; var am = {}; if (ad && typeof ad === r) { for (var ak in ad) { am[ak] = ad[ak] } } if (Z && typeof Z === r) { for (var ai in Z) { if (typeof am.flashvars != D) { am.flashvars += "&" + ai + "=" + Z[ai] } else { am.flashvars = ai + "=" + Z[ai] } } } if (F(Y)) { var an = u(aj, am, ah); if (aj.id == ah) { w(ah, true) } X.success = true; X.ref = an } else { if (aa && A()) { aj.data = aa; P(aj, am, ah, ac); return } else { w(ah, true) } } if (ac) { ac(X) } }) } else { if (ac) { ac(X) } } }, switchOffAutoHideShow: function () { m = false }, ua: M, getFlashPlayerVersion: function () { return { major: M.pv[0], minor: M.pv[1], release: M.pv[2] } }, hasFlashPlayerVersion: F, createSWF: function (Z, Y, X) { if (M.w3) { return u(Z, Y, X) } else { return undefined } }, showExpressInstall: function (Z, aa, X, Y) { if (M.w3 && A()) { P(Z, aa, X, Y) } }, removeSWF: function (X) { if (M.w3) { y(X) } }, createCSS: function (aa, Z, Y, X) { if (M.w3) { v(aa, Z, Y, X) } }, addDomLoadEvent: K, addLoadEvent: s, getQueryParamValue: function (aa) { var Z = j.location.search || j.location.hash; if (Z) { if (/\?/.test(Z)) { Z = Z.split("?")[1] } if (aa == null) { return L(Z) } var Y = Z.split("&"); for (var X = 0; X < Y.length; X++) { if (Y[X].substring(0, Y[X].indexOf("=")) == aa) { return L(Y[X].substring((Y[X].indexOf("=") + 1))) } } } return "" }, expressInstallCallback: function () { if (a) { var X = c(R); if (X && l) { X.parentNode.replaceChild(l, X); if (Q) { w(Q, true); if (M.ie && M.win) { l.style.display = "block" } } if (E) { E(B) } } a = false } } } }();



function checStarterURL(starterContent) {
	return (starterContent.match(/\.(jpeg|jpg|gif|png)$/) !== null);
}
function scrollY() {
	return window.pageYOffset || docElem.scrollTop;
}


var globalStarter = [],
    perspectiveWrapper = $('.perspective-wrapper'),
    container = $('.container'),
    docElem = window.document.documentElement,
    support = Modernizr.csstransitions,
    transEndEventNames = {
    	'WebkitTransition': 'webkitTransitionEnd',
    	'MozTransition': 'transitionend',
    	'OTransition': 'oTransitionEnd',
    	'msTransition': 'MSTransitionEnd',
    	'transition': 'transitionend'
    },
    transEndEventName = transEndEventNames[Modernizr.prefixed('transition')],
    docscroll = 0,
    contentWrapper = $('.wrapper');


window.onGoa3Event = function (jQueryEvent, goa3Event) {

	zoneInfo = $.grep(globalStarter, function (e) {
		return e.zoneId === goa3Event.zone.id;
	});
	if (zoneInfo.length) {

		zoneInfo = zoneInfo[0];
		zoneInfo.startZone = $('#start-' + zoneInfo.zoneId);
		zoneInfo.parentZoneID = 'perspective-' + zoneInfo.zoneId;
		zoneInfo.zoneWidth = goa3Event.zone.width;
		zoneInfo.zoneHeight = goa3Event.zone.height;


		starterContentfilename = zoneInfo.startZone[0]['innerHTML'].substring(zoneInfo.startZone[0]['innerHTML'].lastIndexOf('/') + 1);
		isStarterImg = checStarterURL(zoneInfo.startZone[0]['innerHTML']);

		if (isStarterImg) {
			zoneInfo.startZone.html('<img src="' + zoneInfo.startZone[0]['innerHTML'] + '"/>');
		} else {
			adSwfUrl = zoneInfo.startZone[0]['innerHTML'];
			zoneInfo.startZone.html('<span id="flash-' + zoneInfo.zoneId + '"/><span class="flash-overlay"></span>');
			swfobject.embedSWF(adSwfUrl, "flash-" + zoneInfo.zoneId, zoneInfo.zoneWidth, zoneInfo.zoneHeight, "9.0.0", null, null, null, { wmode: 'opaque' });
		}
		$('<iframe src="" frameborder="0" scrolling="no" data-counter-zone-id="' + zoneInfo.zoneId + '" id="ctcounter-' + zoneInfo.zoneId + '"></iframe>').appendTo('body');

		if (zoneInfo.autoplay === 1) {

			autoCookie = zoneInfo.autoPlayInt * 24 / zoneInfo.autoPlayCount;
			cookieVal = "autoOpen-" + zoneInfo.zoneId;

			if ($.cookie(cookieVal) || zoneInfo.autoPlayCount === 0 || zoneInfo.autoPlayInt === 0) {
				zoneInfo.autoplayStart = 0;
				zoneInfo.autoplay = 0;
			} else {
				var cookieDate = new Date();
				cookieDate.setTime(cookieDate.getTime() + (autoCookie * 60 * 60 * 1000));
				$.cookie("autoOpen-" + zoneInfo.zoneId, true, { expires: cookieDate, path: '/' });
			}
		} else {
			zoneInfo.autoplayStart = 0;
		}
		zoneInfo.startZone.adPerspective({
			target: '#creative-' + zoneInfo.targetId,
			orientation: zoneInfo.targetOrientation,
			animSpeed: zoneInfo.animSpeed,
			autoplay: zoneInfo.autoplay,
			trigger: zoneInfo.trigger,
			autoplayClose: zoneInfo.autoplayClose,
			autoplayStart: zoneInfo.autoplayStart,
			opacity: zoneInfo.opacity,
			loaded: 0,
			zoneInfo: zoneInfo
		});
	}
};



(function ($) {

	$.fn.bgLoaded = function (custom) {

		var self = this;

		// Default plugin settings
		var defaults = {
			afterLoaded: function () {
				this.addClass('bg-loaded');
			}
		};

		// Merge default and user settings
		var settings = $.extend({}, defaults, custom);

		// Loop through element
		self.each(function () {
			var $this = $(this),
                    bgImgs = $this.css('background-image').split(', ');
			$this.data('loaded-count', 0);

			$.each(bgImgs, function (key, value) {
				var img = value.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
				$('<img/>').attr('src', img).load(function () {
					$(this).remove(); // prevent memory leaks
					$this.data('loaded-count', $this.data('loaded-count') + 1);
					if ($this.data('loaded-count') >= bgImgs.length) {
						settings.afterLoaded.call($this);
					}
				});
			});

		});
	};

	$.fn.adPerspective = function (options) {

		var zoneSettings = $.extend({}, $.fn.adPerspective.defaults, options);
		zoneSettings.zoneInfo.targetIframe = $("iframe[data-counter-zone-id='" + zoneSettings.zoneInfo.zoneId + "']");

		if (zoneSettings.autoplay === 1) {
			setTimeout(function () {
				adOpenEvent(zoneSettings);
			}, zoneSettings.zoneInfo.autoplayStart);
		}

		if (zoneSettings.trigger === 'mouseenter') {
			$(this).append('<span id="hover-countdown" data-count="3"></span>');
			var intervalID;
			var count = 3;
			function targetHover() {
				count = count - 1;
				if (count === 0) {
					adOpenEvent(zoneSettings);
					count = 3;
					$('#hover-countdown').removeClass('counting');
				}
				$('#hover-countdown').attr('data-count', count);
			}
			;
			this.hover(function () {
				$('#hover-countdown').addClass('counting');
				intervalID = setInterval(targetHover, 1000);
			},
                    function () {
                    	count = 3;
                    	$('#hover-countdown').removeClass('counting');
                    	$('#hover-countdown').attr('data-count', count);
                    	window.clearInterval(intervalID);
                    });

		} else if (zoneSettings.trigger === 'click') {

			this.on('click', function () {
				adOpenEvent(zoneSettings);
			});

		}

	};

	function countCt(ctUrl, targetIframe) {
		targetIframe.attr('src', '');
		targetIframe.attr('src', ctUrl);
	}

	function closePerspectiveEvent(e) {
		e.preventDefault();
		if (e.target.className === 'container') {
			countCt(e.data.ctUrl, e.data.targetIframe);

		} else if (e.delegateTarget.className === 'close-popup' && e.target.offsetParent.offsetParent.id === 'creative-' + e.data.targetId) {
			countCt(e.data.ctUrl, e.data.targetIframe);
		}
		closePerspective();
	}
	function adOpenEvent(zoneSettings) {



		function loadTargetZone(zoneInfo) {

			var checkExist = setInterval(function () {
				if ($('#creative-' + zoneInfo.targetId).length) {
					zoneSettings.loaded = 1;
					backgroundImageUrl = $(zoneSettings.target).data('background');
					$(zoneSettings.target).attr('data-orientation', zoneSettings.orientation).attr('data-effect', zoneSettings.effect).addClass('active-template').show();
					perspectiveWrapper.attr('data-speed', zoneSettings.animSpeed);
					$(zoneSettings.target).css('background-image', 'url(' + backgroundImageUrl + ')');
					$(zoneSettings.target).bgLoaded({
						afterLoaded: function () {
							openCycle();
							$(this).addClass('bg-loaded');
						}
					});
					clearInterval(checkExist);
				}
			}, 100);

		}

		function openCycle() {

			if (zoneSettings.zoneInfo.autoplay === 1) {
				countCt(zoneSettings.zoneInfo.ctAutoOpen, zoneSettings.zoneInfo.targetIframe);
				zoneSettings.zoneInfo.autoplay = 0;
				setTimeout(function () {
					closePerspective();
				}, zoneSettings.zoneInfo.autoplayClose);
			} else {
				countCt(zoneSettings.zoneInfo.ctOpen, zoneSettings.zoneInfo.targetIframe);
			}

			$(zoneSettings.target).addClass('ad-active');
			docscroll = scrollY();
			contentWrapper.css('top', docscroll * -1 + 'px');
			document.body.scrollTop = document.documentElement.scrollTop = 0;
			perspectiveWrapper.addClass('modalview').addClass('advorient-' + zoneSettings.orientation);
			setTimeout(function () {
				perspectiveWrapper.addClass('animate');
			}, 25);
			setTimeout(function () {
				container.css('opacity', zoneSettings.opacity);
			}, 60);

			container.on('click.container', {
				ctUrl: zoneSettings.zoneInfo.ctClose,
				targetIframe: zoneSettings.zoneInfo.targetIframe,
				zoneId: zoneSettings.zoneInfo.zoneId,
				targetId: zoneSettings.zoneInfo.targetId
			}, closePerspectiveEvent);

			$('.close-popup').on('click.close', {
				ctUrl: zoneSettings.zoneInfo.ctCloseBtn,
				targetIframe: zoneSettings.zoneInfo.targetIframe,
				zoneId: zoneSettings.zoneInfo.zoneId,
				targetId: zoneSettings.zoneInfo.targetId
			}, closePerspectiveEvent);

		}


		window.goAdverticum3.onReady(function (goa3) {
			if (zoneSettings.loaded !== 0) {
				$("#" + zoneSettings.zoneInfo.parentZoneID).remove();
			}
			$("#perspective").append("<div id='" + zoneSettings.zoneInfo.parentZoneID + "'></div>");
			goa3.getjQuery()('#' + zoneSettings.zoneInfo.parentZoneID).goa(zoneSettings.zoneInfo.targetId, {}, loadTargetZone(zoneSettings.zoneInfo));
		});

	}


	function closePerspective() {
		if (perspectiveWrapper.hasClass('animate')) {
			var onEndTransFn = function (event) {
				if (support && (event.target.className !== 'container' || event.originalEvent.propertyName.indexOf('transform') === -1))
					return;
				$(this).off(transEndEventName, onEndTransFn);
				perspectiveWrapper.attr('class', 'perspective-wrapper');
				document.body.scrollTop = document.documentElement.scrollTop = docscroll;
				contentWrapper.css('top', '0px');
			};
			if (support) {
				perspectiveWrapper.on(transEndEventName, onEndTransFn);
			} else {
				onEndTransFn.call();
			}
			container.css('opacity', 1);
			perspectiveWrapper.removeClass('animate');
			$('.ad-perspective-container').removeClass('ad-active');
			container.off('click.container');
			$('.close-popup').off('click.close');
		}


	}

	$.fn.adPerspective.defaults = {
		trigger: 'click',
		orientation: 'bottom',
		effect: 'slide',
		autoplay: false,
		autoplayStart: 0,
		autoplayClose: 0,
		animSpeed: 500,
		opacity: 1,
		loaded: 0
	};

}(jQuery));;
var $bubbles = $('.bubbles');
function bubbles() {
    $('body').addClass('page404');
    var min_bubble_count = 6, max_bubble_count = 10, min_bubble_size = 40, max_bubble_size = 40;
    var bubbleCount = min_bubble_count + Math.floor(Math.random() * (max_bubble_count + 1));
    for (var i = 0; i < bubbleCount; i++) {
        $bubbles.append('<div class="bubble-container"><div class="bubble"></div></div>');
    }
    $bubbles.find('.bubble-container').each(function () {
        var pos_rand = Math.floor(Math.random() * 101);
        var size_rand = min_bubble_size + Math.floor(Math.random() * (max_bubble_size + 1));
        var delay_rand = Math.floor(Math.random() * 5);
        var speed_rand = 6 + Math.floor(Math.random() * 8);
        var color = '#' + Math.floor(Math.random() * 16777215).toString(16);
        var $this = $(this);
        $this.css({
            'left': pos_rand + '%',
            '-webkit-animation-duration': speed_rand + 's',
            '-moz-animation-duration': speed_rand + 's',
            '-ms-animation-duration': speed_rand + 's',
            'animation-duration': speed_rand + 's',
            '-webkit-animation-delay': delay_rand + 's',
            '-moz-animation-delay': delay_rand + 's',
            '-ms-animation-delay': delay_rand + 's',
            'animation-delay': delay_rand + 's',
        });
        $this.children('.bubble').css({
            'width': size_rand + 'px',
            'height': size_rand + 'px',
            'background': color
        });
    });
}
$(function () {
    var count = 0;
    $('.bubbles').on('touchstart click', '.bubble-container', function (e) {
        e.stopPropagation();
        $(this).remove();
        count++;
        $('.counter span').html(count.toString());
        if (count > 4) {
            $('.bubbles').remove();
            $('.win').fadeIn();
        }
    });
});
bubbles();
//# sourceMappingURL=404.js.map;
$(function () {
    var readmore = '.js-switch-holder[data-font-setting=read-mode]', fontsize = '.js-switch-holder[data-font-setting=font-size]', fontstyle = '.js-switch-holder[data-font-setting=font-style]';
    if ($.cookie('darkmode')) {
        $('.article-view-wrap').addClass('read-mode');
        $('body').addClass('read-mode');
        $('.wrap').addClass('read-mode');
        $('.lead-article').addClass('read-mode');
        $('.grid-view').addClass('read-mode');
        $(readmore + ' .icon-dark').removeClass('active');
        $(readmore + ' .switch').addClass('active');
        $(readmore + ' .icon-light').addClass('active');
    }
    else {
        $('.article-view-wrap').removeClass('read-mode');
        $('body').removeClass('read-mode');
        $('.wrap').removeClass('read-mode');
        $('.lead-article').removeClass('read-mode');
        $('.grid-view').removeClass('read-mode');
        $(readmore + ' .icon-dark').addClass('active');
        $(readmore + ' .switch').removeClass('active');
        $(readmore + ' .icon-light').removeClass('active');
    }
    if (localStorage.getItem('font-size')) {
        $('.article-view-wrap').addClass('font-size');
        $(fontsize + ' .icon-small').removeClass('active');
        $(fontsize + ' .switch').addClass('active');
        $(fontsize + ' .icon-large').addClass('active');
        $('body').addClass('font-size');
        $('.wrap').addClass('font-size');
        $('.lead-article').addClass('font-size');
        $('.grid-view').addClass('font-size');
    }
    else {
        $('.article-view-wrap').removeClass('font-size');
        $(fontsize + ' .icon-small').addClass('active');
        $(fontsize + ' .switch').removeClass('active');
        $(fontsize + ' .icon-large').removeClass('active');
        $('body').removeClass('font-size');
        $('.wrap').removeClass('font-size');
        $('.lead-article').removeClass('font-size');
        $('.grid-view').removeClass('font-size');
    }
    if (localStorage.getItem('font-style')) {
        $('.article-view-wrap').addClass('font-style');
        $(fontstyle + ' .icon-sans').removeClass('active');
        $(fontstyle + ' .switch').addClass('active');
        $(fontstyle + ' .icon-serif').addClass('active');
        $('body').addClass('font-style');
        $('.wrap').addClass('font-style');
        $('.lead-article').addClass('font-style');
        $('.grid-view').addClass('font-style');
    }
    else {
        $('.article-view-wrap').removeClass('font-style');
        $(fontstyle + ' .icon-sans').addClass('active');
        $(fontstyle + ' .switch').removeClass('active');
        $(fontstyle + ' .icon-serif').removeClass('active');
        $('body').removeClass('font-style');
        $('.wrap').removeClass('font-style');
        $('.lead-article').removeClass('font-style');
        $('.grid-view').removeClass('font-style');
    }
    $('.js-switch-holder').click(function (e) {
        var fontSetting = $(this).attr('data-font-setting'), button = $(this).children('.switch');
        var expireDate = moment().add({ y: 1 });
        if (button.hasClass('active')) {
            $('body').removeClass(fontSetting);
            $('.wrap').removeClass(fontSetting);
            $('.lead-article').removeClass(fontSetting);
            $('.grid-view').removeClass(fontSetting);
            $('.article-view-wrap').removeClass(fontSetting);
            if (fontSetting === 'read-mode') {
                $.cookie('darkmode', "", { expires: expireDate.toDate(), path: '/', domain: '.hvg.hu' });
            }
            else {
                localStorage.removeItem(fontSetting);
            }
            button.removeClass('active');
            button.prev('span').addClass('active');
            button.next('span').removeClass('active');
        }
        else {
            $('body').addClass(fontSetting);
            $('.wrap').addClass(fontSetting);
            $('.lead-article').addClass(fontSetting);
            $('.grid-view').addClass(fontSetting);
            $('.article-view-wrap').addClass(fontSetting);
            if (fontSetting === 'read-mode') {
                $.cookie('darkmode', "dark", { expires: expireDate.toDate(), path: '/', domain: '.hvg.hu' });
            }
            else {
                localStorage.setItem(fontSetting, "on");
            }
            button.addClass('active');
            button.next('span').addClass('active');
            button.prev('span').removeClass('active');
        }
        e.preventDefault();
    });
    $('.js-more-tag').click(function (e) {
        if ($(this).hasClass('active')) {
            $(this).removeClass('active');
            $(this).prev('.tags').children('.js-more-open').addClass('hide');
        }
        else {
            $(this).prev('.tags').children('.js-more-open').removeClass('hide');
            $(this).addClass('active');
        }
        e.preventDefault();
    });
    $(".js-more-share").click(function (e) {
        $(this).toggleClass("active");
        $('.share-widget-container').toggleClass('active');
        $('.teaser .text-holder').toggleClass('active');
        e.preventDefault();
    });
});
//# sourceMappingURL=article.js.map;
var dataProtectionWrapper = $('.accordion-mobile-aszf');
if (dataProtectionWrapper.length) {
    dataProtectionWrapper.click(function (e) {
        e.preventDefault();
        var $this = $(this);
        if ($this.next().hasClass('show')) {
            $this.parents('.aszf-accordion').siblings('.accordion-mobile-aszf').addClass('active');
            $this.next().removeClass('show').slideUp(350);
            $this.parents('.aszf-accordion').find('.accordion-mobile-aszf').removeClass('active');
        }
        else {
            $this.addClass('active');
            $this.parents('.aszf-accordion').siblings().find('.panel-content').removeClass('show').slideUp(350);
            $this.next().addClass('show').slideToggle(350);
            $this.siblings('.accordion-mobile-aszf').removeClass('active');
            $this.parents('.aszf-accordion').siblings().find('.accordion-mobile-aszf').removeClass('active');
        }
    });
}
//# sourceMappingURL=DataProtection.js.map;
$(document).ready(function () {
    $('body').on('click', '.site-disqus .disqus-overlay', function (e) {
        $(this).closest('.site-disqus').addClass('open');
    });
});
//# sourceMappingURL=DisqusOverlay.js.map;
var DynamicControl;
(function (DynamicControl_1) {
    var LoadType;
    (function (LoadType) {
        LoadType[LoadType["onscroll"] = 0] = "onscroll";
        LoadType[LoadType["manual"] = 1] = "manual";
    })(LoadType || (LoadType = {}));
    var DynamicControl = (function () {
        function DynamicControl($element) {
            this.isLoaded = false;
            this.thisOnScrollFn = null;
            this.$element = $element;
            this.url = $element.data("dynamic");
            this.loadType = $element.data("load-type");
            this.thisOnScrollFn = this.onScroll.bind(this);
            this.init();
        }
        DynamicControl.prototype.init = function () {
            if (this.loadType === LoadType.onscroll) {
                $(window).bind("scroll", this.thisOnScrollFn);
            }
        };
        DynamicControl.prototype.onScroll = function () {
            if ($(window).scrollTop() >= this.$element.offset().top + this.$element.outerHeight() - window.innerHeight) {
                this.loadAsync();
                $(window).unbind("scroll", this.thisOnScrollFn);
            }
        };
        DynamicControl.prototype.loadAsync = function () {
            var _this = this;
            return $.ajax({
                url: this.url,
                type: "GET"
            }).done(function (htmlResult) {
                _this.$element.append(htmlResult);
            });
        };
        return DynamicControl;
    }());
    $(function () {
        $.fn.dynamicControl = function () {
            return new DynamicControl($(this));
        };
        $("*[data-dynamic][data-load-type='onscroll']").each(function (i, e) {
            new DynamicControl($(e));
        });
    });
})(DynamicControl || (DynamicControl = {}));
//# sourceMappingURL=dynamiccontrol.js.map;
/// <reference path="TypescriptTypes/jquery.d.ts" />
/// <reference path="TypescriptTypes/es6-promise.d.ts" />

var HVG;
(function (HVG) {
    var Facebook;
    (function (Facebook) {
        var ShareCounterUpdater = (function () {
            function ShareCounterUpdater() {
                this.fbGraphApiUrlTemplate = 'https://graph.facebook.com/?fields=og_object%7Blikes.summary(total_count).limit(0)%7D,share&id=';
                this.$fbShareCounterHolder = $('#fbShareCounterHolder');
            }
            ShareCounterUpdater.prototype.updateShareCounter = function (articleUrl) {
                return $.ajax({
                    type: 'GET',
                    url: this.fbGraphApiUrlTemplate + articleUrl
                });
            };
            ShareCounterUpdater.prototype.displayResult = function (shareCounter) {
                var sumFBShareCount = +shareCounter['https'];
                if (shareCounter['http'] !== shareCounter['https']) {
                    sumFBShareCount = shareCounter['http'] + shareCounter['https'];
                }
                if (sumFBShareCount > 1000) {
                    var sumFbShareCountText = (sumFBShareCount / 1000).toFixed(1).toString() + ' K';
                    this.$fbShareCounterHolder.html(sumFbShareCountText);
                }
                else {
                    this.$fbShareCounterHolder.html(sumFBShareCount.toString());
                }
            };
            return ShareCounterUpdater;
        }());
        Facebook.ShareCounterUpdater = ShareCounterUpdater;
        function Initialize(articleUrl) {
            var shareCounter = {};
            var fb = new ShareCounterUpdater();
            fb.updateShareCounter(articleUrl)
                .done(function (result) {
                shareCounter['https'] = result && result.share && result.share.share_count ? result.share.share_count : 0;
            });
            fb.updateShareCounter(articleUrl.replace('https', 'http'))
                .done(function (result) {
                shareCounter['http'] = result && result.share && result.share.share_count ? result.share.share_count : 0;
                fb.displayResult(shareCounter);
            });
        }
        Facebook.Initialize = Initialize;
    })(Facebook = HVG.Facebook || (HVG.Facebook = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=facebooksharecounterupdater.js.map;
var HvgGtm;
(function (HvgGtm) {
    var EventHelper = (function () {
        function EventHelper() {
        }
        EventHelper.sendEventNew = function (eCategory, eAction, eLabel) {
            window.ga('send', { hitType: 'event', eventCategory: eCategory, eventAction: eAction, eventLabel: eLabel });
        };
        EventHelper.pushEvent = function (eventName) {
            if (typeof console != "undefined" && console.log) {
                console.log(eventName);
            }
            dataLayer.push({ 'event': eventName });
        };
        EventHelper.init = function () {
            $("a.logo").click(function () {
                EventHelper.pushEvent("ClickOnHeaderLogo");
            });
            $('a[data-layer]').click(function (e) {
                var active = $(this).attr('data-layer');
                HvgGtm.EventHelper.eventMeasure(active, !$(this).hasClass('active'));
            });
            $('.layer-holder').click(function (e) {
                if (e.target == e.currentTarget) {
                    var active = $('a[data-layer].active').attr('data-layer');
                    HvgGtm.EventHelper.eventMeasure(active, false);
                }
            });
            $('.layer-holder').on('swiperight', function (e) {
                if (e.target == e.currentTarget) {
                    var active = $('a[data-layer].active').attr('data-layer');
                    HvgGtm.EventHelper.eventMeasure(active, false);
                }
            });
            $('.js-switch-holder').click(function (e) {
                var fontSetting = $(this).attr('data-font-setting'), button = $(this).children('.switch');
                HvgGtm.EventHelper.articleEventMeasure(fontSetting, button.hasClass('active'));
            });
            $("a.facebook").click(function () {
                EventHelper.pushEvent("SocialShareClickOnFacebook");
            });
            $("a.viber").click(function () {
                EventHelper.pushEvent("SocialShareClickOnViber");
            });
            $("a.messenger").click(function () {
                EventHelper.pushEvent("SocialShareClickOnMessenger");
            });
            $("a.email").click(function () {
                EventHelper.pushEvent("SocialShareClickOnEmail");
            });
            $("a.whatsapp").click(function () {
                EventHelper.pushEvent("SocialShareClickOnWhatsapp");
            });
            $("a.twitter").click(function () {
                EventHelper.pushEvent("SocialShareClickOnTwitter");
            });
            $("a.google-plus").click(function () {
                EventHelper.pushEvent("SocialShareClickOnGooglePlus");
            });
            $("a.pinterest").click(function () {
                EventHelper.pushEvent("SocialShareClickOnPinterest");
            });
            $('*[data-event-name^="RelatedArticle"]').click(function () {
                var relatedArticleEventName = $(this).data("event-name");
                EventHelper.pushEvent(relatedArticleEventName);
            });
            $(window).bind('scroll', function () {
                var shareIsVisible = HvgGtm.EventHelper.isScrolledIntoView(".share");
                if (shareIsVisible && !HvgGtm.EventHelper.shareReached) {
                    HvgGtm.EventHelper.shareReached = true;
                    EventHelper.pushEvent("ScrollToShare");
                }
            });
            $('*[data-event-name^="ArticleSeriesBox"]').click(function () {
                var articleSeriesBoxEventName = $(this).data("event-name");
                EventHelper.pushEvent(articleSeriesBoxEventName);
            });
            $('*[data-event-name^="ClickOnMobileRecommendedRandomArticle"]').click(function () {
                var mobileRecommendedRandomArticleEventName = $(this).data("event-name");
                EventHelper.pushEvent(mobileRecommendedRandomArticleEventName);
            });
            $("[data-lazy-btn]").click(function () {
                EventHelper.pushEvent("ClickOnMoreArticles");
            });
            HvgGtm.EventHelper.orientationChanged();
            window.addEventListener("orientationchange", function () {
                HvgGtm.EventHelper.orientationChanged();
            }, false);
            $("#searchForm").submit(function () {
                EventHelper.pushEvent("SearchStarted");
            });
            $('body').on('click', '[data-event-category]', function (e) {
                var $element = $(e.currentTarget);
                var eventCategory = $element.attr('data-event-category');
                var eventAction = $element.attr('data-event-action');
                var eventLabel = $element.attr('data-event-label');
                HvgGtm.EventHelper.sendEventNew(eventCategory, eventAction, eventLabel);
            });
        };
        EventHelper.orientationChanged = function () {
            var width = window.innerWidth;
            var height = window.innerHeight;
            if (width < height) {
                HvgGtm.EventHelper.pushEvent("UsedInPortrait");
            }
            if (width > height) {
                HvgGtm.EventHelper.pushEvent("UsedInLandscape");
            }
        };
        EventHelper.isScrolledIntoView = function (element) {
            if ($(element).length === 0)
                return false;
            var docViewTop = $(window).scrollTop();
            var docViewBottom = docViewTop + $(window).height();
            var elemTop = $(element).offset().top;
            var elemBottom = elemTop + $(element).height();
            return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
        };
        EventHelper.eventMeasure = function (eventType, isOpening) {
            if (eventType === "js-hamburger")
                eventType = "Hamburger";
            if (eventType === "js-calendar")
                eventType = "LatestCalendar";
            if (eventType === "js-font-settings")
                eventType = "FontSettings";
            var method = "";
            if (isOpening)
                method = "Open";
            else
                method = "Close";
            HvgGtm.EventHelper.pushEvent(eventType + method);
        };
        EventHelper.articleEventMeasure = function (eventType, isLeftOptionSelected) {
            var eventName = "";
            if (eventType === "font-size") {
                if (isLeftOptionSelected)
                    eventName = "FontSettingsSmallFont";
                else
                    eventName = "FontSettingsLargeFont";
            }
            if (eventType === "read-mode") {
                if (isLeftOptionSelected)
                    eventName = "FontSettingsDayMode";
                else
                    eventName = "FontSettingsNightMode";
            }
            if (eventType === "font-style") {
                if (isLeftOptionSelected)
                    eventName = "FontSettingsSansType";
                else
                    eventName = "FontSettingsSerifType";
            }
            HvgGtm.EventHelper.pushEvent(eventName);
        };
        EventHelper.shareReached = false;
        return EventHelper;
    }());
    HvgGtm.EventHelper = EventHelper;
})(HvgGtm || (HvgGtm = {}));
$(function () {
    HvgGtm.EventHelper.init();
});
//# sourceMappingURL=gtmeventhelper.js.map;
var HvgLazyLoad;
(function (HvgLazyLoad) {
    var KeyValue = (function () {
        function KeyValue(key, value) {
            this.key = key;
            this.value = value;
        }
        return KeyValue;
    }());
    var HvgLazyLoadList = (function () {
        function HvgLazyLoadList($grid) {
            var _this = this;
            this.onNoMoreItems = new ApplicationEvent();
            this.numberOfAutoLoads = 0;
            this.autoLoadTimes = 3;
            this.isAjaxRequestRunning = false;
            this.numberOfItems = 0;
            this.hasMoreItem = true;
            this.initialize($grid);
            this.$loadMoreBtn.on("click", this.loadItems.bind(this));
            var $scroller = $(window);
            $scroller.scroll(function () {
                if ($scroller.scrollTop() >= $grid.offset().top + $grid.outerHeight() - $scroller.innerHeight()) {
                    _this.onBottomScroll();
                }
            });
        }
        HvgLazyLoadList.prototype.urlParameters = function () {
            return this.$container.data("lazy-url-parameters") || "";
        };
        HvgLazyLoadList.prototype.initialize = function ($grid) {
            this.$container = $grid;
            this.id = $grid.data("lazy");
            this.numberOfItems = $("*[data-lazy-control='" + this.id + "'][data-lazy-item]").length;
            this.template = $($grid.data("lazy-item-template")).html();
            this.groupTemplate = $($grid.data("lazy-group-template")).html();
            this.itemsInGroup = $grid.data("lazy-items-in-group");
            this.url = $grid.data("lazy-url");
            this.itemCount = $grid.data("lazy-item-count");
            if ($grid.data("lazy-auto-load-times")) {
                this.autoLoadTimes = $grid.data("lazy-auto-load-times");
            }
            this.$loader = $("div[data-lazy-control='" + this.id + "'][data-lazy-loader]");
            this.$loadMoreBtn = $("*[data-lazy-control='" + this.id + "'][data-lazy-btn]");
            this.$noMoreItemsHolder = $("*[data-lazy-control='" + this.id + "'][data-lazy-no-more-items]");
        };
        HvgLazyLoadList.prototype.onBottomScroll = function () {
            if (this.isAjaxRequestRunning) {
                return;
            }
            if (this.numberOfAutoLoads >= this.autoLoadTimes) {
                if (this.hasMoreItem) {
                    this.$loadMoreBtn.show();
                }
            }
            else if (this.hasMoreItem) {
                this.loadItems();
            }
        };
        HvgLazyLoadList.prototype.loadItems = function () {
            var _this = this;
            if (this.isAjaxRequestRunning) {
                return false;
            }
            this.isAjaxRequestRunning = true;
            this.numberOfAutoLoads++;
            this.$loader.show();
            if (this.numberOfItems > 0) {
                $.ajax({
                    url: window.location.origin + this.url + "?skip=" + this.numberOfItems + "&limit=" + this.itemCount + this.urlParameters(),
                    type: "GET",
                    cache: false
                }).done(function (data) {
                    if (data.length == 0) {
                        _this.handleNoMoreItem();
                        return false;
                    }
                    _this.numberOfItems += data.length;
                    if (_this.groupTemplate) {
                        _this.renderGroup(data);
                    }
                    else {
                        var resultHtml = _this.renderItems(data);
                        _this.$container.append(resultHtml);
                    }
                    if (data.length < _this.itemCount) {
                        _this.handleNoMoreItem();
                    }
                    try {
                        window.savedArticlesHandler.initButtons();
                    }
                    catch (e) {
                        console.log(e);
                    }
                }).always(function () {
                    _this.$loader.hide();
                    _this.isAjaxRequestRunning = false;
                });
            }
            return false;
        };
        HvgLazyLoadList.prototype.handleNoMoreItem = function () {
            this.$loadMoreBtn.hide();
            this.hasMoreItem = false;
            if (this.$noMoreItemsHolder.length) {
                this.$noMoreItemsHolder.show();
            }
            this.onNoMoreItems.fire(null);
        };
        HvgLazyLoadList.prototype.renderGroup = function (data) {
            var n = (this.numberOfItems / 3) - 1;
            for (var i = 0, j = data.length; i < j; i += this.itemsInGroup) {
                var row = data.slice(i, i + this.itemsInGroup);
                this.$container.append(Mustache.to_html(this.groupTemplate, { item: this.renderItems(row) }));
                if (i % 3 == 0) {
                    this.$container.append("<div id='video_box_" + n + "'></div>");
                    n++;
                }
            }
        };
        HvgLazyLoadList.prototype.renderItems = function (items) {
            var resultHtml = "";
            for (var i = 0; i < items.length; i++) {
                resultHtml += Mustache.to_html(this.template, items[i]);
            }
            return resultHtml;
        };
        HvgLazyLoadList.prototype.reset = function () {
            this.initialize(this.$container);
            this.numberOfAutoLoads = 0;
            this.hasMoreItem = true;
        };
        return HvgLazyLoadList;
    }());
    HvgLazyLoad.HvgLazyLoadList = HvgLazyLoadList;
    var lazyLists = [];
    function InitLazyLoadLists() {
        $("*[data-lazy]").each(function (i, e) {
            var id = $(e).data("lazy");
            if (lazyLists.some(function (v, i) { return v.key == id; })) {
                return;
            }
            var lazyList = new HvgLazyLoadList($(e));
            lazyLists.push(new KeyValue(lazyList.id, lazyList));
        });
    }
    HvgLazyLoad.InitLazyLoadLists = InitLazyLoadLists;
    $(function () {
        $.fn.lazyList = function () {
            var $element = $(this);
            var id = $element.data("lazy");
            if (id === null || id === "") {
                throw "Az adott element nem lazy list!";
            }
            var list = lazyLists.filter(function (v, i) {
                return v.key === id;
            });
            if (!list.length) {
                return null;
            }
            return list[0].value;
        };
        InitLazyLoadLists();
    });
})(HvgLazyLoad || (HvgLazyLoad = {}));
//# sourceMappingURL=lazyload.js.map;
(function (factory) {
    factory(moment);
}(function (moment) {
    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
    function translate(number, withoutSuffix, key, isFuture) {
        var num = number, suffix;
        switch (key) {
            case 's':
                return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
            case 'm':
                return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
            case 'mm':
                return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
            case 'h':
                return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
            case 'hh':
                return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
            case 'd':
                return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
            case 'dd':
                return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
            case 'M':
                return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
            case 'MM':
                return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
            case 'y':
                return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
            case 'yy':
                return num + (isFuture || withoutSuffix ? ' év' : ' éve');
        }
        return '';
    }
    function week(isFuture) {
        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
    }
    return moment.defineLocale('hu', {
        months: 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),
        monthsShort: 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),
        weekdays: 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
        weekdaysShort: 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
        weekdaysMin: 'v_h_k_sze_cs_p_szo'.split('_'),
        longDateFormat: {
            LT: 'H:mm',
            LTS: 'LT:ss',
            L: 'YYYY.MM.DD.',
            LL: 'YYYY. MMMM D.',
            LLL: 'YYYY. MMMM D., LT',
            LLLL: 'YYYY. MMMM D., dddd LT'
        },
        meridiemParse: /de|du/i,
        isPM: function (input) {
            return input.charAt(1).toLowerCase() === 'u';
        },
        meridiem: function (hours, minutes, isLower) {
            if (hours < 12) {
                return isLower === true ? 'de' : 'DE';
            }
            else {
                return isLower === true ? 'du' : 'DU';
            }
        },
        calendar: {
            sameDay: '[ma] LT[-kor]',
            nextDay: '[holnap] LT[-kor]',
            nextWeek: function () {
                return week.call(this, true);
            },
            lastDay: '[tegnap] LT[-kor]',
            lastWeek: function () {
                return week.call(this, false);
            },
            sameElse: 'L'
        },
        relativeTime: {
            future: '%s múlva',
            past: '%s',
            s: translate,
            m: translate,
            mm: translate,
            h: translate,
            hh: translate,
            d: translate,
            dd: translate,
            M: translate,
            MM: translate,
            y: translate,
            yy: translate
        },
        ordinalParse: /\d{1,2}\./,
        ordinal: '%d.',
        week: {
            dow: 1,
            doy: 7
        }
    });
}));
//# sourceMappingURL=moment-hu-locale.js.map;
$(function () {
    var isWindowsPhone = /windows phone/i.test(navigator.userAgent.toLowerCase());
    if (isWindowsPhone) {
        $('html').addClass('ie-mobile');
    }
    $(document).ready(function () {
        initFbPage();
        initDarkModeAd();
    });
    function initDarkModeAd() {
        $(".font-tab").click(function () {
            var darkModeBtn = document.getElementById('btn-dark-mode');
            if (darkModeBtn) {
                darkModeBtn.src = document.getElementById('btn-dark-mode').getAttribute('data-adurl');
            }
        });
    }
    function initFbPage() {
        if ($(".fb-page").length > 0) {
            $(".fb-page").parent("div").addClass('fb-holder-div');
        }
        else {
        }
    }
    $('a[data-layer]').click(function (e) {
        var active = $(this).attr('data-layer');
        if ($(this).hasClass('active')) {
            $('.scroller').removeClass('disable-scroll');
            $('body').removeClass('disable-body-scroll');
            $('a[data-layer]').removeClass('active');
            $('.layer-holder').addClass('hide');
        }
        else {
            $('.scroller').addClass('disable-scroll');
            $('body').addClass('disable-body-scroll');
            $('a[data-layer]').removeClass('active');
            $(this).addClass('active');
            $('.layer-holder').addClass('hide');
            $('.layer-holder[data-layer="' + active + '"]').removeClass('hide');
        }
        e.preventDefault();
    });
    $('.layer-holder').click(function (e) {
        if (e.target == e.currentTarget) {
            $(this).addClass('hide');
            $('.scroller').removeClass('disable-scroll');
            $('body').removeClass('disable-body-scroll');
            $('a[data-layer]').removeClass('active');
        }
    });
    $('.layer-holder').on('swiperight', function (e) {
        if (e.target == e.currentTarget) {
            $(this).addClass('hide');
            $('.scroller').removeClass('disable-scroll');
            $('body').removeClass('disable-body-scroll');
            $('a[data-layer]').removeClass('active');
        }
    });
    $('.filter-button').insertAfter('header');
    $('.sidebar').insertAfter('header');
    $('a[data-tab]').click(function (e) {
        var active = $(this).attr('data-tab');
        $('.tab a').removeClass('active');
        $(this).addClass('active');
        $('.tab-content').addClass('hide');
        $('.tab-content[data-tab="' + active + '"]').removeClass('hide');
        e.preventDefault();
    });
    $('.js-close-breaking').click(function (e) {
        $('.breaking-holder').addClass('hide');
        e.preventDefault();
    });
    if ($('.adult-content-wrap').length) {
        $('html, body').bind('touchmove scroll mousewheel', function (e) {
            e.preventDefault();
        });
    }
    $('#over-18').click(function (e) {
        $('html, body').unbind('touchmove scroll mousewheel');
        e.preventDefault();
    });
    $('.js-to-top').click(function (e) {
        $('html, body').scrollTop(0);
        e.preventDefault();
    });
    $(".latest-reports-wrap .button").click(function (e) {
        $('html, body').animate({
            scrollTop: $(".pp-box").offset().top - 70
        }, 700);
        e.preventDefault();
    });
    $(window).load(function () {
        if ($('.placeholder-ad .wrap-ad').length != 0) {
            $('.placeholder-ad .wrap-ad').each(function () {
                var prArticle = $(this).find('.mobile-pr-article');
                if (prArticle.length != 0) {
                    var prText = $(this).find('.text-holder a');
                    var divh = $(this).find('.text-holder').height();
                    while ($(prText).outerHeight() > divh) {
                        $(prText).text(function (index, text) {
                            return text.replace(/\W*\s(\S)*$/, '...');
                        });
                    }
                }
            });
        }
        ;
    });
    $(window).on("load", function () {
        var hasSeenBubble = $.cookie('hasSeenBubble');
        function openBubble() {
            var timeouts = [];
            $('.fh-bubble').each(function (index) {
                var $divBubble = $(this);
                $divBubble.addClass('bubble-active');
                timeouts[index] = setTimeout(function () {
                    $divBubble.removeClass('bubble-active').hide();
                }, 10000);
                $('.bubble-active').click(function () {
                    clearTimeout(timeouts[index]);
                    $divBubble.removeClass('bubble-active').hide();
                });
                console.log('show bubble');
            });
        }
        if (hasSeenBubble == 1) {
            $('.fh-bubble').hide();
            return false;
        }
        else {
            openBubble();
        }
        $.cookie('hasSeenBubble', '1', { expires: 365 });
    });
});
window.onload = function () {
    var placeholderDivs = document.querySelectorAll('.placeholder-ad');
    if (placeholderDivs.length > 0) {
        setTimeout(checkDivHeights, 5000);
    }
    else {
        console.log("No 'placeholder-ad' divs are present on the page.");
    }
};
function checkDivHeights() {
    console.log('Checking div heights...');
    var placeholderDivs = document.querySelectorAll('.placeholder-ad');
    for (var index = 0; index < placeholderDivs.length; index++) {
        var placeholderDiv = placeholderDivs[index];
        var goAdverticumDiv = placeholderDiv.querySelector('.goAdverticum');
        if (goAdverticumDiv) {
            var height = goAdverticumDiv.offsetHeight;
            console.log("Placeholder " + index + " / goAdverticum height: " + height + "px");
            placeholderDiv.classList.add("checked-height-" + index);
            var hidePlaceholder = height <= 65;
            var firstIframe = goAdverticumDiv.querySelector('iframe');
            if (firstIframe) {
                var iframeHeight = firstIframe.offsetHeight;
                if (iframeHeight <= 65) {
                    hidePlaceholder = true;
                }
            }
            if (hidePlaceholder) {
                placeholderDiv.classList.add('hide-placeholder');
                console.log("Placeholder " + index + " hidden.");
            }
        }
    }
}
//# sourceMappingURL=sitebuild.js.map;
var HVG;
(function (HVG) {
    var BannerControlManager;
    (function (BannerControlManager) {
        function HideBannersIfZoneIsEmpty() {
            $("div[id^='zone']").each(function (i, element) {
                var zoneId = $(element).attr("id").replace("zone", '');
                HideBannerIfZoneIsEmpty(zoneId);
            });
        }
        BannerControlManager.HideBannersIfZoneIsEmpty = HideBannersIfZoneIsEmpty;
        function HideBannerIfZoneIsEmpty(zoneId) {
            var element = $("div[id='zone" + zoneId + "']");
            var zone = window["goAdverticum3"].getZone(zoneId);
            if ((zone === null || zone.empty) && $(element).parents("div[id^='zone']").length === 0) {
                var parents = $(element).parents(".placeholder-ad");
                if (parents.length) {
                    parents.hide();
                }
                else {
                    $(element).hide();
                }
            }
        }
        BannerControlManager.HideBannerIfZoneIsEmpty = HideBannerIfZoneIsEmpty;
        ;
    })(BannerControlManager = HVG.BannerControlManager || (HVG.BannerControlManager = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=bannercontrolmanager.js.map;
var HVG;
(function (HVG) {
    $(function () {
        if (typeof ScarabQueue !== 'undefined') {
            ScarabOffers.getScarabOffers(10);
        }
    });
    var ScarabOffers = (function () {
        function ScarabOffers() {
        }
        ScarabOffers.getScarabOffers = function (limit) {
            if (limit === void 0) { limit = 10; }
            ScarabQueue.push(["recommend", {
                    logic: "RELATED",
                    containerId: "scarab-offers-container",
                    limit: limit,
                    success: function (SC, render) {
                        HVG.ScarabOffers.RecommendedScarabItems = SC.page.products;
                        HVG.ScarabOffers.SuccessScarabQuery.fire(null);
                    }
                }]);
            ScarabQueue.push(['go']);
        };
        ScarabOffers.SuccessScarabQuery = new ApplicationEvent();
        return ScarabOffers;
    }());
    HVG.ScarabOffers = ScarabOffers;
})(HVG || (HVG = {}));
//# sourceMappingURL=scaraboffers.js.map;
var HVG;
(function (HVG) {
    var ScarabBoxRenderer = (function () {
        function ScarabBoxRenderer() {
        }
        ScarabBoxRenderer.ScarabOffersExist = function () {
            return !$('#scarab-offers-container').length ? false : true;
        };
        ScarabBoxRenderer.Render = function (templateName, containerName, startIndex, endIndex) {
            var template = $('#' + templateName).html();
            var scarabOffers = {
                offers: HVG.ScarabOffers.RecommendedScarabItems.slice(startIndex, endIndex + 1),
                defaultImage: "data:image/gif;base64,R0lGODlhLAGqAIAAAP///wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEyLzAyLzA2LTE0OjU2OjI3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNzg0MUMzRUI5MDMxMUU0OUEwOThDNjA1Mzg4MjA3MyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNzg0MUMzRkI5MDMxMUU0OUEwOThDNjA1Mzg4MjA3MyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM3ODQxQzNDQjkwMzExRTQ5QTA5OEM2MDUzODgyMDczIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkM3ODQxQzNEQjkwMzExRTQ5QTA5OEM2MDUzODgyMDczIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAAAsAAAAACwBqgAAAv+Ej6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/4PDAqHxKLxiEwql8ym8wmNSqfUqvWKzWq33K73Cw6Lx+Sy+YxOq9fstvsNj8vn9Lr9js/r9/y+/w8YKDhIWGh4iJiouMjY6PgIGSk5SVlpeYmZqbnJ2en5CRoqOkpaanqKmqq6ytrq+gobKztLW2t7i5uru8vb6/sLHCw8TFxsfIycrLzM3Oz8DB0tPU1dbX2Nna29zd3t/Q0eLj5OXm5+jp6uvs7e7v4OHy8/T19vf4+fr7/P3+//DzCgwIEECxo8iDChwoUMGzp8CDGixIkUK1q8iDGjxo0vHDt6/AgypMiRJEuaPIkypcqVLFu6fAkzpsyZNGvavIkzp86dPHv6/Ak0qNCNBQAAOw=="
            };
            for (var i = 0; i < scarabOffers.offers.length; i++) {
                scarabOffers.offers[i].timestamp = ScarabBoxRenderer.prettyDate(scarabOffers.offers[i].timestamp);
                scarabOffers.offers[i].link = scarabOffers.offers[i].link.replace("hvg.hu", window.location.host);
                scarabOffers.offers[i].index = i + 1;
            }
            var htmlContent = Mustache.to_html(template, scarabOffers);
            $('#' + containerName).html(htmlContent);
        };
        ScarabBoxRenderer.prettyDate = function (datetime) {
            var date = moment(datetime, "YYYYMMDDThhmmTZD");
            return date.format("YYYY. MMMM. D. H:mm");
        };
        return ScarabBoxRenderer;
    }());
    HVG.ScarabBoxRenderer = ScarabBoxRenderer;
})(HVG || (HVG = {}));
//# sourceMappingURL=scarabboxrenderer.js.map;
/// <reference path="TypescriptTypes/jquery.d.ts" />
/// <reference path="TypescriptTypes/es6-promise.d.ts" />

var HVG;
(function (HVG) {
    var Facebook;
    (function (Facebook) {
        var ShareCounterUpdater = (function () {
            function ShareCounterUpdater() {
                this.fbGraphApiUrlTemplate = 'https://graph.facebook.com/?fields=og_object%7Blikes.summary(total_count).limit(0)%7D,share&id=';
                this.$fbShareCounterHolder = $('#fbShareCounterHolder');
            }
            ShareCounterUpdater.prototype.updateShareCounter = function (articleUrl) {
                return $.ajax({
                    type: 'GET',
                    url: this.fbGraphApiUrlTemplate + articleUrl
                });
            };
            ShareCounterUpdater.prototype.displayResult = function (shareCounter) {
                var sumFBShareCount = +shareCounter['https'];
                if (shareCounter['http'] !== shareCounter['https']) {
                    sumFBShareCount = shareCounter['http'] + shareCounter['https'];
                }
                if (sumFBShareCount > 1000) {
                    var sumFbShareCountText = (sumFBShareCount / 1000).toFixed(1).toString() + ' K';
                    this.$fbShareCounterHolder.html(sumFbShareCountText);
                }
                else {
                    this.$fbShareCounterHolder.html(sumFBShareCount.toString());
                }
            };
            return ShareCounterUpdater;
        }());
        Facebook.ShareCounterUpdater = ShareCounterUpdater;
        function Initialize(articleUrl) {
            var shareCounter = {};
            var fb = new ShareCounterUpdater();
            fb.updateShareCounter(articleUrl)
                .done(function (result) {
                shareCounter['https'] = result && result.share && result.share.share_count ? result.share.share_count : 0;
            });
            fb.updateShareCounter(articleUrl.replace('https', 'http'))
                .done(function (result) {
                shareCounter['http'] = result && result.share && result.share.share_count ? result.share.share_count : 0;
                fb.displayResult(shareCounter);
            });
        }
        Facebook.Initialize = Initialize;
    })(Facebook = HVG.Facebook || (HVG.Facebook = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=facebooksharecounterupdater.js.map;
var HVG;
(function (HVG) {
    var BottomScarabBoxRenderer;
    (function (BottomScarabBoxRenderer) {
        HVG.ScarabOffers.SuccessScarabQuery.bind(function () {
            if (!HVG.ScarabBoxRenderer.ScarabOffersExist) {
                return;
            }
            HVG.ScarabBoxRenderer.Render('bottom-scarab-template', 'bottom-scarab-container', 0, 2);
        });
    })(BottomScarabBoxRenderer = HVG.BottomScarabBoxRenderer || (HVG.BottomScarabBoxRenderer = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=bottomscarabboxrenderer.js.map;
$(function () {
    if (window.galleryImages) {
        var currentImageIndex = 0;
        var $galleryViewer = $('.gallery-viewer .image-holder');
        var $pagers = $('.gallery-viewer a[data-url]');
        var $nextLink = $('#next-img');
        var $previousLink = $('#prev-img');
        var $restartLink = $('.icon-again');
        $galleryViewer.click(toggleControls);
        var section = document.querySelector('.text-holder .text p');
        var baseHeight = section.offsetHeight;
        var startHeight = 54;
        if (window.screen.width <= 767 && window.screen.height <= 768) {
            function textHeight(element) {
                if (section.scrollHeight > startHeight) {
                    var sectionHeight = section.scrollHeight;
                    var baseHeight = startHeight;
                    section.style.height = baseHeight + 'px';
                    console.log('startHeight: ' + startHeight + ' / if baseHeight ' + baseHeight);
                }
                else {
                    var sectionHeight = section.scrollHeight;
                    var baseHeight = section.offsetHeight;
                    if (baseHeight > startHeight) {
                        var baseHeight = startHeight;
                        section.style.height = baseHeight + 'px';
                        console.log('startHeight: ' + startHeight + ' / else if baseHeight ' + baseHeight);
                    }
                    else {
                        section.style.height = startHeight + 'px';
                        console.log('startHeight: ' + startHeight + ' / else startHeight ' + startHeight);
                    }
                }
                section.setAttribute('data-collapsed', 'true');
                if (section.offsetHeight < section.scrollHeight) {
                    section.classList.remove('disabled-dots');
                }
                else {
                    section.classList.add('disabled-dots');
                }
            }
            textHeight(section);
            function collapseSection(element) {
                var sectionHeight = element.offsetHeight;
                var elementTransition = element.style.transition;
                element.style.transition = '';
                requestAnimationFrame(function () {
                    element.style.height = sectionHeight + 'px';
                    element.style.transition = elementTransition;
                    requestAnimationFrame(function () {
                        if (section.scrollHeight > startHeight) {
                            var sectionHeight = section.scrollHeight;
                            var baseHeight = startHeight;
                            section.style.height = baseHeight + 'px';
                            console.log('startHeight: ' + startHeight + ' / if baseHeight ' + baseHeight);
                        }
                        else {
                            var sectionHeight = section.scrollHeight;
                            var baseHeight = section.offsetHeight;
                            if (baseHeight > startHeight) {
                                var baseHeight = startHeight;
                                section.style.height = baseHeight + 'px';
                                console.log('startHeight: ' + startHeight + ' / else if baseHeight ' + baseHeight);
                            }
                            else {
                                section.style.height = startHeight + 'px';
                                console.log('startHeight: ' + startHeight + ' / else startHeight ' + startHeight);
                            }
                        }
                    });
                });
                element.setAttribute('data-collapsed', 'true');
            }
            function expandSection(element) {
                var sectionHeight = element.scrollHeight;
                element.style.height = sectionHeight + 'px';
                element.addEventListener('transitionend', function (e) {
                    element.removeEventListener('transitionend', arguments.callee);
                    element.style.height = null;
                });
                element.setAttribute('data-collapsed', 'false');
            }
            document.querySelector('.text').addEventListener('click', function (e) {
                var section = document.querySelector('.text-holder .text p');
                var isCollapsed = section.getAttribute('data-collapsed') === 'true';
                if (isCollapsed) {
                    if (section.offsetHeight < section.scrollHeight) {
                        expandSection(section);
                        section.setAttribute('data-collapsed', 'false');
                        $('.text-holder').addClass('slide-out-bg');
                    }
                }
                else {
                    collapseSection(section);
                    $('.text-holder').removeClass('slide-out-bg');
                }
            });
        }
        function swapLayer() {
            if (window.galleryImages[currentImageIndex].Visible) {
                showImage(currentImageIndex);
                hideLayer();
            }
            else {
                showLayer();
                hideImage();
            }
        }
        if (currentImageIndex == 0) {
            $('.image').append(addImage());
            $('.image').append(addLayer());
            swapLayer();
        }
        if (window.galleryImages.length > 1) {
            prefetchNextImage(window.galleryImages[1].ImageUrl);
        }
        function prefetchNextImage(url) {
            $('<img/>')[0]["src"] = url;
        }
        function toggleControls() {
            $(this).toggleClass('active');
            $('.header').toggleClass('slide-up');
            $('.text-holder, .share, .counter').toggleClass('slide-out');
            $('.text-holder').removeClass('slide-out-bg');
        }
        function hideControls() {
            $('.header').addClass('slide-up');
            $('.text-holder, .share, .counter').addClass('slide-out');
            $('.text-holder').removeClass('slide-out-bg');
        }
        function showRestartPage() {
            hideLayer();
            $("a[rel='next']").hide();
            $("a[rel='prev']").hide();
            $('.image img').hide();
            $('.text-holder').hide();
            $('.counter').hide();
            $('.text-holder .author').hide();
            $('.share').hide();
            $("div[class='last-slide hide']").show();
        }
        function getNextImage(e) {
            currentImageIndex++;
            e.preventDefault();
            $previousLink.show();
            if (currentImageIndex === window.galleryImages.length) {
                showRestartPage();
                $nextLink.hide();
                return;
            }
            hideControls();
            swapLayer();
            if (currentImageIndex < window.galleryImages.length - 1) {
                prefetchNextImage(window.galleryImages[currentImageIndex + 1].ImageUrl);
            }
        }
        function getPrevImage(e) {
            console.log(currentImageIndex);
            if (currentImageIndex > 0) {
                currentImageIndex--;
            }
            e.preventDefault();
            $nextLink.show();
            if (0 <= currentImageIndex) {
                hideControls();
                swapLayer();
                if (currentImageIndex === 0) {
                    $previousLink.hide();
                }
            }
        }
        function showCurrentImage(e) {
            e.preventDefault();
            hideLayer();
            showImage(currentImageIndex);
            if (window.screen.width <= 767 && window.screen.height <= 768) {
                textHeight(section);
                collapseSection(section);
            }
        }
        $nextLink.click(function (e) {
            getNextImage(e);
            if (window.screen.width <= 767 && window.screen.height <= 768) {
                textHeight(section);
                collapseSection(section);
            }
        });
        $galleryViewer.on("swipeleft", function (e) {
            getNextImage(e);
            if (window.screen.width <= 767 && window.screen.height <= 768) {
                textHeight(section);
                collapseSection(section);
            }
        });
        $previousLink.click(function (e) {
            getPrevImage(e);
            if (window.screen.width <= 767 && window.screen.height <= 768) {
                textHeight(section);
                collapseSection(section);
            }
        });
        $galleryViewer.on("swiperight", function (e) {
            getPrevImage(e);
            if (window.screen.width <= 767 && window.screen.height <= 768) {
                textHeight(section);
                collapseSection(section);
            }
        });
        $('.adult-content').click(function (e) {
            showCurrentImage(e);
        });
        $galleryViewer.on("click", function (e) {
            showCurrentImage(e);
        });
        function showImage(index) {
            $('.image img').show();
            var currentImage = window.galleryImages[index];
            $('.image img').attr('src', currentImage.ImageUrl);
            $('.text-holder .info').html(currentImage.PrettyReleaseDate);
            $('.text-holder h1').html(currentImage.Caption);
            $('.text-holder p').html(currentImage.Description);
            $('.counter .current').html(currentImage.Id);
            $('.text-holder .author').html(currentImage.Source);
        }
        function showLayer() {
            $('.image .adult-content').show();
        }
        function hideLayer() {
            $('.image .adult-content').hide();
        }
        function hideImage() {
            $('.image img').hide();
        }
        function addImage() {
            return "<img src='" + window.galleryImages[currentImageIndex].ImageUrl + "' alt='' title='' />";
        }
        function addLayer() {
            return "<a class='adult-content'>Figyelem!<br><br>A kép megtekintését kizárólag erős idegzetű, felnőtt látogatóinknak ajánljuk!<br>Tovább a fotóra...</a>";
        }
    }
});
//# sourceMappingURL=gallery.js.map;
var LiveReportList;
(function (LiveReportList) {
    $(function () {
        var liveReportLazyList = $("div[data-lazy='livereport']")["lazyList"]();
        if (liveReportLazyList !== null) {
            liveReportLazyList.onNoMoreItems.bind(function () {
                $("#dynamic-lead-article")["dynamicControl"]().loadAsync();
                $("#dynamic-paralell-articles")["dynamicControl"]().loadAsync().done(function () {
                    HvgLazyLoad.InitLazyLoadLists();
                });
            });
        }
    });
})(LiveReportList || (LiveReportList = {}));
//# sourceMappingURL=LiveReportList.js.map;
var HVG;
(function (HVG) {
    var LiveReportSorter = (function () {
        function LiveReportSorter(isInAscendingOrder, webId, relativeArticleUrl) {
            this.cookieName = '_hvg_ascendingorder_livereports';
            this.twoWeekInDays = 2 * 7;
            this.verbose = true;
            this.isInAscendingOrder = isInAscendingOrder;
            this.webId = webId;
            this.relativeArticleUrl = relativeArticleUrl;
            this.init();
        }
        LiveReportSorter.prototype.init = function () {
            var _this = this;
            $(".sorter .asc").click(function (e) {
                return _this.setToAscending();
            });
            $(".sorter .desc").click(function (e) {
                return _this.setToDescending();
            });
        };
        LiveReportSorter.prototype.createReverseOrderCookie = function (cookieValue) {
            $.cookie(this.cookieName, cookieValue, { expires: this.twoWeekInDays, path: '/', domain: 'hvg.hu' });
        };
        LiveReportSorter.prototype.setToAscending = function () {
            if (this.isInAscendingOrder)
                return false;
            if (this.verbose)
                console.log("live report sorter setToAscending");
            var self = this;
            var reverseOrderCookieValue = decodeURIComponent($.cookie(this.cookieName));
            if (reverseOrderCookieValue === undefined) {
                this.createReverseOrderCookie(this.webId);
            }
            else {
                var reverseOrderList = reverseOrderCookieValue.split(',');
                var cookieContainsWebId = reverseOrderList.some(function (item) { return item === self.webId; });
                if (!cookieContainsWebId) {
                    this.createReverseOrderCookie(reverseOrderCookieValue + ',' + self.webId);
                }
            }
            window.location.href = this.relativeArticleUrl;
            return false;
        };
        LiveReportSorter.prototype.setToDescending = function () {
            if (!this.isInAscendingOrder)
                return false;
            if (this.verbose)
                console.log("live report sorter setToDescending");
            var self = this;
            var reverseOrderCookieValue = decodeURIComponent($.cookie(this.cookieName));
            if (reverseOrderCookieValue != undefined) {
                var reverseOrderList = reverseOrderCookieValue.split(',');
                var cookieContainsWebId = reverseOrderList.some(function (item) { return item === self.webId; });
                if (cookieContainsWebId) {
                    reverseOrderList = $.grep(reverseOrderList, function (value) { return value != self.webId; });
                    reverseOrderCookieValue = reverseOrderList.join(',');
                    this.createReverseOrderCookie(reverseOrderCookieValue);
                }
            }
            window.location.href = this.relativeArticleUrl;
            return false;
        };
        return LiveReportSorter;
    }());
    HVG.LiveReportSorter = LiveReportSorter;
})(HVG || (HVG = {}));
//# sourceMappingURL=LiveReportSorter.js.map;
var HVG;
(function (HVG) {
    var RightScarabBoxRenderer;
    (function (RightScarabBoxRenderer) {
        HVG.ScarabOffers.SuccessScarabQuery.bind(function () {
            if (!HVG.ScarabBoxRenderer.ScarabOffersExist) {
                return;
            }
            HVG.ScarabBoxRenderer.Render('right-scarab-template', 'right-scarab-container', 3, 4);
            if ($('.article-content').length) {
                var articleHeight = $('.article-content').outerHeight();
                var sidebarHeight = $('.sidebar').outerHeight();
                var relatedHeight = $('.article-content .related').outerHeight();
                if (articleHeight < sidebarHeight + relatedHeight) {
                    $('.article-content .related').addClass('hide');
                }
            }
        });
    })(RightScarabBoxRenderer = HVG.RightScarabBoxRenderer || (HVG.RightScarabBoxRenderer = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=rightscarabboxrenderer.js.map;
var HVG;
(function (HVG) {
    var Mobile;
    (function (Mobile) {
        function Chunk(array, chunkSize) {
            return [].concat.apply([], array.map(function (elem, i) {
                return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
            }));
        }
        var Calendar = (function () {
            function Calendar() {
            }
            Calendar.prototype.initialize = function (calendarElementSelector) {
                var calendar = $(calendarElementSelector)["clndr"]({
                    constraints: {
                        endDate: moment().format("YYYY-MM-DD")
                    },
                    render: function (data) {
                        for (var i = 0; i < data.days.length; i++) {
                            data.days[i].monthMM = data.days[i].date.format("MM");
                            data.days[i].dayDD = data.days[i].date.format("DD");
                        }
                        data.days = Chunk(data.days, 7);
                        for (var i = 0; i < data.days.length; i++) {
                            data.days[i][6].isSunday = true;
                        }
                        return Mustache.to_html($("#latestlist-calendar-template").html(), data);
                    }
                });
            };
            return Calendar;
        }());
        Mobile.Calendar = Calendar;
    })(Mobile = HVG.Mobile || (HVG.Mobile = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=calendar.js.map;
var BullshitMeter;
(function (BullshitMeter) {
    $(function () {
        $("form[data-type='bullshitmeter'] button").on("click", bullshitMeter);
    });
    function bullshitMeter() {
        var bullshitMeterId = $(this).data("id");
        var selectedBullshitMeterItemId = $("input[data-id='" + bullshitMeterId + "']:checked").val();
        if (selectedBullshitMeterItemId) {
            increment(bullshitMeterId, selectedBullshitMeterItemId);
        }
        else {
            getResult(bullshitMeterId);
        }
        return false;
    }
    function increment(bullshitMeterId, selectedBullshitMeterItemId) {
        console.log("increment");
        $.ajax("/bullshitmeter/" + bullshitMeterId + "/increment/" + selectedBullshitMeterItemId, { type: "POST" })
            .done(function (result) { return displayResult(result, bullshitMeterId); })
            .fail(function (result) { return displayError(bullshitMeterId); })
            .always(hideLoader);
    }
    function getResult(bullshitMeterId) {
        console.log("getResult");
        $.ajax("/bullshitmeter/" + bullshitMeterId + "/result")
            .done(function (result) { return displayResult(result, bullshitMeterId); })
            .fail(function (result) { return displayError(bullshitMeterId); })
            .always(hideLoader);
    }
    function displayResult(result, bullshitMeterId) {
        var $form = $("form[data-id='" + bullshitMeterId + "']");
        $form.find('.answers').addClass('hide');
        $form.find('.article-bullshitmeter').addClass('hide');
        $form.find('.bullshitmeter-title').addClass('hide');
        $form.find('.bullshitmeter-statement').addClass('hide');
        $form.find('.bullshitmeter-question').addClass('hide');
        $form.find('.result').removeClass('hide');
        $form.find('.quiz .info').html('Szavazás eredmény');
        var htmlResult = Mustache.render($("#bullshitmeter-result-template-" + bullshitMeterId).html(), result);
        $form.append(htmlResult);
    }
    function displayError(bullshitMeterId) {
        $("#" + bullshitMeterId).html("Hiba történt a szavazat elküldésekor, kérjük próbálja újra!");
    }
    function showLoader() {
        $(this).addClass("loading");
    }
    function hideLoader() {
        $(this).removeClass("loading");
    }
})(BullshitMeter || (BullshitMeter = {}));
//# sourceMappingURL=BullshitMeter.js.map;
var EDULINE;
(function (EDULINE) {
    var Vote;
    (function (Vote) {
        function CastVote(event) {
            event = event || window.event;
            var voteId = $(event.currentTarget).data('vote-control'), vote = new VoteControl(voteId);
            vote.cast();
            return false;
        }
        Vote.CastVote = CastVote;
        var VoteControl = (function () {
            function VoteControl(id) {
                this.id = id;
                this.$articleVote = $('#' + this.id);
                this.$form = $('[data-vote="' + this.id + '"]');
                var $selectedOption = this.$form.find('[data-vote-option] input:checked');
                this.selectedOptionId = $selectedOption.val();
            }
            VoteControl.prototype.cast = function () {
                if (this.selectedOptionId) {
                    this.increment();
                }
                else {
                    this.getResult();
                }
            };
            VoteControl.prototype.increment = function () {
                var _this = this;
                $.ajax({
                    type: 'POST',
                    url: '/vote/vote/' + this.id + '/increment/' + this.selectedOptionId
                }).done(function (result) {
                    _this.displayResult(result);
                }).fail(function (result) {
                    _this.displayError();
                });
            };
            VoteControl.prototype.getResult = function () {
                var _this = this;
                $.ajax({
                    type: 'GET',
                    url: '/vote/vote/' + this.id + '/result'
                }).done(function (result) {
                    _this.displayResult(result);
                }).fail(function (result) {
                    _this.displayError();
                });
            };
            VoteControl.prototype.displayResult = function (result) {
                this.$form.find('.vote-option').not('[data-vote-option]').remove();
                this.$articleVote.addClass('result');
                for (var i in result.voteItems) {
                    this.displayOptionResult(result.voteItems[i], result.vote.voteItems[i].id, parseInt(i));
                }
            };
            VoteControl.prototype.displayOptionResult = function (option, optionId, itemIdx) {
                var $voteOption = $('[data-vote-option="' + optionId + '"]'), $percent = $voteOption.find('.percent'), $resultChart = $voteOption.find('.result-chart');
                $percent.html(option.percent + '%');
                if (option.isLongest) {
                    $resultChart.addClass('longest');
                }
                var percent = parseInt(option.percent, 10);
                setTimeout(function () { $resultChart.find('.line').css('width', percent + '%'); }, itemIdx * 100);
            };
            VoteControl.prototype.displayError = function () {
                this.$articleVote.html('Hiba történt a szavazat elküldésekor, kérjük próbálja újra!');
            };
            return VoteControl;
        }());
    })(Vote = EDULINE.Vote || (EDULINE.Vote = {}));
})(EDULINE || (EDULINE = {}));
$(document).ready(function () {
    $('body').on('submit', '.article-vote .vote-form', function (event) {
        event.preventDefault();
    });
});
//# sourceMappingURL=Vote.js.map;
var HVG;
(function (HVG) {
    var Vote;
    (function (Vote) {
        function CastVote(event) {
            event = event || window.event;
            var voteId = $(event.currentTarget).data('vote-control'), vote = new VoteControl(voteId);
            vote.cast();
            return false;
        }
        Vote.CastVote = CastVote;
        var VoteControl = (function () {
            function VoteControl(id) {
                this.id = id;
                this.$articleVote = $('#' + this.id);
                this.$form = $('[data-vote="' + this.id + '"]');
                var $selectedOption = this.$form.find('[data-vote-option] input:checked');
                this.selectedOptionId = $selectedOption.val();
            }
            VoteControl.prototype.cast = function () {
                if (this.selectedOptionId) {
                    this.increment();
                }
                else {
                    this.getResult();
                }
            };
            VoteControl.prototype.increment = function () {
                var _this = this;
                $.ajax({
                    type: 'POST',
                    url: '/vote/vote/' + this.id + '/increment/' + this.selectedOptionId
                }).done(function (result) {
                    _this.displayResult(result);
                }).fail(function (result) {
                    _this.displayError();
                });
            };
            VoteControl.prototype.getResult = function () {
                var _this = this;
                $.ajax({
                    type: 'GET',
                    url: '/vote/vote/' + this.id + '/result'
                }).done(function (result) {
                    _this.displayResult(result);
                }).fail(function (result) {
                    _this.displayError();
                });
            };
            VoteControl.prototype.displayResult = function (result) {
                this.$form.find('.vote-option').not('[data-vote-option]').remove();
                this.$articleVote.addClass('result');
                for (var i in result.voteItems) {
                    this.displayOptionResult(result.voteItems[i], result.vote.voteItems[i].id, parseInt(i));
                }
            };
            VoteControl.prototype.displayOptionResult = function (option, optionId, itemIdx) {
                var $voteOption = $('[data-vote-option="' + optionId + '"]'), $percent = $voteOption.find('.percent'), $resultChart = $voteOption.find('.result-chart');
                $percent.html(option.percent + '%');
                if (option.isLongest) {
                    $resultChart.addClass('longest');
                }
                var percent = parseInt(option.percent, 10);
                setTimeout(function () { $resultChart.find('.line').css('width', percent + '%'); }, itemIdx * 100);
            };
            VoteControl.prototype.displayError = function () {
                this.$articleVote.html('Hiba történt a szavazat elküldésekor, kérjük próbálja újra!');
            };
            return VoteControl;
        }());
    })(Vote = HVG.Vote || (HVG.Vote = {}));
})(HVG || (HVG = {}));
$(document).ready(function () {
    $('body').on('submit', '.article-vote .vote-form', function (event) {
        event.preventDefault();
    });
});
//# sourceMappingURL=Vote.js.map;
var BreakingArticleStripe;
(function (BreakingArticleStripe) {
    var $breakingHolder = null;
    $.cookie.raw = true;
    $(function () {
        $breakingHolder = $(".breaking-holder");
        if ($breakingHolder.length) {
            $("*[data-id='breaking-dismiss']").on("click", dismiss);
        }
    });
    function dismiss() {
        $breakingHolder.addClass("hide");
        var value = $breakingHolder.data("webid");
        var breakingArticlesCookie = $.cookie("BreakingArticles");
        if (breakingArticlesCookie && breakingArticlesCookie.indexOf(value) === -1) {
            value = breakingArticlesCookie + "&" + value;
        }
        $.cookie("BreakingArticles", value, { expires: moment().add({ hours: 1 }).toDate() });
    }
})(BreakingArticleStripe || (BreakingArticleStripe = {}));
//# sourceMappingURL=breakingarticlestripe.js.map;
var HVG;
(function (HVG) {
    var MyHVGArticles;
    (function (MyHVGArticles) {
        // az articlebox id-ja(a CSHTML-ben van benne),
        // és a cikkek trending típusai felsorolva, amiket meg kell jeleníteni,
        // pl. ['Short', 'Short', 'Long'], ez 3 cikket jelenít meg, 2 short trending-et, és 1 long trending-et
        function renderMyHVGBox(boxName, upperArticles, lowerArticles) {
            var upperArticlesData;
            $.ajax(window.trendingAPIBaseURL + '/v01/hvg360/trending/articles', {
                type: 'POST',
                contentType: "application/json; charset=utf-8",
                data: JSON.stringify(upperArticles),
                dataType: 'json'
            })
                .done(function (data) {
                upperArticlesData = data;
                if (lowerArticles === undefined || lowerArticles === null || (Array.isArray(lowerArticles) && lowerArticles.length === 0)) {
                    // A nem belépett user esetén fut be ide, csak egy sornyi cikk jelenik meg, alsó sorban pedig valami marketing HTML
                    $("#" + boxName).html(Mustache.to_html($("#" + boxName + "-template-anonym").html(), { "items": data }));
                    initFlickity();
                }
                else {
                    $.ajax(window.trendingAPIBaseURL + '/v01/hvg360/trending/articles', {
                        type: 'POST',
                        contentType: "application/json; charset=utf-8",
                        data: JSON.stringify(lowerArticles),
                        dataType: 'json'
                    })
                        .done(function (data) {
                        // ótvar hekk.. :D
                        for (var _idx = 0; _idx < data.length; _idx++) {
                            data[_idx].index = _idx + 1;
                        }
                        $("#" + boxName).html(Mustache.to_html($("#" + boxName + "-template").html(), { upperitems: upperArticlesData, loweritems: data }));
                        initFlickity();
                    });
                }
            });
        }
        MyHVGArticles.renderMyHVGBox = renderMyHVGBox;
        function initFlickity() {
            //desktop
            var $carousel = $('.slider-d');
            var $carousel2 = $('.slider-d2');
            if ($carousel.length) {
                $carousel.on('ready.flickity', function () {
                    console.log('Flickity desktop ready');
                });
                $carousel.flickity({
                    freeScroll: false,
                    contain: true,
                    pageDots: false,
                    prevNextButtons: true,
                    draggable: '>2',
                    freeScrollFriction: 0.03,
                    groupCells: true
                });
            }
            if ($carousel2.length) {
                $carousel2.on('ready.flickity', function () {
                    console.log('Flickity desktop 2 ready');
                });
                $carousel2.flickity({
                    freeScroll: false,
                    contain: true,
                    pageDots: false,
                    prevNextButtons: true,
                    draggable: '>2',
                    freeScrollFriction: 0.03,
                    groupCells: true
                });
            }
            //mobile
            var $carousel_m = $('.slider-m');
            var $carousel_m2 = $('.slider-m2');
            if ($carousel_m.length) {
                $carousel_m.on('ready.flickity', function () {
                    console.log('Flickity mobile ready');
                });
                $carousel_m.flickity({
                    freeScroll: false,
                    contain: true,
                    pageDots: false,
                    prevNextButtons: true,
                    draggable: '>1',
                    freeScrollFriction: 0.03,
                    groupCells: true,
                    cellAlign: 'left'
                });
            }
            if ($carousel_m2.length) {
                $carousel_m2.on('ready.flickity', function () {
                    console.log('Flickity mobile 2 ready');
                });
                $carousel_m2.flickity({
                    freeScroll: false,
                    contain: true,
                    pageDots: false,
                    prevNextButtons: true,
                    draggable: '>1',
                    freeScrollFriction: 0.03,
                    groupCells: true,
                    cellAlign: 'left'
                });
            }
        }
    })(MyHVGArticles = HVG.MyHVGArticles || (HVG.MyHVGArticles = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=MyHVGArticleRenderer.js.map;
var HVG;
(function (HVG) {
    var TrendingArticles;
    (function (TrendingArticles) {
        function renderTrendingBox(boxName, articles) {
            $.ajax(window.trendingAPIBaseURL + '/v01/hvg360/trending/articles', {
                type: 'POST',
                contentType: "application/json; charset=utf-8",
                data: JSON.stringify(articles),
                dataType: 'json'
            })
                .done(function (data) {
                console.log(data[0]);
                $("#" + boxName).html(Mustache.to_html($("#" + boxName + "-template").html(), { "items": data }));
            });
        }
        TrendingArticles.renderTrendingBox = renderTrendingBox;
    })(TrendingArticles = HVG.TrendingArticles || (HVG.TrendingArticles = {}));
})(HVG || (HVG = {}));
//# sourceMappingURL=TrendingArticleRenderer.js.map;
