/* Minification failed. Returning unminified contents.
(12251,21-22): run-time error JS1195: Expected expression: )
(12251,24-25): run-time error JS1195: Expected expression: >
(12256,10-11): run-time error JS1195: Expected expression: ,
(12258,6-7): run-time error JS1195: Expected expression: )
(12261,29-30): run-time error JS1195: Expected expression: )
(12261,31-32): run-time error JS1004: Expected ';': {
(12274,2-3): run-time error JS1195: Expected expression: )
 */


/*!
 * parallax.js v1.5.0 (http://pixelcog.github.io/parallax.js/)
 * @copyright 2016 PixelCog, Inc.
 * @license MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE)
 */
!function (t, i, e, s) { function o(i, e) { var h = this; "object" == typeof e && (delete e.refresh, delete e.render, t.extend(this, e)), this.$element = t(i), !this.imageSrc && this.$element.is("img") && (this.imageSrc = this.$element.attr("src")); var r = (this.position + "").toLowerCase().match(/\S+/g) || []; if (r.length < 1 && r.push("center"), 1 == r.length && r.push(r[0]), "top" != r[0] && "bottom" != r[0] && "left" != r[1] && "right" != r[1] || (r = [r[1], r[0]]), this.positionX !== s && (r[0] = this.positionX.toLowerCase()), this.positionY !== s && (r[1] = this.positionY.toLowerCase()), h.positionX = r[0], h.positionY = r[1], "left" != this.positionX && "right" != this.positionX && (isNaN(parseInt(this.positionX)) ? this.positionX = "center" : this.positionX = parseInt(this.positionX)), "top" != this.positionY && "bottom" != this.positionY && (isNaN(parseInt(this.positionY)) ? this.positionY = "center" : this.positionY = parseInt(this.positionY)), this.position = this.positionX + (isNaN(this.positionX) ? "" : "px") + " " + this.positionY + (isNaN(this.positionY) ? "" : "px"), navigator.userAgent.match(/(iPod|iPhone|iPad)/)) return this.imageSrc && this.iosFix && !this.$element.is("img") && this.$element.css({ backgroundImage: 'url("' + this.imageSrc + '")', backgroundSize: "cover", backgroundPosition: this.position }), this; if (navigator.userAgent.match(/(Android)/)) return this.imageSrc && this.androidFix && !this.$element.is("img") && this.$element.css({ backgroundImage: 'url("' + this.imageSrc + '")', backgroundSize: "cover", backgroundPosition: this.position }), this; this.$mirror = t("<div />").prependTo(this.mirrorContainer); var a = this.$element.find(">.parallax-slider"), n = !1; 0 == a.length ? this.$slider = t("<img />").prependTo(this.$mirror) : (this.$slider = a.prependTo(this.$mirror), n = !0), this.$mirror.addClass("parallax-mirror").css({ visibility: "hidden", zIndex: this.zIndex, position: "fixed", top: 0, left: 0, overflow: "hidden" }), this.$slider.addClass("parallax-slider").one("load", function () { h.naturalHeight && h.naturalWidth || (h.naturalHeight = this.naturalHeight || this.height || 1, h.naturalWidth = this.naturalWidth || this.width || 1), h.aspectRatio = h.naturalWidth / h.naturalHeight, o.isSetup || o.setup(), o.sliders.push(h), o.isFresh = !1, o.requestRender() }), n || (this.$slider[0].src = this.imageSrc), (this.naturalHeight && this.naturalWidth || this.$slider[0].complete || a.length > 0) && this.$slider.trigger("load") } !function () { for (var t = 0, e = ["ms", "moz", "webkit", "o"], s = 0; s < e.length && !i.requestAnimationFrame; ++s)i.requestAnimationFrame = i[e[s] + "RequestAnimationFrame"], i.cancelAnimationFrame = i[e[s] + "CancelAnimationFrame"] || i[e[s] + "CancelRequestAnimationFrame"]; i.requestAnimationFrame || (i.requestAnimationFrame = function (e) { var s = (new Date).getTime(), o = Math.max(0, 16 - (s - t)), h = i.setTimeout(function () { e(s + o) }, o); return t = s + o, h }), i.cancelAnimationFrame || (i.cancelAnimationFrame = function (t) { clearTimeout(t) }) }(), t.extend(o.prototype, { speed: .2, bleed: 0, zIndex: -100, iosFix: !0, androidFix: !0, position: "center", overScrollFix: !1, mirrorContainer: "body", refresh: function () { this.boxWidth = this.$element.outerWidth(), this.boxHeight = this.$element.outerHeight() + 2 * this.bleed, this.boxOffsetTop = this.$element.offset().top - this.bleed, this.boxOffsetLeft = this.$element.offset().left, this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight; var t, i = o.winHeight, e = o.docHeight, s = Math.min(this.boxOffsetTop, e - i), h = Math.max(this.boxOffsetTop + this.boxHeight - i, 0), r = this.boxHeight + (s - h) * (1 - this.speed) | 0, a = (this.boxOffsetTop - s) * (1 - this.speed) | 0; r * this.aspectRatio >= this.boxWidth ? (this.imageWidth = r * this.aspectRatio | 0, this.imageHeight = r, this.offsetBaseTop = a, t = this.imageWidth - this.boxWidth, "left" == this.positionX ? this.offsetLeft = 0 : "right" == this.positionX ? this.offsetLeft = -t : isNaN(this.positionX) ? this.offsetLeft = -t / 2 | 0 : this.offsetLeft = Math.max(this.positionX, -t)) : (this.imageWidth = this.boxWidth, this.imageHeight = this.boxWidth / this.aspectRatio | 0, this.offsetLeft = 0, t = this.imageHeight - r, "top" == this.positionY ? this.offsetBaseTop = a : "bottom" == this.positionY ? this.offsetBaseTop = a - t : isNaN(this.positionY) ? this.offsetBaseTop = a - t / 2 | 0 : this.offsetBaseTop = a + Math.max(this.positionY, -t)) }, render: function () { var t = o.scrollTop, i = o.scrollLeft, e = this.overScrollFix ? o.overScroll : 0, s = t + o.winHeight; this.boxOffsetBottom > t && this.boxOffsetTop <= s ? (this.visibility = "visible", this.mirrorTop = this.boxOffsetTop - t, this.mirrorLeft = this.boxOffsetLeft - i, this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed)) : this.visibility = "hidden", this.$mirror.css({ transform: "translate3d(" + this.mirrorLeft + "px, " + (this.mirrorTop - e) + "px, 0px)", visibility: this.visibility, height: this.boxHeight, width: this.boxWidth }), this.$slider.css({ transform: "translate3d(" + this.offsetLeft + "px, " + this.offsetTop + "px, 0px)", position: "absolute", height: this.imageHeight, width: this.imageWidth, maxWidth: "none" }) } }), t.extend(o, { scrollTop: 0, scrollLeft: 0, winHeight: 0, winWidth: 0, docHeight: 1 << 30, docWidth: 1 << 30, sliders: [], isReady: !1, isFresh: !1, isBusy: !1, setup: function () { function s() { if (p == i.pageYOffset) return i.requestAnimationFrame(s), !1; p = i.pageYOffset, h.render(), i.requestAnimationFrame(s) } if (!this.isReady) { var h = this, r = t(e), a = t(i), n = function () { o.winHeight = a.height(), o.winWidth = a.width(), o.docHeight = r.height(), o.docWidth = r.width() }, l = function () { var t = a.scrollTop(), i = o.docHeight - o.winHeight, e = o.docWidth - o.winWidth; o.scrollTop = Math.max(0, Math.min(i, t)), o.scrollLeft = Math.max(0, Math.min(e, a.scrollLeft())), o.overScroll = Math.max(t - i, Math.min(t, 0)) }; a.on("resize.px.parallax load.px.parallax", function () { n(), h.refresh(), o.isFresh = !1, o.requestRender() }).on("scroll.px.parallax load.px.parallax", function () { l(), o.requestRender() }), n(), l(), this.isReady = !0; var p = -1; s() } }, configure: function (i) { "object" == typeof i && (delete i.refresh, delete i.render, t.extend(this.prototype, i)) }, refresh: function () { t.each(this.sliders, function () { this.refresh() }), this.isFresh = !0 }, render: function () { this.isFresh || this.refresh(), t.each(this.sliders, function () { this.render() }) }, requestRender: function () { var t = this; t.render(), t.isBusy = !1 }, destroy: function (e) { var s, h = t(e).data("px.parallax"); for (h.$mirror.remove(), s = 0; s < this.sliders.length; s += 1)this.sliders[s] == h && this.sliders.splice(s, 1); t(e).data("px.parallax", !1), 0 === this.sliders.length && (t(i).off("scroll.px.parallax resize.px.parallax load.px.parallax"), this.isReady = !1, o.isSetup = !1) } }); var h = t.fn.parallax; t.fn.parallax = function (s) { return this.each(function () { var h = t(this), r = "object" == typeof s && s; this == i || this == e || h.is("body") ? o.configure(r) : h.data("px.parallax") ? "object" == typeof s && t.extend(h.data("px.parallax"), r) : (r = t.extend({}, h.data(), r), h.data("px.parallax", new o(this, r))), "string" == typeof s && ("destroy" == s ? o.destroy(this) : o[s]()) }) }, t.fn.parallax.Constructor = o, t.fn.parallax.noConflict = function () { return t.fn.parallax = h, this }, t(function () { t('[data-parallax="scroll"]').parallax() }) }(jQuery, window, document);





!function (e, t) { "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define([], t) : "object" == typeof exports ? exports.AOS = t() : e.AOS = t() }(this, function () { return function (e) { function t(o) { if (n[o]) return n[o].exports; var i = n[o] = { exports: {}, id: o, loaded: !1 }; return e[o].call(i.exports, i, i.exports, t), i.loaded = !0, i.exports } var n = {}; return t.m = e, t.c = n, t.p = "dist/", t(0) }([function (e, t, n) { "use strict"; function o(e) { return e && e.__esModule ? e : { default: e } } var i = Object.assign || function (e) { for (var t = 1; t < arguments.length; t++) { var n = arguments[t]; for (var o in n) Object.prototype.hasOwnProperty.call(n, o) && (e[o] = n[o]) } return e }, r = n(1), a = (o(r), n(6)), u = o(a), c = n(7), f = o(c), s = n(8), d = o(s), l = n(9), p = o(l), m = n(10), b = o(m), v = n(11), y = o(v), g = n(14), h = o(g), w = [], k = !1, x = document.all && !window.atob, j = { offset: 120, delay: 0, easing: "ease", duration: 400, disable: !1, once: !1, startEvent: "DOMContentLoaded" }, O = function () { var e = arguments.length > 0 && void 0 !== arguments[0] && arguments[0]; if (e && (k = !0), k) return w = (0, y.default)(w, j), (0, b.default)(w, j.once), w }, S = function () { w = (0, h.default)(), O() }, _ = function () { w.forEach(function (e, t) { e.node.removeAttribute("data-aos"), e.node.removeAttribute("data-aos-easing"), e.node.removeAttribute("data-aos-duration"), e.node.removeAttribute("data-aos-delay") }) }, E = function (e) { return e === !0 || "mobile" === e && p.default.mobile() || "phone" === e && p.default.phone() || "tablet" === e && p.default.tablet() || "function" == typeof e && e() === !0 }, z = function (e) { return j = i(j, e), w = (0, h.default)(), E(j.disable) || x ? _() : (document.querySelector("body").setAttribute("data-aos-easing", j.easing), document.querySelector("body").setAttribute("data-aos-duration", j.duration), document.querySelector("body").setAttribute("data-aos-delay", j.delay), "DOMContentLoaded" === j.startEvent && ["complete", "interactive"].indexOf(document.readyState) > -1 ? O(!0) : "load" === j.startEvent ? window.addEventListener(j.startEvent, function () { O(!0) }) : document.addEventListener(j.startEvent, function () { O(!0) }), window.addEventListener("resize", (0, f.default)(O, 50, !0)), window.addEventListener("orientationchange", (0, f.default)(O, 50, !0)), window.addEventListener("scroll", (0, u.default)(function () { (0, b.default)(w, j.once) }, 99)), document.addEventListener("DOMNodeRemoved", function (e) { var t = e.target; t && 1 === t.nodeType && t.hasAttribute && t.hasAttribute("data-aos") && (0, f.default)(S, 50, !0) }), (0, d.default)("[data-aos]", S), w) }; e.exports = { init: z, refresh: O, refreshHard: S } }, function (e, t) { }, , , , , function (e, t) { (function (t) { "use strict"; function n(e, t, n) { function o(t) { var n = b, o = v; return b = v = void 0, k = t, g = e.apply(o, n) } function r(e) { return k = e, h = setTimeout(s, t), S ? o(e) : g } function a(e) { var n = e - w, o = e - k, i = t - n; return _ ? j(i, y - o) : i } function c(e) { var n = e - w, o = e - k; return void 0 === w || n >= t || n < 0 || _ && o >= y } function s() { var e = O(); return c(e) ? d(e) : void (h = setTimeout(s, a(e))) } function d(e) { return h = void 0, E && b ? o(e) : (b = v = void 0, g) } function l() { void 0 !== h && clearTimeout(h), k = 0, b = w = v = h = void 0 } function p() { return void 0 === h ? g : d(O()) } function m() { var e = O(), n = c(e); if (b = arguments, v = this, w = e, n) { if (void 0 === h) return r(w); if (_) return h = setTimeout(s, t), o(w) } return void 0 === h && (h = setTimeout(s, t)), g } var b, v, y, g, h, w, k = 0, S = !1, _ = !1, E = !0; if ("function" != typeof e) throw new TypeError(f); return t = u(t) || 0, i(n) && (S = !!n.leading, _ = "maxWait" in n, y = _ ? x(u(n.maxWait) || 0, t) : y, E = "trailing" in n ? !!n.trailing : E), m.cancel = l, m.flush = p, m } function o(e, t, o) { var r = !0, a = !0; if ("function" != typeof e) throw new TypeError(f); return i(o) && (r = "leading" in o ? !!o.leading : r, a = "trailing" in o ? !!o.trailing : a), n(e, t, { leading: r, maxWait: t, trailing: a }) } function i(e) { var t = "undefined" == typeof e ? "undefined" : c(e); return !!e && ("object" == t || "function" == t) } function r(e) { return !!e && "object" == ("undefined" == typeof e ? "undefined" : c(e)) } function a(e) { return "symbol" == ("undefined" == typeof e ? "undefined" : c(e)) || r(e) && k.call(e) == d } function u(e) { if ("number" == typeof e) return e; if (a(e)) return s; if (i(e)) { var t = "function" == typeof e.valueOf ? e.valueOf() : e; e = i(t) ? t + "" : t } if ("string" != typeof e) return 0 === e ? e : +e; e = e.replace(l, ""); var n = m.test(e); return n || b.test(e) ? v(e.slice(2), n ? 2 : 8) : p.test(e) ? s : +e } var c = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e }, f = "Expected a function", s = NaN, d = "[object Symbol]", l = /^\s+|\s+$/g, p = /^[-+]0x[0-9a-f]+$/i, m = /^0b[01]+$/i, b = /^0o[0-7]+$/i, v = parseInt, y = "object" == ("undefined" == typeof t ? "undefined" : c(t)) && t && t.Object === Object && t, g = "object" == ("undefined" == typeof self ? "undefined" : c(self)) && self && self.Object === Object && self, h = y || g || Function("return this")(), w = Object.prototype, k = w.toString, x = Math.max, j = Math.min, O = function () { return h.Date.now() }; e.exports = o }).call(t, function () { return this }()) }, function (e, t) { (function (t) { "use strict"; function n(e, t, n) { function i(t) { var n = b, o = v; return b = v = void 0, O = t, g = e.apply(o, n) } function r(e) { return O = e, h = setTimeout(s, t), S ? i(e) : g } function u(e) { var n = e - w, o = e - O, i = t - n; return _ ? x(i, y - o) : i } function f(e) { var n = e - w, o = e - O; return void 0 === w || n >= t || n < 0 || _ && o >= y } function s() { var e = j(); return f(e) ? d(e) : void (h = setTimeout(s, u(e))) } function d(e) { return h = void 0, E && b ? i(e) : (b = v = void 0, g) } function l() { void 0 !== h && clearTimeout(h), O = 0, b = w = v = h = void 0 } function p() { return void 0 === h ? g : d(j()) } function m() { var e = j(), n = f(e); if (b = arguments, v = this, w = e, n) { if (void 0 === h) return r(w); if (_) return h = setTimeout(s, t), i(w) } return void 0 === h && (h = setTimeout(s, t)), g } var b, v, y, g, h, w, O = 0, S = !1, _ = !1, E = !0; if ("function" != typeof e) throw new TypeError(c); return t = a(t) || 0, o(n) && (S = !!n.leading, _ = "maxWait" in n, y = _ ? k(a(n.maxWait) || 0, t) : y, E = "trailing" in n ? !!n.trailing : E), m.cancel = l, m.flush = p, m } function o(e) { var t = "undefined" == typeof e ? "undefined" : u(e); return !!e && ("object" == t || "function" == t) } function i(e) { return !!e && "object" == ("undefined" == typeof e ? "undefined" : u(e)) } function r(e) { return "symbol" == ("undefined" == typeof e ? "undefined" : u(e)) || i(e) && w.call(e) == s } function a(e) { if ("number" == typeof e) return e; if (r(e)) return f; if (o(e)) { var t = "function" == typeof e.valueOf ? e.valueOf() : e; e = o(t) ? t + "" : t } if ("string" != typeof e) return 0 === e ? e : +e; e = e.replace(d, ""); var n = p.test(e); return n || m.test(e) ? b(e.slice(2), n ? 2 : 8) : l.test(e) ? f : +e } var u = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) { return typeof e } : function (e) { return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e }, c = "Expected a function", f = NaN, s = "[object Symbol]", d = /^\s+|\s+$/g, l = /^[-+]0x[0-9a-f]+$/i, p = /^0b[01]+$/i, m = /^0o[0-7]+$/i, b = parseInt, v = "object" == ("undefined" == typeof t ? "undefined" : u(t)) && t && t.Object === Object && t, y = "object" == ("undefined" == typeof self ? "undefined" : u(self)) && self && self.Object === Object && self, g = v || y || Function("return this")(), h = Object.prototype, w = h.toString, k = Math.max, x = Math.min, j = function () { return g.Date.now() }; e.exports = n }).call(t, function () { return this }()) }, function (e, t) { "use strict"; function n(e, t) { a.push({ selector: e, fn: t }), !u && r && (u = new r(o), u.observe(i.documentElement, { childList: !0, subtree: !0, removedNodes: !0 })), o() } function o() { for (var e, t, n = 0, o = a.length; n < o; n++) { e = a[n], t = i.querySelectorAll(e.selector); for (var r, u = 0, c = t.length; u < c; u++)r = t[u], r.ready || (r.ready = !0, e.fn.call(r, r)) } } Object.defineProperty(t, "__esModule", { value: !0 }); var i = window.document, r = window.MutationObserver || window.WebKitMutationObserver, a = [], u = void 0; t.default = n }, function (e, t) { "use strict"; function n(e, t) { if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") } function o() { return navigator.userAgent || navigator.vendor || window.opera || "" } Object.defineProperty(t, "__esModule", { value: !0 }); var i = function () { function e(e, t) { for (var n = 0; n < t.length; n++) { var o = t[n]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, o.key, o) } } return function (t, n, o) { return n && e(t.prototype, n), o && e(t, o), t } }(), r = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i, a = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i, u = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i, c = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i, f = function () { function e() { n(this, e) } return i(e, [{ key: "phone", value: function () { var e = o(); return !(!r.test(e) && !a.test(e.substr(0, 4))) } }, { key: "mobile", value: function () { var e = o(); return !(!u.test(e) && !c.test(e.substr(0, 4))) } }, { key: "tablet", value: function () { return this.mobile() && !this.phone() } }]), e }(); t.default = new f }, function (e, t) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); var n = function (e, t, n) { var o = e.node.getAttribute("data-aos-once"); t > e.position ? e.node.classList.add("aos-animate") : "undefined" != typeof o && ("false" === o || !n && "true" !== o) && e.node.classList.remove("aos-animate") }, o = function (e, t) { var o = window.pageYOffset, i = window.innerHeight; e.forEach(function (e, r) { n(e, i + o, t) }) }; t.default = o }, function (e, t, n) { "use strict"; function o(e) { return e && e.__esModule ? e : { default: e } } Object.defineProperty(t, "__esModule", { value: !0 }); var i = n(12), r = o(i), a = function (e, t) { return e.forEach(function (e, n) { e.node.classList.add("aos-init"), e.position = (0, r.default)(e.node, t.offset) }), e }; t.default = a }, function (e, t, n) { "use strict"; function o(e) { return e && e.__esModule ? e : { default: e } } Object.defineProperty(t, "__esModule", { value: !0 }); var i = n(13), r = o(i), a = function (e, t) { var n = 0, o = 0, i = window.innerHeight, a = { offset: e.getAttribute("data-aos-offset"), anchor: e.getAttribute("data-aos-anchor"), anchorPlacement: e.getAttribute("data-aos-anchor-placement") }; switch (a.offset && !isNaN(a.offset) && (o = parseInt(a.offset)), a.anchor && document.querySelectorAll(a.anchor) && (e = document.querySelectorAll(a.anchor)[0]), n = (0, r.default)(e).top, a.anchorPlacement) { case "top-bottom": break; case "center-bottom": n += e.offsetHeight / 2; break; case "bottom-bottom": n += e.offsetHeight; break; case "top-center": n += i / 2; break; case "bottom-center": n += i / 2 + e.offsetHeight; break; case "center-center": n += i / 2 + e.offsetHeight / 2; break; case "top-top": n += i; break; case "bottom-top": n += e.offsetHeight + i; break; case "center-top": n += e.offsetHeight / 2 + i }return a.anchorPlacement || a.offset || isNaN(t) || (o = t), n + o }; t.default = a }, function (e, t) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); var n = function (e) { for (var t = 0, n = 0; e && !isNaN(e.offsetLeft) && !isNaN(e.offsetTop);)t += e.offsetLeft - ("BODY" != e.tagName ? e.scrollLeft : 0), n += e.offsetTop - ("BODY" != e.tagName ? e.scrollTop : 0), e = e.offsetParent; return { top: n, left: t } }; t.default = n }, function (e, t) { "use strict"; Object.defineProperty(t, "__esModule", { value: !0 }); var n = function (e) { e = e || document.querySelectorAll("[data-aos]"); var t = []; return [].forEach.call(e, function (e, n) { t.push({ node: e }) }), t }; t.default = n }]) });
//# sourceMappingURL=aos.js.map



/**
 * SimpleBar.js - v3.1.0
 * Scrollbars, simpler.
 * https://grsmto.github.io/simplebar/
 * 
 * Made by Adrien Denat from a fork by Jonathan Nicol
 * Under MIT License
 */

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
            (global.SimpleBar = factory());
}(this, (function () {
    'use strict';

    var _isObject = function (it) {
        return typeof it === 'object' ? it !== null : typeof it === 'function';
    };

    var _anObject = function (it) {
        if (!_isObject(it)) throw TypeError(it + ' is not an object!');
        return it;
    };

    var _fails = function (exec) {
        try {
            return !!exec();
        } catch (e) {
            return true;
        }
    };

    // Thank's IE8 for his funny defineProperty
    var _descriptors = !_fails(function () {
        return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
    });

    var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    function createCommonjsModule(fn, module) {
        return module = { exports: {} }, fn(module, module.exports), module.exports;
    }

    var _global = createCommonjsModule(function (module) {
        // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
        var global = module.exports = typeof window != 'undefined' && window.Math == Math
            ? window : typeof self != 'undefined' && self.Math == Math ? self
                // eslint-disable-next-line no-new-func
                : Function('return this')();
        if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
    });

    var document$1 = _global.document;
    // typeof document.createElement is 'object' in old IE
    var is = _isObject(document$1) && _isObject(document$1.createElement);
    var _domCreate = function (it) {
        return is ? document$1.createElement(it) : {};
    };

    var _ie8DomDefine = !_descriptors && !_fails(function () {
        return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7;
    });

    // 7.1.1 ToPrimitive(input [, PreferredType])

    // instead of the ES6 spec version, we didn't implement @@toPrimitive case
    // and the second argument - flag - preferred type is a string
    var _toPrimitive = function (it, S) {
        if (!_isObject(it)) return it;
        var fn, val;
        if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
        if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
        if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
        throw TypeError("Can't convert object to primitive value");
    };

    var dP = Object.defineProperty;

    var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
        _anObject(O);
        P = _toPrimitive(P, true);
        _anObject(Attributes);
        if (_ie8DomDefine) try {
            return dP(O, P, Attributes);
        } catch (e) { /* empty */ }
        if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
        if ('value' in Attributes) O[P] = Attributes.value;
        return O;
    };

    var _objectDp = {
        f: f
    };

    var _propertyDesc = function (bitmap, value) {
        return {
            enumerable: !(bitmap & 1),
            configurable: !(bitmap & 2),
            writable: !(bitmap & 4),
            value: value
        };
    };

    var _hide = _descriptors ? function (object, key, value) {
        return _objectDp.f(object, key, _propertyDesc(1, value));
    } : function (object, key, value) {
        object[key] = value;
        return object;
    };

    var hasOwnProperty = {}.hasOwnProperty;
    var _has = function (it, key) {
        return hasOwnProperty.call(it, key);
    };

    var id = 0;
    var px = Math.random();
    var _uid = function (key) {
        return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
    };

    var _core = createCommonjsModule(function (module) {
        var core = module.exports = { version: '2.5.7' };
        if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
    });
    var _core_1 = _core.version;

    var _redefine = createCommonjsModule(function (module) {
        var SRC = _uid('src');
        var TO_STRING = 'toString';
        var $toString = Function[TO_STRING];
        var TPL = ('' + $toString).split(TO_STRING);

        _core.inspectSource = function (it) {
            return $toString.call(it);
        };

        (module.exports = function (O, key, val, safe) {
            var isFunction = typeof val == 'function';
            if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
            if (O[key] === val) return;
            if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
            if (O === _global) {
                O[key] = val;
            } else if (!safe) {
                delete O[key];
                _hide(O, key, val);
            } else if (O[key]) {
                O[key] = val;
            } else {
                _hide(O, key, val);
            }
            // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
        })(Function.prototype, TO_STRING, function toString() {
            return typeof this == 'function' && this[SRC] || $toString.call(this);
        });
    });

    // 7.2.1 RequireObjectCoercible(argument)
    var _defined = function (it) {
        if (it == undefined) throw TypeError("Can't call method on  " + it);
        return it;
    };

    var _library = false;

    var _shared = createCommonjsModule(function (module) {
        var SHARED = '__core-js_shared__';
        var store = _global[SHARED] || (_global[SHARED] = {});

        (module.exports = function (key, value) {
            return store[key] || (store[key] = value !== undefined ? value : {});
        })('versions', []).push({
            version: _core.version,
            mode: _library ? 'pure' : 'global',
            copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
        });
    });

    var _wks = createCommonjsModule(function (module) {
        var store = _shared('wks');

        var Symbol = _global.Symbol;
        var USE_SYMBOL = typeof Symbol == 'function';

        var $exports = module.exports = function (name) {
            return store[name] || (store[name] =
                USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name));
        };

        $exports.store = store;
    });

    var _fixReWks = function (KEY, length, exec) {
        var SYMBOL = _wks(KEY);
        var fns = exec(_defined, SYMBOL, ''[KEY]);
        var strfn = fns[0];
        var rxfn = fns[1];
        if (_fails(function () {
            var O = {};
            O[SYMBOL] = function () { return 7; };
            return ''[KEY](O) != 7;
        })) {
            _redefine(String.prototype, KEY, strfn);
            _hide(RegExp.prototype, SYMBOL, length == 2
                // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
                // 21.2.5.11 RegExp.prototype[@@split](string, limit)
                ? function (string, arg) { return rxfn.call(string, this, arg); }
                // 21.2.5.6 RegExp.prototype[@@match](string)
                // 21.2.5.9 RegExp.prototype[@@search](string)
                : function (string) { return rxfn.call(string, this); }
            );
        }
    };

    // @@replace logic
    _fixReWks('replace', 2, function (defined, REPLACE, $replace) {
        // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
        return [function replace(searchValue, replaceValue) {
            var O = defined(this);
            var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
            return fn !== undefined
                ? fn.call(searchValue, O, replaceValue)
                : $replace.call(String(O), searchValue, replaceValue);
        }, $replace];
    });

    var dP$1 = _objectDp.f;
    var FProto = Function.prototype;
    var nameRE = /^\s*function ([^ (]*)/;
    var NAME = 'name';

    // 19.2.4.2 name
    NAME in FProto || _descriptors && dP$1(FProto, NAME, {
        configurable: true,
        get: function () {
            try {
                return ('' + this).match(nameRE)[1];
            } catch (e) {
                return '';
            }
        }
    });

    // @@match logic
    _fixReWks('match', 1, function (defined, MATCH, $match) {
        // 21.1.3.11 String.prototype.match(regexp)
        return [function match(regexp) {
            var O = defined(this);
            var fn = regexp == undefined ? undefined : regexp[MATCH];
            return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
        }, $match];
    });

    // 22.1.3.31 Array.prototype[@@unscopables]
    var UNSCOPABLES = _wks('unscopables');
    var ArrayProto = Array.prototype;
    if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
    var _addToUnscopables = function (key) {
        ArrayProto[UNSCOPABLES][key] = true;
    };

    var _iterStep = function (done, value) {
        return { value: value, done: !!done };
    };

    var _iterators = {};

    var toString = {}.toString;

    var _cof = function (it) {
        return toString.call(it).slice(8, -1);
    };

    // fallback for non-array-like ES3 and non-enumerable old V8 strings

    // eslint-disable-next-line no-prototype-builtins
    var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
        return _cof(it) == 'String' ? it.split('') : Object(it);
    };

    // to indexed object, toObject with fallback for non-array-like ES3 strings


    var _toIobject = function (it) {
        return _iobject(_defined(it));
    };

    var _aFunction = function (it) {
        if (typeof it != 'function') throw TypeError(it + ' is not a function!');
        return it;
    };

    // optional / simple context binding

    var _ctx = function (fn, that, length) {
        _aFunction(fn);
        if (that === undefined) return fn;
        switch (length) {
            case 1: return function (a) {
                return fn.call(that, a);
            };
            case 2: return function (a, b) {
                return fn.call(that, a, b);
            };
            case 3: return function (a, b, c) {
                return fn.call(that, a, b, c);
            };
        }
        return function (/* ...args */) {
            return fn.apply(that, arguments);
        };
    };

    var PROTOTYPE = 'prototype';

    var $export = function (type, name, source) {
        var IS_FORCED = type & $export.F;
        var IS_GLOBAL = type & $export.G;
        var IS_STATIC = type & $export.S;
        var IS_PROTO = type & $export.P;
        var IS_BIND = type & $export.B;
        var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
        var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
        var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
        var key, own, out, exp;
        if (IS_GLOBAL) source = name;
        for (key in source) {
            // contains in native
            own = !IS_FORCED && target && target[key] !== undefined;
            // export native or passed
            out = (own ? target : source)[key];
            // bind timers to global for call from export context
            exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
            // extend global
            if (target) _redefine(target, key, out, type & $export.U);
            // export
            if (exports[key] != out) _hide(exports, key, exp);
            if (IS_PROTO && expProto[key] != out) expProto[key] = out;
        }
    };
    _global.core = _core;
    // type bitmap
    $export.F = 1;   // forced
    $export.G = 2;   // global
    $export.S = 4;   // static
    $export.P = 8;   // proto
    $export.B = 16;  // bind
    $export.W = 32;  // wrap
    $export.U = 64;  // safe
    $export.R = 128; // real proto method for `library`
    var _export = $export;

    // 7.1.4 ToInteger
    var ceil = Math.ceil;
    var floor = Math.floor;
    var _toInteger = function (it) {
        return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
    };

    // 7.1.15 ToLength

    var min = Math.min;
    var _toLength = function (it) {
        return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
    };

    var max = Math.max;
    var min$1 = Math.min;
    var _toAbsoluteIndex = function (index, length) {
        index = _toInteger(index);
        return index < 0 ? max(index + length, 0) : min$1(index, length);
    };

    // false -> Array#indexOf
    // true  -> Array#includes



    var _arrayIncludes = function (IS_INCLUDES) {
        return function ($this, el, fromIndex) {
            var O = _toIobject($this);
            var length = _toLength(O.length);
            var index = _toAbsoluteIndex(fromIndex, length);
            var value;
            // Array#includes uses SameValueZero equality algorithm
            // eslint-disable-next-line no-self-compare
            if (IS_INCLUDES && el != el) while (length > index) {
                value = O[index++];
                // eslint-disable-next-line no-self-compare
                if (value != value) return true;
                // Array#indexOf ignores holes, Array#includes - not
            } else for (; length > index; index++) if (IS_INCLUDES || index in O) {
                if (O[index] === el) return IS_INCLUDES || index || 0;
            } return !IS_INCLUDES && -1;
        };
    };

    var shared = _shared('keys');

    var _sharedKey = function (key) {
        return shared[key] || (shared[key] = _uid(key));
    };

    var arrayIndexOf = _arrayIncludes(false);
    var IE_PROTO = _sharedKey('IE_PROTO');

    var _objectKeysInternal = function (object, names) {
        var O = _toIobject(object);
        var i = 0;
        var result = [];
        var key;
        for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key);
        // Don't enum bug & hidden keys
        while (names.length > i) if (_has(O, key = names[i++])) {
            ~arrayIndexOf(result, key) || result.push(key);
        }
        return result;
    };

    // IE 8- don't enum bug keys
    var _enumBugKeys = (
        'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
    ).split(',');

    // 19.1.2.14 / 15.2.3.14 Object.keys(O)



    var _objectKeys = Object.keys || function keys(O) {
        return _objectKeysInternal(O, _enumBugKeys);
    };

    var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
        _anObject(O);
        var keys = _objectKeys(Properties);
        var length = keys.length;
        var i = 0;
        var P;
        while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]);
        return O;
    };

    var document$2 = _global.document;
    var _html = document$2 && document$2.documentElement;

    // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])



    var IE_PROTO$1 = _sharedKey('IE_PROTO');
    var Empty = function () { /* empty */ };
    var PROTOTYPE$1 = 'prototype';

    // Create object with fake `null` prototype: use iframe Object with cleared prototype
    var createDict = function () {
        // Thrash, waste and sodomy: IE GC bug
        var iframe = _domCreate('iframe');
        var i = _enumBugKeys.length;
        var lt = '<';
        var gt = '>';
        var iframeDocument;
        iframe.style.display = 'none';
        _html.appendChild(iframe);
        iframe.src = 'javascript:'; // eslint-disable-line no-script-url
        // createDict = iframe.contentWindow.Object;
        // html.removeChild(iframe);
        iframeDocument = iframe.contentWindow.document;
        iframeDocument.open();
        iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
        iframeDocument.close();
        createDict = iframeDocument.F;
        while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]];
        return createDict();
    };

    var _objectCreate = Object.create || function create(O, Properties) {
        var result;
        if (O !== null) {
            Empty[PROTOTYPE$1] = _anObject(O);
            result = new Empty();
            Empty[PROTOTYPE$1] = null;
            // add "__proto__" for Object.getPrototypeOf polyfill
            result[IE_PROTO$1] = O;
        } else result = createDict();
        return Properties === undefined ? result : _objectDps(result, Properties);
    };

    var def = _objectDp.f;

    var TAG = _wks('toStringTag');

    var _setToStringTag = function (it, tag, stat) {
        if (it && !_has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
    };

    var IteratorPrototype = {};

    // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
    _hide(IteratorPrototype, _wks('iterator'), function () { return this; });

    var _iterCreate = function (Constructor, NAME, next) {
        Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) });
        _setToStringTag(Constructor, NAME + ' Iterator');
    };

    // 7.1.13 ToObject(argument)

    var _toObject = function (it) {
        return Object(_defined(it));
    };

    // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)


    var IE_PROTO$2 = _sharedKey('IE_PROTO');
    var ObjectProto = Object.prototype;

    var _objectGpo = Object.getPrototypeOf || function (O) {
        O = _toObject(O);
        if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
        if (typeof O.constructor == 'function' && O instanceof O.constructor) {
            return O.constructor.prototype;
        } return O instanceof Object ? ObjectProto : null;
    };

    var ITERATOR = _wks('iterator');
    var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
    var FF_ITERATOR = '@@iterator';
    var KEYS = 'keys';
    var VALUES = 'values';

    var returnThis = function () { return this; };

    var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
        _iterCreate(Constructor, NAME, next);
        var getMethod = function (kind) {
            if (!BUGGY && kind in proto) return proto[kind];
            switch (kind) {
                case KEYS: return function keys() { return new Constructor(this, kind); };
                case VALUES: return function values() { return new Constructor(this, kind); };
            } return function entries() { return new Constructor(this, kind); };
        };
        var TAG = NAME + ' Iterator';
        var DEF_VALUES = DEFAULT == VALUES;
        var VALUES_BUG = false;
        var proto = Base.prototype;
        var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
        var $default = $native || getMethod(DEFAULT);
        var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
        var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
        var methods, key, IteratorPrototype;
        // Fix native
        if ($anyNative) {
            IteratorPrototype = _objectGpo($anyNative.call(new Base()));
            if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
                // Set @@toStringTag to native iterators
                _setToStringTag(IteratorPrototype, TAG, true);
                // fix for some old engines
                if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis);
            }
        }
        // fix Array#{values, @@iterator}.name in V8 / FF
        if (DEF_VALUES && $native && $native.name !== VALUES) {
            VALUES_BUG = true;
            $default = function values() { return $native.call(this); };
        }
        // Define iterator
        if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
            _hide(proto, ITERATOR, $default);
        }
        // Plug for library
        _iterators[NAME] = $default;
        _iterators[TAG] = returnThis;
        if (DEFAULT) {
            methods = {
                values: DEF_VALUES ? $default : getMethod(VALUES),
                keys: IS_SET ? $default : getMethod(KEYS),
                entries: $entries
            };
            if (FORCED) for (key in methods) {
                if (!(key in proto)) _redefine(proto, key, methods[key]);
            } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
        }
        return methods;
    };

    // 22.1.3.4 Array.prototype.entries()
    // 22.1.3.13 Array.prototype.keys()
    // 22.1.3.29 Array.prototype.values()
    // 22.1.3.30 Array.prototype[@@iterator]()
    var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
        this._t = _toIobject(iterated); // target
        this._i = 0;                   // next index
        this._k = kind;                // kind
        // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
    }, function () {
        var O = this._t;
        var kind = this._k;
        var index = this._i++;
        if (!O || index >= O.length) {
            this._t = undefined;
            return _iterStep(1);
        }
        if (kind == 'keys') return _iterStep(0, index);
        if (kind == 'values') return _iterStep(0, O[index]);
        return _iterStep(0, [index, O[index]]);
    }, 'values');

    // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
    _iterators.Arguments = _iterators.Array;

    _addToUnscopables('keys');
    _addToUnscopables('values');
    _addToUnscopables('entries');

    var ITERATOR$1 = _wks('iterator');
    var TO_STRING_TAG = _wks('toStringTag');
    var ArrayValues = _iterators.Array;

    var DOMIterables = {
        CSSRuleList: true, // TODO: Not spec compliant, should be false.
        CSSStyleDeclaration: false,
        CSSValueList: false,
        ClientRectList: false,
        DOMRectList: false,
        DOMStringList: false,
        DOMTokenList: true,
        DataTransferItemList: false,
        FileList: false,
        HTMLAllCollection: false,
        HTMLCollection: false,
        HTMLFormElement: false,
        HTMLSelectElement: false,
        MediaList: true, // TODO: Not spec compliant, should be false.
        MimeTypeArray: false,
        NamedNodeMap: false,
        NodeList: true,
        PaintRequestList: false,
        Plugin: false,
        PluginArray: false,
        SVGLengthList: false,
        SVGNumberList: false,
        SVGPathSegList: false,
        SVGPointList: false,
        SVGStringList: false,
        SVGTransformList: false,
        SourceBufferList: false,
        StyleSheetList: true, // TODO: Not spec compliant, should be false.
        TextTrackCueList: false,
        TextTrackList: false,
        TouchList: false
    };

    for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
        var NAME$1 = collections[i];
        var explicit = DOMIterables[NAME$1];
        var Collection = _global[NAME$1];
        var proto = Collection && Collection.prototype;
        var key;
        if (proto) {
            if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
            if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME$1);
            _iterators[NAME$1] = ArrayValues;
            if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
        }
    }

    // true  -> String#at
    // false -> String#codePointAt
    var _stringAt = function (TO_STRING) {
        return function (that, pos) {
            var s = String(_defined(that));
            var i = _toInteger(pos);
            var l = s.length;
            var a, b;
            if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
            a = s.charCodeAt(i);
            return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
                ? TO_STRING ? s.charAt(i) : a
                : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
        };
    };

    var $at = _stringAt(true);

    // 21.1.3.27 String.prototype[@@iterator]()
    _iterDefine(String, 'String', function (iterated) {
        this._t = String(iterated); // target
        this._i = 0;                // next index
        // 21.1.5.2.1 %StringIteratorPrototype%.next()
    }, function () {
        var O = this._t;
        var index = this._i;
        var point;
        if (index >= O.length) return { value: undefined, done: true };
        point = $at(O, index);
        this._i += point.length;
        return { value: point, done: false };
    });

    // call something on iterator step with safe closing on error

    var _iterCall = function (iterator, fn, value, entries) {
        try {
            return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
            // 7.4.6 IteratorClose(iterator, completion)
        } catch (e) {
            var ret = iterator['return'];
            if (ret !== undefined) _anObject(ret.call(iterator));
            throw e;
        }
    };

    // check on default Array iterator

    var ITERATOR$2 = _wks('iterator');
    var ArrayProto$1 = Array.prototype;

    var _isArrayIter = function (it) {
        return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it);
    };

    var _createProperty = function (object, index, value) {
        if (index in object) _objectDp.f(object, index, _propertyDesc(0, value));
        else object[index] = value;
    };

    // getting tag from 19.1.3.6 Object.prototype.toString()

    var TAG$1 = _wks('toStringTag');
    // ES3 wrong here
    var ARG = _cof(function () { return arguments; }()) == 'Arguments';

    // fallback for IE11 Script Access Denied error
    var tryGet = function (it, key) {
        try {
            return it[key];
        } catch (e) { /* empty */ }
    };

    var _classof = function (it) {
        var O, T, B;
        return it === undefined ? 'Undefined' : it === null ? 'Null'
            // @@toStringTag case
            : typeof (T = tryGet(O = Object(it), TAG$1)) == 'string' ? T
                // builtinTag case
                : ARG ? _cof(O)
                    // ES3 arguments fallback
                    : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
    };

    var ITERATOR$3 = _wks('iterator');

    var core_getIteratorMethod = _core.getIteratorMethod = function (it) {
        if (it != undefined) return it[ITERATOR$3]
            || it['@@iterator']
            || _iterators[_classof(it)];
    };

    var ITERATOR$4 = _wks('iterator');
    var SAFE_CLOSING = false;

    try {
        var riter = [7][ITERATOR$4]();
        riter['return'] = function () { SAFE_CLOSING = true; };
    } catch (e) { /* empty */ }

    var _iterDetect = function (exec, skipClosing) {
        if (!skipClosing && !SAFE_CLOSING) return false;
        var safe = false;
        try {
            var arr = [7];
            var iter = arr[ITERATOR$4]();
            iter.next = function () { return { done: safe = true }; };
            arr[ITERATOR$4] = function () { return iter; };
            exec(arr);
        } catch (e) { /* empty */ }
        return safe;
    };

    _export(_export.S + _export.F * !_iterDetect(function (iter) { }), 'Array', {
        // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
        from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
            var O = _toObject(arrayLike);
            var C = typeof this == 'function' ? this : Array;
            var aLen = arguments.length;
            var mapfn = aLen > 1 ? arguments[1] : undefined;
            var mapping = mapfn !== undefined;
            var index = 0;
            var iterFn = core_getIteratorMethod(O);
            var length, result, step, iterator;
            if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
            // if object isn't iterable or it's array with default iterator - use simple case
            if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) {
                for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
                    _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
                }
            } else {
                length = _toLength(O.length);
                for (result = new C(length); length > index; index++) {
                    _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
                }
            }
            result.length = index;
            return result;
        }
    });

    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }

    function _defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    function _createClass(Constructor, protoProps, staticProps) {
        if (protoProps) _defineProperties(Constructor.prototype, protoProps);
        if (staticProps) _defineProperties(Constructor, staticProps);
        return Constructor;
    }

    function _defineProperty(obj, key, value) {
        if (key in obj) {
            Object.defineProperty(obj, key, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true
            });
        } else {
            obj[key] = value;
        }

        return obj;
    }

    function _objectSpread(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i] != null ? arguments[i] : {};
            var ownKeys = Object.keys(source);

            if (typeof Object.getOwnPropertySymbols === 'function') {
                ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
                    return Object.getOwnPropertyDescriptor(source, sym).enumerable;
                }));
            }

            ownKeys.forEach(function (key) {
                _defineProperty(target, key, source[key]);
            });
        }

        return target;
    }

    var scrollbarWidth = createCommonjsModule(function (module, exports) {
        /*! scrollbarWidth.js v0.1.3 | felixexter | MIT | https://github.com/felixexter/scrollbarWidth */
        (function (root, factory) {
            {
                module.exports = factory();
            }
        }(commonjsGlobal, function () {

            function scrollbarWidth() {
                if (typeof document === 'undefined') {
                    return 0
                }

                var
                    body = document.body,
                    box = document.createElement('div'),
                    boxStyle = box.style,
                    width;

                boxStyle.position = 'absolute';
                boxStyle.top = boxStyle.left = '-9999px';
                boxStyle.width = boxStyle.height = '100px';
                boxStyle.overflow = 'scroll';

                body.appendChild(box);

                width = box.offsetWidth - box.clientWidth;

                body.removeChild(box);

                return width;
            }

            return scrollbarWidth;
        }));
    });

	/**
	 * lodash (Custom Build) <https://lodash.com/>
	 * Build: `lodash modularize exports="npm" -o ./`
	 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
	 * Released under MIT license <https://lodash.com/license>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT = 'Expected a function';

    /** Used as references for various `Number` constants. */
    var NAN = 0 / 0;

    /** `Object#toString` result references. */
    var symbolTag = '[object Symbol]';

    /** Used to match leading and trailing whitespace. */
    var reTrim = /^\s+|\s+$/g;

    /** Used to detect bad signed hexadecimal string values. */
    var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

    /** Used to detect binary string values. */
    var reIsBinary = /^0b[01]+$/i;

    /** Used to detect octal string values. */
    var reIsOctal = /^0o[0-7]+$/i;

    /** Built-in method references without a dependency on `root`. */
    var freeParseInt = parseInt;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root = freeGlobal || freeSelf || Function('return this')();

    /** Used for built-in method references. */
    var objectProto = Object.prototype;

	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
    var objectToString = objectProto.toString;

    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeMax = Math.max,
        nativeMin = Math.min;

	/**
	 * Gets the timestamp of the number of milliseconds that have elapsed since
	 * the Unix epoch (1 January 1970 00:00:00 UTC).
	 *
	 * @static
	 * @memberOf _
	 * @since 2.4.0
	 * @category Date
	 * @returns {number} Returns the timestamp.
	 * @example
	 *
	 * _.defer(function(stamp) {
	 *   console.log(_.now() - stamp);
	 * }, _.now());
	 * // => Logs the number of milliseconds it took for the deferred invocation.
	 */
    var now = function () {
        return root.Date.now();
    };

	/**
	 * Creates a debounced function that delays invoking `func` until after `wait`
	 * milliseconds have elapsed since the last time the debounced function was
	 * invoked. The debounced function comes with a `cancel` method to cancel
	 * delayed `func` invocations and a `flush` method to immediately invoke them.
	 * Provide `options` to indicate whether `func` should be invoked on the
	 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
	 * with the last arguments provided to the debounced function. Subsequent
	 * calls to the debounced function return the result of the last `func`
	 * invocation.
	 *
	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
	 * invoked on the trailing edge of the timeout only if the debounced function
	 * is invoked more than once during the `wait` timeout.
	 *
	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	 *
	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	 * for details over the differences between `_.debounce` and `_.throttle`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to debounce.
	 * @param {number} [wait=0] The number of milliseconds to delay.
	 * @param {Object} [options={}] The options object.
	 * @param {boolean} [options.leading=false]
	 *  Specify invoking on the leading edge of the timeout.
	 * @param {number} [options.maxWait]
	 *  The maximum time `func` is allowed to be delayed before it's invoked.
	 * @param {boolean} [options.trailing=true]
	 *  Specify invoking on the trailing edge of the timeout.
	 * @returns {Function} Returns the new debounced function.
	 * @example
	 *
	 * // Avoid costly calculations while the window size is in flux.
	 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
	 *
	 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
	 * jQuery(element).on('click', _.debounce(sendMail, 300, {
	 *   'leading': true,
	 *   'trailing': false
	 * }));
	 *
	 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
	 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
	 * var source = new EventSource('/stream');
	 * jQuery(source).on('message', debounced);
	 *
	 * // Cancel the trailing debounced invocation.
	 * jQuery(window).on('popstate', debounced.cancel);
	 */
    function debounce(func, wait, options) {
        var lastArgs,
            lastThis,
            maxWait,
            result,
            timerId,
            lastCallTime,
            lastInvokeTime = 0,
            leading = false,
            maxing = false,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
        }
        wait = toNumber(wait) || 0;
        if (isObject(options)) {
            leading = !!options.leading;
            maxing = 'maxWait' in options;
            maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }

        function invokeFunc(time) {
            var args = lastArgs,
                thisArg = lastThis;

            lastArgs = lastThis = undefined;
            lastInvokeTime = time;
            result = func.apply(thisArg, args);
            return result;
        }

        function leadingEdge(time) {
            // Reset any `maxWait` timer.
            lastInvokeTime = time;
            // Start the timer for the trailing edge.
            timerId = setTimeout(timerExpired, wait);
            // Invoke the leading edge.
            return leading ? invokeFunc(time) : result;
        }

        function remainingWait(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime,
                result = wait - timeSinceLastCall;

            return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
        }

        function shouldInvoke(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime;

            // Either this is the first call, activity has stopped and we're at the
            // trailing edge, the system time has gone backwards and we're treating
            // it as the trailing edge, or we've hit the `maxWait` limit.
            return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
                (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
        }

        function timerExpired() {
            var time = now();
            if (shouldInvoke(time)) {
                return trailingEdge(time);
            }
            // Restart the timer.
            timerId = setTimeout(timerExpired, remainingWait(time));
        }

        function trailingEdge(time) {
            timerId = undefined;

            // Only invoke if we have `lastArgs` which means `func` has been
            // debounced at least once.
            if (trailing && lastArgs) {
                return invokeFunc(time);
            }
            lastArgs = lastThis = undefined;
            return result;
        }

        function cancel() {
            if (timerId !== undefined) {
                clearTimeout(timerId);
            }
            lastInvokeTime = 0;
            lastArgs = lastCallTime = lastThis = timerId = undefined;
        }

        function flush() {
            return timerId === undefined ? result : trailingEdge(now());
        }

        function debounced() {
            var time = now(),
                isInvoking = shouldInvoke(time);

            lastArgs = arguments;
            lastThis = this;
            lastCallTime = time;

            if (isInvoking) {
                if (timerId === undefined) {
                    return leadingEdge(lastCallTime);
                }
                if (maxing) {
                    // Handle invocations in a tight loop.
                    timerId = setTimeout(timerExpired, wait);
                    return invokeFunc(lastCallTime);
                }
            }
            if (timerId === undefined) {
                timerId = setTimeout(timerExpired, wait);
            }
            return result;
        }
        debounced.cancel = cancel;
        debounced.flush = flush;
        return debounced;
    }

	/**
	 * Creates a throttled function that only invokes `func` at most once per
	 * every `wait` milliseconds. The throttled function comes with a `cancel`
	 * method to cancel delayed `func` invocations and a `flush` method to
	 * immediately invoke them. Provide `options` to indicate whether `func`
	 * should be invoked on the leading and/or trailing edge of the `wait`
	 * timeout. The `func` is invoked with the last arguments provided to the
	 * throttled function. Subsequent calls to the throttled function return the
	 * result of the last `func` invocation.
	 *
	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
	 * invoked on the trailing edge of the timeout only if the throttled function
	 * is invoked more than once during the `wait` timeout.
	 *
	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	 *
	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	 * for details over the differences between `_.throttle` and `_.debounce`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to throttle.
	 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
	 * @param {Object} [options={}] The options object.
	 * @param {boolean} [options.leading=true]
	 *  Specify invoking on the leading edge of the timeout.
	 * @param {boolean} [options.trailing=true]
	 *  Specify invoking on the trailing edge of the timeout.
	 * @returns {Function} Returns the new throttled function.
	 * @example
	 *
	 * // Avoid excessively updating the position while scrolling.
	 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
	 *
	 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
	 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
	 * jQuery(element).on('click', throttled);
	 *
	 * // Cancel the trailing throttled invocation.
	 * jQuery(window).on('popstate', throttled.cancel);
	 */
    function throttle(func, wait, options) {
        var leading = true,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT);
        }
        if (isObject(options)) {
            leading = 'leading' in options ? !!options.leading : leading;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }
        return debounce(func, wait, {
            'leading': leading,
            'maxWait': wait,
            'trailing': trailing
        });
    }

	/**
	 * Checks if `value` is the
	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(_.noop);
	 * // => true
	 *
	 * _.isObject(null);
	 * // => false
	 */
    function isObject(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

	/**
	 * Checks if `value` is object-like. A value is object-like if it's not `null`
	 * and has a `typeof` result of "object".
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
	 * @example
	 *
	 * _.isObjectLike({});
	 * // => true
	 *
	 * _.isObjectLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isObjectLike(_.noop);
	 * // => false
	 *
	 * _.isObjectLike(null);
	 * // => false
	 */
    function isObjectLike(value) {
        return !!value && typeof value == 'object';
    }

	/**
	 * Checks if `value` is classified as a `Symbol` primitive or object.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
	 * @example
	 *
	 * _.isSymbol(Symbol.iterator);
	 * // => true
	 *
	 * _.isSymbol('abc');
	 * // => false
	 */
    function isSymbol(value) {
        return typeof value == 'symbol' ||
            (isObjectLike(value) && objectToString.call(value) == symbolTag);
    }

	/**
	 * Converts `value` to a number.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to process.
	 * @returns {number} Returns the number.
	 * @example
	 *
	 * _.toNumber(3.2);
	 * // => 3.2
	 *
	 * _.toNumber(Number.MIN_VALUE);
	 * // => 5e-324
	 *
	 * _.toNumber(Infinity);
	 * // => Infinity
	 *
	 * _.toNumber('3.2');
	 * // => 3.2
	 */
    function toNumber(value) {
        if (typeof value == 'number') {
            return value;
        }
        if (isSymbol(value)) {
            return NAN;
        }
        if (isObject(value)) {
            var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
            value = isObject(other) ? (other + '') : other;
        }
        if (typeof value != 'string') {
            return value === 0 ? value : +value;
        }
        value = value.replace(reTrim, '');
        var isBinary = reIsBinary.test(value);
        return (isBinary || reIsOctal.test(value))
            ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
            : (reIsBadHex.test(value) ? NAN : +value);
    }

    var lodash_throttle = throttle;

	/**
	 * lodash (Custom Build) <https://lodash.com/>
	 * Build: `lodash modularize exports="npm" -o ./`
	 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
	 * Released under MIT license <https://lodash.com/license>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT$1 = 'Expected a function';

    /** Used as references for various `Number` constants. */
    var NAN$1 = 0 / 0;

    /** `Object#toString` result references. */
    var symbolTag$1 = '[object Symbol]';

    /** Used to match leading and trailing whitespace. */
    var reTrim$1 = /^\s+|\s+$/g;

    /** Used to detect bad signed hexadecimal string values. */
    var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i;

    /** Used to detect binary string values. */
    var reIsBinary$1 = /^0b[01]+$/i;

    /** Used to detect octal string values. */
    var reIsOctal$1 = /^0o[0-7]+$/i;

    /** Built-in method references without a dependency on `root`. */
    var freeParseInt$1 = parseInt;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')();

    /** Used for built-in method references. */
    var objectProto$1 = Object.prototype;

	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
    var objectToString$1 = objectProto$1.toString;

    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeMax$1 = Math.max,
        nativeMin$1 = Math.min;

	/**
	 * Gets the timestamp of the number of milliseconds that have elapsed since
	 * the Unix epoch (1 January 1970 00:00:00 UTC).
	 *
	 * @static
	 * @memberOf _
	 * @since 2.4.0
	 * @category Date
	 * @returns {number} Returns the timestamp.
	 * @example
	 *
	 * _.defer(function(stamp) {
	 *   console.log(_.now() - stamp);
	 * }, _.now());
	 * // => Logs the number of milliseconds it took for the deferred invocation.
	 */
    var now$1 = function () {
        return root$1.Date.now();
    };

	/**
	 * Creates a debounced function that delays invoking `func` until after `wait`
	 * milliseconds have elapsed since the last time the debounced function was
	 * invoked. The debounced function comes with a `cancel` method to cancel
	 * delayed `func` invocations and a `flush` method to immediately invoke them.
	 * Provide `options` to indicate whether `func` should be invoked on the
	 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
	 * with the last arguments provided to the debounced function. Subsequent
	 * calls to the debounced function return the result of the last `func`
	 * invocation.
	 *
	 * **Note:** If `leading` and `trailing` options are `true`, `func` is
	 * invoked on the trailing edge of the timeout only if the debounced function
	 * is invoked more than once during the `wait` timeout.
	 *
	 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	 *
	 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	 * for details over the differences between `_.debounce` and `_.throttle`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to debounce.
	 * @param {number} [wait=0] The number of milliseconds to delay.
	 * @param {Object} [options={}] The options object.
	 * @param {boolean} [options.leading=false]
	 *  Specify invoking on the leading edge of the timeout.
	 * @param {number} [options.maxWait]
	 *  The maximum time `func` is allowed to be delayed before it's invoked.
	 * @param {boolean} [options.trailing=true]
	 *  Specify invoking on the trailing edge of the timeout.
	 * @returns {Function} Returns the new debounced function.
	 * @example
	 *
	 * // Avoid costly calculations while the window size is in flux.
	 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
	 *
	 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
	 * jQuery(element).on('click', _.debounce(sendMail, 300, {
	 *   'leading': true,
	 *   'trailing': false
	 * }));
	 *
	 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
	 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
	 * var source = new EventSource('/stream');
	 * jQuery(source).on('message', debounced);
	 *
	 * // Cancel the trailing debounced invocation.
	 * jQuery(window).on('popstate', debounced.cancel);
	 */
    function debounce$1(func, wait, options) {
        var lastArgs,
            lastThis,
            maxWait,
            result,
            timerId,
            lastCallTime,
            lastInvokeTime = 0,
            leading = false,
            maxing = false,
            trailing = true;

        if (typeof func != 'function') {
            throw new TypeError(FUNC_ERROR_TEXT$1);
        }
        wait = toNumber$1(wait) || 0;
        if (isObject$1(options)) {
            leading = !!options.leading;
            maxing = 'maxWait' in options;
            maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait;
            trailing = 'trailing' in options ? !!options.trailing : trailing;
        }

        function invokeFunc(time) {
            var args = lastArgs,
                thisArg = lastThis;

            lastArgs = lastThis = undefined;
            lastInvokeTime = time;
            result = func.apply(thisArg, args);
            return result;
        }

        function leadingEdge(time) {
            // Reset any `maxWait` timer.
            lastInvokeTime = time;
            // Start the timer for the trailing edge.
            timerId = setTimeout(timerExpired, wait);
            // Invoke the leading edge.
            return leading ? invokeFunc(time) : result;
        }

        function remainingWait(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime,
                result = wait - timeSinceLastCall;

            return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result;
        }

        function shouldInvoke(time) {
            var timeSinceLastCall = time - lastCallTime,
                timeSinceLastInvoke = time - lastInvokeTime;

            // Either this is the first call, activity has stopped and we're at the
            // trailing edge, the system time has gone backwards and we're treating
            // it as the trailing edge, or we've hit the `maxWait` limit.
            return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
                (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
        }

        function timerExpired() {
            var time = now$1();
            if (shouldInvoke(time)) {
                return trailingEdge(time);
            }
            // Restart the timer.
            timerId = setTimeout(timerExpired, remainingWait(time));
        }

        function trailingEdge(time) {
            timerId = undefined;

            // Only invoke if we have `lastArgs` which means `func` has been
            // debounced at least once.
            if (trailing && lastArgs) {
                return invokeFunc(time);
            }
            lastArgs = lastThis = undefined;
            return result;
        }

        function cancel() {
            if (timerId !== undefined) {
                clearTimeout(timerId);
            }
            lastInvokeTime = 0;
            lastArgs = lastCallTime = lastThis = timerId = undefined;
        }

        function flush() {
            return timerId === undefined ? result : trailingEdge(now$1());
        }

        function debounced() {
            var time = now$1(),
                isInvoking = shouldInvoke(time);

            lastArgs = arguments;
            lastThis = this;
            lastCallTime = time;

            if (isInvoking) {
                if (timerId === undefined) {
                    return leadingEdge(lastCallTime);
                }
                if (maxing) {
                    // Handle invocations in a tight loop.
                    timerId = setTimeout(timerExpired, wait);
                    return invokeFunc(lastCallTime);
                }
            }
            if (timerId === undefined) {
                timerId = setTimeout(timerExpired, wait);
            }
            return result;
        }
        debounced.cancel = cancel;
        debounced.flush = flush;
        return debounced;
    }

	/**
	 * Checks if `value` is the
	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(_.noop);
	 * // => true
	 *
	 * _.isObject(null);
	 * // => false
	 */
    function isObject$1(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

	/**
	 * Checks if `value` is object-like. A value is object-like if it's not `null`
	 * and has a `typeof` result of "object".
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
	 * @example
	 *
	 * _.isObjectLike({});
	 * // => true
	 *
	 * _.isObjectLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isObjectLike(_.noop);
	 * // => false
	 *
	 * _.isObjectLike(null);
	 * // => false
	 */
    function isObjectLike$1(value) {
        return !!value && typeof value == 'object';
    }

	/**
	 * Checks if `value` is classified as a `Symbol` primitive or object.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
	 * @example
	 *
	 * _.isSymbol(Symbol.iterator);
	 * // => true
	 *
	 * _.isSymbol('abc');
	 * // => false
	 */
    function isSymbol$1(value) {
        return typeof value == 'symbol' ||
            (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1);
    }

	/**
	 * Converts `value` to a number.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to process.
	 * @returns {number} Returns the number.
	 * @example
	 *
	 * _.toNumber(3.2);
	 * // => 3.2
	 *
	 * _.toNumber(Number.MIN_VALUE);
	 * // => 5e-324
	 *
	 * _.toNumber(Infinity);
	 * // => Infinity
	 *
	 * _.toNumber('3.2');
	 * // => 3.2
	 */
    function toNumber$1(value) {
        if (typeof value == 'number') {
            return value;
        }
        if (isSymbol$1(value)) {
            return NAN$1;
        }
        if (isObject$1(value)) {
            var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
            value = isObject$1(other) ? (other + '') : other;
        }
        if (typeof value != 'string') {
            return value === 0 ? value : +value;
        }
        value = value.replace(reTrim$1, '');
        var isBinary = reIsBinary$1.test(value);
        return (isBinary || reIsOctal$1.test(value))
            ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8)
            : (reIsBadHex$1.test(value) ? NAN$1 : +value);
    }

    var lodash_debounce = debounce$1;

	/**
	 * lodash (Custom Build) <https://lodash.com/>
	 * Build: `lodash modularize exports="npm" -o ./`
	 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
	 * Released under MIT license <https://lodash.com/license>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 */

    /** Used as the `TypeError` message for "Functions" methods. */
    var FUNC_ERROR_TEXT$2 = 'Expected a function';

    /** Used to stand-in for `undefined` hash values. */
    var HASH_UNDEFINED = '__lodash_hash_undefined__';

    /** `Object#toString` result references. */
    var funcTag = '[object Function]',
        genTag = '[object GeneratorFunction]';

	/**
	 * Used to match `RegExp`
	 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
	 */
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

    /** Used to detect host constructors (Safari). */
    var reIsHostCtor = /^\[object .+?Constructor\]$/;

    /** Detect free variable `global` from Node.js. */
    var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

    /** Detect free variable `self`. */
    var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self;

    /** Used as a reference to the global object. */
    var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')();

	/**
	 * Gets the value at `key` of `object`.
	 *
	 * @private
	 * @param {Object} [object] The object to query.
	 * @param {string} key The key of the property to get.
	 * @returns {*} Returns the property value.
	 */
    function getValue(object, key) {
        return object == null ? undefined : object[key];
    }

	/**
	 * Checks if `value` is a host object in IE < 9.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
	 */
    function isHostObject(value) {
        // Many host objects are `Object` objects that can coerce to strings
        // despite having improperly defined `toString` methods.
        var result = false;
        if (value != null && typeof value.toString != 'function') {
            try {
                result = !!(value + '');
            } catch (e) { }
        }
        return result;
    }

    /** Used for built-in method references. */
    var arrayProto = Array.prototype,
        funcProto = Function.prototype,
        objectProto$2 = Object.prototype;

    /** Used to detect overreaching core-js shims. */
    var coreJsData = root$2['__core-js_shared__'];

    /** Used to detect methods masquerading as native. */
    var maskSrcKey = (function () {
        var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
        return uid ? ('Symbol(src)_1.' + uid) : '';
    }());

    /** Used to resolve the decompiled source of functions. */
    var funcToString = funcProto.toString;

    /** Used to check objects for own properties. */
    var hasOwnProperty$1 = objectProto$2.hasOwnProperty;

	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
    var objectToString$2 = objectProto$2.toString;

    /** Used to detect if a method is native. */
    var reIsNative = RegExp('^' +
        funcToString.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
            .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
    );

    /** Built-in value references. */
    var splice = arrayProto.splice;

    /* Built-in method references that are verified to be native. */
    var Map$1 = getNative(root$2, 'Map'),
        nativeCreate = getNative(Object, 'create');

	/**
	 * Creates a hash object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
    function Hash(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

	/**
	 * Removes all key-value entries from the hash.
	 *
	 * @private
	 * @name clear
	 * @memberOf Hash
	 */
    function hashClear() {
        this.__data__ = nativeCreate ? nativeCreate(null) : {};
    }

	/**
	 * Removes `key` and its value from the hash.
	 *
	 * @private
	 * @name delete
	 * @memberOf Hash
	 * @param {Object} hash The hash to modify.
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
    function hashDelete(key) {
        return this.has(key) && delete this.__data__[key];
    }

	/**
	 * Gets the hash value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf Hash
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
    function hashGet(key) {
        var data = this.__data__;
        if (nativeCreate) {
            var result = data[key];
            return result === HASH_UNDEFINED ? undefined : result;
        }
        return hasOwnProperty$1.call(data, key) ? data[key] : undefined;
    }

	/**
	 * Checks if a hash value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf Hash
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
    function hashHas(key) {
        var data = this.__data__;
        return nativeCreate ? data[key] !== undefined : hasOwnProperty$1.call(data, key);
    }

	/**
	 * Sets the hash `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf Hash
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the hash instance.
	 */
    function hashSet(key, value) {
        var data = this.__data__;
        data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
        return this;
    }

    // Add methods to `Hash`.
    Hash.prototype.clear = hashClear;
    Hash.prototype['delete'] = hashDelete;
    Hash.prototype.get = hashGet;
    Hash.prototype.has = hashHas;
    Hash.prototype.set = hashSet;

	/**
	 * Creates an list cache object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
    function ListCache(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

	/**
	 * Removes all key-value entries from the list cache.
	 *
	 * @private
	 * @name clear
	 * @memberOf ListCache
	 */
    function listCacheClear() {
        this.__data__ = [];
    }

	/**
	 * Removes `key` and its value from the list cache.
	 *
	 * @private
	 * @name delete
	 * @memberOf ListCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
    function listCacheDelete(key) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        if (index < 0) {
            return false;
        }
        var lastIndex = data.length - 1;
        if (index == lastIndex) {
            data.pop();
        } else {
            splice.call(data, index, 1);
        }
        return true;
    }

	/**
	 * Gets the list cache value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf ListCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
    function listCacheGet(key) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        return index < 0 ? undefined : data[index][1];
    }

	/**
	 * Checks if a list cache value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf ListCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
    function listCacheHas(key) {
        return assocIndexOf(this.__data__, key) > -1;
    }

	/**
	 * Sets the list cache `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf ListCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the list cache instance.
	 */
    function listCacheSet(key, value) {
        var data = this.__data__,
            index = assocIndexOf(data, key);

        if (index < 0) {
            data.push([key, value]);
        } else {
            data[index][1] = value;
        }
        return this;
    }

    // Add methods to `ListCache`.
    ListCache.prototype.clear = listCacheClear;
    ListCache.prototype['delete'] = listCacheDelete;
    ListCache.prototype.get = listCacheGet;
    ListCache.prototype.has = listCacheHas;
    ListCache.prototype.set = listCacheSet;

	/**
	 * Creates a map cache object to store key-value pairs.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
    function MapCache(entries) {
        var index = -1,
            length = entries ? entries.length : 0;

        this.clear();
        while (++index < length) {
            var entry = entries[index];
            this.set(entry[0], entry[1]);
        }
    }

	/**
	 * Removes all key-value entries from the map.
	 *
	 * @private
	 * @name clear
	 * @memberOf MapCache
	 */
    function mapCacheClear() {
        this.__data__ = {
            'hash': new Hash,
            'map': new (Map$1 || ListCache),
            'string': new Hash
        };
    }

	/**
	 * Removes `key` and its value from the map.
	 *
	 * @private
	 * @name delete
	 * @memberOf MapCache
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
    function mapCacheDelete(key) {
        return getMapData(this, key)['delete'](key);
    }

	/**
	 * Gets the map value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf MapCache
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
    function mapCacheGet(key) {
        return getMapData(this, key).get(key);
    }

	/**
	 * Checks if a map value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf MapCache
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
    function mapCacheHas(key) {
        return getMapData(this, key).has(key);
    }

	/**
	 * Sets the map `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf MapCache
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the map cache instance.
	 */
    function mapCacheSet(key, value) {
        getMapData(this, key).set(key, value);
        return this;
    }

    // Add methods to `MapCache`.
    MapCache.prototype.clear = mapCacheClear;
    MapCache.prototype['delete'] = mapCacheDelete;
    MapCache.prototype.get = mapCacheGet;
    MapCache.prototype.has = mapCacheHas;
    MapCache.prototype.set = mapCacheSet;

	/**
	 * Gets the index at which the `key` is found in `array` of key-value pairs.
	 *
	 * @private
	 * @param {Array} array The array to inspect.
	 * @param {*} key The key to search for.
	 * @returns {number} Returns the index of the matched value, else `-1`.
	 */
    function assocIndexOf(array, key) {
        var length = array.length;
        while (length--) {
            if (eq(array[length][0], key)) {
                return length;
            }
        }
        return -1;
    }

	/**
	 * The base implementation of `_.isNative` without bad shim checks.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a native function,
	 *  else `false`.
	 */
    function baseIsNative(value) {
        if (!isObject$2(value) || isMasked(value)) {
            return false;
        }
        var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
        return pattern.test(toSource(value));
    }

	/**
	 * Gets the data for `map`.
	 *
	 * @private
	 * @param {Object} map The map to query.
	 * @param {string} key The reference key.
	 * @returns {*} Returns the map data.
	 */
    function getMapData(map, key) {
        var data = map.__data__;
        return isKeyable(key)
            ? data[typeof key == 'string' ? 'string' : 'hash']
            : data.map;
    }

	/**
	 * Gets the native function at `key` of `object`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {string} key The key of the method to get.
	 * @returns {*} Returns the function if it's native, else `undefined`.
	 */
    function getNative(object, key) {
        var value = getValue(object, key);
        return baseIsNative(value) ? value : undefined;
    }

	/**
	 * Checks if `value` is suitable for use as unique object key.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
	 */
    function isKeyable(value) {
        var type = typeof value;
        return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
            ? (value !== '__proto__')
            : (value === null);
    }

	/**
	 * Checks if `func` has its source masked.
	 *
	 * @private
	 * @param {Function} func The function to check.
	 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
	 */
    function isMasked(func) {
        return !!maskSrcKey && (maskSrcKey in func);
    }

	/**
	 * Converts `func` to its source code.
	 *
	 * @private
	 * @param {Function} func The function to process.
	 * @returns {string} Returns the source code.
	 */
    function toSource(func) {
        if (func != null) {
            try {
                return funcToString.call(func);
            } catch (e) { }
            try {
                return (func + '');
            } catch (e) { }
        }
        return '';
    }

	/**
	 * Creates a function that memoizes the result of `func`. If `resolver` is
	 * provided, it determines the cache key for storing the result based on the
	 * arguments provided to the memoized function. By default, the first argument
	 * provided to the memoized function is used as the map cache key. The `func`
	 * is invoked with the `this` binding of the memoized function.
	 *
	 * **Note:** The cache is exposed as the `cache` property on the memoized
	 * function. Its creation may be customized by replacing the `_.memoize.Cache`
	 * constructor with one whose instances implement the
	 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
	 * method interface of `delete`, `get`, `has`, and `set`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Function
	 * @param {Function} func The function to have its output memoized.
	 * @param {Function} [resolver] The function to resolve the cache key.
	 * @returns {Function} Returns the new memoized function.
	 * @example
	 *
	 * var object = { 'a': 1, 'b': 2 };
	 * var other = { 'c': 3, 'd': 4 };
	 *
	 * var values = _.memoize(_.values);
	 * values(object);
	 * // => [1, 2]
	 *
	 * values(other);
	 * // => [3, 4]
	 *
	 * object.a = 2;
	 * values(object);
	 * // => [1, 2]
	 *
	 * // Modify the result cache.
	 * values.cache.set(object, ['a', 'b']);
	 * values(object);
	 * // => ['a', 'b']
	 *
	 * // Replace `_.memoize.Cache`.
	 * _.memoize.Cache = WeakMap;
	 */
    function memoize(func, resolver) {
        if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
            throw new TypeError(FUNC_ERROR_TEXT$2);
        }
        var memoized = function () {
            var args = arguments,
                key = resolver ? resolver.apply(this, args) : args[0],
                cache = memoized.cache;

            if (cache.has(key)) {
                return cache.get(key);
            }
            var result = func.apply(this, args);
            memoized.cache = cache.set(key, result);
            return result;
        };
        memoized.cache = new (memoize.Cache || MapCache);
        return memoized;
    }

    // Assign cache to `_.memoize`.
    memoize.Cache = MapCache;

	/**
	 * Performs a
	 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	 * comparison between two values to determine if they are equivalent.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to compare.
	 * @param {*} other The other value to compare.
	 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	 * @example
	 *
	 * var object = { 'a': 1 };
	 * var other = { 'a': 1 };
	 *
	 * _.eq(object, object);
	 * // => true
	 *
	 * _.eq(object, other);
	 * // => false
	 *
	 * _.eq('a', 'a');
	 * // => true
	 *
	 * _.eq('a', Object('a'));
	 * // => false
	 *
	 * _.eq(NaN, NaN);
	 * // => true
	 */
    function eq(value, other) {
        return value === other || (value !== value && other !== other);
    }

	/**
	 * Checks if `value` is classified as a `Function` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
	 * @example
	 *
	 * _.isFunction(_);
	 * // => true
	 *
	 * _.isFunction(/abc/);
	 * // => false
	 */
    function isFunction(value) {
        // The use of `Object#toString` avoids issues with the `typeof` operator
        // in Safari 8-9 which returns 'object' for typed array and other constructors.
        var tag = isObject$2(value) ? objectToString$2.call(value) : '';
        return tag == funcTag || tag == genTag;
    }

	/**
	 * Checks if `value` is the
	 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
	 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
	 * @example
	 *
	 * _.isObject({});
	 * // => true
	 *
	 * _.isObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isObject(_.noop);
	 * // => true
	 *
	 * _.isObject(null);
	 * // => false
	 */
    function isObject$2(value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    }

    var lodash_memoize = memoize;

	/**
	 * A collection of shims that provide minimal functionality of the ES6 collections.
	 *
	 * These implementations are not meant to be used outside of the ResizeObserver
	 * modules as they cover only a limited range of use cases.
	 */
    /* eslint-disable require-jsdoc, valid-jsdoc */
    var MapShim = (function () {
        if (typeof Map !== 'undefined') {
            return Map;
        }

		/**
		 * Returns index in provided array that matches the specified key.
		 *
		 * @param {Array<Array>} arr
		 * @param {*} key
		 * @returns {number}
		 */
        function getIndex(arr, key) {
            var result = -1;

            arr.some(function (entry, index) {
                if (entry[0] === key) {
                    result = index;

                    return true;
                }

                return false;
            });

            return result;
        }

        return (function () {
            function anonymous() {
                this.__entries__ = [];
            }

            var prototypeAccessors = { size: { configurable: true } };

			/**
			 * @returns {boolean}
			 */
            prototypeAccessors.size.get = function () {
                return this.__entries__.length;
            };

			/**
			 * @param {*} key
			 * @returns {*}
			 */
            anonymous.prototype.get = function (key) {
                var index = getIndex(this.__entries__, key);
                var entry = this.__entries__[index];

                return entry && entry[1];
            };

			/**
			 * @param {*} key
			 * @param {*} value
			 * @returns {void}
			 */
            anonymous.prototype.set = function (key, value) {
                var index = getIndex(this.__entries__, key);

                if (~index) {
                    this.__entries__[index][1] = value;
                } else {
                    this.__entries__.push([key, value]);
                }
            };

			/**
			 * @param {*} key
			 * @returns {void}
			 */
            anonymous.prototype.delete = function (key) {
                var entries = this.__entries__;
                var index = getIndex(entries, key);

                if (~index) {
                    entries.splice(index, 1);
                }
            };

			/**
			 * @param {*} key
			 * @returns {void}
			 */
            anonymous.prototype.has = function (key) {
                return !!~getIndex(this.__entries__, key);
            };

			/**
			 * @returns {void}
			 */
            anonymous.prototype.clear = function () {
                this.__entries__.splice(0);
            };

			/**
			 * @param {Function} callback
			 * @param {*} [ctx=null]
			 * @returns {void}
			 */
            anonymous.prototype.forEach = function (callback, ctx) {
                var this$1 = this;
                if (ctx === void 0) ctx = null;

                for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) {
                    var entry = list[i];

                    callback.call(ctx, entry[1], entry[0]);
                }
            };

            Object.defineProperties(anonymous.prototype, prototypeAccessors);

            return anonymous;
        }());
    })();

	/**
	 * Detects whether window and document objects are available in current environment.
	 */
    var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;

    // Returns global object of a current environment.
    var global$1 = (function () {
        if (typeof global !== 'undefined' && global.Math === Math) {
            return global;
        }

        if (typeof self !== 'undefined' && self.Math === Math) {
            return self;
        }

        if (typeof window !== 'undefined' && window.Math === Math) {
            return window;
        }

        // eslint-disable-next-line no-new-func
        return Function('return this')();
    })();

	/**
	 * A shim for the requestAnimationFrame which falls back to the setTimeout if
	 * first one is not supported.
	 *
	 * @returns {number} Requests' identifier.
	 */
    var requestAnimationFrame$1 = (function () {
        if (typeof requestAnimationFrame === 'function') {
            // It's required to use a bounded function because IE sometimes throws
            // an "Invalid calling object" error if rAF is invoked without the global
            // object on the left hand side.
            return requestAnimationFrame.bind(global$1);
        }

        return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
    })();

    // Defines minimum timeout before adding a trailing call.
    var trailingTimeout = 2;

	/**
	 * Creates a wrapper function which ensures that provided callback will be
	 * invoked only once during the specified delay period.
	 *
	 * @param {Function} callback - Function to be invoked after the delay period.
	 * @param {number} delay - Delay after which to invoke callback.
	 * @returns {Function}
	 */
    var throttle$1 = function (callback, delay) {
        var leadingCall = false,
            trailingCall = false,
            lastCallTime = 0;

		/**
		 * Invokes the original callback function and schedules new invocation if
		 * the "proxy" was called during current request.
		 *
		 * @returns {void}
		 */
        function resolvePending() {
            if (leadingCall) {
                leadingCall = false;

                callback();
            }

            if (trailingCall) {
                proxy();
            }
        }

		/**
		 * Callback invoked after the specified delay. It will further postpone
		 * invocation of the original function delegating it to the
		 * requestAnimationFrame.
		 *
		 * @returns {void}
		 */
        function timeoutCallback() {
            requestAnimationFrame$1(resolvePending);
        }

		/**
		 * Schedules invocation of the original function.
		 *
		 * @returns {void}
		 */
        function proxy() {
            var timeStamp = Date.now();

            if (leadingCall) {
                // Reject immediately following calls.
                if (timeStamp - lastCallTime < trailingTimeout) {
                    return;
                }

                // Schedule new call to be in invoked when the pending one is resolved.
                // This is important for "transitions" which never actually start
                // immediately so there is a chance that we might miss one if change
                // happens amids the pending invocation.
                trailingCall = true;
            } else {
                leadingCall = true;
                trailingCall = false;

                setTimeout(timeoutCallback, delay);
            }

            lastCallTime = timeStamp;
        }

        return proxy;
    };

    // Minimum delay before invoking the update of observers.
    var REFRESH_DELAY = 20;

    // A list of substrings of CSS properties used to find transition events that
    // might affect dimensions of observed elements.
    var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];

    // Check if MutationObserver is available.
    var mutationObserverSupported = typeof MutationObserver !== 'undefined';

	/**
	 * Singleton controller class which handles updates of ResizeObserver instances.
	 */
    var ResizeObserverController = function () {
        this.connected_ = false;
        this.mutationEventsAdded_ = false;
        this.mutationsObserver_ = null;
        this.observers_ = [];

        this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
        this.refresh = throttle$1(this.refresh.bind(this), REFRESH_DELAY);
    };

	/**
	 * Adds observer to observers list.
	 *
	 * @param {ResizeObserverSPI} observer - Observer to be added.
	 * @returns {void}
	 */


	/**
	 * Holds reference to the controller's instance.
	 *
	 * @private {ResizeObserverController}
	 */


	/**
	 * Keeps reference to the instance of MutationObserver.
	 *
	 * @private {MutationObserver}
	 */

	/**
	 * Indicates whether DOM listeners have been added.
	 *
	 * @private {boolean}
	 */
    ResizeObserverController.prototype.addObserver = function (observer) {
        if (!~this.observers_.indexOf(observer)) {
            this.observers_.push(observer);
        }

        // Add listeners if they haven't been added yet.
        if (!this.connected_) {
            this.connect_();
        }
    };

	/**
	 * Removes observer from observers list.
	 *
	 * @param {ResizeObserverSPI} observer - Observer to be removed.
	 * @returns {void}
	 */
    ResizeObserverController.prototype.removeObserver = function (observer) {
        var observers = this.observers_;
        var index = observers.indexOf(observer);

        // Remove observer if it's present in registry.
        if (~index) {
            observers.splice(index, 1);
        }

        // Remove listeners if controller has no connected observers.
        if (!observers.length && this.connected_) {
            this.disconnect_();
        }
    };

	/**
	 * Invokes the update of observers. It will continue running updates insofar
	 * it detects changes.
	 *
	 * @returns {void}
	 */
    ResizeObserverController.prototype.refresh = function () {
        var changesDetected = this.updateObservers_();

        // Continue running updates if changes have been detected as there might
        // be future ones caused by CSS transitions.
        if (changesDetected) {
            this.refresh();
        }
    };

	/**
	 * Updates every observer from observers list and notifies them of queued
	 * entries.
	 *
	 * @private
	 * @returns {boolean} Returns "true" if any observer has detected changes in
	 *  dimensions of it's elements.
	 */
    ResizeObserverController.prototype.updateObservers_ = function () {
        // Collect observers that have active observations.
        var activeObservers = this.observers_.filter(function (observer) {
            return observer.gatherActive(), observer.hasActive();
        });

        // Deliver notifications in a separate cycle in order to avoid any
        // collisions between observers, e.g. when multiple instances of
        // ResizeObserver are tracking the same element and the callback of one
        // of them changes content dimensions of the observed target. Sometimes
        // this may result in notifications being blocked for the rest of observers.
        activeObservers.forEach(function (observer) { return observer.broadcastActive(); });

        return activeObservers.length > 0;
    };

	/**
	 * Initializes DOM listeners.
	 *
	 * @private
	 * @returns {void}
	 */
    ResizeObserverController.prototype.connect_ = function () {
        // Do nothing if running in a non-browser environment or if listeners
        // have been already added.
        if (!isBrowser || this.connected_) {
            return;
        }

        // Subscription to the "Transitionend" event is used as a workaround for
        // delayed transitions. This way it's possible to capture at least the
        // final state of an element.
        document.addEventListener('transitionend', this.onTransitionEnd_);

        window.addEventListener('resize', this.refresh);

        if (mutationObserverSupported) {
            this.mutationsObserver_ = new MutationObserver(this.refresh);

            this.mutationsObserver_.observe(document, {
                attributes: true,
                childList: true,
                characterData: true,
                subtree: true
            });
        } else {
            document.addEventListener('DOMSubtreeModified', this.refresh);

            this.mutationEventsAdded_ = true;
        }

        this.connected_ = true;
    };

	/**
	 * Removes DOM listeners.
	 *
	 * @private
	 * @returns {void}
	 */
    ResizeObserverController.prototype.disconnect_ = function () {
        // Do nothing if running in a non-browser environment or if listeners
        // have been already removed.
        if (!isBrowser || !this.connected_) {
            return;
        }

        document.removeEventListener('transitionend', this.onTransitionEnd_);
        window.removeEventListener('resize', this.refresh);

        if (this.mutationsObserver_) {
            this.mutationsObserver_.disconnect();
        }

        if (this.mutationEventsAdded_) {
            document.removeEventListener('DOMSubtreeModified', this.refresh);
        }

        this.mutationsObserver_ = null;
        this.mutationEventsAdded_ = false;
        this.connected_ = false;
    };

	/**
	 * "Transitionend" event handler.
	 *
	 * @private
	 * @param {TransitionEvent} event
	 * @returns {void}
	 */
    ResizeObserverController.prototype.onTransitionEnd_ = function (ref) {
        var propertyName = ref.propertyName; if (propertyName === void 0) propertyName = '';

        // Detect whether transition may affect dimensions of an element.
        var isReflowProperty = transitionKeys.some(function (key) {
            return !!~propertyName.indexOf(key);
        });

        if (isReflowProperty) {
            this.refresh();
        }
    };

	/**
	 * Returns instance of the ResizeObserverController.
	 *
	 * @returns {ResizeObserverController}
	 */
    ResizeObserverController.getInstance = function () {
        if (!this.instance_) {
            this.instance_ = new ResizeObserverController();
        }

        return this.instance_;
    };

    ResizeObserverController.instance_ = null;

	/**
	 * Defines non-writable/enumerable properties of the provided target object.
	 *
	 * @param {Object} target - Object for which to define properties.
	 * @param {Object} props - Properties to be defined.
	 * @returns {Object} Target object.
	 */
    var defineConfigurable = (function (target, props) {
        for (var i = 0, list = Object.keys(props); i < list.length; i += 1) {
            var key = list[i];

            Object.defineProperty(target, key, {
                value: props[key],
                enumerable: false,
                writable: false,
                configurable: true
            });
        }

        return target;
    });

	/**
	 * Returns the global object associated with provided element.
	 *
	 * @param {Object} target
	 * @returns {Object}
	 */
    var getWindowOf = (function (target) {
        // Assume that the element is an instance of Node, which means that it
        // has the "ownerDocument" property from which we can retrieve a
        // corresponding global object.
        var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;

        // Return the local global object if it's not possible extract one from
        // provided element.
        return ownerGlobal || global$1;
    });

    // Placeholder of an empty content rectangle.
    var emptyRect = createRectInit(0, 0, 0, 0);

	/**
	 * Converts provided string to a number.
	 *
	 * @param {number|string} value
	 * @returns {number}
	 */
    function toFloat(value) {
        return parseFloat(value) || 0;
    }

	/**
	 * Extracts borders size from provided styles.
	 *
	 * @param {CSSStyleDeclaration} styles
	 * @param {...string} positions - Borders positions (top, right, ...)
	 * @returns {number}
	 */
    function getBordersSize(styles) {
        var positions = [], len = arguments.length - 1;
        while (len-- > 0) positions[len] = arguments[len + 1];

        return positions.reduce(function (size, position) {
            var value = styles['border-' + position + '-width'];

            return size + toFloat(value);
        }, 0);
    }

	/**
	 * Extracts paddings sizes from provided styles.
	 *
	 * @param {CSSStyleDeclaration} styles
	 * @returns {Object} Paddings box.
	 */
    function getPaddings(styles) {
        var positions = ['top', 'right', 'bottom', 'left'];
        var paddings = {};

        for (var i = 0, list = positions; i < list.length; i += 1) {
            var position = list[i];

            var value = styles['padding-' + position];

            paddings[position] = toFloat(value);
        }

        return paddings;
    }

	/**
	 * Calculates content rectangle of provided SVG element.
	 *
	 * @param {SVGGraphicsElement} target - Element content rectangle of which needs
	 *      to be calculated.
	 * @returns {DOMRectInit}
	 */
    function getSVGContentRect(target) {
        var bbox = target.getBBox();

        return createRectInit(0, 0, bbox.width, bbox.height);
    }

	/**
	 * Calculates content rectangle of provided HTMLElement.
	 *
	 * @param {HTMLElement} target - Element for which to calculate the content rectangle.
	 * @returns {DOMRectInit}
	 */
    function getHTMLElementContentRect(target) {
        // Client width & height properties can't be
        // used exclusively as they provide rounded values.
        var clientWidth = target.clientWidth;
        var clientHeight = target.clientHeight;

        // By this condition we can catch all non-replaced inline, hidden and
        // detached elements. Though elements with width & height properties less
        // than 0.5 will be discarded as well.
        //
        // Without it we would need to implement separate methods for each of
        // those cases and it's not possible to perform a precise and performance
        // effective test for hidden elements. E.g. even jQuery's ':visible' filter
        // gives wrong results for elements with width & height less than 0.5.
        if (!clientWidth && !clientHeight) {
            return emptyRect;
        }

        var styles = getWindowOf(target).getComputedStyle(target);
        var paddings = getPaddings(styles);
        var horizPad = paddings.left + paddings.right;
        var vertPad = paddings.top + paddings.bottom;

        // Computed styles of width & height are being used because they are the
        // only dimensions available to JS that contain non-rounded values. It could
        // be possible to utilize the getBoundingClientRect if only it's data wasn't
        // affected by CSS transformations let alone paddings, borders and scroll bars.
        var width = toFloat(styles.width),
            height = toFloat(styles.height);

        // Width & height include paddings and borders when the 'border-box' box
        // model is applied (except for IE).
        if (styles.boxSizing === 'border-box') {
            // Following conditions are required to handle Internet Explorer which
            // doesn't include paddings and borders to computed CSS dimensions.
            //
            // We can say that if CSS dimensions + paddings are equal to the "client"
            // properties then it's either IE, and thus we don't need to subtract
            // anything, or an element merely doesn't have paddings/borders styles.
            if (Math.round(width + horizPad) !== clientWidth) {
                width -= getBordersSize(styles, 'left', 'right') + horizPad;
            }

            if (Math.round(height + vertPad) !== clientHeight) {
                height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
            }
        }

        // Following steps can't be applied to the document's root element as its
        // client[Width/Height] properties represent viewport area of the window.
        // Besides, it's as well not necessary as the <html> itself neither has
        // rendered scroll bars nor it can be clipped.
        if (!isDocumentElement(target)) {
            // In some browsers (only in Firefox, actually) CSS width & height
            // include scroll bars size which can be removed at this step as scroll
            // bars are the only difference between rounded dimensions + paddings
            // and "client" properties, though that is not always true in Chrome.
            var vertScrollbar = Math.round(width + horizPad) - clientWidth;
            var horizScrollbar = Math.round(height + vertPad) - clientHeight;

            // Chrome has a rather weird rounding of "client" properties.
            // E.g. for an element with content width of 314.2px it sometimes gives
            // the client width of 315px and for the width of 314.7px it may give
            // 314px. And it doesn't happen all the time. So just ignore this delta
            // as a non-relevant.
            if (Math.abs(vertScrollbar) !== 1) {
                width -= vertScrollbar;
            }

            if (Math.abs(horizScrollbar) !== 1) {
                height -= horizScrollbar;
            }
        }

        return createRectInit(paddings.left, paddings.top, width, height);
    }

	/**
	 * Checks whether provided element is an instance of the SVGGraphicsElement.
	 *
	 * @param {Element} target - Element to be checked.
	 * @returns {boolean}
	 */
    var isSVGGraphicsElement = (function () {
        // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
        // interface.
        if (typeof SVGGraphicsElement !== 'undefined') {
            return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
        }

        // If it's so, then check that element is at least an instance of the
        // SVGElement and that it has the "getBBox" method.
        // eslint-disable-next-line no-extra-parens
        return function (target) { return target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'; };
    })();

	/**
	 * Checks whether provided element is a document element (<html>).
	 *
	 * @param {Element} target - Element to be checked.
	 * @returns {boolean}
	 */
    function isDocumentElement(target) {
        return target === getWindowOf(target).document.documentElement;
    }

	/**
	 * Calculates an appropriate content rectangle for provided html or svg element.
	 *
	 * @param {Element} target - Element content rectangle of which needs to be calculated.
	 * @returns {DOMRectInit}
	 */
    function getContentRect(target) {
        if (!isBrowser) {
            return emptyRect;
        }

        if (isSVGGraphicsElement(target)) {
            return getSVGContentRect(target);
        }

        return getHTMLElementContentRect(target);
    }

	/**
	 * Creates rectangle with an interface of the DOMRectReadOnly.
	 * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
	 *
	 * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
	 * @returns {DOMRectReadOnly}
	 */
    function createReadOnlyRect(ref) {
        var x = ref.x;
        var y = ref.y;
        var width = ref.width;
        var height = ref.height;

        // If DOMRectReadOnly is available use it as a prototype for the rectangle.
        var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
        var rect = Object.create(Constr.prototype);

        // Rectangle's properties are not writable and non-enumerable.
        defineConfigurable(rect, {
            x: x, y: y, width: width, height: height,
            top: y,
            right: x + width,
            bottom: height + y,
            left: x
        });

        return rect;
    }

	/**
	 * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
	 * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
	 *
	 * @param {number} x - X coordinate.
	 * @param {number} y - Y coordinate.
	 * @param {number} width - Rectangle's width.
	 * @param {number} height - Rectangle's height.
	 * @returns {DOMRectInit}
	 */
    function createRectInit(x, y, width, height) {
        return { x: x, y: y, width: width, height: height };
    }

	/**
	 * Class that is responsible for computations of the content rectangle of
	 * provided DOM element and for keeping track of it's changes.
	 */
    var ResizeObservation = function (target) {
        this.broadcastWidth = 0;
        this.broadcastHeight = 0;
        this.contentRect_ = createRectInit(0, 0, 0, 0);

        this.target = target;
    };

	/**
	 * Updates content rectangle and tells whether it's width or height properties
	 * have changed since the last broadcast.
	 *
	 * @returns {boolean}
	 */


	/**
	 * Reference to the last observed content rectangle.
	 *
	 * @private {DOMRectInit}
	 */


	/**
	 * Broadcasted width of content rectangle.
	 *
	 * @type {number}
	 */
    ResizeObservation.prototype.isActive = function () {
        var rect = getContentRect(this.target);

        this.contentRect_ = rect;

        return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight;
    };

	/**
	 * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
	 * from the corresponding properties of the last observed content rectangle.
	 *
	 * @returns {DOMRectInit} Last observed content rectangle.
	 */
    ResizeObservation.prototype.broadcastRect = function () {
        var rect = this.contentRect_;

        this.broadcastWidth = rect.width;
        this.broadcastHeight = rect.height;

        return rect;
    };

    var ResizeObserverEntry = function (target, rectInit) {
        var contentRect = createReadOnlyRect(rectInit);

        // According to the specification following properties are not writable
        // and are also not enumerable in the native implementation.
        //
        // Property accessors are not being used as they'd require to define a
        // private WeakMap storage which may cause memory leaks in browsers that
        // don't support this type of collections.
        defineConfigurable(this, { target: target, contentRect: contentRect });
    };

    var ResizeObserverSPI = function (callback, controller, callbackCtx) {
        this.activeObservations_ = [];
        this.observations_ = new MapShim();

        if (typeof callback !== 'function') {
            throw new TypeError('The callback provided as parameter 1 is not a function.');
        }

        this.callback_ = callback;
        this.controller_ = controller;
        this.callbackCtx_ = callbackCtx;
    };

	/**
	 * Starts observing provided element.
	 *
	 * @param {Element} target - Element to be observed.
	 * @returns {void}
	 */


	/**
	 * Registry of the ResizeObservation instances.
	 *
	 * @private {Map<Element, ResizeObservation>}
	 */


	/**
	 * Public ResizeObserver instance which will be passed to the callback
	 * function and used as a value of it's "this" binding.
	 *
	 * @private {ResizeObserver}
	 */

	/**
	 * Collection of resize observations that have detected changes in dimensions
	 * of elements.
	 *
	 * @private {Array<ResizeObservation>}
	 */
    ResizeObserverSPI.prototype.observe = function (target) {
        if (!arguments.length) {
            throw new TypeError('1 argument required, but only 0 present.');
        }

        // Do nothing if current environment doesn't have the Element interface.
        if (typeof Element === 'undefined' || !(Element instanceof Object)) {
            return;
        }

        if (!(target instanceof getWindowOf(target).Element)) {
            throw new TypeError('parameter 1 is not of type "Element".');
        }

        var observations = this.observations_;

        // Do nothing if element is already being observed.
        if (observations.has(target)) {
            return;
        }

        observations.set(target, new ResizeObservation(target));

        this.controller_.addObserver(this);

        // Force the update of observations.
        this.controller_.refresh();
    };

	/**
	 * Stops observing provided element.
	 *
	 * @param {Element} target - Element to stop observing.
	 * @returns {void}
	 */
    ResizeObserverSPI.prototype.unobserve = function (target) {
        if (!arguments.length) {
            throw new TypeError('1 argument required, but only 0 present.');
        }

        // Do nothing if current environment doesn't have the Element interface.
        if (typeof Element === 'undefined' || !(Element instanceof Object)) {
            return;
        }

        if (!(target instanceof getWindowOf(target).Element)) {
            throw new TypeError('parameter 1 is not of type "Element".');
        }

        var observations = this.observations_;

        // Do nothing if element is not being observed.
        if (!observations.has(target)) {
            return;
        }

        observations.delete(target);

        if (!observations.size) {
            this.controller_.removeObserver(this);
        }
    };

	/**
	 * Stops observing all elements.
	 *
	 * @returns {void}
	 */
    ResizeObserverSPI.prototype.disconnect = function () {
        this.clearActive();
        this.observations_.clear();
        this.controller_.removeObserver(this);
    };

	/**
	 * Collects observation instances the associated element of which has changed
	 * it's content rectangle.
	 *
	 * @returns {void}
	 */
    ResizeObserverSPI.prototype.gatherActive = function () {
        var this$1 = this;

        this.clearActive();

        this.observations_.forEach(function (observation) {
            if (observation.isActive()) {
                this$1.activeObservations_.push(observation);
            }
        });
    };

	/**
	 * Invokes initial callback function with a list of ResizeObserverEntry
	 * instances collected from active resize observations.
	 *
	 * @returns {void}
	 */
    ResizeObserverSPI.prototype.broadcastActive = function () {
        // Do nothing if observer doesn't have active observations.
        if (!this.hasActive()) {
            return;
        }

        var ctx = this.callbackCtx_;

        // Create ResizeObserverEntry instance for every active observation.
        var entries = this.activeObservations_.map(function (observation) {
            return new ResizeObserverEntry(observation.target, observation.broadcastRect());
        });

        this.callback_.call(ctx, entries, ctx);
        this.clearActive();
    };

	/**
	 * Clears the collection of active observations.
	 *
	 * @returns {void}
	 */
    ResizeObserverSPI.prototype.clearActive = function () {
        this.activeObservations_.splice(0);
    };

	/**
	 * Tells whether observer has active observations.
	 *
	 * @returns {boolean}
	 */
    ResizeObserverSPI.prototype.hasActive = function () {
        return this.activeObservations_.length > 0;
    };

    // Registry of internal observers. If WeakMap is not available use current shim
    // for the Map collection as it has all required methods and because WeakMap
    // can't be fully polyfilled anyway.
    var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();

	/**
	 * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
	 * exposing only those methods and properties that are defined in the spec.
	 */
    var ResizeObserver = function (callback) {
        if (!(this instanceof ResizeObserver)) {
            throw new TypeError('Cannot call a class as a function.');
        }
        if (!arguments.length) {
            throw new TypeError('1 argument required, but only 0 present.');
        }

        var controller = ResizeObserverController.getInstance();
        var observer = new ResizeObserverSPI(callback, controller, this);

        observers.set(this, observer);
    };

    // Expose public methods of ResizeObserver.
    ['observe', 'unobserve', 'disconnect'].forEach(function (method) {
        ResizeObserver.prototype[method] = function () {
            return (ref = observers.get(this))[method].apply(ref, arguments);
            var ref;
        };
    });

    var index = (function () {
        // Export existing implementation if available.
        if (typeof global$1.ResizeObserver !== 'undefined') {
            return global$1.ResizeObserver;
        }

        return ResizeObserver;
    })();

    var canUseDOM = !!(
        typeof window !== 'undefined' &&
        window.document &&
        window.document.createElement
    );

    var canUseDom = canUseDOM;

    var SimpleBar =
        /*#__PURE__*/
        function () {
            function SimpleBar(element, options) {
                var _this = this;

                _classCallCheck(this, SimpleBar);

                this.onScroll = function () {
                    if (!_this.scrollXTicking) {
                        window.requestAnimationFrame(_this.scrollX);
                        _this.scrollXTicking = true;
                    }

                    if (!_this.scrollYTicking) {
                        window.requestAnimationFrame(_this.scrollY);
                        _this.scrollYTicking = true;
                    }
                };

                this.scrollX = function () {
                    if (_this.axis.x.isOverflowing) {
                        _this.showScrollbar('x');

                        _this.positionScrollbar('x');
                    }

                    _this.scrollXTicking = false;
                };

                this.scrollY = function () {
                    if (_this.axis.y.isOverflowing) {
                        _this.showScrollbar('y');

                        _this.positionScrollbar('y');
                    }

                    _this.scrollYTicking = false;
                };

                this.onMouseEnter = function () {
                    _this.showScrollbar('x');

                    _this.showScrollbar('y');
                };

                this.onMouseMove = function (e) {
                    _this.mouseX = e.clientX;
                    _this.mouseY = e.clientY;

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        _this.onMouseMoveForAxis('x');
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        _this.onMouseMoveForAxis('y');
                    }
                };

                this.onMouseLeave = function () {
                    _this.onMouseMove.cancel();

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        _this.onMouseLeaveForAxis('x');
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        _this.onMouseLeaveForAxis('y');
                    }

                    _this.mouseX = -1;
                    _this.mouseY = -1;
                };

                this.onWindowResize = function () {
                    // Recalculate scrollbarWidth in case it's a zoom
                    _this.scrollbarWidth = scrollbarWidth();

                    _this.hideNativeScrollbar();
                };

                this.hideScrollbars = function () {
                    _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
                    _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();

                    if (!_this.isWithinBounds(_this.axis.y.track.rect)) {
                        _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible);

                        _this.axis.y.isVisible = false;
                    }

                    if (!_this.isWithinBounds(_this.axis.x.track.rect)) {
                        _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible);

                        _this.axis.x.isVisible = false;
                    }
                };

                this.onPointerEvent = function (e) {
                    var isWithinBoundsY, isWithinBoundsX;

                    if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
                        isWithinBoundsX = _this.isWithinBounds(_this.axis.x.scrollbar.rect);
                    }

                    if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
                        isWithinBoundsY = _this.isWithinBounds(_this.axis.y.scrollbar.rect);
                    } // If any pointer event is called on the scrollbar


                    if (isWithinBoundsY || isWithinBoundsX) {
                        // Preventing the event's default action stops text being
                        // selectable during the drag.
                        e.preventDefault(); // Prevent event leaking

                        e.stopPropagation();

                        if (e.type === 'mousedown') {
                            if (isWithinBoundsY) {
                                _this.onDragStart(e, 'y');
                            }

                            if (isWithinBoundsX) {
                                _this.onDragStart(e, 'x');
                            }
                        }
                    }
                };

                this.drag = function (e) {
                    var eventOffset;
                    var track = _this.axis[_this.draggedAxis].track;
                    var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr];
                    var scrollbar = _this.axis[_this.draggedAxis].scrollbar;
                    e.preventDefault();
                    e.stopPropagation();

                    if (_this.draggedAxis === 'y') {
                        eventOffset = e.pageY;
                    } else {
                        eventOffset = e.pageX;
                    } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).


                    var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width.

                    var dragPerc = dragPos / track.rect[_this.axis[_this.draggedAxis].sizeAttr]; // Scroll the content by the same percentage.

                    var scrollPos = dragPerc * _this.contentEl[_this.axis[_this.draggedAxis].scrollSizeAttr]; // Fix browsers inconsistency on RTL

                    if (_this.draggedAxis === 'x') {
                        scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos;
                        scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos;
                    }

                    _this.contentEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos;
                };

                this.onEndDrag = function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    document.removeEventListener('mousemove', _this.drag);
                    document.removeEventListener('mouseup', _this.onEndDrag);
                };

                this.el = element;
                this.flashTimeout;
                this.contentEl;
                this.offsetEl;
                this.maskEl;
                this.globalObserver;
                this.mutationObserver;
                this.resizeObserver;
                this.scrollbarWidth;
                this.minScrollbarWidth = 20;
                this.options = _objectSpread({}, SimpleBar.defaultOptions, options);
                this.classNames = _objectSpread({}, SimpleBar.defaultOptions.classNames, this.options.classNames);
                this.isRtl;
                this.axis = {
                    x: {
                        scrollOffsetAttr: 'scrollLeft',
                        sizeAttr: 'width',
                        scrollSizeAttr: 'scrollWidth',
                        offsetAttr: 'left',
                        overflowAttr: 'overflowX',
                        dragOffset: 0,
                        isOverflowing: true,
                        isVisible: false,
                        forceVisible: false,
                        track: {},
                        scrollbar: {}
                    },
                    y: {
                        scrollOffsetAttr: 'scrollTop',
                        sizeAttr: 'height',
                        scrollSizeAttr: 'scrollHeight',
                        offsetAttr: 'top',
                        overflowAttr: 'overflowY',
                        dragOffset: 0,
                        isOverflowing: true,
                        isVisible: false,
                        forceVisible: false,
                        track: {},
                        scrollbar: {}
                    }
                };
                this.recalculate = lodash_throttle(this.recalculate.bind(this), 64);
                this.onMouseMove = lodash_throttle(this.onMouseMove.bind(this), 64);
                this.hideScrollbars = lodash_debounce(this.hideScrollbars.bind(this), this.options.timeout);
                this.onWindowResize = lodash_debounce(this.onWindowResize.bind(this), 64, {
                    leading: true
                });
                SimpleBar.getRtlHelpers = lodash_memoize(SimpleBar.getRtlHelpers); // getContentElement is deprecated

                this.getContentElement = this.getScrollElement;
                this.init();
            }
			/**
			 * Static properties
			 */

			/**
			 * Helper to fix browsers inconsistency on RTL:
			 *  - Firefox inverts the scrollbar initial position
			 *  - IE11 inverts both scrollbar position and scrolling offset
			 * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634
			 */


            _createClass(SimpleBar, [{
                key: "init",
                value: function init() {
                    // Save a reference to the instance, so we know this DOM node has already been instancied
                    this.el.SimpleBar = this;
                    this.initDOM(); // We stop here on server-side

                    if (canUseDom) {
                        // Recalculate scrollbarWidth in case it's a zoom
                        this.scrollbarWidth = scrollbarWidth();
                        this.recalculate();
                        this.initListeners();
                    }
                }
            }, {
                key: "initDOM",
                value: function initDOM() {
                    var _this2 = this;

                    // make sure this element doesn't have the elements yet
                    if (Array.from(this.el.children).filter(function (child) {
                        return child.classList.contains(_this2.classNames.wrapper);
                    }).length) {
                        // assume that element has his DOM already initiated
                        this.wrapperEl = this.el.querySelector(".".concat(this.classNames.wrapper));
                        this.contentEl = this.el.querySelector(".".concat(this.classNames.content));
                        this.offsetEl = this.el.querySelector(".".concat(this.classNames.offset));
                        this.maskEl = this.el.querySelector(".".concat(this.classNames.mask));
                        this.placeholderEl = this.el.querySelector(".".concat(this.classNames.placeholder));
                        this.heightAutoObserverWrapperEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverWrapperEl));
                        this.heightAutoObserverEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverEl));
                        this.axis.x.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.horizontal));
                        this.axis.y.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.vertical));
                    } else {
                        // Prepare DOM
                        this.wrapperEl = document.createElement('div');
                        this.contentEl = document.createElement('div');
                        this.offsetEl = document.createElement('div');
                        this.maskEl = document.createElement('div');
                        this.placeholderEl = document.createElement('div');
                        this.heightAutoObserverWrapperEl = document.createElement('div');
                        this.heightAutoObserverEl = document.createElement('div');
                        this.wrapperEl.classList.add(this.classNames.wrapper);
                        this.contentEl.classList.add(this.classNames.content);
                        this.offsetEl.classList.add(this.classNames.offset);
                        this.maskEl.classList.add(this.classNames.mask);
                        this.placeholderEl.classList.add(this.classNames.placeholder);
                        this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl);
                        this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl);

                        while (this.el.firstChild) {
                            this.contentEl.appendChild(this.el.firstChild);
                        }

                        this.offsetEl.appendChild(this.contentEl);
                        this.maskEl.appendChild(this.offsetEl);
                        this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl);
                        this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl);
                        this.wrapperEl.appendChild(this.maskEl);
                        this.wrapperEl.appendChild(this.placeholderEl);
                        this.el.appendChild(this.wrapperEl);
                    }

                    if (!this.axis.x.track.el || !this.axis.y.track.el) {
                        var track = document.createElement('div');
                        var scrollbar = document.createElement('div');
                        track.classList.add(this.classNames.track);
                        scrollbar.classList.add(this.classNames.scrollbar);

                        if (!this.options.autoHide) {
                            scrollbar.classList.add(this.classNames.visible);
                        }

                        track.appendChild(scrollbar);
                        this.axis.x.track.el = track.cloneNode(true);
                        this.axis.x.track.el.classList.add(this.classNames.horizontal);
                        this.axis.y.track.el = track.cloneNode(true);
                        this.axis.y.track.el.classList.add(this.classNames.vertical);
                        this.el.appendChild(this.axis.x.track.el);
                        this.el.appendChild(this.axis.y.track.el);
                    }

                    this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector(".".concat(this.classNames.scrollbar));
                    this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector(".".concat(this.classNames.scrollbar));
                    this.el.setAttribute('data-simplebar', 'init');
                }
            }, {
                key: "initListeners",
                value: function initListeners() {
                    var _this3 = this;

                    // Event listeners
                    if (this.options.autoHide) {
                        this.el.addEventListener('mouseenter', this.onMouseEnter);
                    }

                    ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) {
                        _this3.el.addEventListener(e, _this3.onPointerEvent, true);
                    });
                    this.el.addEventListener('mousemove', this.onMouseMove);
                    this.el.addEventListener('mouseleave', this.onMouseLeave);
                    this.contentEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize

                    window.addEventListener('resize', this.onWindowResize); // MutationObserver is IE11+

                    if (typeof MutationObserver !== 'undefined') {
                        // create an observer instance
                        this.mutationObserver = new MutationObserver(function (mutations) {
                            mutations.forEach(function (mutation) {
                                if (mutation.target === _this3.el || !_this3.isChildNode(mutation.target) || mutation.addedNodes.length) {
                                    _this3.recalculate();
                                }
                            });
                        }); // pass in the target node, as well as the observer options

                        this.mutationObserver.observe(this.el, {
                            attributes: true,
                            childList: true,
                            characterData: true,
                            subtree: true
                        });
                    }

                    this.resizeObserver = new index(this.recalculate);
                    this.resizeObserver.observe(this.el);
                }
            }, {
                key: "recalculate",
                value: function recalculate() {
                    var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1;
                    this.elStyles = window.getComputedStyle(this.el);
                    this.isRtl = this.elStyles.direction === 'rtl';
                    this.contentEl.style.padding = "".concat(this.elStyles.paddingTop, " ").concat(this.elStyles.paddingRight, " ").concat(this.elStyles.paddingBottom, " ").concat(this.elStyles.paddingLeft);
                    this.contentEl.style.height = isHeightAuto ? 'auto' : '100%';
                    this.placeholderEl.style.width = "".concat(this.contentEl.scrollWidth, "px");
                    this.placeholderEl.style.height = "".concat(this.contentEl.scrollHeight, "px");
                    this.wrapperEl.style.margin = "-".concat(this.elStyles.paddingTop, " -").concat(this.elStyles.paddingRight, " -").concat(this.elStyles.paddingBottom, " -").concat(this.elStyles.paddingLeft);
                    this.axis.x.track.rect = this.axis.x.track.el.getBoundingClientRect();
                    this.axis.y.track.rect = this.axis.y.track.el.getBoundingClientRect(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset)

                    this.axis.x.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollWidth : this.contentEl.scrollWidth - this.minScrollbarWidth) > Math.ceil(this.axis.x.track.rect.width);
                    this.axis.y.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollHeight : this.contentEl.scrollHeight - this.minScrollbarWidth) > Math.ceil(this.axis.y.track.rect.height); // Set isOverflowing to false if user explicitely set hidden overflow

                    this.axis.x.isOverflowing = this.elStyles.overflowX === 'hidden' ? false : this.axis.x.isOverflowing;
                    this.axis.y.isOverflowing = this.elStyles.overflowY === 'hidden' ? false : this.axis.y.isOverflowing;
                    this.axis.x.forceVisible = this.options.forceVisible === "x" || this.options.forceVisible === true;
                    this.axis.y.forceVisible = this.options.forceVisible === "y" || this.options.forceVisible === true;
                    this.axis.x.scrollbar.size = this.getScrollbarSize('x');
                    this.axis.y.scrollbar.size = this.getScrollbarSize('y');
                    this.axis.x.scrollbar.el.style.width = "".concat(this.axis.x.scrollbar.size, "px");
                    this.axis.y.scrollbar.el.style.height = "".concat(this.axis.y.scrollbar.size, "px");
                    this.positionScrollbar('x');
                    this.positionScrollbar('y');
                    this.toggleTrackVisibility('x');
                    this.toggleTrackVisibility('y');
                    this.hideNativeScrollbar();
                }
				/**
				 * Calculate scrollbar size
				 */

            }, {
                key: "getScrollbarSize",
                value: function getScrollbarSize() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var contentSize = this.scrollbarWidth ? this.contentEl[this.axis[axis].scrollSizeAttr] : this.contentEl[this.axis[axis].scrollSizeAttr] - this.minScrollbarWidth;
                    var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
                    var scrollbarSize;

                    if (!this.axis[axis].isOverflowing) {
                        return;
                    }

                    var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle.

                    scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize);

                    if (this.options.scrollbarMaxSize) {
                        scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize);
                    }

                    return scrollbarSize;
                }
            }, {
                key: "positionScrollbar",
                value: function positionScrollbar() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr];
                    var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
                    var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
                    var scrollbar = this.axis[axis].scrollbar;
                    var scrollOffset = this.contentEl[this.axis[axis].scrollOffsetAttr];
                    scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset;
                    var scrollPourcent = scrollOffset / (contentSize - hostSize);
                    var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent);
                    handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset;
                    scrollbar.el.style.transform = axis === 'x' ? "translate3d(".concat(handleOffset, "px, 0, 0)") : "translate3d(0, ".concat(handleOffset, "px, 0)");
                }
            }, {
                key: "toggleTrackVisibility",
                value: function toggleTrackVisibility() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var track = this.axis[axis].track.el;
                    var scrollbar = this.axis[axis].scrollbar.el;

                    if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) {
                        track.style.visibility = 'visible';
                        this.contentEl.style[this.axis[axis].overflowAttr] = 'scroll';
                    } else {
                        track.style.visibility = 'hidden';
                        this.contentEl.style[this.axis[axis].overflowAttr] = 'hidden';
                    } // Even if forceVisible is enabled, scrollbar itself should be hidden


                    if (this.axis[axis].isOverflowing) {
                        scrollbar.style.visibility = 'visible';
                    } else {
                        scrollbar.style.visibility = 'hidden';
                    }
                }
            }, {
                key: "hideNativeScrollbar",
                value: function hideNativeScrollbar() {
                    this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0;
                    this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0; // If floating scrollbar

                    if (!this.scrollbarWidth) {
                        var paddingDirection = [this.isRtl ? 'paddingLeft' : 'paddingRight'];
                        this.contentEl.style[paddingDirection] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "calc(".concat(this.elStyles[paddingDirection], " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles[paddingDirection];
                        this.contentEl.style.paddingBottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "calc(".concat(this.elStyles.paddingBottom, " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles.paddingBottom;
                    }
                }
				/**
				 * On scroll event handling
				 */

            }, {
                key: "onMouseMoveForAxis",
                value: function onMouseMoveForAxis() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect();
                    this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect();
                    var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect);

                    if (isWithinScrollbarBoundsX) {
                        this.axis[axis].scrollbar.el.classList.add(this.classNames.hover);
                    } else {
                        this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
                    }

                    if (this.isWithinBounds(this.axis[axis].track.rect)) {
                        this.showScrollbar(axis);
                        this.axis[axis].track.el.classList.add(this.classNames.hover);
                    } else {
                        this.axis[axis].track.el.classList.remove(this.classNames.hover);
                    }
                }
            }, {
                key: "onMouseLeaveForAxis",
                value: function onMouseLeaveForAxis() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    this.axis[axis].track.el.classList.remove(this.classNames.hover);
                    this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
                }
            }, {
                key: "showScrollbar",

				/**
				 * Show scrollbar
				 */
                value: function showScrollbar() {
                    var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
                    var scrollbar = this.axis[axis].scrollbar.el;

                    if (!this.axis[axis].isVisible) {
                        scrollbar.classList.add(this.classNames.visible);
                        this.axis[axis].isVisible = true;
                    }

                    if (this.options.autoHide) {
                        this.hideScrollbars();
                    }
                }
				/**
				 * Hide Scrollbar
				 */

            }, {
                key: "onDragStart",

				/**
				 * on scrollbar handle drag movement starts
				 */
                value: function onDragStart(e) {
                    var axis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'y';
                    var scrollbar = this.axis[axis].scrollbar.el; // Measure how far the user's mouse is from the top of the scrollbar drag handle.

                    var eventOffset = axis === 'y' ? e.pageY : e.pageX;
                    this.axis[axis].dragOffset = eventOffset - scrollbar.getBoundingClientRect()[this.axis[axis].offsetAttr];
                    this.draggedAxis = axis;
                    document.addEventListener('mousemove', this.drag);
                    document.addEventListener('mouseup', this.onEndDrag);
                }
				/**
				 * Drag scrollbar handle
				 */

            }, {
                key: "getScrollElement",

				/**
				 * Getter for original scrolling element
				 */
                value: function getScrollElement() {
                    return this.contentEl;
                }
            }, {
                key: "removeListeners",
                value: function removeListeners() {
                    // Event listeners
                    if (this.options.autoHide) {
                        this.el.removeEventListener('mouseenter', this.onMouseEnter);
                    }

                    this.contentEl.removeEventListener('scroll', this.onScroll);
                    window.removeEventListener('resize', this.onWindowResize);
                    this.mutationObserver && this.mutationObserver.disconnect();
                    this.resizeObserver.disconnect();
                }
				/**
				 * UnMount mutation observer and delete SimpleBar instance from DOM element
				 */

            }, {
                key: "unMount",
                value: function unMount() {
                    this.removeListeners();
                    this.el.SimpleBar = null;
                }
				/**
				 * Recursively walks up the parent nodes looking for this.el
				 */

            }, {
                key: "isChildNode",
                value: function isChildNode(el) {
                    if (el === null) return false;
                    if (el === this.el) return true;
                    return this.isChildNode(el.parentNode);
                }
				/**
				 * Check if mouse is within bounds
				 */

            }, {
                key: "isWithinBounds",
                value: function isWithinBounds(bbox) {
                    return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height;
                }
            }], [{
                key: "getRtlHelpers",
                value: function getRtlHelpers() {
                    var dummyDiv = document.createElement('div');
                    dummyDiv.innerHTML = '<div class="hs-dummy-scrollbar-size"><div style="height: 200%; width: 200%; margin: 10px 0;"></div></div>';
                    var scrollbarDummyEl = dummyDiv.firstElementChild;
                    document.body.appendChild(scrollbarDummyEl);
                    var dummyContainerChild = scrollbarDummyEl.firstElementChild;
                    scrollbarDummyEl.scrollLeft = 0;
                    var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl);
                    var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild);
                    scrollbarDummyEl.scrollLeft = 999;
                    var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild);
                    return {
                        // determines if the scrolling is responding with negative values
                        isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0,
                        // determines if the origin scrollbar position is inverted or not (positioned on left or right)
                        isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left
                    };
                }
            }, {
                key: "initHtmlApi",
                value: function initHtmlApi() {
                    this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+

                    if (typeof MutationObserver !== 'undefined') {
                        // Mutation observer to observe dynamically added elements
                        this.globalObserver = new MutationObserver(function (mutations) {
                            mutations.forEach(function (mutation) {
                                Array.from(mutation.addedNodes).forEach(function (addedNode) {
                                    if (addedNode.nodeType === 1) {
                                        if (addedNode.hasAttribute('data-simplebar')) {
                                            !addedNode.SimpleBar && new SimpleBar(addedNode, SimpleBar.getElOptions(addedNode));
                                        } else {
                                            Array.from(addedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                                                !el.SimpleBar && new SimpleBar(el, SimpleBar.getElOptions(el));
                                            });
                                        }
                                    }
                                });
                                Array.from(mutation.removedNodes).forEach(function (removedNode) {
                                    if (removedNode.nodeType === 1) {
                                        if (removedNode.hasAttribute('data-simplebar')) {
                                            removedNode.SimpleBar && removedNode.SimpleBar.unMount();
                                        } else {
                                            Array.from(removedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                                                el.SimpleBar && el.SimpleBar.unMount();
                                            });
                                        }
                                    }
                                });
                            });
                        });
                        this.globalObserver.observe(document, {
                            childList: true,
                            subtree: true
                        });
                    } // Taken from jQuery `ready` function
                    // Instantiate elements already present on the page


                    if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) {
                        // Handle it asynchronously to allow scripts the opportunity to delay init
                        window.setTimeout(this.initDOMLoadedElements);
                    } else {
                        document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements);
                        window.addEventListener('load', this.initDOMLoadedElements);
                    }
                } // Helper function to retrieve options from element attributes

            }, {
                key: "getElOptions",
                value: function getElOptions(el) {
                    var options = Array.from(el.attributes).reduce(function (acc, attribute) {
                        var option = attribute.name.match(/data-simplebar-(.+)/);

                        if (option) {
                            var key = option[1].replace(/\W+(.)/g, function (x, chr) {
                                return chr.toUpperCase();
                            });

                            switch (attribute.value) {
                                case 'true':
                                    acc[key] = true;
                                    break;

                                case 'false':
                                    acc[key] = false;
                                    break;

                                case undefined:
                                    acc[key] = true;
                                    break;

                                default:
                                    acc[key] = attribute.value;
                            }
                        }

                        return acc;
                    }, {});
                    return options;
                }
            }, {
                key: "removeObserver",
                value: function removeObserver() {
                    this.globalObserver.disconnect();
                }
            }, {
                key: "initDOMLoadedElements",
                value: function initDOMLoadedElements() {
                    document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements);
                    window.removeEventListener('load', this.initDOMLoadedElements);
                    Array.from(document.querySelectorAll('[data-simplebar]')).forEach(function (el) {
                        if (!el.SimpleBar) new SimpleBar(el, SimpleBar.getElOptions(el));
                    });
                }
            }, {
                key: "getOffset",
                value: function getOffset(el) {
                    var rect = el.getBoundingClientRect();
                    return {
                        top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),
                        left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft)
                    };
                }
            }]);

            return SimpleBar;
        }();
	/**
	 * HTML API
	 * Called only in a browser env.
	 */


    SimpleBar.defaultOptions = {
        autoHide: true,
        forceVisible: false,
        classNames: {
            content: 'simplebar-content',
            offset: 'simplebar-offset',
            mask: 'simplebar-mask',
            wrapper: 'simplebar-wrapper',
            placeholder: 'simplebar-placeholder',
            scrollbar: 'simplebar-scrollbar',
            track: 'simplebar-track',
            heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper',
            heightAutoObserverEl: 'simplebar-height-auto-observer',
            visible: 'simplebar-visible',
            horizontal: 'simplebar-horizontal',
            vertical: 'simplebar-vertical',
            hover: 'simplebar-hover'
        },
        scrollbarMinSize: 25,
        scrollbarMaxSize: 0,
        timeout: 1000
    };

    if (canUseDom) {
        SimpleBar.initHtmlApi();
    }

    return SimpleBar;

})));
(function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f() } else if (typeof define === "function" && define.amd) { define([], f) } else { var g; if (typeof window !== "undefined") { g = window } else if (typeof global !== "undefined") { g = global } else if (typeof self !== "undefined") { g = self } else { g = this } g.ProgressBar = f() } })(function () {
    var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({
        1: [function (require, module, exports) {
            /* shifty - v1.5.3 - 2016-11-29 - http://jeremyckahn.github.io/shifty */
            ; (function () {
                var root = this || Function('return this')();

                /**
                 * Shifty Core
                 * By Jeremy Kahn - jeremyckahn@gmail.com
                 */

                var Tweenable = (function () {

                    'use strict';

                    // Aliases that get defined later in this function
                    var formula;

                    // CONSTANTS
                    var DEFAULT_SCHEDULE_FUNCTION;
                    var DEFAULT_EASING = 'linear';
                    var DEFAULT_DURATION = 500;
                    var UPDATE_TIME = 1000 / 60;

                    var _now = Date.now
                        ? Date.now
                        : function () { return +new Date(); };

                    var now = typeof SHIFTY_DEBUG_NOW !== 'undefined' ? SHIFTY_DEBUG_NOW : _now;

                    if (typeof window !== 'undefined') {
                        // requestAnimationFrame() shim by Paul Irish (modified for Shifty)
                        // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
                        DEFAULT_SCHEDULE_FUNCTION = window.requestAnimationFrame
                            || window.webkitRequestAnimationFrame
                            || window.oRequestAnimationFrame
                            || window.msRequestAnimationFrame
                            || (window.mozCancelRequestAnimationFrame
                                && window.mozRequestAnimationFrame)
                            || setTimeout;
                    } else {
                        DEFAULT_SCHEDULE_FUNCTION = setTimeout;
                    }

                    function noop() {
                        // NOOP!
                    }

                    /**
                     * Handy shortcut for doing a for-in loop. This is not a "normal" each
                     * function, it is optimized for Shifty.  The iterator function only receives
                     * the property name, not the value.
                     * @param {Object} obj
                     * @param {Function(string)} fn
                     * @private
                     */
                    function each(obj, fn) {
                        var key;
                        for (key in obj) {
                            if (Object.hasOwnProperty.call(obj, key)) {
                                fn(key);
                            }
                        }
                    }

                    /**
                     * Perform a shallow copy of Object properties.
                     * @param {Object} targetObject The object to copy into
                     * @param {Object} srcObject The object to copy from
                     * @return {Object} A reference to the augmented `targetObj` Object
                     * @private
                     */
                    function shallowCopy(targetObj, srcObj) {
                        each(srcObj, function (prop) {
                            targetObj[prop] = srcObj[prop];
                        });

                        return targetObj;
                    }

                    /**
                     * Copies each property from src onto target, but only if the property to
                     * copy to target is undefined.
                     * @param {Object} target Missing properties in this Object are filled in
                     * @param {Object} src
                     * @private
                     */
                    function defaults(target, src) {
                        each(src, function (prop) {
                            if (typeof target[prop] === 'undefined') {
                                target[prop] = src[prop];
                            }
                        });
                    }

                    /**
                     * Calculates the interpolated tween values of an Object for a given
                     * timestamp.
                     * @param {Number} forPosition The position to compute the state for.
                     * @param {Object} currentState Current state properties.
                     * @param {Object} originalState: The original state properties the Object is
                     * tweening from.
                     * @param {Object} targetState: The destination state properties the Object
                     * is tweening to.
                     * @param {number} duration: The length of the tween in milliseconds.
                     * @param {number} timestamp: The UNIX epoch time at which the tween began.
                     * @param {Object} easing: This Object's keys must correspond to the keys in
                     * targetState.
                     * @private
                     */
                    function tweenProps(forPosition, currentState, originalState, targetState,
                        duration, timestamp, easing) {
                        var normalizedPosition =
                            forPosition < timestamp ? 0 : (forPosition - timestamp) / duration;


                        var prop;
                        var easingObjectProp;
                        var easingFn;
                        for (prop in currentState) {
                            if (currentState.hasOwnProperty(prop)) {
                                easingObjectProp = easing[prop];
                                easingFn = typeof easingObjectProp === 'function'
                                    ? easingObjectProp
                                    : formula[easingObjectProp];

                                currentState[prop] = tweenProp(
                                    originalState[prop],
                                    targetState[prop],
                                    easingFn,
                                    normalizedPosition
                                );
                            }
                        }

                        return currentState;
                    }

                    /**
                     * Tweens a single property.
                     * @param {number} start The value that the tween started from.
                     * @param {number} end The value that the tween should end at.
                     * @param {Function} easingFunc The easing curve to apply to the tween.
                     * @param {number} position The normalized position (between 0.0 and 1.0) to
                     * calculate the midpoint of 'start' and 'end' against.
                     * @return {number} The tweened value.
                     * @private
                     */
                    function tweenProp(start, end, easingFunc, position) {
                        return start + (end - start) * easingFunc(position);
                    }

                    /**
                     * Applies a filter to Tweenable instance.
                     * @param {Tweenable} tweenable The `Tweenable` instance to call the filter
                     * upon.
                     * @param {String} filterName The name of the filter to apply.
                     * @private
                     */
                    function applyFilter(tweenable, filterName) {
                        var filters = Tweenable.prototype.filter;
                        var args = tweenable._filterArgs;

                        each(filters, function (name) {
                            if (typeof filters[name][filterName] !== 'undefined') {
                                filters[name][filterName].apply(tweenable, args);
                            }
                        });
                    }

                    var timeoutHandler_endTime;
                    var timeoutHandler_currentTime;
                    var timeoutHandler_isEnded;
                    var timeoutHandler_offset;
                    /**
                     * Handles the update logic for one step of a tween.
                     * @param {Tweenable} tweenable
                     * @param {number} timestamp
                     * @param {number} delay
                     * @param {number} duration
                     * @param {Object} currentState
                     * @param {Object} originalState
                     * @param {Object} targetState
                     * @param {Object} easing
                     * @param {Function(Object, *, number)} step
                     * @param {Function(Function,number)}} schedule
                     * @param {number=} opt_currentTimeOverride Needed for accurate timestamp in
                     * Tweenable#seek.
                     * @private
                     */
                    function timeoutHandler(tweenable, timestamp, delay, duration, currentState,
                        originalState, targetState, easing, step, schedule,
                        opt_currentTimeOverride) {

                        timeoutHandler_endTime = timestamp + delay + duration;

                        timeoutHandler_currentTime =
                            Math.min(opt_currentTimeOverride || now(), timeoutHandler_endTime);

                        timeoutHandler_isEnded =
                            timeoutHandler_currentTime >= timeoutHandler_endTime;

                        timeoutHandler_offset = duration - (
                            timeoutHandler_endTime - timeoutHandler_currentTime);

                        if (tweenable.isPlaying()) {
                            if (timeoutHandler_isEnded) {
                                step(targetState, tweenable._attachment, timeoutHandler_offset);
                                tweenable.stop(true);
                            } else {
                                tweenable._scheduleId =
                                    schedule(tweenable._timeoutHandler, UPDATE_TIME);

                                applyFilter(tweenable, 'beforeTween');

                                // If the animation has not yet reached the start point (e.g., there was
                                // delay that has not yet completed), just interpolate the starting
                                // position of the tween.
                                if (timeoutHandler_currentTime < (timestamp + delay)) {
                                    tweenProps(1, currentState, originalState, targetState, 1, 1, easing);
                                } else {
                                    tweenProps(timeoutHandler_currentTime, currentState, originalState,
                                        targetState, duration, timestamp + delay, easing);
                                }

                                applyFilter(tweenable, 'afterTween');

                                step(currentState, tweenable._attachment, timeoutHandler_offset);
                            }
                        }
                    }


                    /**
                     * Creates a usable easing Object from a string, a function or another easing
                     * Object.  If `easing` is an Object, then this function clones it and fills
                     * in the missing properties with `"linear"`.
                     * @param {Object.<string|Function>} fromTweenParams
                     * @param {Object|string|Function} easing
                     * @return {Object.<string|Function>}
                     * @private
                     */
                    function composeEasingObject(fromTweenParams, easing) {
                        var composedEasing = {};
                        var typeofEasing = typeof easing;

                        if (typeofEasing === 'string' || typeofEasing === 'function') {
                            each(fromTweenParams, function (prop) {
                                composedEasing[prop] = easing;
                            });
                        } else {
                            each(fromTweenParams, function (prop) {
                                if (!composedEasing[prop]) {
                                    composedEasing[prop] = easing[prop] || DEFAULT_EASING;
                                }
                            });
                        }

                        return composedEasing;
                    }

                    /**
                     * Tweenable constructor.
                     * @class Tweenable
                     * @param {Object=} opt_initialState The values that the initial tween should
                     * start at if a `from` object is not provided to `{{#crossLink
                     * "Tweenable/tween:method"}}{{/crossLink}}` or `{{#crossLink
                     * "Tweenable/setConfig:method"}}{{/crossLink}}`.
                     * @param {Object=} opt_config Configuration object to be passed to
                     * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`.
                     * @module Tweenable
                     * @constructor
                     */
                    function Tweenable(opt_initialState, opt_config) {
                        this._currentState = opt_initialState || {};
                        this._configured = false;
                        this._scheduleFunction = DEFAULT_SCHEDULE_FUNCTION;

                        // To prevent unnecessary calls to setConfig do not set default
                        // configuration here.  Only set default configuration immediately before
                        // tweening if none has been set.
                        if (typeof opt_config !== 'undefined') {
                            this.setConfig(opt_config);
                        }
                    }

                    /**
                     * Configure and start a tween.
                     * @method tween
                     * @param {Object=} opt_config Configuration object to be passed to
                     * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`.
                     * @chainable
                     */
                    Tweenable.prototype.tween = function (opt_config) {
                        if (this._isTweening) {
                            return this;
                        }

                        // Only set default config if no configuration has been set previously and
                        // none is provided now.
                        if (opt_config !== undefined || !this._configured) {
                            this.setConfig(opt_config);
                        }

                        this._timestamp = now();
                        this._start(this.get(), this._attachment);
                        return this.resume();
                    };

                    /**
                     * Configure a tween that will start at some point in the future.
                     *
                     * @method setConfig
                     * @param {Object} config The following values are valid:
                     * - __from__ (_Object=_): Starting position.  If omitted, `{{#crossLink
                     *   "Tweenable/get:method"}}get(){{/crossLink}}` is used.
                     * - __to__ (_Object=_): Ending position.
                     * - __duration__ (_number=_): How many milliseconds to animate for.
                     * - __delay__ (_delay=_): How many milliseconds to wait before starting the
                     *   tween.
                     * - __start__ (_Function(Object, *)_): Function to execute when the tween
                     *   begins.  Receives the state of the tween as the first parameter and
                     *   `attachment` as the second parameter.
                     * - __step__ (_Function(Object, *, number)_): Function to execute on every
                     *   tick.  Receives `{{#crossLink
                     *   "Tweenable/get:method"}}get(){{/crossLink}}` as the first parameter,
                     *   `attachment` as the second parameter, and the time elapsed since the
                     *   start of the tween as the third. This function is not called on the
                     *   final step of the animation, but `finish` is.
                     * - __finish__ (_Function(Object, *)_): Function to execute upon tween
                     *   completion.  Receives the state of the tween as the first parameter and
                     *   `attachment` as the second parameter.
                     * - __easing__ (_Object.<string|Function>|string|Function=_): Easing curve
                     *   name(s) or function(s) to use for the tween.
                     * - __attachment__ (_*_): Cached value that is passed to the
                     *   `step`/`start`/`finish` methods.
                     * @chainable
                     */
                    Tweenable.prototype.setConfig = function (config) {
                        config = config || {};
                        this._configured = true;

                        // Attach something to this Tweenable instance (e.g.: a DOM element, an
                        // object, a string, etc.);
                        this._attachment = config.attachment;

                        // Init the internal state
                        this._pausedAtTime = null;
                        this._scheduleId = null;
                        this._delay = config.delay || 0;
                        this._start = config.start || noop;
                        this._step = config.step || noop;
                        this._finish = config.finish || noop;
                        this._duration = config.duration || DEFAULT_DURATION;
                        this._currentState = shallowCopy({}, config.from || this.get());
                        this._originalState = this.get();
                        this._targetState = shallowCopy({}, config.to || this.get());

                        var self = this;
                        this._timeoutHandler = function () {
                            timeoutHandler(self,
                                self._timestamp,
                                self._delay,
                                self._duration,
                                self._currentState,
                                self._originalState,
                                self._targetState,
                                self._easing,
                                self._step,
                                self._scheduleFunction
                            );
                        };

                        // Aliases used below
                        var currentState = this._currentState;
                        var targetState = this._targetState;

                        // Ensure that there is always something to tween to.
                        defaults(targetState, currentState);

                        this._easing = composeEasingObject(
                            currentState, config.easing || DEFAULT_EASING);

                        this._filterArgs =
                            [currentState, this._originalState, targetState, this._easing];

                        applyFilter(this, 'tweenCreated');
                        return this;
                    };

                    /**
                     * @method get
                     * @return {Object} The current state.
                     */
                    Tweenable.prototype.get = function () {
                        return shallowCopy({}, this._currentState);
                    };

                    /**
                     * @method set
                     * @param {Object} state The current state.
                     */
                    Tweenable.prototype.set = function (state) {
                        this._currentState = state;
                    };

                    /**
                     * Pause a tween.  Paused tweens can be resumed from the point at which they
                     * were paused.  This is different from `{{#crossLink
                     * "Tweenable/stop:method"}}{{/crossLink}}`, as that method
                     * causes a tween to start over when it is resumed.
                     * @method pause
                     * @chainable
                     */
                    Tweenable.prototype.pause = function () {
                        this._pausedAtTime = now();
                        this._isPaused = true;
                        return this;
                    };

                    /**
                     * Resume a paused tween.
                     * @method resume
                     * @chainable
                     */
                    Tweenable.prototype.resume = function () {
                        if (this._isPaused) {
                            this._timestamp += now() - this._pausedAtTime;
                        }

                        this._isPaused = false;
                        this._isTweening = true;

                        this._timeoutHandler();

                        return this;
                    };

                    /**
                     * Move the state of the animation to a specific point in the tween's
                     * timeline.  If the animation is not running, this will cause the `step`
                     * handlers to be called.
                     * @method seek
                     * @param {millisecond} millisecond The millisecond of the animation to seek
                     * to.  This must not be less than `0`.
                     * @chainable
                     */
                    Tweenable.prototype.seek = function (millisecond) {
                        millisecond = Math.max(millisecond, 0);
                        var currentTime = now();

                        if ((this._timestamp + millisecond) === 0) {
                            return this;
                        }

                        this._timestamp = currentTime - millisecond;

                        if (!this.isPlaying()) {
                            this._isTweening = true;
                            this._isPaused = false;

                            // If the animation is not running, call timeoutHandler to make sure that
                            // any step handlers are run.
                            timeoutHandler(this,
                                this._timestamp,
                                this._delay,
                                this._duration,
                                this._currentState,
                                this._originalState,
                                this._targetState,
                                this._easing,
                                this._step,
                                this._scheduleFunction,
                                currentTime
                            );

                            this.pause();
                        }

                        return this;
                    };

                    /**
                     * Stops and cancels a tween.
                     * @param {boolean=} gotoEnd If `false` or omitted, the tween just stops at
                     * its current state, and the `finish` handler is not invoked.  If `true`,
                     * the tweened object's values are instantly set to the target values, and
                     * `finish` is invoked.
                     * @method stop
                     * @chainable
                     */
                    Tweenable.prototype.stop = function (gotoEnd) {
                        this._isTweening = false;
                        this._isPaused = false;
                        this._timeoutHandler = noop;

                        (root.cancelAnimationFrame ||
                            root.webkitCancelAnimationFrame ||
                            root.oCancelAnimationFrame ||
                            root.msCancelAnimationFrame ||
                            root.mozCancelRequestAnimationFrame ||
                            root.clearTimeout)(this._scheduleId);

                        if (gotoEnd) {
                            applyFilter(this, 'beforeTween');
                            tweenProps(
                                1,
                                this._currentState,
                                this._originalState,
                                this._targetState,
                                1,
                                0,
                                this._easing
                            );
                            applyFilter(this, 'afterTween');
                            applyFilter(this, 'afterTweenEnd');
                            this._finish.call(this, this._currentState, this._attachment);
                        }

                        return this;
                    };

                    /**
                     * @method isPlaying
                     * @return {boolean} Whether or not a tween is running.
                     */
                    Tweenable.prototype.isPlaying = function () {
                        return this._isTweening && !this._isPaused;
                    };

                    /**
                     * Set a custom schedule function.
                     *
                     * If a custom function is not set,
                     * [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame)
                     * is used if available, otherwise
                     * [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout)
                     * is used.
                     * @method setScheduleFunction
                     * @param {Function(Function,number)} scheduleFunction The function to be
                     * used to schedule the next frame to be rendered.
                     */
                    Tweenable.prototype.setScheduleFunction = function (scheduleFunction) {
                        this._scheduleFunction = scheduleFunction;
                    };

                    /**
                     * `delete` all "own" properties.  Call this when the `Tweenable` instance
                     * is no longer needed to free memory.
                     * @method dispose
                     */
                    Tweenable.prototype.dispose = function () {
                        var prop;
                        for (prop in this) {
                            if (this.hasOwnProperty(prop)) {
                                delete this[prop];
                            }
                        }
                    };

                    /**
                     * Filters are used for transforming the properties of a tween at various
                     * points in a Tweenable's life cycle.  See the README for more info on this.
                     * @private
                     */
                    Tweenable.prototype.filter = {};

                    /**
                     * This object contains all of the tweens available to Shifty.  It is
                     * extensible - simply attach properties to the `Tweenable.prototype.formula`
                     * Object following the same format as `linear`.
                     *
                     * `pos` should be a normalized `number` (between 0 and 1).
                     * @property formula
                     * @type {Object(function)}
                     */
                    Tweenable.prototype.formula = {
                        linear: function (pos) {
                            return pos;
                        }
                    };

                    formula = Tweenable.prototype.formula;

                    shallowCopy(Tweenable, {
                        'now': now
                        , 'each': each
                        , 'tweenProps': tweenProps
                        , 'tweenProp': tweenProp
                        , 'applyFilter': applyFilter
                        , 'shallowCopy': shallowCopy
                        , 'defaults': defaults
                        , 'composeEasingObject': composeEasingObject
                    });

                    // `root` is provided in the intro/outro files.

                    // A hook used for unit testing.
                    if (typeof SHIFTY_DEBUG_NOW === 'function') {
                        root.timeoutHandler = timeoutHandler;
                    }

                    // Bootstrap Tweenable appropriately for the environment.
                    if (typeof exports === 'object') {
                        // CommonJS
                        module.exports = Tweenable;
                    } else if (typeof define === 'function' && define.amd) {
                        // AMD
                        define(function () { return Tweenable; });
                    } else if (typeof root.Tweenable === 'undefined') {
                        // Browser: Make `Tweenable` globally accessible.
                        root.Tweenable = Tweenable;
                    }

                    return Tweenable;

                }());

                /*!
                 * All equations are adapted from Thomas Fuchs'
                 * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/penner.js).
                 *
                 * Based on Easing Equations (c) 2003 [Robert
                 * Penner](http://www.robertpenner.com/), all rights reserved. This work is
                 * [subject to terms](http://www.robertpenner.com/easing_terms_of_use.html).
                 */

                /*!
                 *  TERMS OF USE - EASING EQUATIONS
                 *  Open source under the BSD License.
                 *  Easing Equations (c) 2003 Robert Penner, all rights reserved.
                 */

                ; (function () {

                    Tweenable.shallowCopy(Tweenable.prototype.formula, {
                        easeInQuad: function (pos) {
                            return Math.pow(pos, 2);
                        },

                        easeOutQuad: function (pos) {
                            return -(Math.pow((pos - 1), 2) - 1);
                        },

                        easeInOutQuad: function (pos) {
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 2); }
                            return -0.5 * ((pos -= 2) * pos - 2);
                        },

                        easeInCubic: function (pos) {
                            return Math.pow(pos, 3);
                        },

                        easeOutCubic: function (pos) {
                            return (Math.pow((pos - 1), 3) + 1);
                        },

                        easeInOutCubic: function (pos) {
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 3); }
                            return 0.5 * (Math.pow((pos - 2), 3) + 2);
                        },

                        easeInQuart: function (pos) {
                            return Math.pow(pos, 4);
                        },

                        easeOutQuart: function (pos) {
                            return -(Math.pow((pos - 1), 4) - 1);
                        },

                        easeInOutQuart: function (pos) {
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 4); }
                            return -0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2);
                        },

                        easeInQuint: function (pos) {
                            return Math.pow(pos, 5);
                        },

                        easeOutQuint: function (pos) {
                            return (Math.pow((pos - 1), 5) + 1);
                        },

                        easeInOutQuint: function (pos) {
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 5); }
                            return 0.5 * (Math.pow((pos - 2), 5) + 2);
                        },

                        easeInSine: function (pos) {
                            return -Math.cos(pos * (Math.PI / 2)) + 1;
                        },

                        easeOutSine: function (pos) {
                            return Math.sin(pos * (Math.PI / 2));
                        },

                        easeInOutSine: function (pos) {
                            return (-0.5 * (Math.cos(Math.PI * pos) - 1));
                        },

                        easeInExpo: function (pos) {
                            return (pos === 0) ? 0 : Math.pow(2, 10 * (pos - 1));
                        },

                        easeOutExpo: function (pos) {
                            return (pos === 1) ? 1 : -Math.pow(2, -10 * pos) + 1;
                        },

                        easeInOutExpo: function (pos) {
                            if (pos === 0) { return 0; }
                            if (pos === 1) { return 1; }
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(2, 10 * (pos - 1)); }
                            return 0.5 * (-Math.pow(2, -10 * --pos) + 2);
                        },

                        easeInCirc: function (pos) {
                            return -(Math.sqrt(1 - (pos * pos)) - 1);
                        },

                        easeOutCirc: function (pos) {
                            return Math.sqrt(1 - Math.pow((pos - 1), 2));
                        },

                        easeInOutCirc: function (pos) {
                            if ((pos /= 0.5) < 1) { return -0.5 * (Math.sqrt(1 - pos * pos) - 1); }
                            return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1);
                        },

                        easeOutBounce: function (pos) {
                            if ((pos) < (1 / 2.75)) {
                                return (7.5625 * pos * pos);
                            } else if (pos < (2 / 2.75)) {
                                return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
                            } else if (pos < (2.5 / 2.75)) {
                                return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
                            } else {
                                return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
                            }
                        },

                        easeInBack: function (pos) {
                            var s = 1.70158;
                            return (pos) * pos * ((s + 1) * pos - s);
                        },

                        easeOutBack: function (pos) {
                            var s = 1.70158;
                            return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1;
                        },

                        easeInOutBack: function (pos) {
                            var s = 1.70158;
                            if ((pos /= 0.5) < 1) {
                                return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s));
                            }
                            return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
                        },

                        elastic: function (pos) {
                            // jshint maxlen:90
                            return -1 * Math.pow(4, -8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1;
                        },

                        swingFromTo: function (pos) {
                            var s = 1.70158;
                            return ((pos /= 0.5) < 1) ?
                                0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) :
                                0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
                        },

                        swingFrom: function (pos) {
                            var s = 1.70158;
                            return pos * pos * ((s + 1) * pos - s);
                        },

                        swingTo: function (pos) {
                            var s = 1.70158;
                            return (pos -= 1) * pos * ((s + 1) * pos + s) + 1;
                        },

                        bounce: function (pos) {
                            if (pos < (1 / 2.75)) {
                                return (7.5625 * pos * pos);
                            } else if (pos < (2 / 2.75)) {
                                return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
                            } else if (pos < (2.5 / 2.75)) {
                                return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
                            } else {
                                return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
                            }
                        },

                        bouncePast: function (pos) {
                            if (pos < (1 / 2.75)) {
                                return (7.5625 * pos * pos);
                            } else if (pos < (2 / 2.75)) {
                                return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
                            } else if (pos < (2.5 / 2.75)) {
                                return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
                            } else {
                                return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
                            }
                        },

                        easeFromTo: function (pos) {
                            if ((pos /= 0.5) < 1) { return 0.5 * Math.pow(pos, 4); }
                            return -0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2);
                        },

                        easeFrom: function (pos) {
                            return Math.pow(pos, 4);
                        },

                        easeTo: function (pos) {
                            return Math.pow(pos, 0.25);
                        }
                    });

                }());

                // jshint maxlen:100
                /**
                 * The Bezier magic in this file is adapted/copied almost wholesale from
                 * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/cubic-bezier.js),
                 * which was adapted from Apple code (which probably came from
                 * [here](http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h)).
                 * Special thanks to Apple and Thomas Fuchs for much of this code.
                 */

                /**
                 *  Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
                 *
                 *  Redistribution and use in source and binary forms, with or without
                 *  modification, are permitted provided that the following conditions are met:
                 *
                 *  1. Redistributions of source code must retain the above copyright notice,
                 *  this list of conditions and the following disclaimer.
                 *
                 *  2. Redistributions in binary form must reproduce the above copyright notice,
                 *  this list of conditions and the following disclaimer in the documentation
                 *  and/or other materials provided with the distribution.
                 *
                 *  3. Neither the name of the copyright holder(s) nor the names of any
                 *  contributors may be used to endorse or promote products derived from
                 *  this software without specific prior written permission.
                 *
                 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
                 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
                 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                 *  POSSIBILITY OF SUCH DAMAGE.
                 */
                ; (function () {
                    // port of webkit cubic bezier handling by http://www.netzgesta.de/dev/
                    function cubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {
                        var ax = 0, bx = 0, cx = 0, ay = 0, by = 0, cy = 0;
                        function sampleCurveX(t) {
                            return ((ax * t + bx) * t + cx) * t;
                        }
                        function sampleCurveY(t) {
                            return ((ay * t + by) * t + cy) * t;
                        }
                        function sampleCurveDerivativeX(t) {
                            return (3.0 * ax * t + 2.0 * bx) * t + cx;
                        }
                        function solveEpsilon(duration) {
                            return 1.0 / (200.0 * duration);
                        }
                        function solve(x, epsilon) {
                            return sampleCurveY(solveCurveX(x, epsilon));
                        }
                        function fabs(n) {
                            if (n >= 0) {
                                return n;
                            } else {
                                return 0 - n;
                            }
                        }
                        function solveCurveX(x, epsilon) {
                            var t0, t1, t2, x2, d2, i;
                            for (t2 = x, i = 0; i < 8; i++) {
                                x2 = sampleCurveX(t2) - x;
                                if (fabs(x2) < epsilon) {
                                    return t2;
                                }
                                d2 = sampleCurveDerivativeX(t2);
                                if (fabs(d2) < 1e-6) {
                                    break;
                                }
                                t2 = t2 - x2 / d2;
                            }
                            t0 = 0.0;
                            t1 = 1.0;
                            t2 = x;
                            if (t2 < t0) {
                                return t0;
                            }
                            if (t2 > t1) {
                                return t1;
                            }
                            while (t0 < t1) {
                                x2 = sampleCurveX(t2);
                                if (fabs(x2 - x) < epsilon) {
                                    return t2;
                                }
                                if (x > x2) {
                                    t0 = t2;
                                } else {
                                    t1 = t2;
                                }
                                t2 = (t1 - t0) * 0.5 + t0;
                            }
                            return t2; // Failure.
                        }
                        cx = 3.0 * p1x;
                        bx = 3.0 * (p2x - p1x) - cx;
                        ax = 1.0 - cx - bx;
                        cy = 3.0 * p1y;
                        by = 3.0 * (p2y - p1y) - cy;
                        ay = 1.0 - cy - by;
                        return solve(t, solveEpsilon(duration));
                    }
                    /**
                     *  getCubicBezierTransition(x1, y1, x2, y2) -> Function
                     *
                     *  Generates a transition easing function that is compatible
                     *  with WebKit's CSS transitions `-webkit-transition-timing-function`
                     *  CSS property.
                     *
                     *  The W3C has more information about CSS3 transition timing functions:
                     *  http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag
                     *
                     *  @param {number} x1
                     *  @param {number} y1
                     *  @param {number} x2
                     *  @param {number} y2
                     *  @return {function}
                     *  @private
                     */
                    function getCubicBezierTransition(x1, y1, x2, y2) {
                        return function (pos) {
                            return cubicBezierAtTime(pos, x1, y1, x2, y2, 1);
                        };
                    }
                    // End ported code

                    /**
                     * Create a Bezier easing function and attach it to `{{#crossLink
                     * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`.  This
                     * function gives you total control over the easing curve.  Matthew Lein's
                     * [Ceaser](http://matthewlein.com/ceaser/) is a useful tool for visualizing
                     * the curves you can make with this function.
                     * @method setBezierFunction
                     * @param {string} name The name of the easing curve.  Overwrites the old
                     * easing function on `{{#crossLink
                     * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}` if it
                     * exists.
                     * @param {number} x1
                     * @param {number} y1
                     * @param {number} x2
                     * @param {number} y2
                     * @return {function} The easing function that was attached to
                     * Tweenable.prototype.formula.
                     */
                    Tweenable.setBezierFunction = function (name, x1, y1, x2, y2) {
                        var cubicBezierTransition = getCubicBezierTransition(x1, y1, x2, y2);
                        cubicBezierTransition.displayName = name;
                        cubicBezierTransition.x1 = x1;
                        cubicBezierTransition.y1 = y1;
                        cubicBezierTransition.x2 = x2;
                        cubicBezierTransition.y2 = y2;

                        return Tweenable.prototype.formula[name] = cubicBezierTransition;
                    };


                    /**
                     * `delete` an easing function from `{{#crossLink
                     * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`.  Be
                     * careful with this method, as it `delete`s whatever easing formula matches
                     * `name` (which means you can delete standard Shifty easing functions).
                     * @method unsetBezierFunction
                     * @param {string} name The name of the easing function to delete.
                     * @return {function}
                     */
                    Tweenable.unsetBezierFunction = function (name) {
                        delete Tweenable.prototype.formula[name];
                    };

                })();

                ; (function () {

                    function getInterpolatedValues(
                        from, current, targetState, position, easing, delay) {
                        return Tweenable.tweenProps(
                            position, current, from, targetState, 1, delay, easing);
                    }

                    // Fake a Tweenable and patch some internals.  This approach allows us to
                    // skip uneccessary processing and object recreation, cutting down on garbage
                    // collection pauses.
                    var mockTweenable = new Tweenable();
                    mockTweenable._filterArgs = [];

                    /**
                     * Compute the midpoint of two Objects.  This method effectively calculates a
                     * specific frame of animation that `{{#crossLink
                     * "Tweenable/tween:method"}}{{/crossLink}}` does many times over the course
                     * of a full tween.
                     *
                     *     var interpolatedValues = Tweenable.interpolate({
                     *       width: '100px',
                     *       opacity: 0,
                     *       color: '#fff'
                     *     }, {
                     *       width: '200px',
                     *       opacity: 1,
                     *       color: '#000'
                     *     }, 0.5);
                     *
                     *     console.log(interpolatedValues);
                     *     // {opacity: 0.5, width: "150px", color: "rgb(127,127,127)"}
                     *
                     * @static
                     * @method interpolate
                     * @param {Object} from The starting values to tween from.
                     * @param {Object} targetState The ending values to tween to.
                     * @param {number} position The normalized position value (between `0.0` and
                     * `1.0`) to interpolate the values between `from` and `to` for.  `from`
                     * represents `0` and `to` represents `1`.
                     * @param {Object.<string|Function>|string|Function} easing The easing
                     * curve(s) to calculate the midpoint against.  You can reference any easing
                     * function attached to `Tweenable.prototype.formula`, or provide the easing
                     * function(s) directly.  If omitted, this defaults to "linear".
                     * @param {number=} opt_delay Optional delay to pad the beginning of the
                     * interpolated tween with.  This increases the range of `position` from (`0`
                     * through `1`) to (`0` through `1 + opt_delay`).  So, a delay of `0.5` would
                     * increase all valid values of `position` to numbers between `0` and `1.5`.
                     * @return {Object}
                     */
                    Tweenable.interpolate = function (
                        from, targetState, position, easing, opt_delay) {

                        var current = Tweenable.shallowCopy({}, from);
                        var delay = opt_delay || 0;
                        var easingObject = Tweenable.composeEasingObject(
                            from, easing || 'linear');

                        mockTweenable.set({});

                        // Alias and reuse the _filterArgs array instead of recreating it.
                        var filterArgs = mockTweenable._filterArgs;
                        filterArgs.length = 0;
                        filterArgs[0] = current;
                        filterArgs[1] = from;
                        filterArgs[2] = targetState;
                        filterArgs[3] = easingObject;

                        // Any defined value transformation must be applied
                        Tweenable.applyFilter(mockTweenable, 'tweenCreated');
                        Tweenable.applyFilter(mockTweenable, 'beforeTween');

                        var interpolatedValues = getInterpolatedValues(
                            from, current, targetState, position, easingObject, delay);

                        // Transform values back into their original format
                        Tweenable.applyFilter(mockTweenable, 'afterTween');

                        return interpolatedValues;
                    };

                }());

                /**
                 * This module adds string interpolation support to Shifty.
                 *
                 * The Token extension allows Shifty to tween numbers inside of strings.  Among
                 * other things, this allows you to animate CSS properties.  For example, you
                 * can do this:
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { transform: 'translateX(45px)' },
                 *       to: { transform: 'translateX(90xp)' }
                 *     });
                 *
                 * `translateX(45)` will be tweened to `translateX(90)`.  To demonstrate:
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { transform: 'translateX(45px)' },
                 *       to: { transform: 'translateX(90px)' },
                 *       step: function (state) {
                 *         console.log(state.transform);
                 *       }
                 *     });
                 *
                 * The above snippet will log something like this in the console:
                 *
                 *     translateX(60.3px)
                 *     ...
                 *     translateX(76.05px)
                 *     ...
                 *     translateX(90px)
                 *
                 * Another use for this is animating colors:
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { color: 'rgb(0,255,0)' },
                 *       to: { color: 'rgb(255,0,255)' },
                 *       step: function (state) {
                 *         console.log(state.color);
                 *       }
                 *     });
                 *
                 * The above snippet will log something like this:
                 *
                 *     rgb(84,170,84)
                 *     ...
                 *     rgb(170,84,170)
                 *     ...
                 *     rgb(255,0,255)
                 *
                 * This extension also supports hexadecimal colors, in both long (`#ff00ff`)
                 * and short (`#f0f`) forms.  Be aware that hexadecimal input values will be
                 * converted into the equivalent RGB output values.  This is done to optimize
                 * for performance.
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { color: '#0f0' },
                 *       to: { color: '#f0f' },
                 *       step: function (state) {
                 *         console.log(state.color);
                 *       }
                 *     });
                 *
                 * This snippet will generate the same output as the one before it because
                 * equivalent values were supplied (just in hexadecimal form rather than RGB):
                 *
                 *     rgb(84,170,84)
                 *     ...
                 *     rgb(170,84,170)
                 *     ...
                 *     rgb(255,0,255)
                 *
                 * ## Easing support
                 *
                 * Easing works somewhat differently in the Token extension.  This is because
                 * some CSS properties have multiple values in them, and you might need to
                 * tween each value along its own easing curve.  A basic example:
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { transform: 'translateX(0px) translateY(0px)' },
                 *       to: { transform:   'translateX(100px) translateY(100px)' },
                 *       easing: { transform: 'easeInQuad' },
                 *       step: function (state) {
                 *         console.log(state.transform);
                 *       }
                 *     });
                 *
                 * The above snippet will create values like this:
                 *
                 *     translateX(11.56px) translateY(11.56px)
                 *     ...
                 *     translateX(46.24px) translateY(46.24px)
                 *     ...
                 *     translateX(100px) translateY(100px)
                 *
                 * In this case, the values for `translateX` and `translateY` are always the
                 * same for each step of the tween, because they have the same start and end
                 * points and both use the same easing curve.  We can also tween `translateX`
                 * and `translateY` along independent curves:
                 *
                 *     var tweenable = new Tweenable();
                 *     tweenable.tween({
                 *       from: { transform: 'translateX(0px) translateY(0px)' },
                 *       to: { transform:   'translateX(100px) translateY(100px)' },
                 *       easing: { transform: 'easeInQuad bounce' },
                 *       step: function (state) {
                 *         console.log(state.transform);
                 *       }
                 *     });
                 *
                 * The above snippet will create values like this:
                 *
                 *     translateX(10.89px) translateY(82.35px)
                 *     ...
                 *     translateX(44.89px) translateY(86.73px)
                 *     ...
                 *     translateX(100px) translateY(100px)
                 *
                 * `translateX` and `translateY` are not in sync anymore, because `easeInQuad`
                 * was specified for `translateX` and `bounce` for `translateY`.  Mixing and
                 * matching easing curves can make for some interesting motion in your
                 * animations.
                 *
                 * The order of the space-separated easing curves correspond the token values
                 * they apply to.  If there are more token values than easing curves listed,
                 * the last easing curve listed is used.
                 * @submodule Tweenable.token
                 */

                // token function is defined above only so that dox-foundation sees it as
                // documentation and renders it.  It is never used, and is optimized away at
                // build time.

                ; (function (Tweenable) {

                    /**
                     * @typedef {{
                     *   formatString: string
                     *   chunkNames: Array.<string>
                     * }}
                     * @private
                     */
                    var formatManifest;

                    // CONSTANTS

                    var R_NUMBER_COMPONENT = /(\d|\-|\.)/;
                    var R_FORMAT_CHUNKS = /([^\-0-9\.]+)/g;
                    var R_UNFORMATTED_VALUES = /[0-9.\-]+/g;
                    var R_RGB = new RegExp(
                        'rgb\\(' + R_UNFORMATTED_VALUES.source +
                        (/,\s*/.source) + R_UNFORMATTED_VALUES.source +
                        (/,\s*/.source) + R_UNFORMATTED_VALUES.source + '\\)', 'g');
                    var R_RGB_PREFIX = /^.*\(/;
                    var R_HEX = /#([0-9]|[a-f]){3,6}/gi;
                    var VALUE_PLACEHOLDER = 'VAL';

                    // HELPERS

                    /**
                     * @param {Array.number} rawValues
                     * @param {string} prefix
                     *
                     * @return {Array.<string>}
                     * @private
                     */
                    function getFormatChunksFrom(rawValues, prefix) {
                        var accumulator = [];

                        var rawValuesLength = rawValues.length;
                        var i;

                        for (i = 0; i < rawValuesLength; i++) {
                            accumulator.push('_' + prefix + '_' + i);
                        }

                        return accumulator;
                    }

                    /**
                     * @param {string} formattedString
                     *
                     * @return {string}
                     * @private
                     */
                    function getFormatStringFrom(formattedString) {
                        var chunks = formattedString.match(R_FORMAT_CHUNKS);

                        if (!chunks) {
                            // chunks will be null if there were no tokens to parse in
                            // formattedString (for example, if formattedString is '2').  Coerce
                            // chunks to be useful here.
                            chunks = ['', ''];

                            // If there is only one chunk, assume that the string is a number
                            // followed by a token...
                            // NOTE: This may be an unwise assumption.
                        } else if (chunks.length === 1 ||
                            // ...or if the string starts with a number component (".", "-", or a
                            // digit)...
                            formattedString.charAt(0).match(R_NUMBER_COMPONENT)) {
                            // ...prepend an empty string here to make sure that the formatted number
                            // is properly replaced by VALUE_PLACEHOLDER
                            chunks.unshift('');
                        }

                        return chunks.join(VALUE_PLACEHOLDER);
                    }

                    /**
                     * Convert all hex color values within a string to an rgb string.
                     *
                     * @param {Object} stateObject
                     *
                     * @return {Object} The modified obj
                     * @private
                     */
                    function sanitizeObjectForHexProps(stateObject) {
                        Tweenable.each(stateObject, function (prop) {
                            var currentProp = stateObject[prop];

                            if (typeof currentProp === 'string' && currentProp.match(R_HEX)) {
                                stateObject[prop] = sanitizeHexChunksToRGB(currentProp);
                            }
                        });
                    }

                    /**
                     * @param {string} str
                     *
                     * @return {string}
                     * @private
                     */
                    function sanitizeHexChunksToRGB(str) {
                        return filterStringChunks(R_HEX, str, convertHexToRGB);
                    }

                    /**
                     * @param {string} hexString
                     *
                     * @return {string}
                     * @private
                     */
                    function convertHexToRGB(hexString) {
                        var rgbArr = hexToRGBArray(hexString);
                        return 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')';
                    }

                    var hexToRGBArray_returnArray = [];
                    /**
                     * Convert a hexadecimal string to an array with three items, one each for
                     * the red, blue, and green decimal values.
                     *
                     * @param {string} hex A hexadecimal string.
                     *
                     * @returns {Array.<number>} The converted Array of RGB values if `hex` is a
                     * valid string, or an Array of three 0's.
                     * @private
                     */
                    function hexToRGBArray(hex) {

                        hex = hex.replace(/#/, '');

                        // If the string is a shorthand three digit hex notation, normalize it to
                        // the standard six digit notation
                        if (hex.length === 3) {
                            hex = hex.split('');
                            hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
                        }

                        hexToRGBArray_returnArray[0] = hexToDec(hex.substr(0, 2));
                        hexToRGBArray_returnArray[1] = hexToDec(hex.substr(2, 2));
                        hexToRGBArray_returnArray[2] = hexToDec(hex.substr(4, 2));

                        return hexToRGBArray_returnArray;
                    }

                    /**
                     * Convert a base-16 number to base-10.
                     *
                     * @param {Number|String} hex The value to convert
                     *
                     * @returns {Number} The base-10 equivalent of `hex`.
                     * @private
                     */
                    function hexToDec(hex) {
                        return parseInt(hex, 16);
                    }

                    /**
                     * Runs a filter operation on all chunks of a string that match a RegExp
                     *
                     * @param {RegExp} pattern
                     * @param {string} unfilteredString
                     * @param {function(string)} filter
                     *
                     * @return {string}
                     * @private
                     */
                    function filterStringChunks(pattern, unfilteredString, filter) {
                        var pattenMatches = unfilteredString.match(pattern);
                        var filteredString = unfilteredString.replace(pattern, VALUE_PLACEHOLDER);

                        if (pattenMatches) {
                            var pattenMatchesLength = pattenMatches.length;
                            var currentChunk;

                            for (var i = 0; i < pattenMatchesLength; i++) {
                                currentChunk = pattenMatches.shift();
                                filteredString = filteredString.replace(
                                    VALUE_PLACEHOLDER, filter(currentChunk));
                            }
                        }

                        return filteredString;
                    }

                    /**
                     * Check for floating point values within rgb strings and rounds them.
                     *
                     * @param {string} formattedString
                     *
                     * @return {string}
                     * @private
                     */
                    function sanitizeRGBChunks(formattedString) {
                        return filterStringChunks(R_RGB, formattedString, sanitizeRGBChunk);
                    }

                    /**
                     * @param {string} rgbChunk
                     *
                     * @return {string}
                     * @private
                     */
                    function sanitizeRGBChunk(rgbChunk) {
                        var numbers = rgbChunk.match(R_UNFORMATTED_VALUES);
                        var numbersLength = numbers.length;
                        var sanitizedString = rgbChunk.match(R_RGB_PREFIX)[0];

                        for (var i = 0; i < numbersLength; i++) {
                            sanitizedString += parseInt(numbers[i], 10) + ',';
                        }

                        sanitizedString = sanitizedString.slice(0, -1) + ')';

                        return sanitizedString;
                    }

                    /**
                     * @param {Object} stateObject
                     *
                     * @return {Object} An Object of formatManifests that correspond to
                     * the string properties of stateObject
                     * @private
                     */
                    function getFormatManifests(stateObject) {
                        var manifestAccumulator = {};

                        Tweenable.each(stateObject, function (prop) {
                            var currentProp = stateObject[prop];

                            if (typeof currentProp === 'string') {
                                var rawValues = getValuesFrom(currentProp);

                                manifestAccumulator[prop] = {
                                    'formatString': getFormatStringFrom(currentProp)
                                    , 'chunkNames': getFormatChunksFrom(rawValues, prop)
                                };
                            }
                        });

                        return manifestAccumulator;
                    }

                    /**
                     * @param {Object} stateObject
                     * @param {Object} formatManifests
                     * @private
                     */
                    function expandFormattedProperties(stateObject, formatManifests) {
                        Tweenable.each(formatManifests, function (prop) {
                            var currentProp = stateObject[prop];
                            var rawValues = getValuesFrom(currentProp);
                            var rawValuesLength = rawValues.length;

                            for (var i = 0; i < rawValuesLength; i++) {
                                stateObject[formatManifests[prop].chunkNames[i]] = +rawValues[i];
                            }

                            delete stateObject[prop];
                        });
                    }

                    /**
                     * @param {Object} stateObject
                     * @param {Object} formatManifests
                     * @private
                     */
                    function collapseFormattedProperties(stateObject, formatManifests) {
                        Tweenable.each(formatManifests, function (prop) {
                            var currentProp = stateObject[prop];
                            var formatChunks = extractPropertyChunks(
                                stateObject, formatManifests[prop].chunkNames);
                            var valuesList = getValuesList(
                                formatChunks, formatManifests[prop].chunkNames);
                            currentProp = getFormattedValues(
                                formatManifests[prop].formatString, valuesList);
                            stateObject[prop] = sanitizeRGBChunks(currentProp);
                        });
                    }

                    /**
                     * @param {Object} stateObject
                     * @param {Array.<string>} chunkNames
                     *
                     * @return {Object} The extracted value chunks.
                     * @private
                     */
                    function extractPropertyChunks(stateObject, chunkNames) {
                        var extractedValues = {};
                        var currentChunkName, chunkNamesLength = chunkNames.length;

                        for (var i = 0; i < chunkNamesLength; i++) {
                            currentChunkName = chunkNames[i];
                            extractedValues[currentChunkName] = stateObject[currentChunkName];
                            delete stateObject[currentChunkName];
                        }

                        return extractedValues;
                    }

                    var getValuesList_accumulator = [];
                    /**
                     * @param {Object} stateObject
                     * @param {Array.<string>} chunkNames
                     *
                     * @return {Array.<number>}
                     * @private
                     */
                    function getValuesList(stateObject, chunkNames) {
                        getValuesList_accumulator.length = 0;
                        var chunkNamesLength = chunkNames.length;

                        for (var i = 0; i < chunkNamesLength; i++) {
                            getValuesList_accumulator.push(stateObject[chunkNames[i]]);
                        }

                        return getValuesList_accumulator;
                    }

                    /**
                     * @param {string} formatString
                     * @param {Array.<number>} rawValues
                     *
                     * @return {string}
                     * @private
                     */
                    function getFormattedValues(formatString, rawValues) {
                        var formattedValueString = formatString;
                        var rawValuesLength = rawValues.length;

                        for (var i = 0; i < rawValuesLength; i++) {
                            formattedValueString = formattedValueString.replace(
                                VALUE_PLACEHOLDER, +rawValues[i].toFixed(4));
                        }

                        return formattedValueString;
                    }

                    /**
                     * Note: It's the duty of the caller to convert the Array elements of the
                     * return value into numbers.  This is a performance optimization.
                     *
                     * @param {string} formattedString
                     *
                     * @return {Array.<string>|null}
                     * @private
                     */
                    function getValuesFrom(formattedString) {
                        return formattedString.match(R_UNFORMATTED_VALUES);
                    }

                    /**
                     * @param {Object} easingObject
                     * @param {Object} tokenData
                     * @private
                     */
                    function expandEasingObject(easingObject, tokenData) {
                        Tweenable.each(tokenData, function (prop) {
                            var currentProp = tokenData[prop];
                            var chunkNames = currentProp.chunkNames;
                            var chunkLength = chunkNames.length;

                            var easing = easingObject[prop];
                            var i;

                            if (typeof easing === 'string') {
                                var easingChunks = easing.split(' ');
                                var lastEasingChunk = easingChunks[easingChunks.length - 1];

                                for (i = 0; i < chunkLength; i++) {
                                    easingObject[chunkNames[i]] = easingChunks[i] || lastEasingChunk;
                                }

                            } else {
                                for (i = 0; i < chunkLength; i++) {
                                    easingObject[chunkNames[i]] = easing;
                                }
                            }

                            delete easingObject[prop];
                        });
                    }

                    /**
                     * @param {Object} easingObject
                     * @param {Object} tokenData
                     * @private
                     */
                    function collapseEasingObject(easingObject, tokenData) {
                        Tweenable.each(tokenData, function (prop) {
                            var currentProp = tokenData[prop];
                            var chunkNames = currentProp.chunkNames;
                            var chunkLength = chunkNames.length;

                            var firstEasing = easingObject[chunkNames[0]];
                            var typeofEasings = typeof firstEasing;

                            if (typeofEasings === 'string') {
                                var composedEasingString = '';

                                for (var i = 0; i < chunkLength; i++) {
                                    composedEasingString += ' ' + easingObject[chunkNames[i]];
                                    delete easingObject[chunkNames[i]];
                                }

                                easingObject[prop] = composedEasingString.substr(1);
                            } else {
                                easingObject[prop] = firstEasing;
                            }
                        });
                    }

                    Tweenable.prototype.filter.token = {
                        'tweenCreated': function (currentState, fromState, toState, easingObject) {
                            sanitizeObjectForHexProps(currentState);
                            sanitizeObjectForHexProps(fromState);
                            sanitizeObjectForHexProps(toState);
                            this._tokenData = getFormatManifests(currentState);
                        },

                        'beforeTween': function (currentState, fromState, toState, easingObject) {
                            expandEasingObject(easingObject, this._tokenData);
                            expandFormattedProperties(currentState, this._tokenData);
                            expandFormattedProperties(fromState, this._tokenData);
                            expandFormattedProperties(toState, this._tokenData);
                        },

                        'afterTween': function (currentState, fromState, toState, easingObject) {
                            collapseFormattedProperties(currentState, this._tokenData);
                            collapseFormattedProperties(fromState, this._tokenData);
                            collapseFormattedProperties(toState, this._tokenData);
                            collapseEasingObject(easingObject, this._tokenData);
                        }
                    };

                }(Tweenable));

            }).call(null);

        }, {}], 2: [function (require, module, exports) {
            // Circle shaped progress bar

            var Shape = require('./shape');
            var utils = require('./utils');

            var Circle = function Circle(container, options) {
                // Use two arcs to form a circle
                // See this answer http://stackoverflow.com/a/10477334/1446092
                this._pathTemplate =
                    'M 50,50 m 0,-{radius}' +
                    ' a {radius},{radius} 0 1 1 0,{2radius}' +
                    ' a {radius},{radius} 0 1 1 0,-{2radius}';

                this.containerAspectRatio = 1;

                Shape.apply(this, arguments);
            };

            Circle.prototype = new Shape();
            Circle.prototype.constructor = Circle;

            Circle.prototype._pathString = function _pathString(opts) {
                var widthOfWider = opts.strokeWidth;
                if (opts.trailWidth && opts.trailWidth > opts.strokeWidth) {
                    widthOfWider = opts.trailWidth;
                }

                var r = 50 - widthOfWider / 2;

                return utils.render(this._pathTemplate, {
                    radius: r,
                    '2radius': r * 2
                });
            };

            Circle.prototype._trailString = function _trailString(opts) {
                return this._pathString(opts);
            };

            module.exports = Circle;

        }, { "./shape": 7, "./utils": 9 }], 3: [function (require, module, exports) {
            // Line shaped progress bar

            var Shape = require('./shape');
            var utils = require('./utils');

            var Line = function Line(container, options) {
                this._pathTemplate = 'M 0,{center} L 100,{center}';
                Shape.apply(this, arguments);
            };

            Line.prototype = new Shape();
            Line.prototype.constructor = Line;

            Line.prototype._initializeSvg = function _initializeSvg(svg, opts) {
                svg.setAttribute('viewBox', '0 0 100 ' + opts.strokeWidth);
                svg.setAttribute('preserveAspectRatio', 'none');
            };

            Line.prototype._pathString = function _pathString(opts) {
                return utils.render(this._pathTemplate, {
                    center: opts.strokeWidth / 2
                });
            };

            Line.prototype._trailString = function _trailString(opts) {
                return this._pathString(opts);
            };

            module.exports = Line;

        }, { "./shape": 7, "./utils": 9 }], 4: [function (require, module, exports) {
            module.exports = {
                // Higher level API, different shaped progress bars
                Line: require('./line'),
                Circle: require('./circle'),
                SemiCircle: require('./semicircle'),
                Square: require('./square'),

                // Lower level API to use any SVG path
                Path: require('./path'),

                // Base-class for creating new custom shapes
                // to be in line with the API of built-in shapes
                // Undocumented.
                Shape: require('./shape'),

                // Internal utils, undocumented.
                utils: require('./utils')
            };

        }, { "./circle": 2, "./line": 3, "./path": 5, "./semicircle": 6, "./shape": 7, "./square": 8, "./utils": 9 }], 5: [function (require, module, exports) {
            // Lower level API to animate any kind of svg path

            var Tweenable = require('shifty');
            var utils = require('./utils');

            var EASING_ALIASES = {
                easeIn: 'easeInCubic',
                easeOut: 'easeOutCubic',
                easeInOut: 'easeInOutCubic'
            };

            var Path = function Path(path, opts) {
                // Throw a better error if not initialized with `new` keyword
                if (!(this instanceof Path)) {
                    throw new Error('Constructor was called without new keyword');
                }

                // Default parameters for animation
                opts = utils.extend({
                    duration: 800,
                    easing: 'linear',
                    from: {},
                    to: {},
                    step: function () { }
                }, opts);

                var element;
                if (utils.isString(path)) {
                    element = document.querySelector(path);
                } else {
                    element = path;
                }

                // Reveal .path as public attribute
                this.path = element;
                this._opts = opts;
                this._tweenable = null;

                // Set up the starting positions
                var length = this.path.getTotalLength();
                this.path.style.strokeDasharray = length + ' ' + length;
                this.set(0);
            };

            Path.prototype.value = function value() {
                var offset = this._getComputedDashOffset();
                var length = this.path.getTotalLength();

                var progress = 1 - offset / length;
                // Round number to prevent returning very small number like 1e-30, which
                // is practically 0
                return parseFloat(progress.toFixed(6), 10);
            };

            Path.prototype.set = function set(progress) {
                this.stop();

                this.path.style.strokeDashoffset = this._progressToOffset(progress);

                var step = this._opts.step;
                if (utils.isFunction(step)) {
                    var easing = this._easing(this._opts.easing);
                    var values = this._calculateTo(progress, easing);
                    var reference = this._opts.shape || this;
                    step(values, reference, this._opts.attachment);
                }
            };

            Path.prototype.stop = function stop() {
                this._stopTween();
                this.path.style.strokeDashoffset = this._getComputedDashOffset();
            };

            // Method introduced here:
            // http://jakearchibald.com/2013/animated-line-drawing-svg/
            Path.prototype.animate = function animate(progress, opts, cb) {
                opts = opts || {};

                if (utils.isFunction(opts)) {
                    cb = opts;
                    opts = {};
                }

                var passedOpts = utils.extend({}, opts);

                // Copy default opts to new object so defaults are not modified
                var defaultOpts = utils.extend({}, this._opts);
                opts = utils.extend(defaultOpts, opts);

                var shiftyEasing = this._easing(opts.easing);
                var values = this._resolveFromAndTo(progress, shiftyEasing, passedOpts);

                this.stop();

                // Trigger a layout so styles are calculated & the browser
                // picks up the starting position before animating
                this.path.getBoundingClientRect();

                var offset = this._getComputedDashOffset();
                var newOffset = this._progressToOffset(progress);

                var self = this;
                this._tweenable = new Tweenable();
                this._tweenable.tween({
                    from: utils.extend({ offset: offset }, values.from),
                    to: utils.extend({ offset: newOffset }, values.to),
                    duration: opts.duration,
                    easing: shiftyEasing,
                    step: function (state) {
                        self.path.style.strokeDashoffset = state.offset;
                        var reference = opts.shape || self;
                        opts.step(state, reference, opts.attachment);
                    },
                    finish: function (state) {
                        if (utils.isFunction(cb)) {
                            cb();
                        }
                    }
                });
            };

            Path.prototype._getComputedDashOffset = function _getComputedDashOffset() {
                var computedStyle = window.getComputedStyle(this.path, null);
                return parseFloat(computedStyle.getPropertyValue('stroke-dashoffset'), 10);
            };

            Path.prototype._progressToOffset = function _progressToOffset(progress) {
                var length = this.path.getTotalLength();
                return length - progress * length;
            };

            // Resolves from and to values for animation.
            Path.prototype._resolveFromAndTo = function _resolveFromAndTo(progress, easing, opts) {
                if (opts.from && opts.to) {
                    return {
                        from: opts.from,
                        to: opts.to
                    };
                }

                return {
                    from: this._calculateFrom(easing),
                    to: this._calculateTo(progress, easing)
                };
            };

            // Calculate `from` values from options passed at initialization
            Path.prototype._calculateFrom = function _calculateFrom(easing) {
                return Tweenable.interpolate(this._opts.from, this._opts.to, this.value(), easing);
            };

            // Calculate `to` values from options passed at initialization
            Path.prototype._calculateTo = function _calculateTo(progress, easing) {
                return Tweenable.interpolate(this._opts.from, this._opts.to, progress, easing);
            };

            Path.prototype._stopTween = function _stopTween() {
                if (this._tweenable !== null) {
                    this._tweenable.stop();
                    this._tweenable = null;
                }
            };

            Path.prototype._easing = function _easing(easing) {
                if (EASING_ALIASES.hasOwnProperty(easing)) {
                    return EASING_ALIASES[easing];
                }

                return easing;
            };

            module.exports = Path;

        }, { "./utils": 9, "shifty": 1 }], 6: [function (require, module, exports) {
            // Semi-SemiCircle shaped progress bar

            var Shape = require('./shape');
            var Circle = require('./circle');
            var utils = require('./utils');

            var SemiCircle = function SemiCircle(container, options) {
                // Use one arc to form a SemiCircle
                // See this answer http://stackoverflow.com/a/10477334/1446092
                this._pathTemplate =
                    'M 50,50 m -{radius},0' +
                    ' a {radius},{radius} 0 1 1 {2radius},0';

                this.containerAspectRatio = 2;

                Shape.apply(this, arguments);
            };

            SemiCircle.prototype = new Shape();
            SemiCircle.prototype.constructor = SemiCircle;

            SemiCircle.prototype._initializeSvg = function _initializeSvg(svg, opts) {
                svg.setAttribute('viewBox', '0 0 100 50');
            };

            SemiCircle.prototype._initializeTextContainer = function _initializeTextContainer(
                opts,
                container,
                textContainer
            ) {
                if (opts.text.style) {
                    // Reset top style
                    textContainer.style.top = 'auto';
                    textContainer.style.bottom = '0';

                    if (opts.text.alignToBottom) {
                        utils.setStyle(textContainer, 'transform', 'translate(-50%, 0)');
                    } else {
                        utils.setStyle(textContainer, 'transform', 'translate(-50%, 50%)');
                    }
                }
            };

            // Share functionality with Circle, just have different path
            SemiCircle.prototype._pathString = Circle.prototype._pathString;
            SemiCircle.prototype._trailString = Circle.prototype._trailString;

            module.exports = SemiCircle;

        }, { "./circle": 2, "./shape": 7, "./utils": 9 }], 7: [function (require, module, exports) {
            // Base object for different progress bar shapes

            var Path = require('./path');
            var utils = require('./utils');

            var DESTROYED_ERROR = 'Object is destroyed';

            var Shape = function Shape(container, opts) {
                // Throw a better error if progress bars are not initialized with `new`
                // keyword
                if (!(this instanceof Shape)) {
                    throw new Error('Constructor was called without new keyword');
                }

                // Prevent calling constructor without parameters so inheritance
                // works correctly. To understand, this is how Shape is inherited:
                //
                //   Line.prototype = new Shape();
                //
                // We just want to set the prototype for Line.
                if (arguments.length === 0) {
                    return;
                }

                // Default parameters for progress bar creation
                this._opts = utils.extend({
                    color: '#555',
                    strokeWidth: 1.0,
                    trailColor: null,
                    trailWidth: null,
                    fill: null,
                    text: {
                        style: {
                            color: null,
                            position: 'absolute',
                            left: '50%',
                            top: '50%',
                            padding: 0,
                            margin: 0,
                            transform: {
                                prefix: true,
                                value: 'translate(-50%, -50%)'
                            }
                        },
                        autoStyleContainer: true,
                        alignToBottom: true,
                        value: null,
                        className: 'progressbar-text'
                    },
                    svgStyle: {
                        display: 'block',
                        width: '100%'
                    },
                    warnings: false
                }, opts, true);  // Use recursive extend

                // If user specifies e.g. svgStyle or text style, the whole object
                // should replace the defaults to make working with styles easier
                if (utils.isObject(opts) && opts.svgStyle !== undefined) {
                    this._opts.svgStyle = opts.svgStyle;
                }
                if (utils.isObject(opts) && utils.isObject(opts.text) && opts.text.style !== undefined) {
                    this._opts.text.style = opts.text.style;
                }

                var svgView = this._createSvgView(this._opts);

                var element;
                if (utils.isString(container)) {
                    element = document.querySelector(container);
                } else {
                    element = container;
                }

                if (!element) {
                    throw new Error('Container does not exist: ' + container);
                }

                this._container = element;
                this._container.appendChild(svgView.svg);
                if (this._opts.warnings) {
                    this._warnContainerAspectRatio(this._container);
                }

                if (this._opts.svgStyle) {
                    utils.setStyles(svgView.svg, this._opts.svgStyle);
                }

                // Expose public attributes before Path initialization
                this.svg = svgView.svg;
                this.path = svgView.path;
                this.trail = svgView.trail;
                this.text = null;

                var newOpts = utils.extend({
                    attachment: undefined,
                    shape: this
                }, this._opts);
                this._progressPath = new Path(svgView.path, newOpts);

                if (utils.isObject(this._opts.text) && this._opts.text.value !== null) {
                    this.setText(this._opts.text.value);
                }
            };

            Shape.prototype.animate = function animate(progress, opts, cb) {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                this._progressPath.animate(progress, opts, cb);
            };

            Shape.prototype.stop = function stop() {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                // Don't crash if stop is called inside step function
                if (this._progressPath === undefined) {
                    return;
                }

                this._progressPath.stop();
            };

            Shape.prototype.destroy = function destroy() {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                this.stop();
                this.svg.parentNode.removeChild(this.svg);
                this.svg = null;
                this.path = null;
                this.trail = null;
                this._progressPath = null;

                if (this.text !== null) {
                    this.text.parentNode.removeChild(this.text);
                    this.text = null;
                }
            };

            Shape.prototype.set = function set(progress) {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                this._progressPath.set(progress);
            };

            Shape.prototype.value = function value() {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                if (this._progressPath === undefined) {
                    return 0;
                }

                return this._progressPath.value();
            };

            Shape.prototype.setText = function setText(newText) {
                if (this._progressPath === null) {
                    throw new Error(DESTROYED_ERROR);
                }

                if (this.text === null) {
                    // Create new text node
                    this.text = this._createTextContainer(this._opts, this._container);
                    this._container.appendChild(this.text);
                }

                // Remove previous text and add new
                if (utils.isObject(newText)) {
                    utils.removeChildren(this.text);
                    this.text.appendChild(newText);
                } else {
                    this.text.innerHTML = newText;
                }
            };

            Shape.prototype._createSvgView = function _createSvgView(opts) {
                var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                this._initializeSvg(svg, opts);

                var trailPath = null;
                // Each option listed in the if condition are 'triggers' for creating
                // the trail path
                if (opts.trailColor || opts.trailWidth) {
                    trailPath = this._createTrail(opts);
                    svg.appendChild(trailPath);
                }

                var path = this._createPath(opts);
                svg.appendChild(path);

                return {
                    svg: svg,
                    path: path,
                    trail: trailPath
                };
            };

            Shape.prototype._initializeSvg = function _initializeSvg(svg, opts) {
                svg.setAttribute('viewBox', '0 0 100 100');
            };

            Shape.prototype._createPath = function _createPath(opts) {
                var pathString = this._pathString(opts);
                return this._createPathElement(pathString, opts);
            };

            Shape.prototype._createTrail = function _createTrail(opts) {
                // Create path string with original passed options
                var pathString = this._trailString(opts);

                // Prevent modifying original
                var newOpts = utils.extend({}, opts);

                // Defaults for parameters which modify trail path
                if (!newOpts.trailColor) {
                    newOpts.trailColor = '#eee';
                }
                if (!newOpts.trailWidth) {
                    newOpts.trailWidth = newOpts.strokeWidth;
                }

                newOpts.color = newOpts.trailColor;
                newOpts.strokeWidth = newOpts.trailWidth;

                // When trail path is set, fill must be set for it instead of the
                // actual path to prevent trail stroke from clipping
                newOpts.fill = null;

                return this._createPathElement(pathString, newOpts);
            };

            Shape.prototype._createPathElement = function _createPathElement(pathString, opts) {
                var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', pathString);
                path.setAttribute('stroke', opts.color);
                path.setAttribute('stroke-width', opts.strokeWidth);

                if (opts.fill) {
                    path.setAttribute('fill', opts.fill);
                } else {
                    path.setAttribute('fill-opacity', '0');
                }

                return path;
            };

            Shape.prototype._createTextContainer = function _createTextContainer(opts, container) {
                var textContainer = document.createElement('div');
                textContainer.className = opts.text.className;

                var textStyle = opts.text.style;
                if (textStyle) {
                    if (opts.text.autoStyleContainer) {
                        container.style.position = 'relative';
                    }

                    utils.setStyles(textContainer, textStyle);
                    // Default text color to progress bar's color
                    if (!textStyle.color) {
                        textContainer.style.color = opts.color;
                    }
                }

                this._initializeTextContainer(opts, container, textContainer);
                return textContainer;
            };

            // Give custom shapes possibility to modify text element
            Shape.prototype._initializeTextContainer = function (opts, container, element) {
                // By default, no-op
                // Custom shapes should respect API options, such as text.style
            };

            Shape.prototype._pathString = function _pathString(opts) {
                throw new Error('Override this function for each progress bar');
            };

            Shape.prototype._trailString = function _trailString(opts) {
                throw new Error('Override this function for each progress bar');
            };

            Shape.prototype._warnContainerAspectRatio = function _warnContainerAspectRatio(container) {
                if (!this.containerAspectRatio) {
                    return;
                }

                var computedStyle = window.getComputedStyle(container, null);
                var width = parseFloat(computedStyle.getPropertyValue('width'), 10);
                var height = parseFloat(computedStyle.getPropertyValue('height'), 10);
                if (!utils.floatEquals(this.containerAspectRatio, width / height)) {
                    console.warn(
                        'Incorrect aspect ratio of container',
                        '#' + container.id,
                        'detected:',
                        computedStyle.getPropertyValue('width') + '(width)',
                        '/',
                        computedStyle.getPropertyValue('height') + '(height)',
                        '=',
                        width / height
                    );

                    console.warn(
                        'Aspect ratio of should be',
                        this.containerAspectRatio
                    );
                }
            };

            module.exports = Shape;

        }, { "./path": 5, "./utils": 9 }], 8: [function (require, module, exports) {
            // Square shaped progress bar
            // Note: Square is not core part of API anymore. It's left here
            //       for reference. square is not included to the progressbar
            //       build anymore

            var Shape = require('./shape');
            var utils = require('./utils');

            var Square = function Square(container, options) {
                this._pathTemplate =
                    'M 0,{halfOfStrokeWidth}' +
                    ' L {width},{halfOfStrokeWidth}' +
                    ' L {width},{width}' +
                    ' L {halfOfStrokeWidth},{width}' +
                    ' L {halfOfStrokeWidth},{strokeWidth}';

                this._trailTemplate =
                    'M {startMargin},{halfOfStrokeWidth}' +
                    ' L {width},{halfOfStrokeWidth}' +
                    ' L {width},{width}' +
                    ' L {halfOfStrokeWidth},{width}' +
                    ' L {halfOfStrokeWidth},{halfOfStrokeWidth}';

                Shape.apply(this, arguments);
            };

            Square.prototype = new Shape();
            Square.prototype.constructor = Square;

            Square.prototype._pathString = function _pathString(opts) {
                var w = 100 - opts.strokeWidth / 2;

                return utils.render(this._pathTemplate, {
                    width: w,
                    strokeWidth: opts.strokeWidth,
                    halfOfStrokeWidth: opts.strokeWidth / 2
                });
            };

            Square.prototype._trailString = function _trailString(opts) {
                var w = 100 - opts.strokeWidth / 2;

                return utils.render(this._trailTemplate, {
                    width: w,
                    strokeWidth: opts.strokeWidth,
                    halfOfStrokeWidth: opts.strokeWidth / 2,
                    startMargin: opts.strokeWidth / 2 - opts.trailWidth / 2
                });
            };

            module.exports = Square;

        }, { "./shape": 7, "./utils": 9 }], 9: [function (require, module, exports) {
            // Utility functions

            var PREFIXES = 'Webkit Moz O ms'.split(' ');
            var FLOAT_COMPARISON_EPSILON = 0.001;

            // Copy all attributes from source object to destination object.
            // destination object is mutated.
            function extend(destination, source, recursive) {
                destination = destination || {};
                source = source || {};
                recursive = recursive || false;

                for (var attrName in source) {
                    if (source.hasOwnProperty(attrName)) {
                        var destVal = destination[attrName];
                        var sourceVal = source[attrName];
                        if (recursive && isObject(destVal) && isObject(sourceVal)) {
                            destination[attrName] = extend(destVal, sourceVal, recursive);
                        } else {
                            destination[attrName] = sourceVal;
                        }
                    }
                }

                return destination;
            }

            // Renders templates with given variables. Variables must be surrounded with
            // braces without any spaces, e.g. {variable}
            // All instances of variable placeholders will be replaced with given content
            // Example:
            // render('Hello, {message}!', {message: 'world'})
            function render(template, vars) {
                var rendered = template;

                for (var key in vars) {
                    if (vars.hasOwnProperty(key)) {
                        var val = vars[key];
                        var regExpString = '\\{' + key + '\\}';
                        var regExp = new RegExp(regExpString, 'g');

                        rendered = rendered.replace(regExp, val);
                    }
                }

                return rendered;
            }

            function setStyle(element, style, value) {
                var elStyle = element.style;  // cache for performance

                for (var i = 0; i < PREFIXES.length; ++i) {
                    var prefix = PREFIXES[i];
                    elStyle[prefix + capitalize(style)] = value;
                }

                elStyle[style] = value;
            }

            function setStyles(element, styles) {
                forEachObject(styles, function (styleValue, styleName) {
                    // Allow disabling some individual styles by setting them
                    // to null or undefined
                    if (styleValue === null || styleValue === undefined) {
                        return;
                    }

                    // If style's value is {prefix: true, value: '50%'},
                    // Set also browser prefixed styles
                    if (isObject(styleValue) && styleValue.prefix === true) {
                        setStyle(element, styleName, styleValue.value);
                    } else {
                        element.style[styleName] = styleValue;
                    }
                });
            }

            function capitalize(text) {
                return text.charAt(0).toUpperCase() + text.slice(1);
            }

            function isString(obj) {
                return typeof obj === 'string' || obj instanceof String;
            }

            function isFunction(obj) {
                return typeof obj === 'function';
            }

            function isArray(obj) {
                return Object.prototype.toString.call(obj) === '[object Array]';
            }

            // Returns true if `obj` is object as in {a: 1, b: 2}, not if it's function or
            // array
            function isObject(obj) {
                if (isArray(obj)) {
                    return false;
                }

                var type = typeof obj;
                return type === 'object' && !!obj;
            }

            function forEachObject(object, callback) {
                for (var key in object) {
                    if (object.hasOwnProperty(key)) {
                        var val = object[key];
                        callback(val, key);
                    }
                }
            }

            function floatEquals(a, b) {
                return Math.abs(a - b) < FLOAT_COMPARISON_EPSILON;
            }

            // https://coderwall.com/p/nygghw/don-t-use-innerhtml-to-empty-dom-elements
            function removeChildren(el) {
                while (el.firstChild) {
                    el.removeChild(el.firstChild);
                }
            }

            module.exports = {
                extend: extend,
                render: render,
                setStyle: setStyle,
                setStyles: setStyles,
                capitalize: capitalize,
                isString: isString,
                isFunction: isFunction,
                isObject: isObject,
                forEachObject: forEachObject,
                floatEquals: floatEquals,
                removeChildren: removeChildren
            };

        }, {}]
    }, {}, [4])(4)
});

/*! Select2 4.0.6-rc.1 | https://github.com/select2/select2/blob/master/LICENSE.md */!function (a) { "function" == typeof define && define.amd ? define(["jquery"], a) : "object" == typeof module && module.exports ? module.exports = function (b, c) { return void 0 === c && (c = "undefined" != typeof window ? require("jquery") : require("jquery")(b)), a(c), c } : a(jQuery) }(function (a) { var b = function () { if (a && a.fn && a.fn.select2 && a.fn.select2.amd) var b = a.fn.select2.amd; var b; return function () { if (!b || !b.requirejs) { b ? c = b : b = {}; var a, c, d; !function (b) { function e(a, b) { return v.call(a, b) } function f(a, b) { var c, d, e, f, g, h, i, j, k, l, m, n, o = b && b.split("/"), p = t.map, q = p && p["*"] || {}; if (a) { for (a = a.split("/"), g = a.length - 1, t.nodeIdCompat && x.test(a[g]) && (a[g] = a[g].replace(x, "")), "." === a[0].charAt(0) && o && (n = o.slice(0, o.length - 1), a = n.concat(a)), k = 0; k < a.length; k++)if ("." === (m = a[k])) a.splice(k, 1), k -= 1; else if (".." === m) { if (0 === k || 1 === k && ".." === a[2] || ".." === a[k - 1]) continue; k > 0 && (a.splice(k - 1, 2), k -= 2) } a = a.join("/") } if ((o || q) && p) { for (c = a.split("/"), k = c.length; k > 0; k -= 1) { if (d = c.slice(0, k).join("/"), o) for (l = o.length; l > 0; l -= 1)if ((e = p[o.slice(0, l).join("/")]) && (e = e[d])) { f = e, h = k; break } if (f) break; !i && q && q[d] && (i = q[d], j = k) } !f && i && (f = i, h = j), f && (c.splice(0, h, f), a = c.join("/")) } return a } function g(a, c) { return function () { var d = w.call(arguments, 0); return "string" != typeof d[0] && 1 === d.length && d.push(null), o.apply(b, d.concat([a, c])) } } function h(a) { return function (b) { return f(b, a) } } function i(a) { return function (b) { r[a] = b } } function j(a) { if (e(s, a)) { var c = s[a]; delete s[a], u[a] = !0, n.apply(b, c) } if (!e(r, a) && !e(u, a)) throw new Error("No " + a); return r[a] } function k(a) { var b, c = a ? a.indexOf("!") : -1; return c > -1 && (b = a.substring(0, c), a = a.substring(c + 1, a.length)), [b, a] } function l(a) { return a ? k(a) : [] } function m(a) { return function () { return t && t.config && t.config[a] || {} } } var n, o, p, q, r = {}, s = {}, t = {}, u = {}, v = Object.prototype.hasOwnProperty, w = [].slice, x = /\.js$/; p = function (a, b) { var c, d = k(a), e = d[0], g = b[1]; return a = d[1], e && (e = f(e, g), c = j(e)), e ? a = c && c.normalize ? c.normalize(a, h(g)) : f(a, g) : (a = f(a, g), d = k(a), e = d[0], a = d[1], e && (c = j(e))), { f: e ? e + "!" + a : a, n: a, pr: e, p: c } }, q = { require: function (a) { return g(a) }, exports: function (a) { var b = r[a]; return void 0 !== b ? b : r[a] = {} }, module: function (a) { return { id: a, uri: "", exports: r[a], config: m(a) } } }, n = function (a, c, d, f) { var h, k, m, n, o, t, v, w = [], x = typeof d; if (f = f || a, t = l(f), "undefined" === x || "function" === x) { for (c = !c.length && d.length ? ["require", "exports", "module"] : c, o = 0; o < c.length; o += 1)if (n = p(c[o], t), "require" === (k = n.f)) w[o] = q.require(a); else if ("exports" === k) w[o] = q.exports(a), v = !0; else if ("module" === k) h = w[o] = q.module(a); else if (e(r, k) || e(s, k) || e(u, k)) w[o] = j(k); else { if (!n.p) throw new Error(a + " missing " + k); n.p.load(n.n, g(f, !0), i(k), {}), w[o] = r[k] } m = d ? d.apply(r[a], w) : void 0, a && (h && h.exports !== b && h.exports !== r[a] ? r[a] = h.exports : m === b && v || (r[a] = m)) } else a && (r[a] = d) }, a = c = o = function (a, c, d, e, f) { if ("string" == typeof a) return q[a] ? q[a](c) : j(p(a, l(c)).f); if (!a.splice) { if (t = a, t.deps && o(t.deps, t.callback), !c) return; c.splice ? (a = c, c = d, d = null) : a = b } return c = c || function () { }, "function" == typeof d && (d = e, e = f), e ? n(b, a, c, d) : setTimeout(function () { n(b, a, c, d) }, 4), o }, o.config = function (a) { return o(a) }, a._defined = r, d = function (a, b, c) { if ("string" != typeof a) throw new Error("See almond README: incorrect module build, no module name"); b.splice || (c = b, b = []), e(r, a) || e(s, a) || (s[a] = [a, b, c]) }, d.amd = { jQuery: !0 } }(), b.requirejs = a, b.require = c, b.define = d } }(), b.define("almond", function () { }), b.define("jquery", [], function () { var b = a || $; return null == b && console && console.error && console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."), b }), b.define("select2/utils", ["jquery"], function (a) { function b(a) { var b = a.prototype, c = []; for (var d in b) { "function" == typeof b[d] && ("constructor" !== d && c.push(d)) } return c } var c = {}; c.Extend = function (a, b) { function c() { this.constructor = a } var d = {}.hasOwnProperty; for (var e in b) d.call(b, e) && (a[e] = b[e]); return c.prototype = b.prototype, a.prototype = new c, a.__super__ = b.prototype, a }, c.Decorate = function (a, c) { function d() { var b = Array.prototype.unshift, d = c.prototype.constructor.length, e = a.prototype.constructor; d > 0 && (b.call(arguments, a.prototype.constructor), e = c.prototype.constructor), e.apply(this, arguments) } function e() { this.constructor = d } var f = b(c), g = b(a); c.displayName = a.displayName, d.prototype = new e; for (var h = 0; h < g.length; h++) { var i = g[h]; d.prototype[i] = a.prototype[i] } for (var j = (function (a) { var b = function () { }; a in d.prototype && (b = d.prototype[a]); var e = c.prototype[a]; return function () { return Array.prototype.unshift.call(arguments, b), e.apply(this, arguments) } }), k = 0; k < f.length; k++) { var l = f[k]; d.prototype[l] = j(l) } return d }; var d = function () { this.listeners = {} }; d.prototype.on = function (a, b) { this.listeners = this.listeners || {}, a in this.listeners ? this.listeners[a].push(b) : this.listeners[a] = [b] }, d.prototype.trigger = function (a) { var b = Array.prototype.slice, c = b.call(arguments, 1); this.listeners = this.listeners || {}, null == c && (c = []), 0 === c.length && c.push({}), c[0]._type = a, a in this.listeners && this.invoke(this.listeners[a], b.call(arguments, 1)), "*" in this.listeners && this.invoke(this.listeners["*"], arguments) }, d.prototype.invoke = function (a, b) { for (var c = 0, d = a.length; c < d; c++)a[c].apply(this, b) }, c.Observable = d, c.generateChars = function (a) { for (var b = "", c = 0; c < a; c++) { b += Math.floor(36 * Math.random()).toString(36) } return b }, c.bind = function (a, b) { return function () { a.apply(b, arguments) } }, c._convertData = function (a) { for (var b in a) { var c = b.split("-"), d = a; if (1 !== c.length) { for (var e = 0; e < c.length; e++) { var f = c[e]; f = f.substring(0, 1).toLowerCase() + f.substring(1), f in d || (d[f] = {}), e == c.length - 1 && (d[f] = a[b]), d = d[f] } delete a[b] } } return a }, c.hasScroll = function (b, c) { var d = a(c), e = c.style.overflowX, f = c.style.overflowY; return (e !== f || "hidden" !== f && "visible" !== f) && ("scroll" === e || "scroll" === f || (d.innerHeight() < c.scrollHeight || d.innerWidth() < c.scrollWidth)) }, c.escapeMarkup = function (a) { var b = { "\\": "&#92;", "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;", "/": "&#47;" }; return "string" != typeof a ? a : String(a).replace(/[&<>"'\/\\]/g, function (a) { return b[a] }) }, c.appendMany = function (b, c) { if ("1.7" === a.fn.jquery.substr(0, 3)) { var d = a(); a.map(c, function (a) { d = d.add(a) }), c = d } b.append(c) }, c.__cache = {}; var e = 0; return c.GetUniqueElementId = function (a) { var b = a.getAttribute("data-select2-id"); return null == b && (a.id ? (b = a.id, a.setAttribute("data-select2-id", b)) : (a.setAttribute("data-select2-id", ++e), b = e.toString())), b }, c.StoreData = function (a, b, d) { var e = c.GetUniqueElementId(a); c.__cache[e] || (c.__cache[e] = {}), c.__cache[e][b] = d }, c.GetData = function (b, d) { var e = c.GetUniqueElementId(b); return d ? c.__cache[e] && null != c.__cache[e][d] ? c.__cache[e][d] : a(b).data(d) : c.__cache[e] }, c.RemoveData = function (a) { var b = c.GetUniqueElementId(a); null != c.__cache[b] && delete c.__cache[b] }, c }), b.define("select2/results", ["jquery", "./utils"], function (a, b) { function c(a, b, d) { this.$element = a, this.data = d, this.options = b, c.__super__.constructor.call(this) } return b.Extend(c, b.Observable), c.prototype.render = function () { var b = a('<ul class="select2-results__options" role="tree"></ul>'); return this.options.get("multiple") && b.attr("aria-multiselectable", "true"), this.$results = b, b }, c.prototype.clear = function () { this.$results.empty() }, c.prototype.displayMessage = function (b) { var c = this.options.get("escapeMarkup"); this.clear(), this.hideLoading(); var d = a('<li role="treeitem" aria-live="assertive" class="select2-results__option"></li>'), e = this.options.get("translations").get(b.message); d.append(c(e(b.args))), d[0].className += " select2-results__message", this.$results.append(d) }, c.prototype.hideMessages = function () { this.$results.find(".select2-results__message").remove() }, c.prototype.append = function (a) { this.hideLoading(); var b = []; if (null == a.results || 0 === a.results.length) return void (0 === this.$results.children().length && this.trigger("results:message", { message: "noResults" })); a.results = this.sort(a.results); for (var c = 0; c < a.results.length; c++) { var d = a.results[c], e = this.option(d); b.push(e) } this.$results.append(b) }, c.prototype.position = function (a, b) { b.find(".select2-results").append(a) }, c.prototype.sort = function (a) { return this.options.get("sorter")(a) }, c.prototype.highlightFirstItem = function () { var a = this.$results.find(".select2-results__option[aria-selected]"), b = a.filter("[aria-selected=true]"); b.length > 0 ? b.first().trigger("mouseenter") : a.first().trigger("mouseenter"), this.ensureHighlightVisible() }, c.prototype.setClasses = function () { var c = this; this.data.current(function (d) { var e = a.map(d, function (a) { return a.id.toString() }); c.$results.find(".select2-results__option[aria-selected]").each(function () { var c = a(this), d = b.GetData(this, "data"), f = "" + d.id; null != d.element && d.element.selected || null == d.element && a.inArray(f, e) > -1 ? c.attr("aria-selected", "true") : c.attr("aria-selected", "false") }) }) }, c.prototype.showLoading = function (a) { this.hideLoading(); var b = this.options.get("translations").get("searching"), c = { disabled: !0, loading: !0, text: b(a) }, d = this.option(c); d.className += " loading-results", this.$results.prepend(d) }, c.prototype.hideLoading = function () { this.$results.find(".loading-results").remove() }, c.prototype.option = function (c) { var d = document.createElement("li"); d.className = "select2-results__option"; var e = { role: "treeitem", "aria-selected": "false" }; c.disabled && (delete e["aria-selected"], e["aria-disabled"] = "true"), null == c.id && delete e["aria-selected"], null != c._resultId && (d.id = c._resultId), c.title && (d.title = c.title), c.children && (e.role = "group", e["aria-label"] = c.text, delete e["aria-selected"]); for (var f in e) { var g = e[f]; d.setAttribute(f, g) } if (c.children) { var h = a(d), i = document.createElement("strong"); i.className = "select2-results__group"; a(i); this.template(c, i); for (var j = [], k = 0; k < c.children.length; k++) { var l = c.children[k], m = this.option(l); j.push(m) } var n = a("<ul></ul>", { class: "select2-results__options select2-results__options--nested" }); n.append(j), h.append(i), h.append(n) } else this.template(c, d); return b.StoreData(d, "data", c), d }, c.prototype.bind = function (c, d) { var e = this, f = c.id + "-results"; this.$results.attr("id", f), c.on("results:all", function (a) { e.clear(), e.append(a.data), c.isOpen() && (e.setClasses(), e.highlightFirstItem()) }), c.on("results:append", function (a) { e.append(a.data), c.isOpen() && e.setClasses() }), c.on("query", function (a) { e.hideMessages(), e.showLoading(a) }), c.on("select", function () { c.isOpen() && (e.setClasses(), e.highlightFirstItem()) }), c.on("unselect", function () { c.isOpen() && (e.setClasses(), e.highlightFirstItem()) }), c.on("open", function () { e.$results.attr("aria-expanded", "true"), e.$results.attr("aria-hidden", "false"), e.setClasses(), e.ensureHighlightVisible() }), c.on("close", function () { e.$results.attr("aria-expanded", "false"), e.$results.attr("aria-hidden", "true"), e.$results.removeAttr("aria-activedescendant") }), c.on("results:toggle", function () { var a = e.getHighlightedResults(); 0 !== a.length && a.trigger("mouseup") }), c.on("results:select", function () { var a = e.getHighlightedResults(); if (0 !== a.length) { var c = b.GetData(a[0], "data"); "true" == a.attr("aria-selected") ? e.trigger("close", {}) : e.trigger("select", { data: c }) } }), c.on("results:previous", function () { var a = e.getHighlightedResults(), b = e.$results.find("[aria-selected]"), c = b.index(a); if (!(c <= 0)) { var d = c - 1; 0 === a.length && (d = 0); var f = b.eq(d); f.trigger("mouseenter"); var g = e.$results.offset().top, h = f.offset().top, i = e.$results.scrollTop() + (h - g); 0 === d ? e.$results.scrollTop(0) : h - g < 0 && e.$results.scrollTop(i) } }), c.on("results:next", function () { var a = e.getHighlightedResults(), b = e.$results.find("[aria-selected]"), c = b.index(a), d = c + 1; if (!(d >= b.length)) { var f = b.eq(d); f.trigger("mouseenter"); var g = e.$results.offset().top + e.$results.outerHeight(!1), h = f.offset().top + f.outerHeight(!1), i = e.$results.scrollTop() + h - g; 0 === d ? e.$results.scrollTop(0) : h > g && e.$results.scrollTop(i) } }), c.on("results:focus", function (a) { a.element.addClass("select2-results__option--highlighted") }), c.on("results:message", function (a) { e.displayMessage(a) }), a.fn.mousewheel && this.$results.on("mousewheel", function (a) { var b = e.$results.scrollTop(), c = e.$results.get(0).scrollHeight - b + a.deltaY, d = a.deltaY > 0 && b - a.deltaY <= 0, f = a.deltaY < 0 && c <= e.$results.height(); d ? (e.$results.scrollTop(0), a.preventDefault(), a.stopPropagation()) : f && (e.$results.scrollTop(e.$results.get(0).scrollHeight - e.$results.height()), a.preventDefault(), a.stopPropagation()) }), this.$results.on("mouseup", ".select2-results__option[aria-selected]", function (c) { var d = a(this), f = b.GetData(this, "data"); if ("true" === d.attr("aria-selected")) return void (e.options.get("multiple") ? e.trigger("unselect", { originalEvent: c, data: f }) : e.trigger("close", {})); e.trigger("select", { originalEvent: c, data: f }) }), this.$results.on("mouseenter", ".select2-results__option[aria-selected]", function (c) { var d = b.GetData(this, "data"); e.getHighlightedResults().removeClass("select2-results__option--highlighted"), e.trigger("results:focus", { data: d, element: a(this) }) }) }, c.prototype.getHighlightedResults = function () { return this.$results.find(".select2-results__option--highlighted") }, c.prototype.destroy = function () { this.$results.remove() }, c.prototype.ensureHighlightVisible = function () { var a = this.getHighlightedResults(); if (0 !== a.length) { var b = this.$results.find("[aria-selected]"), c = b.index(a), d = this.$results.offset().top, e = a.offset().top, f = this.$results.scrollTop() + (e - d), g = e - d; f -= 2 * a.outerHeight(!1), c <= 2 ? this.$results.scrollTop(0) : (g > this.$results.outerHeight() || g < 0) && this.$results.scrollTop(f) } }, c.prototype.template = function (b, c) { var d = this.options.get("templateResult"), e = this.options.get("escapeMarkup"), f = d(b, c); null == f ? c.style.display = "none" : "string" == typeof f ? c.innerHTML = e(f) : a(c).append(f) }, c }), b.define("select2/keys", [], function () { return { BACKSPACE: 8, TAB: 9, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, ESC: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, DELETE: 46 } }), b.define("select2/selection/base", ["jquery", "../utils", "../keys"], function (a, b, c) { function d(a, b) { this.$element = a, this.options = b, d.__super__.constructor.call(this) } return b.Extend(d, b.Observable), d.prototype.render = function () { var c = a('<span class="select2-selection" role="combobox"  aria-haspopup="true" aria-expanded="false"></span>'); return this._tabindex = 0, null != b.GetData(this.$element[0], "old-tabindex") ? this._tabindex = b.GetData(this.$element[0], "old-tabindex") : null != this.$element.attr("tabindex") && (this._tabindex = this.$element.attr("tabindex")), c.attr("title", this.$element.attr("title")), c.attr("tabindex", this._tabindex), this.$selection = c, c }, d.prototype.bind = function (a, b) { var d = this, e = (a.id, a.id + "-results"); this.container = a, this.$selection.on("focus", function (a) { d.trigger("focus", a) }), this.$selection.on("blur", function (a) { d._handleBlur(a) }), this.$selection.on("keydown", function (a) { d.trigger("keypress", a), a.which === c.SPACE && a.preventDefault() }), a.on("results:focus", function (a) { d.$selection.attr("aria-activedescendant", a.data._resultId) }), a.on("selection:update", function (a) { d.update(a.data) }), a.on("open", function () { d.$selection.attr("aria-expanded", "true"), d.$selection.attr("aria-owns", e), d._attachCloseHandler(a) }), a.on("close", function () { d.$selection.attr("aria-expanded", "false"), d.$selection.removeAttr("aria-activedescendant"), d.$selection.removeAttr("aria-owns"), d.$selection.focus(), window.setTimeout(function () { d.$selection.focus() }, 0), d._detachCloseHandler(a) }), a.on("enable", function () { d.$selection.attr("tabindex", d._tabindex) }), a.on("disable", function () { d.$selection.attr("tabindex", "-1") }) }, d.prototype._handleBlur = function (b) { var c = this; window.setTimeout(function () { document.activeElement == c.$selection[0] || a.contains(c.$selection[0], document.activeElement) || c.trigger("blur", b) }, 1) }, d.prototype._attachCloseHandler = function (c) { a(document.body).on("mousedown.select2." + c.id, function (c) { var d = a(c.target), e = d.closest(".select2"); a(".select2.select2-container--open").each(function () { a(this), this != e[0] && b.GetData(this, "element").select2("close") }) }) }, d.prototype._detachCloseHandler = function (b) { a(document.body).off("mousedown.select2." + b.id) }, d.prototype.position = function (a, b) { b.find(".selection").append(a) }, d.prototype.destroy = function () { this._detachCloseHandler(this.container) }, d.prototype.update = function (a) { throw new Error("The `update` method must be defined in child classes.") }, d }), b.define("select2/selection/single", ["jquery", "./base", "../utils", "../keys"], function (a, b, c, d) { function e() { e.__super__.constructor.apply(this, arguments) } return c.Extend(e, b), e.prototype.render = function () { var a = e.__super__.render.call(this); return a.addClass("select2-selection--single"), a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'), a }, e.prototype.bind = function (a, b) { var c = this; e.__super__.bind.apply(this, arguments); var d = a.id + "-container"; this.$selection.find(".select2-selection__rendered").attr("id", d).attr("role", "textbox").attr("aria-readonly", "true"), this.$selection.attr("aria-labelledby", d), this.$selection.on("mousedown", function (a) { 1 === a.which && c.trigger("toggle", { originalEvent: a }) }), this.$selection.on("focus", function (a) { }), this.$selection.on("blur", function (a) { }), a.on("focus", function (b) { a.isOpen() || c.$selection.focus() }) }, e.prototype.clear = function () { var a = this.$selection.find(".select2-selection__rendered"); a.empty(), a.removeAttr("title") }, e.prototype.display = function (a, b) { var c = this.options.get("templateSelection"); return this.options.get("escapeMarkup")(c(a, b)) }, e.prototype.selectionContainer = function () { return a("<span></span>") }, e.prototype.update = function (a) { if (0 === a.length) return void this.clear(); var b = a[0], c = this.$selection.find(".select2-selection__rendered"), d = this.display(b, c); c.empty().append(d), c.attr("title", b.title || b.text) }, e }), b.define("select2/selection/multiple", ["jquery", "./base", "../utils"], function (a, b, c) { function d(a, b) { d.__super__.constructor.apply(this, arguments) } return c.Extend(d, b), d.prototype.render = function () { var a = d.__super__.render.call(this); return a.addClass("select2-selection--multiple"), a.html('<ul class="select2-selection__rendered"></ul>'), a }, d.prototype.bind = function (b, e) { var f = this; d.__super__.bind.apply(this, arguments), this.$selection.on("click", function (a) { f.trigger("toggle", { originalEvent: a }) }), this.$selection.on("click", ".select2-selection__choice__remove", function (b) { if (!f.options.get("disabled")) { var d = a(this), e = d.parent(), g = c.GetData(e[0], "data"); f.trigger("unselect", { originalEvent: b, data: g }) } }) }, d.prototype.clear = function () { var a = this.$selection.find(".select2-selection__rendered"); a.empty(), a.removeAttr("title") }, d.prototype.display = function (a, b) { var c = this.options.get("templateSelection"); return this.options.get("escapeMarkup")(c(a, b)) }, d.prototype.selectionContainer = function () { return a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>') }, d.prototype.update = function (a) { if (this.clear(), 0 !== a.length) { for (var b = [], d = 0; d < a.length; d++) { var e = a[d], f = this.selectionContainer(), g = this.display(e, f); f.append(g), f.attr("title", e.title || e.text), c.StoreData(f[0], "data", e), b.push(f) } var h = this.$selection.find(".select2-selection__rendered"); c.appendMany(h, b) } }, d }), b.define("select2/selection/placeholder", ["../utils"], function (a) { function b(a, b, c) { this.placeholder = this.normalizePlaceholder(c.get("placeholder")), a.call(this, b, c) } return b.prototype.normalizePlaceholder = function (a, b) { return "string" == typeof b && (b = { id: "", text: b }), b }, b.prototype.createPlaceholder = function (a, b) { var c = this.selectionContainer(); return c.html(this.display(b)), c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"), c }, b.prototype.update = function (a, b) { var c = 1 == b.length && b[0].id != this.placeholder.id; if (b.length > 1 || c) return a.call(this, b); this.clear(); var d = this.createPlaceholder(this.placeholder); this.$selection.find(".select2-selection__rendered").append(d) }, b }), b.define("select2/selection/allowClear", ["jquery", "../keys", "../utils"], function (a, b, c) { function d() { } return d.prototype.bind = function (a, b, c) { var d = this; a.call(this, b, c), null == this.placeholder && this.options.get("debug") && window.console && console.error && console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."), this.$selection.on("mousedown", ".select2-selection__clear", function (a) { d._handleClear(a) }), b.on("keypress", function (a) { d._handleKeyboardClear(a, b) }) }, d.prototype._handleClear = function (a, b) { if (!this.options.get("disabled")) { var d = this.$selection.find(".select2-selection__clear"); if (0 !== d.length) { b.stopPropagation(); var e = c.GetData(d[0], "data"), f = this.$element.val(); this.$element.val(this.placeholder.id); var g = { data: e }; if (this.trigger("clear", g), g.prevented) return void this.$element.val(f); for (var h = 0; h < e.length; h++)if (g = { data: e[h] }, this.trigger("unselect", g), g.prevented) return void this.$element.val(f); this.$element.trigger("change"), this.trigger("toggle", {}) } } }, d.prototype._handleKeyboardClear = function (a, c, d) { d.isOpen() || c.which != b.DELETE && c.which != b.BACKSPACE || this._handleClear(c) }, d.prototype.update = function (b, d) { if (b.call(this, d), !(this.$selection.find(".select2-selection__placeholder").length > 0 || 0 === d.length)) { var e = a('<span class="select2-selection__clear">&times;</span>'); c.StoreData(e[0], "data", d), this.$selection.find(".select2-selection__rendered").prepend(e) } }, d }), b.define("select2/selection/search", ["jquery", "../utils", "../keys"], function (a, b, c) { function d(a, b, c) { a.call(this, b, c) } return d.prototype.render = function (b) { var c = a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="textbox" aria-autocomplete="list" /></li>'); this.$searchContainer = c, this.$search = c.find("input"); var d = b.call(this); return this._transferTabIndex(), d }, d.prototype.bind = function (a, d, e) { var f = this; a.call(this, d, e), d.on("open", function () { f.$search.trigger("focus") }), d.on("close", function () { f.$search.val(""), f.$search.removeAttr("aria-activedescendant"), f.$search.trigger("focus") }), d.on("enable", function () { f.$search.prop("disabled", !1), f._transferTabIndex() }), d.on("disable", function () { f.$search.prop("disabled", !0) }), d.on("focus", function (a) { f.$search.trigger("focus") }), d.on("results:focus", function (a) { f.$search.attr("aria-activedescendant", a.id) }), this.$selection.on("focusin", ".select2-search--inline", function (a) { f.trigger("focus", a) }), this.$selection.on("focusout", ".select2-search--inline", function (a) { f._handleBlur(a) }), this.$selection.on("keydown", ".select2-search--inline", function (a) { if (a.stopPropagation(), f.trigger("keypress", a), f._keyUpPrevented = a.isDefaultPrevented(), a.which === c.BACKSPACE && "" === f.$search.val()) { var d = f.$searchContainer.prev(".select2-selection__choice"); if (d.length > 0) { var e = b.GetData(d[0], "data"); f.searchRemoveChoice(e), a.preventDefault() } } }); var g = document.documentMode, h = g && g <= 11; this.$selection.on("input.searchcheck", ".select2-search--inline", function (a) { if (h) return void f.$selection.off("input.search input.searchcheck"); f.$selection.off("keyup.search") }), this.$selection.on("keyup.search input.search", ".select2-search--inline", function (a) { if (h && "input" === a.type) return void f.$selection.off("input.search input.searchcheck"); var b = a.which; b != c.SHIFT && b != c.CTRL && b != c.ALT && b != c.TAB && f.handleSearch(a) }) }, d.prototype._transferTabIndex = function (a) { this.$search.attr("tabindex", this.$selection.attr("tabindex")), this.$selection.attr("tabindex", "-1") }, d.prototype.createPlaceholder = function (a, b) { this.$search.attr("placeholder", b.text) }, d.prototype.update = function (a, b) { var c = this.$search[0] == document.activeElement; if (this.$search.attr("placeholder", ""), a.call(this, b), this.$selection.find(".select2-selection__rendered").append(this.$searchContainer), this.resizeSearch(), c) { this.$element.find("[data-select2-tag]").length ? this.$element.focus() : this.$search.focus() } }, d.prototype.handleSearch = function () { if (this.resizeSearch(), !this._keyUpPrevented) { var a = this.$search.val(); this.trigger("query", { term: a }) } this._keyUpPrevented = !1 }, d.prototype.searchRemoveChoice = function (a, b) { this.trigger("unselect", { data: b }), this.$search.val(b.text), this.handleSearch() }, d.prototype.resizeSearch = function () { this.$search.css("width", "25px"); var a = ""; if ("" !== this.$search.attr("placeholder")) a = this.$selection.find(".select2-selection__rendered").innerWidth(); else { a = .75 * (this.$search.val().length + 1) + "em" } this.$search.css("width", a) }, d }), b.define("select2/selection/eventRelay", ["jquery"], function (a) { function b() { } return b.prototype.bind = function (b, c, d) { var e = this, f = ["open", "opening", "close", "closing", "select", "selecting", "unselect", "unselecting", "clear", "clearing"], g = ["opening", "closing", "selecting", "unselecting", "clearing"]; b.call(this, c, d), c.on("*", function (b, c) { if (-1 !== a.inArray(b, f)) { c = c || {}; var d = a.Event("select2:" + b, { params: c }); e.$element.trigger(d), -1 !== a.inArray(b, g) && (c.prevented = d.isDefaultPrevented()) } }) }, b }), b.define("select2/translation", ["jquery", "require"], function (a, b) { function c(a) { this.dict = a || {} } return c.prototype.all = function () { return this.dict }, c.prototype.get = function (a) { return this.dict[a] }, c.prototype.extend = function (b) { this.dict = a.extend({}, b.all(), this.dict) }, c._cache = {}, c.loadPath = function (a) { if (!(a in c._cache)) { var d = b(a); c._cache[a] = d } return new c(c._cache[a]) }, c }), b.define("select2/diacritics", [], function () { return { "Ⓐ": "A", "Ａ": "A", "À": "A", "Á": "A", "Â": "A", "Ầ": "A", "Ấ": "A", "Ẫ": "A", "Ẩ": "A", "Ã": "A", "Ā": "A", "Ă": "A", "Ằ": "A", "Ắ": "A", "Ẵ": "A", "Ẳ": "A", "Ȧ": "A", "Ǡ": "A", "Ä": "A", "Ǟ": "A", "Ả": "A", "Å": "A", "Ǻ": "A", "Ǎ": "A", "Ȁ": "A", "Ȃ": "A", "Ạ": "A", "Ậ": "A", "Ặ": "A", "Ḁ": "A", "Ą": "A", "Ⱥ": "A", "Ɐ": "A", "Ꜳ": "AA", "Æ": "AE", "Ǽ": "AE", "Ǣ": "AE", "Ꜵ": "AO", "Ꜷ": "AU", "Ꜹ": "AV", "Ꜻ": "AV", "Ꜽ": "AY", "Ⓑ": "B", "Ｂ": "B", "Ḃ": "B", "Ḅ": "B", "Ḇ": "B", "Ƀ": "B", "Ƃ": "B", "Ɓ": "B", "Ⓒ": "C", "Ｃ": "C", "Ć": "C", "Ĉ": "C", "Ċ": "C", "Č": "C", "Ç": "C", "Ḉ": "C", "Ƈ": "C", "Ȼ": "C", "Ꜿ": "C", "Ⓓ": "D", "Ｄ": "D", "Ḋ": "D", "Ď": "D", "Ḍ": "D", "Ḑ": "D", "Ḓ": "D", "Ḏ": "D", "Đ": "D", "Ƌ": "D", "Ɗ": "D", "Ɖ": "D", "Ꝺ": "D", "Ǳ": "DZ", "Ǆ": "DZ", "ǲ": "Dz", "ǅ": "Dz", "Ⓔ": "E", "Ｅ": "E", "È": "E", "É": "E", "Ê": "E", "Ề": "E", "Ế": "E", "Ễ": "E", "Ể": "E", "Ẽ": "E", "Ē": "E", "Ḕ": "E", "Ḗ": "E", "Ĕ": "E", "Ė": "E", "Ë": "E", "Ẻ": "E", "Ě": "E", "Ȅ": "E", "Ȇ": "E", "Ẹ": "E", "Ệ": "E", "Ȩ": "E", "Ḝ": "E", "Ę": "E", "Ḙ": "E", "Ḛ": "E", "Ɛ": "E", "Ǝ": "E", "Ⓕ": "F", "Ｆ": "F", "Ḟ": "F", "Ƒ": "F", "Ꝼ": "F", "Ⓖ": "G", "Ｇ": "G", "Ǵ": "G", "Ĝ": "G", "Ḡ": "G", "Ğ": "G", "Ġ": "G", "Ǧ": "G", "Ģ": "G", "Ǥ": "G", "Ɠ": "G", "Ꞡ": "G", "Ᵹ": "G", "Ꝿ": "G", "Ⓗ": "H", "Ｈ": "H", "Ĥ": "H", "Ḣ": "H", "Ḧ": "H", "Ȟ": "H", "Ḥ": "H", "Ḩ": "H", "Ḫ": "H", "Ħ": "H", "Ⱨ": "H", "Ⱶ": "H", "Ɥ": "H", "Ⓘ": "I", "Ｉ": "I", "Ì": "I", "Í": "I", "Î": "I", "Ĩ": "I", "Ī": "I", "Ĭ": "I", "İ": "I", "Ï": "I", "Ḯ": "I", "Ỉ": "I", "Ǐ": "I", "Ȉ": "I", "Ȋ": "I", "Ị": "I", "Į": "I", "Ḭ": "I", "Ɨ": "I", "Ⓙ": "J", "Ｊ": "J", "Ĵ": "J", "Ɉ": "J", "Ⓚ": "K", "Ｋ": "K", "Ḱ": "K", "Ǩ": "K", "Ḳ": "K", "Ķ": "K", "Ḵ": "K", "Ƙ": "K", "Ⱪ": "K", "Ꝁ": "K", "Ꝃ": "K", "Ꝅ": "K", "Ꞣ": "K", "Ⓛ": "L", "Ｌ": "L", "Ŀ": "L", "Ĺ": "L", "Ľ": "L", "Ḷ": "L", "Ḹ": "L", "Ļ": "L", "Ḽ": "L", "Ḻ": "L", "Ł": "L", "Ƚ": "L", "Ɫ": "L", "Ⱡ": "L", "Ꝉ": "L", "Ꝇ": "L", "Ꞁ": "L", "Ǉ": "LJ", "ǈ": "Lj", "Ⓜ": "M", "Ｍ": "M", "Ḿ": "M", "Ṁ": "M", "Ṃ": "M", "Ɱ": "M", "Ɯ": "M", "Ⓝ": "N", "Ｎ": "N", "Ǹ": "N", "Ń": "N", "Ñ": "N", "Ṅ": "N", "Ň": "N", "Ṇ": "N", "Ņ": "N", "Ṋ": "N", "Ṉ": "N", "Ƞ": "N", "Ɲ": "N", "Ꞑ": "N", "Ꞥ": "N", "Ǌ": "NJ", "ǋ": "Nj", "Ⓞ": "O", "Ｏ": "O", "Ò": "O", "Ó": "O", "Ô": "O", "Ồ": "O", "Ố": "O", "Ỗ": "O", "Ổ": "O", "Õ": "O", "Ṍ": "O", "Ȭ": "O", "Ṏ": "O", "Ō": "O", "Ṑ": "O", "Ṓ": "O", "Ŏ": "O", "Ȯ": "O", "Ȱ": "O", "Ö": "O", "Ȫ": "O", "Ỏ": "O", "Ő": "O", "Ǒ": "O", "Ȍ": "O", "Ȏ": "O", "Ơ": "O", "Ờ": "O", "Ớ": "O", "Ỡ": "O", "Ở": "O", "Ợ": "O", "Ọ": "O", "Ộ": "O", "Ǫ": "O", "Ǭ": "O", "Ø": "O", "Ǿ": "O", "Ɔ": "O", "Ɵ": "O", "Ꝋ": "O", "Ꝍ": "O", "Ƣ": "OI", "Ꝏ": "OO", "Ȣ": "OU", "Ⓟ": "P", "Ｐ": "P", "Ṕ": "P", "Ṗ": "P", "Ƥ": "P", "Ᵽ": "P", "Ꝑ": "P", "Ꝓ": "P", "Ꝕ": "P", "Ⓠ": "Q", "Ｑ": "Q", "Ꝗ": "Q", "Ꝙ": "Q", "Ɋ": "Q", "Ⓡ": "R", "Ｒ": "R", "Ŕ": "R", "Ṙ": "R", "Ř": "R", "Ȑ": "R", "Ȓ": "R", "Ṛ": "R", "Ṝ": "R", "Ŗ": "R", "Ṟ": "R", "Ɍ": "R", "Ɽ": "R", "Ꝛ": "R", "Ꞧ": "R", "Ꞃ": "R", "Ⓢ": "S", "Ｓ": "S", "ẞ": "S", "Ś": "S", "Ṥ": "S", "Ŝ": "S", "Ṡ": "S", "Š": "S", "Ṧ": "S", "Ṣ": "S", "Ṩ": "S", "Ș": "S", "Ş": "S", "Ȿ": "S", "Ꞩ": "S", "Ꞅ": "S", "Ⓣ": "T", "Ｔ": "T", "Ṫ": "T", "Ť": "T", "Ṭ": "T", "Ț": "T", "Ţ": "T", "Ṱ": "T", "Ṯ": "T", "Ŧ": "T", "Ƭ": "T", "Ʈ": "T", "Ⱦ": "T", "Ꞇ": "T", "Ꜩ": "TZ", "Ⓤ": "U", "Ｕ": "U", "Ù": "U", "Ú": "U", "Û": "U", "Ũ": "U", "Ṹ": "U", "Ū": "U", "Ṻ": "U", "Ŭ": "U", "Ü": "U", "Ǜ": "U", "Ǘ": "U", "Ǖ": "U", "Ǚ": "U", "Ủ": "U", "Ů": "U", "Ű": "U", "Ǔ": "U", "Ȕ": "U", "Ȗ": "U", "Ư": "U", "Ừ": "U", "Ứ": "U", "Ữ": "U", "Ử": "U", "Ự": "U", "Ụ": "U", "Ṳ": "U", "Ų": "U", "Ṷ": "U", "Ṵ": "U", "Ʉ": "U", "Ⓥ": "V", "Ｖ": "V", "Ṽ": "V", "Ṿ": "V", "Ʋ": "V", "Ꝟ": "V", "Ʌ": "V", "Ꝡ": "VY", "Ⓦ": "W", "Ｗ": "W", "Ẁ": "W", "Ẃ": "W", "Ŵ": "W", "Ẇ": "W", "Ẅ": "W", "Ẉ": "W", "Ⱳ": "W", "Ⓧ": "X", "Ｘ": "X", "Ẋ": "X", "Ẍ": "X", "Ⓨ": "Y", "Ｙ": "Y", "Ỳ": "Y", "Ý": "Y", "Ŷ": "Y", "Ỹ": "Y", "Ȳ": "Y", "Ẏ": "Y", "Ÿ": "Y", "Ỷ": "Y", "Ỵ": "Y", "Ƴ": "Y", "Ɏ": "Y", "Ỿ": "Y", "Ⓩ": "Z", "Ｚ": "Z", "Ź": "Z", "Ẑ": "Z", "Ż": "Z", "Ž": "Z", "Ẓ": "Z", "Ẕ": "Z", "Ƶ": "Z", "Ȥ": "Z", "Ɀ": "Z", "Ⱬ": "Z", "Ꝣ": "Z", "ⓐ": "a", "ａ": "a", "ẚ": "a", "à": "a", "á": "a", "â": "a", "ầ": "a", "ấ": "a", "ẫ": "a", "ẩ": "a", "ã": "a", "ā": "a", "ă": "a", "ằ": "a", "ắ": "a", "ẵ": "a", "ẳ": "a", "ȧ": "a", "ǡ": "a", "ä": "a", "ǟ": "a", "ả": "a", "å": "a", "ǻ": "a", "ǎ": "a", "ȁ": "a", "ȃ": "a", "ạ": "a", "ậ": "a", "ặ": "a", "ḁ": "a", "ą": "a", "ⱥ": "a", "ɐ": "a", "ꜳ": "aa", "æ": "ae", "ǽ": "ae", "ǣ": "ae", "ꜵ": "ao", "ꜷ": "au", "ꜹ": "av", "ꜻ": "av", "ꜽ": "ay", "ⓑ": "b", "ｂ": "b", "ḃ": "b", "ḅ": "b", "ḇ": "b", "ƀ": "b", "ƃ": "b", "ɓ": "b", "ⓒ": "c", "ｃ": "c", "ć": "c", "ĉ": "c", "ċ": "c", "č": "c", "ç": "c", "ḉ": "c", "ƈ": "c", "ȼ": "c", "ꜿ": "c", "ↄ": "c", "ⓓ": "d", "ｄ": "d", "ḋ": "d", "ď": "d", "ḍ": "d", "ḑ": "d", "ḓ": "d", "ḏ": "d", "đ": "d", "ƌ": "d", "ɖ": "d", "ɗ": "d", "ꝺ": "d", "ǳ": "dz", "ǆ": "dz", "ⓔ": "e", "ｅ": "e", "è": "e", "é": "e", "ê": "e", "ề": "e", "ế": "e", "ễ": "e", "ể": "e", "ẽ": "e", "ē": "e", "ḕ": "e", "ḗ": "e", "ĕ": "e", "ė": "e", "ë": "e", "ẻ": "e", "ě": "e", "ȅ": "e", "ȇ": "e", "ẹ": "e", "ệ": "e", "ȩ": "e", "ḝ": "e", "ę": "e", "ḙ": "e", "ḛ": "e", "ɇ": "e", "ɛ": "e", "ǝ": "e", "ⓕ": "f", "ｆ": "f", "ḟ": "f", "ƒ": "f", "ꝼ": "f", "ⓖ": "g", "ｇ": "g", "ǵ": "g", "ĝ": "g", "ḡ": "g", "ğ": "g", "ġ": "g", "ǧ": "g", "ģ": "g", "ǥ": "g", "ɠ": "g", "ꞡ": "g", "ᵹ": "g", "ꝿ": "g", "ⓗ": "h", "ｈ": "h", "ĥ": "h", "ḣ": "h", "ḧ": "h", "ȟ": "h", "ḥ": "h", "ḩ": "h", "ḫ": "h", "ẖ": "h", "ħ": "h", "ⱨ": "h", "ⱶ": "h", "ɥ": "h", "ƕ": "hv", "ⓘ": "i", "ｉ": "i", "ì": "i", "í": "i", "î": "i", "ĩ": "i", "ī": "i", "ĭ": "i", "ï": "i", "ḯ": "i", "ỉ": "i", "ǐ": "i", "ȉ": "i", "ȋ": "i", "ị": "i", "į": "i", "ḭ": "i", "ɨ": "i", "ı": "i", "ⓙ": "j", "ｊ": "j", "ĵ": "j", "ǰ": "j", "ɉ": "j", "ⓚ": "k", "ｋ": "k", "ḱ": "k", "ǩ": "k", "ḳ": "k", "ķ": "k", "ḵ": "k", "ƙ": "k", "ⱪ": "k", "ꝁ": "k", "ꝃ": "k", "ꝅ": "k", "ꞣ": "k", "ⓛ": "l", "ｌ": "l", "ŀ": "l", "ĺ": "l", "ľ": "l", "ḷ": "l", "ḹ": "l", "ļ": "l", "ḽ": "l", "ḻ": "l", "ſ": "l", "ł": "l", "ƚ": "l", "ɫ": "l", "ⱡ": "l", "ꝉ": "l", "ꞁ": "l", "ꝇ": "l", "ǉ": "lj", "ⓜ": "m", "ｍ": "m", "ḿ": "m", "ṁ": "m", "ṃ": "m", "ɱ": "m", "ɯ": "m", "ⓝ": "n", "ｎ": "n", "ǹ": "n", "ń": "n", "ñ": "n", "ṅ": "n", "ň": "n", "ṇ": "n", "ņ": "n", "ṋ": "n", "ṉ": "n", "ƞ": "n", "ɲ": "n", "ŉ": "n", "ꞑ": "n", "ꞥ": "n", "ǌ": "nj", "ⓞ": "o", "ｏ": "o", "ò": "o", "ó": "o", "ô": "o", "ồ": "o", "ố": "o", "ỗ": "o", "ổ": "o", "õ": "o", "ṍ": "o", "ȭ": "o", "ṏ": "o", "ō": "o", "ṑ": "o", "ṓ": "o", "ŏ": "o", "ȯ": "o", "ȱ": "o", "ö": "o", "ȫ": "o", "ỏ": "o", "ő": "o", "ǒ": "o", "ȍ": "o", "ȏ": "o", "ơ": "o", "ờ": "o", "ớ": "o", "ỡ": "o", "ở": "o", "ợ": "o", "ọ": "o", "ộ": "o", "ǫ": "o", "ǭ": "o", "ø": "o", "ǿ": "o", "ɔ": "o", "ꝋ": "o", "ꝍ": "o", "ɵ": "o", "ƣ": "oi", "ȣ": "ou", "ꝏ": "oo", "ⓟ": "p", "ｐ": "p", "ṕ": "p", "ṗ": "p", "ƥ": "p", "ᵽ": "p", "ꝑ": "p", "ꝓ": "p", "ꝕ": "p", "ⓠ": "q", "ｑ": "q", "ɋ": "q", "ꝗ": "q", "ꝙ": "q", "ⓡ": "r", "ｒ": "r", "ŕ": "r", "ṙ": "r", "ř": "r", "ȑ": "r", "ȓ": "r", "ṛ": "r", "ṝ": "r", "ŗ": "r", "ṟ": "r", "ɍ": "r", "ɽ": "r", "ꝛ": "r", "ꞧ": "r", "ꞃ": "r", "ⓢ": "s", "ｓ": "s", "ß": "s", "ś": "s", "ṥ": "s", "ŝ": "s", "ṡ": "s", "š": "s", "ṧ": "s", "ṣ": "s", "ṩ": "s", "ș": "s", "ş": "s", "ȿ": "s", "ꞩ": "s", "ꞅ": "s", "ẛ": "s", "ⓣ": "t", "ｔ": "t", "ṫ": "t", "ẗ": "t", "ť": "t", "ṭ": "t", "ț": "t", "ţ": "t", "ṱ": "t", "ṯ": "t", "ŧ": "t", "ƭ": "t", "ʈ": "t", "ⱦ": "t", "ꞇ": "t", "ꜩ": "tz", "ⓤ": "u", "ｕ": "u", "ù": "u", "ú": "u", "û": "u", "ũ": "u", "ṹ": "u", "ū": "u", "ṻ": "u", "ŭ": "u", "ü": "u", "ǜ": "u", "ǘ": "u", "ǖ": "u", "ǚ": "u", "ủ": "u", "ů": "u", "ű": "u", "ǔ": "u", "ȕ": "u", "ȗ": "u", "ư": "u", "ừ": "u", "ứ": "u", "ữ": "u", "ử": "u", "ự": "u", "ụ": "u", "ṳ": "u", "ų": "u", "ṷ": "u", "ṵ": "u", "ʉ": "u", "ⓥ": "v", "ｖ": "v", "ṽ": "v", "ṿ": "v", "ʋ": "v", "ꝟ": "v", "ʌ": "v", "ꝡ": "vy", "ⓦ": "w", "ｗ": "w", "ẁ": "w", "ẃ": "w", "ŵ": "w", "ẇ": "w", "ẅ": "w", "ẘ": "w", "ẉ": "w", "ⱳ": "w", "ⓧ": "x", "ｘ": "x", "ẋ": "x", "ẍ": "x", "ⓨ": "y", "ｙ": "y", "ỳ": "y", "ý": "y", "ŷ": "y", "ỹ": "y", "ȳ": "y", "ẏ": "y", "ÿ": "y", "ỷ": "y", "ẙ": "y", "ỵ": "y", "ƴ": "y", "ɏ": "y", "ỿ": "y", "ⓩ": "z", "ｚ": "z", "ź": "z", "ẑ": "z", "ż": "z", "ž": "z", "ẓ": "z", "ẕ": "z", "ƶ": "z", "ȥ": "z", "ɀ": "z", "ⱬ": "z", "ꝣ": "z", "Ά": "Α", "Έ": "Ε", "Ή": "Η", "Ί": "Ι", "Ϊ": "Ι", "Ό": "Ο", "Ύ": "Υ", "Ϋ": "Υ", "Ώ": "Ω", "ά": "α", "έ": "ε", "ή": "η", "ί": "ι", "ϊ": "ι", "ΐ": "ι", "ό": "ο", "ύ": "υ", "ϋ": "υ", "ΰ": "υ", "ω": "ω", "ς": "σ" } }), b.define("select2/data/base", ["../utils"], function (a) { function b(a, c) { b.__super__.constructor.call(this) } return a.Extend(b, a.Observable), b.prototype.current = function (a) { throw new Error("The `current` method must be defined in child classes.") }, b.prototype.query = function (a, b) { throw new Error("The `query` method must be defined in child classes.") }, b.prototype.bind = function (a, b) { }, b.prototype.destroy = function () { }, b.prototype.generateResultId = function (b, c) { var d = b.id + "-result-"; return d += a.generateChars(4), null != c.id ? d += "-" + c.id.toString() : d += "-" + a.generateChars(4), d }, b }), b.define("select2/data/select", ["./base", "../utils", "jquery"], function (a, b, c) { function d(a, b) { this.$element = a, this.options = b, d.__super__.constructor.call(this) } return b.Extend(d, a), d.prototype.current = function (a) { var b = [], d = this; this.$element.find(":selected").each(function () { var a = c(this), e = d.item(a); b.push(e) }), a(b) }, d.prototype.select = function (a) { var b = this; if (a.selected = !0, c(a.element).is("option")) return a.element.selected = !0, void this.$element.trigger("change"); if (this.$element.prop("multiple")) this.current(function (d) { var e = []; a = [a], a.push.apply(a, d); for (var f = 0; f < a.length; f++) { var g = a[f].id; -1 === c.inArray(g, e) && e.push(g) } b.$element.val(e), b.$element.trigger("change") }); else { var d = a.id; this.$element.val(d), this.$element.trigger("change") } }, d.prototype.unselect = function (a) { var b = this; if (this.$element.prop("multiple")) { if (a.selected = !1, c(a.element).is("option")) return a.element.selected = !1, void this.$element.trigger("change"); this.current(function (d) { for (var e = [], f = 0; f < d.length; f++) { var g = d[f].id; g !== a.id && -1 === c.inArray(g, e) && e.push(g) } b.$element.val(e), b.$element.trigger("change") }) } }, d.prototype.bind = function (a, b) { var c = this; this.container = a, a.on("select", function (a) { c.select(a.data) }), a.on("unselect", function (a) { c.unselect(a.data) }) }, d.prototype.destroy = function () { this.$element.find("*").each(function () { b.RemoveData(this) }) }, d.prototype.query = function (a, b) { var d = [], e = this; this.$element.children().each(function () { var b = c(this); if (b.is("option") || b.is("optgroup")) { var f = e.item(b), g = e.matches(a, f); null !== g && d.push(g) } }), b({ results: d }) }, d.prototype.addOptions = function (a) { b.appendMany(this.$element, a) }, d.prototype.option = function (a) { var d; a.children ? (d = document.createElement("optgroup"), d.label = a.text) : (d = document.createElement("option"), void 0 !== d.textContent ? d.textContent = a.text : d.innerText = a.text), void 0 !== a.id && (d.value = a.id), a.disabled && (d.disabled = !0), a.selected && (d.selected = !0), a.title && (d.title = a.title); var e = c(d), f = this._normalizeItem(a); return f.element = d, b.StoreData(d, "data", f), e }, d.prototype.item = function (a) { var d = {}; if (null != (d = b.GetData(a[0], "data"))) return d; if (a.is("option")) d = { id: a.val(), text: a.text(), disabled: a.prop("disabled"), selected: a.prop("selected"), title: a.prop("title") }; else if (a.is("optgroup")) { d = { text: a.prop("label"), children: [], title: a.prop("title") }; for (var e = a.children("option"), f = [], g = 0; g < e.length; g++) { var h = c(e[g]), i = this.item(h); f.push(i) } d.children = f } return d = this._normalizeItem(d), d.element = a[0], b.StoreData(a[0], "data", d), d }, d.prototype._normalizeItem = function (a) { a !== Object(a) && (a = { id: a, text: a }), a = c.extend({}, { text: "" }, a); var b = { selected: !1, disabled: !1 }; return null != a.id && (a.id = a.id.toString()), null != a.text && (a.text = a.text.toString()), null == a._resultId && a.id && null != this.container && (a._resultId = this.generateResultId(this.container, a)), c.extend({}, b, a) }, d.prototype.matches = function (a, b) { return this.options.get("matcher")(a, b) }, d }), b.define("select2/data/array", ["./select", "../utils", "jquery"], function (a, b, c) { function d(a, b) { var c = b.get("data") || []; d.__super__.constructor.call(this, a, b), this.addOptions(this.convertToOptions(c)) } return b.Extend(d, a), d.prototype.select = function (a) { var b = this.$element.find("option").filter(function (b, c) { return c.value == a.id.toString() }); 0 === b.length && (b = this.option(a), this.addOptions(b)), d.__super__.select.call(this, a) }, d.prototype.convertToOptions = function (a) { function d(a) { return function () { return c(this).val() == a.id } } for (var e = this, f = this.$element.find("option"), g = f.map(function () { return e.item(c(this)).id }).get(), h = [], i = 0; i < a.length; i++) { var j = this._normalizeItem(a[i]); if (c.inArray(j.id, g) >= 0) { var k = f.filter(d(j)), l = this.item(k), m = c.extend(!0, {}, j, l), n = this.option(m); k.replaceWith(n) } else { var o = this.option(j); if (j.children) { var p = this.convertToOptions(j.children); b.appendMany(o, p) } h.push(o) } } return h }, d }), b.define("select2/data/ajax", ["./array", "../utils", "jquery"], function (a, b, c) { function d(a, b) { this.ajaxOptions = this._applyDefaults(b.get("ajax")), null != this.ajaxOptions.processResults && (this.processResults = this.ajaxOptions.processResults), d.__super__.constructor.call(this, a, b) } return b.Extend(d, a), d.prototype._applyDefaults = function (a) { var b = { data: function (a) { return c.extend({}, a, { q: a.term }) }, transport: function (a, b, d) { var e = c.ajax(a); return e.then(b), e.fail(d), e } }; return c.extend({}, b, a, !0) }, d.prototype.processResults = function (a) { return a }, d.prototype.query = function (a, b) { function d() { var d = f.transport(f, function (d) { var f = e.processResults(d, a); e.options.get("debug") && window.console && console.error && (f && f.results && c.isArray(f.results) || console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")), b(f) }, function () { "status" in d && (0 === d.status || "0" === d.status) || e.trigger("results:message", { message: "errorLoading" }) }); e._request = d } var e = this; null != this._request && (c.isFunction(this._request.abort) && this._request.abort(), this._request = null); var f = c.extend({ type: "GET" }, this.ajaxOptions); "function" == typeof f.url && (f.url = f.url.call(this.$element, a)), "function" == typeof f.data && (f.data = f.data.call(this.$element, a)), this.ajaxOptions.delay && null != a.term ? (this._queryTimeout && window.clearTimeout(this._queryTimeout), this._queryTimeout = window.setTimeout(d, this.ajaxOptions.delay)) : d() }, d }), b.define("select2/data/tags", ["jquery"], function (a) { function b(b, c, d) { var e = d.get("tags"), f = d.get("createTag"); void 0 !== f && (this.createTag = f); var g = d.get("insertTag"); if (void 0 !== g && (this.insertTag = g), b.call(this, c, d), a.isArray(e)) for (var h = 0; h < e.length; h++) { var i = e[h], j = this._normalizeItem(i), k = this.option(j); this.$element.append(k) } } return b.prototype.query = function (a, b, c) { function d(a, f) { for (var g = a.results, h = 0; h < g.length; h++) { var i = g[h], j = null != i.children && !d({ results: i.children }, !0); if ((i.text || "").toUpperCase() === (b.term || "").toUpperCase() || j) return !f && (a.data = g, void c(a)) } if (f) return !0; var k = e.createTag(b); if (null != k) { var l = e.option(k); l.attr("data-select2-tag", !0), e.addOptions([l]), e.insertTag(g, k) } a.results = g, c(a) } var e = this; if (this._removeOldTags(), null == b.term || null != b.page) return void a.call(this, b, c); a.call(this, b, d) }, b.prototype.createTag = function (b, c) { var d = a.trim(c.term); return "" === d ? null : { id: d, text: d } }, b.prototype.insertTag = function (a, b, c) { b.unshift(c) }, b.prototype._removeOldTags = function (b) { this._lastTag; this.$element.find("option[data-select2-tag]").each(function () { this.selected || a(this).remove() }) }, b }), b.define("select2/data/tokenizer", ["jquery"], function (a) { function b(a, b, c) { var d = c.get("tokenizer"); void 0 !== d && (this.tokenizer = d), a.call(this, b, c) } return b.prototype.bind = function (a, b, c) { a.call(this, b, c), this.$search = b.dropdown.$search || b.selection.$search || c.find(".select2-search__field") }, b.prototype.query = function (b, c, d) { function e(b) { var c = g._normalizeItem(b); if (!g.$element.find("option").filter(function () { return a(this).val() === c.id }).length) { var d = g.option(c); d.attr("data-select2-tag", !0), g._removeOldTags(), g.addOptions([d]) } f(c) } function f(a) { g.trigger("select", { data: a }) } var g = this; c.term = c.term || ""; var h = this.tokenizer(c, this.options, e); h.term !== c.term && (this.$search.length && (this.$search.val(h.term), this.$search.focus()), c.term = h.term), b.call(this, c, d) }, b.prototype.tokenizer = function (b, c, d, e) { for (var f = d.get("tokenSeparators") || [], g = c.term, h = 0, i = this.createTag || function (a) { return { id: a.term, text: a.term } }; h < g.length;) { var j = g[h]; if (-1 !== a.inArray(j, f)) { var k = g.substr(0, h), l = a.extend({}, c, { term: k }), m = i(l); null != m ? (e(m), g = g.substr(h + 1) || "", h = 0) : h++ } else h++ } return { term: g } }, b }), b.define("select2/data/minimumInputLength", [], function () { function a(a, b, c) { this.minimumInputLength = c.get("minimumInputLength"), a.call(this, b, c) } return a.prototype.query = function (a, b, c) { if (b.term = b.term || "", b.term.length < this.minimumInputLength) return void this.trigger("results:message", { message: "inputTooShort", args: { minimum: this.minimumInputLength, input: b.term, params: b } }); a.call(this, b, c) }, a }), b.define("select2/data/maximumInputLength", [], function () { function a(a, b, c) { this.maximumInputLength = c.get("maximumInputLength"), a.call(this, b, c) } return a.prototype.query = function (a, b, c) { if (b.term = b.term || "", this.maximumInputLength > 0 && b.term.length > this.maximumInputLength) return void this.trigger("results:message", { message: "inputTooLong", args: { maximum: this.maximumInputLength, input: b.term, params: b } }); a.call(this, b, c) }, a }), b.define("select2/data/maximumSelectionLength", [], function () { function a(a, b, c) { this.maximumSelectionLength = c.get("maximumSelectionLength"), a.call(this, b, c) } return a.prototype.query = function (a, b, c) { var d = this; this.current(function (e) { var f = null != e ? e.length : 0; if (d.maximumSelectionLength > 0 && f >= d.maximumSelectionLength) return void d.trigger("results:message", { message: "maximumSelected", args: { maximum: d.maximumSelectionLength } }); a.call(d, b, c) }) }, a }), b.define("select2/dropdown", ["jquery", "./utils"], function (a, b) { function c(a, b) { this.$element = a, this.options = b, c.__super__.constructor.call(this) } return b.Extend(c, b.Observable), c.prototype.render = function () { var b = a('<span class="select2-dropdown"><span class="select2-results"></span></span>'); return b.attr("dir", this.options.get("dir")), this.$dropdown = b, b }, c.prototype.bind = function () { }, c.prototype.position = function (a, b) { }, c.prototype.destroy = function () { this.$dropdown.remove() }, c }), b.define("select2/dropdown/search", ["jquery", "../utils"], function (a, b) { function c() { } return c.prototype.render = function (b) { var c = b.call(this), d = a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="textbox" /></span>'); return this.$searchContainer = d, this.$search = d.find("input"), c.prepend(d), c }, c.prototype.bind = function (b, c, d) { var e = this; b.call(this, c, d), this.$search.on("keydown", function (a) { e.trigger("keypress", a), e._keyUpPrevented = a.isDefaultPrevented() }), this.$search.on("input", function (b) { a(this).off("keyup") }), this.$search.on("keyup input", function (a) { e.handleSearch(a) }), c.on("open", function () { e.$search.attr("tabindex", 0), e.$search.focus(), window.setTimeout(function () { e.$search.focus() }, 0) }), c.on("close", function () { e.$search.attr("tabindex", -1), e.$search.val(""), e.$search.blur() }), c.on("focus", function () { c.isOpen() || e.$search.focus() }), c.on("results:all", function (a) { if (null == a.query.term || "" === a.query.term) { e.showSearch(a) ? e.$searchContainer.removeClass("select2-search--hide") : e.$searchContainer.addClass("select2-search--hide") } }) }, c.prototype.handleSearch = function (a) { if (!this._keyUpPrevented) { var b = this.$search.val(); this.trigger("query", { term: b }) } this._keyUpPrevented = !1 }, c.prototype.showSearch = function (a, b) { return !0 }, c }), b.define("select2/dropdown/hidePlaceholder", [], function () { function a(a, b, c, d) { this.placeholder = this.normalizePlaceholder(c.get("placeholder")), a.call(this, b, c, d) } return a.prototype.append = function (a, b) { b.results = this.removePlaceholder(b.results), a.call(this, b) }, a.prototype.normalizePlaceholder = function (a, b) { return "string" == typeof b && (b = { id: "", text: b }), b }, a.prototype.removePlaceholder = function (a, b) { for (var c = b.slice(0), d = b.length - 1; d >= 0; d--) { var e = b[d]; this.placeholder.id === e.id && c.splice(d, 1) } return c }, a }), b.define("select2/dropdown/infiniteScroll", ["jquery"], function (a) { function b(a, b, c, d) { this.lastParams = {}, a.call(this, b, c, d), this.$loadingMore = this.createLoadingMore(), this.loading = !1 } return b.prototype.append = function (a, b) { this.$loadingMore.remove(), this.loading = !1, a.call(this, b), this.showLoadingMore(b) && this.$results.append(this.$loadingMore) }, b.prototype.bind = function (b, c, d) { var e = this; b.call(this, c, d), c.on("query", function (a) { e.lastParams = a, e.loading = !0 }), c.on("query:append", function (a) { e.lastParams = a, e.loading = !0 }), this.$results.on("scroll", function () { var b = a.contains(document.documentElement, e.$loadingMore[0]); if (!e.loading && b) { e.$results.offset().top + e.$results.outerHeight(!1) + 50 >= e.$loadingMore.offset().top + e.$loadingMore.outerHeight(!1) && e.loadMore() } }) }, b.prototype.loadMore = function () { this.loading = !0; var b = a.extend({}, { page: 1 }, this.lastParams); b.page++ , this.trigger("query:append", b) }, b.prototype.showLoadingMore = function (a, b) { return b.pagination && b.pagination.more }, b.prototype.createLoadingMore = function () { var b = a('<li class="select2-results__option select2-results__option--load-more"role="treeitem" aria-disabled="true"></li>'), c = this.options.get("translations").get("loadingMore"); return b.html(c(this.lastParams)), b }, b }), b.define("select2/dropdown/attachBody", ["jquery", "../utils"], function (a, b) { function c(b, c, d) { this.$dropdownParent = d.get("dropdownParent") || a(document.body), b.call(this, c, d) } return c.prototype.bind = function (a, b, c) { var d = this, e = !1; a.call(this, b, c), b.on("open", function () { d._showDropdown(), d._attachPositioningHandler(b), e || (e = !0, b.on("results:all", function () { d._positionDropdown(), d._resizeDropdown() }), b.on("results:append", function () { d._positionDropdown(), d._resizeDropdown() })) }), b.on("close", function () { d._hideDropdown(), d._detachPositioningHandler(b) }), this.$dropdownContainer.on("mousedown", function (a) { a.stopPropagation() }) }, c.prototype.destroy = function (a) { a.call(this), this.$dropdownContainer.remove() }, c.prototype.position = function (a, b, c) { b.attr("class", c.attr("class")), b.removeClass("select2"), b.addClass("select2-container--open"), b.css({ position: "absolute", top: -999999 }), this.$container = c }, c.prototype.render = function (b) { var c = a("<span></span>"), d = b.call(this); return c.append(d), this.$dropdownContainer = c, c }, c.prototype._hideDropdown = function (a) { this.$dropdownContainer.detach() }, c.prototype._attachPositioningHandler = function (c, d) { var e = this, f = "scroll.select2." + d.id, g = "resize.select2." + d.id, h = "orientationchange.select2." + d.id, i = this.$container.parents().filter(b.hasScroll); i.each(function () { b.StoreData(this, "select2-scroll-position", { x: a(this).scrollLeft(), y: a(this).scrollTop() }) }), i.on(f, function (c) { var d = b.GetData(this, "select2-scroll-position"); a(this).scrollTop(d.y) }), a(window).on(f + " " + g + " " + h, function (a) { e._positionDropdown(), e._resizeDropdown() }) }, c.prototype._detachPositioningHandler = function (c, d) { var e = "scroll.select2." + d.id, f = "resize.select2." + d.id, g = "orientationchange.select2." + d.id; this.$container.parents().filter(b.hasScroll).off(e), a(window).off(e + " " + f + " " + g) }, c.prototype._positionDropdown = function () { var b = a(window), c = this.$dropdown.hasClass("select2-dropdown--above"), d = this.$dropdown.hasClass("select2-dropdown--below"), e = null, f = this.$container.offset(); f.bottom = f.top + this.$container.outerHeight(!1); var g = { height: this.$container.outerHeight(!1) }; g.top = f.top, g.bottom = f.top + g.height; var h = { height: this.$dropdown.outerHeight(!1) }, i = { top: b.scrollTop(), bottom: b.scrollTop() + b.height() }, j = i.top < f.top - h.height, k = i.bottom > f.bottom + h.height, l = { left: f.left, top: g.bottom }, m = this.$dropdownParent; "static" === m.css("position") && (m = m.offsetParent()); var n = m.offset(); l.top -= n.top, l.left -= n.left, c || d || (e = "below"), k || !j || c ? !j && k && c && (e = "below") : e = "above", ("above" == e || c && "below" !== e) && (l.top = g.top - n.top - h.height), null != e && (this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--" + e), this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--" + e)), this.$dropdownContainer.css(l) }, c.prototype._resizeDropdown = function () { var a = { width: this.$container.outerWidth(!1) + "px" }; this.options.get("dropdownAutoWidth") && (a.minWidth = a.width, a.position = "relative", a.width = "auto"), this.$dropdown.css(a) }, c.prototype._showDropdown = function (a) { this.$dropdownContainer.appendTo(this.$dropdownParent), this._positionDropdown(), this._resizeDropdown() }, c }), b.define("select2/dropdown/minimumResultsForSearch", [], function () { function a(b) { for (var c = 0, d = 0; d < b.length; d++) { var e = b[d]; e.children ? c += a(e.children) : c++ } return c } function b(a, b, c, d) { this.minimumResultsForSearch = c.get("minimumResultsForSearch"), this.minimumResultsForSearch < 0 && (this.minimumResultsForSearch = 1 / 0), a.call(this, b, c, d) } return b.prototype.showSearch = function (b, c) { return !(a(c.data.results) < this.minimumResultsForSearch) && b.call(this, c) }, b }), b.define("select2/dropdown/selectOnClose", ["../utils"], function (a) { function b() { } return b.prototype.bind = function (a, b, c) { var d = this; a.call(this, b, c), b.on("close", function (a) { d._handleSelectOnClose(a) }) }, b.prototype._handleSelectOnClose = function (b, c) { if (c && null != c.originalSelect2Event) { var d = c.originalSelect2Event; if ("select" === d._type || "unselect" === d._type) return } var e = this.getHighlightedResults(); if (!(e.length < 1)) { var f = a.GetData(e[0], "data"); null != f.element && f.element.selected || null == f.element && f.selected || this.trigger("select", { data: f }) } }, b }), b.define("select2/dropdown/closeOnSelect", [], function () { function a() { } return a.prototype.bind = function (a, b, c) { var d = this; a.call(this, b, c), b.on("select", function (a) { d._selectTriggered(a) }), b.on("unselect", function (a) { d._selectTriggered(a) }) }, a.prototype._selectTriggered = function (a, b) { var c = b.originalEvent; c && c.ctrlKey || this.trigger("close", { originalEvent: c, originalSelect2Event: b }) }, a }), b.define("select2/i18n/en", [], function () { return { errorLoading: function () { return "The results could not be loaded." }, inputTooLong: function (a) { var b = a.input.length - a.maximum, c = "Please delete " + b + " character"; return 1 != b && (c += "s"), c }, inputTooShort: function (a) { return "Please enter " + (a.minimum - a.input.length) + " or more characters" }, loadingMore: function () { return "Loading more results…" }, maximumSelected: function (a) { var b = "You can only select " + a.maximum + " item"; return 1 != a.maximum && (b += "s"), b }, noResults: function () { return "No results found" }, searching: function () { return "Searching…" } } }), b.define("select2/defaults", ["jquery", "require", "./results", "./selection/single", "./selection/multiple", "./selection/placeholder", "./selection/allowClear", "./selection/search", "./selection/eventRelay", "./utils", "./translation", "./diacritics", "./data/select", "./data/array", "./data/ajax", "./data/tags", "./data/tokenizer", "./data/minimumInputLength", "./data/maximumInputLength", "./data/maximumSelectionLength", "./dropdown", "./dropdown/search", "./dropdown/hidePlaceholder", "./dropdown/infiniteScroll", "./dropdown/attachBody", "./dropdown/minimumResultsForSearch", "./dropdown/selectOnClose", "./dropdown/closeOnSelect", "./i18n/en"], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C) { function D() { this.reset() } return D.prototype.apply = function (l) { if (l = a.extend(!0, {}, this.defaults, l), null == l.dataAdapter) { if (null != l.ajax ? l.dataAdapter = o : null != l.data ? l.dataAdapter = n : l.dataAdapter = m, l.minimumInputLength > 0 && (l.dataAdapter = j.Decorate(l.dataAdapter, r)), l.maximumInputLength > 0 && (l.dataAdapter = j.Decorate(l.dataAdapter, s)), l.maximumSelectionLength > 0 && (l.dataAdapter = j.Decorate(l.dataAdapter, t)), l.tags && (l.dataAdapter = j.Decorate(l.dataAdapter, p)), null == l.tokenSeparators && null == l.tokenizer || (l.dataAdapter = j.Decorate(l.dataAdapter, q)), null != l.query) { var C = b(l.amdBase + "compat/query"); l.dataAdapter = j.Decorate(l.dataAdapter, C) } if (null != l.initSelection) { var D = b(l.amdBase + "compat/initSelection"); l.dataAdapter = j.Decorate(l.dataAdapter, D) } } if (null == l.resultsAdapter && (l.resultsAdapter = c, null != l.ajax && (l.resultsAdapter = j.Decorate(l.resultsAdapter, x)), null != l.placeholder && (l.resultsAdapter = j.Decorate(l.resultsAdapter, w)), l.selectOnClose && (l.resultsAdapter = j.Decorate(l.resultsAdapter, A))), null == l.dropdownAdapter) { if (l.multiple) l.dropdownAdapter = u; else { var E = j.Decorate(u, v); l.dropdownAdapter = E } if (0 !== l.minimumResultsForSearch && (l.dropdownAdapter = j.Decorate(l.dropdownAdapter, z)), l.closeOnSelect && (l.dropdownAdapter = j.Decorate(l.dropdownAdapter, B)), null != l.dropdownCssClass || null != l.dropdownCss || null != l.adaptDropdownCssClass) { var F = b(l.amdBase + "compat/dropdownCss"); l.dropdownAdapter = j.Decorate(l.dropdownAdapter, F) } l.dropdownAdapter = j.Decorate(l.dropdownAdapter, y) } if (null == l.selectionAdapter) { if (l.multiple ? l.selectionAdapter = e : l.selectionAdapter = d, null != l.placeholder && (l.selectionAdapter = j.Decorate(l.selectionAdapter, f)), l.allowClear && (l.selectionAdapter = j.Decorate(l.selectionAdapter, g)), l.multiple && (l.selectionAdapter = j.Decorate(l.selectionAdapter, h)), null != l.containerCssClass || null != l.containerCss || null != l.adaptContainerCssClass) { var G = b(l.amdBase + "compat/containerCss"); l.selectionAdapter = j.Decorate(l.selectionAdapter, G) } l.selectionAdapter = j.Decorate(l.selectionAdapter, i) } if ("string" == typeof l.language) if (l.language.indexOf("-") > 0) { var H = l.language.split("-"), I = H[0]; l.language = [l.language, I] } else l.language = [l.language]; if (a.isArray(l.language)) { var J = new k; l.language.push("en"); for (var K = l.language, L = 0; L < K.length; L++) { var M = K[L], N = {}; try { N = k.loadPath(M) } catch (a) { try { M = this.defaults.amdLanguageBase + M, N = k.loadPath(M) } catch (a) { l.debug && window.console && console.warn && console.warn('Select2: The language file for "' + M + '" could not be automatically loaded. A fallback will be used instead.'); continue } } J.extend(N) } l.translations = J } else { var O = k.loadPath(this.defaults.amdLanguageBase + "en"), P = new k(l.language); P.extend(O), l.translations = P } return l }, D.prototype.reset = function () { function b(a) { function b(a) { return l[a] || a } return a.replace(/[^\u0000-\u007E]/g, b) } function c(d, e) { if ("" === a.trim(d.term)) return e; if (e.children && e.children.length > 0) { for (var f = a.extend(!0, {}, e), g = e.children.length - 1; g >= 0; g--) { null == c(d, e.children[g]) && f.children.splice(g, 1) } return f.children.length > 0 ? f : c(d, f) } var h = b(e.text).toUpperCase(), i = b(d.term).toUpperCase(); return h.indexOf(i) > -1 ? e : null } this.defaults = { amdBase: "./", amdLanguageBase: "./i18n/", closeOnSelect: !0, debug: !1, dropdownAutoWidth: !1, escapeMarkup: j.escapeMarkup, language: C, matcher: c, minimumInputLength: 0, maximumInputLength: 0, maximumSelectionLength: 0, minimumResultsForSearch: 0, selectOnClose: !1, sorter: function (a) { return a }, templateResult: function (a) { return a.text }, templateSelection: function (a) { return a.text }, theme: "default", width: "resolve" } }, D.prototype.set = function (b, c) { var d = a.camelCase(b), e = {}; e[d] = c; var f = j._convertData(e); a.extend(!0, this.defaults, f) }, new D }), b.define("select2/options", ["require", "jquery", "./defaults", "./utils"], function (a, b, c, d) { function e(b, e) { if (this.options = b, null != e && this.fromElement(e), this.options = c.apply(this.options), e && e.is("input")) { var f = a(this.get("amdBase") + "compat/inputData"); this.options.dataAdapter = d.Decorate(this.options.dataAdapter, f) } } return e.prototype.fromElement = function (a) { var c = ["select2"]; null == this.options.multiple && (this.options.multiple = a.prop("multiple")), null == this.options.disabled && (this.options.disabled = a.prop("disabled")), null == this.options.language && (a.prop("lang") ? this.options.language = a.prop("lang").toLowerCase() : a.closest("[lang]").prop("lang") && (this.options.language = a.closest("[lang]").prop("lang"))), null == this.options.dir && (a.prop("dir") ? this.options.dir = a.prop("dir") : a.closest("[dir]").prop("dir") ? this.options.dir = a.closest("[dir]").prop("dir") : this.options.dir = "ltr"), a.prop("disabled", this.options.disabled), a.prop("multiple", this.options.multiple), d.GetData(a[0], "select2Tags") && (this.options.debug && window.console && console.warn && console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'), d.StoreData(a[0], "data", d.GetData(a[0], "select2Tags")), d.StoreData(a[0], "tags", !0)), d.GetData(a[0], "ajaxUrl") && (this.options.debug && window.console && console.warn && console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."), a.attr("ajax--url", d.GetData(a[0], "ajaxUrl")), d.StoreData(a[0], "ajax-Url", d.GetData(a[0], "ajaxUrl"))); var e = {}; e = b.fn.jquery && "1." == b.fn.jquery.substr(0, 2) && a[0].dataset ? b.extend(!0, {}, a[0].dataset, d.GetData(a[0])) : d.GetData(a[0]); var f = b.extend(!0, {}, e); f = d._convertData(f); for (var g in f) b.inArray(g, c) > -1 || (b.isPlainObject(this.options[g]) ? b.extend(this.options[g], f[g]) : this.options[g] = f[g]); return this }, e.prototype.get = function (a) { return this.options[a] }, e.prototype.set = function (a, b) { this.options[a] = b }, e }), b.define("select2/core", ["jquery", "./options", "./utils", "./keys"], function (a, b, c, d) { var e = function (a, d) { null != c.GetData(a[0], "select2") && c.GetData(a[0], "select2").destroy(), this.$element = a, this.id = this._generateId(a), d = d || {}, this.options = new b(d, a), e.__super__.constructor.call(this); var f = a.attr("tabindex") || 0; c.StoreData(a[0], "old-tabindex", f), a.attr("tabindex", "-1"); var g = this.options.get("dataAdapter"); this.dataAdapter = new g(a, this.options); var h = this.render(); this._placeContainer(h); var i = this.options.get("selectionAdapter"); this.selection = new i(a, this.options), this.$selection = this.selection.render(), this.selection.position(this.$selection, h); var j = this.options.get("dropdownAdapter"); this.dropdown = new j(a, this.options), this.$dropdown = this.dropdown.render(), this.dropdown.position(this.$dropdown, h); var k = this.options.get("resultsAdapter"); this.results = new k(a, this.options, this.dataAdapter), this.$results = this.results.render(), this.results.position(this.$results, this.$dropdown); var l = this; this._bindAdapters(), this._registerDomEvents(), this._registerDataEvents(), this._registerSelectionEvents(), this._registerDropdownEvents(), this._registerResultsEvents(), this._registerEvents(), this.dataAdapter.current(function (a) { l.trigger("selection:update", { data: a }) }), a.addClass("select2-hidden-accessible"), a.attr("aria-hidden", "true"), this._syncAttributes(), c.StoreData(a[0], "select2", this), a.data("select2", this) }; return c.Extend(e, c.Observable), e.prototype._generateId = function (a) { var b = ""; return b = null != a.attr("id") ? a.attr("id") : null != a.attr("name") ? a.attr("name") + "-" + c.generateChars(2) : c.generateChars(4), b = b.replace(/(:|\.|\[|\]|,)/g, ""), b = "select2-" + b }, e.prototype._placeContainer = function (a) { a.insertAfter(this.$element); var b = this._resolveWidth(this.$element, this.options.get("width")); null != b && a.css("width", b) }, e.prototype._resolveWidth = function (a, b) { var c = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; if ("resolve" == b) { var d = this._resolveWidth(a, "style"); return null != d ? d : this._resolveWidth(a, "element") } if ("element" == b) { var e = a.outerWidth(!1); return e <= 0 ? "auto" : e + "px" } if ("style" == b) { var f = a.attr("style"); if ("string" != typeof f) return null; for (var g = f.split(";"), h = 0, i = g.length; h < i; h += 1) { var j = g[h].replace(/\s/g, ""), k = j.match(c); if (null !== k && k.length >= 1) return k[1] } return null } return b }, e.prototype._bindAdapters = function () { this.dataAdapter.bind(this, this.$container), this.selection.bind(this, this.$container), this.dropdown.bind(this, this.$container), this.results.bind(this, this.$container) }, e.prototype._registerDomEvents = function () { var b = this; this.$element.on("change.select2", function () { b.dataAdapter.current(function (a) { b.trigger("selection:update", { data: a }) }) }), this.$element.on("focus.select2", function (a) { b.trigger("focus", a) }), this._syncA = c.bind(this._syncAttributes, this), this._syncS = c.bind(this._syncSubtree, this), this.$element[0].attachEvent && this.$element[0].attachEvent("onpropertychange", this._syncA); var d = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; null != d ? (this._observer = new d(function (c) { a.each(c, b._syncA), a.each(c, b._syncS) }), this._observer.observe(this.$element[0], { attributes: !0, childList: !0, subtree: !1 })) : this.$element[0].addEventListener && (this.$element[0].addEventListener("DOMAttrModified", b._syncA, !1), this.$element[0].addEventListener("DOMNodeInserted", b._syncS, !1), this.$element[0].addEventListener("DOMNodeRemoved", b._syncS, !1)) }, e.prototype._registerDataEvents = function () { var a = this; this.dataAdapter.on("*", function (b, c) { a.trigger(b, c) }) }, e.prototype._registerSelectionEvents = function () { var b = this, c = ["toggle", "focus"]; this.selection.on("toggle", function () { b.toggleDropdown() }), this.selection.on("focus", function (a) { b.focus(a) }), this.selection.on("*", function (d, e) { -1 === a.inArray(d, c) && b.trigger(d, e) }) }, e.prototype._registerDropdownEvents = function () { var a = this; this.dropdown.on("*", function (b, c) { a.trigger(b, c) }) }, e.prototype._registerResultsEvents = function () { var a = this; this.results.on("*", function (b, c) { a.trigger(b, c) }) }, e.prototype._registerEvents = function () { var a = this; this.on("open", function () { a.$container.addClass("select2-container--open") }), this.on("close", function () { a.$container.removeClass("select2-container--open") }), this.on("enable", function () { a.$container.removeClass("select2-container--disabled") }), this.on("disable", function () { a.$container.addClass("select2-container--disabled") }), this.on("blur", function () { a.$container.removeClass("select2-container--focus") }), this.on("query", function (b) { a.isOpen() || a.trigger("open", {}), this.dataAdapter.query(b, function (c) { a.trigger("results:all", { data: c, query: b }) }) }), this.on("query:append", function (b) { this.dataAdapter.query(b, function (c) { a.trigger("results:append", { data: c, query: b }) }) }), this.on("keypress", function (b) { var c = b.which; a.isOpen() ? c === d.ESC || c === d.TAB || c === d.UP && b.altKey ? (a.close(), b.preventDefault()) : c === d.ENTER ? (a.trigger("results:select", {}), b.preventDefault()) : c === d.SPACE && b.ctrlKey ? (a.trigger("results:toggle", {}), b.preventDefault()) : c === d.UP ? (a.trigger("results:previous", {}), b.preventDefault()) : c === d.DOWN && (a.trigger("results:next", {}), b.preventDefault()) : (c === d.ENTER || c === d.SPACE || c === d.DOWN && b.altKey) && (a.open(), b.preventDefault()) }) }, e.prototype._syncAttributes = function () { this.options.set("disabled", this.$element.prop("disabled")), this.options.get("disabled") ? (this.isOpen() && this.close(), this.trigger("disable", {})) : this.trigger("enable", {}) }, e.prototype._syncSubtree = function (a, b) { var c = !1, d = this; if (!a || !a.target || "OPTION" === a.target.nodeName || "OPTGROUP" === a.target.nodeName) { if (b) if (b.addedNodes && b.addedNodes.length > 0) for (var e = 0; e < b.addedNodes.length; e++) { var f = b.addedNodes[e]; f.selected && (c = !0) } else b.removedNodes && b.removedNodes.length > 0 && (c = !0); else c = !0; c && this.dataAdapter.current(function (a) { d.trigger("selection:update", { data: a }) }) } }, e.prototype.trigger = function (a, b) { var c = e.__super__.trigger, d = { open: "opening", close: "closing", select: "selecting", unselect: "unselecting", clear: "clearing" }; if (void 0 === b && (b = {}), a in d) { var f = d[a], g = { prevented: !1, name: a, args: b }; if (c.call(this, f, g), g.prevented) return void (b.prevented = !0) } c.call(this, a, b) }, e.prototype.toggleDropdown = function () { this.options.get("disabled") || (this.isOpen() ? this.close() : this.open()) }, e.prototype.open = function () { this.isOpen() || this.trigger("query", {}) }, e.prototype.close = function () { this.isOpen() && this.trigger("close", {}) }, e.prototype.isOpen = function () { return this.$container.hasClass("select2-container--open") }, e.prototype.hasFocus = function () { return this.$container.hasClass("select2-container--focus") }, e.prototype.focus = function (a) { this.hasFocus() || (this.$container.addClass("select2-container--focus"), this.trigger("focus", {})) }, e.prototype.enable = function (a) { this.options.get("debug") && window.console && console.warn && console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'), null != a && 0 !== a.length || (a = [!0]); var b = !a[0]; this.$element.prop("disabled", b) }, e.prototype.data = function () { this.options.get("debug") && arguments.length > 0 && window.console && console.warn && console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.'); var a = []; return this.dataAdapter.current(function (b) { a = b }), a }, e.prototype.val = function (b) { if (this.options.get("debug") && window.console && console.warn && console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'), null == b || 0 === b.length) return this.$element.val(); var c = b[0]; a.isArray(c) && (c = a.map(c, function (a) { return a.toString() })), this.$element.val(c).trigger("change") }, e.prototype.destroy = function () { this.$container.remove(), this.$element[0].detachEvent && this.$element[0].detachEvent("onpropertychange", this._syncA), null != this._observer ? (this._observer.disconnect(), this._observer = null) : this.$element[0].removeEventListener && (this.$element[0].removeEventListener("DOMAttrModified", this._syncA, !1), this.$element[0].removeEventListener("DOMNodeInserted", this._syncS, !1), this.$element[0].removeEventListener("DOMNodeRemoved", this._syncS, !1)), this._syncA = null, this._syncS = null, this.$element.off(".select2"), this.$element.attr("tabindex", c.GetData(this.$element[0], "old-tabindex")), this.$element.removeClass("select2-hidden-accessible"), this.$element.attr("aria-hidden", "false"), c.RemoveData(this.$element[0]), this.$element.removeData("select2"), this.dataAdapter.destroy(), this.selection.destroy(), this.dropdown.destroy(), this.results.destroy(), this.dataAdapter = null, this.selection = null, this.dropdown = null, this.results = null }, e.prototype.render = function () { var b = a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>'); return b.attr("dir", this.options.get("dir")), this.$container = b, this.$container.addClass("select2-container--" + this.options.get("theme")), c.StoreData(b[0], "element", this.$element), b }, e }), b.define("select2/compat/utils", ["jquery"], function (a) { function b(b, c, d) { var e, f, g = []; e = a.trim(b.attr("class")), e && (e = "" + e, a(e.split(/\s+/)).each(function () { 0 === this.indexOf("select2-") && g.push(this) })), e = a.trim(c.attr("class")), e && (e = "" + e, a(e.split(/\s+/)).each(function () { 0 !== this.indexOf("select2-") && null != (f = d(this)) && g.push(f) })), b.attr("class", g.join(" ")) } return { syncCssClasses: b } }), b.define("select2/compat/containerCss", ["jquery", "./utils"], function (a, b) { function c(a) { return null } function d() { } return d.prototype.render = function (d) { var e = d.call(this), f = this.options.get("containerCssClass") || ""; a.isFunction(f) && (f = f(this.$element)); var g = this.options.get("adaptContainerCssClass"); if (g = g || c, -1 !== f.indexOf(":all:")) { f = f.replace(":all:", ""); var h = g; g = function (a) { var b = h(a); return null != b ? b + " " + a : a } } var i = this.options.get("containerCss") || {}; return a.isFunction(i) && (i = i(this.$element)), b.syncCssClasses(e, this.$element, g), e.css(i), e.addClass(f), e }, d }), b.define("select2/compat/dropdownCss", ["jquery", "./utils"], function (a, b) { function c(a) { return null } function d() { } return d.prototype.render = function (d) { var e = d.call(this), f = this.options.get("dropdownCssClass") || ""; a.isFunction(f) && (f = f(this.$element)); var g = this.options.get("adaptDropdownCssClass"); if (g = g || c, -1 !== f.indexOf(":all:")) { f = f.replace(":all:", ""); var h = g; g = function (a) { var b = h(a); return null != b ? b + " " + a : a } } var i = this.options.get("dropdownCss") || {}; return a.isFunction(i) && (i = i(this.$element)), b.syncCssClasses(e, this.$element, g), e.css(i), e.addClass(f), e }, d }), b.define("select2/compat/initSelection", ["jquery"], function (a) { function b(a, b, c) { c.get("debug") && window.console && console.warn && console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"), this.initSelection = c.get("initSelection"), this._isInitialized = !1, a.call(this, b, c) } return b.prototype.current = function (b, c) { var d = this; if (this._isInitialized) return void b.call(this, c); this.initSelection.call(null, this.$element, function (b) { d._isInitialized = !0, a.isArray(b) || (b = [b]), c(b) }) }, b }), b.define("select2/compat/inputData", ["jquery", "../utils"], function (a, b) { function c(a, b, c) { this._currentData = [], this._valueSeparator = c.get("valueSeparator") || ",", "hidden" === b.prop("type") && c.get("debug") && console && console.warn && console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."), a.call(this, b, c) } return c.prototype.current = function (b, c) { function d(b, c) { var e = []; return b.selected || -1 !== a.inArray(b.id, c) ? (b.selected = !0, e.push(b)) : b.selected = !1, b.children && e.push.apply(e, d(b.children, c)), e } for (var e = [], f = 0; f < this._currentData.length; f++) { var g = this._currentData[f]; e.push.apply(e, d(g, this.$element.val().split(this._valueSeparator))) } c(e) }, c.prototype.select = function (b, c) { if (this.options.get("multiple")) { var d = this.$element.val(); d += this._valueSeparator + c.id, this.$element.val(d), this.$element.trigger("change") } else this.current(function (b) { a.map(b, function (a) { a.selected = !1 }) }), this.$element.val(c.id), this.$element.trigger("change") }, c.prototype.unselect = function (a, b) { var c = this; b.selected = !1, this.current(function (a) { for (var d = [], e = 0; e < a.length; e++) { var f = a[e]; b.id != f.id && d.push(f.id) } c.$element.val(d.join(c._valueSeparator)), c.$element.trigger("change") }) }, c.prototype.query = function (a, b, c) { for (var d = [], e = 0; e < this._currentData.length; e++) { var f = this._currentData[e], g = this.matches(b, f); null !== g && d.push(g) } c({ results: d }) }, c.prototype.addOptions = function (c, d) { var e = a.map(d, function (a) { return b.GetData(a[0], "data") }); this._currentData.push.apply(this._currentData, e) }, c }), b.define("select2/compat/matcher", ["jquery"], function (a) { function b(b) { function c(c, d) { var e = a.extend(!0, {}, d); if (null == c.term || "" === a.trim(c.term)) return e; if (d.children) { for (var f = d.children.length - 1; f >= 0; f--) { var g = d.children[f]; b(c.term, g.text, g) || e.children.splice(f, 1) } if (e.children.length > 0) return e } return b(c.term, d.text, d) ? e : null } return c } return b }), b.define("select2/compat/query", [], function () { function a(a, b, c) { c.get("debug") && window.console && console.warn && console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."), a.call(this, b, c) } return a.prototype.query = function (a, b, c) { b.callback = c, this.options.get("query").call(null, b) }, a }), b.define("select2/dropdown/attachContainer", [], function () { function a(a, b, c) { a.call(this, b, c) } return a.prototype.position = function (a, b, c) { c.find(".dropdown-wrapper").append(b), b.addClass("select2-dropdown--below"), c.addClass("select2-container--below") }, a }), b.define("select2/dropdown/stopPropagation", [], function () { function a() { } return a.prototype.bind = function (a, b, c) { a.call(this, b, c); var d = ["blur", "change", "click", "dblclick", "focus", "focusin", "focusout", "input", "keydown", "keyup", "keypress", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseover", "mouseup", "search", "touchend", "touchstart"]; this.$dropdown.on(d.join(" "), function (a) { a.stopPropagation() }) }, a }), b.define("select2/selection/stopPropagation", [], function () { function a() { } return a.prototype.bind = function (a, b, c) { a.call(this, b, c); var d = ["blur", "change", "click", "dblclick", "focus", "focusin", "focusout", "input", "keydown", "keyup", "keypress", "mousedown", "mouseenter", "mouseleave", "mousemove", "mouseover", "mouseup", "search", "touchend", "touchstart"]; this.$selection.on(d.join(" "), function (a) { a.stopPropagation() }) }, a }), function (c) { "function" == typeof b.define && b.define.amd ? b.define("jquery-mousewheel", ["jquery"], c) : "object" == typeof exports ? module.exports = c : c(a) }(function (a) { function b(b) { var g = b || window.event, h = i.call(arguments, 1), j = 0, l = 0, m = 0, n = 0, o = 0, p = 0; if (b = a.event.fix(g), b.type = "mousewheel", "detail" in g && (m = -1 * g.detail), "wheelDelta" in g && (m = g.wheelDelta), "wheelDeltaY" in g && (m = g.wheelDeltaY), "wheelDeltaX" in g && (l = -1 * g.wheelDeltaX), "axis" in g && g.axis === g.HORIZONTAL_AXIS && (l = -1 * m, m = 0), j = 0 === m ? l : m, "deltaY" in g && (m = -1 * g.deltaY, j = m), "deltaX" in g && (l = g.deltaX, 0 === m && (j = -1 * l)), 0 !== m || 0 !== l) { if (1 === g.deltaMode) { var q = a.data(this, "mousewheel-line-height"); j *= q, m *= q, l *= q } else if (2 === g.deltaMode) { var r = a.data(this, "mousewheel-page-height"); j *= r, m *= r, l *= r } if (n = Math.max(Math.abs(m), Math.abs(l)), (!f || n < f) && (f = n, d(g, n) && (f /= 40)), d(g, n) && (j /= 40, l /= 40, m /= 40), j = Math[j >= 1 ? "floor" : "ceil"](j / f), l = Math[l >= 1 ? "floor" : "ceil"](l / f), m = Math[m >= 1 ? "floor" : "ceil"](m / f), k.settings.normalizeOffset && this.getBoundingClientRect) { var s = this.getBoundingClientRect(); o = b.clientX - s.left, p = b.clientY - s.top } return b.deltaX = l, b.deltaY = m, b.deltaFactor = f, b.offsetX = o, b.offsetY = p, b.deltaMode = 0, h.unshift(b, j, l, m), e && clearTimeout(e), e = setTimeout(c, 200), (a.event.dispatch || a.event.handle).apply(this, h) } } function c() { f = null } function d(a, b) { return k.settings.adjustOldDeltas && "mousewheel" === a.type && b % 120 == 0 } var e, f, g = ["wheel", "mousewheel", "DOMMouseScroll", "MozMousePixelScroll"], h = "onwheel" in document || document.documentMode >= 9 ? ["wheel"] : ["mousewheel", "DomMouseScroll", "MozMousePixelScroll"], i = Array.prototype.slice; if (a.event.fixHooks) for (var j = g.length; j;)a.event.fixHooks[g[--j]] = a.event.mouseHooks; var k = a.event.special.mousewheel = { version: "3.1.12", setup: function () { if (this.addEventListener) for (var c = h.length; c;)this.addEventListener(h[--c], b, !1); else this.onmousewheel = b; a.data(this, "mousewheel-line-height", k.getLineHeight(this)), a.data(this, "mousewheel-page-height", k.getPageHeight(this)) }, teardown: function () { if (this.removeEventListener) for (var c = h.length; c;)this.removeEventListener(h[--c], b, !1); else this.onmousewheel = null; a.removeData(this, "mousewheel-line-height"), a.removeData(this, "mousewheel-page-height") }, getLineHeight: function (b) { var c = a(b), d = c["offsetParent" in a.fn ? "offsetParent" : "parent"](); return d.length || (d = a("body")), parseInt(d.css("fontSize"), 10) || parseInt(c.css("fontSize"), 10) || 16 }, getPageHeight: function (b) { return a(b).height() }, settings: { adjustOldDeltas: !0, normalizeOffset: !0 } }; a.fn.extend({ mousewheel: function (a) { return a ? this.bind("mousewheel", a) : this.trigger("mousewheel") }, unmousewheel: function (a) { return this.unbind("mousewheel", a) } }) }), b.define("jquery.select2", ["jquery", "jquery-mousewheel", "./select2/core", "./select2/defaults", "./select2/utils"], function (a, b, c, d, e) { if (null == a.fn.select2) { var f = ["open", "close", "destroy"]; a.fn.select2 = function (b) { if ("object" == typeof (b = b || {})) return this.each(function () { var d = a.extend(!0, {}, b); new c(a(this), d) }), this; if ("string" == typeof b) { var d, g = Array.prototype.slice.call(arguments, 1); return this.each(function () { var a = e.GetData(this, "select2"); null == a && window.console && console.error && console.error("The select2('" + b + "') method was called on an element that is not using Select2."), d = a[b].apply(a, g) }), a.inArray(b, f) > -1 ? this : d } throw new Error("Invalid arguments for Select2: " + b) } } return null == a.fn.select2.defaults && (a.fn.select2.defaults = d), c }), { define: b.define, require: b.require } }(), c = b.require("jquery.select2"); return a.fn.select2.amd = b, c });




/**
 * sifter.js
 * Copyright (c) 2013 Brian Reavis & contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @author Brian Reavis <brian@thirdroute.com>
 */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define('sifter', factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.Sifter = factory();
    }
}(this, function () {

	/**
	 * Textually searches arrays and hashes of objects
	 * by property (or multiple properties). Designed
	 * specifically for autocomplete.
	 *
	 * @constructor
	 * @param {array|object} items
	 * @param {object} items
	 */
    var Sifter = function (items, settings) {
        this.items = items;
        this.settings = settings || { diacritics: true };
    };

	/**
	 * Splits a search string into an array of individual
	 * regexps to be used to match results.
	 *
	 * @param {string} query
	 * @returns {array}
	 */
    Sifter.prototype.tokenize = function (query) {
        query = trim(String(query || '').toLowerCase());
        if (!query || !query.length) return [];

        var i, n, regex, letter;
        var tokens = [];
        var words = query.split(/ +/);

        for (i = 0, n = words.length; i < n; i++) {
            regex = escape_regex(words[i]);
            if (this.settings.diacritics) {
                for (letter in DIACRITICS) {
                    if (DIACRITICS.hasOwnProperty(letter)) {
                        regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]);
                    }
                }
            }
            tokens.push({
                string: words[i],
                regex: new RegExp(regex, 'i')
            });
        }

        return tokens;
    };

	/**
	 * Iterates over arrays and hashes.
	 *
	 * ```
	 * this.iterator(this.items, function(item, id) {
	 *    // invoked for each item
	 * });
	 * ```
	 *
	 * @param {array|object} object
	 */
    Sifter.prototype.iterator = function (object, callback) {
        var iterator;
        if (is_array(object)) {
            iterator = Array.prototype.forEach || function (callback) {
                for (var i = 0, n = this.length; i < n; i++) {
                    callback(this[i], i, this);
                }
            };
        } else {
            iterator = function (callback) {
                for (var key in this) {
                    if (this.hasOwnProperty(key)) {
                        callback(this[key], key, this);
                    }
                }
            };
        }

        iterator.apply(object, [callback]);
    };

	/**
	 * Returns a function to be used to score individual results.
	 *
	 * Good matches will have a higher score than poor matches.
	 * If an item is not a match, 0 will be returned by the function.
	 *
	 * @param {object|string} search
	 * @param {object} options (optional)
	 * @returns {function}
	 */
    Sifter.prototype.getScoreFunction = function (search, options) {
        var self, fields, tokens, token_count, nesting;

        self = this;
        search = self.prepareSearch(search, options);
        tokens = search.tokens;
        fields = search.options.fields;
        token_count = tokens.length;
        nesting = search.options.nesting;

		/**
		 * Calculates how close of a match the
		 * given value is against a search token.
		 *
		 * @param {mixed} value
		 * @param {object} token
		 * @return {number}
		 */
        var scoreValue = function (value, token) {
            var score, pos;

            if (!value) return 0;
            value = String(value || '');
            pos = value.search(token.regex);
            if (pos === -1) return 0;
            score = token.string.length / value.length;
            if (pos === 0) score += 0.5;
            return score;
        };

		/**
		 * Calculates the score of an object
		 * against the search query.
		 *
		 * @param {object} token
		 * @param {object} data
		 * @return {number}
		 */
        var scoreObject = (function () {
            var field_count = fields.length;
            if (!field_count) {
                return function () { return 0; };
            }
            if (field_count === 1) {
                return function (token, data) {
                    return scoreValue(getattr(data, fields[0], nesting), token);
                };
            }
            return function (token, data) {
                for (var i = 0, sum = 0; i < field_count; i++) {
                    sum += scoreValue(getattr(data, fields[i], nesting), token);
                }
                return sum / field_count;
            };
        })();

        if (!token_count) {
            return function () { return 0; };
        }
        if (token_count === 1) {
            return function (data) {
                return scoreObject(tokens[0], data);
            };
        }

        if (search.options.conjunction === 'and') {
            return function (data) {
                var score;
                for (var i = 0, sum = 0; i < token_count; i++) {
                    score = scoreObject(tokens[i], data);
                    if (score <= 0) return 0;
                    sum += score;
                }
                return sum / token_count;
            };
        } else {
            return function (data) {
                for (var i = 0, sum = 0; i < token_count; i++) {
                    sum += scoreObject(tokens[i], data);
                }
                return sum / token_count;
            };
        }
    };

	/**
	 * Returns a function that can be used to compare two
	 * results, for sorting purposes. If no sorting should
	 * be performed, `null` will be returned.
	 *
	 * @param {string|object} search
	 * @param {object} options
	 * @return function(a,b)
	 */
    Sifter.prototype.getSortFunction = function (search, options) {
        var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort;

        self = this;
        search = self.prepareSearch(search, options);
        sort = (!search.query && options.sort_empty) || options.sort;

		/**
		 * Fetches the specified sort field value
		 * from a search result item.
		 *
		 * @param  {string} name
		 * @param  {object} result
		 * @return {mixed}
		 */
        get_field = function (name, result) {
            if (name === '$score') return result.score;
            return getattr(self.items[result.id], name, options.nesting);
        };

        // parse options
        fields = [];
        if (sort) {
            for (i = 0, n = sort.length; i < n; i++) {
                if (search.query || sort[i].field !== '$score') {
                    fields.push(sort[i]);
                }
            }
        }

        // the "$score" field is implied to be the primary
        // sort field, unless it's manually specified
        if (search.query) {
            implicit_score = true;
            for (i = 0, n = fields.length; i < n; i++) {
                if (fields[i].field === '$score') {
                    implicit_score = false;
                    break;
                }
            }
            if (implicit_score) {
                fields.unshift({ field: '$score', direction: 'desc' });
            }
        } else {
            for (i = 0, n = fields.length; i < n; i++) {
                if (fields[i].field === '$score') {
                    fields.splice(i, 1);
                    break;
                }
            }
        }

        multipliers = [];
        for (i = 0, n = fields.length; i < n; i++) {
            multipliers.push(fields[i].direction === 'desc' ? -1 : 1);
        }

        // build function
        fields_count = fields.length;
        if (!fields_count) {
            return null;
        } else if (fields_count === 1) {
            field = fields[0].field;
            multiplier = multipliers[0];
            return function (a, b) {
                return multiplier * cmp(
                    get_field(field, a),
                    get_field(field, b)
                );
            };
        } else {
            return function (a, b) {
                var i, result, a_value, b_value, field;
                for (i = 0; i < fields_count; i++) {
                    field = fields[i].field;
                    result = multipliers[i] * cmp(
                        get_field(field, a),
                        get_field(field, b)
                    );
                    if (result) return result;
                }
                return 0;
            };
        }
    };

	/**
	 * Parses a search query and returns an object
	 * with tokens and fields ready to be populated
	 * with results.
	 *
	 * @param {string} query
	 * @param {object} options
	 * @returns {object}
	 */
    Sifter.prototype.prepareSearch = function (query, options) {
        if (typeof query === 'object') return query;

        options = extend({}, options);

        var option_fields = options.fields;
        var option_sort = options.sort;
        var option_sort_empty = options.sort_empty;

        if (option_fields && !is_array(option_fields)) options.fields = [option_fields];
        if (option_sort && !is_array(option_sort)) options.sort = [option_sort];
        if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty];

        return {
            options: options,
            query: String(query || '').toLowerCase(),
            tokens: this.tokenize(query),
            total: 0,
            items: []
        };
    };

	/**
	 * Searches through all items and returns a sorted array of matches.
	 *
	 * The `options` parameter can contain:
	 *
	 *   - fields {string|array}
	 *   - sort {array}
	 *   - score {function}
	 *   - filter {bool}
	 *   - limit {integer}
	 *
	 * Returns an object containing:
	 *
	 *   - options {object}
	 *   - query {string}
	 *   - tokens {array}
	 *   - total {int}
	 *   - items {array}
	 *
	 * @param {string} query
	 * @param {object} options
	 * @returns {object}
	 */
    Sifter.prototype.search = function (query, options) {
        var self = this, value, score, search, calculateScore;
        var fn_sort;
        var fn_score;

        search = this.prepareSearch(query, options);
        options = search.options;
        query = search.query;

        // generate result scoring function
        fn_score = options.score || self.getScoreFunction(search);

        // perform search and sort
        if (query.length) {
            self.iterator(self.items, function (item, id) {
                score = fn_score(item);
                if (options.filter === false || score > 0) {
                    search.items.push({ 'score': score, 'id': id });
                }
            });
        } else {
            self.iterator(self.items, function (item, id) {
                search.items.push({ 'score': 1, 'id': id });
            });
        }

        fn_sort = self.getSortFunction(search, options);
        if (fn_sort) search.items.sort(fn_sort);

        // apply limits
        search.total = search.items.length;
        if (typeof options.limit === 'number') {
            search.items = search.items.slice(0, options.limit);
        }

        return search;
    };

    // utilities
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    var cmp = function (a, b) {
        if (typeof a === 'number' && typeof b === 'number') {
            return a > b ? 1 : (a < b ? -1 : 0);
        }
        a = asciifold(String(a || ''));
        b = asciifold(String(b || ''));
        if (a > b) return 1;
        if (b > a) return -1;
        return 0;
    };

    var extend = function (a, b) {
        var i, n, k, object;
        for (i = 1, n = arguments.length; i < n; i++) {
            object = arguments[i];
            if (!object) continue;
            for (k in object) {
                if (object.hasOwnProperty(k)) {
                    a[k] = object[k];
                }
            }
        }
        return a;
    };

	/**
	 * A property getter resolving dot-notation
	 * @param  {Object}  obj     The root object to fetch property on
	 * @param  {String}  name    The optionally dotted property name to fetch
	 * @param  {Boolean} nesting Handle nesting or not
	 * @return {Object}          The resolved property value
	 */
    var getattr = function (obj, name, nesting) {
        if (!obj || !name) return;
        if (!nesting) return obj[name];
        var names = name.split(".");
        while (names.length && (obj = obj[names.shift()]));
        return obj;
    };

    var trim = function (str) {
        return (str + '').replace(/^\s+|\s+$|/g, '');
    };

    var escape_regex = function (str) {
        return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
    };

    var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function (object) {
        return Object.prototype.toString.call(object) === '[object Array]';
    };

    var DIACRITICS = {
        'a': '[aḀḁĂăÂâǍǎȺⱥȦȧẠạÄäÀàÁáĀāÃãÅåąĄÃąĄ]',
        'b': '[b␢βΒB฿𐌁ᛒ]',
        'c': '[cĆćĈĉČčĊċC̄c̄ÇçḈḉȻȼƇƈɕᴄＣｃ]',
        'd': '[dĎďḊḋḐḑḌḍḒḓḎḏĐđD̦d̦ƉɖƊɗƋƌᵭᶁᶑȡᴅＤｄð]',
        'e': '[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀềỄễỂểḜḝḖḗḔḕȆȇẸẹỆệⱸᴇＥｅɘǝƏƐε]',
        'f': '[fƑƒḞḟ]',
        'g': '[gɢ₲ǤǥĜĝĞğĢģƓɠĠġ]',
        'h': '[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]',
        'i': '[iÍíÌìĬĭÎîǏǐÏïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪＩｉ]',
        'j': '[jȷĴĵɈɉʝɟʲ]',
        'k': '[kƘƙꝀꝁḰḱǨǩḲḳḴḵκϰ₭]',
        'l': '[lŁłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟＬｌ]',
        'n': '[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲȠƞᵰᶇɳȵɴＮｎŊŋ]',
        'o': '[oØøÖöÓóÒòÔôǑǒŐőŎŏȮȯỌọƟɵƠơỎỏŌōÕõǪǫȌȍՕօ]',
        'p': '[pṔṕṖṗⱣᵽƤƥᵱ]',
        'q': '[qꝖꝗʠɊɋꝘꝙq̃]',
        'r': '[rŔŕɌɍŘřŖŗṘṙȐȑȒȓṚṛⱤɽ]',
        's': '[sŚśṠṡṢṣꞨꞩŜŝŠšŞşȘșS̈s̈]',
        't': '[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]',
        'u': '[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]',
        'v': '[vṼṽṾṿƲʋꝞꝟⱱʋ]',
        'w': '[wẂẃẀẁŴŵẄẅẆẇẈẉ]',
        'x': '[xẌẍẊẋχ]',
        'y': '[yÝýỲỳŶŷŸÿỸỹẎẏỴỵɎɏƳƴ]',
        'z': '[zŹźẐẑŽžŻżẒẓẔẕƵƶ]'
    };

    var asciifold = (function () {
        var i, n, k, chunk;
        var foreignletters = '';
        var lookup = {};
        for (k in DIACRITICS) {
            if (DIACRITICS.hasOwnProperty(k)) {
                chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1);
                foreignletters += chunk;
                for (i = 0, n = chunk.length; i < n; i++) {
                    lookup[chunk.charAt(i)] = k;
                }
            }
        }
        var regexp = new RegExp('[' + foreignletters + ']', 'g');
        return function (str) {
            return str.replace(regexp, function (foreignletter) {
                return lookup[foreignletter];
            }).toLowerCase();
        };
    })();


    // export
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    return Sifter;
}));



/**
 * microplugin.js
 * Copyright (c) 2013 Brian Reavis & contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @author Brian Reavis <brian@thirdroute.com>
 */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define('microplugin', factory);
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.MicroPlugin = factory();
    }
}(this, function () {
    var MicroPlugin = {};

    MicroPlugin.mixin = function (Interface) {
        Interface.plugins = {};

		/**
		 * Initializes the listed plugins (with options).
		 * Acceptable formats:
		 *
		 * List (without options):
		 *   ['a', 'b', 'c']
		 *
		 * List (with options):
		 *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
		 *
		 * Hash (with options):
		 *   {'a': { ... }, 'b': { ... }, 'c': { ... }}
		 *
		 * @param {mixed} plugins
		 */
        Interface.prototype.initializePlugins = function (plugins) {
            var i, n, key;
            var self = this;
            var queue = [];

            self.plugins = {
                names: [],
                settings: {},
                requested: {},
                loaded: {}
            };

            if (utils.isArray(plugins)) {
                for (i = 0, n = plugins.length; i < n; i++) {
                    if (typeof plugins[i] === 'string') {
                        queue.push(plugins[i]);
                    } else {
                        self.plugins.settings[plugins[i].name] = plugins[i].options;
                        queue.push(plugins[i].name);
                    }
                }
            } else if (plugins) {
                for (key in plugins) {
                    if (plugins.hasOwnProperty(key)) {
                        self.plugins.settings[key] = plugins[key];
                        queue.push(key);
                    }
                }
            }

            while (queue.length) {
                self.require(queue.shift());
            }
        };

        Interface.prototype.loadPlugin = function (name) {
            var self = this;
            var plugins = self.plugins;
            var plugin = Interface.plugins[name];

            if (!Interface.plugins.hasOwnProperty(name)) {
                throw new Error('Unable to find "' + name + '" plugin');
            }

            plugins.requested[name] = true;
            plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
            plugins.names.push(name);
        };

		/**
		 * Initializes a plugin.
		 *
		 * @param {string} name
		 */
        Interface.prototype.require = function (name) {
            var self = this;
            var plugins = self.plugins;

            if (!self.plugins.loaded.hasOwnProperty(name)) {
                if (plugins.requested[name]) {
                    throw new Error('Plugin has circular dependency ("' + name + '")');
                }
                self.loadPlugin(name);
            }

            return plugins.loaded[name];
        };

		/**
		 * Registers a plugin.
		 *
		 * @param {string} name
		 * @param {function} fn
		 */
        Interface.define = function (name, fn) {
            Interface.plugins[name] = {
                'name': name,
                'fn': fn
            };
        };
    };

    var utils = {
        isArray: Array.isArray || function (vArg) {
            return Object.prototype.toString.call(vArg) === '[object Array]';
        }
    };

    return MicroPlugin;
}));

/**
 * selectize.js (v0.12.6)
 * Copyright (c) 2013–2015 Brian Reavis & contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @author Brian Reavis <brian@thirdroute.com>
 */

/*jshint curly:false */
/*jshint browser:true */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define('selectize', ['jquery', 'sifter', 'microplugin'], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory(require('jquery'), require('sifter'), require('microplugin'));
    } else {
        root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin);
    }
}(this, function ($, Sifter, MicroPlugin) {
    'use strict';

    var highlight = function ($element, pattern) {
        if (typeof pattern === 'string' && !pattern.length) return;
        var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern;

        var highlight = function (node) {
            var skip = 0;
            // Wrap matching part of text node with highlighting <span>, e.g.
            // Soccer  ->  <span class="highlight">Soc</span>cer  for regex = /soc/i
            if (node.nodeType === 3) {
                var pos = node.data.search(regex);
                if (pos >= 0 && node.data.length > 0) {
                    var match = node.data.match(regex);
                    var spannode = document.createElement('span');
                    spannode.className = 'highlight';
                    var middlebit = node.splitText(pos);
                    var endbit = middlebit.splitText(match[0].length);
                    var middleclone = middlebit.cloneNode(true);
                    spannode.appendChild(middleclone);
                    middlebit.parentNode.replaceChild(spannode, middlebit);
                    skip = 1;
                }
            }
            // Recurse element node, looking for child text nodes to highlight, unless element 
            // is childless, <script>, <style>, or already highlighted: <span class="hightlight">
            else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {
                for (var i = 0; i < node.childNodes.length; ++i) {
                    i += highlight(node.childNodes[i]);
                }
            }
            return skip;
        };

        return $element.each(function () {
            highlight(this);
        });
    };

	/**
	 * removeHighlight fn copied from highlight v5 and
	 * edited to remove with() and pass js strict mode
	 */
    $.fn.removeHighlight = function () {
        return this.find("span.highlight").each(function () {
            this.parentNode.firstChild.nodeName;
            var parent = this.parentNode;
            parent.replaceChild(this.firstChild, this);
            parent.normalize();
        }).end();
    };


    var MicroEvent = function () { };
    MicroEvent.prototype = {
        on: function (event, fct) {
            this._events = this._events || {};
            this._events[event] = this._events[event] || [];
            this._events[event].push(fct);
        },
        off: function (event, fct) {
            var n = arguments.length;
            if (n === 0) return delete this._events;
            if (n === 1) return delete this._events[event];

            this._events = this._events || {};
            if (event in this._events === false) return;
            this._events[event].splice(this._events[event].indexOf(fct), 1);
        },
        trigger: function (event /* , args... */) {
            this._events = this._events || {};
            if (event in this._events === false) return;
            for (var i = 0; i < this._events[event].length; i++) {
                this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
            }
        }
    };

	/**
	 * Mixin will delegate all MicroEvent.js function in the destination object.
	 *
	 * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent
	 *
	 * @param {object} the object which will support MicroEvent
	 */
    MicroEvent.mixin = function (destObject) {
        var props = ['on', 'off', 'trigger'];
        for (var i = 0; i < props.length; i++) {
            destObject.prototype[props[i]] = MicroEvent.prototype[props[i]];
        }
    };

    var IS_MAC = /Mac/.test(navigator.userAgent);

    var KEY_A = 65;
    var KEY_COMMA = 188;
    var KEY_RETURN = 13;
    var KEY_ESC = 27;
    var KEY_LEFT = 37;
    var KEY_UP = 38;
    var KEY_P = 80;
    var KEY_RIGHT = 39;
    var KEY_DOWN = 40;
    var KEY_N = 78;
    var KEY_BACKSPACE = 8;
    var KEY_DELETE = 46;
    var KEY_SHIFT = 16;
    var KEY_CMD = IS_MAC ? 91 : 17;
    var KEY_CTRL = IS_MAC ? 18 : 17;
    var KEY_TAB = 9;

    var TAG_SELECT = 1;
    var TAG_INPUT = 2;

    // for now, android support in general is too spotty to support validity
    var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity;


    var isset = function (object) {
        return typeof object !== 'undefined';
    };

	/**
	 * Converts a scalar to its best string representation
	 * for hash keys and HTML attribute values.
	 *
	 * Transformations:
	 *   'str'     -> 'str'
	 *   null      -> ''
	 *   undefined -> ''
	 *   true      -> '1'
	 *   false     -> '0'
	 *   0         -> '0'
	 *   1         -> '1'
	 *
	 * @param {string} value
	 * @returns {string|null}
	 */
    var hash_key = function (value) {
        if (typeof value === 'undefined' || value === null) return null;
        if (typeof value === 'boolean') return value ? '1' : '0';
        return value + '';
    };

	/**
	 * Escapes a string for use within HTML.
	 *
	 * @param {string} str
	 * @returns {string}
	 */
    var escape_html = function (str) {
        return (str + '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;');
    };

	/**
	 * Escapes "$" characters in replacement strings.
	 *
	 * @param {string} str
	 * @returns {string}
	 */
    var escape_replace = function (str) {
        return (str + '').replace(/\$/g, '$$$$');
    };

    var hook = {};

	/**
	 * Wraps `method` on `self` so that `fn`
	 * is invoked before the original method.
	 *
	 * @param {object} self
	 * @param {string} method
	 * @param {function} fn
	 */
    hook.before = function (self, method, fn) {
        var original = self[method];
        self[method] = function () {
            fn.apply(self, arguments);
            return original.apply(self, arguments);
        };
    };

	/**
	 * Wraps `method` on `self` so that `fn`
	 * is invoked after the original method.
	 *
	 * @param {object} self
	 * @param {string} method
	 * @param {function} fn
	 */
    hook.after = function (self, method, fn) {
        var original = self[method];
        self[method] = function () {
            var result = original.apply(self, arguments);
            fn.apply(self, arguments);
            return result;
        };
    };

	/**
	 * Wraps `fn` so that it can only be invoked once.
	 *
	 * @param {function} fn
	 * @returns {function}
	 */
    var once = function (fn) {
        var called = false;
        return function () {
            if (called) return;
            called = true;
            fn.apply(this, arguments);
        };
    };

	/**
	 * Wraps `fn` so that it can only be called once
	 * every `delay` milliseconds (invoked on the falling edge).
	 *
	 * @param {function} fn
	 * @param {int} delay
	 * @returns {function}
	 */
    var debounce = function (fn, delay) {
        var timeout;
        return function () {
            var self = this;
            var args = arguments;
            window.clearTimeout(timeout);
            timeout = window.setTimeout(function () {
                fn.apply(self, args);
            }, delay);
        };
    };

	/**
	 * Debounce all fired events types listed in `types`
	 * while executing the provided `fn`.
	 *
	 * @param {object} self
	 * @param {array} types
	 * @param {function} fn
	 */
    var debounce_events = function (self, types, fn) {
        var type;
        var trigger = self.trigger;
        var event_args = {};

        // override trigger method
        self.trigger = function () {
            var type = arguments[0];
            if (types.indexOf(type) !== -1) {
                event_args[type] = arguments;
            } else {
                return trigger.apply(self, arguments);
            }
        };

        // invoke provided function
        fn.apply(self, []);
        self.trigger = trigger;

        // trigger queued events
        for (type in event_args) {
            if (event_args.hasOwnProperty(type)) {
                trigger.apply(self, event_args[type]);
            }
        }
    };

	/**
	 * A workaround for http://bugs.jquery.com/ticket/6696
	 *
	 * @param {object} $parent - Parent element to listen on.
	 * @param {string} event - Event name.
	 * @param {string} selector - Descendant selector to filter by.
	 * @param {function} fn - Event handler.
	 */
    var watchChildEvent = function ($parent, event, selector, fn) {
        $parent.on(event, selector, function (e) {
            var child = e.target;
            while (child && child.parentNode !== $parent[0]) {
                child = child.parentNode;
            }
            e.currentTarget = child;
            return fn.apply(this, [e]);
        });
    };

	/**
	 * Determines the current selection within a text input control.
	 * Returns an object containing:
	 *   - start
	 *   - length
	 *
	 * @param {object} input
	 * @returns {object}
	 */
    var getSelection = function (input) {
        var result = {};
        if ('selectionStart' in input) {
            result.start = input.selectionStart;
            result.length = input.selectionEnd - result.start;
        } else if (document.selection) {
            input.focus();
            var sel = document.selection.createRange();
            var selLen = document.selection.createRange().text.length;
            sel.moveStart('character', -input.value.length);
            result.start = sel.text.length - selLen;
            result.length = selLen;
        }
        return result;
    };

	/**
	 * Copies CSS properties from one element to another.
	 *
	 * @param {object} $from
	 * @param {object} $to
	 * @param {array} properties
	 */
    var transferStyles = function ($from, $to, properties) {
        var i, n, styles = {};
        if (properties) {
            for (i = 0, n = properties.length; i < n; i++) {
                styles[properties[i]] = $from.css(properties[i]);
            }
        } else {
            styles = $from.css();
        }
        $to.css(styles);
    };

	/**
	 * Measures the width of a string within a
	 * parent element (in pixels).
	 *
	 * @param {string} str
	 * @param {object} $parent
	 * @returns {int}
	 */
    var measureString = function (str, $parent) {
        if (!str) {
            return 0;
        }

        if (!Selectize.$testInput) {
            Selectize.$testInput = $('<span />').css({
                position: 'absolute',
                top: -99999,
                left: -99999,
                width: 'auto',
                padding: 0,
                whiteSpace: 'pre'
            }).appendTo('body');
        }

        Selectize.$testInput.text(str);

        transferStyles($parent, Selectize.$testInput, [
            'letterSpacing',
            'fontSize',
            'fontFamily',
            'fontWeight',
            'textTransform'
        ]);

        return Selectize.$testInput.width();
    };

	/**
	 * Sets up an input to grow horizontally as the user
	 * types. If the value is changed manually, you can
	 * trigger the "update" handler to resize:
	 *
	 * $input.trigger('update');
	 *
	 * @param {object} $input
	 */
    var autoGrow = function ($input) {
        var currentWidth = null;

        var update = function (e, options) {
            var value, keyCode, printable, placeholder, width;
            var shift, character, selection;
            e = e || window.event || {};
            options = options || {};

            if (e.metaKey || e.altKey) return;
            if (!options.force && $input.data('grow') === false) return;

            value = $input.val();
            if (e.type && e.type.toLowerCase() === 'keydown') {
                keyCode = e.keyCode;
                printable = (
                    (keyCode >= 48 && keyCode <= 57) || // 0-9
                    (keyCode >= 65 && keyCode <= 90) || // a-z
                    (keyCode >= 96 && keyCode <= 111) || // numpad 0-9, numeric operators
                    (keyCode >= 186 && keyCode <= 222) || // semicolon, equal, comma, dash, etc.
                    keyCode === 32 // space
                );

                if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) {
                    selection = getSelection($input[0]);
                    if (selection.length) {
                        value = value.substring(0, selection.start) + value.substring(selection.start + selection.length);
                    } else if (keyCode === KEY_BACKSPACE && selection.start) {
                        value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1);
                    } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') {
                        value = value.substring(0, selection.start) + value.substring(selection.start + 1);
                    }
                } else if (printable) {
                    shift = e.shiftKey;
                    character = String.fromCharCode(e.keyCode);
                    if (shift) character = character.toUpperCase();
                    else character = character.toLowerCase();
                    value += character;
                }
            }

            placeholder = $input.attr('placeholder');
            if (!value && placeholder) {
                value = placeholder;
            }

            width = measureString(value, $input) + 4;
            if (width !== currentWidth) {
                currentWidth = width;
                $input.width(width);
                $input.triggerHandler('resize');
            }
        };

        $input.on('keydown keyup update blur', update);
        update();
    };

    var domToString = function (d) {
        var tmp = document.createElement('div');

        tmp.appendChild(d.cloneNode(true));

        return tmp.innerHTML;
    };

    var logError = function (message, options) {
        if (!options) options = {};
        var component = "Selectize";

        console.error(component + ": " + message)

        if (options.explanation) {
            // console.group is undefined in <IE11
            if (console.group) console.group();
            console.error(options.explanation);
            if (console.group) console.groupEnd();
        }
    }


    var Selectize = function ($input, settings) {
        var key, i, n, dir, input, self = this;
        input = $input[0];
        input.selectize = self;

        // detect rtl environment
        var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);
        dir = computedStyle ? computedStyle.getPropertyValue('direction') : input.currentStyle && input.currentStyle.direction;
        dir = dir || $input.parents('[dir]:first').attr('dir') || '';

        // setup default state
        $.extend(self, {
            order: 0,
            settings: settings,
            $input: $input,
            tabIndex: $input.attr('tabindex') || '',
            tagType: input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT,
            rtl: /rtl/i.test(dir),

            eventNS: '.selectize' + (++Selectize.count),
            highlightedValue: null,
            isBlurring: false,
            isOpen: false,
            isDisabled: false,
            isRequired: $input.is('[required]'),
            isInvalid: false,
            isLocked: false,
            isFocused: false,
            isInputHidden: false,
            isSetup: false,
            isShiftDown: false,
            isCmdDown: false,
            isCtrlDown: false,
            ignoreFocus: false,
            ignoreBlur: false,
            ignoreHover: false,
            hasOptions: false,
            currentResults: null,
            lastValue: '',
            caretPos: 0,
            loading: 0,
            loadedSearches: {},

            $activeOption: null,
            $activeItems: [],

            optgroups: {},
            options: {},
            userOptions: {},
            items: [],
            renderCache: {},
            onSearchChange: settings.loadThrottle === null ? self.onSearchChange : debounce(self.onSearchChange, settings.loadThrottle)
        });

        // search system
        self.sifter = new Sifter(this.options, { diacritics: settings.diacritics });

        // build options table
        if (self.settings.options) {
            for (i = 0, n = self.settings.options.length; i < n; i++) {
                self.registerOption(self.settings.options[i]);
            }
            delete self.settings.options;
        }

        // build optgroup table
        if (self.settings.optgroups) {
            for (i = 0, n = self.settings.optgroups.length; i < n; i++) {
                self.registerOptionGroup(self.settings.optgroups[i]);
            }
            delete self.settings.optgroups;
        }

        // option-dependent defaults
        self.settings.mode = self.settings.mode || (self.settings.maxItems === 1 ? 'single' : 'multi');
        if (typeof self.settings.hideSelected !== 'boolean') {
            self.settings.hideSelected = self.settings.mode === 'multi';
        }

        self.initializePlugins(self.settings.plugins);
        self.setupCallbacks();
        self.setupTemplates();
        self.setup();
    };

    // mixins
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    MicroEvent.mixin(Selectize);

    if (typeof MicroPlugin !== "undefined") {
        MicroPlugin.mixin(Selectize);
    } else {
        logError("Dependency MicroPlugin is missing",
            {
                explanation:
                "Make sure you either: (1) are using the \"standalone\" " +
                "version of Selectize, or (2) require MicroPlugin before you " +
                "load Selectize."
            }
        );
    }


    // methods
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    $.extend(Selectize.prototype, {

		/**
		 * Creates all elements and sets up event bindings.
		 */
        setup: function () {
            var self = this;
            var settings = self.settings;
            var eventNS = self.eventNS;
            var $window = $(window);
            var $document = $(document);
            var $input = self.$input;

            var $wrapper;
            var $control;
            var $control_input;
            var $dropdown;
            var $dropdown_content;
            var $dropdown_parent;
            var inputMode;
            var timeout_blur;
            var timeout_focus;
            var classes;
            var classes_plugins;
            var inputId;

            inputMode = self.settings.mode;
            classes = $input.attr('class') || '';

            $wrapper = $('<div>').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode);
            $control = $('<div>').addClass(settings.inputClass).addClass('items').appendTo($wrapper);
            $control_input = $('<input type="text" autocomplete="off" />').appendTo($control).attr('tabindex', $input.is(':disabled') ? '-1' : self.tabIndex);
            $dropdown_parent = $(settings.dropdownParent || $wrapper);
            $dropdown = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
            $dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);

            if (inputId = $input.attr('id')) {
                $control_input.attr('id', inputId + '-selectized');
                $("label[for='" + inputId + "']").attr('for', inputId + '-selectized');
            }

            if (self.settings.copyClassesToDropdown) {
                $dropdown.addClass(classes);
            }

            $wrapper.css({
                width: $input[0].style.width
            });

            if (self.plugins.names.length) {
                classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');
                $wrapper.addClass(classes_plugins);
                $dropdown.addClass(classes_plugins);
            }

            if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) {
                $input.attr('multiple', 'multiple');
            }

            if (self.settings.placeholder) {
                $control_input.attr('placeholder', settings.placeholder);
            }

            // if splitOn was not passed in, construct it from the delimiter to allow pasting universally
            if (!self.settings.splitOn && self.settings.delimiter) {
                var delimiterEscaped = self.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
                self.settings.splitOn = new RegExp('\\s*' + delimiterEscaped + '+\\s*');
            }

            if ($input.attr('autocorrect')) {
                $control_input.attr('autocorrect', $input.attr('autocorrect'));
            }

            if ($input.attr('autocapitalize')) {
                $control_input.attr('autocapitalize', $input.attr('autocapitalize'));
            }
            $control_input[0].type = $input[0].type;

            self.$wrapper = $wrapper;
            self.$control = $control;
            self.$control_input = $control_input;
            self.$dropdown = $dropdown;
            self.$dropdown_content = $dropdown_content;

            $dropdown.on('mouseenter mousedown click', '[data-disabled]>[data-selectable]', function (e) { e.stopImmediatePropagation(); });
            $dropdown.on('mouseenter', '[data-selectable]', function () { return self.onOptionHover.apply(self, arguments); });
            $dropdown.on('mousedown click', '[data-selectable]', function () { return self.onOptionSelect.apply(self, arguments); });
            watchChildEvent($control, 'mousedown', '*:not(input)', function () { return self.onItemSelect.apply(self, arguments); });
            autoGrow($control_input);

            $control.on({
                mousedown: function () { return self.onMouseDown.apply(self, arguments); },
                click: function () { return self.onClick.apply(self, arguments); }
            });

            $control_input.on({
                mousedown: function (e) { e.stopPropagation(); },
                keydown: function () { return self.onKeyDown.apply(self, arguments); },
                keyup: function () { return self.onKeyUp.apply(self, arguments); },
                keypress: function () { return self.onKeyPress.apply(self, arguments); },
                resize: function () { self.positionDropdown.apply(self, []); },
                blur: function () { return self.onBlur.apply(self, arguments); },
                focus: function () { self.ignoreBlur = false; return self.onFocus.apply(self, arguments); },
                paste: function () { return self.onPaste.apply(self, arguments); }
            });

            $document.on('keydown' + eventNS, function (e) {
                self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey'];
                self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey'];
                self.isShiftDown = e.shiftKey;
            });

            $document.on('keyup' + eventNS, function (e) {
                if (e.keyCode === KEY_CTRL) self.isCtrlDown = false;
                if (e.keyCode === KEY_SHIFT) self.isShiftDown = false;
                if (e.keyCode === KEY_CMD) self.isCmdDown = false;
            });

            $document.on('mousedown' + eventNS, function (e) {
                if (self.isFocused) {
                    // prevent events on the dropdown scrollbar from causing the control to blur
                    if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) {
                        return false;
                    }
                    // blur on click outside
                    if (!self.$control.has(e.target).length && e.target !== self.$control[0]) {
                        self.blur(e.target);
                    }
                }
            });

            $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function () {
                if (self.isOpen) {
                    self.positionDropdown.apply(self, arguments);
                }
            });
            $window.on('mousemove' + eventNS, function () {
                self.ignoreHover = false;
            });

            // store original children and tab index so that they can be
            // restored when the destroy() method is called.
            this.revertSettings = {
                $children: $input.children().detach(),
                tabindex: $input.attr('tabindex')
            };

            $input.attr('tabindex', -1).hide().after(self.$wrapper);

            if ($.isArray(settings.items)) {
                self.setValue(settings.items);
                delete settings.items;
            }

            // feature detect for the validation API
            if (SUPPORTS_VALIDITY_API) {
                $input.on('invalid' + eventNS, function (e) {
                    e.preventDefault();
                    self.isInvalid = true;
                    self.refreshState();
                });
            }

            self.updateOriginalInput();
            self.refreshItems();
            self.refreshState();
            self.updatePlaceholder();
            self.isSetup = true;

            if ($input.is(':disabled')) {
                self.disable();
            }

            self.on('change', this.onChange);

            $input.data('selectize', self);
            $input.addClass('selectized');
            self.trigger('initialize');

            // preload options
            if (settings.preload === true) {
                self.onSearchChange('');
            }

        },

		/**
		 * Sets up default rendering functions.
		 */
        setupTemplates: function () {
            var self = this;
            var field_label = self.settings.labelField;
            var field_optgroup = self.settings.optgroupLabelField;

            var templates = {
                'optgroup': function (data) {
                    return '<div class="optgroup">' + data.html + '</div>';
                },
                'optgroup_header': function (data, escape) {
                    return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>';
                },
                'option': function (data, escape) {
                    return '<div class="option">' + escape(data[field_label]) + '</div>';
                },
                'item': function (data, escape) {
                    return '<div class="item">' + escape(data[field_label]) + '</div>';
                },
                'option_create': function (data, escape) {
                    return '<div class="create">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';
                }
            };

            self.settings.render = $.extend({}, templates, self.settings.render);
        },

		/**
		 * Maps fired events to callbacks provided
		 * in the settings used when creating the control.
		 */
        setupCallbacks: function () {
            var key, fn, callbacks = {
                'initialize': 'onInitialize',
                'change': 'onChange',
                'item_add': 'onItemAdd',
                'item_remove': 'onItemRemove',
                'clear': 'onClear',
                'option_add': 'onOptionAdd',
                'option_remove': 'onOptionRemove',
                'option_clear': 'onOptionClear',
                'optgroup_add': 'onOptionGroupAdd',
                'optgroup_remove': 'onOptionGroupRemove',
                'optgroup_clear': 'onOptionGroupClear',
                'dropdown_open': 'onDropdownOpen',
                'dropdown_close': 'onDropdownClose',
                'type': 'onType',
                'load': 'onLoad',
                'focus': 'onFocus',
                'blur': 'onBlur'
            };

            for (key in callbacks) {
                if (callbacks.hasOwnProperty(key)) {
                    fn = this.settings[callbacks[key]];
                    if (fn) this.on(key, fn);
                }
            }
        },

		/**
		 * Triggered when the main control element
		 * has a click event.
		 *
		 * @param {object} e
		 * @return {boolean}
		 */
        onClick: function (e) {
            var self = this;

            // necessary for mobile webkit devices (manual focus triggering
            // is ignored unless invoked within a click event)
            // also necessary to reopen a dropdown that has been closed by
            // closeAfterSelect
            if (!self.isFocused || !self.isOpen) {
                self.focus();
                e.preventDefault();
            }
        },

		/**
		 * Triggered when the main control element
		 * has a mouse down event.
		 *
		 * @param {object} e
		 * @return {boolean}
		 */
        onMouseDown: function (e) {
            var self = this;
            var defaultPrevented = e.isDefaultPrevented();
            var $target = $(e.target);

            if (self.isFocused) {
                // retain focus by preventing native handling. if the
                // event target is the input it should not be modified.
                // otherwise, text selection within the input won't work.
                if (e.target !== self.$control_input[0]) {
                    if (self.settings.mode === 'single') {
                        // toggle dropdown
                        self.isOpen ? self.close() : self.open();
                    } else if (!defaultPrevented) {
                        self.setActiveItem(null);
                    }
                    return false;
                }
            } else {
                // give control focus
                if (!defaultPrevented) {
                    window.setTimeout(function () {
                        self.focus();
                    }, 0);
                }
            }
        },

		/**
		 * Triggered when the value of the control has been changed.
		 * This should propagate the event to the original DOM
		 * input / select element.
		 */
        onChange: function () {
            this.$input.trigger('change');
        },

		/**
		 * Triggered on <input> paste.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onPaste: function (e) {
            var self = this;

            if (self.isFull() || self.isInputHidden || self.isLocked) {
                e.preventDefault();
                return;
            }

            // If a regex or string is included, this will split the pasted
            // input and create Items for each separate value
            if (self.settings.splitOn) {

                // Wait for pasted text to be recognized in value
                setTimeout(function () {
                    var pastedText = self.$control_input.val();
                    if (!pastedText.match(self.settings.splitOn)) { return }

                    var splitInput = $.trim(pastedText).split(self.settings.splitOn);
                    for (var i = 0, n = splitInput.length; i < n; i++) {
                        self.createItem(splitInput[i]);
                    }
                }, 0);
            }
        },

		/**
		 * Triggered on <input> keypress.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onKeyPress: function (e) {
            if (this.isLocked) return e && e.preventDefault();
            var character = String.fromCharCode(e.keyCode || e.which);
            if (this.settings.create && this.settings.mode === 'multi' && character === this.settings.delimiter) {
                this.createItem();
                e.preventDefault();
                return false;
            }
        },

		/**
		 * Triggered on <input> keydown.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onKeyDown: function (e) {
            var isInput = e.target === this.$control_input[0];
            var self = this;

            if (self.isLocked) {
                if (e.keyCode !== KEY_TAB) {
                    e.preventDefault();
                }
                return;
            }

            switch (e.keyCode) {
                case KEY_A:
                    if (self.isCmdDown) {
                        self.selectAll();
                        return;
                    }
                    break;
                case KEY_ESC:
                    if (self.isOpen) {
                        e.preventDefault();
                        e.stopPropagation();
                        self.close();
                    }
                    return;
                case KEY_N:
                    if (!e.ctrlKey || e.altKey) break;
                case KEY_DOWN:
                    if (!self.isOpen && self.hasOptions) {
                        self.open();
                    } else if (self.$activeOption) {
                        self.ignoreHover = true;
                        var $next = self.getAdjacentOption(self.$activeOption, 1);
                        if ($next.length) self.setActiveOption($next, true, true);
                    }
                    e.preventDefault();
                    return;
                case KEY_P:
                    if (!e.ctrlKey || e.altKey) break;
                case KEY_UP:
                    if (self.$activeOption) {
                        self.ignoreHover = true;
                        var $prev = self.getAdjacentOption(self.$activeOption, -1);
                        if ($prev.length) self.setActiveOption($prev, true, true);
                    }
                    e.preventDefault();
                    return;
                case KEY_RETURN:
                    if (self.isOpen && self.$activeOption) {
                        self.onOptionSelect({ currentTarget: self.$activeOption });
                        e.preventDefault();
                    }
                    return;
                case KEY_LEFT:
                    self.advanceSelection(-1, e);
                    return;
                case KEY_RIGHT:
                    self.advanceSelection(1, e);
                    return;
                case KEY_TAB:
                    if (self.settings.selectOnTab && self.isOpen && self.$activeOption) {
                        self.onOptionSelect({ currentTarget: self.$activeOption });

                        // Default behaviour is to jump to the next field, we only want this
                        // if the current field doesn't accept any more entries
                        if (!self.isFull()) {
                            e.preventDefault();
                        }
                    }
                    if (self.settings.create && self.createItem()) {
                        e.preventDefault();
                    }
                    return;
                case KEY_BACKSPACE:
                case KEY_DELETE:
                    self.deleteSelection(e);
                    return;
            }

            if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) {
                e.preventDefault();
                return;
            }
        },

		/**
		 * Triggered on <input> keyup.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onKeyUp: function (e) {
            var self = this;

            if (self.isLocked) return e && e.preventDefault();
            var value = self.$control_input.val() || '';
            if (self.lastValue !== value) {
                self.lastValue = value;
                self.onSearchChange(value);
                self.refreshOptions();
                self.trigger('type', value);
            }
        },

		/**
		 * Invokes the user-provide option provider / loader.
		 *
		 * Note: this function is debounced in the Selectize
		 * constructor (by `settings.loadThrottle` milliseconds)
		 *
		 * @param {string} value
		 */
        onSearchChange: function (value) {
            var self = this;
            var fn = self.settings.load;
            if (!fn) return;
            if (self.loadedSearches.hasOwnProperty(value)) return;
            self.loadedSearches[value] = true;
            self.load(function (callback) {
                fn.apply(self, [value, callback]);
            });
        },

		/**
		 * Triggered on <input> focus.
		 *
		 * @param {object} e (optional)
		 * @returns {boolean}
		 */
        onFocus: function (e) {
            var self = this;
            var wasFocused = self.isFocused;

            if (self.isDisabled) {
                self.blur();
                e && e.preventDefault();
                return false;
            }

            if (self.ignoreFocus) return;
            self.isFocused = true;
            if (self.settings.preload === 'focus') self.onSearchChange('');

            if (!wasFocused) self.trigger('focus');

            if (!self.$activeItems.length) {
                self.showInput();
                self.setActiveItem(null);
                self.refreshOptions(!!self.settings.openOnFocus);
            }

            self.refreshState();
        },

		/**
		 * Triggered on <input> blur.
		 *
		 * @param {object} e
		 * @param {Element} dest
		 */
        onBlur: function (e, dest) {
            var self = this;
            if (!self.isFocused) return;
            self.isFocused = false;

            if (self.ignoreFocus) {
                return;
            } else if (!self.ignoreBlur && document.activeElement === self.$dropdown_content[0]) {
                // necessary to prevent IE closing the dropdown when the scrollbar is clicked
                self.ignoreBlur = true;
                self.onFocus(e);
                return;
            }

            var deactivate = function () {
                self.close();
                self.setTextboxValue('');
                self.setActiveItem(null);
                self.setActiveOption(null);
                self.setCaret(self.items.length);
                self.refreshState();

                // IE11 bug: element still marked as active
                dest && dest.focus && dest.focus();

                self.isBlurring = false;
                self.ignoreFocus = false;
                self.trigger('blur');
            };

            self.isBlurring = true;
            self.ignoreFocus = true;
            if (self.settings.create && self.settings.createOnBlur) {
                self.createItem(null, false, deactivate);
            } else {
                deactivate();
            }
        },

		/**
		 * Triggered when the user rolls over
		 * an option in the autocomplete dropdown menu.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onOptionHover: function (e) {
            if (this.ignoreHover) return;
            this.setActiveOption(e.currentTarget, false);
        },

		/**
		 * Triggered when the user clicks on an option
		 * in the autocomplete dropdown menu.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onOptionSelect: function (e) {
            var value, $target, $option, self = this;

            if (e.preventDefault) {
                e.preventDefault();
                e.stopPropagation();
            }

            $target = $(e.currentTarget);
            if ($target.hasClass('create')) {
                self.createItem(null, function () {
                    if (self.settings.closeAfterSelect) {
                        self.close();
                    }
                });
            } else {
                value = $target.attr('data-value');
                if (typeof value !== 'undefined') {
                    self.lastQuery = null;
                    self.setTextboxValue('');
                    self.addItem(value);
                    if (self.settings.closeAfterSelect) {
                        self.close();
                    } else if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) {
                        self.setActiveOption(self.getOption(value));
                    }
                }
            }
        },

		/**
		 * Triggered when the user clicks on an item
		 * that has been selected.
		 *
		 * @param {object} e
		 * @returns {boolean}
		 */
        onItemSelect: function (e) {
            var self = this;

            if (self.isLocked) return;
            if (self.settings.mode === 'multi') {
                e.preventDefault();
                self.setActiveItem(e.currentTarget, e);
            }
        },

		/**
		 * Invokes the provided method that provides
		 * results to a callback---which are then added
		 * as options to the control.
		 *
		 * @param {function} fn
		 */
        load: function (fn) {
            var self = this;
            var $wrapper = self.$wrapper.addClass(self.settings.loadingClass);

            self.loading++;
            fn.apply(self, [function (results) {
                self.loading = Math.max(self.loading - 1, 0);
                if (results && results.length) {
                    self.addOption(results);
                    self.refreshOptions(self.isFocused && !self.isInputHidden);
                }
                if (!self.loading) {
                    $wrapper.removeClass(self.settings.loadingClass);
                }
                self.trigger('load', results);
            }]);
        },

		/**
		 * Sets the input field of the control to the specified value.
		 *
		 * @param {string} value
		 */
        setTextboxValue: function (value) {
            var $input = this.$control_input;
            var changed = $input.val() !== value;
            if (changed) {
                $input.val(value).triggerHandler('update');
                this.lastValue = value;
            }
        },

		/**
		 * Returns the value of the control. If multiple items
		 * can be selected (e.g. <select multiple>), this returns
		 * an array. If only one item can be selected, this
		 * returns a string.
		 *
		 * @returns {mixed}
		 */
        getValue: function () {
            if (this.tagType === TAG_SELECT && this.$input.attr('multiple')) {
                return this.items;
            } else {
                return this.items.join(this.settings.delimiter);
            }
        },

		/**
		 * Resets the selected items to the given value.
		 *
		 * @param {mixed} value
		 */
        setValue: function (value, silent) {
            var events = silent ? [] : ['change'];

            debounce_events(this, events, function () {
                this.clear(silent);
                this.addItems(value, silent);
            });
        },

		/**
		 * Sets the selected item.
		 *
		 * @param {object} $item
		 * @param {object} e (optional)
		 */
        setActiveItem: function ($item, e) {
            var self = this;
            var eventName;
            var i, idx, begin, end, item, swap;
            var $last;

            if (self.settings.mode === 'single') return;
            $item = $($item);

            // clear the active selection
            if (!$item.length) {
                $(self.$activeItems).removeClass('active');
                self.$activeItems = [];
                if (self.isFocused) {
                    self.showInput();
                }
                return;
            }

            // modify selection
            eventName = e && e.type.toLowerCase();

            if (eventName === 'mousedown' && self.isShiftDown && self.$activeItems.length) {
                $last = self.$control.children('.active:last');
                begin = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$last[0]]);
                end = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$item[0]]);
                if (begin > end) {
                    swap = begin;
                    begin = end;
                    end = swap;
                }
                for (i = begin; i <= end; i++) {
                    item = self.$control[0].childNodes[i];
                    if (self.$activeItems.indexOf(item) === -1) {
                        $(item).addClass('active');
                        self.$activeItems.push(item);
                    }
                }
                e.preventDefault();
            } else if ((eventName === 'mousedown' && self.isCtrlDown) || (eventName === 'keydown' && this.isShiftDown)) {
                if ($item.hasClass('active')) {
                    idx = self.$activeItems.indexOf($item[0]);
                    self.$activeItems.splice(idx, 1);
                    $item.removeClass('active');
                } else {
                    self.$activeItems.push($item.addClass('active')[0]);
                }
            } else {
                $(self.$activeItems).removeClass('active');
                self.$activeItems = [$item.addClass('active')[0]];
            }

            // ensure control has focus
            self.hideInput();
            if (!this.isFocused) {
                self.focus();
            }
        },

		/**
		 * Sets the selected item in the dropdown menu
		 * of available options.
		 *
		 * @param {object} $object
		 * @param {boolean} scroll
		 * @param {boolean} animate
		 */
        setActiveOption: function ($option, scroll, animate) {
            var height_menu, height_item, y;
            var scroll_top, scroll_bottom;
            var self = this;

            if (self.$activeOption) self.$activeOption.removeClass('active');
            self.$activeOption = null;

            $option = $($option);
            if (!$option.length) return;

            self.$activeOption = $option.addClass('active');

            if (scroll || !isset(scroll)) {

                height_menu = self.$dropdown_content.height();
                height_item = self.$activeOption.outerHeight(true);
                scroll = self.$dropdown_content.scrollTop() || 0;
                y = self.$activeOption.offset().top - self.$dropdown_content.offset().top + scroll;
                scroll_top = y;
                scroll_bottom = y - height_menu + height_item;

                if (y + height_item > height_menu + scroll) {
                    self.$dropdown_content.stop().animate({ scrollTop: scroll_bottom }, animate ? self.settings.scrollDuration : 0);
                } else if (y < scroll) {
                    self.$dropdown_content.stop().animate({ scrollTop: scroll_top }, animate ? self.settings.scrollDuration : 0);
                }

            }
        },

		/**
		 * Selects all items (CTRL + A).
		 */
        selectAll: function () {
            var self = this;
            if (self.settings.mode === 'single') return;

            self.$activeItems = Array.prototype.slice.apply(self.$control.children(':not(input)').addClass('active'));
            if (self.$activeItems.length) {
                self.hideInput();
                self.close();
            }
            self.focus();
        },

		/**
		 * Hides the input element out of view, while
		 * retaining its focus.
		 */
        hideInput: function () {
            var self = this;

            self.setTextboxValue('');
            self.$control_input.css({ opacity: 0, position: 'absolute', left: self.rtl ? 10000 : -10000 });
            self.isInputHidden = true;
        },

		/**
		 * Restores input visibility.
		 */
        showInput: function () {
            this.$control_input.css({ opacity: 1, position: 'relative', left: 0 });
            this.isInputHidden = false;
        },

		/**
		 * Gives the control focus.
		 */
        focus: function () {
            var self = this;
            if (self.isDisabled) return;

            self.ignoreFocus = true;
            self.$control_input[0].focus();
            window.setTimeout(function () {
                self.ignoreFocus = false;
                self.onFocus();
            }, 0);
        },

		/**
		 * Forces the control out of focus.
		 *
		 * @param {Element} dest
		 */
        blur: function (dest) {
            this.$control_input[0].blur();
            this.onBlur(null, dest);
        },

		/**
		 * Returns a function that scores an object
		 * to show how good of a match it is to the
		 * provided query.
		 *
		 * @param {string} query
		 * @param {object} options
		 * @return {function}
		 */
        getScoreFunction: function (query) {
            return this.sifter.getScoreFunction(query, this.getSearchOptions());
        },

		/**
		 * Returns search options for sifter (the system
		 * for scoring and sorting results).
		 *
		 * @see https://github.com/brianreavis/sifter.js
		 * @return {object}
		 */
        getSearchOptions: function () {
            var settings = this.settings;
            var sort = settings.sortField;
            if (typeof sort === 'string') {
                sort = [{ field: sort }];
            }

            return {
                fields: settings.searchField,
                conjunction: settings.searchConjunction,
                sort: sort,
                nesting: settings.nesting
            };
        },

		/**
		 * Searches through available options and returns
		 * a sorted array of matches.
		 *
		 * Returns an object containing:
		 *
		 *   - query {string}
		 *   - tokens {array}
		 *   - total {int}
		 *   - items {array}
		 *
		 * @param {string} query
		 * @returns {object}
		 */
        search: function (query) {
            var i, value, score, result, calculateScore;
            var self = this;
            var settings = self.settings;
            var options = this.getSearchOptions();

            // validate user-provided result scoring function
            if (settings.score) {
                calculateScore = self.settings.score.apply(this, [query]);
                if (typeof calculateScore !== 'function') {
                    throw new Error('Selectize "score" setting must be a function that returns a function');
                }
            }

            // perform search
            if (query !== self.lastQuery) {
                self.lastQuery = query;
                result = self.sifter.search(query, $.extend(options, { score: calculateScore }));
                self.currentResults = result;
            } else {
                result = $.extend(true, {}, self.currentResults);
            }

            // filter out selected items
            if (settings.hideSelected) {
                for (i = result.items.length - 1; i >= 0; i--) {
                    if (self.items.indexOf(hash_key(result.items[i].id)) !== -1) {
                        result.items.splice(i, 1);
                    }
                }
            }

            return result;
        },

		/**
		 * Refreshes the list of available options shown
		 * in the autocomplete dropdown menu.
		 *
		 * @param {boolean} triggerDropdown
		 */
        refreshOptions: function (triggerDropdown) {
            var i, j, k, n, groups, groups_order, option, option_html, optgroup, optgroups, html, html_children, has_create_option;
            var $active, $active_before, $create;

            if (typeof triggerDropdown === 'undefined') {
                triggerDropdown = true;
            }

            var self = this;
            var query = $.trim(self.$control_input.val());
            var results = self.search(query);
            var $dropdown_content = self.$dropdown_content;
            var active_before = self.$activeOption && hash_key(self.$activeOption.attr('data-value'));

            // build markup
            n = results.items.length;
            if (typeof self.settings.maxOptions === 'number') {
                n = Math.min(n, self.settings.maxOptions);
            }

            // render and group available options individually
            groups = {};
            groups_order = [];

            for (i = 0; i < n; i++) {
                option = self.options[results.items[i].id];
                option_html = self.render('option', option);
                optgroup = option[self.settings.optgroupField] || '';
                optgroups = $.isArray(optgroup) ? optgroup : [optgroup];

                for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
                    optgroup = optgroups[j];
                    if (!self.optgroups.hasOwnProperty(optgroup)) {
                        optgroup = '';
                    }
                    if (!groups.hasOwnProperty(optgroup)) {
                        groups[optgroup] = document.createDocumentFragment();
                        groups_order.push(optgroup);
                    }
                    groups[optgroup].appendChild(option_html);
                }
            }

            // sort optgroups
            if (this.settings.lockOptgroupOrder) {
                groups_order.sort(function (a, b) {
                    var a_order = self.optgroups[a].$order || 0;
                    var b_order = self.optgroups[b].$order || 0;
                    return a_order - b_order;
                });
            }

            // render optgroup headers & join groups
            html = document.createDocumentFragment();
            for (i = 0, n = groups_order.length; i < n; i++) {
                optgroup = groups_order[i];
                if (self.optgroups.hasOwnProperty(optgroup) && groups[optgroup].childNodes.length) {
                    // render the optgroup header and options within it,
                    // then pass it to the wrapper template
                    html_children = document.createDocumentFragment();
                    html_children.appendChild(self.render('optgroup_header', self.optgroups[optgroup]));
                    html_children.appendChild(groups[optgroup]);

                    html.appendChild(self.render('optgroup', $.extend({}, self.optgroups[optgroup], {
                        html: domToString(html_children),
                        dom: html_children
                    })));
                } else {
                    html.appendChild(groups[optgroup]);
                }
            }

            $dropdown_content.html(html);

            // highlight matching terms inline
            if (self.settings.highlight) {
                $dropdown_content.removeHighlight();
                if (results.query.length && results.tokens.length) {
                    for (i = 0, n = results.tokens.length; i < n; i++) {
                        highlight($dropdown_content, results.tokens[i].regex);
                    }
                }
            }

            // add "selected" class to selected options
            if (!self.settings.hideSelected) {
                for (i = 0, n = self.items.length; i < n; i++) {
                    self.getOption(self.items[i]).addClass('selected');
                }
            }

            // add create option
            has_create_option = self.canCreate(query);
            if (has_create_option) {
                $dropdown_content.prepend(self.render('option_create', { input: query }));
                $create = $($dropdown_content[0].childNodes[0]);
            }

            // activate
            self.hasOptions = results.items.length > 0 || has_create_option;
            if (self.hasOptions) {
                if (results.items.length > 0) {
                    $active_before = active_before && self.getOption(active_before);
                    if ($active_before && $active_before.length) {
                        $active = $active_before;
                    } else if (self.settings.mode === 'single' && self.items.length) {
                        $active = self.getOption(self.items[0]);
                    }
                    if (!$active || !$active.length) {
                        if ($create && !self.settings.addPrecedence) {
                            $active = self.getAdjacentOption($create, 1);
                        } else {
                            $active = $dropdown_content.find('[data-selectable]:first');
                        }
                    }
                } else {
                    $active = $create;
                }
                self.setActiveOption($active);
                if (triggerDropdown && !self.isOpen) { self.open(); }
            } else {
                self.setActiveOption(null);
                if (triggerDropdown && self.isOpen) { self.close(); }
            }
        },

		/**
		 * Adds an available option. If it already exists,
		 * nothing will happen. Note: this does not refresh
		 * the options list dropdown (use `refreshOptions`
		 * for that).
		 *
		 * Usage:
		 *
		 *   this.addOption(data)
		 *
		 * @param {object|array} data
		 */
        addOption: function (data) {
            var i, n, value, self = this;

            if ($.isArray(data)) {
                for (i = 0, n = data.length; i < n; i++) {
                    self.addOption(data[i]);
                }
                return;
            }

            if (value = self.registerOption(data)) {
                self.userOptions[value] = true;
                self.lastQuery = null;
                self.trigger('option_add', value, data);
            }
        },

		/**
		 * Registers an option to the pool of options.
		 *
		 * @param {object} data
		 * @return {boolean|string}
		 */
        registerOption: function (data) {
            var key = hash_key(data[this.settings.valueField]);
            if (typeof key === 'undefined' || key === null || this.options.hasOwnProperty(key)) return false;
            data.$order = data.$order || ++this.order;
            this.options[key] = data;
            return key;
        },

		/**
		 * Registers an option group to the pool of option groups.
		 *
		 * @param {object} data
		 * @return {boolean|string}
		 */
        registerOptionGroup: function (data) {
            var key = hash_key(data[this.settings.optgroupValueField]);
            if (!key) return false;

            data.$order = data.$order || ++this.order;
            this.optgroups[key] = data;
            return key;
        },

		/**
		 * Registers a new optgroup for options
		 * to be bucketed into.
		 *
		 * @param {string} id
		 * @param {object} data
		 */
        addOptionGroup: function (id, data) {
            data[this.settings.optgroupValueField] = id;
            if (id = this.registerOptionGroup(data)) {
                this.trigger('optgroup_add', id, data);
            }
        },

		/**
		 * Removes an existing option group.
		 *
		 * @param {string} id
		 */
        removeOptionGroup: function (id) {
            if (this.optgroups.hasOwnProperty(id)) {
                delete this.optgroups[id];
                this.renderCache = {};
                this.trigger('optgroup_remove', id);
            }
        },

		/**
		 * Clears all existing option groups.
		 */
        clearOptionGroups: function () {
            this.optgroups = {};
            this.renderCache = {};
            this.trigger('optgroup_clear');
        },

		/**
		 * Updates an option available for selection. If
		 * it is visible in the selected items or options
		 * dropdown, it will be re-rendered automatically.
		 *
		 * @param {string} value
		 * @param {object} data
		 */
        updateOption: function (value, data) {
            var self = this;
            var $item, $item_new;
            var value_new, index_item, cache_items, cache_options, order_old;

            value = hash_key(value);
            value_new = hash_key(data[self.settings.valueField]);

            // sanity checks
            if (value === null) return;
            if (!self.options.hasOwnProperty(value)) return;
            if (typeof value_new !== 'string') throw new Error('Value must be set in option data');

            order_old = self.options[value].$order;

            // update references
            if (value_new !== value) {
                delete self.options[value];
                index_item = self.items.indexOf(value);
                if (index_item !== -1) {
                    self.items.splice(index_item, 1, value_new);
                }
            }
            data.$order = data.$order || order_old;
            self.options[value_new] = data;

            // invalidate render cache
            cache_items = self.renderCache['item'];
            cache_options = self.renderCache['option'];

            if (cache_items) {
                delete cache_items[value];
                delete cache_items[value_new];
            }
            if (cache_options) {
                delete cache_options[value];
                delete cache_options[value_new];
            }

            // update the item if it's selected
            if (self.items.indexOf(value_new) !== -1) {
                $item = self.getItem(value);
                $item_new = $(self.render('item', data));
                if ($item.hasClass('active')) $item_new.addClass('active');
                $item.replaceWith($item_new);
            }

            // invalidate last query because we might have updated the sortField
            self.lastQuery = null;

            // update dropdown contents
            if (self.isOpen) {
                self.refreshOptions(false);
            }
        },

		/**
		 * Removes a single option.
		 *
		 * @param {string} value
		 * @param {boolean} silent
		 */
        removeOption: function (value, silent) {
            var self = this;
            value = hash_key(value);

            var cache_items = self.renderCache['item'];
            var cache_options = self.renderCache['option'];
            if (cache_items) delete cache_items[value];
            if (cache_options) delete cache_options[value];

            delete self.userOptions[value];
            delete self.options[value];
            self.lastQuery = null;
            self.trigger('option_remove', value);
            self.removeItem(value, silent);
        },

		/**
		 * Clears all options.
		 */
        clearOptions: function () {
            var self = this;

            self.loadedSearches = {};
            self.userOptions = {};
            self.renderCache = {};
            var options = self.options;
            $.each(self.options, function (key, value) {
                if (self.items.indexOf(key) == -1) {
                    delete options[key];
                }
            });
            self.options = self.sifter.items = options;
            self.lastQuery = null;
            self.trigger('option_clear');
        },

		/**
		 * Returns the jQuery element of the option
		 * matching the given value.
		 *
		 * @param {string} value
		 * @returns {object}
		 */
        getOption: function (value) {
            return this.getElementWithValue(value, this.$dropdown_content.find('[data-selectable]'));
        },

		/**
		 * Returns the jQuery element of the next or
		 * previous selectable option.
		 *
		 * @param {object} $option
		 * @param {int} direction  can be 1 for next or -1 for previous
		 * @return {object}
		 */
        getAdjacentOption: function ($option, direction) {
            var $options = this.$dropdown.find('[data-selectable]');
            var index = $options.index($option) + direction;

            return index >= 0 && index < $options.length ? $options.eq(index) : $();
        },

		/**
		 * Finds the first element with a "data-value" attribute
		 * that matches the given value.
		 *
		 * @param {mixed} value
		 * @param {object} $els
		 * @return {object}
		 */
        getElementWithValue: function (value, $els) {
            value = hash_key(value);

            if (typeof value !== 'undefined' && value !== null) {
                for (var i = 0, n = $els.length; i < n; i++) {
                    if ($els[i].getAttribute('data-value') === value) {
                        return $($els[i]);
                    }
                }
            }

            return $();
        },

		/**
		 * Returns the jQuery element of the item
		 * matching the given value.
		 *
		 * @param {string} value
		 * @returns {object}
		 */
        getItem: function (value) {
            return this.getElementWithValue(value, this.$control.children());
        },

		/**
		 * "Selects" multiple items at once. Adds them to the list
		 * at the current caret position.
		 *
		 * @param {string} value
		 * @param {boolean} silent
		 */
        addItems: function (values, silent) {
            this.buffer = document.createDocumentFragment();

            var childNodes = this.$control[0].childNodes;
            for (var i = 0; i < childNodes.length; i++) {
                this.buffer.appendChild(childNodes[i]);
            }

            var items = $.isArray(values) ? values : [values];
            for (var i = 0, n = items.length; i < n; i++) {
                this.isPending = (i < n - 1);
                this.addItem(items[i], silent);
            }

            var control = this.$control[0];
            control.insertBefore(this.buffer, control.firstChild);

            this.buffer = null;
        },

		/**
		 * "Selects" an item. Adds it to the list
		 * at the current caret position.
		 *
		 * @param {string} value
		 * @param {boolean} silent
		 */
        addItem: function (value, silent) {
            var events = silent ? [] : ['change'];

            debounce_events(this, events, function () {
                var $item, $option, $options;
                var self = this;
                var inputMode = self.settings.mode;
                var i, active, value_next, wasFull;
                value = hash_key(value);

                if (self.items.indexOf(value) !== -1) {
                    if (inputMode === 'single') self.close();
                    return;
                }

                if (!self.options.hasOwnProperty(value)) return;
                if (inputMode === 'single') self.clear(silent);
                if (inputMode === 'multi' && self.isFull()) return;

                $item = $(self.render('item', self.options[value]));
                wasFull = self.isFull();
                self.items.splice(self.caretPos, 0, value);
                self.insertAtCaret($item);
                if (!self.isPending || (!wasFull && self.isFull())) {
                    self.refreshState();
                }

                if (self.isSetup) {
                    $options = self.$dropdown_content.find('[data-selectable]');

                    // update menu / remove the option (if this is not one item being added as part of series)
                    if (!self.isPending) {
                        $option = self.getOption(value);
                        value_next = self.getAdjacentOption($option, 1).attr('data-value');
                        self.refreshOptions(self.isFocused && inputMode !== 'single');
                        if (value_next) {
                            self.setActiveOption(self.getOption(value_next));
                        }
                    }

                    // hide the menu if the maximum number of items have been selected or no options are left
                    if (!$options.length || self.isFull()) {
                        self.close();
                    } else if (!self.isPending) {
                        self.positionDropdown();
                    }

                    self.updatePlaceholder();
                    self.trigger('item_add', value, $item);

                    if (!self.isPending) {
                        self.updateOriginalInput({ silent: silent });
                    }
                }
            });
        },

		/**
		 * Removes the selected item matching
		 * the provided value.
		 *
		 * @param {string} value
		 */
        removeItem: function (value, silent) {
            var self = this;
            var $item, i, idx;

            $item = (value instanceof $) ? value : self.getItem(value);
            value = hash_key($item.attr('data-value'));
            i = self.items.indexOf(value);

            if (i !== -1) {
                $item.remove();
                if ($item.hasClass('active')) {
                    idx = self.$activeItems.indexOf($item[0]);
                    self.$activeItems.splice(idx, 1);
                }

                self.items.splice(i, 1);
                self.lastQuery = null;
                if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
                    self.removeOption(value, silent);
                }

                if (i < self.caretPos) {
                    self.setCaret(self.caretPos - 1);
                }

                self.refreshState();
                self.updatePlaceholder();
                self.updateOriginalInput({ silent: silent });
                self.positionDropdown();
                self.trigger('item_remove', value, $item);
            }
        },

		/**
		 * Invokes the `create` method provided in the
		 * selectize options that should provide the data
		 * for the new item, given the user input.
		 *
		 * Once this completes, it will be added
		 * to the item list.
		 *
		 * @param {string} value
		 * @param {boolean} [triggerDropdown]
		 * @param {function} [callback]
		 * @return {boolean}
		 */
        createItem: function (input, triggerDropdown) {
            var self = this;
            var caret = self.caretPos;
            input = input || $.trim(self.$control_input.val() || '');

            var callback = arguments[arguments.length - 1];
            if (typeof callback !== 'function') callback = function () { };

            if (typeof triggerDropdown !== 'boolean') {
                triggerDropdown = true;
            }

            if (!self.canCreate(input)) {
                callback();
                return false;
            }

            self.lock();

            var setup = (typeof self.settings.create === 'function') ? this.settings.create : function (input) {
                var data = {};
                data[self.settings.labelField] = input;
                data[self.settings.valueField] = input;
                return data;
            };

            var create = once(function (data) {
                self.unlock();

                if (!data || typeof data !== 'object') return callback();
                var value = hash_key(data[self.settings.valueField]);
                if (typeof value !== 'string') return callback();

                self.setTextboxValue('');
                self.addOption(data);
                self.setCaret(caret);
                self.addItem(value);
                self.refreshOptions(triggerDropdown && self.settings.mode !== 'single');
                callback(data);
            });

            var output = setup.apply(this, [input, create]);
            if (typeof output !== 'undefined') {
                create(output);
            }

            return true;
        },

		/**
		 * Re-renders the selected item lists.
		 */
        refreshItems: function () {
            this.lastQuery = null;

            if (this.isSetup) {
                this.addItem(this.items);
            }

            this.refreshState();
            this.updateOriginalInput();
        },

		/**
		 * Updates all state-dependent attributes
		 * and CSS classes.
		 */
        refreshState: function () {
            this.refreshValidityState();
            this.refreshClasses();
        },

		/**
		 * Update the `required` attribute of both input and control input.
		 *
		 * The `required` property needs to be activated on the control input
		 * for the error to be displayed at the right place. `required` also
		 * needs to be temporarily deactivated on the input since the input is
		 * hidden and can't show errors.
		 */
        refreshValidityState: function () {
            if (!this.isRequired) return false;

            var invalid = !this.items.length;

            this.isInvalid = invalid;
            this.$control_input.prop('required', invalid);
            this.$input.prop('required', !invalid);
        },

		/**
		 * Updates all state-dependent CSS classes.
		 */
        refreshClasses: function () {
            var self = this;
            var isFull = self.isFull();
            var isLocked = self.isLocked;

            self.$wrapper
                .toggleClass('rtl', self.rtl);

            self.$control
                .toggleClass('focus', self.isFocused)
                .toggleClass('disabled', self.isDisabled)
                .toggleClass('required', self.isRequired)
                .toggleClass('invalid', self.isInvalid)
                .toggleClass('locked', isLocked)
                .toggleClass('full', isFull).toggleClass('not-full', !isFull)
                .toggleClass('input-active', self.isFocused && !self.isInputHidden)
                .toggleClass('dropdown-active', self.isOpen)
                .toggleClass('has-options', !$.isEmptyObject(self.options))
                .toggleClass('has-items', self.items.length > 0);

            self.$control_input.data('grow', !isFull && !isLocked);
        },

		/**
		 * Determines whether or not more items can be added
		 * to the control without exceeding the user-defined maximum.
		 *
		 * @returns {boolean}
		 */
        isFull: function () {
            return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;
        },

		/**
		 * Refreshes the original <select> or <input>
		 * element to reflect the current state.
		 */
        updateOriginalInput: function (opts) {
            var i, n, options, label, self = this;
            opts = opts || {};

            if (self.tagType === TAG_SELECT) {
                options = [];
                for (i = 0, n = self.items.length; i < n; i++) {
                    label = self.options[self.items[i]][self.settings.labelField] || '';
                    options.push('<option value="' + escape_html(self.items[i]) + '" selected="selected">' + escape_html(label) + '</option>');
                }
                if (!options.length && !this.$input.attr('multiple')) {
                    options.push('<option value="" selected="selected"></option>');
                }
                self.$input.html(options.join(''));
            } else {
                self.$input.val(self.getValue());
                self.$input.attr('value', self.$input.val());
            }

            if (self.isSetup) {
                if (!opts.silent) {
                    self.trigger('change', self.$input.val());
                }
            }
        },

		/**
		 * Shows/hide the input placeholder depending
		 * on if there items in the list already.
		 */
        updatePlaceholder: function () {
            if (!this.settings.placeholder) return;
            var $input = this.$control_input;

            if (this.items.length) {
                $input.removeAttr('placeholder');
            } else {
                $input.attr('placeholder', this.settings.placeholder);
            }
            $input.triggerHandler('update', { force: true });
        },

		/**
		 * Shows the autocomplete dropdown containing
		 * the available options.
		 */
        open: function () {
            var self = this;

            if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return;
            self.focus();
            self.isOpen = true;
            self.refreshState();
            self.$dropdown.css({ visibility: 'hidden', display: 'block' });
            self.positionDropdown();
            self.$dropdown.css({ visibility: 'visible' });
            self.trigger('dropdown_open', self.$dropdown);
        },

		/**
		 * Closes the autocomplete dropdown menu.
		 */
        close: function () {
            var self = this;
            var trigger = self.isOpen;

            if (self.settings.mode === 'single' && self.items.length) {
                self.hideInput();

                // Do not trigger blur while inside a blur event,
                // this fixes some weird tabbing behavior in FF and IE.
                // See #1164
                if (!self.isBlurring) {
                    self.$control_input.blur(); // close keyboard on iOS
                }
            }

            self.isOpen = false;
            self.$dropdown.hide();
            self.setActiveOption(null);
            self.refreshState();

            if (trigger) self.trigger('dropdown_close', self.$dropdown);
        },

		/**
		 * Calculates and applies the appropriate
		 * position of the dropdown.
		 */
        positionDropdown: function () {
            var $control = this.$control;
            var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position();
            offset.top += $control.outerHeight(true);

            this.$dropdown.css({
                width: $control[0].getBoundingClientRect().width,
                top: offset.top,
                left: offset.left
            });
        },

		/**
		 * Resets / clears all selected items
		 * from the control.
		 *
		 * @param {boolean} silent
		 */
        clear: function (silent) {
            var self = this;

            if (!self.items.length) return;
            self.$control.children(':not(input)').remove();
            self.items = [];
            self.lastQuery = null;
            self.setCaret(0);
            self.setActiveItem(null);
            self.updatePlaceholder();
            self.updateOriginalInput({ silent: silent });
            self.refreshState();
            self.showInput();
            self.trigger('clear');
        },

		/**
		 * A helper method for inserting an element
		 * at the current caret position.
		 *
		 * @param {object} $el
		 */
        insertAtCaret: function ($el) {
            var caret = Math.min(this.caretPos, this.items.length);
            var el = $el[0];
            var target = this.buffer || this.$control[0];

            if (caret === 0) {
                target.insertBefore(el, target.firstChild);
            } else {
                target.insertBefore(el, target.childNodes[caret]);
            }

            this.setCaret(caret + 1);
        },

		/**
		 * Removes the current selected item(s).
		 *
		 * @param {object} e (optional)
		 * @returns {boolean}
		 */
        deleteSelection: function (e) {
            var i, n, direction, selection, values, caret, option_select, $option_select, $tail;
            var self = this;

            direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1;
            selection = getSelection(self.$control_input[0]);

            if (self.$activeOption && !self.settings.hideSelected) {
                option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value');
            }

            // determine items that will be removed
            values = [];

            if (self.$activeItems.length) {
                $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first'));
                caret = self.$control.children(':not(input)').index($tail);
                if (direction > 0) { caret++; }

                for (i = 0, n = self.$activeItems.length; i < n; i++) {
                    values.push($(self.$activeItems[i]).attr('data-value'));
                }
                if (e) {
                    e.preventDefault();
                    e.stopPropagation();
                }
            } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {
                if (direction < 0 && selection.start === 0 && selection.length === 0) {
                    values.push(self.items[self.caretPos - 1]);
                } else if (direction > 0 && selection.start === self.$control_input.val().length) {
                    values.push(self.items[self.caretPos]);
                }
            }

            // allow the callback to abort
            if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) {
                return false;
            }

            // perform removal
            if (typeof caret !== 'undefined') {
                self.setCaret(caret);
            }
            while (values.length) {
                self.removeItem(values.pop());
            }

            self.showInput();
            self.positionDropdown();
            self.refreshOptions(true);

            // select previous option
            if (option_select) {
                $option_select = self.getOption(option_select);
                if ($option_select.length) {
                    self.setActiveOption($option_select);
                }
            }

            return true;
        },

		/**
		 * Selects the previous / next item (depending
		 * on the `direction` argument).
		 *
		 * > 0 - right
		 * < 0 - left
		 *
		 * @param {int} direction
		 * @param {object} e (optional)
		 */
        advanceSelection: function (direction, e) {
            var tail, selection, idx, valueLength, cursorAtEdge, $tail;
            var self = this;

            if (direction === 0) return;
            if (self.rtl) direction *= -1;

            tail = direction > 0 ? 'last' : 'first';
            selection = getSelection(self.$control_input[0]);

            if (self.isFocused && !self.isInputHidden) {
                valueLength = self.$control_input.val().length;
                cursorAtEdge = direction < 0
                    ? selection.start === 0 && selection.length === 0
                    : selection.start === valueLength;

                if (cursorAtEdge && !valueLength) {
                    self.advanceCaret(direction, e);
                }
            } else {
                $tail = self.$control.children('.active:' + tail);
                if ($tail.length) {
                    idx = self.$control.children(':not(input)').index($tail);
                    self.setActiveItem(null);
                    self.setCaret(direction > 0 ? idx + 1 : idx);
                }
            }
        },

		/**
		 * Moves the caret left / right.
		 *
		 * @param {int} direction
		 * @param {object} e (optional)
		 */
        advanceCaret: function (direction, e) {
            var self = this, fn, $adj;

            if (direction === 0) return;

            fn = direction > 0 ? 'next' : 'prev';
            if (self.isShiftDown) {
                $adj = self.$control_input[fn]();
                if ($adj.length) {
                    self.hideInput();
                    self.setActiveItem($adj);
                    e && e.preventDefault();
                }
            } else {
                self.setCaret(self.caretPos + direction);
            }
        },

		/**
		 * Moves the caret to the specified index.
		 *
		 * @param {int} i
		 */
        setCaret: function (i) {
            var self = this;

            if (self.settings.mode === 'single') {
                i = self.items.length;
            } else {
                i = Math.max(0, Math.min(self.items.length, i));
            }

            if (!self.isPending) {
                // the input must be moved by leaving it in place and moving the
                // siblings, due to the fact that focus cannot be restored once lost
                // on mobile webkit devices
                var j, n, fn, $children, $child;
                $children = self.$control.children(':not(input)');
                for (j = 0, n = $children.length; j < n; j++) {
                    $child = $($children[j]).detach();
                    if (j < i) {
                        self.$control_input.before($child);
                    } else {
                        self.$control.append($child);
                    }
                }
            }

            self.caretPos = i;
        },

		/**
		 * Disables user input on the control. Used while
		 * items are being asynchronously created.
		 */
        lock: function () {
            this.close();
            this.isLocked = true;
            this.refreshState();
        },

		/**
		 * Re-enables user input on the control.
		 */
        unlock: function () {
            this.isLocked = false;
            this.refreshState();
        },

		/**
		 * Disables user input on the control completely.
		 * While disabled, it cannot receive focus.
		 */
        disable: function () {
            var self = this;
            self.$input.prop('disabled', true);
            self.$control_input.prop('disabled', true).prop('tabindex', -1);
            self.isDisabled = true;
            self.lock();
        },

		/**
		 * Enables the control so that it can respond
		 * to focus and user input.
		 */
        enable: function () {
            var self = this;
            self.$input.prop('disabled', false);
            self.$control_input.prop('disabled', false).prop('tabindex', self.tabIndex);
            self.isDisabled = false;
            self.unlock();
        },

		/**
		 * Completely destroys the control and
		 * unbinds all event listeners so that it can
		 * be garbage collected.
		 */
        destroy: function () {
            var self = this;
            var eventNS = self.eventNS;
            var revertSettings = self.revertSettings;

            self.trigger('destroy');
            self.off();
            self.$wrapper.remove();
            self.$dropdown.remove();

            self.$input
                .html('')
                .append(revertSettings.$children)
                .removeAttr('tabindex')
                .removeClass('selectized')
                .attr({ tabindex: revertSettings.tabindex })
                .show();

            self.$control_input.removeData('grow');
            self.$input.removeData('selectize');

            if (--Selectize.count == 0 && Selectize.$testInput) {
                Selectize.$testInput.remove();
                Selectize.$testInput = undefined;
            }

            $(window).off(eventNS);
            $(document).off(eventNS);
            $(document.body).off(eventNS);

            delete self.$input[0].selectize;
        },

		/**
		 * A helper method for rendering "item" and
		 * "option" templates, given the data.
		 *
		 * @param {string} templateName
		 * @param {object} data
		 * @returns {string}
		 */
        render: function (templateName, data) {
            var value, id, label;
            var html = '';
            var cache = false;
            var self = this;
            var regex_tag = /^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;

            if (templateName === 'option' || templateName === 'item') {
                value = hash_key(data[self.settings.valueField]);
                cache = !!value;
            }

            // pull markup from cache if it exists
            if (cache) {
                if (!isset(self.renderCache[templateName])) {
                    self.renderCache[templateName] = {};
                }
                if (self.renderCache[templateName].hasOwnProperty(value)) {
                    return self.renderCache[templateName][value];
                }
            }

            // render markup
            html = $(self.settings.render[templateName].apply(this, [data, escape_html]));

            // add mandatory attributes
            if (templateName === 'option' || templateName === 'option_create') {
                if (!data[self.settings.disabledField]) {
                    html.attr('data-selectable', '');
                }
            }
            else if (templateName === 'optgroup') {
                id = data[self.settings.optgroupValueField] || '';
                html.attr('data-group', id);
                if (data[self.settings.disabledField]) {
                    html.attr('data-disabled', '');
                }
            }
            if (templateName === 'option' || templateName === 'item') {
                html.attr('data-value', value || '');
            }

            // update cache
            if (cache) {
                self.renderCache[templateName][value] = html[0];
            }

            return html[0];
        },

		/**
		 * Clears the render cache for a template. If
		 * no template is given, clears all render
		 * caches.
		 *
		 * @param {string} templateName
		 */
        clearCache: function (templateName) {
            var self = this;
            if (typeof templateName === 'undefined') {
                self.renderCache = {};
            } else {
                delete self.renderCache[templateName];
            }
        },

		/**
		 * Determines whether or not to display the
		 * create item prompt, given a user input.
		 *
		 * @param {string} input
		 * @return {boolean}
		 */
        canCreate: function (input) {
            var self = this;
            if (!self.settings.create) return false;
            var filter = self.settings.createFilter;
            return input.length
                && (typeof filter !== 'function' || filter.apply(self, [input]))
                && (typeof filter !== 'string' || new RegExp(filter).test(input))
                && (!(filter instanceof RegExp) || filter.test(input));
        }

    });


    Selectize.count = 0;
    Selectize.defaults = {
        options: [],
        optgroups: [],

        plugins: [],
        delimiter: ',',
        splitOn: null, // regexp or string for splitting up values from a paste command
        persist: true,
        diacritics: true,
        create: false,
        createOnBlur: false,
        createFilter: null,
        highlight: true,
        openOnFocus: true,
        maxOptions: 1000,
        maxItems: null,
        hideSelected: null,
        addPrecedence: false,
        selectOnTab: false,
        preload: false,
        allowEmptyOption: false,
        closeAfterSelect: false,

        scrollDuration: 60,
        loadThrottle: 300,
        loadingClass: 'loading',

        dataAttr: 'data-data',
        optgroupField: 'optgroup',
        valueField: 'value',
        labelField: 'text',
        disabledField: 'disabled',
        optgroupLabelField: 'label',
        optgroupValueField: 'value',
        lockOptgroupOrder: false,

        sortField: '$order',
        searchField: ['text'],
        searchConjunction: 'and',

        mode: null,
        wrapperClass: 'selectize-control',
        inputClass: 'selectize-input',
        dropdownClass: 'selectize-dropdown',
        dropdownContentClass: 'selectize-dropdown-content',

        dropdownParent: null,

        copyClassesToDropdown: true,

		/*
		load                 : null, // function(query, callback) { ... }
		score                : null, // function(search) { ... }
		onInitialize         : null, // function() { ... }
		onChange             : null, // function(value) { ... }
		onItemAdd            : null, // function(value, $item) { ... }
		onItemRemove         : null, // function(value) { ... }
		onClear              : null, // function() { ... }
		onOptionAdd          : null, // function(value, data) { ... }
		onOptionRemove       : null, // function(value) { ... }
		onOptionClear        : null, // function() { ... }
		onOptionGroupAdd     : null, // function(id, data) { ... }
		onOptionGroupRemove  : null, // function(id) { ... }
		onOptionGroupClear   : null, // function() { ... }
		onDropdownOpen       : null, // function($dropdown) { ... }
		onDropdownClose      : null, // function($dropdown) { ... }
		onType               : null, // function(str) { ... }
		onDelete             : null, // function(values) { ... }
		*/

        render: {
			/*
			item: null,
			optgroup: null,
			optgroup_header: null,
			option: null,
			option_create: null
			*/
        }
    };


    $.fn.selectize = function (settings_user) {
        var defaults = $.fn.selectize.defaults;
        var settings = $.extend({}, defaults, settings_user);
        var attr_data = settings.dataAttr;
        var field_label = settings.labelField;
        var field_value = settings.valueField;
        var field_disabled = settings.disabledField;
        var field_optgroup = settings.optgroupField;
        var field_optgroup_label = settings.optgroupLabelField;
        var field_optgroup_value = settings.optgroupValueField;

		/**
		 * Initializes selectize from a <input type="text"> element.
		 *
		 * @param {object} $input
		 * @param {object} settings_element
		 */
        var init_textbox = function ($input, settings_element) {
            var i, n, values, option;

            var data_raw = $input.attr(attr_data);

            if (!data_raw) {
                var value = $.trim($input.val() || '');
                if (!settings.allowEmptyOption && !value.length) return;
                values = value.split(settings.delimiter);
                for (i = 0, n = values.length; i < n; i++) {
                    option = {};
                    option[field_label] = values[i];
                    option[field_value] = values[i];
                    settings_element.options.push(option);
                }
                settings_element.items = values;
            } else {
                settings_element.options = JSON.parse(data_raw);
                for (i = 0, n = settings_element.options.length; i < n; i++) {
                    settings_element.items.push(settings_element.options[i][field_value]);
                }
            }
        };

		/**
		 * Initializes selectize from a <select> element.
		 *
		 * @param {object} $input
		 * @param {object} settings_element
		 */
        var init_select = function ($input, settings_element) {
            var i, n, tagName, $children, order = 0;
            var options = settings_element.options;
            var optionsMap = {};

            var readData = function ($el) {
                var data = attr_data && $el.attr(attr_data);
                if (typeof data === 'string' && data.length) {
                    return JSON.parse(data);
                }
                return null;
            };

            var addOption = function ($option, group) {
                $option = $($option);

                var value = hash_key($option.val());
                if (!value && !settings.allowEmptyOption) return;

                // if the option already exists, it's probably been
                // duplicated in another optgroup. in this case, push
                // the current group to the "optgroup" property on the
                // existing option so that it's rendered in both places.
                if (optionsMap.hasOwnProperty(value)) {
                    if (group) {
                        var arr = optionsMap[value][field_optgroup];
                        if (!arr) {
                            optionsMap[value][field_optgroup] = group;
                        } else if (!$.isArray(arr)) {
                            optionsMap[value][field_optgroup] = [arr, group];
                        } else {
                            arr.push(group);
                        }
                    }
                    return;
                }

                var option = readData($option) || {};
                option[field_label] = option[field_label] || $option.text();
                option[field_value] = option[field_value] || value;
                option[field_disabled] = option[field_disabled] || $option.prop('disabled');
                option[field_optgroup] = option[field_optgroup] || group;

                optionsMap[value] = option;
                options.push(option);

                if ($option.is(':selected')) {
                    settings_element.items.push(value);
                }
            };

            var addGroup = function ($optgroup) {
                var i, n, id, optgroup, $options;

                $optgroup = $($optgroup);
                id = $optgroup.attr('label');

                if (id) {
                    optgroup = readData($optgroup) || {};
                    optgroup[field_optgroup_label] = id;
                    optgroup[field_optgroup_value] = id;
                    optgroup[field_disabled] = $optgroup.prop('disabled');
                    settings_element.optgroups.push(optgroup);
                }

                $options = $('option', $optgroup);
                for (i = 0, n = $options.length; i < n; i++) {
                    addOption($options[i], id);
                }
            };

            settings_element.maxItems = $input.attr('multiple') ? null : 1;

            $children = $input.children();
            for (i = 0, n = $children.length; i < n; i++) {
                tagName = $children[i].tagName.toLowerCase();
                if (tagName === 'optgroup') {
                    addGroup($children[i]);
                } else if (tagName === 'option') {
                    addOption($children[i]);
                }
            }
        };

        return this.each(function () {
            if (this.selectize) return;

            var instance;
            var $input = $(this);
            var tag_name = this.tagName.toLowerCase();
            var placeholder = $input.attr('placeholder') || $input.attr('data-placeholder');
            if (!placeholder && !settings.allowEmptyOption) {
                placeholder = $input.children('option[value=""]').text();
            }

            var settings_element = {
                'placeholder': placeholder,
                'options': [],
                'optgroups': [],
                'items': []
            };

            if (tag_name === 'select') {
                init_select($input, settings_element);
            } else {
                init_textbox($input, settings_element);
            }

            instance = new Selectize($input, $.extend(true, {}, defaults, settings_element, settings_user));
        });
    };

    $.fn.selectize.defaults = Selectize.defaults;
    $.fn.selectize.support = {
        validity: SUPPORTS_VALIDITY_API
    };


    Selectize.define('drag_drop', function (options) {
        if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');
        if (this.settings.mode !== 'multi') return;
        var self = this;

        self.lock = (function () {
            var original = self.lock;
            return function () {
                var sortable = self.$control.data('sortable');
                if (sortable) sortable.disable();
                return original.apply(self, arguments);
            };
        })();

        self.unlock = (function () {
            var original = self.unlock;
            return function () {
                var sortable = self.$control.data('sortable');
                if (sortable) sortable.enable();
                return original.apply(self, arguments);
            };
        })();

        self.setup = (function () {
            var original = self.setup;
            return function () {
                original.apply(this, arguments);

                var $control = self.$control.sortable({
                    items: '[data-value]',
                    forcePlaceholderSize: true,
                    disabled: self.isLocked,
                    start: function (e, ui) {
                        ui.placeholder.css('width', ui.helper.css('width'));
                        $control.css({ overflow: 'visible' });
                    },
                    stop: function () {
                        $control.css({ overflow: 'hidden' });
                        var active = self.$activeItems ? self.$activeItems.slice() : null;
                        var values = [];
                        $control.children('[data-value]').each(function () {
                            values.push($(this).attr('data-value'));
                        });
                        self.setValue(values);
                        self.setActiveItem(active);
                    }
                });
            };
        })();

    });

    Selectize.define('dropdown_header', function (options) {
        var self = this;

        options = $.extend({
            title: 'Untitled',
            headerClass: 'selectize-dropdown-header',
            titleRowClass: 'selectize-dropdown-header-title',
            labelClass: 'selectize-dropdown-header-label',
            closeClass: 'selectize-dropdown-header-close',

            html: function (data) {
                return (
                    '<div class="' + data.headerClass + '">' +
                    '<div class="' + data.titleRowClass + '">' +
                    '<span class="' + data.labelClass + '">' + data.title + '</span>' +
                    '<a href="javascript:void(0)" class="' + data.closeClass + '">&times;</a>' +
                    '</div>' +
                    '</div>'
                );
            }
        }, options);

        self.setup = (function () {
            var original = self.setup;
            return function () {
                original.apply(self, arguments);
                self.$dropdown_header = $(options.html(options));
                self.$dropdown.prepend(self.$dropdown_header);
            };
        })();

    });

    Selectize.define('optgroup_columns', function (options) {
        var self = this;

        options = $.extend({
            equalizeWidth: true,
            equalizeHeight: true
        }, options);

        this.getAdjacentOption = function ($option, direction) {
            var $options = $option.closest('[data-group]').find('[data-selectable]');
            var index = $options.index($option) + direction;

            return index >= 0 && index < $options.length ? $options.eq(index) : $();
        };

        this.onKeyDown = (function () {
            var original = self.onKeyDown;
            return function (e) {
                var index, $option, $options, $optgroup;

                if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) {
                    self.ignoreHover = true;
                    $optgroup = this.$activeOption.closest('[data-group]');
                    index = $optgroup.find('[data-selectable]').index(this.$activeOption);

                    if (e.keyCode === KEY_LEFT) {
                        $optgroup = $optgroup.prev('[data-group]');
                    } else {
                        $optgroup = $optgroup.next('[data-group]');
                    }

                    $options = $optgroup.find('[data-selectable]');
                    $option = $options.eq(Math.min($options.length - 1, index));
                    if ($option.length) {
                        this.setActiveOption($option);
                    }
                    return;
                }

                return original.apply(this, arguments);
            };
        })();

        var getScrollbarWidth = function () {
            var div;
            var width = getScrollbarWidth.width;
            var doc = document;

            if (typeof width === 'undefined') {
                div = doc.createElement('div');
                div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>';
                div = div.firstChild;
                doc.body.appendChild(div);
                width = getScrollbarWidth.width = div.offsetWidth - div.clientWidth;
                doc.body.removeChild(div);
            }
            return width;
        };

        var equalizeSizes = function () {
            var i, n, height_max, width, width_last, width_parent, $optgroups;

            $optgroups = $('[data-group]', self.$dropdown_content);
            n = $optgroups.length;
            if (!n || !self.$dropdown_content.width()) return;

            if (options.equalizeHeight) {
                height_max = 0;
                for (i = 0; i < n; i++) {
                    height_max = Math.max(height_max, $optgroups.eq(i).height());
                }
                $optgroups.css({ height: height_max });
            }

            if (options.equalizeWidth) {
                width_parent = self.$dropdown_content.innerWidth() - getScrollbarWidth();
                width = Math.round(width_parent / n);
                $optgroups.css({ width: width });
                if (n > 1) {
                    width_last = width_parent - width * (n - 1);
                    $optgroups.eq(n - 1).css({ width: width_last });
                }
            }
        };

        if (options.equalizeHeight || options.equalizeWidth) {
            hook.after(this, 'positionDropdown', equalizeSizes);
            hook.after(this, 'refreshOptions', equalizeSizes);
        }


    });

    Selectize.define('remove_button', function (options) {
        options = $.extend({
            label: '&times;',
            title: 'Remove',
            className: 'remove',
            append: true
        }, options);

        var singleClose = function (thisRef, options) {

            options.className = 'remove-single';

            var self = thisRef;
            var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';

            /**
             * Appends an element as a child (with raw HTML).
             *
             * @param {string} html_container
             * @param {string} html_element
             * @return {string}
             */
            var append = function (html_container, html_element) {
                return $('<span>').append(html_container)
                    .append(html_element);
            };

            thisRef.setup = (function () {
                var original = self.setup;
                return function () {
                    // override the item rendering method to add the button to each
                    if (options.append) {
                        var id = $(self.$input.context).attr('id');
                        var selectizer = $('#' + id);

                        var render_item = self.settings.render.item;
                        self.settings.render.item = function (data) {
                            return append(render_item.apply(thisRef, arguments), html);
                        };
                    }

                    original.apply(thisRef, arguments);

                    // add event listener
                    thisRef.$control.on('click', '.' + options.className, function (e) {
                        e.preventDefault();
                        if (self.isLocked) return;

                        self.clear();
                    });

                };
            })();
        };

        var multiClose = function (thisRef, options) {

            var self = thisRef;
            var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';

            /**
             * Appends an element as a child (with raw HTML).
             *
             * @param {string} html_container
             * @param {string} html_element
             * @return {string}
             */
            var append = function (html_container, html_element) {
                var pos = html_container.search(/(<\/[^>]+>\s*)$/);
                return html_container.substring(0, pos) + html_element + html_container.substring(pos);
            };

            thisRef.setup = (function () {
                var original = self.setup;
                return function () {
                    // override the item rendering method to add the button to each
                    if (options.append) {
                        var render_item = self.settings.render.item;
                        self.settings.render.item = function (data) {
                            return append(render_item.apply(thisRef, arguments), html);
                        };
                    }

                    original.apply(thisRef, arguments);

                    // add event listener
                    thisRef.$control.on('click', '.' + options.className, function (e) {
                        e.preventDefault();
                        if (self.isLocked) return;

                        var $item = $(e.currentTarget).parent();
                        self.setActiveItem($item);
                        if (self.deleteSelection()) {
                            self.setCaret(self.items.length);
                        }
                    });

                };
            })();
        };

        if (this.settings.mode === 'single') {
            singleClose(this, options);
            return;
        } else {
            multiClose(this, options);
        }
    });


    Selectize.define('restore_on_backspace', function (options) {
        var self = this;

        options.text = options.text || function (option) {
            return option[this.settings.labelField];
        };

        this.onKeyDown = (function () {
            var original = self.onKeyDown;
            return function (e) {
                var index, option;
                if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) {
                    index = this.caretPos - 1;
                    if (index >= 0 && index < this.items.length) {
                        option = this.options[this.items[index]];
                        if (this.deleteSelection(e)) {
                            this.setTextboxValue(options.text.apply(this, [option]));
                            this.refreshOptions(true);
                        }
                        e.preventDefault();
                        return;
                    }
                }
                return original.apply(this, arguments);
            };
        })();
    });


    return Selectize;
}));




/*!
Waypoints - 4.0.1
Copyright © 2011-2016 Caleb Troughton
Licensed under the MIT license.
https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
*/
!function () { "use strict"; function t(o) { if (!o) throw new Error("No options passed to Waypoint constructor"); if (!o.element) throw new Error("No element option passed to Waypoint constructor"); if (!o.handler) throw new Error("No handler option passed to Waypoint constructor"); this.key = "waypoint-" + e, this.options = t.Adapter.extend({}, t.defaults, o), this.element = this.options.element, this.adapter = new t.Adapter(this.element), this.callback = o.handler, this.axis = this.options.horizontal ? "horizontal" : "vertical", this.enabled = this.options.enabled, this.triggerPoint = null, this.group = t.Group.findOrCreate({ name: this.options.group, axis: this.axis }), this.context = t.Context.findOrCreateByElement(this.options.context), t.offsetAliases[this.options.offset] && (this.options.offset = t.offsetAliases[this.options.offset]), this.group.add(this), this.context.add(this), i[this.key] = this, e += 1 } var e = 0, i = {}; t.prototype.queueTrigger = function (t) { this.group.queueTrigger(this, t) }, t.prototype.trigger = function (t) { this.enabled && this.callback && this.callback.apply(this, t) }, t.prototype.destroy = function () { this.context.remove(this), this.group.remove(this), delete i[this.key] }, t.prototype.disable = function () { return this.enabled = !1, this }, t.prototype.enable = function () { return this.context.refresh(), this.enabled = !0, this }, t.prototype.next = function () { return this.group.next(this) }, t.prototype.previous = function () { return this.group.previous(this) }, t.invokeAll = function (t) { var e = []; for (var o in i) e.push(i[o]); for (var n = 0, r = e.length; r > n; n++)e[n][t]() }, t.destroyAll = function () { t.invokeAll("destroy") }, t.disableAll = function () { t.invokeAll("disable") }, t.enableAll = function () { t.Context.refreshAll(); for (var e in i) i[e].enabled = !0; return this }, t.refreshAll = function () { t.Context.refreshAll() }, t.viewportHeight = function () { return window.innerHeight || document.documentElement.clientHeight }, t.viewportWidth = function () { return document.documentElement.clientWidth }, t.adapters = [], t.defaults = { context: window, continuous: !0, enabled: !0, group: "default", horizontal: !1, offset: 0 }, t.offsetAliases = { "bottom-in-view": function () { return this.context.innerHeight() - this.adapter.outerHeight() }, "right-in-view": function () { return this.context.innerWidth() - this.adapter.outerWidth() } }, window.Waypoint = t }(), function () { "use strict"; function t(t) { window.setTimeout(t, 1e3 / 60) } function e(t) { this.element = t, this.Adapter = n.Adapter, this.adapter = new this.Adapter(t), this.key = "waypoint-context-" + i, this.didScroll = !1, this.didResize = !1, this.oldScroll = { x: this.adapter.scrollLeft(), y: this.adapter.scrollTop() }, this.waypoints = { vertical: {}, horizontal: {} }, t.waypointContextKey = this.key, o[t.waypointContextKey] = this, i += 1, n.windowContext || (n.windowContext = !0, n.windowContext = new e(window)), this.createThrottledScrollHandler(), this.createThrottledResizeHandler() } var i = 0, o = {}, n = window.Waypoint, r = window.onload; e.prototype.add = function (t) { var e = t.options.horizontal ? "horizontal" : "vertical"; this.waypoints[e][t.key] = t, this.refresh() }, e.prototype.checkEmpty = function () { var t = this.Adapter.isEmptyObject(this.waypoints.horizontal), e = this.Adapter.isEmptyObject(this.waypoints.vertical), i = this.element == this.element.window; t && e && !i && (this.adapter.off(".waypoints"), delete o[this.key]) }, e.prototype.createThrottledResizeHandler = function () { function t() { e.handleResize(), e.didResize = !1 } var e = this; this.adapter.on("resize.waypoints", function () { e.didResize || (e.didResize = !0, n.requestAnimationFrame(t)) }) }, e.prototype.createThrottledScrollHandler = function () { function t() { e.handleScroll(), e.didScroll = !1 } var e = this; this.adapter.on("scroll.waypoints", function () { (!e.didScroll || n.isTouch) && (e.didScroll = !0, n.requestAnimationFrame(t)) }) }, e.prototype.handleResize = function () { n.Context.refreshAll() }, e.prototype.handleScroll = function () { var t = {}, e = { horizontal: { newScroll: this.adapter.scrollLeft(), oldScroll: this.oldScroll.x, forward: "right", backward: "left" }, vertical: { newScroll: this.adapter.scrollTop(), oldScroll: this.oldScroll.y, forward: "down", backward: "up" } }; for (var i in e) { var o = e[i], n = o.newScroll > o.oldScroll, r = n ? o.forward : o.backward; for (var s in this.waypoints[i]) { var a = this.waypoints[i][s]; if (null !== a.triggerPoint) { var l = o.oldScroll < a.triggerPoint, h = o.newScroll >= a.triggerPoint, p = l && h, u = !l && !h; (p || u) && (a.queueTrigger(r), t[a.group.id] = a.group) } } } for (var c in t) t[c].flushTriggers(); this.oldScroll = { x: e.horizontal.newScroll, y: e.vertical.newScroll } }, e.prototype.innerHeight = function () { return this.element == this.element.window ? n.viewportHeight() : this.adapter.innerHeight() }, e.prototype.remove = function (t) { delete this.waypoints[t.axis][t.key], this.checkEmpty() }, e.prototype.innerWidth = function () { return this.element == this.element.window ? n.viewportWidth() : this.adapter.innerWidth() }, e.prototype.destroy = function () { var t = []; for (var e in this.waypoints) for (var i in this.waypoints[e]) t.push(this.waypoints[e][i]); for (var o = 0, n = t.length; n > o; o++)t[o].destroy() }, e.prototype.refresh = function () { var t, e = this.element == this.element.window, i = e ? void 0 : this.adapter.offset(), o = {}; this.handleScroll(), t = { horizontal: { contextOffset: e ? 0 : i.left, contextScroll: e ? 0 : this.oldScroll.x, contextDimension: this.innerWidth(), oldScroll: this.oldScroll.x, forward: "right", backward: "left", offsetProp: "left" }, vertical: { contextOffset: e ? 0 : i.top, contextScroll: e ? 0 : this.oldScroll.y, contextDimension: this.innerHeight(), oldScroll: this.oldScroll.y, forward: "down", backward: "up", offsetProp: "top" } }; for (var r in t) { var s = t[r]; for (var a in this.waypoints[r]) { var l, h, p, u, c, d = this.waypoints[r][a], f = d.options.offset, w = d.triggerPoint, y = 0, g = null == w; d.element !== d.element.window && (y = d.adapter.offset()[s.offsetProp]), "function" == typeof f ? f = f.apply(d) : "string" == typeof f && (f = parseFloat(f), d.options.offset.indexOf("%") > -1 && (f = Math.ceil(s.contextDimension * f / 100))), l = s.contextScroll - s.contextOffset, d.triggerPoint = Math.floor(y + l - f), h = w < s.oldScroll, p = d.triggerPoint >= s.oldScroll, u = h && p, c = !h && !p, !g && u ? (d.queueTrigger(s.backward), o[d.group.id] = d.group) : !g && c ? (d.queueTrigger(s.forward), o[d.group.id] = d.group) : g && s.oldScroll >= d.triggerPoint && (d.queueTrigger(s.forward), o[d.group.id] = d.group) } } return n.requestAnimationFrame(function () { for (var t in o) o[t].flushTriggers() }), this }, e.findOrCreateByElement = function (t) { return e.findByElement(t) || new e(t) }, e.refreshAll = function () { for (var t in o) o[t].refresh() }, e.findByElement = function (t) { return o[t.waypointContextKey] }, window.onload = function () { r && r(), e.refreshAll() }, n.requestAnimationFrame = function (e) { var i = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || t; i.call(window, e) }, n.Context = e }(), function () { "use strict"; function t(t, e) { return t.triggerPoint - e.triggerPoint } function e(t, e) { return e.triggerPoint - t.triggerPoint } function i(t) { this.name = t.name, this.axis = t.axis, this.id = this.name + "-" + this.axis, this.waypoints = [], this.clearTriggerQueues(), o[this.axis][this.name] = this } var o = { vertical: {}, horizontal: {} }, n = window.Waypoint; i.prototype.add = function (t) { this.waypoints.push(t) }, i.prototype.clearTriggerQueues = function () { this.triggerQueues = { up: [], down: [], left: [], right: [] } }, i.prototype.flushTriggers = function () { for (var i in this.triggerQueues) { var o = this.triggerQueues[i], n = "up" === i || "left" === i; o.sort(n ? e : t); for (var r = 0, s = o.length; s > r; r += 1) { var a = o[r]; (a.options.continuous || r === o.length - 1) && a.trigger([i]) } } this.clearTriggerQueues() }, i.prototype.next = function (e) { this.waypoints.sort(t); var i = n.Adapter.inArray(e, this.waypoints), o = i === this.waypoints.length - 1; return o ? null : this.waypoints[i + 1] }, i.prototype.previous = function (e) { this.waypoints.sort(t); var i = n.Adapter.inArray(e, this.waypoints); return i ? this.waypoints[i - 1] : null }, i.prototype.queueTrigger = function (t, e) { this.triggerQueues[e].push(t) }, i.prototype.remove = function (t) { var e = n.Adapter.inArray(t, this.waypoints); e > -1 && this.waypoints.splice(e, 1) }, i.prototype.first = function () { return this.waypoints[0] }, i.prototype.last = function () { return this.waypoints[this.waypoints.length - 1] }, i.findOrCreate = function (t) { return o[t.axis][t.name] || new i(t) }, n.Group = i }(), function () { "use strict"; function t(t) { this.$element = e(t) } var e = window.jQuery, i = window.Waypoint; e.each(["innerHeight", "innerWidth", "off", "offset", "on", "outerHeight", "outerWidth", "scrollLeft", "scrollTop"], function (e, i) { t.prototype[i] = function () { var t = Array.prototype.slice.call(arguments); return this.$element[i].apply(this.$element, t) } }), e.each(["extend", "inArray", "isEmptyObject"], function (i, o) { t[o] = e[o] }), i.adapters.push({ name: "jquery", Adapter: t }), i.Adapter = t }(), function () { "use strict"; function t(t) { return function () { var i = [], o = arguments[0]; return t.isFunction(arguments[0]) && (o = t.extend({}, arguments[1]), o.handler = arguments[0]), this.each(function () { var n = t.extend({}, o, { element: this }); "string" == typeof n.context && (n.context = t(this).closest(n.context)[0]), i.push(new e(n)) }), i } } var e = window.Waypoint; window.jQuery && (window.jQuery.fn.waypoint = t(window.jQuery)), window.Zepto && (window.Zepto.fn.waypoint = t(window.Zepto)) }();




/*!
Waypoints Inview Shortcut - 4.0.1
Copyright © 2011-2016 Caleb Troughton
Licensed under the MIT license.
https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
*/
!function () { "use strict"; function t() { } function e(t) { this.options = i.Adapter.extend({}, e.defaults, t), this.axis = this.options.horizontal ? "horizontal" : "vertical", this.waypoints = [], this.element = this.options.element, this.createWaypoints() } var i = window.Waypoint; e.prototype.createWaypoints = function () { for (var t = { vertical: [{ down: "enter", up: "exited", offset: "100%" }, { down: "entered", up: "exit", offset: "bottom-in-view" }, { down: "exit", up: "entered", offset: 0 }, { down: "exited", up: "enter", offset: function () { return -this.adapter.outerHeight() } }], horizontal: [{ right: "enter", left: "exited", offset: "100%" }, { right: "entered", left: "exit", offset: "right-in-view" }, { right: "exit", left: "entered", offset: 0 }, { right: "exited", left: "enter", offset: function () { return -this.adapter.outerWidth() } }] }, e = 0, i = t[this.axis].length; i > e; e++) { var n = t[this.axis][e]; this.createWaypoint(n) } }, e.prototype.createWaypoint = function (t) { var e = this; this.waypoints.push(new i({ context: this.options.context, element: this.options.element, enabled: this.options.enabled, handler: function (t) { return function (i) { e.options[t[i]].call(e, i) } }(t), offset: t.offset, horizontal: this.options.horizontal })) }, e.prototype.destroy = function () { for (var t = 0, e = this.waypoints.length; e > t; t++) this.waypoints[t].destroy(); this.waypoints = [] }, e.prototype.disable = function () { for (var t = 0, e = this.waypoints.length; e > t; t++) this.waypoints[t].disable() }, e.prototype.enable = function () { for (var t = 0, e = this.waypoints.length; e > t; t++) this.waypoints[t].enable() }, e.defaults = { context: window, enabled: !0, enter: t, entered: t, exit: t, exited: t }, i.Inview = e }();

/*! jQuery & Zepto Lazy v1.7.10 - http://jquery.eisbehr.de/lazy - MIT&GPL-2.0 license - Copyright 2012-2018 Daniel 'Eisbehr' Kern */
!function (t, e) { "use strict"; function r(r, a, i, u, l) { function f() { L = t.devicePixelRatio > 1, i = c(i), a.delay >= 0 && setTimeout(function () { s(!0) }, a.delay), (a.delay < 0 || a.combined) && (u.e = v(a.throttle, function (t) { "resize" === t.type && (w = B = -1), s(t.all) }), u.a = function (t) { t = c(t), i.push.apply(i, t) }, u.g = function () { return i = n(i).filter(function () { return !n(this).data(a.loadedName) }) }, u.f = function (t) { for (var e = 0; e < t.length; e++) { var r = i.filter(function () { return this === t[e] }); r.length && s(!1, r) } }, s(), n(a.appendScroll).on("scroll." + l + " resize." + l, u.e)) } function c(t) { var i = a.defaultImage, o = a.placeholder, u = a.imageBase, l = a.srcsetAttribute, f = a.loaderAttribute, c = a._f || {}; t = n(t).filter(function () { var t = n(this), r = m(this); return !t.data(a.handledName) && (t.attr(a.attribute) || t.attr(l) || t.attr(f) || c[r] !== e) }).data("plugin_" + a.name, r); for (var s = 0, d = t.length; s < d; s++) { var A = n(t[s]), g = m(t[s]), h = A.attr(a.imageBaseAttribute) || u; g === N && h && A.attr(l) && A.attr(l, b(A.attr(l), h)), c[g] === e || A.attr(f) || A.attr(f, c[g]), g === N && i && !A.attr(E) ? A.attr(E, i) : g === N || !o || A.css(O) && "none" !== A.css(O) || A.css(O, "url('" + o + "')") } return t } function s(t, e) { if (!i.length) return void (a.autoDestroy && r.destroy()); for (var o = e || i, u = !1, l = a.imageBase || "", f = a.srcsetAttribute, c = a.handledName, s = 0; s < o.length; s++)if (t || e || A(o[s])) { var g = n(o[s]), h = m(o[s]), b = g.attr(a.attribute), v = g.attr(a.imageBaseAttribute) || l, p = g.attr(a.loaderAttribute); g.data(c) || a.visibleOnly && !g.is(":visible") || !((b || g.attr(f)) && (h === N && (v + b !== g.attr(E) || g.attr(f) !== g.attr(F)) || h !== N && v + b !== g.css(O)) || p) || (u = !0, g.data(c, !0), d(g, h, v, p)) } u && (i = n(i).filter(function () { return !n(this).data(c) })) } function d(t, e, r, i) { ++z; var o = function () { y("onError", t), p(), o = n.noop }; y("beforeLoad", t); var u = a.attribute, l = a.srcsetAttribute, f = a.sizesAttribute, c = a.retinaAttribute, s = a.removeAttribute, d = a.loadedName, A = t.attr(c); if (i) { var g = function () { s && t.removeAttr(a.loaderAttribute), t.data(d, !0), y(T, t), setTimeout(p, 1), g = n.noop }; t.off(I).one(I, o).one(D, g), y(i, t, function (e) { e ? (t.off(D), g()) : (t.off(I), o()) }) || t.trigger(I) } else { var h = n(new Image); h.one(I, o).one(D, function () { t.hide(), e === N ? t.attr(C, h.attr(C)).attr(F, h.attr(F)).attr(E, h.attr(E)) : t.css(O, "url('" + h.attr(E) + "')"), t[a.effect](a.effectTime), s && (t.removeAttr(u + " " + l + " " + c + " " + a.imageBaseAttribute), f !== C && t.removeAttr(f)), t.data(d, !0), y(T, t), h.remove(), p() }); var m = (L && A ? A : t.attr(u)) || ""; h.attr(C, t.attr(f)).attr(F, t.attr(l)).attr(E, m ? r + m : null), h.complete && h.trigger(D) } } function A(t) { var e = t.getBoundingClientRect(), r = a.scrollDirection, n = a.threshold, i = h() + n > e.top && -n < e.bottom, o = g() + n > e.left && -n < e.right; return "vertical" === r ? i : "horizontal" === r ? o : i && o } function g() { return w >= 0 ? w : w = n(t).width() } function h() { return B >= 0 ? B : B = n(t).height() } function m(t) { return t.tagName.toLowerCase() } function b(t, e) { if (e) { var r = t.split(","); t = ""; for (var a = 0, n = r.length; a < n; a++)t += e + r[a].trim() + (a !== n - 1 ? "," : "") } return t } function v(t, e) { var n, i = 0; return function (o, u) { function l() { i = +new Date, e.call(r, o) } var f = +new Date - i; n && clearTimeout(n), f > t || !a.enableThrottle || u ? l() : n = setTimeout(l, t - f) } } function p() { --z, i.length || z || y("onFinishedAll") } function y(t, e, n) { return !!(t = a[t]) && (t.apply(r, [].slice.call(arguments, 1)), !0) } var z = 0, w = -1, B = -1, L = !1, T = "afterLoad", D = "load", I = "error", N = "img", E = "src", F = "srcset", C = "sizes", O = "background-image"; "event" === a.bind || o ? f() : n(t).on(D + "." + l, f) } function a(a, o) { var u = this, l = n.extend({}, u.config, o), f = {}, c = l.name + "-" + ++i; return u.config = function (t, r) { return r === e ? l[t] : (l[t] = r, u) }, u.addItems = function (t) { return f.a && f.a("string" === n.type(t) ? n(t) : t), u }, u.getItems = function () { return f.g ? f.g() : {} }, u.update = function (t) { return f.e && f.e({}, !t), u }, u.force = function (t) { return f.f && f.f("string" === n.type(t) ? n(t) : t), u }, u.loadAll = function () { return f.e && f.e({ all: !0 }, !0), u }, u.destroy = function () { return n(l.appendScroll).off("." + c, f.e), n(t).off("." + c), f = {}, e }, r(u, l, a, f, c), l.chainable ? a : u } var n = t.jQuery || t.Zepto, i = 0, o = !1; n.fn.Lazy = n.fn.lazy = function (t) { return new a(this, t) }, n.Lazy = n.lazy = function (t, r, i) { if (n.isFunction(r) && (i = r, r = []), n.isFunction(i)) { t = n.isArray(t) ? t : [t], r = n.isArray(r) ? r : [r]; for (var o = a.prototype.config, u = o._f || (o._f = {}), l = 0, f = t.length; l < f; l++)(o[t[l]] === e || n.isFunction(o[t[l]])) && (o[t[l]] = i); for (var c = 0, s = r.length; c < s; c++)u[r[c]] = t[0] } }, a.prototype.config = { name: "lazy", chainable: !0, autoDestroy: !0, bind: "load", threshold: 500, visibleOnly: !1, appendScroll: t, scrollDirection: "both", imageBase: null, defaultImage: "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==", placeholder: null, delay: -1, combined: !1, attribute: "data-src", srcsetAttribute: "data-srcset", sizesAttribute: "data-sizes", retinaAttribute: "data-retina", loaderAttribute: "data-loader", imageBaseAttribute: "data-imagebase", removeAttribute: !0, handledName: "handled", loadedName: "loaded", effect: "show", effectTime: 0, enableThrottle: !0, throttle: 250, beforeLoad: e, afterLoad: e, onError: e, onFinishedAll: e }, n(t).on("load", function () { o = !0 }) }(window);;
$(document).ready(function (e) {


    $('.flightSchedule').each(function (i) {
        $(this).attr('data-offest', $(this).offset().top)
        console.log($(this).offset().top)
    })
    if (window.location.href.indexOf("french") > -1) {
        $('body').addClass('french');
    }

    if ($('.internalNav').length > 0) {
        var navTop = $('.internalNav').offset().top;
        $(window).scroll(function (event) {
            var scroll = $(window).scrollTop();

            if (scroll > navTop) { 
                $('.internalNav').addClass('fixed');
                $('.flightSchedule').each(function (i) {
                    $this = $(this)
                    if ($this.attr('data-offest') < scroll + 100) { 
                        $('nav a.active').removeClass('active');
                        $('nav a:eq(' + i + ')').addClass('active');
                    }
                });
            }
            else {
                $('.internalNav').removeClass('fixed');
            }
        });
    }



    $('.progress .blue-bar').addClass('atZero')
    if ($(".onlyEnglishNote").length > 0) {

        /*  var bannerHeight = $(".mainBanner").height();
          var subMenuHeight = $(".pagesMenu").height();
          var footerHeight = $("footer").height();
          var footerOffetTop = $("footer").offset().top;
          var englishNoteTop = bannerHeight + subMenuHeight;
          var englishNoteHeight = (englishNoteTop + footerOffetTop) - footerHeight;
          englishNoteHeight = englishNoteHeight - 100;
          $(".onlyEnglishNote").css("top", englishNoteTop);
          $(".onlyEnglishNote").css("height", englishNoteHeight);*/
        $('body').addClass('hideLanguage')
    }
    $('body').addClass('loaded')

    $('.lazy').lazy({
        // your configuration goes here
        scrollDirection: 'vertical',
        effect: 'fadeIn',
        visibleOnly: true,
        onError: function (element) {
            console.log('error loading ' + element.data('src'));
        }
    });
    $('.creditcards a,#aSuccess ').fancybox({
        touch: false, clickSlide: false,
    })
    $('.partnersBlock .listingItemLI .logoImage:not(.hasLink)').click(function () {
        $(this).siblings('.col-md-9').fadeIn();
        $(this).siblings('.col-md-9').append('<a href="javascript:;" class="closePartners"></a>');
        $('.partnersBlock').addClass('Opened'); $('.partnersBlock .closePartners').click(function () {
            $('.partnersBlock').removeClass('Opened')
            $(".partnersBlock .col-md-9").fadeOut();
        })
    })
    $('.autoSuggest.hotel .custom-combobox .custom-combobox-input').attr('placeholder', 'Where are you going?')
    $('.custom-combobox input').click(function () {
        $(this).siblings('a').trigger('click');

    })


    $(document).mouseup(function (e) {
        var container = $(".partnersBlock .col-md-9");

        // if the target of the click isn't the container nor a descendant of the container
        if (!container.is(e.target) && container.has(e.target).length === 0) {
            $('.partnersBlock').removeClass('Opened')
            container.fadeOut();
        }
    });

    // if($(window).width() > 767){
    //     subMenuMore()
    // }

    function isIE() {
        ua = navigator.userAgent;
        /* MSIE used to detect old browsers and Trident used to newer ones*/
        var is_ie = ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;

        return is_ie;
    }

    $('.js-example-basic-single').select2();
    if (document.documentMode || /Edge/.test(navigator.userAgent)) {
        $('.parallaxEffect').addClass('withBackgroundImage');
        $('.parallaxEffect').attr("data-image-src", "");
    }

    if (isIE()) {
        $('.parallaxEffect').addClass('withBackgroundImage');
        $('.parallaxEffect').attr("data-image-src", "");
    }

    if ($('body.arabicLanguage').length > 0) {

        $('.parallaxEffect').addClass('withBackgroundImage')
        $('.scheduleContainer').addClass('withBackgroundImage')
    }
    else {
        $('.parallaxEffect').parallax()
    }

    $('.inputTrigger').click(function () {

        $(this).parent().find('input').focus()
    })
    if ($(window).height() < 800) {
        $('body').addClass('smallHeightWindow')
    }
    if ($(window).width() > 767) {
        if ($('.bookTripBlock .calendar').length > 0) {
            new SimpleBar($('.bookTripBlock .calendar')[0]);
        }
        if ($('.measales .tabsHolder .tab').not($('.activitiesPage .tabsHolder .tab')).length > 0) {
            new SimpleBar($('.measales .tabsHolder .tab')[0]);
        }

    }


    $('.calendarClose').click(function () {
        $('.calendarsBlock').removeClass('visible')
        $('.mainRightBlock').removeClass('activeCalendar')
    })
    $('.calendarClosePopup').click(function () {
        $(".calendarPopup").css("visibility", "hidden")
        $('.calendarPopup').css("opacity", "0");
        $(".calendarPopup .calendarsBlock").css("visibility", "hidden")

    })
    if ($(window).width() < 992) {


        setTimeout(function () { mobileMenu() }, 1000);
       
    }

    if ($("#historylist li").length > 0) {
        var size_li = $("#historylist li").size();
        var x = 3;
        $('#historylist li:lt(' + x + ')').show();
        $('#loadMore').click(function () {
            x = (x + 5 <= size_li) ? x + 5 : size_li;
            $('#historylist li:lt(' + x + ')').slideDown();
            $('html,body').animate({
                scrollTop: $(this).offset().top
            }, 500);
        });
        $('#showLess').click(function () {
            x = (x - 5 < 0) ? 3 : x - 5;
            $('#historylist li').not(':lt(' + x + ')').hide();
        });
    }

    bookBuyBg()
    $('.customSelect select').dropkick({
        mobile: true
    });
    progress()
    //milesProgress()


    showMinusAndPlus()
    scrollDetect()
    newsBackgroud()

    mainMenuHover()
 

    if ($(window).width() > 767) {
        setTimeout(function () { bookATrip(); }, 500);
        AOS.init();
    }
    if ($(window).width() < 767) {
        setTimeout(function () { mobileBookAtrip(); }, 500);
        entertainmentMobile()
    }
    
    
    setTimeout(function () { hpBanner() }, 500);
    bookType()
    $(window).resize(function () {
        bookATrip();

    });
    menuFunction()
    //CALL FUNCTIONS HERE
    tabsTrigger();
    $('.listingImage').each(function () {
        var el = $(this)
        $(".listingHolder").imagesLoaded(function () {
            el.removeClass("listingImageLoad")
        })
    })

    // add classes for mobile/desktop on body
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
        $("body").addClass("mobile")
    }
    else {
        $("body").addClass("desktop")
    }

    // mobile menu
    $(".mainMenuParent").before("<div class='mobileMenuToggler'><span></span></div>")
    $(".mobileMenuToggler").click(function (e) {
        //$('body').toggleClass("menuActive")
        $("body").addClass("fixedPage");
        $(this).toggleClass("active")
        $(".mainMenuParent").toggleClass("active")
        $('.searchParent').toggleClass("active")
        $('.logoHolder').toggleClass("active")
        e.stopPropagation();
        e.preventDefault();
    })

    $(document).mouseup(function (e) {
        var container = $(".menusMain.active");

        // if the target of the click isn't the container nor a descendant of the container
        if (!container.is(e.target) && container.has(e.target).length === 0) {
            $("body").removeClass("fixedPage");
            $(".mainMenuParent").removeClass("active")
            $('.searchParent').removeClass("active")
            $('.logoHolder').removeClass("active")
        }
        if ($(".countriesPopup.show").length > 0) {
            $(".countriesPopup").removeClass("show");
        }
    });

    // add mobile submenu togglers
    $("mainMenuSubClass ul li.hasSubmenu").each(function () {
        $(this).append("<span class='subMenuToggle'></span>")
    })

    $(".subMenuToggle").click(function () {
        $(this).parent().find(".ddSecondLevel").slideToggle();
        $(this).parent().toggleClass("openSubmenu")
    })


    // close mobile menu on outside click
    $(".mainMenuParent .mobileMenuToggler ").click(function (e) {
        if ($(e.target).closest('mainMenuSubClass ul').length === 0) {
            $(".mobileMenuToggler").toggleClass("active")
            $(".mainMenuParent").removeClass("active")
        }
    })
    //$(".mainMenu").click(function (e) {
    //    if ($(e.target).closest('ul').length === 0) {

    //        $(".hasSubmenu a").toggleClass("active")
    //    }
    //})

    // Expand/Collapse


    $('.toggleTitle').click(function () {
        if (!($(this).hasClass('active'))) {
           $('.toggleContent').hide(); 
           $('.toggleTitle').removeClass('active')
             $('.toggleItem').removeClass('active')
            $(this).parent().toggleClass('active')
            $(this).parent().find($('.toggleContent')).slideToggle(function () {
                $(window).trigger('resize.px.parallax');
            });

            $(this).toggleClass('active')
            $("html, body").animate({ scrollTop: $(this).offset().top - 200 });
        }
        else {


            $(this).parent().find($('.toggleContent')).slideToggle(function () {
                $(window).trigger('resize.px.parallax');
            });
            $(this).parent().removeClass('active')
            $(this).removeClass('active');

        }


    });

    $('.calculateBtn').click(function () {
        $('.calculate').slideDown()
        $('.calculate').toggleClass('active')
    });

    $('.datepicker').click(function (e) {
        $('.calendarPopup').css("visibility", "visible");
        $('.calendarPopup').css("opacity", "1");
        $('.calendarPopup .calendarsBlock').css("visibility", "visible");
        e.stopPropagation();
        e.preventDefault();
    })
    countryLanguage();
    $("body").click(function () {
        $(".calendarPopup").css("visibility", "hidden")
        $('.calendarPopup').css("opacity", "1");
        $(".calendarPopup .calendarsBlock").css("visibility", "hidden")
    });

    // Prevent events from getting pass .popup
    $(".calendarPopup").click(function (e) {
        e.stopPropagation();
    });
    $(".calendarPopup .calendarsBlock").click(function (e) {
        e.stopPropagation();
    });
    $(".tabLinks a").click(function () {
        $(".calendarsBlock").hide()
        $(this).addClass("active");
        $(this).parent().find("a").not($(this)).removeClass("active");
        if (!$(this).hasClass("bookMiles")) {
            $(".mainRightBlock").removeClass("visible");
            $(".mainRightBlock[data-index=" + $(this).index() + "]").addClass("visible");
            $(".calendarsBlock").removeClass("visible");
            $(".mainRightBlock").removeClass("activeCalendar");
            setTimeout(function () { $(".calendarsBlock").show() }, 500)
        }
    });

    //$(".countriesPopup .countries ul li a").click(function (e) {
    //    e.preventDefault();
    //    $("body").removeClass("fixedPage");
    //    $(".countriesPopup").removeClass("visible")

    //});


    $('.selectized').selectize({
        persist: false,
        maxItems: 1,
        valueField: 'countryCode',
        labelField: 'countryCode',
        searchField: ['countryCode'],
        render: {
            item: function (item, escape) {
                return '<div class="country">' +
                    (item.countryCode ? '<span class="countryCode">' + escape(item.countryCode) + '</span>' : '')
                '</div>';
            }
        }
    });

    $(".closeCustPopup").click(function () {
        $(this).parent().css("display", "none");
        $('.partnersBlock').removeClass('Opened');
    });

    $('.aff-companies-block .listingItemLI .showmore').click(function () {
        $(this).addClass('hide');
        $(this).parent().find('.showless').addClass('show');
        $(this).closest('.listingItemLI').find('.moreContent').slideDown();
        $('html, body').animate({
            scrollTop: ($(this).closest('.listingItemLI').find('.moreContent').offset().top)
        }, 500);
    })
    $('.aff-companies-block .listingItemLI .showless').click(function () {
        $(this).removeClass('show')
        $(this).parent().find('.showmore').removeClass('hide');
        $(this).closest('.listingItemLI').find('.moreContent').slideUp();
    })
    var $affectedElements = $("p , li , a, label, div"); // Can be extended, ex. $("div, p, span.someClass")

    // Storing the original size in a data attribute so size can be reset
    $affectedElements.each(function () {
        var $this = $(this);
        $this.data("orig-size", $this.css("font-size"));
    });

    $(".biggerFont").click(function () {
        changeFontSize(1);
    })

    $(".smallerFont").click(function () {
        changeFontSize(-1);
    })


    function changeFontSize(direction) {
        $affectedElements.each(function () {
            var $this = $(this);
            $this.css("font-size", parseInt($this.css("font-size")) + direction);
        });
    }


    $('.rightMenu .searchToggle').click(function (e) {
        e.preventDefault();
        $("body").addClass("fixedPage");
        $(".searchPopup").addClass("visible");
        setTimeout(function () {
            $("#txtAdvancedSearch").focus();
        }, 500)

    });

    $('.closeSearch').click(function () {
        $("body").removeClass("fixedPage");
        $(".searchPopup").removeClass("visible");
    })
    $('.aboutAirport .bigNumber,.myaccount-details h4 , .numberOfMiles span , .progress-info .number.withAnimation , #trainingCenterNumber1 , #trainingCenterNumber2 , #trainingCenterNumber3 , #trainingCenterNumber4').addClass('withCounter')
    if ($('.bigNumber.withCounter').length > 0) {

        var inview = new Waypoint.Inview({
            element: $('.aboutAirport .bigNumber.withCounter')[0],
            enter: function (up) {

                counterAnimation();
                $('.aboutAirport .biprogress-infogNumber').removeClass('withCounter')
            },
        })
    }
    if ($('.progress').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('.progress')[0],
            enter: function (up) {
                $('.progress .blue-bar.atZero').removeClass('atZero')


            },
        })
    }
    if ($('.myaccount-details h4.withCounter').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('.myaccount-details h4.withCounter')[0],
            enter: function (up) {
                var $this2 = $(this)
                counterAnimation2();
                $('.myaccount-details h4.withCounter').removeClass('withCounter')


            },
        })
    }


    if ($('#trainingCenterNumber1').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('#trainingCenterNumber1')[0],
            enter: function (up) {
                var $this = $(this);
                trainingCenterNumber1();
                $('#trainingCenterNumber1').removeClass('withCounter')
            },
        })
    }
    if ($('#trainingCenterNumber2').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('#trainingCenterNumber2')[0],
            enter: function (up) {
                var $this = $(this);
                trainingCenterNumber2();
                $('#trainingCenterNumber2').removeClass('withCounter')
            },
        })
    }
    if ($('#trainingCenterNumber3').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('#trainingCenterNumber3')[0],
            enter: function (up) {
                var $this = $(this);
                trainingCenterNumber3();
                $('#trainingCenterNumber3').removeClass('withCounter')
            },
        })
    }
    if ($('#trainingCenterNumber4').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('#trainingCenterNumber4')[0],
            enter: function (up) {
                var $this = $(this);
                trainingCenterNumber4();
                $('#trainingCenterNumber4').removeClass('withCounter')
            },
        })
    }

    if ($('.numberOfMiles span.withCounter').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('.numberOfMiles span.withCounter')[0],
            enter: function (up) {
                var $this = $(this)
                counterAnimation3();
                $('.numberOfMiles span').removeClass('withCounter')
            },
        })
    }
    if ($('.progress-info .number.withAnimation').length > 0) {
        var inview = new Waypoint.Inview({
            element: $('.progress-info .number.withAnimation.withCounter')[0],
            enter: function (up) {
                var $this = $(this)
                counterAnimation4();
                $('.progress-info .number.withAnimation').removeClass('withCounter')
            },
        })
    }


    setTimeout(function () {
        $('.latestNews .itemHolder').each(function () {
            $this = $(this)
            if ($($this.find('.backgroundImage')).length > 0) {
                $($this).addClass('withBgImage')
            }
        })

    }, 500)
    if ($(window).width() < 992) {

    }

    $('.Tips .col-sm-4').matchHeight({
        byRow: true
    })
    $('.cedarLinksHolder').matchHeight({
        byRow: true
    })
    $('.Tips .col-sm-4 .p20').matchHeight({
        byRow: true
    })
    $('.Tips .col-sm-4 .description').matchHeight({
        byRow: true
    })
    setTimeout(function () {
        $('.youNeedToKnow .aboutText').matchHeight({
            byRow: true
        })
      
        $('.entertainmentListing .movieItem.col-md-3 .movieInfo h4').matchHeight({
            byRow: true
        })

    }, 500)

    setTimeout(function () {
      
        $('.specialOccasionPage  .product-box .pr-info .pr-details').matchHeight({
            byRow: false
        })

    }, 1500)




    //$(".bookingOffices a.currentOffice").click(function (e) {
    //    e.preventDefault();
    //    $("body").addClass("fixedPage");
    //    $(".countriesPopup").addClass("visible");
    //});
    //$('.closeCountries').click(function () {
    //    $("body").removeClass("fixedPage");
    //    $(".countriesPopup").removeClass("visible");
    //});
  
    if ($('body.arabicLanguage').length > 0) {
        $('.adsBlock .owl-carousel').owlCarousel({ loop: true, nav: true, dots: false, items: 1, rtl: true });
        $('.airlines.owl-carousel').owlCarousel({ loop: false, nav: true, dots: true, items: 5, rtl: true });
        travelerCarouselArabic()
        $('.months-container.owl-carousel').owlCarousel({ loop: false, margin: 24, nav: true, dots: false, items: 3, rtl: true })
        $('.newstext-carousel.owl-carousel').owlCarousel({ loop: false, margin: 24, nav: true, dots: false, items: 1, rtl: true });
        syncedOwlsArabic()
        if ($(window).width() < 767) {
            setTimeout(function () {
                mobileFunctionsArabic()
                bookandbuyMobile()
                $('.measales .customSelect').parents('body').addClass('meaOutside')
            }, 1000);

        }
    }
    else {
        $('.adsBlock .owl-carousel').owlCarousel({ loop: true, nav: true, dots: false, items: 1 });
        $('.airlines.owl-carousel').owlCarousel({ loop: false, nav: true, dots: true, items: 5 });
        travelerCarousel()
        $('.months-container.owl-carousel').owlCarousel({ loop: false, margin: 24, nav: true, dots: false, items: 3 })
        $('.newstext-carousel.owl-carousel').owlCarousel({ loop: false, margin: 24, nav: true, dots: false, items: 1 });
        syncedOwls()
        if ($(window).width() < 767) {
            setTimeout(function () {
                mobileFunctions()
                bookandbuyMobile() 
                $('.measales .customSelect').parents('body').addClass('meaOutside')
            }, 1000);

        }
    }

    if ($(".schedContainer").length > 0) {
        $(".flightsColorCode a").click(function () {
            if (!$(this).parent().attr("data-dimmed") && $(".flightsColorCode li[data-dimmed=true]").length > 0) {
                $(".arrivalTable .arrivalSchedule li").show();
                $(".flightsColorCode li").removeAttr("data-dimmed");
            }
            else {
                var parentClass = $(this).parent().attr("class");
                $(".arrivalTable .arrivalSchedule li:not(." + parentClass + ")").hide();
                $(".flightsColorCode li:not(." + parentClass + ")").attr("data-dimmed", "true");
                $(".arrivalTable .arrivalSchedule li." + parentClass).show();
                $(".flightsColorCode li." + parentClass).removeAttr("data-dimmed");
            }
        });
    }
    if ($(window).width() > 767) {
        $('.offerDetailsBooking .col-md-6, .entertainmentListing .movieItem').matchHeight();
    }


    $("input[type=text].promoCode,div.promoCode input[type=text]").on("keypress", function (event) {
        var key = String.fromCharCode(event.which);
        var promoCode = /[a-zA-Z0-9]/g;
        if (event.keyCode == 8 || promoCode.test(key))
            return true;
        return false;
    });
    $("input[type=text].promoCode,div.promoCode input[type=text]").on("keyup", function () {
        $(this).val($(this).val().replace(/[^\w]+/g, "").toUpperCase());
    });
});

function countryLanguage() {
    $("header .bookingOffices a").click(function () {
        $(".countriesDD").toggle();
        $('.countriesDD ul').slideUp().removeClass('opened');
    });
    $(".bookingOffices .selectedCountry").html($(".bookingOffices .countriesList ul li.currentOffice").html());
    $(".bookingOffices .selectedLanguage").html($(".bookingOffices .languageList ul li.currentLanguage").html());
    
    $(".bookingOffices .selectedCountry").click(function (e) {
        $(this).next("ul").slideToggle().toggleClass("opened");
        $('.bookingOffices .selectedLanguage + ul').slideUp();
    });
    $(".bookingOffices .selectedLanguage").click(function (e) {
        $(this).next("ul").slideToggle().toggleClass("opened");
        ('.bookingOffices .selectedCountry + ul').slideUp();
    });
    $(".bookingOffices .countriesList ul li").click(function (e) {
        $(this).parent().slideToggle();
        $(".bookingOffices .selectedCountry").html($(this).html());
        $("#hfSelectorCountryID").val($(this).data("country-id"));
        $("#hfSelectorOfficeID").val($(this).data("office-id"));
        $("#hfSelectorCountryName").val($(this).data("country-name"));
        $("#hfSelectorPointOfSale").val($(this).data("pos"));
        $("#hfSelectorRewardsOfficeID").val($(this).data("rewards-office"));
        $("#hfSelectorExternalID").val($(this).data("external-id"));
    });
    $(".bookingOffices .languageList ul li").click(function (e) {
        $(this).parent().slideToggle();
        $(".bookingOffices .selectedLanguage").html($(this).html());
        $("#hfSelectorRedirectLink").val($(this).data("redirect-url"));
    });
    $(".countriesDD .normalBtn").click(function () {
        var CountryID = $("#hfSelectorCountryID").val();
        var OfficeID = $("#hfSelectorOfficeID").val();
        var CountryName = $("#hfSelectorCountryName").val();
        var PointOfSale = $("#hfSelectorPointOfSale").val();
        var RewardsOfficeID = $("#hfSelectorRewardsOfficeID").val();
        var ExternalID = $("#hfSelectorExternalID").val();
        var RedirectLink = $("#hfSelectorRedirectLink").val();
        if (window.location.href == RedirectLink)
            RedirectLink = "";
        SaveCookie(CountryID, OfficeID, CountryName, PointOfSale, RewardsOfficeID, ExternalID, RedirectLink);
    });

    $(document).mouseup(function (e) {
        var container = $(".countriesDD");

        // if the target of the click isn't the container nor a descendant of the container
        if (!container.is(e.target) && container.has(e.target).length === 0) {
            $(".countriesDD").slideUp();
            $('.countriesDD ul').slideUp().removeClass('opened');
        }
    });
}

function SaveCookie(CountryID, OfficeID, CountryName, PointOfSale, RewardsOfficeID, ExternalID, RedirectLink) {
    $("body").prepend("<div class='loader'></div>");
    $.ajax({
        url: '/Home/SaveCookie',
        data: {
            "SiteCookie": false,
            "CountryID": CountryID,
            "OfficeID": OfficeID,
            "PointOfSale": PointOfSale,
            "RewardsOfficeID": RewardsOfficeID,
            "ExternalID": ExternalID
        },
        type: 'GET',
        success: function () {
            //$(".bookingOffices a.currentOffice").html(CountryName);
            //$(".bookingOffices countriesPopup ul").css("display", "block");
            if (RedirectLink != "")
                window.location.href = RedirectLink;
            else
                window.location.reload();
        },
        error: function (e) {
            alert("SaveCookie " + e.responseText);
            $(".loader").remove();
        }
    });
}

$.fn.setCursorPosition = function (pos) {
    this.each(function (index, elem) {
        if (elem.setSelectionRange) {
            elem.setSelectionRange(pos, pos);
        } else if (elem.createTextRange) {
            var range = elem.createTextRange();
            range.collapse(true);
            range.moveEnd('character', pos);
            range.moveStart('character', pos);
            range.select();
        }
    });
    return this;
};
function milesProgress(x) {
    $('.progress .blue-bar').css('left', x + '%');
}

function hpBanner() {
    $('.hpMainBanner').height($(window).height())
}
function menuFunction() {
    $('.ddSecondLevel').width($(window).innerWidth())
}

function tabsTrigger() {
    $('.tabsLinks a').click(function () {
        var $this = $(this);
        var getParent = $this.closest('.tabsMain');
        getParent.find('>.tabsHolder > .tab').hide();
        getParent.find('> .tabsLinks a').not($(this)).removeClass('active');
        $(this).addClass('active');
        getParent.find('> .tabsHolder > .tab:eq(' + $(this).index() + ')').fadeIn();
    })
    $('.tabsMain').each(function (index, element) {
        $(this).find('.tabsLinks a:first').click();
    });
    if (window.location.hash == '#refund') {

        $('.tabsMain').find('.tabsLinks a:eq(1)').click();
    }  
}


function tabsTriggerOffices() {

    $('.tabsLinks a').click(function () {
        var $this = $(this);
        var getParent = $this.closest('.tabsMain');
        getParent.find('.tabsHolder > .tab').hide();
        getParent.find('.tabsLinks a').not($(this)).removeClass('active');
        $(this).addClass('active');
        getParent.find('.tabsHolder > .tab:eq(' + $(this).index() + ')').show();
    })
    $('.tabsMain').each(function (index, element) {
        $(this).find('.tabsLinks a:first').click();
    });

}

function tabsTriggerEntertainment() {

    $('.tabsLinks a').click(function () {
        var $this = $(this);
        var getParent = $this.closest('.tabsMain');
        getParent.find('.tabsHolder > .container > .tab').hide();
        getParent.find('.tabsMain:not(.entSubTabs).tabsLinks a').not($(this)).removeClass('active');
        $(this).addClass('active');
        getParent.find('.tabsHolder > .container> .tab:eq(' + $(this).index() + ')').show();
    })

    $('.tabsMain').each(function (index, element) {
        $(this).find('.tabsLinks a:first').click();
    });

    $('.entSubTabs .tabsLinks a').click(function () {
        var $this = $(this);
        var getParent = $this.closest('.tabsMain');
        getParent.find('.entSubTabs .tabsHolder  .tab').hide();
        getParent.find('.entSubTabs  .tabsLinks a').not($(this)).removeClass('active');
        $(this).addClass('active');
        getParent.find('.entSubTabs .tabsHolder .tab:eq(' + $(this).index() + ')').show();
    })
}

function syncedOwls() {
    var sync1 = $("#sync1");
    var sync2 = $("#sync2");
    var slidesPerPage = 1; //globaly define number of elements per page
    var syncedSecondary = false;

    sync1.owlCarousel({
        items: 1,
        slideSpeed: 2000,
        nav: false,
        autoplay: false,
        dots: false,
        loop: true, animateOut: 'fadeOut',
        responsiveRefreshRate: 200,
        navText: ['<svg width="100%" height="100%" viewBox="0 0 11 20"><path style="fill:none;stroke-width: 1px;stroke: #000;" d="M9.554,1.001l-8.607,8.607l8.607,8.606"/></svg>', '<svg width="100%" height="100%" viewBox="0 0 11 20" version="1.1"><path style="fill:none;stroke-width: 1px;stroke: #000;" d="M1.054,18.214l8.606,-8.606l-8.606,-8.607"/></svg>'],
    }).on('changed.owl.carousel', syncPosition);

    sync2
        .on('initialized.owl.carousel', function () {
            sync2.find(".owl-item").eq(0).addClass("current");
        })
        .owlCarousel({
            items: slidesPerPage,
            dots: false,
            nav: false,
            smartSpeed: 200,
            slideSpeed: 500,

            slideBy: slidesPerPage, //alternatively you can slide by 1, this way the active slide will stick to the first item in the second carousel
            responsiveRefreshRate: 100

        }).on('changed.owl.carousel', syncPosition2);

    function syncPosition(el) {
        //if you set loop to false, you have to restore this next line
        //var current = el.item.index;

        //if you disable loop you have to comment this block
        var count = el.item.count - 1;
        var current = Math.round(el.item.index - (el.item.count / 2) - .5);

        if (current < 0) {
            current = count;
        }
        if (current > count) {
            current = 0;
        }

        //end block

        sync2
            .find(".owl-item")
            .addClass("current")
            .eq(current)
            .removeClass("current");
        var onscreen = sync2.find('.owl-item.active').length - 1;
        var start = sync2.find('.owl-item.active').first().index();
        var end = sync2.find('.owl-item.active').last().index();

        if (current > end) {
            sync2.data('owl.carousel').to(current, 100, true);
        }
        if (current < start) {
            sync2.data('owl.carousel').to(current - onscreen, 100, true);
        }
    }

    function syncPosition2(el) {
        if (syncedSecondary) {
            var number = el.item.index;
            sync1.data('owl.carousel').to(number, 100, true);
        }
    }

    sync2.on("click", ".owl-item", function (e) {
        e.preventDefault();
        var number = $(this).index();
        sync1.data('owl.carousel').to(number, 300, true);
    });

    $('#sync2 .owl-item').addClass('current');
    $('#sync2 .owl-item.current.active').removeClass('current');
}

function syncedOwlsArabic() {
    var sync1 = $("#sync1");
    var sync2 = $("#sync2");
    var slidesPerPage = 1; //globaly define number of elements per page
    var syncedSecondary = false;

    sync1.owlCarousel({
        items: 1,
        slideSpeed: 2000,
        nav: false,
        autoplay: false,
        dots: false,
        rtl: true,
        loop: true, animateOut: 'fadeOut',
        responsiveRefreshRate: 200,
        navText: ['<svg width="100%" height="100%" viewBox="0 0 11 20"><path style="fill:none;stroke-width: 1px;stroke: #000;" d="M9.554,1.001l-8.607,8.607l8.607,8.606"/></svg>', '<svg width="100%" height="100%" viewBox="0 0 11 20" version="1.1"><path style="fill:none;stroke-width: 1px;stroke: #000;" d="M1.054,18.214l8.606,-8.606l-8.606,-8.607"/></svg>'],
    }).on('changed.owl.carousel', syncPosition);

    sync2
        .on('initialized.owl.carousel', function () {
            sync2.find(".owl-item").eq(0).addClass("current");
        })
        .owlCarousel({
            items: slidesPerPage,
            dots: false,
            nav: false,
            smartSpeed: 200,
            slideSpeed: 500,

            slideBy: slidesPerPage, //alternatively you can slide by 1, this way the active slide will stick to the first item in the second carousel
            responsiveRefreshRate: 100

        }).on('changed.owl.carousel', syncPosition2);

    function syncPosition(el) {
        //if you set loop to false, you have to restore this next line
        //var current = el.item.index;

        //if you disable loop you have to comment this block
        var count = el.item.count - 1;
        var current = Math.round(el.item.index - (el.item.count / 2) - .5);

        if (current < 0) {
            current = count;
        }
        if (current > count) {
            current = 0;
        }

        //end block

        sync2
            .find(".owl-item")
            .addClass("current")
            .eq(current)
            .removeClass("current");
        var onscreen = sync2.find('.owl-item.active').length - 1;
        var start = sync2.find('.owl-item.active').first().index();
        var end = sync2.find('.owl-item.active').last().index();

        if (current > end) {
            sync2.data('owl.carousel').to(current, 100, true);
        }
        if (current < start) {
            sync2.data('owl.carousel').to(current - onscreen, 100, true);
        }
    }

    function syncPosition2(el) {
        if (syncedSecondary) {
            var number = el.item.index;
            sync1.data('owl.carousel').to(number, 100, true);
        }
    }

    sync2.on("click", ".owl-item", function (e) {
        e.preventDefault();
        var number = $(this).index();
        sync1.data('owl.carousel').to(number, 300, true);
    });

    $('#sync2 .owl-item').addClass('current');
    $('#sync2 .owl-item.current.active').removeClass('current');
}

function newsBackgroud() {
    value = ($(window).width() - $('.container').width()) / 2
    width = $(window).width() - value + 50
    $('.mainBg').width(width)
}


function travelerCarousel() {
    $('.travelerInfo .owl-carousel').owlCarousel({
        loop: false, margin: 24, nav: true, dots: false, autoWidth: true, responsive: {
            // breakpoint from 0 up
            0: {
                margin: 4,
                nav: false,
            },
            767: {
                margin: 24, nav: true
            }
        }
    })
    marginLeft = (($(window).width() - $('.container').width()) / 2)


    $('.travelerInfo .owl-nav').css('right', marginLeft)

    if (isMobile) {
        $('.travelerInfo .listingInfos').matchHeight({
            byRow: true
        })
    }
}
function travelerCarouselArabic() {
    $('.travelerInfo .owl-carousel').owlCarousel({
        loop: false, margin: 24, nav: true, dots: false, autoWidth: true, rtl: true, responsive: {
            // breakpoint from 0 up
            0: {
                margin: 4,
                nav: false,
                rtl: true,
            },
            767: {
                margin: 24, nav: true, rtl: true,
            }
        }
    })
    marginLeft = (($(window).width() - $('.container').width()) / 2)


    $('.travelerInfo .owl-nav').css('left', marginLeft)

    if (isMobile) {
        $('.travelerInfo .listingInfos').matchHeight({
            byRow: true
        })
    }
}
function bookATrip() {
    try {
        mainHeight = $(window).outerHeight()
        $('.bookTripBlock .leftBlock').css('height', mainHeight)
        $('.bookTripBlock .calendarInfos').css('height', mainHeight)
        $('.bookTripBlock .rightBlock').css('height', mainHeight)
        $('.calendarsBlock').css('height', mainHeight)

        topSectionHeight = $('.topSection').outerHeight()
        bottomSectionHeight = $('.bottomSection').outerHeight()
        totalHeight = mainHeight - (topSectionHeight + bottomSectionHeight + 80)
        blockSameHeight = totalHeight / 2
        //	$('.sameBlock').css('height', blockSameHeight)
    }
    catch (e) {

    }


}

function bookBuyBg() {
    height = $('.bookingtabs .tabsLinks').height()
    widthMargin = ($(window).width() - $('.container').width()) / 2
    $('.leftBackground').css('height', height + 1)
    $('.leftBackground').css('width', widthMargin)

}

function bookType() {
    $('.tripType input').click(function () {
        $('.tripType li').removeClass('active')
        $(this).parent().addClass('active')
    })

    $('.inputEntity.flexibleDate input').click(function () {
        $(this).parent().toggleClass('active');
    })
}



function showMinusAndPlus() {

    $('.calendarInfos .selectNumber').hover(function () {
        var $this = $(this).find('.centeredBlock')
        $this.toggleClass('show')
        $this.parent().find($('.btns')).toggleClass('show')
        if ($this.hasClass('show'))
            $this.animate({ scrollTop: 135 }, 'medium');
        else
            $this.animate({ scrollTop: 0 }, 'medium');
    });
    $('.bookingrow  .selectNumber').hover(function () {
        var $this = $(this).find('.centeredBlock')
        $this.toggleClass('show')
        $this.parent().find($('.btns')).toggleClass('show')
        if ($this.hasClass('show'))
            $this.animate({ scrollTop: 45 }, 'medium');
        else
            $this.animate({ scrollTop: 0 }, 'medium');
    });
}


function scrollDetect() {
    var lastScroll = 0;
    window.onscroll = function () {
        let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value
        if (currentScroll > 500) {
            $('header').addClass('fixed');
            $('header').addClass('color');
            //if (currentScroll > 350) {
            //    if (lastScroll <= currentScroll) {
            //        lastScroll = currentScroll;
            //        $('header').addClass('color').removeClass('show');
            //    } else {
            //        lastScroll = currentScroll;
            //        $('header').addClass('show');
            //    }
            //}
        }
        else if (currentScroll == 0) {
            $('header').removeClass('fixed').removeClass('show').removeClass('color');
        }
    };
}


function progress() {

    try {
        var bar1 = new ProgressBar.Circle("#progress-circle-green1", {
            strokeWidth: 10,
            easing: 'easeInOut',
            duration: 3000,
            color: '#0d795b',
            trailColor: '#d4d4d4',
            trailWidth: 10,
        });
        bar1.animate(0.5);  // Number from 0.0 to 1.0

        var bar2 = new ProgressBar.Circle("#progress-circle-fuschia1", {
            strokeWidth: 10,
            easing: 'easeInOut',
            duration: 3000,
            color: '#ca123d',
            trailColor: '#d4d4d4',
            trailWidth: 10,
        });
        bar2.animate(0.32);  // Number from 0.0 to 1.0

        var bar3 = new ProgressBar.Circle("#progress-circle-green2", {
            strokeWidth: 10,
            easing: 'easeInOut',
            duration: 3000,
            color: '#0d795b',
            trailColor: '#d4d4d4',
            trailWidth: 10,
        });
        bar3.animate(0.5);  // Number from 0.0 to 1.0

        var bar4 = new ProgressBar.Circle("#progress-circle-fuschia2", {
            strokeWidth: 10,
            easing: 'easeInOut',
            duration: 3000,
            color: '#ca123d',
            trailColor: '#d4d4d4',
            trailWidth: 10,
        });
        bar4.animate(0.8);  // Number from 0.0 to 1.0

    } catch (e) {
    }

    try {
        for (var i = 0; i < $("[progress-circle-green-data-percent]").length; i++) {
            var greenCircleId = "#progress-circle-green-" + i;
            var bar1 = new ProgressBar.Circle(greenCircleId, {
                strokeWidth: 10,
                easing: 'easeInOut',
                duration: 3000,
                color: '#0d795b',
                trailColor: '#d4d4d4',
                trailWidth: 10,
            });
            var percentGreen = parseFloat($($("[progress-circle-green-data-percent]")[i]).attr("progress-circle-green-data-percent"))
            bar1.animate(percentGreen);  // Number from 0.0 to 1.0

            var fuschiaCircleId = "#progress-circle-fuschia-" + i;
            var bar2 = new ProgressBar.Circle(fuschiaCircleId, {
                strokeWidth: 10,
                easing: 'easeInOut',
                duration: 1000,
                color: '#ca123d',
                trailColor: '#d4d4d4',
                trailWidth: 10,
            });
            var percentFuchia = parseFloat($($("[progress-circle-fuschia-data-percent]")[i]).attr("progress-circle-fuschia-data-percent"))
            bar2.animate(percentFuchia);  // Number from 0.0 to 1.0
        }

    } catch (e) {
    }

}


function mobileMenu() {
    if ($('body.loggedIn').length > 0) {

        loginContent = $('.loginParent.loggedIn')
    }
    else {
        loginContent = $('.rightMenu .loginParent')
    }

    bookingOfficesContent = $('.rightMenu .bookingOffices')
    //console.log(loginContent.html())
    $('.mainMenuSubClass > ul').prepend('<li class="loginParent">' + loginContent.html() + '</li><li class="bookingOffices">' + bookingOfficesContent.html() + '</li>')
    $(loginContent).html('')
    $(bookingOfficesContent).html('')
    //$('.currentOffice').click(function () {
    //    $('.countriesPopup').addClass('show')
    //})
    //$('.closeCountries').click(function () {
    //    $('.countriesPopup').removeClass('show')
    //})
    morelinks = $('.moreLinks')
    //console.log(morelinks.html())
    $('.pagesMenu .mainMenu>ul').append(morelinks.html())
    $('.hashiddenlinks').html('')
    $('.hashiddenlinks').hide()
    if ($('.pagesMenu a.active').length > 0) {
        activeLink = $('.pagesMenu').find('a.active')
        $(activeLink).parent().addClass('activeMenuParent')
    }
    else {
        activeLink = $('.breadCrumbInsideCont').find('a.active')
    }
    if ($(activeLink) && $(activeLink).length > 0) {
        $('.pagesMenu .mainMenu').prepend('<a href="javascript:;" class="pagesMenuToggle">' + $(activeLink).html() + '</a>')
        $('.pagesMenuToggle').click(function () {
            $(this).parent().find('ul').slideToggle();
            $('.pagesMenu2 ul').slideUp();
        });
        $('.pagesMenu2 .mainMenu').prepend('<a href="javascript:;" class="thirdLevelMenuToggle">More about ' + $(activeLink).html() + '</a>')
        $('.thirdLevelMenuToggle').click(function () {
            $(this).parent().find('ul').slideToggle();
        });
    }

    $('.loggedInMainBtn').click(function () {
        $(this).toggleClass('active');
        $('.loggedInMenu,.loggedInMenunew ').css('opacity', '0');
        $('.loggedInMenu,.loggedInMenunew ').slideToggle();
        setTimeout(function () {
            $('.loggedInMenu,.loggedInMenunew ').css('opacity', '1');
        }, 350);

    })
    countryLanguage();
}
function mobileBookAtrip() {
    mainBlockHeight = $(window).height() - 120
    $('.mainRightBlock').height(mainBlockHeight)
}
function mobileFunctions() {
    setTimeout(function () {
        $('.latestNews ul').addClass('owl-carousel')
        $('.latestNews .owl-carousel').owlCarousel({ loop: false, margin: 15, nav: false, dots: false, autoWidth: true })
        $('.privilegesTable').parent().addClass('tableParent')
    }, 500);

}
function mobileFunctionsArabic() {
    setTimeout(function () {
        $('.latestNews ul').addClass('owl-carousel')
        $('.latestNews .owl-carousel').owlCarousel({ loop: false, margin: 15, nav: false, dots: false, autoWidth: true, rtl: true })
        $('.privilegesTable').parent().addClass('tableParent')
    }, 500);

}

function mainMenuHover() {
    $('.hasSubmenu').hover(function () {
        $('body').addClass('withHoveredSearch');
    }, function () {
        $('body').removeClass('withHoveredSearch');
    });
    $('.fullScreenLinks li').hover(function () {
    });




    $('.fullScreenLinks li:eq(0)').hover(function () {
        $('.hpMainBanner').addClass('bookAndBuyBg');
    }, function () {
        $('.hpMainBanner').removeClass('bookAndBuyBg');
    });
    $('.fullScreenLinks li:eq(1)').hover(function () {
        $('.hpMainBanner').addClass('onlineCheckInBg');
    }, function () {
        $('.hpMainBanner').removeClass('onlineCheckInBg');
    });
    $('.fullScreenLinks li:eq(2)').hover(function () {
        $('.hpMainBanner').addClass('checkMyTripBg');
    }, function () {
        $('.hpMainBanner').removeClass('checkMyTripBg');
    });
    $('.fullScreenLinks li:eq(3)').hover(function () {
        $('.hpMainBanner').addClass('flightScheduleBg');
    }, function () {
        $('.hpMainBanner').removeClass('flightScheduleBg');
    });
}


function counterAnimation() {
    $('.aboutAirport .bigNumber.withCounter').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(parseFloat(now).toFixed(size));
                }
            });

    });
}


function counterAnimation2() {
    $('.myAccountDashboard h4.withCounter').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function counterAnimation3() {
    $('.numberOfMiles span.withCounter').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}

function trainingCenterNumber1() {
    $('h5#trainingCenterNumber1').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $('h5#trainingCenterNumber1').prop('Counter', 0).animate({
            Counter: 4000
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function trainingCenterNumber2() {
    $('h5#trainingCenterNumber2').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $('h5#trainingCenterNumber2').prop('Counter', 0).animate({
            Counter: 11500
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function trainingCenterNumber3() {
    $('h5#trainingCenterNumber3').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $('h5#trainingCenterNumber3').prop('Counter', 0).animate({
            Counter: 17000
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function trainingCenterNumber4() {
    $('h5#trainingCenterNumber4').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $('h5#trainingCenterNumber4').prop('Counter', 0).animate({
            Counter: 11000
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function counterAnimation4() {
    $('.progress-info .number.withAnimation.withCounter').each(function (index) {
        var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
        $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
        }, {
                duration: 3000,
                step: function (now) {
                    $(this).text(Math.ceil(now).toLocaleString('en'));
                }
            });

    });
}
function bookandbuyMobile() {
    if ($('.bookandbuy .option').length > 0) {
        
        var activeTabLink = $('.tabsLinks a.active');
        $('.tabsLinks a.active').addClass('hidden');
        $('.tabsMain').not('.rendered').addClass('rendered').prepend(' <a href="javascript:;" class="tabsMobileToggle">' + $(activeTabLink).html() + '</a>')
        $('.tabsMobileToggle').not('.rendered').addClass('rendered').click(function () {
            $('.tabsLinks').slideToggle()
        })
        $('.tabsLinks a').click(function () {
            $('.tabsLinks').slideToggle()
            var newActiveTab = $(this).html()
            $('.tabsLinks a').removeClass('hidden')
            $(this).addClass('hidden')

            $('.tabsMobileToggle').html(newActiveTab)
        })
    }
}
function entertainmentMobile() {
    if ($('.entertainmentTabs').length > 0) {


        //$('.entertainmentTabs .tabsMobileToggle').not('.rendered').addClass('rendered').click(function () {
        //    $('.entertainmentTabs .tabsLinks').slideToggle()
        //})
        setTimeout(function () {
            var activeTabLink = $('.tabsMain:not(.entSubTabs) > .tabsLinks  a.active')
            $('.entertainmentTabs').prepend(' <a href="javascript:;" class="tabsMobileToggle">' + activeTabLink.text() + '</a>')
            $('.tabsMain:not(.entSubTabs) > .tabsLinks a.active').addClass('hidden')
            $('.tabsMobileToggle').click(function () {
                $('.tabsMain:not(.entSubTabs) > .tabsLinks').slideToggle()
            })
            $('.tabsMain:not(.entSubTabs) > .tabsLinks a').click(function () {
                $('.tabsMain:not(.entSubTabs) > .tabsLinks').slideToggle()
                var newActiveTab = $(this).html()
                $('.tabsMain:not(.entSubTabs) > .tabsLinks a').removeClass('hidden')
                $(this).addClass('hidden')
                $('.entertainmentTabs .tabsMobileToggle').html(newActiveTab)
            })
        }, 500);
       
       
        
        //$('.entertainmentTabs .tabsMobileToggle').text(activeTabLink.text());
        
       
    }
}

var isMobile = false
if ($(window).width() < 767) {
    isMobile = true

}
else {
    isMobile = false
}

function checkIfMobile() {
    var check = false;
    (function (a, b) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true })(navigator.userAgent || navigator.vendor || window.opera, 'http://detectmobilebrowser.com/mobile');
    return check;
}

function SaveAllowCookie() {
    $("#divAllowCookies").hide();
    $.ajax({
        url: '/Home/SaveCookie',
        data: {
            "SiteCookie": true,
            "CountryID": "",
            "OfficeID": "",
            "PointOfSale": "",
            "RewardsOfficeID": "",
            "ExternalID": ""
        },
        type: 'GET'
    });
}

function SaveCovidTerms() {
    $("#divCovidTerms").hide();
    if ($(".divCovidTerms:visible").length == 0) {
        $("#hfAcceptedCovidTerms").val("2");
        if ($(".homePage").length > 0)
            $(".formActions.booking input[type=submit]").click();
        else {
            var attr = $("#divBookingForm").attr("data-triptype");
            if (attr == "roundtrip")
                $("#divBookingForm .tab.container[data-attribute=roundtrip] input[type=submit]").click();
            if (attr == "oneway")
                $("#divBookingForm .tab.container[data-attribute=oneway] input[type=submit]").click();
            if (attr == "multi")
                $("#divBookingForm .tab.container[data-attribute=multi] input[type=submit]").click();
        }
    }
}
function SaveCovidTerms1() {
    $("#divCovidTerms1").hide();
    if ($(".divCovidTerms:visible").length == 0) {
        $("#hfAcceptedCovidTerms").val("2");
        if ($(".homePage").length > 0)
            $(".formActions.booking input[type=submit]").click();
        else {
            var attr = $("#divBookingForm").attr("data-triptype");
            if (attr == "roundtrip")
                $("#divBookingForm .tab.container[data-attribute=roundtrip] input[type=submit]").click();
            if (attr == "oneway")
                $("#divBookingForm .tab.container[data-attribute=oneway] input[type=submit]").click();
            if (attr == "multi")
                $("#divBookingForm .tab.container[data-attribute=multi] input[type=submit]").click();
        }
    }
}
function SaveCovidTermsAth() {
    $("#divCovidTermsAth").hide();    
    if ($(".divCovidTerms:visible").length == 0) {
        $("#hfAcceptedCovidTerms").val("2");
        if ($(".homePage").length > 0)
            $(".formActions.booking input[type=submit]").click();
        else {
            var attr = $("#divBookingForm").attr("data-triptype");
            if (attr == "roundtrip")
                $("#divBookingForm .tab.container[data-attribute=roundtrip] input[type=submit]").click();
            if (attr == "oneway")
                $("#divBookingForm .tab.container[data-attribute=oneway] input[type=submit]").click();
            if (attr == "multi")
                $("#divBookingForm .tab.container[data-attribute=multi] input[type=submit]").click();
        }
    }
}
function SaveCovidTermsLca() {
    $("#divCovidTermsLca").hide();
    if ($(".divCovidTerms:visible").length == 0) {
        $("#hfAcceptedCovidTerms").val("2");
        if ($(".homePage").length > 0)
            $(".formActions.booking input[type=submit]").click();
        else {
            var attr = $("#divBookingForm").attr("data-triptype");
            if (attr == "roundtrip")
                $("#divBookingForm .tab.container[data-attribute=roundtrip] input[type=submit]").click();
            if (attr == "oneway")
                $("#divBookingForm .tab.container[data-attribute=oneway] input[type=submit]").click();
            if (attr == "multi")
                $("#divBookingForm .tab.container[data-attribute=multi] input[type=submit]").click();
        }
    }
}
function SaveCovidTermsAmm() {
    $("#divCovidTermsAmm").hide();
    if ($(".divCovidTerms:visible").length == 0) {
        $("#hfAcceptedCovidTerms").val("2");
        if ($(".homePage").length > 0)
            $(".formActions.booking input[type=submit]").click();
        else {
            var attr = $("#divBookingForm").attr("data-triptype");
            if (attr == "roundtrip")
                $("#divBookingForm .tab.container[data-attribute=roundtrip] input[type=submit]").click();
            if (attr == "oneway")
                $("#divBookingForm .tab.container[data-attribute=oneway] input[type=submit]").click();
            if (attr == "multi")
                $("#divBookingForm .tab.container[data-attribute=multi] input[type=submit]").click();
        }
    }
}

function formatDayNumber(dayNumber) {
    if (parseInt(dayNumber) < 10) {
        dayNumber = "0" + dayNumber;
    }
    return dayNumber
}

function printCard() {
    var disp_setting = "toolbar=no,location=no,directories=no,menubar=no,";
    disp_setting += "scrollbars=yes,width=960, height=500, right=100, top=100";
    var content_value = $(".printarea").html()
    var docprint = window.open("", "", disp_setting);
    docprint.document.open();
    docprint.document.write("<html><head><title>Middle East Airlines</title>");
    docprint.document.write("<link rel='stylesheet' type='text/css' href='/styles/mea-v3.css' />");
    docprint.document.write("<link rel='stylesheet' type='text/css' href='/styles/mea-v3-responsive.css' />");
    docprint.document.write("<link rel='stylesheet' type='text/css' href='/styles/print.css' />");
    docprint.document.write("<body onload='self.print();self.close();'><div class='myAccountDashboard'><div class='accountContent'><div class='cardHolder'>" + content_value + "</div></div></div>");
    docprint.document.write("</body></html>");
    docprint.document.close();
    docprint.focus();
}

function inputFunctions() {
   
   
    $('.loginWrapper .greyBlock .inputParent input[type="email"],.loginWrapper .greyBlock .inputParent input[type="text"]').on('focusin',
        function () {
            if ($(this).hasClass('input-validation-error')){
                return;
            } else {
                $(this).parent().addClass('focused');
            }

        }).on('focusout', function () {
            $(this).parent().removeClass('focused');

        });
       
    $('.loginWrapper input[type="submit"]').click(function () {

        setTimeout(() => {
            if ($(this).parent().find('input[type="email"]').hasClass('input-validation-error')) {
                $(this).focus();
                $(this).parent().find('.inputParent').addClass('error');
            }
        }, "20")
        
    })
   
}
$(document).ready(function () {
        AOS.init();
    $('.RailFly .whiteBox').matchHeight({
        byRow: true
    })
    if ($('.topNotificationBanner').length > 0) {
        $('body').addClass('withNotification');
    }
    $('.closeNotification').click(function () {
        $('.topNotificationBanner').hide();
        $('body').removeClass('withNotification');
    });
    inputFunctions();
});;
