').append(this.$clear)))},value2html:function(a,c){var d=a?this.dpg.formatDate(a,this.parsedViewFormat,this.options.datepicker.language):"";b.superclass.value2html.call(this,d,c)},html2value:function(a){return this.parseDate(a,this.parsedViewFormat)},value2str:function(a){return a?this.dpg.formatDate(a,this.parsedFormat,this.options.datepicker.language):""},str2value:function(a){return this.parseDate(a,this.parsedFormat)},value2submit:function(a){return this.value2str(a)},value2input:function(a){this.$input.bdatepicker("update",a)},input2value:function(){return this.$input.data("datepicker").date},activate:function(){},clear:function(){this.$input.data("datepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".day",function(b){if(!a(b.currentTarget).is(".old")&&!a(b.currentTarget).is(".new")){var c=a(this).closest("form");setTimeout(function(){c.submit()},200)}})},parseDate:function(a,b){var c,d=null;return a&&(d=this.dpg.parseDate(a,b,this.options.datepicker.language),"string"==typeof a&&(c=this.dpg.formatDate(d,b,this.options.datepicker.language),a!==c&&(d=null))),d}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd",viewformat:null,datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!1},clear:"× clear"}),a.fn.editabletypes.date=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datefield",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.date),a.extend(b.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.bdatepicker(this.options.datepicker),this.$input.off("focus keydown"),this.$input.keyup(a.proxy(function(){this.$tpl.removeData("date"),this.$tpl.bdatepicker("update")},this))},value2input:function(a){this.$input.val(a?this.dpg.formatDate(a,this.parsedViewFormat,this.options.datepicker.language):""),this.$tpl.bdatepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),b.defaults=a.extend({},a.fn.editabletypes.date.defaults,{tpl:'
',inputclass:"input-small",datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!0}}),a.fn.editabletypes.datefield=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datetime",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{initPicker:function(b,c){this.options.viewformat||(this.options.viewformat=this.options.format),b.datetimepicker=a.fn.editableutils.tryParseJson(b.datetimepicker,!0),this.options.datetimepicker=a.extend({},c.datetimepicker,b.datetimepicker,{format:this.options.viewformat}),this.options.datetimepicker.language=this.options.datetimepicker.language||"en",this.dpg=a.fn.datetimepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.format,this.options.formatType),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat,this.options.formatType)},render:function(){this.$input.datetimepicker(this.options.datetimepicker),this.$input.on("changeMode",function(){var b=a(this).closest("form").parent();setTimeout(function(){b.triggerHandler("resize")},0)}),this.options.clear&&(this.$clear=a('
').html(this.options.clear).click(a.proxy(function(a){a.preventDefault(),a.stopPropagation(),this.clear()},this)),this.$tpl.parent().append(a('
').append(this.$clear)))},value2html:function(a,c){var d=a?this.dpg.formatDate(this.toUTC(a),this.parsedViewFormat,this.options.datetimepicker.language,this.options.formatType):"";return c?(b.superclass.value2html.call(this,d,c),void 0):d},html2value:function(a){var b=this.parseDate(a,this.parsedViewFormat);return b?this.fromUTC(b):null},value2str:function(a){return a?this.dpg.formatDate(this.toUTC(a),this.parsedFormat,this.options.datetimepicker.language,this.options.formatType):""},str2value:function(a){var b=this.parseDate(a,this.parsedFormat);return b?this.fromUTC(b):null},value2submit:function(a){return this.value2str(a)},value2input:function(a){a&&this.$input.data("datetimepicker").setDate(a)},input2value:function(){var a=this.$input.data("datetimepicker");return a.date?a.getDate():null},activate:function(){},clear:function(){this.$input.data("datetimepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".minute",function(){var b=a(this).closest("form");setTimeout(function(){b.submit()},200)})},toUTC:function(a){return a?new Date(a.valueOf()-6e4*a.getTimezoneOffset()):a},fromUTC:function(a){return a?new Date(a.valueOf()+6e4*a.getTimezoneOffset()):a},parseDate:function(a,b){var c,d=null;return a&&(d=this.dpg.parseDate(a,b,this.options.datetimepicker.language,this.options.formatType),"string"==typeof a&&(c=this.dpg.formatDate(d,b,this.options.datetimepicker.language,this.options.formatType),a!==c&&(d=null))),d}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd hh:ii",formatType:"standard",viewformat:null,datetimepicker:{todayHighlight:!1,autoclose:!1},clear:"× clear"}),a.fn.editabletypes.datetime=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("datetimefield",a,b.defaults),this.initPicker(a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.datetime),a.extend(b.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.datetimepicker(this.options.datetimepicker),this.$input.off("focus keydown"),this.$input.keyup(a.proxy(function(){this.$tpl.removeData("date"),this.$tpl.datetimepicker("update")},this))},value2input:function(a){this.$input.val(this.value2html(a)),this.$tpl.datetimepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),b.defaults=a.extend({},a.fn.editabletypes.datetime.defaults,{tpl:'
',inputclass:"input-medium",datetimepicker:{todayHighlight:!1,autoclose:!0}}),a.fn.editabletypes.datetimefield=b}(window.jQuery);
\ No newline at end of file
diff --git a/src/main/resources/webapp/js/bootstrap.min.js b/src/main/resources/webapp/js/bootstrap.min.js
new file mode 100755
index 0000000..14756fa
--- /dev/null
+++ b/src/main/resources/webapp/js/bootstrap.min.js
@@ -0,0 +1,706 @@
+/*!
+ * Bootstrap v3.3.2 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if ("undefined" == typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");
++function (a) {
+ "use strict";
+ var b = a.fn.jquery.split(" ")[0].split(".");
+ if (b[0] < 2 && b[1] < 9 || 1 == b[0] && 9 == b[1] && b[2] < 1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")
+}(jQuery), +function (a) {
+ "use strict";
+ function b() {
+ var a = document.createElement("bootstrap"), b = {WebkitTransition: "webkitTransitionEnd", MozTransition: "transitionend", OTransition: "oTransitionEnd otransitionend", transition: "transitionend"};
+ for (var c in b)if (void 0 !== a.style[c])return{end: b[c]};
+ return!1
+ }
+
+ a.fn.emulateTransitionEnd = function (b) {
+ var c = !1, d = this;
+ a(this).one("bsTransitionEnd", function () {
+ c = !0
+ });
+ var e = function () {
+ c || a(d).trigger(a.support.transition.end)
+ };
+ return setTimeout(e, b), this
+ }, a(function () {
+ a.support.transition = b(), a.support.transition && (a.event.special.bsTransitionEnd = {bindType: a.support.transition.end, delegateType: a.support.transition.end, handle: function (b) {
+ return a(b.target).is(this) ? b.handleObj.handler.apply(this, arguments) : void 0
+ }})
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var c = a(this), e = c.data("bs.alert");
+ e || c.data("bs.alert", e = new d(this)), "string" == typeof b && e[b].call(c)
+ })
+ }
+
+ var c = '[data-dismiss="alert"]', d = function (b) {
+ a(b).on("click", c, this.close)
+ };
+ d.VERSION = "3.3.2", d.TRANSITION_DURATION = 150, d.prototype.close = function (b) {
+ function c() {
+ g.detach().trigger("closed.bs.alert").remove()
+ }
+
+ var e = a(this), f = e.attr("data-target");
+ f || (f = e.attr("href"), f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
+ var g = a(f);
+ b && b.preventDefault(), g.length || (g = e.closest(".alert")), g.trigger(b = a.Event("close.bs.alert")), b.isDefaultPrevented() || (g.removeClass("in"), a.support.transition && g.hasClass("fade") ? g.one("bsTransitionEnd", c).emulateTransitionEnd(d.TRANSITION_DURATION) : c())
+ };
+ var e = a.fn.alert;
+ a.fn.alert = b, a.fn.alert.Constructor = d, a.fn.alert.noConflict = function () {
+ return a.fn.alert = e, this
+ }, a(document).on("click.bs.alert.data-api", c, d.prototype.close)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.button"), f = "object" == typeof b && b;
+ e || d.data("bs.button", e = new c(this, f)), "toggle" == b ? e.toggle() : b && e.setState(b)
+ })
+ }
+
+ var c = function (b, d) {
+ this.$element = a(b), this.options = a.extend({}, c.DEFAULTS, d), this.isLoading = !1
+ };
+ c.VERSION = "3.3.2", c.DEFAULTS = {loadingText: "loading..."}, c.prototype.setState = function (b) {
+ var c = "disabled", d = this.$element, e = d.is("input") ? "val" : "html", f = d.data();
+ b += "Text", null == f.resetText && d.data("resetText", d[e]()), setTimeout(a.proxy(function () {
+ d[e](null == f[b] ? this.options[b] : f[b]), "loadingText" == b ? (this.isLoading = !0, d.addClass(c).attr(c, c)) : this.isLoading && (this.isLoading = !1, d.removeClass(c).removeAttr(c))
+ }, this), 0)
+ }, c.prototype.toggle = function () {
+ var a = !0, b = this.$element.closest('[data-toggle="buttons"]');
+ if (b.length) {
+ var c = this.$element.find("input");
+ "radio" == c.prop("type") && (c.prop("checked") && this.$element.hasClass("active") ? a = !1 : b.find(".active").removeClass("active")), a && c.prop("checked", !this.$element.hasClass("active")).trigger("change")
+ } else this.$element.attr("aria-pressed", !this.$element.hasClass("active"));
+ a && this.$element.toggleClass("active")
+ };
+ var d = a.fn.button;
+ a.fn.button = b, a.fn.button.Constructor = c, a.fn.button.noConflict = function () {
+ return a.fn.button = d, this
+ }, a(document).on("click.bs.button.data-api", '[data-toggle^="button"]', function (c) {
+ var d = a(c.target);
+ d.hasClass("btn") || (d = d.closest(".btn")), b.call(d, "toggle"), c.preventDefault()
+ }).on("focus.bs.button.data-api blur.bs.button.data-api", '[data-toggle^="button"]', function (b) {
+ a(b.target).closest(".btn").toggleClass("focus", /^focus(in)?$/.test(b.type))
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.carousel"), f = a.extend({}, c.DEFAULTS, d.data(), "object" == typeof b && b), g = "string" == typeof b ? b : f.slide;
+ e || d.data("bs.carousel", e = new c(this, f)), "number" == typeof b ? e.to(b) : g ? e[g]() : f.interval && e.pause().cycle()
+ })
+ }
+
+ var c = function (b, c) {
+ this.$element = a(b), this.$indicators = this.$element.find(".carousel-indicators"), this.options = c, this.paused = this.sliding = this.interval = this.$active = this.$items = null, this.options.keyboard && this.$element.on("keydown.bs.carousel", a.proxy(this.keydown, this)), "hover" == this.options.pause && !("ontouchstart"in document.documentElement) && this.$element.on("mouseenter.bs.carousel", a.proxy(this.pause, this)).on("mouseleave.bs.carousel", a.proxy(this.cycle, this))
+ };
+ c.VERSION = "3.3.2", c.TRANSITION_DURATION = 600, c.DEFAULTS = {interval: 5e3, pause: "hover", wrap: !0, keyboard: !0}, c.prototype.keydown = function (a) {
+ if (!/input|textarea/i.test(a.target.tagName)) {
+ switch (a.which) {
+ case 37:
+ this.prev();
+ break;
+ case 39:
+ this.next();
+ break;
+ default:
+ return
+ }
+ a.preventDefault()
+ }
+ }, c.prototype.cycle = function (b) {
+ return b || (this.paused = !1), this.interval && clearInterval(this.interval), this.options.interval && !this.paused && (this.interval = setInterval(a.proxy(this.next, this), this.options.interval)), this
+ }, c.prototype.getItemIndex = function (a) {
+ return this.$items = a.parent().children(".item"), this.$items.index(a || this.$active)
+ }, c.prototype.getItemForDirection = function (a, b) {
+ var c = this.getItemIndex(b), d = "prev" == a && 0 === c || "next" == a && c == this.$items.length - 1;
+ if (d && !this.options.wrap)return b;
+ var e = "prev" == a ? -1 : 1, f = (c + e) % this.$items.length;
+ return this.$items.eq(f)
+ }, c.prototype.to = function (a) {
+ var b = this, c = this.getItemIndex(this.$active = this.$element.find(".item.active"));
+ return a > this.$items.length - 1 || 0 > a ? void 0 : this.sliding ? this.$element.one("slid.bs.carousel", function () {
+ b.to(a)
+ }) : c == a ? this.pause().cycle() : this.slide(a > c ? "next" : "prev", this.$items.eq(a))
+ }, c.prototype.pause = function (b) {
+ return b || (this.paused = !0), this.$element.find(".next, .prev").length && a.support.transition && (this.$element.trigger(a.support.transition.end), this.cycle(!0)), this.interval = clearInterval(this.interval), this
+ }, c.prototype.next = function () {
+ return this.sliding ? void 0 : this.slide("next")
+ }, c.prototype.prev = function () {
+ return this.sliding ? void 0 : this.slide("prev")
+ }, c.prototype.slide = function (b, d) {
+ var e = this.$element.find(".item.active"), f = d || this.getItemForDirection(b, e), g = this.interval, h = "next" == b ? "left" : "right", i = this;
+ if (f.hasClass("active"))return this.sliding = !1;
+ var j = f[0], k = a.Event("slide.bs.carousel", {relatedTarget: j, direction: h});
+ if (this.$element.trigger(k), !k.isDefaultPrevented()) {
+ if (this.sliding = !0, g && this.pause(), this.$indicators.length) {
+ this.$indicators.find(".active").removeClass("active");
+ var l = a(this.$indicators.children()[this.getItemIndex(f)]);
+ l && l.addClass("active")
+ }
+ var m = a.Event("slid.bs.carousel", {relatedTarget: j, direction: h});
+ return a.support.transition && this.$element.hasClass("slide") ? (f.addClass(b), f[0].offsetWidth, e.addClass(h), f.addClass(h), e.one("bsTransitionEnd", function () {
+ f.removeClass([b, h].join(" ")).addClass("active"), e.removeClass(["active", h].join(" ")), i.sliding = !1, setTimeout(function () {
+ i.$element.trigger(m)
+ }, 0)
+ }).emulateTransitionEnd(c.TRANSITION_DURATION)) : (e.removeClass("active"), f.addClass("active"), this.sliding = !1, this.$element.trigger(m)), g && this.cycle(), this
+ }
+ };
+ var d = a.fn.carousel;
+ a.fn.carousel = b, a.fn.carousel.Constructor = c, a.fn.carousel.noConflict = function () {
+ return a.fn.carousel = d, this
+ };
+ var e = function (c) {
+ var d, e = a(this), f = a(e.attr("data-target") || (d = e.attr("href")) && d.replace(/.*(?=#[^\s]+$)/, ""));
+ if (f.hasClass("carousel")) {
+ var g = a.extend({}, f.data(), e.data()), h = e.attr("data-slide-to");
+ h && (g.interval = !1), b.call(f, g), h && f.data("bs.carousel").to(h), c.preventDefault()
+ }
+ };
+ a(document).on("click.bs.carousel.data-api", "[data-slide]", e).on("click.bs.carousel.data-api", "[data-slide-to]", e), a(window).on("load", function () {
+ a('[data-ride="carousel"]').each(function () {
+ var c = a(this);
+ b.call(c, c.data())
+ })
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ var c, d = b.attr("data-target") || (c = b.attr("href")) && c.replace(/.*(?=#[^\s]+$)/, "");
+ return a(d)
+ }
+
+ function c(b) {
+ return this.each(function () {
+ var c = a(this), e = c.data("bs.collapse"), f = a.extend({}, d.DEFAULTS, c.data(), "object" == typeof b && b);
+ !e && f.toggle && "show" == b && (f.toggle = !1), e || c.data("bs.collapse", e = new d(this, f)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var d = function (b, c) {
+ this.$element = a(b), this.options = a.extend({}, d.DEFAULTS, c), this.$trigger = a(this.options.trigger).filter('[href="#' + b.id + '"], [data-target="#' + b.id + '"]'), this.transitioning = null, this.options.parent ? this.$parent = this.getParent() : this.addAriaAndCollapsedClass(this.$element, this.$trigger), this.options.toggle && this.toggle()
+ };
+ d.VERSION = "3.3.2", d.TRANSITION_DURATION = 350, d.DEFAULTS = {toggle: !0, trigger: '[data-toggle="collapse"]'}, d.prototype.dimension = function () {
+ var a = this.$element.hasClass("width");
+ return a ? "width" : "height"
+ }, d.prototype.show = function () {
+ if (!this.transitioning && !this.$element.hasClass("in")) {
+ var b, e = this.$parent && this.$parent.children(".panel").children(".in, .collapsing");
+ if (!(e && e.length && (b = e.data("bs.collapse"), b && b.transitioning))) {
+ var f = a.Event("show.bs.collapse");
+ if (this.$element.trigger(f), !f.isDefaultPrevented()) {
+ e && e.length && (c.call(e, "hide"), b || e.data("bs.collapse", null));
+ var g = this.dimension();
+ this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded", !0), this.$trigger.removeClass("collapsed").attr("aria-expanded", !0), this.transitioning = 1;
+ var h = function () {
+ this.$element.removeClass("collapsing").addClass("collapse in")[g](""), this.transitioning = 0, this.$element.trigger("shown.bs.collapse")
+ };
+ if (!a.support.transition)return h.call(this);
+ var i = a.camelCase(["scroll", g].join("-"));
+ this.$element.one("bsTransitionEnd", a.proxy(h, this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])
+ }
+ }
+ }
+ }, d.prototype.hide = function () {
+ if (!this.transitioning && this.$element.hasClass("in")) {
+ var b = a.Event("hide.bs.collapse");
+ if (this.$element.trigger(b), !b.isDefaultPrevented()) {
+ var c = this.dimension();
+ this.$element[c](this.$element[c]())[0].offsetHeight, this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded", !1), this.$trigger.addClass("collapsed").attr("aria-expanded", !1), this.transitioning = 1;
+ var e = function () {
+ this.transitioning = 0, this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")
+ };
+ return a.support.transition ? void this.$element[c](0).one("bsTransitionEnd", a.proxy(e, this)).emulateTransitionEnd(d.TRANSITION_DURATION) : e.call(this)
+ }
+ }
+ }, d.prototype.toggle = function () {
+ this[this.$element.hasClass("in") ? "hide" : "show"]()
+ }, d.prototype.getParent = function () {
+ return a(this.options.parent).find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]').each(a.proxy(function (c, d) {
+ var e = a(d);
+ this.addAriaAndCollapsedClass(b(e), e)
+ }, this)).end()
+ }, d.prototype.addAriaAndCollapsedClass = function (a, b) {
+ var c = a.hasClass("in");
+ a.attr("aria-expanded", c), b.toggleClass("collapsed", !c).attr("aria-expanded", c)
+ };
+ var e = a.fn.collapse;
+ a.fn.collapse = c, a.fn.collapse.Constructor = d, a.fn.collapse.noConflict = function () {
+ return a.fn.collapse = e, this
+ }, a(document).on("click.bs.collapse.data-api", '[data-toggle="collapse"]', function (d) {
+ var e = a(this);
+ e.attr("data-target") || d.preventDefault();
+ var f = b(e), g = f.data("bs.collapse"), h = g ? "toggle" : a.extend({}, e.data(), {trigger: this});
+ c.call(f, h)
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ b && 3 === b.which || (a(e).remove(), a(f).each(function () {
+ var d = a(this), e = c(d), f = {relatedTarget: this};
+ e.hasClass("open") && (e.trigger(b = a.Event("hide.bs.dropdown", f)), b.isDefaultPrevented() || (d.attr("aria-expanded", "false"), e.removeClass("open").trigger("hidden.bs.dropdown", f)))
+ }))
+ }
+
+ function c(b) {
+ var c = b.attr("data-target");
+ c || (c = b.attr("href"), c = c && /#[A-Za-z]/.test(c) && c.replace(/.*(?=#[^\s]*$)/, ""));
+ var d = c && a(c);
+ return d && d.length ? d : b.parent()
+ }
+
+ function d(b) {
+ return this.each(function () {
+ var c = a(this), d = c.data("bs.dropdown");
+ d || c.data("bs.dropdown", d = new g(this)), "string" == typeof b && d[b].call(c)
+ })
+ }
+
+ var e = ".dropdown-backdrop", f = '[data-toggle="dropdown"]', g = function (b) {
+ a(b).on("click.bs.dropdown", this.toggle)
+ };
+ g.VERSION = "3.3.2", g.prototype.toggle = function (d) {
+ var e = a(this);
+ if (!e.is(".disabled, :disabled")) {
+ var f = c(e), g = f.hasClass("open");
+ if (b(), !g) {
+ "ontouchstart"in document.documentElement && !f.closest(".navbar-nav").length && a('
').insertAfter(a(this)).on("click", b);
+ var h = {relatedTarget: this};
+ if (f.trigger(d = a.Event("show.bs.dropdown", h)), d.isDefaultPrevented())return;
+ e.trigger("focus").attr("aria-expanded", "true"), f.toggleClass("open").trigger("shown.bs.dropdown", h)
+ }
+ return!1
+ }
+ }, g.prototype.keydown = function (b) {
+ if (/(38|40|27|32)/.test(b.which) && !/input|textarea/i.test(b.target.tagName)) {
+ var d = a(this);
+ if (b.preventDefault(), b.stopPropagation(), !d.is(".disabled, :disabled")) {
+ var e = c(d), g = e.hasClass("open");
+ if (!g && 27 != b.which || g && 27 == b.which)return 27 == b.which && e.find(f).trigger("focus"), d.trigger("click");
+ var h = " li:not(.divider):visible a", i = e.find('[role="menu"]' + h + ', [role="listbox"]' + h);
+ if (i.length) {
+ var j = i.index(b.target);
+ 38 == b.which && j > 0 && j--, 40 == b.which && j < i.length - 1 && j++, ~j || (j = 0), i.eq(j).trigger("focus")
+ }
+ }
+ }
+ };
+ var h = a.fn.dropdown;
+ a.fn.dropdown = d, a.fn.dropdown.Constructor = g, a.fn.dropdown.noConflict = function () {
+ return a.fn.dropdown = h, this
+ }, a(document).on("click.bs.dropdown.data-api", b).on("click.bs.dropdown.data-api", ".dropdown form", function (a) {
+ a.stopPropagation()
+ }).on("click.bs.dropdown.data-api", f, g.prototype.toggle).on("keydown.bs.dropdown.data-api", f, g.prototype.keydown).on("keydown.bs.dropdown.data-api", '[role="menu"]', g.prototype.keydown).on("keydown.bs.dropdown.data-api", '[role="listbox"]', g.prototype.keydown)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b, d) {
+ return this.each(function () {
+ var e = a(this), f = e.data("bs.modal"), g = a.extend({}, c.DEFAULTS, e.data(), "object" == typeof b && b);
+ f || e.data("bs.modal", f = new c(this, g)), "string" == typeof b ? f[b](d) : g.show && f.show(d)
+ })
+ }
+
+ var c = function (b, c) {
+ this.options = c, this.$body = a(document.body), this.$element = a(b), this.$backdrop = this.isShown = null, this.scrollbarWidth = 0, this.options.remote && this.$element.find(".modal-content").load(this.options.remote, a.proxy(function () {
+ this.$element.trigger("loaded.bs.modal")
+ }, this))
+ };
+ c.VERSION = "3.3.2", c.TRANSITION_DURATION = 300, c.BACKDROP_TRANSITION_DURATION = 150, c.DEFAULTS = {backdrop: !0, keyboard: !0, show: !0}, c.prototype.toggle = function (a) {
+ return this.isShown ? this.hide() : this.show(a)
+ }, c.prototype.show = function (b) {
+ var d = this, e = a.Event("show.bs.modal", {relatedTarget: b});
+ this.$element.trigger(e), this.isShown || e.isDefaultPrevented() || (this.isShown = !0, this.checkScrollbar(), this.setScrollbar(), this.$body.addClass("modal-open"), this.escape(), this.resize(), this.$element.on("click.dismiss.bs.modal", '[data-dismiss="modal"]', a.proxy(this.hide, this)), this.backdrop(function () {
+ var e = a.support.transition && d.$element.hasClass("fade");
+ d.$element.parent().length || d.$element.appendTo(d.$body), d.$element.show().scrollTop(0), d.options.backdrop && d.adjustBackdrop(), d.adjustDialog(), e && d.$element[0].offsetWidth, d.$element.addClass("in").attr("aria-hidden", !1), d.enforceFocus();
+ var f = a.Event("shown.bs.modal", {relatedTarget: b});
+ e ? d.$element.find(".modal-dialog").one("bsTransitionEnd", function () {
+ d.$element.trigger("focus").trigger(f)
+ }).emulateTransitionEnd(c.TRANSITION_DURATION) : d.$element.trigger("focus").trigger(f)
+ }))
+ }, c.prototype.hide = function (b) {
+ b && b.preventDefault(), b = a.Event("hide.bs.modal"), this.$element.trigger(b), this.isShown && !b.isDefaultPrevented() && (this.isShown = !1, this.escape(), this.resize(), a(document).off("focusin.bs.modal"), this.$element.removeClass("in").attr("aria-hidden", !0).off("click.dismiss.bs.modal"), a.support.transition && this.$element.hasClass("fade") ? this.$element.one("bsTransitionEnd", a.proxy(this.hideModal, this)).emulateTransitionEnd(c.TRANSITION_DURATION) : this.hideModal())
+ }, c.prototype.enforceFocus = function () {
+ a(document).off("focusin.bs.modal").on("focusin.bs.modal", a.proxy(function (a) {
+ this.$element[0] === a.target || this.$element.has(a.target).length || this.$element.trigger("focus")
+ }, this))
+ }, c.prototype.escape = function () {
+ this.isShown && this.options.keyboard ? this.$element.on("keydown.dismiss.bs.modal", a.proxy(function (a) {
+ 27 == a.which && this.hide()
+ }, this)) : this.isShown || this.$element.off("keydown.dismiss.bs.modal")
+ }, c.prototype.resize = function () {
+ this.isShown ? a(window).on("resize.bs.modal", a.proxy(this.handleUpdate, this)) : a(window).off("resize.bs.modal")
+ }, c.prototype.hideModal = function () {
+ var a = this;
+ this.$element.hide(), this.backdrop(function () {
+ a.$body.removeClass("modal-open"), a.resetAdjustments(), a.resetScrollbar(), a.$element.trigger("hidden.bs.modal")
+ })
+ }, c.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove(), this.$backdrop = null
+ }, c.prototype.backdrop = function (b) {
+ var d = this, e = this.$element.hasClass("fade") ? "fade" : "";
+ if (this.isShown && this.options.backdrop) {
+ var f = a.support.transition && e;
+ if (this.$backdrop = a('
').prependTo(this.$element).on("click.dismiss.bs.modal", a.proxy(function (a) {
+ a.target === a.currentTarget && ("static" == this.options.backdrop ? this.$element[0].focus.call(this.$element[0]) : this.hide.call(this))
+ }, this)), f && this.$backdrop[0].offsetWidth, this.$backdrop.addClass("in"), !b)return;
+ f ? this.$backdrop.one("bsTransitionEnd", b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : b()
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass("in");
+ var g = function () {
+ d.removeBackdrop(), b && b()
+ };
+ a.support.transition && this.$element.hasClass("fade") ? this.$backdrop.one("bsTransitionEnd", g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : g()
+ } else b && b()
+ }, c.prototype.handleUpdate = function () {
+ this.options.backdrop && this.adjustBackdrop(), this.adjustDialog()
+ }, c.prototype.adjustBackdrop = function () {
+ this.$backdrop.css("height", 0).css("height", this.$element[0].scrollHeight)
+ }, c.prototype.adjustDialog = function () {
+ var a = this.$element[0].scrollHeight > document.documentElement.clientHeight;
+ this.$element.css({paddingLeft: !this.bodyIsOverflowing && a ? this.scrollbarWidth : "", paddingRight: this.bodyIsOverflowing && !a ? this.scrollbarWidth : ""})
+ }, c.prototype.resetAdjustments = function () {
+ this.$element.css({paddingLeft: "", paddingRight: ""})
+ }, c.prototype.checkScrollbar = function () {
+ this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight, this.scrollbarWidth = this.measureScrollbar()
+ }, c.prototype.setScrollbar = function () {
+ var a = parseInt(this.$body.css("padding-right") || 0, 10);
+ this.bodyIsOverflowing && this.$body.css("padding-right", a + this.scrollbarWidth)
+ }, c.prototype.resetScrollbar = function () {
+ this.$body.css("padding-right", "")
+ }, c.prototype.measureScrollbar = function () {
+ var a = document.createElement("div");
+ a.className = "modal-scrollbar-measure", this.$body.append(a);
+ var b = a.offsetWidth - a.clientWidth;
+ return this.$body[0].removeChild(a), b
+ };
+ var d = a.fn.modal;
+ a.fn.modal = b, a.fn.modal.Constructor = c, a.fn.modal.noConflict = function () {
+ return a.fn.modal = d, this
+ }, a(document).on("click.bs.modal.data-api", '[data-toggle="modal"]', function (c) {
+ var d = a(this), e = d.attr("href"), f = a(d.attr("data-target") || e && e.replace(/.*(?=#[^\s]+$)/, "")), g = f.data("bs.modal") ? "toggle" : a.extend({remote: !/#/.test(e) && e}, f.data(), d.data());
+ d.is("a") && c.preventDefault(), f.one("show.bs.modal", function (a) {
+ a.isDefaultPrevented() || f.one("hidden.bs.modal", function () {
+ d.is(":visible") && d.trigger("focus")
+ })
+ }), b.call(f, g, this)
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.tooltip"), f = "object" == typeof b && b;
+ (e || "destroy" != b) && (e || d.data("bs.tooltip", e = new c(this, f)), "string" == typeof b && e[b]())
+ })
+ }
+
+ var c = function (a, b) {
+ this.type = this.options = this.enabled = this.timeout = this.hoverState = this.$element = null, this.init("tooltip", a, b)
+ };
+ c.VERSION = "3.3.2", c.TRANSITION_DURATION = 150, c.DEFAULTS = {animation: !0, placement: "top", selector: !1, template: '
', trigger: "hover focus", title: "", delay: 0, html: !1, container: !1, viewport: {selector: "body", padding: 0}}, c.prototype.init = function (b, c, d) {
+ this.enabled = !0, this.type = b, this.$element = a(c), this.options = this.getOptions(d), this.$viewport = this.options.viewport && a(this.options.viewport.selector || this.options.viewport);
+ for (var e = this.options.trigger.split(" "), f = e.length; f--;) {
+ var g = e[f];
+ if ("click" == g)this.$element.on("click." + this.type, this.options.selector, a.proxy(this.toggle, this)); else if ("manual" != g) {
+ var h = "hover" == g ? "mouseenter" : "focusin", i = "hover" == g ? "mouseleave" : "focusout";
+ this.$element.on(h + "." + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(i + "." + this.type, this.options.selector, a.proxy(this.leave, this))
+ }
+ }
+ this.options.selector ? this._options = a.extend({}, this.options, {trigger: "manual", selector: ""}) : this.fixTitle()
+ }, c.prototype.getDefaults = function () {
+ return c.DEFAULTS
+ }, c.prototype.getOptions = function (b) {
+ return b = a.extend({}, this.getDefaults(), this.$element.data(), b), b.delay && "number" == typeof b.delay && (b.delay = {show: b.delay, hide: b.delay}), b
+ }, c.prototype.getDelegateOptions = function () {
+ var b = {}, c = this.getDefaults();
+ return this._options && a.each(this._options, function (a, d) {
+ c[a] != d && (b[a] = d)
+ }), b
+ }, c.prototype.enter = function (b) {
+ var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
+ return c && c.$tip && c.$tip.is(":visible") ? void(c.hoverState = "in") : (c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), clearTimeout(c.timeout), c.hoverState = "in", c.options.delay && c.options.delay.show ? void(c.timeout = setTimeout(function () {
+ "in" == c.hoverState && c.show()
+ }, c.options.delay.show)) : c.show())
+ }, c.prototype.leave = function (b) {
+ var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
+ return c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), clearTimeout(c.timeout), c.hoverState = "out", c.options.delay && c.options.delay.hide ? void(c.timeout = setTimeout(function () {
+ "out" == c.hoverState && c.hide()
+ }, c.options.delay.hide)) : c.hide()
+ }, c.prototype.show = function () {
+ var b = a.Event("show.bs." + this.type);
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(b);
+ var d = a.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]);
+ if (b.isDefaultPrevented() || !d)return;
+ var e = this, f = this.tip(), g = this.getUID(this.type);
+ this.setContent(), f.attr("id", g), this.$element.attr("aria-describedby", g), this.options.animation && f.addClass("fade");
+ var h = "function" == typeof this.options.placement ? this.options.placement.call(this, f[0], this.$element[0]) : this.options.placement, i = /\s?auto?\s?/i, j = i.test(h);
+ j && (h = h.replace(i, "") || "top"), f.detach().css({top: 0, left: 0, display: "block"}).addClass(h).data("bs." + this.type, this), this.options.container ? f.appendTo(this.options.container) : f.insertAfter(this.$element);
+ var k = this.getPosition(), l = f[0].offsetWidth, m = f[0].offsetHeight;
+ if (j) {
+ var n = h, o = this.options.container ? a(this.options.container) : this.$element.parent(), p = this.getPosition(o);
+ h = "bottom" == h && k.bottom + m > p.bottom ? "top" : "top" == h && k.top - m < p.top ? "bottom" : "right" == h && k.right + l > p.width ? "left" : "left" == h && k.left - l < p.left ? "right" : h, f.removeClass(n).addClass(h)
+ }
+ var q = this.getCalculatedOffset(h, k, l, m);
+ this.applyPlacement(q, h);
+ var r = function () {
+ var a = e.hoverState;
+ e.$element.trigger("shown.bs." + e.type), e.hoverState = null, "out" == a && e.leave(e)
+ };
+ a.support.transition && this.$tip.hasClass("fade") ? f.one("bsTransitionEnd", r).emulateTransitionEnd(c.TRANSITION_DURATION) : r()
+ }
+ }, c.prototype.applyPlacement = function (b, c) {
+ var d = this.tip(), e = d[0].offsetWidth, f = d[0].offsetHeight, g = parseInt(d.css("margin-top"), 10), h = parseInt(d.css("margin-left"), 10);
+ isNaN(g) && (g = 0), isNaN(h) && (h = 0), b.top = b.top + g, b.left = b.left + h, a.offset.setOffset(d[0], a.extend({using: function (a) {
+ d.css({top: Math.round(a.top), left: Math.round(a.left)})
+ }}, b), 0), d.addClass("in");
+ var i = d[0].offsetWidth, j = d[0].offsetHeight;
+ "top" == c && j != f && (b.top = b.top + f - j);
+ var k = this.getViewportAdjustedDelta(c, b, i, j);
+ k.left ? b.left += k.left : b.top += k.top;
+ var l = /top|bottom/.test(c), m = l ? 2 * k.left - e + i : 2 * k.top - f + j, n = l ? "offsetWidth" : "offsetHeight";
+ d.offset(b), this.replaceArrow(m, d[0][n], l)
+ }, c.prototype.replaceArrow = function (a, b, c) {
+ this.arrow().css(c ? "left" : "top", 50 * (1 - a / b) + "%").css(c ? "top" : "left", "")
+ }, c.prototype.setContent = function () {
+ var a = this.tip(), b = this.getTitle();
+ a.find(".tooltip-inner")[this.options.html ? "html" : "text"](b), a.removeClass("fade in top bottom left right")
+ }, c.prototype.hide = function (b) {
+ function d() {
+ "in" != e.hoverState && f.detach(), e.$element.removeAttr("aria-describedby").trigger("hidden.bs." + e.type), b && b()
+ }
+
+ var e = this, f = this.tip(), g = a.Event("hide.bs." + this.type);
+ return this.$element.trigger(g), g.isDefaultPrevented() ? void 0 : (f.removeClass("in"), a.support.transition && this.$tip.hasClass("fade") ? f.one("bsTransitionEnd", d).emulateTransitionEnd(c.TRANSITION_DURATION) : d(), this.hoverState = null, this)
+ }, c.prototype.fixTitle = function () {
+ var a = this.$element;
+ (a.attr("title") || "string" != typeof a.attr("data-original-title")) && a.attr("data-original-title", a.attr("title") || "").attr("title", "")
+ }, c.prototype.hasContent = function () {
+ return this.getTitle()
+ }, c.prototype.getPosition = function (b) {
+ b = b || this.$element;
+ var c = b[0], d = "BODY" == c.tagName, e = c.getBoundingClientRect();
+ null == e.width && (e = a.extend({}, e, {width: e.right - e.left, height: e.bottom - e.top}));
+ var f = d ? {top: 0, left: 0} : b.offset(), g = {scroll: d ? document.documentElement.scrollTop || document.body.scrollTop : b.scrollTop()}, h = d ? {width: a(window).width(), height: a(window).height()} : null;
+ return a.extend({}, e, g, h, f)
+ }, c.prototype.getCalculatedOffset = function (a, b, c, d) {
+ return"bottom" == a ? {top: b.top + b.height, left: b.left + b.width / 2 - c / 2} : "top" == a ? {top: b.top - d, left: b.left + b.width / 2 - c / 2} : "left" == a ? {top: b.top + b.height / 2 - d / 2, left: b.left - c} : {top: b.top + b.height / 2 - d / 2, left: b.left + b.width}
+ }, c.prototype.getViewportAdjustedDelta = function (a, b, c, d) {
+ var e = {top: 0, left: 0};
+ if (!this.$viewport)return e;
+ var f = this.options.viewport && this.options.viewport.padding || 0, g = this.getPosition(this.$viewport);
+ if (/right|left/.test(a)) {
+ var h = b.top - f - g.scroll, i = b.top + f - g.scroll + d;
+ h < g.top ? e.top = g.top - h : i > g.top + g.height && (e.top = g.top + g.height - i)
+ } else {
+ var j = b.left - f, k = b.left + f + c;
+ j < g.left ? e.left = g.left - j : k > g.width && (e.left = g.left + g.width - k)
+ }
+ return e
+ }, c.prototype.getTitle = function () {
+ var a, b = this.$element, c = this.options;
+ return a = b.attr("data-original-title") || ("function" == typeof c.title ? c.title.call(b[0]) : c.title)
+ }, c.prototype.getUID = function (a) {
+ do a += ~~(1e6 * Math.random()); while (document.getElementById(a));
+ return a
+ }, c.prototype.tip = function () {
+ return this.$tip = this.$tip || a(this.options.template)
+ }, c.prototype.arrow = function () {
+ return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
+ }, c.prototype.enable = function () {
+ this.enabled = !0
+ }, c.prototype.disable = function () {
+ this.enabled = !1
+ }, c.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }, c.prototype.toggle = function (b) {
+ var c = this;
+ b && (c = a(b.currentTarget).data("bs." + this.type), c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c))), c.tip().hasClass("in") ? c.leave(c) : c.enter(c)
+ }, c.prototype.destroy = function () {
+ var a = this;
+ clearTimeout(this.timeout), this.hide(function () {
+ a.$element.off("." + a.type).removeData("bs." + a.type)
+ })
+ };
+ var d = a.fn.tooltip;
+ a.fn.tooltip = b, a.fn.tooltip.Constructor = c, a.fn.tooltip.noConflict = function () {
+ return a.fn.tooltip = d, this
+ }
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.popover"), f = "object" == typeof b && b;
+ (e || "destroy" != b) && (e || d.data("bs.popover", e = new c(this, f)), "string" == typeof b && e[b]())
+ })
+ }
+
+ var c = function (a, b) {
+ this.init("popover", a, b)
+ };
+ if (!a.fn.tooltip)throw new Error("Popover requires tooltip.js");
+ c.VERSION = "3.3.2", c.DEFAULTS = a.extend({}, a.fn.tooltip.Constructor.DEFAULTS, {placement: "right", trigger: "click", content: "", template: '
'}), c.prototype = a.extend({}, a.fn.tooltip.Constructor.prototype), c.prototype.constructor = c, c.prototype.getDefaults = function () {
+ return c.DEFAULTS
+ }, c.prototype.setContent = function () {
+ var a = this.tip(), b = this.getTitle(), c = this.getContent();
+ a.find(".popover-title")[this.options.html ? "html" : "text"](b), a.find(".popover-content").children().detach().end()[this.options.html ? "string" == typeof c ? "html" : "append" : "text"](c), a.removeClass("fade top bottom left right in"), a.find(".popover-title").html() || a.find(".popover-title").hide()
+ }, c.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }, c.prototype.getContent = function () {
+ var a = this.$element, b = this.options;
+ return a.attr("data-content") || ("function" == typeof b.content ? b.content.call(a[0]) : b.content)
+ }, c.prototype.arrow = function () {
+ return this.$arrow = this.$arrow || this.tip().find(".arrow")
+ }, c.prototype.tip = function () {
+ return this.$tip || (this.$tip = a(this.options.template)), this.$tip
+ };
+ var d = a.fn.popover;
+ a.fn.popover = b, a.fn.popover.Constructor = c, a.fn.popover.noConflict = function () {
+ return a.fn.popover = d, this
+ }
+}(jQuery), +function (a) {
+ "use strict";
+ function b(c, d) {
+ var e = a.proxy(this.process, this);
+ this.$body = a("body"), this.$scrollElement = a(a(c).is("body") ? window : c), this.options = a.extend({}, b.DEFAULTS, d), this.selector = (this.options.target || "") + " .nav li > a", this.offsets = [], this.targets = [], this.activeTarget = null, this.scrollHeight = 0, this.$scrollElement.on("scroll.bs.scrollspy", e), this.refresh(), this.process()
+ }
+
+ function c(c) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.scrollspy"), f = "object" == typeof c && c;
+ e || d.data("bs.scrollspy", e = new b(this, f)), "string" == typeof c && e[c]()
+ })
+ }
+
+ b.VERSION = "3.3.2", b.DEFAULTS = {offset: 10}, b.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }, b.prototype.refresh = function () {
+ var b = "offset", c = 0;
+ a.isWindow(this.$scrollElement[0]) || (b = "position", c = this.$scrollElement.scrollTop()), this.offsets = [], this.targets = [], this.scrollHeight = this.getScrollHeight();
+ var d = this;
+ this.$body.find(this.selector).map(function () {
+ var d = a(this), e = d.data("target") || d.attr("href"), f = /^#./.test(e) && a(e);
+ return f && f.length && f.is(":visible") && [
+ [f[b]().top + c, e]
+ ] || null
+ }).sort(function (a, b) {
+ return a[0] - b[0]
+ }).each(function () {
+ d.offsets.push(this[0]), d.targets.push(this[1])
+ })
+ }, b.prototype.process = function () {
+ var a, b = this.$scrollElement.scrollTop() + this.options.offset, c = this.getScrollHeight(), d = this.options.offset + c - this.$scrollElement.height(), e = this.offsets, f = this.targets, g = this.activeTarget;
+ if (this.scrollHeight != c && this.refresh(), b >= d)return g != (a = f[f.length - 1]) && this.activate(a);
+ if (g && b < e[0])return this.activeTarget = null, this.clear();
+ for (a = e.length; a--;)g != f[a] && b >= e[a] && (!e[a + 1] || b <= e[a + 1]) && this.activate(f[a])
+ }, b.prototype.activate = function (b) {
+ this.activeTarget = b, this.clear();
+ var c = this.selector + '[data-target="' + b + '"],' + this.selector + '[href="' + b + '"]', d = a(c).parents("li").addClass("active");
+ d.parent(".dropdown-menu").length && (d = d.closest("li.dropdown").addClass("active")), d.trigger("activate.bs.scrollspy")
+ }, b.prototype.clear = function () {
+ a(this.selector).parentsUntil(this.options.target, ".active").removeClass("active")
+ };
+ var d = a.fn.scrollspy;
+ a.fn.scrollspy = c, a.fn.scrollspy.Constructor = b, a.fn.scrollspy.noConflict = function () {
+ return a.fn.scrollspy = d, this
+ }, a(window).on("load.bs.scrollspy.data-api", function () {
+ a('[data-spy="scroll"]').each(function () {
+ var b = a(this);
+ c.call(b, b.data())
+ })
+ })
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.tab");
+ e || d.data("bs.tab", e = new c(this)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var c = function (b) {
+ this.element = a(b)
+ };
+ c.VERSION = "3.3.2", c.TRANSITION_DURATION = 150, c.prototype.show = function () {
+ var b = this.element, c = b.closest("ul:not(.dropdown-menu)"), d = b.data("target");
+ if (d || (d = b.attr("href"), d = d && d.replace(/.*(?=#[^\s]*$)/, "")), !b.parent("li").hasClass("active")) {
+ var e = c.find(".active:last a"), f = a.Event("hide.bs.tab", {relatedTarget: b[0]}), g = a.Event("show.bs.tab", {relatedTarget: e[0]});
+ if (e.trigger(f), b.trigger(g), !g.isDefaultPrevented() && !f.isDefaultPrevented()) {
+ var h = a(d);
+ this.activate(b.closest("li"), c), this.activate(h, h.parent(), function () {
+ e.trigger({type: "hidden.bs.tab", relatedTarget: b[0]}), b.trigger({type: "shown.bs.tab", relatedTarget: e[0]})
+ })
+ }
+ }
+ }, c.prototype.activate = function (b, d, e) {
+ function f() {
+ g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !1), b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded", !0), h ? (b[0].offsetWidth, b.addClass("in")) : b.removeClass("fade"), b.parent(".dropdown-menu") && b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !0), e && e()
+ }
+
+ var g = d.find("> .active"), h = e && a.support.transition && (g.length && g.hasClass("fade") || !!d.find("> .fade").length);
+ g.length && h ? g.one("bsTransitionEnd", f).emulateTransitionEnd(c.TRANSITION_DURATION) : f(), g.removeClass("in")
+ };
+ var d = a.fn.tab;
+ a.fn.tab = b, a.fn.tab.Constructor = c, a.fn.tab.noConflict = function () {
+ return a.fn.tab = d, this
+ };
+ var e = function (c) {
+ c.preventDefault(), b.call(a(this), "show")
+ };
+ a(document).on("click.bs.tab.data-api", '[data-toggle="tab"]', e).on("click.bs.tab.data-api", '[data-toggle="pill"]', e)
+}(jQuery), +function (a) {
+ "use strict";
+ function b(b) {
+ return this.each(function () {
+ var d = a(this), e = d.data("bs.affix"), f = "object" == typeof b && b;
+ e || d.data("bs.affix", e = new c(this, f)), "string" == typeof b && e[b]()
+ })
+ }
+
+ var c = function (b, d) {
+ this.options = a.extend({}, c.DEFAULTS, d), this.$target = a(this.options.target).on("scroll.bs.affix.data-api", a.proxy(this.checkPosition, this)).on("click.bs.affix.data-api", a.proxy(this.checkPositionWithEventLoop, this)), this.$element = a(b), this.affixed = this.unpin = this.pinnedOffset = null, this.checkPosition()
+ };
+ c.VERSION = "3.3.2", c.RESET = "affix affix-top affix-bottom", c.DEFAULTS = {offset: 0, target: window}, c.prototype.getState = function (a, b, c, d) {
+ var e = this.$target.scrollTop(), f = this.$element.offset(), g = this.$target.height();
+ if (null != c && "top" == this.affixed)return c > e ? "top" : !1;
+ if ("bottom" == this.affixed)return null != c ? e + this.unpin <= f.top ? !1 : "bottom" : a - d >= e + g ? !1 : "bottom";
+ var h = null == this.affixed, i = h ? e : f.top, j = h ? g : b;
+ return null != c && c >= e ? "top" : null != d && i + j >= a - d ? "bottom" : !1
+ }, c.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset)return this.pinnedOffset;
+ this.$element.removeClass(c.RESET).addClass("affix");
+ var a = this.$target.scrollTop(), b = this.$element.offset();
+ return this.pinnedOffset = b.top - a
+ }, c.prototype.checkPositionWithEventLoop = function () {
+ setTimeout(a.proxy(this.checkPosition, this), 1)
+ }, c.prototype.checkPosition = function () {
+ if (this.$element.is(":visible")) {
+ var b = this.$element.height(), d = this.options.offset, e = d.top, f = d.bottom, g = a("body").height();
+ "object" != typeof d && (f = e = d), "function" == typeof e && (e = d.top(this.$element)), "function" == typeof f && (f = d.bottom(this.$element));
+ var h = this.getState(g, b, e, f);
+ if (this.affixed != h) {
+ null != this.unpin && this.$element.css("top", "");
+ var i = "affix" + (h ? "-" + h : ""), j = a.Event(i + ".bs.affix");
+ if (this.$element.trigger(j), j.isDefaultPrevented())return;
+ this.affixed = h, this.unpin = "bottom" == h ? this.getPinnedOffset() : null, this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix", "affixed") + ".bs.affix")
+ }
+ "bottom" == h && this.$element.offset({top: g - b - f})
+ }
+ };
+ var d = a.fn.affix;
+ a.fn.affix = b, a.fn.affix.Constructor = c, a.fn.affix.noConflict = function () {
+ return a.fn.affix = d, this
+ }, a(window).on("load", function () {
+ a('[data-spy="affix"]').each(function () {
+ var c = a(this), d = c.data();
+ d.offset = d.offset || {}, null != d.offsetBottom && (d.offset.bottom = d.offsetBottom), null != d.offsetTop && (d.offset.top = d.offsetTop), b.call(c, d)
+ })
+ })
+}(jQuery);
\ No newline at end of file
diff --git a/src/main/resources/webapp/js/dataTables.bootstrap.min.js b/src/main/resources/webapp/js/dataTables.bootstrap.min.js
new file mode 100755
index 0000000..412a1ce
--- /dev/null
+++ b/src/main/resources/webapp/js/dataTables.bootstrap.min.js
@@ -0,0 +1,52 @@
+/*!
+ DataTables Bootstrap 3 integration
+ ©2011-2014 SpryMedia Ltd - datatables.net/license
+ */
+(function () {
+ var f = function (c, b) {
+ c.extend(!0, b.defaults, {dom: "<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'p>>", renderer: "bootstrap"});
+ c.extend(b.ext.classes, {sWrapper: "dataTables_wrapper form-inline dt-bootstrap", sFilterInput: "form-control input-sm", sLengthSelect: "form-control input-sm"});
+ b.ext.renderer.pageButton.bootstrap = function (g, f, p, k, h, l) {
+ var q = new b.Api(g), r = g.oClasses, i = g.oLanguage.oPaginate, d, e, o = function (b, f) {
+ var j, m, n, a, k = function (a) {
+ a.preventDefault();
+ c(a.currentTarget).hasClass("disabled") || q.page(a.data.action).draw(!1)
+ };
+ j = 0;
+ for (m = f.length; j < m; j++)if (a = f[j], c.isArray(a))o(b, a); else {
+ e = d = "";
+ switch (a) {
+ case "ellipsis":
+ d = "…";
+ e = "disabled";
+ break;
+ case "first":
+ d = i.sFirst;
+ e = a + (0 < h ? "" : " disabled");
+ break;
+ case "previous":
+ d = i.sPrevious;
+ e = a + (0 < h ? "" : " disabled");
+ break;
+ case "next":
+ d = i.sNext;
+ e = a + (h < l - 1 ? "" : " disabled");
+ break;
+ case "last":
+ d = i.sLast;
+ e = a + (h < l - 1 ? "" : " disabled");
+ break;
+ default:
+ d = a + 1, e = h === a ? "active" : ""
+ }
+ d && (n = c("
", {"class": r.sPageButton + " " +
+ e, "aria-controls": g.sTableId, tabindex: g.iTabIndex, id: 0 === p && "string" === typeof a ? g.sTableId + "_" + a : null}).append(c("", {href: "#"}).html(d)).appendTo(b), g.oApi._fnBindAction(n, {action: a}, k))
+ }
+ };
+ o(c(f).empty().html('').children("ul"), k)
+ };
+ b.TableTools && (c.extend(!0, b.TableTools.classes, {container: "DTTT btn-group", buttons: {normal: "btn btn-default", disabled: "disabled"}, collection: {container: "DTTT_dropdown dropdown-menu", buttons: {normal: "", disabled: "disabled"}}, print: {info: "DTTT_print_info"},
+ select: {row: "active"}}), c.extend(!0, b.TableTools.DEFAULTS.oTags, {collection: {container: "ul", button: "li", liner: "a"}}))
+ };
+ "function" === typeof define && define.amd ? define(["jquery", "datatables"], f) : "object" === typeof exports ? f(require("jquery"), require("datatables")) : jQuery && f(jQuery, jQuery.fn.dataTable)
+})(window, document);
diff --git a/src/main/resources/webapp/js/excanvas.min.js b/src/main/resources/webapp/js/excanvas.min.js
new file mode 100755
index 0000000..fcd6ad7
--- /dev/null
+++ b/src/main/resources/webapp/js/excanvas.min.js
@@ -0,0 +1,886 @@
+if (!document.createElement("canvas").getContext) {
+ (function () {
+ var ab = Math;
+ var n = ab.round;
+ var l = ab.sin;
+ var A = ab.cos;
+ var H = ab.abs;
+ var N = ab.sqrt;
+ var d = 10;
+ var f = d / 2;
+ var z = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];
+
+ function y() {
+ return this.context_ || (this.context_ = new D(this))
+ }
+
+ var t = Array.prototype.slice;
+
+ function g(j, m, p) {
+ var i = t.call(arguments, 2);
+ return function () {
+ return j.apply(m, i.concat(t.call(arguments)))
+ }
+ }
+
+ function af(i) {
+ return String(i).replace(/&/g, "&").replace(/"/g, """)
+ }
+
+ function Y(m, j, i) {
+ if (!m.namespaces[j]) {
+ m.namespaces.add(j, i, "#default#VML")
+ }
+ }
+
+ function R(j) {
+ Y(j, "g_vml_", "urn:schemas-microsoft-com:vml");
+ Y(j, "g_o_", "urn:schemas-microsoft-com:office:office");
+ if (!j.styleSheets.ex_canvas_) {
+ var i = j.createStyleSheet();
+ i.owningElement.id = "ex_canvas_";
+ i.cssText = "canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"
+ }
+ }
+
+ R(document);
+ var e = {init: function (i) {
+ var j = i || document;
+ j.createElement("canvas");
+ j.attachEvent("onreadystatechange", g(this.init_, this, j))
+ }, init_: function (p) {
+ var m = p.getElementsByTagName("canvas");
+ for (var j = 0; j < m.length; j++) {
+ this.initElement(m[j])
+ }
+ }, initElement: function (j) {
+ if (!j.getContext) {
+ j.getContext = y;
+ R(j.ownerDocument);
+ j.innerHTML = "";
+ j.attachEvent("onpropertychange", x);
+ j.attachEvent("onresize", W);
+ var i = j.attributes;
+ if (i.width && i.width.specified) {
+ j.style.width = i.width.nodeValue + "px"
+ } else {
+ j.width = j.clientWidth
+ }
+ if (i.height && i.height.specified) {
+ j.style.height = i.height.nodeValue + "px"
+ } else {
+ j.height = j.clientHeight
+ }
+ }
+ return j
+ }};
+
+ function x(j) {
+ var i = j.srcElement;
+ switch (j.propertyName) {
+ case"width":
+ i.getContext().clearRect();
+ i.style.width = i.attributes.width.nodeValue + "px";
+ i.firstChild.style.width = i.clientWidth + "px";
+ break;
+ case"height":
+ i.getContext().clearRect();
+ i.style.height = i.attributes.height.nodeValue + "px";
+ i.firstChild.style.height = i.clientHeight + "px";
+ break
+ }
+ }
+
+ function W(j) {
+ var i = j.srcElement;
+ if (i.firstChild) {
+ i.firstChild.style.width = i.clientWidth + "px";
+ i.firstChild.style.height = i.clientHeight + "px"
+ }
+ }
+
+ e.init();
+ var k = [];
+ for (var ae = 0; ae < 16; ae++) {
+ for (var ad = 0; ad < 16; ad++) {
+ k[ae * 16 + ad] = ae.toString(16) + ad.toString(16)
+ }
+ }
+ function B() {
+ return[
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ]
+ }
+
+ function J(p, m) {
+ var j = B();
+ for (var i = 0; i < 3; i++) {
+ for (var ah = 0; ah < 3; ah++) {
+ var Z = 0;
+ for (var ag = 0; ag < 3; ag++) {
+ Z += p[i][ag] * m[ag][ah]
+ }
+ j[i][ah] = Z
+ }
+ }
+ return j
+ }
+
+ function v(j, i) {
+ i.fillStyle = j.fillStyle;
+ i.lineCap = j.lineCap;
+ i.lineJoin = j.lineJoin;
+ i.lineWidth = j.lineWidth;
+ i.miterLimit = j.miterLimit;
+ i.shadowBlur = j.shadowBlur;
+ i.shadowColor = j.shadowColor;
+ i.shadowOffsetX = j.shadowOffsetX;
+ i.shadowOffsetY = j.shadowOffsetY;
+ i.strokeStyle = j.strokeStyle;
+ i.globalAlpha = j.globalAlpha;
+ i.font = j.font;
+ i.textAlign = j.textAlign;
+ i.textBaseline = j.textBaseline;
+ i.arcScaleX_ = j.arcScaleX_;
+ i.arcScaleY_ = j.arcScaleY_;
+ i.lineScale_ = j.lineScale_
+ }
+
+ var b = {aliceblue: "#F0F8FF", antiquewhite: "#FAEBD7", aquamarine: "#7FFFD4", azure: "#F0FFFF", beige: "#F5F5DC", bisque: "#FFE4C4", black: "#000000", blanchedalmond: "#FFEBCD", blueviolet: "#8A2BE2", brown: "#A52A2A", burlywood: "#DEB887", cadetblue: "#5F9EA0", chartreuse: "#7FFF00", chocolate: "#D2691E", coral: "#FF7F50", cornflowerblue: "#6495ED", cornsilk: "#FFF8DC", crimson: "#DC143C", cyan: "#00FFFF", darkblue: "#00008B", darkcyan: "#008B8B", darkgoldenrod: "#B8860B", darkgray: "#A9A9A9", darkgreen: "#006400", darkgrey: "#A9A9A9", darkkhaki: "#BDB76B", darkmagenta: "#8B008B", darkolivegreen: "#556B2F", darkorange: "#FF8C00", darkorchid: "#9932CC", darkred: "#8B0000", darksalmon: "#E9967A", darkseagreen: "#8FBC8F", darkslateblue: "#483D8B", darkslategray: "#2F4F4F", darkslategrey: "#2F4F4F", darkturquoise: "#00CED1", darkviolet: "#9400D3", deeppink: "#FF1493", deepskyblue: "#00BFFF", dimgray: "#696969", dimgrey: "#696969", dodgerblue: "#1E90FF", firebrick: "#B22222", floralwhite: "#FFFAF0", forestgreen: "#228B22", gainsboro: "#DCDCDC", ghostwhite: "#F8F8FF", gold: "#FFD700", goldenrod: "#DAA520", grey: "#808080", greenyellow: "#ADFF2F", honeydew: "#F0FFF0", hotpink: "#FF69B4", indianred: "#CD5C5C", indigo: "#4B0082", ivory: "#FFFFF0", khaki: "#F0E68C", lavender: "#E6E6FA", lavenderblush: "#FFF0F5", lawngreen: "#7CFC00", lemonchiffon: "#FFFACD", lightblue: "#ADD8E6", lightcoral: "#F08080", lightcyan: "#E0FFFF", lightgoldenrodyellow: "#FAFAD2", lightgreen: "#90EE90", lightgrey: "#D3D3D3", lightpink: "#FFB6C1", lightsalmon: "#FFA07A", lightseagreen: "#20B2AA", lightskyblue: "#87CEFA", lightslategray: "#778899", lightslategrey: "#778899", lightsteelblue: "#B0C4DE", lightyellow: "#FFFFE0", limegreen: "#32CD32", linen: "#FAF0E6", magenta: "#FF00FF", mediumaquamarine: "#66CDAA", mediumblue: "#0000CD", mediumorchid: "#BA55D3", mediumpurple: "#9370DB", mediumseagreen: "#3CB371", mediumslateblue: "#7B68EE", mediumspringgreen: "#00FA9A", mediumturquoise: "#48D1CC", mediumvioletred: "#C71585", midnightblue: "#191970", mintcream: "#F5FFFA", mistyrose: "#FFE4E1", moccasin: "#FFE4B5", navajowhite: "#FFDEAD", oldlace: "#FDF5E6", olivedrab: "#6B8E23", orange: "#FFA500", orangered: "#FF4500", orchid: "#DA70D6", palegoldenrod: "#EEE8AA", palegreen: "#98FB98", paleturquoise: "#AFEEEE", palevioletred: "#DB7093", papayawhip: "#FFEFD5", peachpuff: "#FFDAB9", peru: "#CD853F", pink: "#FFC0CB", plum: "#DDA0DD", powderblue: "#B0E0E6", rosybrown: "#BC8F8F", royalblue: "#4169E1", saddlebrown: "#8B4513", salmon: "#FA8072", sandybrown: "#F4A460", seagreen: "#2E8B57", seashell: "#FFF5EE", sienna: "#A0522D", skyblue: "#87CEEB", slateblue: "#6A5ACD", slategray: "#708090", slategrey: "#708090", snow: "#FFFAFA", springgreen: "#00FF7F", steelblue: "#4682B4", tan: "#D2B48C", thistle: "#D8BFD8", tomato: "#FF6347", turquoise: "#40E0D0", violet: "#EE82EE", wheat: "#F5DEB3", whitesmoke: "#F5F5F5", yellowgreen: "#9ACD32"};
+
+ function M(j) {
+ var p = j.indexOf("(", 3);
+ var i = j.indexOf(")", p + 1);
+ var m = j.substring(p + 1, i).split(",");
+ if (m.length != 4 || j.charAt(3) != "a") {
+ m[3] = 1
+ }
+ return m
+ }
+
+ function c(i) {
+ return parseFloat(i) / 100
+ }
+
+ function r(j, m, i) {
+ return Math.min(i, Math.max(m, j))
+ }
+
+ function I(ag) {
+ var i, ai, aj, ah, ak, Z;
+ ah = parseFloat(ag[0]) / 360 % 360;
+ if (ah < 0) {
+ ah++
+ }
+ ak = r(c(ag[1]), 0, 1);
+ Z = r(c(ag[2]), 0, 1);
+ if (ak == 0) {
+ i = ai = aj = Z
+ } else {
+ var j = Z < 0.5 ? Z * (1 + ak) : Z + ak - Z * ak;
+ var m = 2 * Z - j;
+ i = a(m, j, ah + 1 / 3);
+ ai = a(m, j, ah);
+ aj = a(m, j, ah - 1 / 3)
+ }
+ return"#" + k[Math.floor(i * 255)] + k[Math.floor(ai * 255)] + k[Math.floor(aj * 255)]
+ }
+
+ function a(j, i, m) {
+ if (m < 0) {
+ m++
+ }
+ if (m > 1) {
+ m--
+ }
+ if (6 * m < 1) {
+ return j + (i - j) * 6 * m
+ } else {
+ if (2 * m < 1) {
+ return i
+ } else {
+ if (3 * m < 2) {
+ return j + (i - j) * (2 / 3 - m) * 6
+ } else {
+ return j
+ }
+ }
+ }
+ }
+
+ var C = {};
+
+ function F(j) {
+ if (j in C) {
+ return C[j]
+ }
+ var ag, Z = 1;
+ j = String(j);
+ if (j.charAt(0) == "#") {
+ ag = j
+ } else {
+ if (/^rgb/.test(j)) {
+ var p = M(j);
+ var ag = "#", ah;
+ for (var m = 0; m < 3; m++) {
+ if (p[m].indexOf("%") != -1) {
+ ah = Math.floor(c(p[m]) * 255)
+ } else {
+ ah = +p[m]
+ }
+ ag += k[r(ah, 0, 255)]
+ }
+ Z = +p[3]
+ } else {
+ if (/^hsl/.test(j)) {
+ var p = M(j);
+ ag = I(p);
+ Z = p[3]
+ } else {
+ ag = b[j] || j
+ }
+ }
+ }
+ return C[j] = {color: ag, alpha: Z}
+ }
+
+ var o = {style: "normal", variant: "normal", weight: "normal", size: 10, family: "sans-serif"};
+ var L = {};
+
+ function E(i) {
+ if (L[i]) {
+ return L[i]
+ }
+ var p = document.createElement("div");
+ var m = p.style;
+ try {
+ m.font = i
+ } catch (j) {
+ }
+ return L[i] = {style: m.fontStyle || o.style, variant: m.fontVariant || o.variant, weight: m.fontWeight || o.weight, size: m.fontSize || o.size, family: m.fontFamily || o.family}
+ }
+
+ function u(m, j) {
+ var i = {};
+ for (var ah in m) {
+ i[ah] = m[ah]
+ }
+ var ag = parseFloat(j.currentStyle.fontSize), Z = parseFloat(m.size);
+ if (typeof m.size == "number") {
+ i.size = m.size
+ } else {
+ if (m.size.indexOf("px") != -1) {
+ i.size = Z
+ } else {
+ if (m.size.indexOf("em") != -1) {
+ i.size = ag * Z
+ } else {
+ if (m.size.indexOf("%") != -1) {
+ i.size = (ag / 100) * Z
+ } else {
+ if (m.size.indexOf("pt") != -1) {
+ i.size = Z / 0.75
+ } else {
+ i.size = ag
+ }
+ }
+ }
+ }
+ }
+ i.size *= 0.981;
+ return i
+ }
+
+ function ac(i) {
+ return i.style + " " + i.variant + " " + i.weight + " " + i.size + "px " + i.family
+ }
+
+ var s = {butt: "flat", round: "round"};
+
+ function S(i) {
+ return s[i] || "square"
+ }
+
+ function D(i) {
+ this.m_ = B();
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+ this.strokeStyle = "#000";
+ this.fillStyle = "#000";
+ this.lineWidth = 1;
+ this.lineJoin = "miter";
+ this.lineCap = "butt";
+ this.miterLimit = d * 1;
+ this.globalAlpha = 1;
+ this.font = "10px sans-serif";
+ this.textAlign = "left";
+ this.textBaseline = "alphabetic";
+ this.canvas = i;
+ var m = "width:" + i.clientWidth + "px;height:" + i.clientHeight + "px;overflow:hidden;position:absolute";
+ var j = i.ownerDocument.createElement("div");
+ j.style.cssText = m;
+ i.appendChild(j);
+ var p = j.cloneNode(false);
+ p.style.backgroundColor = "red";
+ p.style.filter = "alpha(opacity=0)";
+ i.appendChild(p);
+ this.element_ = j;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ this.lineScale_ = 1
+ }
+
+ var q = D.prototype;
+ q.clearRect = function () {
+ if (this.textMeasureEl_) {
+ this.textMeasureEl_.removeNode(true);
+ this.textMeasureEl_ = null
+ }
+ this.element_.innerHTML = ""
+ };
+ q.beginPath = function () {
+ this.currentPath_ = []
+ };
+ q.moveTo = function (j, i) {
+ var m = V(this, j, i);
+ this.currentPath_.push({type: "moveTo", x: m.x, y: m.y});
+ this.currentX_ = m.x;
+ this.currentY_ = m.y
+ };
+ q.lineTo = function (j, i) {
+ var m = V(this, j, i);
+ this.currentPath_.push({type: "lineTo", x: m.x, y: m.y});
+ this.currentX_ = m.x;
+ this.currentY_ = m.y
+ };
+ q.bezierCurveTo = function (m, j, ak, aj, ai, ag) {
+ var i = V(this, ai, ag);
+ var ah = V(this, m, j);
+ var Z = V(this, ak, aj);
+ K(this, ah, Z, i)
+ };
+ function K(i, Z, m, j) {
+ i.currentPath_.push({type: "bezierCurveTo", cp1x: Z.x, cp1y: Z.y, cp2x: m.x, cp2y: m.y, x: j.x, y: j.y});
+ i.currentX_ = j.x;
+ i.currentY_ = j.y
+ }
+
+ q.quadraticCurveTo = function (ai, m, j, i) {
+ var ah = V(this, ai, m);
+ var ag = V(this, j, i);
+ var aj = {x: this.currentX_ + 2 / 3 * (ah.x - this.currentX_), y: this.currentY_ + 2 / 3 * (ah.y - this.currentY_)};
+ var Z = {x: aj.x + (ag.x - this.currentX_) / 3, y: aj.y + (ag.y - this.currentY_) / 3};
+ K(this, aj, Z, ag)
+ };
+ q.arc = function (al, aj, ak, ag, j, m) {
+ ak *= d;
+ var ap = m ? "at" : "wa";
+ var am = al + A(ag) * ak - f;
+ var ao = aj + l(ag) * ak - f;
+ var i = al + A(j) * ak - f;
+ var an = aj + l(j) * ak - f;
+ if (am == i && !m) {
+ am += 0.125
+ }
+ var Z = V(this, al, aj);
+ var ai = V(this, am, ao);
+ var ah = V(this, i, an);
+ this.currentPath_.push({type: ap, x: Z.x, y: Z.y, radius: ak, xStart: ai.x, yStart: ai.y, xEnd: ah.x, yEnd: ah.y})
+ };
+ q.rect = function (m, j, i, p) {
+ this.moveTo(m, j);
+ this.lineTo(m + i, j);
+ this.lineTo(m + i, j + p);
+ this.lineTo(m, j + p);
+ this.closePath()
+ };
+ q.strokeRect = function (m, j, i, p) {
+ var Z = this.currentPath_;
+ this.beginPath();
+ this.moveTo(m, j);
+ this.lineTo(m + i, j);
+ this.lineTo(m + i, j + p);
+ this.lineTo(m, j + p);
+ this.closePath();
+ this.stroke();
+ this.currentPath_ = Z
+ };
+ q.fillRect = function (m, j, i, p) {
+ var Z = this.currentPath_;
+ this.beginPath();
+ this.moveTo(m, j);
+ this.lineTo(m + i, j);
+ this.lineTo(m + i, j + p);
+ this.lineTo(m, j + p);
+ this.closePath();
+ this.fill();
+ this.currentPath_ = Z
+ };
+ q.createLinearGradient = function (j, p, i, m) {
+ var Z = new U("gradient");
+ Z.x0_ = j;
+ Z.y0_ = p;
+ Z.x1_ = i;
+ Z.y1_ = m;
+ return Z
+ };
+ q.createRadialGradient = function (p, ag, m, j, Z, i) {
+ var ah = new U("gradientradial");
+ ah.x0_ = p;
+ ah.y0_ = ag;
+ ah.r0_ = m;
+ ah.x1_ = j;
+ ah.y1_ = Z;
+ ah.r1_ = i;
+ return ah
+ };
+ q.drawImage = function (aq, m) {
+ var aj, ah, al, ay, ao, am, at, aA;
+ var ak = aq.runtimeStyle.width;
+ var ap = aq.runtimeStyle.height;
+ aq.runtimeStyle.width = "auto";
+ aq.runtimeStyle.height = "auto";
+ var ai = aq.width;
+ var aw = aq.height;
+ aq.runtimeStyle.width = ak;
+ aq.runtimeStyle.height = ap;
+ if (arguments.length == 3) {
+ aj = arguments[1];
+ ah = arguments[2];
+ ao = am = 0;
+ at = al = ai;
+ aA = ay = aw
+ } else {
+ if (arguments.length == 5) {
+ aj = arguments[1];
+ ah = arguments[2];
+ al = arguments[3];
+ ay = arguments[4];
+ ao = am = 0;
+ at = ai;
+ aA = aw
+ } else {
+ if (arguments.length == 9) {
+ ao = arguments[1];
+ am = arguments[2];
+ at = arguments[3];
+ aA = arguments[4];
+ aj = arguments[5];
+ ah = arguments[6];
+ al = arguments[7];
+ ay = arguments[8]
+ } else {
+ throw Error("Invalid number of arguments")
+ }
+ }
+ }
+ var az = V(this, aj, ah);
+ var p = at / 2;
+ var j = aA / 2;
+ var ax = [];
+ var i = 10;
+ var ag = 10;
+ ax.push(" ', ' ", " ");
+ this.element_.insertAdjacentHTML("BeforeEnd", ax.join(""))
+ };
+ q.stroke = function (ao) {
+ var Z = 10;
+ var ap = 10;
+ var ag = 5000;
+ var ai = {x: null, y: null};
+ var an = {x: null, y: null};
+ for (var aj = 0; aj < this.currentPath_.length; aj += ag) {
+ var am = [];
+ var ah = false;
+ am.push(" an.x) {
+ an.x = m.x
+ }
+ if (ai.y == null || m.y < ai.y) {
+ ai.y = m.y
+ }
+ if (an.y == null || m.y > an.y) {
+ an.y = m.y
+ }
+ }
+ }
+ am.push(' ">');
+ if (!ao) {
+ w(this, am)
+ } else {
+ G(this, am, ai, an)
+ }
+ am.push(" ");
+ this.element_.insertAdjacentHTML("beforeEnd", am.join(""))
+ }
+ };
+ function w(m, ag) {
+ var j = F(m.strokeStyle);
+ var p = j.color;
+ var Z = j.alpha * m.globalAlpha;
+ var i = m.lineScale_ * m.lineWidth;
+ if (i < 1) {
+ Z *= i
+ }
+ ag.push(" ')
+ }
+
+ function G(aq, ai, aK, ar) {
+ var aj = aq.fillStyle;
+ var aB = aq.arcScaleX_;
+ var aA = aq.arcScaleY_;
+ var j = ar.x - aK.x;
+ var p = ar.y - aK.y;
+ if (aj instanceof U) {
+ var an = 0;
+ var aF = {x: 0, y: 0};
+ var ax = 0;
+ var am = 1;
+ if (aj.type_ == "gradient") {
+ var al = aj.x0_ / aB;
+ var m = aj.y0_ / aA;
+ var ak = aj.x1_ / aB;
+ var aM = aj.y1_ / aA;
+ var aJ = V(aq, al, m);
+ var aI = V(aq, ak, aM);
+ var ag = aI.x - aJ.x;
+ var Z = aI.y - aJ.y;
+ an = Math.atan2(ag, Z) * 180 / Math.PI;
+ if (an < 0) {
+ an += 360
+ }
+ if (an < 0.000001) {
+ an = 0
+ }
+ } else {
+ var aJ = V(aq, aj.x0_, aj.y0_);
+ aF = {x: (aJ.x - aK.x) / j, y: (aJ.y - aK.y) / p};
+ j /= aB * d;
+ p /= aA * d;
+ var aD = ab.max(j, p);
+ ax = 2 * aj.r0_ / aD;
+ am = 2 * aj.r1_ / aD - ax
+ }
+ var av = aj.colors_;
+ av.sort(function (aN, i) {
+ return aN.offset - i.offset
+ });
+ var ap = av.length;
+ var au = av[0].color;
+ var at = av[ap - 1].color;
+ var az = av[0].alpha * aq.globalAlpha;
+ var ay = av[ap - 1].alpha * aq.globalAlpha;
+ var aE = [];
+ for (var aH = 0; aH < ap; aH++) {
+ var ao = av[aH];
+ aE.push(ao.offset * am + ax + " " + ao.color)
+ }
+ ai.push(' ')
+ } else {
+ if (aj instanceof T) {
+ if (j && p) {
+ var ah = -aK.x;
+ var aC = -aK.y;
+ ai.push(" ')
+ }
+ } else {
+ var aL = F(aq.fillStyle);
+ var aw = aL.color;
+ var aG = aL.alpha * aq.globalAlpha;
+ ai.push(' ')
+ }
+ }
+ }
+
+ q.fill = function () {
+ this.stroke(true)
+ };
+ q.closePath = function () {
+ this.currentPath_.push({type: "close"})
+ };
+ function V(j, Z, p) {
+ var i = j.m_;
+ return{x: d * (Z * i[0][0] + p * i[1][0] + i[2][0]) - f, y: d * (Z * i[0][1] + p * i[1][1] + i[2][1]) - f}
+ }
+
+ q.save = function () {
+ var i = {};
+ v(this, i);
+ this.aStack_.push(i);
+ this.mStack_.push(this.m_);
+ this.m_ = J(B(), this.m_)
+ };
+ q.restore = function () {
+ if (this.aStack_.length) {
+ v(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop()
+ }
+ };
+ function h(i) {
+ return isFinite(i[0][0]) && isFinite(i[0][1]) && isFinite(i[1][0]) && isFinite(i[1][1]) && isFinite(i[2][0]) && isFinite(i[2][1])
+ }
+
+ function aa(j, i, p) {
+ if (!h(i)) {
+ return
+ }
+ j.m_ = i;
+ if (p) {
+ var Z = i[0][0] * i[1][1] - i[0][1] * i[1][0];
+ j.lineScale_ = N(H(Z))
+ }
+ }
+
+ q.translate = function (m, j) {
+ var i = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [m, j, 1]
+ ];
+ aa(this, J(i, this.m_), false)
+ };
+ q.rotate = function (j) {
+ var p = A(j);
+ var m = l(j);
+ var i = [
+ [p, m, 0],
+ [-m, p, 0],
+ [0, 0, 1]
+ ];
+ aa(this, J(i, this.m_), false)
+ };
+ q.scale = function (m, j) {
+ this.arcScaleX_ *= m;
+ this.arcScaleY_ *= j;
+ var i = [
+ [m, 0, 0],
+ [0, j, 0],
+ [0, 0, 1]
+ ];
+ aa(this, J(i, this.m_), true)
+ };
+ q.transform = function (Z, p, ah, ag, j, i) {
+ var m = [
+ [Z, p, 0],
+ [ah, ag, 0],
+ [j, i, 1]
+ ];
+ aa(this, J(m, this.m_), true)
+ };
+ q.setTransform = function (ag, Z, ai, ah, p, j) {
+ var i = [
+ [ag, Z, 0],
+ [ai, ah, 0],
+ [p, j, 1]
+ ];
+ aa(this, i, true)
+ };
+ q.drawText_ = function (am, ak, aj, ap, ai) {
+ var ao = this.m_, at = 1000, j = 0, ar = at, ah = {x: 0, y: 0}, ag = [];
+ var i = u(E(this.font), this.element_);
+ var p = ac(i);
+ var au = this.element_.currentStyle;
+ var Z = this.textAlign.toLowerCase();
+ switch (Z) {
+ case"left":
+ case"center":
+ case"right":
+ break;
+ case"end":
+ Z = au.direction == "ltr" ? "right" : "left";
+ break;
+ case"start":
+ Z = au.direction == "rtl" ? "right" : "left";
+ break;
+ default:
+ Z = "left"
+ }
+ switch (this.textBaseline) {
+ case"hanging":
+ case"top":
+ ah.y = i.size / 1.75;
+ break;
+ case"middle":
+ break;
+ default:
+ case null:
+ case"alphabetic":
+ case"ideographic":
+ case"bottom":
+ ah.y = -i.size / 2.25;
+ break
+ }
+ switch (Z) {
+ case"right":
+ j = at;
+ ar = 0.05;
+ break;
+ case"center":
+ j = ar = at / 2;
+ break
+ }
+ var aq = V(this, ak + ah.x, aj + ah.y);
+ ag.push('');
+ if (ai) {
+ w(this, ag)
+ } else {
+ G(this, ag, {x: -j, y: 0}, {x: ar, y: i.size})
+ }
+ var an = ao[0][0].toFixed(3) + "," + ao[1][0].toFixed(3) + "," + ao[0][1].toFixed(3) + "," + ao[1][1].toFixed(3) + ",0,0";
+ var al = n(aq.x / d) + "," + n(aq.y / d);
+ ag.push(' ', ' ', ' ');
+ this.element_.insertAdjacentHTML("beforeEnd", ag.join(""))
+ };
+ q.fillText = function (m, i, p, j) {
+ this.drawText_(m, i, p, j, false)
+ };
+ q.strokeText = function (m, i, p, j) {
+ this.drawText_(m, i, p, j, true)
+ };
+ q.measureText = function (m) {
+ if (!this.textMeasureEl_) {
+ var i = ' ';
+ this.element_.insertAdjacentHTML("beforeEnd", i);
+ this.textMeasureEl_ = this.element_.lastChild
+ }
+ var j = this.element_.ownerDocument;
+ this.textMeasureEl_.innerHTML = "";
+ this.textMeasureEl_.style.font = this.font;
+ this.textMeasureEl_.appendChild(j.createTextNode(m));
+ return{width: this.textMeasureEl_.offsetWidth}
+ };
+ q.clip = function () {
+ };
+ q.arcTo = function () {
+ };
+ q.createPattern = function (j, i) {
+ return new T(j, i)
+ };
+ function U(i) {
+ this.type_ = i;
+ this.x0_ = 0;
+ this.y0_ = 0;
+ this.r0_ = 0;
+ this.x1_ = 0;
+ this.y1_ = 0;
+ this.r1_ = 0;
+ this.colors_ = []
+ }
+
+ U.prototype.addColorStop = function (j, i) {
+ i = F(i);
+ this.colors_.push({offset: j, color: i.color, alpha: i.alpha})
+ };
+ function T(j, i) {
+ Q(j);
+ switch (i) {
+ case"repeat":
+ case null:
+ case"":
+ this.repetition_ = "repeat";
+ break;
+ case"repeat-x":
+ case"repeat-y":
+ case"no-repeat":
+ this.repetition_ = i;
+ break;
+ default:
+ O("SYNTAX_ERR")
+ }
+ this.src_ = j.src;
+ this.width_ = j.width;
+ this.height_ = j.height
+ }
+
+ function O(i) {
+ throw new P(i)
+ }
+
+ function Q(i) {
+ if (!i || i.nodeType != 1 || i.tagName != "IMG") {
+ O("TYPE_MISMATCH_ERR")
+ }
+ if (i.readyState != "complete") {
+ O("INVALID_STATE_ERR")
+ }
+ }
+
+ function P(i) {
+ this.code = this[i];
+ this.message = i + ": DOM Exception " + this.code
+ }
+
+ var X = P.prototype = new Error;
+ X.INDEX_SIZE_ERR = 1;
+ X.DOMSTRING_SIZE_ERR = 2;
+ X.HIERARCHY_REQUEST_ERR = 3;
+ X.WRONG_DOCUMENT_ERR = 4;
+ X.INVALID_CHARACTER_ERR = 5;
+ X.NO_DATA_ALLOWED_ERR = 6;
+ X.NO_MODIFICATION_ALLOWED_ERR = 7;
+ X.NOT_FOUND_ERR = 8;
+ X.NOT_SUPPORTED_ERR = 9;
+ X.INUSE_ATTRIBUTE_ERR = 10;
+ X.INVALID_STATE_ERR = 11;
+ X.SYNTAX_ERR = 12;
+ X.INVALID_MODIFICATION_ERR = 13;
+ X.NAMESPACE_ERR = 14;
+ X.INVALID_ACCESS_ERR = 15;
+ X.VALIDATION_ERR = 16;
+ X.TYPE_MISMATCH_ERR = 17;
+ G_vmlCanvasManager = e;
+ CanvasRenderingContext2D = D;
+ CanvasGradient = U;
+ CanvasPattern = T;
+ DOMException = P
+ })()
+}
+;
\ No newline at end of file
diff --git a/src/main/resources/webapp/js/jquery.dataTables.min.js b/src/main/resources/webapp/js/jquery.dataTables.min.js
new file mode 100755
index 0000000..97245bc
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.dataTables.min.js
@@ -0,0 +1,2581 @@
+/*! DataTables 1.10.4
+ * ©2008-2014 SpryMedia Ltd - datatables.net/license
+ */
+(function (Da, P, l) {
+ var O = function (g) {
+ function V(a) {
+ var b, c, e = {};
+ g.each(a, function (d) {
+ if ((b = d.match(/^([^A-Z]+?)([A-Z])/)) && -1 !== "a aa ai ao as b fn i m o s ".indexOf(b[1] + " "))c = d.replace(b[0], b[2].toLowerCase()), e[c] = d, "o" === b[1] && V(a[d])
+ });
+ a._hungarianMap = e
+ }
+
+ function G(a, b, c) {
+ a._hungarianMap || V(a);
+ var e;
+ g.each(b, function (d) {
+ e = a._hungarianMap[d];
+ if (e !== l && (c || b[e] === l))"o" === e.charAt(0) ? (b[e] || (b[e] = {}), g.extend(!0, b[e], b[d]), G(a[e], b[e], c)) : b[e] = b[d]
+ })
+ }
+
+ function O(a) {
+ var b = p.defaults.oLanguage, c = a.sZeroRecords;
+ !a.sEmptyTable && (c && "No data available in table" === b.sEmptyTable) && D(a, a, "sZeroRecords", "sEmptyTable");
+ !a.sLoadingRecords && (c && "Loading..." === b.sLoadingRecords) && D(a, a, "sZeroRecords", "sLoadingRecords");
+ a.sInfoThousands && (a.sThousands = a.sInfoThousands);
+ (a = a.sDecimal) && cb(a)
+ }
+
+ function db(a) {
+ z(a, "ordering", "bSort");
+ z(a, "orderMulti", "bSortMulti");
+ z(a, "orderClasses", "bSortClasses");
+ z(a, "orderCellsTop", "bSortCellsTop");
+ z(a, "order", "aaSorting");
+ z(a, "orderFixed", "aaSortingFixed");
+ z(a, "paging", "bPaginate");
+ z(a, "pagingType", "sPaginationType");
+ z(a, "pageLength", "iDisplayLength");
+ z(a, "searching", "bFilter");
+ if (a = a.aoSearchCols)for (var b = 0, c = a.length; b < c; b++)a[b] && G(p.models.oSearch, a[b])
+ }
+
+ function eb(a) {
+ z(a, "orderable", "bSortable");
+ z(a, "orderData", "aDataSort");
+ z(a, "orderSequence", "asSorting");
+ z(a, "orderDataType", "sortDataType")
+ }
+
+ function fb(a) {
+ var a = a.oBrowser, b = g("
").css({position: "absolute", top: 0, left: 0, height: 1, width: 1, overflow: "hidden"}).append(g("
").css({position: "absolute", top: 1, left: 1, width: 100,
+ overflow: "scroll"}).append(g('
').css({width: "100%", height: 10}))).appendTo("body"), c = b.find(".test");
+ a.bScrollOversize = 100 === c[0].offsetWidth;
+ a.bScrollbarLeft = 1 !== c.offset().left;
+ b.remove()
+ }
+
+ function gb(a, b, c, e, d, f) {
+ var h, i = !1;
+ c !== l && (h = c, i = !0);
+ for (; e !== d;)a.hasOwnProperty(e) && (h = i ? b(h, a[e], e, a) : a[e], i = !0, e += f);
+ return h
+ }
+
+ function Ea(a, b) {
+ var c = p.defaults.column, e = a.aoColumns.length, c = g.extend({}, p.models.oColumn, c, {nTh: b ? b : P.createElement("th"), sTitle: c.sTitle ? c.sTitle : b ? b.innerHTML :
+ "", aDataSort: c.aDataSort ? c.aDataSort : [e], mData: c.mData ? c.mData : e, idx: e});
+ a.aoColumns.push(c);
+ c = a.aoPreSearchCols;
+ c[e] = g.extend({}, p.models.oSearch, c[e]);
+ ja(a, e, null)
+ }
+
+ function ja(a, b, c) {
+ var b = a.aoColumns[b], e = a.oClasses, d = g(b.nTh);
+ if (!b.sWidthOrig) {
+ b.sWidthOrig = d.attr("width") || null;
+ var f = (d.attr("style") || "").match(/width:\s*(\d+[pxem%]+)/);
+ f && (b.sWidthOrig = f[1])
+ }
+ c !== l && null !== c && (eb(c), G(p.defaults.column, c), c.mDataProp !== l && !c.mData && (c.mData = c.mDataProp), c.sType && (b._sManualType = c.sType), c.className && !c.sClass && (c.sClass = c.className), g.extend(b, c), D(b, c, "sWidth", "sWidthOrig"), "number" === typeof c.iDataSort && (b.aDataSort = [c.iDataSort]), D(b, c, "aDataSort"));
+ var h = b.mData, i = W(h), j = b.mRender ? W(b.mRender) : null, c = function (a) {
+ return"string" === typeof a && -1 !== a.indexOf("@")
+ };
+ b._bAttrSrc = g.isPlainObject(h) && (c(h.sort) || c(h.type) || c(h.filter));
+ b.fnGetData = function (a, b, c) {
+ var e = i(a, b, l, c);
+ return j && b ? j(e, b, a, c) : e
+ };
+ b.fnSetData = function (a, b, c) {
+ return Q(h)(a, b, c)
+ };
+ "number" !== typeof h && (a._rowReadObject = !0);
+ a.oFeatures.bSort ||
+ (b.bSortable = !1, d.addClass(e.sSortableNone));
+ a = -1 !== g.inArray("asc", b.asSorting);
+ c = -1 !== g.inArray("desc", b.asSorting);
+ !b.bSortable || !a && !c ? (b.sSortingClass = e.sSortableNone, b.sSortingClassJUI = "") : a && !c ? (b.sSortingClass = e.sSortableAsc, b.sSortingClassJUI = e.sSortJUIAscAllowed) : !a && c ? (b.sSortingClass = e.sSortableDesc, b.sSortingClassJUI = e.sSortJUIDescAllowed) : (b.sSortingClass = e.sSortable, b.sSortingClassJUI = e.sSortJUI)
+ }
+
+ function X(a) {
+ if (!1 !== a.oFeatures.bAutoWidth) {
+ var b = a.aoColumns;
+ Fa(a);
+ for (var c = 0, e = b.length; c <
+ e; c++)b[c].nTh.style.width = b[c].sWidth
+ }
+ b = a.oScroll;
+ ("" !== b.sY || "" !== b.sX) && Y(a);
+ u(a, null, "column-sizing", [a])
+ }
+
+ function ka(a, b) {
+ var c = Z(a, "bVisible");
+ return"number" === typeof c[b] ? c[b] : null
+ }
+
+ function $(a, b) {
+ var c = Z(a, "bVisible"), c = g.inArray(b, c);
+ return-1 !== c ? c : null
+ }
+
+ function aa(a) {
+ return Z(a, "bVisible").length
+ }
+
+ function Z(a, b) {
+ var c = [];
+ g.map(a.aoColumns, function (a, d) {
+ a[b] && c.push(d)
+ });
+ return c
+ }
+
+ function Ga(a) {
+ var b = a.aoColumns, c = a.aoData, e = p.ext.type.detect, d, f, h, i, j, g, m, o, k;
+ d = 0;
+ for (f = b.length; d < f; d++)if (m =
+ b[d], k = [], !m.sType && m._sManualType)m.sType = m._sManualType; else if (!m.sType) {
+ h = 0;
+ for (i = e.length; h < i; h++) {
+ j = 0;
+ for (g = c.length; j < g; j++) {
+ k[j] === l && (k[j] = v(a, j, d, "type"));
+ o = e[h](k[j], a);
+ if (!o && h !== e.length - 1)break;
+ if ("html" === o)break
+ }
+ if (o) {
+ m.sType = o;
+ break
+ }
+ }
+ m.sType || (m.sType = "string")
+ }
+ }
+
+ function hb(a, b, c, e) {
+ var d, f, h, i, j, n, m = a.aoColumns;
+ if (b)for (d = b.length - 1; 0 <= d; d--) {
+ n = b[d];
+ var o = n.targets !== l ? n.targets : n.aTargets;
+ g.isArray(o) || (o = [o]);
+ f = 0;
+ for (h = o.length; f < h; f++)if ("number" === typeof o[f] && 0 <= o[f]) {
+ for (; m.length <=
+ o[f];)Ea(a);
+ e(o[f], n)
+ } else if ("number" === typeof o[f] && 0 > o[f])e(m.length + o[f], n); else if ("string" === typeof o[f]) {
+ i = 0;
+ for (j = m.length; i < j; i++)("_all" == o[f] || g(m[i].nTh).hasClass(o[f])) && e(i, n)
+ }
+ }
+ if (c) {
+ d = 0;
+ for (a = c.length; d < a; d++)e(d, c[d])
+ }
+ }
+
+ function I(a, b, c, e) {
+ var d = a.aoData.length, f = g.extend(!0, {}, p.models.oRow, {src: c ? "dom" : "data"});
+ f._aData = b;
+ a.aoData.push(f);
+ for (var b = a.aoColumns, f = 0, h = b.length; f < h; f++)c && Ha(a, d, f, v(a, d, f)), b[f].sType = null;
+ a.aiDisplayMaster.push(d);
+ (c || !a.oFeatures.bDeferRender) && Ia(a,
+ d, c, e);
+ return d
+ }
+
+ function la(a, b) {
+ var c;
+ b instanceof g || (b = g(b));
+ return b.map(function (b, d) {
+ c = ma(a, d);
+ return I(a, c.data, d, c.cells)
+ })
+ }
+
+ function v(a, b, c, e) {
+ var d = a.iDraw, f = a.aoColumns[c], h = a.aoData[b]._aData, i = f.sDefaultContent, c = f.fnGetData(h, e, {settings: a, row: b, col: c});
+ if (c === l)return a.iDrawError != d && null === i && (R(a, 0, "Requested unknown parameter " + ("function" == typeof f.mData ? "{function}" : "'" + f.mData + "'") + " for row " + b, 4), a.iDrawError = d), i;
+ if ((c === h || null === c) && null !== i)c = i; else if ("function" === typeof c)return c.call(h);
+ return null === c && "display" == e ? "" : c
+ }
+
+ function Ha(a, b, c, e) {
+ a.aoColumns[c].fnSetData(a.aoData[b]._aData, e, {settings: a, row: b, col: c})
+ }
+
+ function Ja(a) {
+ return g.map(a.match(/(\\.|[^\.])+/g), function (a) {
+ return a.replace(/\\./g, ".")
+ })
+ }
+
+ function W(a) {
+ if (g.isPlainObject(a)) {
+ var b = {};
+ g.each(a, function (a, c) {
+ c && (b[a] = W(c))
+ });
+ return function (a, c, f, h) {
+ var i = b[c] || b._;
+ return i !== l ? i(a, c, f, h) : a
+ }
+ }
+ if (null === a)return function (a) {
+ return a
+ };
+ if ("function" === typeof a)return function (b, c, f, h) {
+ return a(b, c, f, h)
+ };
+ if ("string" === typeof a && (-1 !== a.indexOf(".") || -1 !== a.indexOf("[") || -1 !== a.indexOf("("))) {
+ var c = function (a, b, f) {
+ var h, i;
+ if ("" !== f) {
+ i = Ja(f);
+ for (var j = 0, g = i.length; j < g; j++) {
+ f = i[j].match(ba);
+ h = i[j].match(S);
+ if (f) {
+ i[j] = i[j].replace(ba, "");
+ "" !== i[j] && (a = a[i[j]]);
+ h = [];
+ i.splice(0, j + 1);
+ i = i.join(".");
+ j = 0;
+ for (g = a.length; j < g; j++)h.push(c(a[j], b, i));
+ a = f[0].substring(1, f[0].length - 1);
+ a = "" === a ? h : h.join(a);
+ break
+ } else if (h) {
+ i[j] = i[j].replace(S, "");
+ a = a[i[j]]();
+ continue
+ }
+ if (null === a || a[i[j]] === l)return l;
+ a = a[i[j]]
+ }
+ }
+ return a
+ };
+ return function (b, d) {
+ return c(b, d, a)
+ }
+ }
+ return function (b) {
+ return b[a]
+ }
+ }
+
+ function Q(a) {
+ if (g.isPlainObject(a))return Q(a._);
+ if (null === a)return function () {
+ };
+ if ("function" === typeof a)return function (b, e, d) {
+ a(b, "set", e, d)
+ };
+ if ("string" === typeof a && (-1 !== a.indexOf(".") || -1 !== a.indexOf("[") || -1 !== a.indexOf("("))) {
+ var b = function (a, e, d) {
+ var d = Ja(d), f;
+ f = d[d.length - 1];
+ for (var h, i, j = 0, g = d.length - 1; j < g; j++) {
+ h = d[j].match(ba);
+ i = d[j].match(S);
+ if (h) {
+ d[j] = d[j].replace(ba, "");
+ a[d[j]] = [];
+ f = d.slice();
+ f.splice(0, j + 1);
+ h = f.join(".");
+ i = 0;
+ for (g =
+ e.length; i < g; i++)f = {}, b(f, e[i], h), a[d[j]].push(f);
+ return
+ }
+ i && (d[j] = d[j].replace(S, ""), a = a[d[j]](e));
+ if (null === a[d[j]] || a[d[j]] === l)a[d[j]] = {};
+ a = a[d[j]]
+ }
+ if (f.match(S))a[f.replace(S, "")](e); else a[f.replace(ba, "")] = e
+ };
+ return function (c, e) {
+ return b(c, e, a)
+ }
+ }
+ return function (b, e) {
+ b[a] = e
+ }
+ }
+
+ function Ka(a) {
+ return C(a.aoData, "_aData")
+ }
+
+ function na(a) {
+ a.aoData.length = 0;
+ a.aiDisplayMaster.length = 0;
+ a.aiDisplay.length = 0
+ }
+
+ function oa(a, b, c) {
+ for (var e = -1, d = 0, f = a.length; d < f; d++)a[d] == b ? e = d : a[d] > b && a[d]--;
+ -1 != e && c === l &&
+ a.splice(e, 1)
+ }
+
+ function ca(a, b, c, e) {
+ var d = a.aoData[b], f, h = function (c, f) {
+ for (; c.childNodes.length;)c.removeChild(c.firstChild);
+ c.innerHTML = v(a, b, f, "display")
+ };
+ if ("dom" === c || (!c || "auto" === c) && "dom" === d.src)d._aData = ma(a, d, e, e === l ? l : d._aData).data; else {
+ var i = d.anCells;
+ if (i)if (e !== l)h(i[e], e); else {
+ c = 0;
+ for (f = i.length; c < f; c++)h(i[c], c)
+ }
+ }
+ d._aSortData = null;
+ d._aFilterData = null;
+ h = a.aoColumns;
+ if (e !== l)h[e].sType = null; else {
+ c = 0;
+ for (f = h.length; c < f; c++)h[c].sType = null;
+ La(d)
+ }
+ }
+
+ function ma(a, b, c, e) {
+ var d = [], f = b.firstChild,
+ h, i = 0, j, n = a.aoColumns, m = a._rowReadObject, e = e || m ? {} : [], o = function (a, b) {
+ if ("string" === typeof a) {
+ var c = a.indexOf("@");
+ -1 !== c && (c = a.substring(c + 1), Q(a)(e, b.getAttribute(c)))
+ }
+ }, a = function (a) {
+ if (c === l || c === i)h = n[i], j = g.trim(a.innerHTML), h && h._bAttrSrc ? (Q(h.mData._)(e, j), o(h.mData.sort, a), o(h.mData.type, a), o(h.mData.filter, a)) : m ? (h._setter || (h._setter = Q(h.mData)), h._setter(e, j)) : e[i] = j;
+ i++
+ };
+ if (f)for (; f;) {
+ b = f.nodeName.toUpperCase();
+ if ("TD" == b || "TH" == b)a(f), d.push(f);
+ f = f.nextSibling
+ } else {
+ d = b.anCells;
+ f = 0;
+ for (b =
+ d.length; f < b; f++)a(d[f])
+ }
+ return{data: e, cells: d}
+ }
+
+ function Ia(a, b, c, e) {
+ var d = a.aoData[b], f = d._aData, h = [], i, j, g, m, o;
+ if (null === d.nTr) {
+ i = c || P.createElement("tr");
+ d.nTr = i;
+ d.anCells = h;
+ i._DT_RowIndex = b;
+ La(d);
+ m = 0;
+ for (o = a.aoColumns.length; m < o; m++) {
+ g = a.aoColumns[m];
+ j = c ? e[m] : P.createElement(g.sCellType);
+ h.push(j);
+ if (!c || g.mRender || g.mData !== m)j.innerHTML = v(a, b, m, "display");
+ g.sClass && (j.className += " " + g.sClass);
+ g.bVisible && !c ? i.appendChild(j) : !g.bVisible && c && j.parentNode.removeChild(j);
+ g.fnCreatedCell && g.fnCreatedCell.call(a.oInstance,
+ j, v(a, b, m), f, b, m)
+ }
+ u(a, "aoRowCreatedCallback", null, [i, f, b])
+ }
+ d.nTr.setAttribute("role", "row")
+ }
+
+ function La(a) {
+ var b = a.nTr, c = a._aData;
+ if (b) {
+ c.DT_RowId && (b.id = c.DT_RowId);
+ if (c.DT_RowClass) {
+ var e = c.DT_RowClass.split(" ");
+ a.__rowc = a.__rowc ? Ma(a.__rowc.concat(e)) : e;
+ g(b).removeClass(a.__rowc.join(" ")).addClass(c.DT_RowClass)
+ }
+ c.DT_RowData && g(b).data(c.DT_RowData)
+ }
+ }
+
+ function ib(a) {
+ var b, c, e, d, f, h = a.nTHead, i = a.nTFoot, j = 0 === g("th, td", h).length, n = a.oClasses, m = a.aoColumns;
+ j && (d = g(" ").appendTo(h));
+ b = 0;
+ for (c =
+ m.length; b < c; b++)f = m[b], e = g(f.nTh).addClass(f.sClass), j && e.appendTo(d), a.oFeatures.bSort && (e.addClass(f.sSortingClass), !1 !== f.bSortable && (e.attr("tabindex", a.iTabIndex).attr("aria-controls", a.sTableId), Na(a, f.nTh, b))), f.sTitle != e.html() && e.html(f.sTitle), Oa(a, "header")(a, e, f, n);
+ j && da(a.aoHeader, h);
+ g(h).find(">tr").attr("role", "row");
+ g(h).find(">tr>th, >tr>td").addClass(n.sHeaderTH);
+ g(i).find(">tr>th, >tr>td").addClass(n.sFooterTH);
+ if (null !== i) {
+ a = a.aoFooter[0];
+ b = 0;
+ for (c = a.length; b < c; b++)f = m[b], f.nTf =
+ a[b].cell, f.sClass && g(f.nTf).addClass(f.sClass)
+ }
+ }
+
+ function ea(a, b, c) {
+ var e, d, f, h = [], i = [], j = a.aoColumns.length, n;
+ if (b) {
+ c === l && (c = !1);
+ e = 0;
+ for (d = b.length; e < d; e++) {
+ h[e] = b[e].slice();
+ h[e].nTr = b[e].nTr;
+ for (f = j - 1; 0 <= f; f--)!a.aoColumns[f].bVisible && !c && h[e].splice(f, 1);
+ i.push([])
+ }
+ e = 0;
+ for (d = h.length; e < d; e++) {
+ if (a = h[e].nTr)for (; f = a.firstChild;)a.removeChild(f);
+ f = 0;
+ for (b = h[e].length; f < b; f++)if (n = j = 1, i[e][f] === l) {
+ a.appendChild(h[e][f].cell);
+ for (i[e][f] = 1; h[e + j] !== l && h[e][f].cell == h[e + j][f].cell;)i[e + j][f] = 1, j++;
+ for (; h[e][f + n] !== l && h[e][f].cell == h[e][f + n].cell;) {
+ for (c = 0; c < j; c++)i[e + c][f + n] = 1;
+ n++
+ }
+ g(h[e][f].cell).attr("rowspan", j).attr("colspan", n)
+ }
+ }
+ }
+ }
+
+ function L(a) {
+ var b = u(a, "aoPreDrawCallback", "preDraw", [a]);
+ if (-1 !== g.inArray(!1, b))B(a, !1); else {
+ var b = [], c = 0, e = a.asStripeClasses, d = e.length, f = a.oLanguage, h = a.iInitDisplayStart, i = "ssp" == A(a), j = a.aiDisplay;
+ a.bDrawing = !0;
+ h !== l && -1 !== h && (a._iDisplayStart = i ? h : h >= a.fnRecordsDisplay() ? 0 : h, a.iInitDisplayStart = -1);
+ var h = a._iDisplayStart, n = a.fnDisplayEnd();
+ if (a.bDeferLoading)a.bDeferLoading = !1, a.iDraw++, B(a, !1); else if (i) {
+ if (!a.bDestroying && !jb(a))return
+ } else a.iDraw++;
+ if (0 !== j.length) {
+ f = i ? a.aoData.length : n;
+ for (i = i ? 0 : h; i < f; i++) {
+ var m = j[i], o = a.aoData[m];
+ null === o.nTr && Ia(a, m);
+ m = o.nTr;
+ if (0 !== d) {
+ var k = e[c % d];
+ o._sRowStripe != k && (g(m).removeClass(o._sRowStripe).addClass(k), o._sRowStripe = k)
+ }
+ u(a, "aoRowCallback", null, [m, o._aData, c, i]);
+ b.push(m);
+ c++
+ }
+ } else c = f.sZeroRecords, 1 == a.iDraw && "ajax" == A(a) ? c = f.sLoadingRecords : f.sEmptyTable && 0 === a.fnRecordsTotal() && (c = f.sEmptyTable), b[0] = g(" ", {"class": d ?
+ e[0] : ""}).append(g(" ", {valign: "top", colSpan: aa(a), "class": a.oClasses.sRowEmpty}).html(c))[0];
+ u(a, "aoHeaderCallback", "header", [g(a.nTHead).children("tr")[0], Ka(a), h, n, j]);
+ u(a, "aoFooterCallback", "footer", [g(a.nTFoot).children("tr")[0], Ka(a), h, n, j]);
+ e = g(a.nTBody);
+ e.children().detach();
+ e.append(g(b));
+ u(a, "aoDrawCallback", "draw", [a]);
+ a.bSorted = !1;
+ a.bFiltered = !1;
+ a.bDrawing = !1
+ }
+ }
+
+ function M(a, b) {
+ var c = a.oFeatures, e = c.bFilter;
+ c.bSort && kb(a);
+ e ? fa(a, a.oPreviousSearch) : a.aiDisplay = a.aiDisplayMaster.slice();
+ !0 !== b && (a._iDisplayStart = 0);
+ a._drawHold = b;
+ L(a);
+ a._drawHold = !1
+ }
+
+ function lb(a) {
+ var b = a.oClasses, c = g(a.nTable), c = g("
").insertBefore(c), e = a.oFeatures, d = g("
", {id: a.sTableId + "_wrapper", "class": b.sWrapper + (a.nTFoot ? "" : " " + b.sNoFooter)});
+ a.nHolding = c[0];
+ a.nTableWrapper = d[0];
+ a.nTableReinsertBefore = a.nTable.nextSibling;
+ for (var f = a.sDom.split(""), h, i, j, n, m, o, k = 0; k < f.length; k++) {
+ h = null;
+ i = f[k];
+ if ("<" == i) {
+ j = g("
")[0];
+ n = f[k + 1];
+ if ("'" == n || '"' == n) {
+ m = "";
+ for (o = 2; f[k + o] != n;)m += f[k + o], o++;
+ "H" == m ? m = b.sJUIHeader :
+ "F" == m && (m = b.sJUIFooter);
+ -1 != m.indexOf(".") ? (n = m.split("."), j.id = n[0].substr(1, n[0].length - 1), j.className = n[1]) : "#" == m.charAt(0) ? j.id = m.substr(1, m.length - 1) : j.className = m;
+ k += o
+ }
+ d.append(j);
+ d = g(j)
+ } else if (">" == i)d = d.parent(); else if ("l" == i && e.bPaginate && e.bLengthChange)h = mb(a); else if ("f" == i && e.bFilter)h = nb(a); else if ("r" == i && e.bProcessing)h = ob(a); else if ("t" == i)h = pb(a); else if ("i" == i && e.bInfo)h = qb(a); else if ("p" == i && e.bPaginate)h = rb(a); else if (0 !== p.ext.feature.length) {
+ j = p.ext.feature;
+ o = 0;
+ for (n = j.length; o <
+ n; o++)if (i == j[o].cFeature) {
+ h = j[o].fnInit(a);
+ break
+ }
+ }
+ h && (j = a.aanFeatures, j[i] || (j[i] = []), j[i].push(h), d.append(h))
+ }
+ c.replaceWith(d)
+ }
+
+ function da(a, b) {
+ var c = g(b).children("tr"), e, d, f, h, i, j, n, m, o, k;
+ a.splice(0, a.length);
+ f = 0;
+ for (j = c.length; f < j; f++)a.push([]);
+ f = 0;
+ for (j = c.length; f < j; f++) {
+ e = c[f];
+ for (d = e.firstChild; d;) {
+ if ("TD" == d.nodeName.toUpperCase() || "TH" == d.nodeName.toUpperCase()) {
+ m = 1 * d.getAttribute("colspan");
+ o = 1 * d.getAttribute("rowspan");
+ m = !m || 0 === m || 1 === m ? 1 : m;
+ o = !o || 0 === o || 1 === o ? 1 : o;
+ h = 0;
+ for (i = a[f]; i[h];)h++;
+ n = h;
+ k = 1 === m ? !0 : !1;
+ for (i = 0; i < m; i++)for (h = 0; h < o; h++)a[f + h][n + i] = {cell: d, unique: k}, a[f + h].nTr = e
+ }
+ d = d.nextSibling
+ }
+ }
+ }
+
+ function pa(a, b, c) {
+ var e = [];
+ c || (c = a.aoHeader, b && (c = [], da(c, b)));
+ for (var b = 0, d = c.length; b < d; b++)for (var f = 0, h = c[b].length; f < h; f++)if (c[b][f].unique && (!e[f] || !a.bSortCellsTop))e[f] = c[b][f].cell;
+ return e
+ }
+
+ function qa(a, b, c) {
+ u(a, "aoServerParams", "serverParams", [b]);
+ if (b && g.isArray(b)) {
+ var e = {}, d = /(.*?)\[\]$/;
+ g.each(b, function (a, b) {
+ var c = b.name.match(d);
+ c ? (c = c[0], e[c] || (e[c] = []), e[c].push(b.value)) :
+ e[b.name] = b.value
+ });
+ b = e
+ }
+ var f, h = a.ajax, i = a.oInstance;
+ if (g.isPlainObject(h) && h.data) {
+ f = h.data;
+ var j = g.isFunction(f) ? f(b) : f, b = g.isFunction(f) && j ? j : g.extend(!0, b, j);
+ delete h.data
+ }
+ j = {data: b, success: function (b) {
+ var f = b.error || b.sError;
+ f && a.oApi._fnLog(a, 0, f);
+ a.json = b;
+ u(a, null, "xhr", [a, b]);
+ c(b)
+ }, dataType: "json", cache: !1, type: a.sServerMethod, error: function (b, c) {
+ var f = a.oApi._fnLog;
+ "parsererror" == c ? f(a, 0, "Invalid JSON response", 1) : 4 === b.readyState && f(a, 0, "Ajax error", 7);
+ B(a, !1)
+ }};
+ a.oAjaxData = b;
+ u(a, null, "preXhr",
+ [a, b]);
+ a.fnServerData ? a.fnServerData.call(i, a.sAjaxSource, g.map(b, function (a, b) {
+ return{name: b, value: a}
+ }), c, a) : a.sAjaxSource || "string" === typeof h ? a.jqXHR = g.ajax(g.extend(j, {url: h || a.sAjaxSource})) : g.isFunction(h) ? a.jqXHR = h.call(i, b, c, a) : (a.jqXHR = g.ajax(g.extend(j, h)), h.data = f)
+ }
+
+ function jb(a) {
+ return a.bAjaxDataGet ? (a.iDraw++, B(a, !0), qa(a, sb(a), function (b) {
+ tb(a, b)
+ }), !1) : !0
+ }
+
+ function sb(a) {
+ var b = a.aoColumns, c = b.length, e = a.oFeatures, d = a.oPreviousSearch, f = a.aoPreSearchCols, h, i = [], j, n, m, o = T(a);
+ h = a._iDisplayStart;
+ j = !1 !== e.bPaginate ? a._iDisplayLength : -1;
+ var k = function (a, b) {
+ i.push({name: a, value: b})
+ };
+ k("sEcho", a.iDraw);
+ k("iColumns", c);
+ k("sColumns", C(b, "sName").join(","));
+ k("iDisplayStart", h);
+ k("iDisplayLength", j);
+ var l = {draw: a.iDraw, columns: [], order: [], start: h, length: j, search: {value: d.sSearch, regex: d.bRegex}};
+ for (h = 0; h < c; h++)n = b[h], m = f[h], j = "function" == typeof n.mData ? "function" : n.mData, l.columns.push({data: j, name: n.sName, searchable: n.bSearchable, orderable: n.bSortable, search: {value: m.sSearch, regex: m.bRegex}}),
+ k("mDataProp_" + h, j), e.bFilter && (k("sSearch_" + h, m.sSearch), k("bRegex_" + h, m.bRegex), k("bSearchable_" + h, n.bSearchable)), e.bSort && k("bSortable_" + h, n.bSortable);
+ e.bFilter && (k("sSearch", d.sSearch), k("bRegex", d.bRegex));
+ e.bSort && (g.each(o, function (a, b) {
+ l.order.push({column: b.col, dir: b.dir});
+ k("iSortCol_" + a, b.col);
+ k("sSortDir_" + a, b.dir)
+ }), k("iSortingCols", o.length));
+ b = p.ext.legacy.ajax;
+ return null === b ? a.sAjaxSource ? i : l : b ? i : l
+ }
+
+ function tb(a, b) {
+ var c = b.sEcho !== l ? b.sEcho : b.draw, e = b.iTotalRecords !== l ? b.iTotalRecords :
+ b.recordsTotal, d = b.iTotalDisplayRecords !== l ? b.iTotalDisplayRecords : b.recordsFiltered;
+ if (c) {
+ if (1 * c < a.iDraw)return;
+ a.iDraw = 1 * c
+ }
+ na(a);
+ a._iRecordsTotal = parseInt(e, 10);
+ a._iRecordsDisplay = parseInt(d, 10);
+ c = ra(a, b);
+ e = 0;
+ for (d = c.length; e < d; e++)I(a, c[e]);
+ a.aiDisplay = a.aiDisplayMaster.slice();
+ a.bAjaxDataGet = !1;
+ L(a);
+ a._bInitComplete || sa(a, b);
+ a.bAjaxDataGet = !0;
+ B(a, !1)
+ }
+
+ function ra(a, b) {
+ var c = g.isPlainObject(a.ajax) && a.ajax.dataSrc !== l ? a.ajax.dataSrc : a.sAjaxDataProp;
+ return"data" === c ? b.aaData || b[c] : "" !== c ? W(c)(b) :
+ b
+ }
+
+ function nb(a) {
+ var b = a.oClasses, c = a.sTableId, e = a.oLanguage, d = a.oPreviousSearch, f = a.aanFeatures, h = ' ', i = e.sSearch, i = i.match(/_INPUT_/) ? i.replace("_INPUT_", h) : i + h, b = g("
", {id: !f.f ? c + "_filter" : null, "class": b.sFilter}).append(g(" ").append(i)), f = function () {
+ var b = !this.value ? "" : this.value;
+ b != d.sSearch && (fa(a, {sSearch: b, bRegex: d.bRegex, bSmart: d.bSmart, bCaseInsensitive: d.bCaseInsensitive}), a._iDisplayStart = 0, L(a))
+ }, h = null !== a.searchDelay ? a.searchDelay :
+ "ssp" === A(a) ? 400 : 0, j = g("input", b).val(d.sSearch).attr("placeholder", e.sSearchPlaceholder).bind("keyup.DT search.DT input.DT paste.DT cut.DT", h ? ta(f, h) : f).bind("keypress.DT", function (a) {
+ if (13 == a.keyCode)return!1
+ }).attr("aria-controls", c);
+ g(a.nTable).on("search.dt.DT", function (b, c) {
+ if (a === c)try {
+ j[0] !== P.activeElement && j.val(d.sSearch)
+ } catch (f) {
+ }
+ });
+ return b[0]
+ }
+
+ function fa(a, b, c) {
+ var e = a.oPreviousSearch, d = a.aoPreSearchCols, f = function (a) {
+ e.sSearch = a.sSearch;
+ e.bRegex = a.bRegex;
+ e.bSmart = a.bSmart;
+ e.bCaseInsensitive =
+ a.bCaseInsensitive
+ };
+ Ga(a);
+ if ("ssp" != A(a)) {
+ ub(a, b.sSearch, c, b.bEscapeRegex !== l ? !b.bEscapeRegex : b.bRegex, b.bSmart, b.bCaseInsensitive);
+ f(b);
+ for (b = 0; b < d.length; b++)vb(a, d[b].sSearch, b, d[b].bEscapeRegex !== l ? !d[b].bEscapeRegex : d[b].bRegex, d[b].bSmart, d[b].bCaseInsensitive);
+ wb(a)
+ } else f(b);
+ a.bFiltered = !0;
+ u(a, null, "search", [a])
+ }
+
+ function wb(a) {
+ for (var b = p.ext.search, c = a.aiDisplay, e, d, f = 0, h = b.length; f < h; f++) {
+ for (var i = [], j = 0, g = c.length; j < g; j++)d = c[j], e = a.aoData[d], b[f](a, e._aFilterData, d, e._aData, j) && i.push(d);
+ c.length = 0;
+ c.push.apply(c, i)
+ }
+ }
+
+ function vb(a, b, c, e, d, f) {
+ if ("" !== b)for (var h = a.aiDisplay, e = Pa(b, e, d, f), d = h.length - 1; 0 <= d; d--)b = a.aoData[h[d]]._aFilterData[c], e.test(b) || h.splice(d, 1)
+ }
+
+ function ub(a, b, c, e, d, f) {
+ var e = Pa(b, e, d, f), d = a.oPreviousSearch.sSearch, f = a.aiDisplayMaster, h;
+ 0 !== p.ext.search.length && (c = !0);
+ h = xb(a);
+ if (0 >= b.length)a.aiDisplay = f.slice(); else {
+ if (h || c || d.length > b.length || 0 !== b.indexOf(d) || a.bSorted)a.aiDisplay = f.slice();
+ b = a.aiDisplay;
+ for (c = b.length - 1; 0 <= c; c--)e.test(a.aoData[b[c]]._sFilterRow) ||
+ b.splice(c, 1)
+ }
+ }
+
+ function Pa(a, b, c, e) {
+ a = b ? a : ua(a);
+ c && (a = "^(?=.*?" + g.map(a.match(/"[^"]+"|[^ ]+/g) || "", function (a) {
+ if ('"' === a.charAt(0))var b = a.match(/^"(.*)"$/), a = b ? b[1] : a;
+ return a.replace('"', "")
+ }).join(")(?=.*?") + ").*$");
+ return RegExp(a, e ? "i" : "")
+ }
+
+ function ua(a) {
+ return a.replace(Xb, "\\$1")
+ }
+
+ function xb(a) {
+ var b = a.aoColumns, c, e, d, f, h, i, g, n, m = p.ext.type.search;
+ c = !1;
+ e = 0;
+ for (f = a.aoData.length; e < f; e++)if (n = a.aoData[e], !n._aFilterData) {
+ i = [];
+ d = 0;
+ for (h = b.length; d < h; d++)c = b[d], c.bSearchable ? (g = v(a, e, d, "filter"),
+ m[c.sType] && (g = m[c.sType](g)), null === g && (g = ""), "string" !== typeof g && g.toString && (g = g.toString())) : g = "", g.indexOf && -1 !== g.indexOf("&") && (va.innerHTML = g, g = Yb ? va.textContent : va.innerText), g.replace && (g = g.replace(/[\r\n]/g, "")), i.push(g);
+ n._aFilterData = i;
+ n._sFilterRow = i.join(" ");
+ c = !0
+ }
+ return c
+ }
+
+ function yb(a) {
+ return{search: a.sSearch, smart: a.bSmart, regex: a.bRegex, caseInsensitive: a.bCaseInsensitive}
+ }
+
+ function zb(a) {
+ return{sSearch: a.search, bSmart: a.smart, bRegex: a.regex, bCaseInsensitive: a.caseInsensitive}
+ }
+
+ function qb(a) {
+ var b = a.sTableId, c = a.aanFeatures.i, e = g("
", {"class": a.oClasses.sInfo, id: !c ? b + "_info" : null});
+ c || (a.aoDrawCallback.push({fn: Ab, sName: "information"}), e.attr("role", "status").attr("aria-live", "polite"), g(a.nTable).attr("aria-describedby", b + "_info"));
+ return e[0]
+ }
+
+ function Ab(a) {
+ var b = a.aanFeatures.i;
+ if (0 !== b.length) {
+ var c = a.oLanguage, e = a._iDisplayStart + 1, d = a.fnDisplayEnd(), f = a.fnRecordsTotal(), h = a.fnRecordsDisplay(), i = h ? c.sInfo : c.sInfoEmpty;
+ h !== f && (i += " " + c.sInfoFiltered);
+ i += c.sInfoPostFix;
+ i = Bb(a, i);
+ c = c.fnInfoCallback;
+ null !== c && (i = c.call(a.oInstance, a, e, d, f, h, i));
+ g(b).html(i)
+ }
+ }
+
+ function Bb(a, b) {
+ var c = a.fnFormatNumber, e = a._iDisplayStart + 1, d = a._iDisplayLength, f = a.fnRecordsDisplay(), h = -1 === d;
+ return b.replace(/_START_/g, c.call(a, e)).replace(/_END_/g, c.call(a, a.fnDisplayEnd())).replace(/_MAX_/g, c.call(a, a.fnRecordsTotal())).replace(/_TOTAL_/g, c.call(a, f)).replace(/_PAGE_/g, c.call(a, h ? 1 : Math.ceil(e / d))).replace(/_PAGES_/g, c.call(a, h ? 1 : Math.ceil(f / d)))
+ }
+
+ function ga(a) {
+ var b, c, e = a.iInitDisplayStart,
+ d = a.aoColumns, f;
+ c = a.oFeatures;
+ if (a.bInitialised) {
+ lb(a);
+ ib(a);
+ ea(a, a.aoHeader);
+ ea(a, a.aoFooter);
+ B(a, !0);
+ c.bAutoWidth && Fa(a);
+ b = 0;
+ for (c = d.length; b < c; b++)f = d[b], f.sWidth && (f.nTh.style.width = s(f.sWidth));
+ M(a);
+ d = A(a);
+ "ssp" != d && ("ajax" == d ? qa(a, [], function (c) {
+ var f = ra(a, c);
+ for (b = 0; b < f.length; b++)I(a, f[b]);
+ a.iInitDisplayStart = e;
+ M(a);
+ B(a, !1);
+ sa(a, c)
+ }, a) : (B(a, !1), sa(a)))
+ } else setTimeout(function () {
+ ga(a)
+ }, 200)
+ }
+
+ function sa(a, b) {
+ a._bInitComplete = !0;
+ b && X(a);
+ u(a, "aoInitComplete", "init", [a, b])
+ }
+
+ function Qa(a, b) {
+ var c =
+ parseInt(b, 10);
+ a._iDisplayLength = c;
+ Ra(a);
+ u(a, null, "length", [a, c])
+ }
+
+ function mb(a) {
+ for (var b = a.oClasses, c = a.sTableId, e = a.aLengthMenu, d = g.isArray(e[0]), f = d ? e[0] : e, e = d ? e[1] : e, d = g(" ", {name: c + "_length", "aria-controls": c, "class": b.sLengthSelect}), h = 0, i = f.length; h < i; h++)d[0][h] = new Option(e[h], f[h]);
+ var j = g("
").addClass(b.sLength);
+ a.aanFeatures.l || (j[0].id = c + "_length");
+ j.children().append(a.oLanguage.sLengthMenu.replace("_MENU_", d[0].outerHTML));
+ g("select", j).val(a._iDisplayLength).bind("change.DT",
+ function () {
+ Qa(a, g(this).val());
+ L(a)
+ });
+ g(a.nTable).bind("length.dt.DT", function (b, c, f) {
+ a === c && g("select", j).val(f)
+ });
+ return j[0]
+ }
+
+ function rb(a) {
+ var b = a.sPaginationType, c = p.ext.pager[b], e = "function" === typeof c, d = function (a) {
+ L(a)
+ }, b = g("
").addClass(a.oClasses.sPaging + b)[0], f = a.aanFeatures;
+ e || c.fnInit(a, b, d);
+ f.p || (b.id = a.sTableId + "_paginate", a.aoDrawCallback.push({fn: function (a) {
+ if (e) {
+ var b = a._iDisplayStart, g = a._iDisplayLength, n = a.fnRecordsDisplay(), m = -1 === g, b = m ? 0 : Math.ceil(b / g), g = m ? 1 : Math.ceil(n /
+ g), n = c(b, g), o, m = 0;
+ for (o = f.p.length; m < o; m++)Oa(a, "pageButton")(a, f.p[m], m, n, b, g)
+ } else c.fnUpdate(a, d)
+ }, sName: "pagination"}));
+ return b
+ }
+
+ function Sa(a, b, c) {
+ var e = a._iDisplayStart, d = a._iDisplayLength, f = a.fnRecordsDisplay();
+ 0 === f || -1 === d ? e = 0 : "number" === typeof b ? (e = b * d, e > f && (e = 0)) : "first" == b ? e = 0 : "previous" == b ? (e = 0 <= d ? e - d : 0, 0 > e && (e = 0)) : "next" == b ? e + d < f && (e += d) : "last" == b ? e = Math.floor((f - 1) / d) * d : R(a, 0, "Unknown paging action: " + b, 5);
+ b = a._iDisplayStart !== e;
+ a._iDisplayStart = e;
+ b && (u(a, null, "page", [a]), c && L(a));
+ return b
+ }
+
+ function ob(a) {
+ return g("
", {id: !a.aanFeatures.r ? a.sTableId + "_processing" : null, "class": a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]
+ }
+
+ function B(a, b) {
+ a.oFeatures.bProcessing && g(a.aanFeatures.r).css("display", b ? "block" : "none");
+ u(a, null, "processing", [a, b])
+ }
+
+ function pb(a) {
+ var b = g(a.nTable);
+ b.attr("role", "grid");
+ var c = a.oScroll;
+ if ("" === c.sX && "" === c.sY)return a.nTable;
+ var e = c.sX, d = c.sY, f = a.oClasses, h = b.children("caption"), i = h.length ? h[0]._captionSide : null,
+ j = g(b[0].cloneNode(!1)), n = g(b[0].cloneNode(!1)), m = b.children("tfoot");
+ c.sX && "100%" === b.attr("width") && b.removeAttr("width");
+ m.length || (m = null);
+ c = g("
", {"class": f.sScrollWrapper}).append(g("
", {"class": f.sScrollHead}).css({overflow: "hidden", position: "relative", border: 0, width: e ? !e ? null : s(e) : "100%"}).append(g("
", {"class": f.sScrollHeadInner}).css({"box-sizing": "content-box", width: c.sXInner || "100%"}).append(j.removeAttr("id").css("margin-left", 0).append("top" === i ? h : null).append(b.children("thead"))))).append(g("
",
+ {"class": f.sScrollBody}).css({overflow: "auto", height: !d ? null : s(d), width: !e ? null : s(e)}).append(b));
+ m && c.append(g("
", {"class": f.sScrollFoot}).css({overflow: "hidden", border: 0, width: e ? !e ? null : s(e) : "100%"}).append(g("
", {"class": f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left", 0).append("bottom" === i ? h : null).append(b.children("tfoot")))));
+ var b = c.children(), o = b[0], f = b[1], k = m ? b[2] : null;
+ e && g(f).scroll(function () {
+ var a = this.scrollLeft;
+ o.scrollLeft = a;
+ m && (k.scrollLeft = a)
+ });
+ a.nScrollHead =
+ o;
+ a.nScrollBody = f;
+ a.nScrollFoot = k;
+ a.aoDrawCallback.push({fn: Y, sName: "scrolling"});
+ return c[0]
+ }
+
+ function Y(a) {
+ var b = a.oScroll, c = b.sX, e = b.sXInner, d = b.sY, f = b.iBarWidth, h = g(a.nScrollHead), i = h[0].style, j = h.children("div"), n = j[0].style, m = j.children("table"), j = a.nScrollBody, o = g(j), k = j.style, l = g(a.nScrollFoot).children("div"), p = l.children("table"), r = g(a.nTHead), q = g(a.nTable), t = q[0], N = t.style, J = a.nTFoot ? g(a.nTFoot) : null, u = a.oBrowser, w = u.bScrollOversize, y, v, x, K, z, A = [], B = [], C = [], D, E = function (a) {
+ a = a.style;
+ a.paddingTop =
+ "0";
+ a.paddingBottom = "0";
+ a.borderTopWidth = "0";
+ a.borderBottomWidth = "0";
+ a.height = 0
+ };
+ q.children("thead, tfoot").remove();
+ z = r.clone().prependTo(q);
+ y = r.find("tr");
+ x = z.find("tr");
+ z.find("th, td").removeAttr("tabindex");
+ J && (K = J.clone().prependTo(q), v = J.find("tr"), K = K.find("tr"));
+ c || (k.width = "100%", h[0].style.width = "100%");
+ g.each(pa(a, z), function (b, c) {
+ D = ka(a, b);
+ c.style.width = a.aoColumns[D].sWidth
+ });
+ J && F(function (a) {
+ a.style.width = ""
+ }, K);
+ b.bCollapse && "" !== d && (k.height = o[0].offsetHeight + r[0].offsetHeight + "px");
+ h = q.outerWidth();
+ if ("" === c) {
+ if (N.width = "100%", w && (q.find("tbody").height() > j.offsetHeight || "scroll" == o.css("overflow-y")))N.width = s(q.outerWidth() - f)
+ } else"" !== e ? N.width = s(e) : h == o.width() && o.height() < q.height() ? (N.width = s(h - f), q.outerWidth() > h - f && (N.width = s(h))) : N.width = s(h);
+ h = q.outerWidth();
+ F(E, x);
+ F(function (a) {
+ C.push(a.innerHTML);
+ A.push(s(g(a).css("width")))
+ }, x);
+ F(function (a, b) {
+ a.style.width = A[b]
+ }, y);
+ g(x).height(0);
+ J && (F(E, K), F(function (a) {
+ B.push(s(g(a).css("width")))
+ }, K), F(function (a, b) {
+ a.style.width =
+ B[b]
+ }, v), g(K).height(0));
+ F(function (a, b) {
+ a.innerHTML = '' + C[b] + "
";
+ a.style.width = A[b]
+ }, x);
+ J && F(function (a, b) {
+ a.innerHTML = "";
+ a.style.width = B[b]
+ }, K);
+ if (q.outerWidth() < h) {
+ v = j.scrollHeight > j.offsetHeight || "scroll" == o.css("overflow-y") ? h + f : h;
+ if (w && (j.scrollHeight > j.offsetHeight || "scroll" == o.css("overflow-y")))N.width = s(v - f);
+ ("" === c || "" !== e) && R(a, 1, "Possible column misalignment", 6)
+ } else v = "100%";
+ k.width = s(v);
+ i.width = s(v);
+ J && (a.nScrollFoot.style.width =
+ s(v));
+ !d && w && (k.height = s(t.offsetHeight + f));
+ d && b.bCollapse && (k.height = s(d), b = c && t.offsetWidth > j.offsetWidth ? f : 0, t.offsetHeight < j.offsetHeight && (k.height = s(t.offsetHeight + b)));
+ b = q.outerWidth();
+ m[0].style.width = s(b);
+ n.width = s(b);
+ m = q.height() > j.clientHeight || "scroll" == o.css("overflow-y");
+ u = "padding" + (u.bScrollbarLeft ? "Left" : "Right");
+ n[u] = m ? f + "px" : "0px";
+ J && (p[0].style.width = s(b), l[0].style.width = s(b), l[0].style[u] = m ? f + "px" : "0px");
+ o.scroll();
+ if ((a.bSorted || a.bFiltered) && !a._drawHold)j.scrollTop = 0
+ }
+
+ function F(a, b, c) {
+ for (var e = 0, d = 0, f = b.length, h, g; d < f;) {
+ h = b[d].firstChild;
+ for (g = c ? c[d].firstChild : null; h;)1 === h.nodeType && (c ? a(h, g, e) : a(h, e), e++), h = h.nextSibling, g = c ? g.nextSibling : null;
+ d++
+ }
+ }
+
+ function Fa(a) {
+ var b = a.nTable, c = a.aoColumns, e = a.oScroll, d = e.sY, f = e.sX, h = e.sXInner, i = c.length, e = Z(a, "bVisible"), j = g("th", a.nTHead), n = b.getAttribute("width"), m = b.parentNode, o = !1, k, l;
+ for (k = 0; k < e.length; k++)l = c[e[k]], null !== l.sWidth && (l.sWidth = Cb(l.sWidthOrig, m), o = !0);
+ if (!o && !f && !d && i == aa(a) && i == j.length)for (k = 0; k < i; k++)c[k].sWidth =
+ s(j.eq(k).width()); else {
+ i = g(b).clone().empty().css("visibility", "hidden").removeAttr("id").append(g(a.nTHead).clone(!1)).append(g(a.nTFoot).clone(!1)).append(g(" "));
+ i.find("tfoot th, tfoot td").css("width", "");
+ var p = i.find("tbody tr"), j = pa(a, i.find("thead")[0]);
+ for (k = 0; k < e.length; k++)l = c[e[k]], j[k].style.width = null !== l.sWidthOrig && "" !== l.sWidthOrig ? s(l.sWidthOrig) : "";
+ if (a.aoData.length)for (k = 0; k < e.length; k++)o = e[k], l = c[o], g(Db(a, o)).clone(!1).append(l.sContentPadding).appendTo(p);
+ i.appendTo(m);
+ f && h ? i.width(h) : f ? (i.css("width", "auto"), i.width() < m.offsetWidth && i.width(m.offsetWidth)) : d ? i.width(m.offsetWidth) : n && i.width(n);
+ Eb(a, i[0]);
+ if (f) {
+ for (k = h = 0; k < e.length; k++)l = c[e[k]], d = g(j[k]).outerWidth(), h += null === l.sWidthOrig ? d : parseInt(l.sWidth, 10) + d - g(j[k]).width();
+ i.width(s(h));
+ b.style.width = s(h)
+ }
+ for (k = 0; k < e.length; k++)if (l = c[e[k]], d = g(j[k]).width())l.sWidth = s(d);
+ b.style.width = s(i.css("width"));
+ i.remove()
+ }
+ n && (b.style.width = s(n));
+ if ((n || f) && !a._reszEvt)g(Da).bind("resize.DT-" + a.sInstance,
+ ta(function () {
+ X(a)
+ })), a._reszEvt = !0
+ }
+
+ function ta(a, b) {
+ var c = b !== l ? b : 200, e, d;
+ return function () {
+ var b = this, h = +new Date, g = arguments;
+ e && h < e + c ? (clearTimeout(d), d = setTimeout(function () {
+ e = l;
+ a.apply(b, g)
+ }, c)) : e ? (e = h, a.apply(b, g)) : e = h
+ }
+ }
+
+ function Cb(a, b) {
+ if (!a)return 0;
+ var c = g("
").css("width", s(a)).appendTo(b || P.body), e = c[0].offsetWidth;
+ c.remove();
+ return e
+ }
+
+ function Eb(a, b) {
+ var c = a.oScroll;
+ if (c.sX || c.sY)c = !c.sX ? c.iBarWidth : 0, b.style.width = s(g(b).outerWidth() - c)
+ }
+
+ function Db(a, b) {
+ var c = Fb(a, b);
+ if (0 > c)return null;
+ var e = a.aoData[c];
+ return!e.nTr ? g(" ").html(v(a, c, b, "display"))[0] : e.anCells[b]
+ }
+
+ function Fb(a, b) {
+ for (var c, e = -1, d = -1, f = 0, h = a.aoData.length; f < h; f++)c = v(a, f, b, "display") + "", c = c.replace(Zb, ""), c.length > e && (e = c.length, d = f);
+ return d
+ }
+
+ function s(a) {
+ return null === a ? "0px" : "number" == typeof a ? 0 > a ? "0px" : a + "px" : a.match(/\d$/) ? a + "px" : a
+ }
+
+ function Gb() {
+ if (!p.__scrollbarWidth) {
+ var a = g("
").css({width: "100%", height: 200, padding: 0})[0], b = g("
").css({position: "absolute", top: 0, left: 0, width: 200, height: 150, padding: 0,
+ overflow: "hidden", visibility: "hidden"}).append(a).appendTo("body"), c = a.offsetWidth;
+ b.css("overflow", "scroll");
+ a = a.offsetWidth;
+ c === a && (a = b[0].clientWidth);
+ b.remove();
+ p.__scrollbarWidth = c - a
+ }
+ return p.__scrollbarWidth
+ }
+
+ function T(a) {
+ var b, c, e = [], d = a.aoColumns, f, h, i, j;
+ b = a.aaSortingFixed;
+ c = g.isPlainObject(b);
+ var n = [];
+ f = function (a) {
+ a.length && !g.isArray(a[0]) ? n.push(a) : n.push.apply(n, a)
+ };
+ g.isArray(b) && f(b);
+ c && b.pre && f(b.pre);
+ f(a.aaSorting);
+ c && b.post && f(b.post);
+ for (a = 0; a < n.length; a++) {
+ j = n[a][0];
+ f = d[j].aDataSort;
+ b = 0;
+ for (c = f.length; b < c; b++)h = f[b], i = d[h].sType || "string", n[a]._idx === l && (n[a]._idx = g.inArray(n[a][1], d[h].asSorting)), e.push({src: j, col: h, dir: n[a][1], index: n[a]._idx, type: i, formatter: p.ext.type.order[i + "-pre"]})
+ }
+ return e
+ }
+
+ function kb(a) {
+ var b, c, e = [], d = p.ext.type.order, f = a.aoData, h = 0, g, j = a.aiDisplayMaster, n;
+ Ga(a);
+ n = T(a);
+ b = 0;
+ for (c = n.length; b < c; b++)g = n[b], g.formatter && h++, Hb(a, g.col);
+ if ("ssp" != A(a) && 0 !== n.length) {
+ b = 0;
+ for (c = j.length; b < c; b++)e[j[b]] = b;
+ h === n.length ? j.sort(function (a, b) {
+ var c, d, h, g, i = n.length,
+ j = f[a]._aSortData, l = f[b]._aSortData;
+ for (h = 0; h < i; h++)if (g = n[h], c = j[g.col], d = l[g.col], c = c < d ? -1 : c > d ? 1 : 0, 0 !== c)return"asc" === g.dir ? c : -c;
+ c = e[a];
+ d = e[b];
+ return c < d ? -1 : c > d ? 1 : 0
+ }) : j.sort(function (a, b) {
+ var c, h, g, i, j = n.length, l = f[a]._aSortData, p = f[b]._aSortData;
+ for (g = 0; g < j; g++)if (i = n[g], c = l[i.col], h = p[i.col], i = d[i.type + "-" + i.dir] || d["string-" + i.dir], c = i(c, h), 0 !== c)return c;
+ c = e[a];
+ h = e[b];
+ return c < h ? -1 : c > h ? 1 : 0
+ })
+ }
+ a.bSorted = !0
+ }
+
+ function Ib(a) {
+ for (var b, c, e = a.aoColumns, d = T(a), a = a.oLanguage.oAria, f = 0, h = e.length; f < h; f++) {
+ c =
+ e[f];
+ var g = c.asSorting;
+ b = c.sTitle.replace(/<.*?>/g, "");
+ var j = c.nTh;
+ j.removeAttribute("aria-sort");
+ c.bSortable && (0 < d.length && d[0].col == f ? (j.setAttribute("aria-sort", "asc" == d[0].dir ? "ascending" : "descending"), c = g[d[0].index + 1] || g[0]) : c = g[0], b += "asc" === c ? a.sSortAscending : a.sSortDescending);
+ j.setAttribute("aria-label", b)
+ }
+ }
+
+ function Ta(a, b, c, e) {
+ var d = a.aaSorting, f = a.aoColumns[b].asSorting, h = function (a, b) {
+ var c = a._idx;
+ c === l && (c = g.inArray(a[1], f));
+ return c + 1 < f.length ? c + 1 : b ? null : 0
+ };
+ "number" === typeof d[0] &&
+ (d = a.aaSorting = [d]);
+ c && a.oFeatures.bSortMulti ? (c = g.inArray(b, C(d, "0")), -1 !== c ? (b = h(d[c], !0), null === b ? d.splice(c, 1) : (d[c][1] = f[b], d[c]._idx = b)) : (d.push([b, f[0], 0]), d[d.length - 1]._idx = 0)) : d.length && d[0][0] == b ? (b = h(d[0]), d.length = 1, d[0][1] = f[b], d[0]._idx = b) : (d.length = 0, d.push([b, f[0]]), d[0]._idx = 0);
+ M(a);
+ "function" == typeof e && e(a)
+ }
+
+ function Na(a, b, c, e) {
+ var d = a.aoColumns[c];
+ Ua(b, {}, function (b) {
+ !1 !== d.bSortable && (a.oFeatures.bProcessing ? (B(a, !0), setTimeout(function () {
+ Ta(a, c, b.shiftKey, e);
+ "ssp" !== A(a) && B(a,
+ !1)
+ }, 0)) : Ta(a, c, b.shiftKey, e))
+ })
+ }
+
+ function wa(a) {
+ var b = a.aLastSort, c = a.oClasses.sSortColumn, e = T(a), d = a.oFeatures, f, h;
+ if (d.bSort && d.bSortClasses) {
+ d = 0;
+ for (f = b.length; d < f; d++)h = b[d].src, g(C(a.aoData, "anCells", h)).removeClass(c + (2 > d ? d + 1 : 3));
+ d = 0;
+ for (f = e.length; d < f; d++)h = e[d].src, g(C(a.aoData, "anCells", h)).addClass(c + (2 > d ? d + 1 : 3))
+ }
+ a.aLastSort = e
+ }
+
+ function Hb(a, b) {
+ var c = a.aoColumns[b], e = p.ext.order[c.sSortDataType], d;
+ e && (d = e.call(a.oInstance, a, b, $(a, b)));
+ for (var f, h = p.ext.type.order[c.sType + "-pre"], g = 0, j = a.aoData.length; g <
+ j; g++)if (c = a.aoData[g], c._aSortData || (c._aSortData = []), !c._aSortData[b] || e)f = e ? d[g] : v(a, g, b, "sort"), c._aSortData[b] = h ? h(f) : f
+ }
+
+ function xa(a) {
+ if (a.oFeatures.bStateSave && !a.bDestroying) {
+ var b = {time: +new Date, start: a._iDisplayStart, length: a._iDisplayLength, order: g.extend(!0, [], a.aaSorting), search: yb(a.oPreviousSearch), columns: g.map(a.aoColumns, function (b, e) {
+ return{visible: b.bVisible, search: yb(a.aoPreSearchCols[e])}
+ })};
+ u(a, "aoStateSaveParams", "stateSaveParams", [a, b]);
+ a.oSavedState = b;
+ a.fnStateSaveCallback.call(a.oInstance,
+ a, b)
+ }
+ }
+
+ function Jb(a) {
+ var b, c, e = a.aoColumns;
+ if (a.oFeatures.bStateSave) {
+ var d = a.fnStateLoadCallback.call(a.oInstance, a);
+ if (d && d.time && (b = u(a, "aoStateLoadParams", "stateLoadParams", [a, d]), -1 === g.inArray(!1, b) && (b = a.iStateDuration, !(0 < b && d.time < +new Date - 1E3 * b) && e.length === d.columns.length))) {
+ a.oLoadedState = g.extend(!0, {}, d);
+ a._iDisplayStart = d.start;
+ a.iInitDisplayStart = d.start;
+ a._iDisplayLength = d.length;
+ a.aaSorting = [];
+ g.each(d.order, function (b, c) {
+ a.aaSorting.push(c[0] >= e.length ? [0, c[1]] : c)
+ });
+ g.extend(a.oPreviousSearch,
+ zb(d.search));
+ b = 0;
+ for (c = d.columns.length; b < c; b++) {
+ var f = d.columns[b];
+ e[b].bVisible = f.visible;
+ g.extend(a.aoPreSearchCols[b], zb(f.search))
+ }
+ u(a, "aoStateLoaded", "stateLoaded", [a, d])
+ }
+ }
+ }
+
+ function ya(a) {
+ var b = p.settings, a = g.inArray(a, C(b, "nTable"));
+ return-1 !== a ? b[a] : null
+ }
+
+ function R(a, b, c, e) {
+ c = "DataTables warning: " + (null !== a ? "table id=" + a.sTableId + " - " : "") + c;
+ e && (c += ". For more information about this error, please see http://datatables.net/tn/" + e);
+ if (b)Da.console && console.log && console.log(c); else if (a = p.ext,
+ "alert" == (a.sErrMode || a.errMode))alert(c); else throw Error(c);
+ }
+
+ function D(a, b, c, e) {
+ g.isArray(c) ? g.each(c, function (c, f) {
+ g.isArray(f) ? D(a, b, f[0], f[1]) : D(a, b, f)
+ }) : (e === l && (e = c), b[c] !== l && (a[e] = b[c]))
+ }
+
+ function Kb(a, b, c) {
+ var e, d;
+ for (d in b)b.hasOwnProperty(d) && (e = b[d], g.isPlainObject(e) ? (g.isPlainObject(a[d]) || (a[d] = {}), g.extend(!0, a[d], e)) : a[d] = c && "data" !== d && "aaData" !== d && g.isArray(e) ? e.slice() : e);
+ return a
+ }
+
+ function Ua(a, b, c) {
+ g(a).bind("click.DT", b, function (b) {
+ a.blur();
+ c(b)
+ }).bind("keypress.DT", b, function (a) {
+ 13 ===
+ a.which && (a.preventDefault(), c(a))
+ }).bind("selectstart.DT", function () {
+ return!1
+ })
+ }
+
+ function x(a, b, c, e) {
+ c && a[b].push({fn: c, sName: e})
+ }
+
+ function u(a, b, c, e) {
+ var d = [];
+ b && (d = g.map(a[b].slice().reverse(), function (b) {
+ return b.fn.apply(a.oInstance, e)
+ }));
+ null !== c && g(a.nTable).trigger(c + ".dt", e);
+ return d
+ }
+
+ function Ra(a) {
+ var b = a._iDisplayStart, c = a.fnDisplayEnd(), e = a._iDisplayLength;
+ b >= c && (b = c - e);
+ b -= b % e;
+ if (-1 === e || 0 > b)b = 0;
+ a._iDisplayStart = b
+ }
+
+ function Oa(a, b) {
+ var c = a.renderer, e = p.ext.renderer[b];
+ return g.isPlainObject(c) &&
+ c[b] ? e[c[b]] || e._ : "string" === typeof c ? e[c] || e._ : e._
+ }
+
+ function A(a) {
+ return a.oFeatures.bServerSide ? "ssp" : a.ajax || a.sAjaxSource ? "ajax" : "dom"
+ }
+
+ function Va(a, b) {
+ var c = [], c = Lb.numbers_length, e = Math.floor(c / 2);
+ b <= c ? c = U(0, b) : a <= e ? (c = U(0, c - 2), c.push("ellipsis"), c.push(b - 1)) : (a >= b - 1 - e ? c = U(b - (c - 2), b) : (c = U(a - 1, a + 2), c.push("ellipsis"), c.push(b - 1)), c.splice(0, 0, "ellipsis"), c.splice(0, 0, 0));
+ c.DT_el = "span";
+ return c
+ }
+
+ function cb(a) {
+ g.each({num: function (b) {
+ return za(b, a)
+ }, "num-fmt": function (b) {
+ return za(b, a, Wa)
+ }, "html-num": function (b) {
+ return za(b,
+ a, Aa)
+ }, "html-num-fmt": function (b) {
+ return za(b, a, Aa, Wa)
+ }}, function (b, c) {
+ w.type.order[b + a + "-pre"] = c;
+ b.match(/^html\-/) && (w.type.search[b + a] = w.type.search.html)
+ })
+ }
+
+ function Mb(a) {
+ return function () {
+ var b = [ya(this[p.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));
+ return p.ext.internal[a].apply(this, b)
+ }
+ }
+
+ var p, w, q, r, t, Xa = {}, Nb = /[\r\n]/g, Aa = /<.*?>/g, $b = /^[\w\+\-]/, ac = /[\w\+\-]$/, Xb = RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)", "g"), Wa = /[',$\u00a3\u20ac\u00a5%\u2009\u202F]/g,
+ H = function (a) {
+ return!a || !0 === a || "-" === a ? !0 : !1
+ }, Ob = function (a) {
+ var b = parseInt(a, 10);
+ return!isNaN(b) && isFinite(a) ? b : null
+ }, Pb = function (a, b) {
+ Xa[b] || (Xa[b] = RegExp(ua(b), "g"));
+ return"string" === typeof a && "." !== b ? a.replace(/\./g, "").replace(Xa[b], ".") : a
+ }, Ya = function (a, b, c) {
+ var e = "string" === typeof a;
+ b && e && (a = Pb(a, b));
+ c && e && (a = a.replace(Wa, ""));
+ return H(a) || !isNaN(parseFloat(a)) && isFinite(a)
+ }, Qb = function (a, b, c) {
+ return H(a) ? !0 : !(H(a) || "string" === typeof a) ? null : Ya(a.replace(Aa, ""), b, c) ? !0 : null
+ }, C = function (a, b, c) {
+ var e = [], d = 0, f = a.length;
+ if (c !== l)for (; d < f; d++)a[d] && a[d][b] && e.push(a[d][b][c]); else for (; d < f; d++)a[d] && e.push(a[d][b]);
+ return e
+ }, ha = function (a, b, c, e) {
+ var d = [], f = 0, h = b.length;
+ if (e !== l)for (; f < h; f++)a[b[f]][c] && d.push(a[b[f]][c][e]); else for (; f < h; f++)d.push(a[b[f]][c]);
+ return d
+ }, U = function (a, b) {
+ var c = [], e;
+ b === l ? (b = 0, e = a) : (e = b, b = a);
+ for (var d = b; d < e; d++)c.push(d);
+ return c
+ }, Rb = function (a) {
+ for (var b = [], c = 0, e = a.length; c < e; c++)a[c] && b.push(a[c]);
+ return b
+ }, Ma = function (a) {
+ var b = [], c, e, d = a.length, f, h = 0;
+ e = 0;
+ a:for (; e < d; e++) {
+ c = a[e];
+ for (f = 0; f < h; f++)if (b[f] === c)continue a;
+ b.push(c);
+ h++
+ }
+ return b
+ }, z = function (a, b, c) {
+ a[b] !== l && (a[c] = a[b])
+ }, ba = /\[.*?\]$/, S = /\(\)$/, va = g("")[0], Yb = va.textContent !== l, Zb = /<.*?>/g;
+ p = function (a) {
+ this.$ = function (a, b) {
+ return this.api(!0).$(a, b)
+ };
+ this._ = function (a, b) {
+ return this.api(!0).rows(a, b).data()
+ };
+ this.api = function (a) {
+ return a ? new q(ya(this[w.iApiIndex])) : new q(this)
+ };
+ this.fnAddData = function (a, b) {
+ var c = this.api(!0), e = g.isArray(a) && (g.isArray(a[0]) || g.isPlainObject(a[0])) ?
+ c.rows.add(a) : c.row.add(a);
+ (b === l || b) && c.draw();
+ return e.flatten().toArray()
+ };
+ this.fnAdjustColumnSizing = function (a) {
+ var b = this.api(!0).columns.adjust(), c = b.settings()[0], e = c.oScroll;
+ a === l || a ? b.draw(!1) : ("" !== e.sX || "" !== e.sY) && Y(c)
+ };
+ this.fnClearTable = function (a) {
+ var b = this.api(!0).clear();
+ (a === l || a) && b.draw()
+ };
+ this.fnClose = function (a) {
+ this.api(!0).row(a).child.hide()
+ };
+ this.fnDeleteRow = function (a, b, c) {
+ var e = this.api(!0), a = e.rows(a), d = a.settings()[0], g = d.aoData[a[0][0]];
+ a.remove();
+ b && b.call(this, d, g);
+ (c === l || c) && e.draw();
+ return g
+ };
+ this.fnDestroy = function (a) {
+ this.api(!0).destroy(a)
+ };
+ this.fnDraw = function (a) {
+ this.api(!0).draw(!a)
+ };
+ this.fnFilter = function (a, b, c, e, d, g) {
+ d = this.api(!0);
+ null === b || b === l ? d.search(a, c, e, g) : d.column(b).search(a, c, e, g);
+ d.draw()
+ };
+ this.fnGetData = function (a, b) {
+ var c = this.api(!0);
+ if (a !== l) {
+ var e = a.nodeName ? a.nodeName.toLowerCase() : "";
+ return b !== l || "td" == e || "th" == e ? c.cell(a, b).data() : c.row(a).data() || null
+ }
+ return c.data().toArray()
+ };
+ this.fnGetNodes = function (a) {
+ var b = this.api(!0);
+ return a !== l ? b.row(a).node() : b.rows().nodes().flatten().toArray()
+ };
+ this.fnGetPosition = function (a) {
+ var b = this.api(!0), c = a.nodeName.toUpperCase();
+ return"TR" == c ? b.row(a).index() : "TD" == c || "TH" == c ? (a = b.cell(a).index(), [a.row, a.columnVisible, a.column]) : null
+ };
+ this.fnIsOpen = function (a) {
+ return this.api(!0).row(a).child.isShown()
+ };
+ this.fnOpen = function (a, b, c) {
+ return this.api(!0).row(a).child(b, c).show().child()[0]
+ };
+ this.fnPageChange = function (a, b) {
+ var c = this.api(!0).page(a);
+ (b === l || b) && c.draw(!1)
+ };
+ this.fnSetColumnVis =
+ function (a, b, c) {
+ a = this.api(!0).column(a).visible(b);
+ (c === l || c) && a.columns.adjust().draw()
+ };
+ this.fnSettings = function () {
+ return ya(this[w.iApiIndex])
+ };
+ this.fnSort = function (a) {
+ this.api(!0).order(a).draw()
+ };
+ this.fnSortListener = function (a, b, c) {
+ this.api(!0).order.listener(a, b, c)
+ };
+ this.fnUpdate = function (a, b, c, e, d) {
+ var g = this.api(!0);
+ c === l || null === c ? g.row(b).data(a) : g.cell(b, c).data(a);
+ (d === l || d) && g.columns.adjust();
+ (e === l || e) && g.draw();
+ return 0
+ };
+ this.fnVersionCheck = w.fnVersionCheck;
+ var b = this, c = a === l, e = this.length;
+ c && (a = {});
+ this.oApi = this.internal = w.internal;
+ for (var d in p.ext.internal)d && (this[d] = Mb(d));
+ this.each(function () {
+ var d = {}, d = 1 < e ? Kb(d, a, !0) : a, h = 0, i, j = this.getAttribute("id"), n = !1, m = p.defaults;
+ if ("table" != this.nodeName.toLowerCase())R(null, 0, "Non-table node initialisation (" + this.nodeName + ")", 2); else {
+ db(m);
+ eb(m.column);
+ G(m, m, !0);
+ G(m.column, m.column, !0);
+ G(m, d);
+ var o = p.settings, h = 0;
+ for (i = o.length; h < i; h++) {
+ if (o[h].nTable == this) {
+ i = d.bRetrieve !== l ? d.bRetrieve : m.bRetrieve;
+ if (c || i)return o[h].oInstance;
+ if (d.bDestroy !==
+ l ? d.bDestroy : m.bDestroy) {
+ o[h].oInstance.fnDestroy();
+ break
+ } else {
+ R(o[h], 0, "Cannot reinitialise DataTable", 3);
+ return
+ }
+ }
+ if (o[h].sTableId == this.id) {
+ o.splice(h, 1);
+ break
+ }
+ }
+ if (null === j || "" === j)this.id = j = "DataTables_Table_" + p.ext._unique++;
+ var k = g.extend(!0, {}, p.models.oSettings, {nTable: this, oApi: b.internal, oInit: d, sDestroyWidth: g(this)[0].style.width, sInstance: j, sTableId: j});
+ o.push(k);
+ k.oInstance = 1 === b.length ? b : g(this).dataTable();
+ db(d);
+ d.oLanguage && O(d.oLanguage);
+ d.aLengthMenu && !d.iDisplayLength && (d.iDisplayLength =
+ g.isArray(d.aLengthMenu[0]) ? d.aLengthMenu[0][0] : d.aLengthMenu[0]);
+ d = Kb(g.extend(!0, {}, m), d);
+ D(k.oFeatures, d, "bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));
+ D(k, d, ["asStripeClasses", "ajax", "fnServerData", "fnFormatNumber", "sServerMethod", "aaSorting", "aaSortingFixed", "aLengthMenu", "sPaginationType", "sAjaxSource", "sAjaxDataProp", "iStateDuration", "sDom", "bSortCellsTop", "iTabIndex", "fnStateLoadCallback", "fnStateSaveCallback",
+ "renderer", "searchDelay", ["iCookieDuration", "iStateDuration"], ["oSearch", "oPreviousSearch"], ["aoSearchCols", "aoPreSearchCols"], ["iDisplayLength", "_iDisplayLength"], ["bJQueryUI", "bJUI"]]);
+ D(k.oScroll, d, [
+ ["sScrollX", "sX"],
+ ["sScrollXInner", "sXInner"],
+ ["sScrollY", "sY"],
+ ["bScrollCollapse", "bCollapse"]
+ ]);
+ D(k.oLanguage, d, "fnInfoCallback");
+ x(k, "aoDrawCallback", d.fnDrawCallback, "user");
+ x(k, "aoServerParams", d.fnServerParams, "user");
+ x(k, "aoStateSaveParams", d.fnStateSaveParams, "user");
+ x(k, "aoStateLoadParams",
+ d.fnStateLoadParams, "user");
+ x(k, "aoStateLoaded", d.fnStateLoaded, "user");
+ x(k, "aoRowCallback", d.fnRowCallback, "user");
+ x(k, "aoRowCreatedCallback", d.fnCreatedRow, "user");
+ x(k, "aoHeaderCallback", d.fnHeaderCallback, "user");
+ x(k, "aoFooterCallback", d.fnFooterCallback, "user");
+ x(k, "aoInitComplete", d.fnInitComplete, "user");
+ x(k, "aoPreDrawCallback", d.fnPreDrawCallback, "user");
+ j = k.oClasses;
+ d.bJQueryUI ? (g.extend(j, p.ext.oJUIClasses, d.oClasses), d.sDom === m.sDom && "lfrtip" === m.sDom && (k.sDom = '<"H"lfr>t<"F"ip>'), k.renderer) ?
+ g.isPlainObject(k.renderer) && !k.renderer.header && (k.renderer.header = "jqueryui") : k.renderer = "jqueryui" : g.extend(j, p.ext.classes, d.oClasses);
+ g(this).addClass(j.sTable);
+ if ("" !== k.oScroll.sX || "" !== k.oScroll.sY)k.oScroll.iBarWidth = Gb();
+ !0 === k.oScroll.sX && (k.oScroll.sX = "100%");
+ k.iInitDisplayStart === l && (k.iInitDisplayStart = d.iDisplayStart, k._iDisplayStart = d.iDisplayStart);
+ null !== d.iDeferLoading && (k.bDeferLoading = !0, h = g.isArray(d.iDeferLoading), k._iRecordsDisplay = h ? d.iDeferLoading[0] : d.iDeferLoading, k._iRecordsTotal =
+ h ? d.iDeferLoading[1] : d.iDeferLoading);
+ var r = k.oLanguage;
+ g.extend(!0, r, d.oLanguage);
+ "" !== r.sUrl && (g.ajax({dataType: "json", url: r.sUrl, success: function (a) {
+ O(a);
+ G(m.oLanguage, a);
+ g.extend(true, r, a);
+ ga(k)
+ }, error: function () {
+ ga(k)
+ }}), n = !0);
+ null === d.asStripeClasses && (k.asStripeClasses = [j.sStripeOdd, j.sStripeEven]);
+ var h = k.asStripeClasses, q = g("tbody tr:eq(0)", this);
+ -1 !== g.inArray(!0, g.map(h, function (a) {
+ return q.hasClass(a)
+ })) && (g("tbody tr", this).removeClass(h.join(" ")), k.asDestroyStripes = h.slice());
+ var o =
+ [], s, h = this.getElementsByTagName("thead");
+ 0 !== h.length && (da(k.aoHeader, h[0]), o = pa(k));
+ if (null === d.aoColumns) {
+ s = [];
+ h = 0;
+ for (i = o.length; h < i; h++)s.push(null)
+ } else s = d.aoColumns;
+ h = 0;
+ for (i = s.length; h < i; h++)Ea(k, o ? o[h] : null);
+ hb(k, d.aoColumnDefs, s, function (a, b) {
+ ja(k, a, b)
+ });
+ if (q.length) {
+ var t = function (a, b) {
+ return a.getAttribute("data-" + b) ? b : null
+ };
+ g.each(ma(k, q[0]).cells, function (a, b) {
+ var c = k.aoColumns[a];
+ if (c.mData === a) {
+ var e = t(b, "sort") || t(b, "order"), d = t(b, "filter") || t(b, "search");
+ if (e !== null || d !== null) {
+ c.mData =
+ {_: a + ".display", sort: e !== null ? a + ".@data-" + e : l, type: e !== null ? a + ".@data-" + e : l, filter: d !== null ? a + ".@data-" + d : l};
+ ja(k, a)
+ }
+ }
+ })
+ }
+ var v = k.oFeatures;
+ d.bStateSave && (v.bStateSave = !0, Jb(k, d), x(k, "aoDrawCallback", xa, "state_save"));
+ if (d.aaSorting === l) {
+ o = k.aaSorting;
+ h = 0;
+ for (i = o.length; h < i; h++)o[h][1] = k.aoColumns[h].asSorting[0]
+ }
+ wa(k);
+ v.bSort && x(k, "aoDrawCallback", function () {
+ if (k.bSorted) {
+ var a = T(k), b = {};
+ g.each(a, function (a, c) {
+ b[c.src] = c.dir
+ });
+ u(k, null, "order", [k, a, b]);
+ Ib(k)
+ }
+ });
+ x(k, "aoDrawCallback", function () {
+ (k.bSorted ||
+ A(k) === "ssp" || v.bDeferRender) && wa(k)
+ }, "sc");
+ fb(k);
+ h = g(this).children("caption").each(function () {
+ this._captionSide = g(this).css("caption-side")
+ });
+ i = g(this).children("thead");
+ 0 === i.length && (i = g("
").appendTo(this));
+ k.nTHead = i[0];
+ i = g(this).children("tbody");
+ 0 === i.length && (i = g("
").appendTo(this));
+ k.nTBody = i[0];
+ i = g(this).children("tfoot");
+ if (0 === i.length && 0 < h.length && ("" !== k.oScroll.sX || "" !== k.oScroll.sY))i = g("
").appendTo(this);
+ 0 === i.length || 0 === i.children().length ? g(this).addClass(j.sNoFooter) :
+ 0 < i.length && (k.nTFoot = i[0], da(k.aoFooter, k.nTFoot));
+ if (d.aaData)for (h = 0; h < d.aaData.length; h++)I(k, d.aaData[h]); else(k.bDeferLoading || "dom" == A(k)) && la(k, g(k.nTBody).children("tr"));
+ k.aiDisplay = k.aiDisplayMaster.slice();
+ k.bInitialised = !0;
+ !1 === n && ga(k)
+ }
+ });
+ b = null;
+ return this
+ };
+ var Sb = [], y = Array.prototype, bc = function (a) {
+ var b, c, e = p.settings, d = g.map(e, function (a) {
+ return a.nTable
+ });
+ if (a) {
+ if (a.nTable && a.oApi)return[a];
+ if (a.nodeName && "table" === a.nodeName.toLowerCase())return b = g.inArray(a, d), -1 !== b ? [e[b]] :
+ null;
+ if (a && "function" === typeof a.settings)return a.settings().toArray();
+ "string" === typeof a ? c = g(a) : a instanceof g && (c = a)
+ } else return[];
+ if (c)return c.map(function () {
+ b = g.inArray(this, d);
+ return-1 !== b ? e[b] : null
+ }).toArray()
+ };
+ q = function (a, b) {
+ if (!this instanceof q)throw"DT API must be constructed as a new object";
+ var c = [], e = function (a) {
+ (a = bc(a)) && c.push.apply(c, a)
+ };
+ if (g.isArray(a))for (var d = 0, f = a.length; d < f; d++)e(a[d]); else e(a);
+ this.context = Ma(c);
+ b && this.push.apply(this, b.toArray ? b.toArray() : b);
+ this.selector =
+ {rows: null, cols: null, opts: null};
+ q.extend(this, this, Sb)
+ };
+ p.Api = q;
+ q.prototype = {concat: y.concat, context: [], each: function (a) {
+ for (var b = 0, c = this.length; b < c; b++)a.call(this, this[b], b, this);
+ return this
+ }, eq: function (a) {
+ var b = this.context;
+ return b.length > a ? new q(b[a], this[a]) : null
+ }, filter: function (a) {
+ var b = [];
+ if (y.filter)b = y.filter.call(this, a, this); else for (var c = 0, e = this.length; c < e; c++)a.call(this, this[c], c, this) && b.push(this[c]);
+ return new q(this.context, b)
+ }, flatten: function () {
+ var a = [];
+ return new q(this.context,
+ a.concat.apply(a, this.toArray()))
+ }, join: y.join, indexOf: y.indexOf || function (a, b) {
+ for (var c = b || 0, e = this.length; c < e; c++)if (this[c] === a)return c;
+ return-1
+ }, iterator: function (a, b, c, e) {
+ var d = [], f, h, g, j, n, m = this.context, o, k, p = this.selector;
+ "string" === typeof a && (e = c, c = b, b = a, a = !1);
+ h = 0;
+ for (g = m.length; h < g; h++) {
+ var r = new q(m[h]);
+ if ("table" === b)f = c.call(r, m[h], h), f !== l && d.push(f); else if ("columns" === b || "rows" === b)f = c.call(r, m[h], this[h], h), f !== l && d.push(f); else if ("column" === b || "column-rows" === b || "row" === b || "cell" ===
+ b) {
+ k = this[h];
+ "column-rows" === b && (o = Ba(m[h], p.opts));
+ j = 0;
+ for (n = k.length; j < n; j++)f = k[j], f = "cell" === b ? c.call(r, m[h], f.row, f.column, h, j) : c.call(r, m[h], f, h, j, o), f !== l && d.push(f)
+ }
+ }
+ return d.length || e ? (a = new q(m, a ? d.concat.apply([], d) : d), b = a.selector, b.rows = p.rows, b.cols = p.cols, b.opts = p.opts, a) : this
+ }, lastIndexOf: y.lastIndexOf || function (a, b) {
+ return this.indexOf.apply(this.toArray.reverse(), arguments)
+ }, length: 0, map: function (a) {
+ var b = [];
+ if (y.map)b = y.map.call(this, a, this); else for (var c = 0, e = this.length; c < e; c++)b.push(a.call(this,
+ this[c], c));
+ return new q(this.context, b)
+ }, pluck: function (a) {
+ return this.map(function (b) {
+ return b[a]
+ })
+ }, pop: y.pop, push: y.push, reduce: y.reduce || function (a, b) {
+ return gb(this, a, b, 0, this.length, 1)
+ }, reduceRight: y.reduceRight || function (a, b) {
+ return gb(this, a, b, this.length - 1, -1, -1)
+ }, reverse: y.reverse, selector: null, shift: y.shift, sort: y.sort, splice: y.splice, toArray: function () {
+ return y.slice.call(this)
+ }, to$: function () {
+ return g(this)
+ }, toJQuery: function () {
+ return g(this)
+ }, unique: function () {
+ return new q(this.context,
+ Ma(this))
+ }, unshift: y.unshift};
+ q.extend = function (a, b, c) {
+ if (b && (b instanceof q || b.__dt_wrapper)) {
+ var e, d, f, h = function (a, b, c) {
+ return function () {
+ var e = b.apply(a, arguments);
+ q.extend(e, e, c.methodExt);
+ return e
+ }
+ };
+ e = 0;
+ for (d = c.length; e < d; e++)f = c[e], b[f.name] = "function" === typeof f.val ? h(a, f.val, f) : g.isPlainObject(f.val) ? {} : f.val, b[f.name].__dt_wrapper = !0, q.extend(a, b[f.name], f.propExt)
+ }
+ };
+ q.register = r = function (a, b) {
+ if (g.isArray(a))for (var c = 0, e = a.length; c < e; c++)q.register(a[c], b); else for (var d = a.split("."),
+ f = Sb, h, i, c = 0, e = d.length; c < e; c++) {
+ h = (i = -1 !== d[c].indexOf("()")) ? d[c].replace("()", "") : d[c];
+ var j;
+ a:{
+ j = 0;
+ for (var n = f.length; j < n; j++)if (f[j].name === h) {
+ j = f[j];
+ break a
+ }
+ j = null
+ }
+ j || (j = {name: h, val: {}, methodExt: [], propExt: []}, f.push(j));
+ c === e - 1 ? j.val = b : f = i ? j.methodExt : j.propExt
+ }
+ };
+ q.registerPlural = t = function (a, b, c) {
+ q.register(a, c);
+ q.register(b, function () {
+ var a = c.apply(this, arguments);
+ return a === this ? this : a instanceof q ? a.length ? g.isArray(a[0]) ? new q(a.context, a[0]) : a[0] : l : a
+ })
+ };
+ r("tables()", function (a) {
+ var b;
+ if (a) {
+ b = q;
+ var c = this.context;
+ if ("number" === typeof a)a = [c[a]]; else var e = g.map(c, function (a) {
+ return a.nTable
+ }), a = g(e).filter(a).map(function () {
+ var a = g.inArray(this, e);
+ return c[a]
+ }).toArray();
+ b = new b(a)
+ } else b = this;
+ return b
+ });
+ r("table()", function (a) {
+ var a = this.tables(a), b = a.context;
+ return b.length ? new q(b[0]) : a
+ });
+ t("tables().nodes()", "table().node()", function () {
+ return this.iterator("table", function (a) {
+ return a.nTable
+ }, 1)
+ });
+ t("tables().body()", "table().body()", function () {
+ return this.iterator("table",
+ function (a) {
+ return a.nTBody
+ }, 1)
+ });
+ t("tables().header()", "table().header()", function () {
+ return this.iterator("table", function (a) {
+ return a.nTHead
+ }, 1)
+ });
+ t("tables().footer()", "table().footer()", function () {
+ return this.iterator("table", function (a) {
+ return a.nTFoot
+ }, 1)
+ });
+ t("tables().containers()", "table().container()", function () {
+ return this.iterator("table", function (a) {
+ return a.nTableWrapper
+ }, 1)
+ });
+ r("draw()", function (a) {
+ return this.iterator("table", function (b) {
+ M(b, !1 === a)
+ })
+ });
+ r("page()", function (a) {
+ return a ===
+ l ? this.page.info().page : this.iterator("table", function (b) {
+ Sa(b, a)
+ })
+ });
+ r("page.info()", function () {
+ if (0 === this.context.length)return l;
+ var a = this.context[0], b = a._iDisplayStart, c = a._iDisplayLength, e = a.fnRecordsDisplay(), d = -1 === c;
+ return{page: d ? 0 : Math.floor(b / c), pages: d ? 1 : Math.ceil(e / c), start: b, end: a.fnDisplayEnd(), length: c, recordsTotal: a.fnRecordsTotal(), recordsDisplay: e}
+ });
+ r("page.len()", function (a) {
+ return a === l ? 0 !== this.context.length ? this.context[0]._iDisplayLength : l : this.iterator("table", function (b) {
+ Qa(b,
+ a)
+ })
+ });
+ var Tb = function (a, b, c) {
+ "ssp" == A(a) ? M(a, b) : (B(a, !0), qa(a, [], function (c) {
+ na(a);
+ for (var c = ra(a, c), e = 0, h = c.length; e < h; e++)I(a, c[e]);
+ M(a, b);
+ B(a, !1)
+ }));
+ if (c) {
+ var e = new q(a);
+ e.one("draw", function () {
+ c(e.ajax.json())
+ })
+ }
+ };
+ r("ajax.json()", function () {
+ var a = this.context;
+ if (0 < a.length)return a[0].json
+ });
+ r("ajax.params()", function () {
+ var a = this.context;
+ if (0 < a.length)return a[0].oAjaxData
+ });
+ r("ajax.reload()", function (a, b) {
+ return this.iterator("table", function (c) {
+ Tb(c, !1 === b, a)
+ })
+ });
+ r("ajax.url()", function (a) {
+ var b =
+ this.context;
+ if (a === l) {
+ if (0 === b.length)return l;
+ b = b[0];
+ return b.ajax ? g.isPlainObject(b.ajax) ? b.ajax.url : b.ajax : b.sAjaxSource
+ }
+ return this.iterator("table", function (b) {
+ g.isPlainObject(b.ajax) ? b.ajax.url = a : b.ajax = a
+ })
+ });
+ r("ajax.url().load()", function (a, b) {
+ return this.iterator("table", function (c) {
+ Tb(c, !1 === b, a)
+ })
+ });
+ var Za = function (a, b) {
+ var c = [], e, d, f, h, i, j;
+ e = typeof a;
+ if (!a || "string" === e || "function" === e || a.length === l)a = [a];
+ f = 0;
+ for (h = a.length; f < h; f++) {
+ d = a[f] && a[f].split ? a[f].split(",") : [a[f]];
+ i = 0;
+ for (j =
+ d.length; i < j; i++)(e = b("string" === typeof d[i] ? g.trim(d[i]) : d[i])) && e.length && c.push.apply(c, e)
+ }
+ return c
+ }, $a = function (a) {
+ a || (a = {});
+ a.filter && !a.search && (a.search = a.filter);
+ return{search: a.search || "none", order: a.order || "current", page: a.page || "all"}
+ }, ab = function (a) {
+ for (var b = 0, c = a.length; b < c; b++)if (0 < a[b].length)return a[0] = a[b], a.length = 1, a.context = [a.context[b]], a;
+ a.length = 0;
+ return a
+ }, Ba = function (a, b) {
+ var c, e, d, f = [], h = a.aiDisplay;
+ c = a.aiDisplayMaster;
+ var i = b.search;
+ e = b.order;
+ d = b.page;
+ if ("ssp" == A(a))return"removed" ===
+ i ? [] : U(0, c.length);
+ if ("current" == d) {
+ c = a._iDisplayStart;
+ for (e = a.fnDisplayEnd(); c < e; c++)f.push(h[c])
+ } else if ("current" == e || "applied" == e)f = "none" == i ? c.slice() : "applied" == i ? h.slice() : g.map(c, function (a) {
+ return-1 === g.inArray(a, h) ? a : null
+ }); else if ("index" == e || "original" == e) {
+ c = 0;
+ for (e = a.aoData.length; c < e; c++)"none" == i ? f.push(c) : (d = g.inArray(c, h), (-1 === d && "removed" == i || 0 <= d && "applied" == i) && f.push(c))
+ }
+ return f
+ };
+ r("rows()", function (a, b) {
+ a === l ? a = "" : g.isPlainObject(a) && (b = a, a = "");
+ var b = $a(b), c = this.iterator("table",
+ function (c) {
+ var d = b;
+ return Za(a, function (a) {
+ var b = Ob(a);
+ if (b !== null && !d)return[b];
+ var i = Ba(c, d);
+ if (b !== null && g.inArray(b, i) !== -1)return[b];
+ if (!a)return i;
+ if (typeof a === "function")return g.map(i, function (b) {
+ var d = c.aoData[b];
+ return a(b, d._aData, d.nTr) ? b : null
+ });
+ b = Rb(ha(c.aoData, i, "nTr"));
+ return a.nodeName && g.inArray(a, b) !== -1 ? [a._DT_RowIndex] : g(b).filter(a).map(function () {
+ return this._DT_RowIndex
+ }).toArray()
+ })
+ }, 1);
+ c.selector.rows = a;
+ c.selector.opts = b;
+ return c
+ });
+ r("rows().nodes()", function () {
+ return this.iterator("row",
+ function (a, b) {
+ return a.aoData[b].nTr || l
+ }, 1)
+ });
+ r("rows().data()", function () {
+ return this.iterator(!0, "rows", function (a, b) {
+ return ha(a.aoData, b, "_aData")
+ }, 1)
+ });
+ t("rows().cache()", "row().cache()", function (a) {
+ return this.iterator("row", function (b, c) {
+ var e = b.aoData[c];
+ return"search" === a ? e._aFilterData : e._aSortData
+ }, 1)
+ });
+ t("rows().invalidate()", "row().invalidate()", function (a) {
+ return this.iterator("row", function (b, c) {
+ ca(b, c, a)
+ })
+ });
+ t("rows().indexes()", "row().index()", function () {
+ return this.iterator("row",
+ function (a, b) {
+ return b
+ }, 1)
+ });
+ t("rows().remove()", "row().remove()", function () {
+ var a = this;
+ return this.iterator("row", function (b, c, e) {
+ var d = b.aoData;
+ d.splice(c, 1);
+ for (var f = 0, h = d.length; f < h; f++)null !== d[f].nTr && (d[f].nTr._DT_RowIndex = f);
+ g.inArray(c, b.aiDisplay);
+ oa(b.aiDisplayMaster, c);
+ oa(b.aiDisplay, c);
+ oa(a[e], c, !1);
+ Ra(b)
+ })
+ });
+ r("rows.add()", function (a) {
+ var b = this.iterator("table", function (b) {
+ var c, f, h, g = [];
+ f = 0;
+ for (h = a.length; f < h; f++)c = a[f], c.nodeName && "TR" === c.nodeName.toUpperCase() ? g.push(la(b, c)[0]) :
+ g.push(I(b, c));
+ return g
+ }, 1), c = this.rows(-1);
+ c.pop();
+ c.push.apply(c, b.toArray());
+ return c
+ });
+ r("row()", function (a, b) {
+ return ab(this.rows(a, b))
+ });
+ r("row().data()", function (a) {
+ var b = this.context;
+ if (a === l)return b.length && this.length ? b[0].aoData[this[0]]._aData : l;
+ b[0].aoData[this[0]]._aData = a;
+ ca(b[0], this[0], "data");
+ return this
+ });
+ r("row().node()", function () {
+ var a = this.context;
+ return a.length && this.length ? a[0].aoData[this[0]].nTr || null : null
+ });
+ r("row.add()", function (a) {
+ a instanceof g && a.length && (a = a[0]);
+ var b = this.iterator("table", function (b) {
+ return a.nodeName && "TR" === a.nodeName.toUpperCase() ? la(b, a)[0] : I(b, a)
+ });
+ return this.row(b[0])
+ });
+ var bb = function (a, b) {
+ var c = a.context;
+ c.length && (c = c[0].aoData[b !== l ? b : a[0]], c._details && (c._details.remove(), c._detailsShow = l, c._details = l))
+ }, Ub = function (a, b) {
+ var c = a.context;
+ if (c.length && a.length) {
+ var e = c[0].aoData[a[0]];
+ if (e._details) {
+ (e._detailsShow = b) ? e._details.insertAfter(e.nTr) : e._details.detach();
+ var d = c[0], f = new q(d), h = d.aoData;
+ f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");
+ 0 < C(h, "_details").length && (f.on("draw.dt.DT_details", function (a, b) {
+ d === b && f.rows({page: "current"}).eq(0).each(function (a) {
+ a = h[a];
+ a._detailsShow && a._details.insertAfter(a.nTr)
+ })
+ }), f.on("column-visibility.dt.DT_details", function (a, b) {
+ if (d === b)for (var c, e = aa(b), f = 0, g = h.length; f < g; f++)c = h[f], c._details && c._details.children("td[colspan]").attr("colspan", e)
+ }), f.on("destroy.dt.DT_details", function (a, b) {
+ if (d === b)for (var c = 0, e = h.length; c < e; c++)h[c]._details && bb(f, c)
+ }))
+ }
+ }
+ };
+ r("row().child()", function (a, b) {
+ var c =
+ this.context;
+ if (a === l)return c.length && this.length ? c[0].aoData[this[0]]._details : l;
+ if (!0 === a)this.child.show(); else if (!1 === a)bb(this); else if (c.length && this.length) {
+ var e = c[0], c = c[0].aoData[this[0]], d = [], f = function (a, b) {
+ if (a.nodeName && "tr" === a.nodeName.toLowerCase())d.push(a); else {
+ var c = g("
").addClass(b);
+ g("td", c).addClass(b).html(a)[0].colSpan = aa(e);
+ d.push(c[0])
+ }
+ };
+ if (g.isArray(a) || a instanceof g)for (var h = 0, i = a.length; h < i; h++)f(a[h], b); else f(a, b);
+ c._details && c._details.remove();
+ c._details =
+ g(d);
+ c._detailsShow && c._details.insertAfter(c.nTr)
+ }
+ return this
+ });
+ r(["row().child.show()", "row().child().show()"], function () {
+ Ub(this, !0);
+ return this
+ });
+ r(["row().child.hide()", "row().child().hide()"], function () {
+ Ub(this, !1);
+ return this
+ });
+ r(["row().child.remove()", "row().child().remove()"], function () {
+ bb(this);
+ return this
+ });
+ r("row().child.isShown()", function () {
+ var a = this.context;
+ return a.length && this.length ? a[0].aoData[this[0]]._detailsShow || !1 : !1
+ });
+ var cc = /^(.+):(name|visIdx|visible)$/, Vb = function (a, b, c, e, d) {
+ for (var c = [], e = 0, f = d.length; e < f; e++)c.push(v(a, d[e], b));
+ return c
+ };
+ r("columns()", function (a, b) {
+ a === l ? a = "" : g.isPlainObject(a) && (b = a, a = "");
+ var b = $a(b), c = this.iterator("table", function (c) {
+ var d = a, f = b, h = c.aoColumns, i = C(h, "sName"), j = C(h, "nTh");
+ return Za(d, function (a) {
+ var b = Ob(a);
+ if (a === "")return U(h.length);
+ if (b !== null)return[b >= 0 ? b : h.length + b];
+ if (typeof a === "function") {
+ var d = Ba(c, f);
+ return g.map(h, function (b, f) {
+ return a(f, Vb(c, f, 0, 0, d), j[f]) ? f : null
+ })
+ }
+ var k = typeof a === "string" ? a.match(cc) : "";
+ if (k)switch (k[2]) {
+ case "visIdx":
+ case "visible":
+ b =
+ parseInt(k[1], 10);
+ if (b < 0) {
+ var l = g.map(h, function (a, b) {
+ return a.bVisible ? b : null
+ });
+ return[l[l.length + b]]
+ }
+ return[ka(c, b)];
+ case "name":
+ return g.map(i, function (a, b) {
+ return a === k[1] ? b : null
+ })
+ } else return g(j).filter(a).map(function () {
+ return g.inArray(this, j)
+ }).toArray()
+ })
+ }, 1);
+ c.selector.cols = a;
+ c.selector.opts = b;
+ return c
+ });
+ t("columns().header()", "column().header()", function () {
+ return this.iterator("column", function (a, b) {
+ return a.aoColumns[b].nTh
+ }, 1)
+ });
+ t("columns().footer()", "column().footer()", function () {
+ return this.iterator("column",
+ function (a, b) {
+ return a.aoColumns[b].nTf
+ }, 1)
+ });
+ t("columns().data()", "column().data()", function () {
+ return this.iterator("column-rows", Vb, 1)
+ });
+ t("columns().dataSrc()", "column().dataSrc()", function () {
+ return this.iterator("column", function (a, b) {
+ return a.aoColumns[b].mData
+ }, 1)
+ });
+ t("columns().cache()", "column().cache()", function (a) {
+ return this.iterator("column-rows", function (b, c, e, d, f) {
+ return ha(b.aoData, f, "search" === a ? "_aFilterData" : "_aSortData", c)
+ }, 1)
+ });
+ t("columns().nodes()", "column().nodes()", function () {
+ return this.iterator("column-rows",
+ function (a, b, c, e, d) {
+ return ha(a.aoData, d, "anCells", b)
+ }, 1)
+ });
+ t("columns().visible()", "column().visible()", function (a, b) {
+ return this.iterator("column", function (c, e) {
+ if (a === l)return c.aoColumns[e].bVisible;
+ var d = c.aoColumns, f = d[e], h = c.aoData, i, j, n;
+ if (a !== l && f.bVisible !== a) {
+ if (a) {
+ var m = g.inArray(!0, C(d, "bVisible"), e + 1);
+ i = 0;
+ for (j = h.length; i < j; i++)n = h[i].nTr, d = h[i].anCells, n && n.insertBefore(d[e], d[m] || null)
+ } else g(C(c.aoData, "anCells", e)).detach();
+ f.bVisible = a;
+ ea(c, c.aoHeader);
+ ea(c, c.aoFooter);
+ if (b === l ||
+ b)X(c), (c.oScroll.sX || c.oScroll.sY) && Y(c);
+ u(c, null, "column-visibility", [c, e, a]);
+ xa(c)
+ }
+ })
+ });
+ t("columns().indexes()", "column().index()", function (a) {
+ return this.iterator("column", function (b, c) {
+ return"visible" === a ? $(b, c) : c
+ }, 1)
+ });
+ r("columns.adjust()", function () {
+ return this.iterator("table", function (a) {
+ X(a)
+ }, 1)
+ });
+ r("column.index()", function (a, b) {
+ if (0 !== this.context.length) {
+ var c = this.context[0];
+ if ("fromVisible" === a || "toData" === a)return ka(c, b);
+ if ("fromData" === a || "toVisible" === a)return $(c, b)
+ }
+ });
+ r("column()",
+ function (a, b) {
+ return ab(this.columns(a, b))
+ });
+ r("cells()", function (a, b, c) {
+ g.isPlainObject(a) && (typeof a.row !== l ? (c = b, b = null) : (c = a, a = null));
+ g.isPlainObject(b) && (c = b, b = null);
+ if (null === b || b === l)return this.iterator("table", function (b) {
+ var e = a, d = $a(c), f = b.aoData, h = Ba(b, d), d = Rb(ha(f, h, "anCells")), i = g([].concat.apply([], d)), j, m = b.aoColumns.length, n, p, r, q, s, t;
+ return Za(e, function (a) {
+ var c = typeof a === "function";
+ if (a === null || a === l || c) {
+ n = [];
+ p = 0;
+ for (r = h.length; p < r; p++) {
+ j = h[p];
+ for (q = 0; q < m; q++) {
+ s = {row: j, column: q};
+ if (c) {
+ t = b.aoData[j];
+ a(s, v(b, j, q), t.anCells[q]) && n.push(s)
+ } else n.push(s)
+ }
+ }
+ return n
+ }
+ return g.isPlainObject(a) ? [a] : i.filter(a).map(function (a, b) {
+ j = b.parentNode._DT_RowIndex;
+ return{row: j, column: g.inArray(b, f[j].anCells)}
+ }).toArray()
+ })
+ });
+ var e = this.columns(b, c), d = this.rows(a, c), f, h, i, j, n, m = this.iterator("table", function (a, b) {
+ f = [];
+ h = 0;
+ for (i = d[b].length; h < i; h++) {
+ j = 0;
+ for (n = e[b].length; j < n; j++)f.push({row: d[b][h], column: e[b][j]})
+ }
+ return f
+ }, 1);
+ g.extend(m.selector, {cols: b, rows: a, opts: c});
+ return m
+ });
+ t("cells().nodes()",
+ "cell().node()", function () {
+ return this.iterator("cell", function (a, b, c) {
+ return(a = a.aoData[b].anCells) ? a[c] : l
+ }, 1)
+ });
+ r("cells().data()", function () {
+ return this.iterator("cell", function (a, b, c) {
+ return v(a, b, c)
+ }, 1)
+ });
+ t("cells().cache()", "cell().cache()", function (a) {
+ a = "search" === a ? "_aFilterData" : "_aSortData";
+ return this.iterator("cell", function (b, c, e) {
+ return b.aoData[c][a][e]
+ }, 1)
+ });
+ t("cells().render()", "cell().render()", function (a) {
+ return this.iterator("cell", function (b, c, e) {
+ return v(b, c, e, a)
+ }, 1)
+ });
+ t("cells().indexes()",
+ "cell().index()", function () {
+ return this.iterator("cell", function (a, b, c) {
+ return{row: b, column: c, columnVisible: $(a, c)}
+ }, 1)
+ });
+ t("cells().invalidate()", "cell().invalidate()", function (a) {
+ return this.iterator("cell", function (b, c, e) {
+ ca(b, c, a, e)
+ })
+ });
+ r("cell()", function (a, b, c) {
+ return ab(this.cells(a, b, c))
+ });
+ r("cell().data()", function (a) {
+ var b = this.context, c = this[0];
+ if (a === l)return b.length && c.length ? v(b[0], c[0].row, c[0].column) : l;
+ Ha(b[0], c[0].row, c[0].column, a);
+ ca(b[0], c[0].row, "data", c[0].column);
+ return this
+ });
+ r("order()", function (a, b) {
+ var c = this.context;
+ if (a === l)return 0 !== c.length ? c[0].aaSorting : l;
+ "number" === typeof a ? a = [
+ [a, b]
+ ] : g.isArray(a[0]) || (a = Array.prototype.slice.call(arguments));
+ return this.iterator("table", function (b) {
+ b.aaSorting = a.slice()
+ })
+ });
+ r("order.listener()", function (a, b, c) {
+ return this.iterator("table", function (e) {
+ Na(e, a, b, c)
+ })
+ });
+ r(["columns().order()", "column().order()"], function (a) {
+ var b = this;
+ return this.iterator("table", function (c, e) {
+ var d = [];
+ g.each(b[e], function (b, c) {
+ d.push([c, a])
+ });
+ c.aaSorting = d
+ })
+ });
+ r("search()", function (a, b, c, e) {
+ var d = this.context;
+ return a === l ? 0 !== d.length ? d[0].oPreviousSearch.sSearch : l : this.iterator("table", function (d) {
+ d.oFeatures.bFilter && fa(d, g.extend({}, d.oPreviousSearch, {sSearch: a + "", bRegex: null === b ? !1 : b, bSmart: null === c ? !0 : c, bCaseInsensitive: null === e ? !0 : e}), 1)
+ })
+ });
+ t("columns().search()", "column().search()", function (a, b, c, e) {
+ return this.iterator("column", function (d, f) {
+ var h = d.aoPreSearchCols;
+ if (a === l)return h[f].sSearch;
+ d.oFeatures.bFilter && (g.extend(h[f],
+ {sSearch: a + "", bRegex: null === b ? !1 : b, bSmart: null === c ? !0 : c, bCaseInsensitive: null === e ? !0 : e}), fa(d, d.oPreviousSearch, 1))
+ })
+ });
+ r("state()", function () {
+ return this.context.length ? this.context[0].oSavedState : null
+ });
+ r("state.clear()", function () {
+ return this.iterator("table", function (a) {
+ a.fnStateSaveCallback.call(a.oInstance, a, {})
+ })
+ });
+ r("state.loaded()", function () {
+ return this.context.length ? this.context[0].oLoadedState : null
+ });
+ r("state.save()", function () {
+ return this.iterator("table", function (a) {
+ xa(a)
+ })
+ });
+ p.versionCheck =
+ p.fnVersionCheck = function (a) {
+ for (var b = p.version.split("."), a = a.split("."), c, e, d = 0, f = a.length; d < f; d++)if (c = parseInt(b[d], 10) || 0, e = parseInt(a[d], 10) || 0, c !== e)return c > e;
+ return!0
+ };
+ p.isDataTable = p.fnIsDataTable = function (a) {
+ var b = g(a).get(0), c = !1;
+ g.each(p.settings, function (a, d) {
+ if (d.nTable === b || d.nScrollHead === b || d.nScrollFoot === b)c = !0
+ });
+ return c
+ };
+ p.tables = p.fnTables = function (a) {
+ return g.map(p.settings, function (b) {
+ if (!a || a && g(b.nTable).is(":visible"))return b.nTable
+ })
+ };
+ p.util = {throttle: ta, escapeRegex: ua};
+ p.camelToHungarian = G;
+ r("$()", function (a, b) {
+ var c = this.rows(b).nodes(), c = g(c);
+ return g([].concat(c.filter(a).toArray(), c.find(a).toArray()))
+ });
+ g.each(["on", "one", "off"], function (a, b) {
+ r(b + "()", function () {
+ var a = Array.prototype.slice.call(arguments);
+ a[0].match(/\.dt\b/) || (a[0] += ".dt");
+ var e = g(this.tables().nodes());
+ e[b].apply(e, a);
+ return this
+ })
+ });
+ r("clear()", function () {
+ return this.iterator("table", function (a) {
+ na(a)
+ })
+ });
+ r("settings()", function () {
+ return new q(this.context, this.context)
+ });
+ r("data()", function () {
+ return this.iterator("table",
+ function (a) {
+ return C(a.aoData, "_aData")
+ }).flatten()
+ });
+ r("destroy()", function (a) {
+ a = a || !1;
+ return this.iterator("table", function (b) {
+ var c = b.nTableWrapper.parentNode, e = b.oClasses, d = b.nTable, f = b.nTBody, h = b.nTHead, i = b.nTFoot, j = g(d), f = g(f), l = g(b.nTableWrapper), m = g.map(b.aoData, function (a) {
+ return a.nTr
+ }), o;
+ b.bDestroying = !0;
+ u(b, "aoDestroyCallback", "destroy", [b]);
+ a || (new q(b)).columns().visible(!0);
+ l.unbind(".DT").find(":not(tbody *)").unbind(".DT");
+ g(Da).unbind(".DT-" + b.sInstance);
+ d != h.parentNode && (j.children("thead").detach(),
+ j.append(h));
+ i && d != i.parentNode && (j.children("tfoot").detach(), j.append(i));
+ j.detach();
+ l.detach();
+ b.aaSorting = [];
+ b.aaSortingFixed = [];
+ wa(b);
+ g(m).removeClass(b.asStripeClasses.join(" "));
+ g("th, td", h).removeClass(e.sSortable + " " + e.sSortableAsc + " " + e.sSortableDesc + " " + e.sSortableNone);
+ b.bJUI && (g("th span." + e.sSortIcon + ", td span." + e.sSortIcon, h).detach(), g("th, td", h).each(function () {
+ var a = g("div." + e.sSortJUIWrapper, this);
+ g(this).append(a.contents());
+ a.detach()
+ }));
+ !a && c && c.insertBefore(d, b.nTableReinsertBefore);
+ f.children().detach();
+ f.append(m);
+ j.css("width", b.sDestroyWidth).removeClass(e.sTable);
+ (o = b.asDestroyStripes.length) && f.children().each(function (a) {
+ g(this).addClass(b.asDestroyStripes[a % o])
+ });
+ c = g.inArray(b, p.settings);
+ -1 !== c && p.settings.splice(c, 1)
+ })
+ });
+ p.version = "1.10.4";
+ p.settings = [];
+ p.models = {};
+ p.models.oSearch = {bCaseInsensitive: !0, sSearch: "", bRegex: !1, bSmart: !0};
+ p.models.oRow = {nTr: null, anCells: null, _aData: [], _aSortData: null, _aFilterData: null, _sFilterRow: null, _sRowStripe: "", src: null};
+ p.models.oColumn =
+ {idx: null, aDataSort: null, asSorting: null, bSearchable: null, bSortable: null, bVisible: null, _sManualType: null, _bAttrSrc: !1, fnCreatedCell: null, fnGetData: null, fnSetData: null, mData: null, mRender: null, nTh: null, nTf: null, sClass: null, sContentPadding: null, sDefaultContent: null, sName: null, sSortDataType: "std", sSortingClass: null, sSortingClassJUI: null, sTitle: null, sType: null, sWidth: null, sWidthOrig: null};
+ p.defaults = {aaData: null, aaSorting: [
+ [0, "asc"]
+ ], aaSortingFixed: [], ajax: null, aLengthMenu: [10, 25, 50, 100], aoColumns: null,
+ aoColumnDefs: null, aoSearchCols: [], asStripeClasses: null, bAutoWidth: !0, bDeferRender: !1, bDestroy: !1, bFilter: !0, bInfo: !0, bJQueryUI: !1, bLengthChange: !0, bPaginate: !0, bProcessing: !1, bRetrieve: !1, bScrollCollapse: !1, bServerSide: !1, bSort: !0, bSortMulti: !0, bSortCellsTop: !1, bSortClasses: !0, bStateSave: !1, fnCreatedRow: null, fnDrawCallback: null, fnFooterCallback: null, fnFormatNumber: function (a) {
+ return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g, this.oLanguage.sThousands)
+ }, fnHeaderCallback: null, fnInfoCallback: null,
+ fnInitComplete: null, fnPreDrawCallback: null, fnRowCallback: null, fnServerData: null, fnServerParams: null, fnStateLoadCallback: function (a) {
+ try {
+ return JSON.parse((-1 === a.iStateDuration ? sessionStorage : localStorage).getItem("DataTables_" + a.sInstance + "_" + location.pathname))
+ } catch (b) {
+ }
+ }, fnStateLoadParams: null, fnStateLoaded: null, fnStateSaveCallback: function (a, b) {
+ try {
+ (-1 === a.iStateDuration ? sessionStorage : localStorage).setItem("DataTables_" + a.sInstance + "_" + location.pathname, JSON.stringify(b))
+ } catch (c) {
+ }
+ }, fnStateSaveParams: null,
+ iStateDuration: 7200, iDeferLoading: null, iDisplayLength: 10, iDisplayStart: 0, iTabIndex: 0, oClasses: {}, oLanguage: {oAria: {sSortAscending: ": activate to sort column ascending", sSortDescending: ": activate to sort column descending"}, oPaginate: {sFirst: "First", sLast: "Last", sNext: "Next", sPrevious: "Previous"}, sEmptyTable: "No data available in table", sInfo: "Showing _START_ to _END_ of _TOTAL_ entries", sInfoEmpty: "Showing 0 to 0 of 0 entries", sInfoFiltered: "(filtered from _MAX_ total entries)", sInfoPostFix: "", sDecimal: "",
+ sThousands: ",", sLengthMenu: "Show _MENU_ entries", sLoadingRecords: "Loading...", sProcessing: "Processing...", sSearch: "Search:", sSearchPlaceholder: "", sUrl: "", sZeroRecords: "No matching records found"}, oSearch: g.extend({}, p.models.oSearch), sAjaxDataProp: "data", sAjaxSource: null, sDom: "lfrtip", searchDelay: null, sPaginationType: "simple_numbers", sScrollX: "", sScrollXInner: "", sScrollY: "", sServerMethod: "GET", renderer: null};
+ V(p.defaults);
+ p.defaults.column = {aDataSort: null, iDataSort: -1, asSorting: ["asc", "desc"], bSearchable: !0,
+ bSortable: !0, bVisible: !0, fnCreatedCell: null, mData: null, mRender: null, sCellType: "td", sClass: "", sContentPadding: "", sDefaultContent: null, sName: "", sSortDataType: "std", sTitle: null, sType: null, sWidth: null};
+ V(p.defaults.column);
+ p.models.oSettings = {oFeatures: {bAutoWidth: null, bDeferRender: null, bFilter: null, bInfo: null, bLengthChange: null, bPaginate: null, bProcessing: null, bServerSide: null, bSort: null, bSortMulti: null, bSortClasses: null, bStateSave: null}, oScroll: {bCollapse: null, iBarWidth: 0, sX: null, sXInner: null, sY: null},
+ oLanguage: {fnInfoCallback: null}, oBrowser: {bScrollOversize: !1, bScrollbarLeft: !1}, ajax: null, aanFeatures: [], aoData: [], aiDisplay: [], aiDisplayMaster: [], aoColumns: [], aoHeader: [], aoFooter: [], oPreviousSearch: {}, aoPreSearchCols: [], aaSorting: null, aaSortingFixed: [], asStripeClasses: null, asDestroyStripes: [], sDestroyWidth: 0, aoRowCallback: [], aoHeaderCallback: [], aoFooterCallback: [], aoDrawCallback: [], aoRowCreatedCallback: [], aoPreDrawCallback: [], aoInitComplete: [], aoStateSaveParams: [], aoStateLoadParams: [], aoStateLoaded: [],
+ sTableId: "", nTable: null, nTHead: null, nTFoot: null, nTBody: null, nTableWrapper: null, bDeferLoading: !1, bInitialised: !1, aoOpenRows: [], sDom: null, searchDelay: null, sPaginationType: "two_button", iStateDuration: 0, aoStateSave: [], aoStateLoad: [], oSavedState: null, oLoadedState: null, sAjaxSource: null, sAjaxDataProp: null, bAjaxDataGet: !0, jqXHR: null, json: l, oAjaxData: l, fnServerData: null, aoServerParams: [], sServerMethod: null, fnFormatNumber: null, aLengthMenu: null, iDraw: 0, bDrawing: !1, iDrawError: -1, _iDisplayLength: 10, _iDisplayStart: 0,
+ _iRecordsTotal: 0, _iRecordsDisplay: 0, bJUI: null, oClasses: {}, bFiltered: !1, bSorted: !1, bSortCellsTop: null, oInit: null, aoDestroyCallback: [], fnRecordsTotal: function () {
+ return"ssp" == A(this) ? 1 * this._iRecordsTotal : this.aiDisplayMaster.length
+ }, fnRecordsDisplay: function () {
+ return"ssp" == A(this) ? 1 * this._iRecordsDisplay : this.aiDisplay.length
+ }, fnDisplayEnd: function () {
+ var a = this._iDisplayLength, b = this._iDisplayStart, c = b + a, e = this.aiDisplay.length, d = this.oFeatures, f = d.bPaginate;
+ return d.bServerSide ? !1 === f || -1 === a ? b + e :
+ Math.min(b + a, this._iRecordsDisplay) : !f || c > e || -1 === a ? e : c
+ }, oInstance: null, sInstance: null, iTabIndex: 0, nScrollHead: null, nScrollFoot: null, aLastSort: [], oPlugins: {}};
+ p.ext = w = {classes: {}, errMode: "alert", feature: [], search: [], internal: {}, legacy: {ajax: null}, pager: {}, renderer: {pageButton: {}, header: {}}, order: {}, type: {detect: [], search: {}, order: {}}, _unique: 0, fnVersionCheck: p.fnVersionCheck, iApiIndex: 0, oJUIClasses: {}, sVersion: p.version};
+ g.extend(w, {afnFiltering: w.search, aTypes: w.type.detect, ofnSearch: w.type.search,
+ oSort: w.type.order, afnSortData: w.order, aoFeatures: w.feature, oApi: w.internal, oStdClasses: w.classes, oPagination: w.pager});
+ g.extend(p.ext.classes, {sTable: "dataTable", sNoFooter: "no-footer", sPageButton: "paginate_button", sPageButtonActive: "current", sPageButtonDisabled: "disabled", sStripeOdd: "odd", sStripeEven: "even", sRowEmpty: "dataTables_empty", sWrapper: "dataTables_wrapper", sFilter: "dataTables_filter", sInfo: "dataTables_info", sPaging: "dataTables_paginate paging_", sLength: "dataTables_length", sProcessing: "dataTables_processing",
+ sSortAsc: "sorting_asc", sSortDesc: "sorting_desc", sSortable: "sorting", sSortableAsc: "sorting_asc_disabled", sSortableDesc: "sorting_desc_disabled", sSortableNone: "sorting_disabled", sSortColumn: "sorting_", sFilterInput: "", sLengthSelect: "", sScrollWrapper: "dataTables_scroll", sScrollHead: "dataTables_scrollHead", sScrollHeadInner: "dataTables_scrollHeadInner", sScrollBody: "dataTables_scrollBody", sScrollFoot: "dataTables_scrollFoot", sScrollFootInner: "dataTables_scrollFootInner", sHeaderTH: "", sFooterTH: "", sSortJUIAsc: "",
+ sSortJUIDesc: "", sSortJUI: "", sSortJUIAscAllowed: "", sSortJUIDescAllowed: "", sSortJUIWrapper: "", sSortIcon: "", sJUIHeader: "", sJUIFooter: ""});
+ var Ca = "", Ca = "", E = Ca + "ui-state-default", ia = Ca + "css_right ui-icon ui-icon-", Wb = Ca + "fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";
+ g.extend(p.ext.oJUIClasses, p.ext.classes, {sPageButton: "fg-button ui-button " + E, sPageButtonActive: "ui-state-disabled", sPageButtonDisabled: "ui-state-disabled", sPaging: "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",
+ sSortAsc: E + " sorting_asc", sSortDesc: E + " sorting_desc", sSortable: E + " sorting", sSortableAsc: E + " sorting_asc_disabled", sSortableDesc: E + " sorting_desc_disabled", sSortableNone: E + " sorting_disabled", sSortJUIAsc: ia + "triangle-1-n", sSortJUIDesc: ia + "triangle-1-s", sSortJUI: ia + "carat-2-n-s", sSortJUIAscAllowed: ia + "carat-1-n", sSortJUIDescAllowed: ia + "carat-1-s", sSortJUIWrapper: "DataTables_sort_wrapper", sSortIcon: "DataTables_sort_icon", sScrollHead: "dataTables_scrollHead " + E, sScrollFoot: "dataTables_scrollFoot " + E,
+ sHeaderTH: E, sFooterTH: E, sJUIHeader: Wb + " ui-corner-tl ui-corner-tr", sJUIFooter: Wb + " ui-corner-bl ui-corner-br"});
+ var Lb = p.ext.pager;
+ g.extend(Lb, {simple: function () {
+ return["previous", "next"]
+ }, full: function () {
+ return["first", "previous", "next", "last"]
+ }, simple_numbers: function (a, b) {
+ return["previous", Va(a, b), "next"]
+ }, full_numbers: function (a, b) {
+ return["first", "previous", Va(a, b), "next", "last"]
+ }, _numbers: Va, numbers_length: 7});
+ g.extend(!0, p.ext.renderer, {pageButton: {_: function (a, b, c, e, d, f) {
+ var h = a.oClasses, i =
+ a.oLanguage.oPaginate, j, l, m = 0, o = function (b, e) {
+ var k, p, r, q, s = function (b) {
+ Sa(a, b.data.action, true)
+ };
+ k = 0;
+ for (p = e.length; k < p; k++) {
+ q = e[k];
+ if (g.isArray(q)) {
+ r = g("<" + (q.DT_el || "div") + "/>").appendTo(b);
+ o(r, q)
+ } else {
+ l = j = "";
+ switch (q) {
+ case "ellipsis":
+ b.append("
… ");
+ break;
+ case "first":
+ j = i.sFirst;
+ l = q + (d > 0 ? "" : " " + h.sPageButtonDisabled);
+ break;
+ case "previous":
+ j = i.sPrevious;
+ l = q + (d > 0 ? "" : " " + h.sPageButtonDisabled);
+ break;
+ case "next":
+ j = i.sNext;
+ l = q + (d < f - 1 ? "" : " " + h.sPageButtonDisabled);
+ break;
+ case "last":
+ j =
+ i.sLast;
+ l = q + (d < f - 1 ? "" : " " + h.sPageButtonDisabled);
+ break;
+ default:
+ j = q + 1;
+ l = d === q ? h.sPageButtonActive : ""
+ }
+ if (j) {
+ r = g("
", {"class": h.sPageButton + " " + l, "aria-controls": a.sTableId, "data-dt-idx": m, tabindex: a.iTabIndex, id: c === 0 && typeof q === "string" ? a.sTableId + "_" + q : null}).html(j).appendTo(b);
+ Ua(r, {action: q}, s);
+ m++
+ }
+ }
+ }
+ };
+ try {
+ var k = g(P.activeElement).data("dt-idx");
+ o(g(b).empty(), e);
+ k !== null && g(b).find("[data-dt-idx=" + k + "]").focus()
+ } catch (p) {
+ }
+ }}});
+ g.extend(p.ext.type.detect, [function (a, b) {
+ var c = b.oLanguage.sDecimal;
+ return Ya(a, c) ? "num" + c : null
+ }, function (a) {
+ if (a && !(a instanceof Date) && (!$b.test(a) || !ac.test(a)))return null;
+ var b = Date.parse(a);
+ return null !== b && !isNaN(b) || H(a) ? "date" : null
+ }, function (a, b) {
+ var c = b.oLanguage.sDecimal;
+ return Ya(a, c, !0) ? "num-fmt" + c : null
+ }, function (a, b) {
+ var c = b.oLanguage.sDecimal;
+ return Qb(a, c) ? "html-num" + c : null
+ }, function (a, b) {
+ var c = b.oLanguage.sDecimal;
+ return Qb(a, c, !0) ? "html-num-fmt" + c : null
+ }, function (a) {
+ return H(a) || "string" === typeof a && -1 !== a.indexOf("<") ? "html" : null
+ }]);
+ g.extend(p.ext.type.search,
+ {html: function (a) {
+ return H(a) ? a : "string" === typeof a ? a.replace(Nb, " ").replace(Aa, "") : ""
+ }, string: function (a) {
+ return H(a) ? a : "string" === typeof a ? a.replace(Nb, " ") : a
+ }});
+ var za = function (a, b, c, e) {
+ if (0 !== a && (!a || "-" === a))return-Infinity;
+ b && (a = Pb(a, b));
+ a.replace && (c && (a = a.replace(c, "")), e && (a = a.replace(e, "")));
+ return 1 * a
+ };
+ g.extend(w.type.order, {"date-pre": function (a) {
+ return Date.parse(a) || 0
+ }, "html-pre": function (a) {
+ return H(a) ? "" : a.replace ? a.replace(/<.*?>/g, "").toLowerCase() : a + ""
+ }, "string-pre": function (a) {
+ return H(a) ?
+ "" : "string" === typeof a ? a.toLowerCase() : !a.toString ? "" : a.toString()
+ }, "string-asc": function (a, b) {
+ return a < b ? -1 : a > b ? 1 : 0
+ }, "string-desc": function (a, b) {
+ return a < b ? 1 : a > b ? -1 : 0
+ }});
+ cb("");
+ g.extend(!0, p.ext.renderer, {header: {_: function (a, b, c, e) {
+ g(a.nTable).on("order.dt.DT", function (d, f, h, g) {
+ if (a === f) {
+ d = c.idx;
+ b.removeClass(c.sSortingClass + " " + e.sSortAsc + " " + e.sSortDesc).addClass(g[d] == "asc" ? e.sSortAsc : g[d] == "desc" ? e.sSortDesc : c.sSortingClass)
+ }
+ })
+ }, jqueryui: function (a, b, c, e) {
+ g("
").addClass(e.sSortJUIWrapper).append(b.contents()).append(g(" ").addClass(e.sSortIcon +
+ " " + c.sSortingClassJUI)).appendTo(b);
+ g(a.nTable).on("order.dt.DT", function (d, f, g, i) {
+ if (a === f) {
+ d = c.idx;
+ b.removeClass(e.sSortAsc + " " + e.sSortDesc).addClass(i[d] == "asc" ? e.sSortAsc : i[d] == "desc" ? e.sSortDesc : c.sSortingClass);
+ b.find("span." + e.sSortIcon).removeClass(e.sSortJUIAsc + " " + e.sSortJUIDesc + " " + e.sSortJUI + " " + e.sSortJUIAscAllowed + " " + e.sSortJUIDescAllowed).addClass(i[d] == "asc" ? e.sSortJUIAsc : i[d] == "desc" ? e.sSortJUIDesc : c.sSortingClassJUI)
+ }
+ })
+ }}});
+ p.render = {number: function (a, b, c, e) {
+ return{display: function (d) {
+ var f =
+ 0 > d ? "-" : "", d = Math.abs(parseFloat(d)), g = parseInt(d, 10), d = c ? b + (d - g).toFixed(c).substring(2) : "";
+ return f + (e || "") + g.toString().replace(/\B(?=(\d{3})+(?!\d))/g, a) + d
+ }}
+ }};
+ g.extend(p.ext.internal, {_fnExternApiFunc: Mb, _fnBuildAjax: qa, _fnAjaxUpdate: jb, _fnAjaxParameters: sb, _fnAjaxUpdateDraw: tb, _fnAjaxDataSrc: ra, _fnAddColumn: Ea, _fnColumnOptions: ja, _fnAdjustColumnSizing: X, _fnVisibleToColumnIndex: ka, _fnColumnIndexToVisible: $, _fnVisbleColumns: aa, _fnGetColumns: Z, _fnColumnTypes: Ga, _fnApplyColumnDefs: hb, _fnHungarianMap: V,
+ _fnCamelToHungarian: G, _fnLanguageCompat: O, _fnBrowserDetect: fb, _fnAddData: I, _fnAddTr: la, _fnNodeToDataIndex: function (a, b) {
+ return b._DT_RowIndex !== l ? b._DT_RowIndex : null
+ }, _fnNodeToColumnIndex: function (a, b, c) {
+ return g.inArray(c, a.aoData[b].anCells)
+ }, _fnGetCellData: v, _fnSetCellData: Ha, _fnSplitObjNotation: Ja, _fnGetObjectDataFn: W, _fnSetObjectDataFn: Q, _fnGetDataMaster: Ka, _fnClearTable: na, _fnDeleteIndex: oa, _fnInvalidate: ca, _fnGetRowElements: ma, _fnCreateTr: Ia, _fnBuildHead: ib, _fnDrawHead: ea, _fnDraw: L, _fnReDraw: M,
+ _fnAddOptionsHtml: lb, _fnDetectHeader: da, _fnGetUniqueThs: pa, _fnFeatureHtmlFilter: nb, _fnFilterComplete: fa, _fnFilterCustom: wb, _fnFilterColumn: vb, _fnFilter: ub, _fnFilterCreateSearch: Pa, _fnEscapeRegex: ua, _fnFilterData: xb, _fnFeatureHtmlInfo: qb, _fnUpdateInfo: Ab, _fnInfoMacros: Bb, _fnInitialise: ga, _fnInitComplete: sa, _fnLengthChange: Qa, _fnFeatureHtmlLength: mb, _fnFeatureHtmlPaginate: rb, _fnPageChange: Sa, _fnFeatureHtmlProcessing: ob, _fnProcessingDisplay: B, _fnFeatureHtmlTable: pb, _fnScrollDraw: Y, _fnApplyToChildren: F,
+ _fnCalculateColumnWidths: Fa, _fnThrottle: ta, _fnConvertToWidth: Cb, _fnScrollingWidthAdjust: Eb, _fnGetWidestNode: Db, _fnGetMaxLenString: Fb, _fnStringToCss: s, _fnScrollBarWidth: Gb, _fnSortFlatten: T, _fnSort: kb, _fnSortAria: Ib, _fnSortListener: Ta, _fnSortAttachListener: Na, _fnSortingClasses: wa, _fnSortData: Hb, _fnSaveState: xa, _fnLoadState: Jb, _fnSettingsFromNode: ya, _fnLog: R, _fnMap: D, _fnBindAction: Ua, _fnCallbackReg: x, _fnCallbackFire: u, _fnLengthOverflow: Ra, _fnRenderer: Oa, _fnDataSource: A, _fnRowAttributes: La, _fnCalculateEnd: function () {
+ }});
+ g.fn.dataTable = p;
+ g.fn.dataTableSettings = p.settings;
+ g.fn.dataTableExt = p.ext;
+ g.fn.DataTable = function (a) {
+ return g(this).dataTable(a).api()
+ };
+ g.each(p, function (a, b) {
+ g.fn.DataTable[a] = b
+ });
+ return g.fn.dataTable
+ };
+ "function" === typeof define && define.amd ? define("datatables", ["jquery"], O) : "object" === typeof exports ? O(require("jquery")) : jQuery && !jQuery.fn.dataTable && O(jQuery)
+})(window, document);
diff --git a/src/main/resources/webapp/js/jquery.flot.js b/src/main/resources/webapp/js/jquery.flot.js
new file mode 100755
index 0000000..4704e92
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.flot.js
@@ -0,0 +1,3273 @@
+/* Javascript plotting library for jQuery, version 0.8.3.
+
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
+ Licensed under the MIT license.
+
+ */
+
+// first an inline dependency, jquery.colorhelpers.js, we inline it here
+// for convenience
+
+/* Plugin for jQuery for working with colors.
+ *
+ * Version 1.1.
+ *
+ * Inspiration from jQuery color animation plugin by John Resig.
+ *
+ * Released under the MIT license by Ole Laursen, October 2009.
+ *
+ * Examples:
+ *
+ * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
+ * var c = $.color.extract($("#mydiv"), 'background-color');
+ * console.log(c.r, c.g, c.b, c.a);
+ * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
+ *
+ * Note that .scale() and .add() return the same modified object
+ * instead of making a new one.
+ *
+ * V. 1.1: Fix error handling so e.g. parsing an empty string does
+ * produce a color rather than just crashing.
+ */
+(function ($) {
+ $.color = {};
+ $.color.make = function (r, g, b, a) {
+ var o = {};
+ o.r = r || 0;
+ o.g = g || 0;
+ o.b = b || 0;
+ o.a = a != null ? a : 1;
+ o.add = function (c, d) {
+ for (var i = 0; i < c.length; ++i)o[c.charAt(i)] += d;
+ return o.normalize()
+ };
+ o.scale = function (c, f) {
+ for (var i = 0; i < c.length; ++i)o[c.charAt(i)] *= f;
+ return o.normalize()
+ };
+ o.toString = function () {
+ if (o.a >= 1) {
+ return"rgb(" + [o.r, o.g, o.b].join(",") + ")"
+ } else {
+ return"rgba(" + [o.r, o.g, o.b, o.a].join(",") + ")"
+ }
+ };
+ o.normalize = function () {
+ function clamp(min, value, max) {
+ return value < min ? min : value > max ? max : value
+ }
+
+ o.r = clamp(0, parseInt(o.r), 255);
+ o.g = clamp(0, parseInt(o.g), 255);
+ o.b = clamp(0, parseInt(o.b), 255);
+ o.a = clamp(0, o.a, 1);
+ return o
+ };
+ o.clone = function () {
+ return $.color.make(o.r, o.b, o.g, o.a)
+ };
+ return o.normalize()
+ };
+ $.color.extract = function (elem, css) {
+ var c;
+ do {
+ c = elem.css(css).toLowerCase();
+ if (c != "" && c != "transparent")break;
+ elem = elem.parent()
+ } while (elem.length && !$.nodeName(elem.get(0), "body"));
+ if (c == "rgba(0, 0, 0, 0)")c = "transparent";
+ return $.color.parse(c)
+ };
+ $.color.parse = function (str) {
+ var res, m = $.color.make;
+ if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
+ if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
+ if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55);
+ if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55, parseFloat(res[4]));
+ if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
+ if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1] + res[1], 16), parseInt(res[2] + res[2], 16), parseInt(res[3] + res[3], 16));
+ var name = $.trim(str).toLowerCase();
+ if (name == "transparent")return m(255, 255, 255, 0); else {
+ res = lookupColors[name] || [0, 0, 0];
+ return m(res[0], res[1], res[2])
+ }
+ };
+ var lookupColors = {aqua: [0, 255, 255], azure: [240, 255, 255], beige: [245, 245, 220], black: [0, 0, 0], blue: [0, 0, 255], brown: [165, 42, 42], cyan: [0, 255, 255], darkblue: [0, 0, 139], darkcyan: [0, 139, 139], darkgrey: [169, 169, 169], darkgreen: [0, 100, 0], darkkhaki: [189, 183, 107], darkmagenta: [139, 0, 139], darkolivegreen: [85, 107, 47], darkorange: [255, 140, 0], darkorchid: [153, 50, 204], darkred: [139, 0, 0], darksalmon: [233, 150, 122], darkviolet: [148, 0, 211], fuchsia: [255, 0, 255], gold: [255, 215, 0], green: [0, 128, 0], indigo: [75, 0, 130], khaki: [240, 230, 140], lightblue: [173, 216, 230], lightcyan: [224, 255, 255], lightgreen: [144, 238, 144], lightgrey: [211, 211, 211], lightpink: [255, 182, 193], lightyellow: [255, 255, 224], lime: [0, 255, 0], magenta: [255, 0, 255], maroon: [128, 0, 0], navy: [0, 0, 128], olive: [128, 128, 0], orange: [255, 165, 0], pink: [255, 192, 203], purple: [128, 0, 128], violet: [128, 0, 128], red: [255, 0, 0], silver: [192, 192, 192], white: [255, 255, 255], yellow: [255, 255, 0]}
+})(jQuery);
+
+// the actual Flot code
+(function ($) {
+
+ // Cache the prototype hasOwnProperty for faster access
+
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+ // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM
+ // operation produces the same effect as detach, i.e. removing the element
+ // without touching its jQuery data.
+
+ // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
+
+ if (!$.fn.detach) {
+ $.fn.detach = function () {
+ return this.each(function () {
+ if (this.parentNode) {
+ this.parentNode.removeChild(this);
+ }
+ });
+ };
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The Canvas object is a wrapper around an HTML5 tag.
+ //
+ // @constructor
+ // @param {string} cls List of classes to apply to the canvas.
+ // @param {element} container Element onto which to append the canvas.
+ //
+ // Requiring a container is a little iffy, but unfortunately canvas
+ // operations don't work unless the canvas is attached to the DOM.
+
+ function Canvas(cls, container) {
+
+ var element = container.children("." + cls)[0];
+
+ if (element == null) {
+
+ element = document.createElement("canvas");
+ element.className = cls;
+
+ $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
+ .appendTo(container);
+
+ // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
+
+ if (!element.getContext) {
+ if (window.G_vmlCanvasManager) {
+ element = window.G_vmlCanvasManager.initElement(element);
+ } else {
+ throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
+ }
+ }
+ }
+
+ this.element = element;
+
+ var context = this.context = element.getContext("2d");
+
+ // Determine the screen's ratio of physical to device-independent
+ // pixels. This is the ratio between the canvas width that the browser
+ // advertises and the number of pixels actually present in that space.
+
+ // The iPhone 4, for example, has a device-independent width of 320px,
+ // but its screen is actually 640px wide. It therefore has a pixel
+ // ratio of 2, while most normal devices have a ratio of 1.
+
+ var devicePixelRatio = window.devicePixelRatio || 1,
+ backingStoreRatio =
+ context.webkitBackingStorePixelRatio ||
+ context.mozBackingStorePixelRatio ||
+ context.msBackingStorePixelRatio ||
+ context.oBackingStorePixelRatio ||
+ context.backingStorePixelRatio || 1;
+
+ this.pixelRatio = devicePixelRatio / backingStoreRatio;
+
+ // Size the canvas to match the internal dimensions of its container
+
+ this.resize(container.width(), container.height());
+
+ // Collection of HTML div layers for text overlaid onto the canvas
+
+ this.textContainer = null;
+ this.text = {};
+
+ // Cache of text fragments and metrics, so we can avoid expensively
+ // re-calculating them when the plot is re-rendered in a loop.
+
+ this._textCache = {};
+ }
+
+ // Resizes the canvas to the given dimensions.
+ //
+ // @param {number} width New width of the canvas, in pixels.
+ // @param {number} width New height of the canvas, in pixels.
+
+ Canvas.prototype.resize = function (width, height) {
+
+ if (width <= 0 || height <= 0) {
+ throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
+ }
+
+ var element = this.element,
+ context = this.context,
+ pixelRatio = this.pixelRatio;
+
+ // Resize the canvas, increasing its density based on the display's
+ // pixel ratio; basically giving it more pixels without increasing the
+ // size of its element, to take advantage of the fact that retina
+ // displays have that many more pixels in the same advertised space.
+
+ // Resizing should reset the state (excanvas seems to be buggy though)
+
+ if (this.width != width) {
+ element.width = width * pixelRatio;
+ element.style.width = width + "px";
+ this.width = width;
+ }
+
+ if (this.height != height) {
+ element.height = height * pixelRatio;
+ element.style.height = height + "px";
+ this.height = height;
+ }
+
+ // Save the context, so we can reset in case we get replotted. The
+ // restore ensure that we're really back at the initial state, and
+ // should be safe even if we haven't saved the initial state yet.
+
+ context.restore();
+ context.save();
+
+ // Scale the coordinate space to match the display density; so even though we
+ // may have twice as many pixels, we still want lines and other drawing to
+ // appear at the same size; the extra pixels will just make them crisper.
+
+ context.scale(pixelRatio, pixelRatio);
+ };
+
+ // Clears the entire canvas area, not including any overlaid HTML text
+
+ Canvas.prototype.clear = function () {
+ this.context.clearRect(0, 0, this.width, this.height);
+ };
+
+ // Finishes rendering the canvas, including managing the text overlay.
+
+ Canvas.prototype.render = function () {
+
+ var cache = this._textCache;
+
+ // For each text layer, add elements marked as active that haven't
+ // already been rendered, and remove those that are no longer active.
+
+ for (var layerKey in cache) {
+ if (hasOwnProperty.call(cache, layerKey)) {
+
+ var layer = this.getTextLayer(layerKey),
+ layerCache = cache[layerKey];
+
+ layer.hide();
+
+ for (var styleKey in layerCache) {
+ if (hasOwnProperty.call(layerCache, styleKey)) {
+ var styleCache = layerCache[styleKey];
+ for (var key in styleCache) {
+ if (hasOwnProperty.call(styleCache, key)) {
+
+ var positions = styleCache[key].positions;
+
+ for (var i = 0, position; position = positions[i]; i++) {
+ if (position.active) {
+ if (!position.rendered) {
+ layer.append(position.element);
+ position.rendered = true;
+ }
+ } else {
+ positions.splice(i--, 1);
+ if (position.rendered) {
+ position.element.detach();
+ }
+ }
+ }
+
+ if (positions.length == 0) {
+ delete styleCache[key];
+ }
+ }
+ }
+ }
+ }
+
+ layer.show();
+ }
+ }
+ };
+
+ // Creates (if necessary) and returns the text overlay container.
+ //
+ // @param {string} classes String of space-separated CSS classes used to
+ // uniquely identify the text layer.
+ // @return {object} The jQuery-wrapped text-layer div.
+
+ Canvas.prototype.getTextLayer = function (classes) {
+
+ var layer = this.text[classes];
+
+ // Create the text layer if it doesn't exist
+
+ if (layer == null) {
+
+ // Create the text layer container, if it doesn't exist
+
+ if (this.textContainer == null) {
+ this.textContainer = $("
")
+ .css({
+ position: "absolute",
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ 'font-size': "smaller",
+ color: "#545454"
+ })
+ .insertAfter(this.element);
+ }
+
+ layer = this.text[classes] = $("
")
+ .addClass(classes)
+ .css({
+ position: "absolute",
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0
+ })
+ .appendTo(this.textContainer);
+ }
+
+ return layer;
+ };
+
+ // Creates (if necessary) and returns a text info object.
+ //
+ // The object looks like this:
+ //
+ // {
+ // width: Width of the text's wrapper div.
+ // height: Height of the text's wrapper div.
+ // element: The jQuery-wrapped HTML div containing the text.
+ // positions: Array of positions at which this text is drawn.
+ // }
+ //
+ // The positions array contains objects that look like this:
+ //
+ // {
+ // active: Flag indicating whether the text should be visible.
+ // rendered: Flag indicating whether the text is currently visible.
+ // element: The jQuery-wrapped HTML div containing the text.
+ // x: X coordinate at which to draw the text.
+ // y: Y coordinate at which to draw the text.
+ // }
+ //
+ // Each position after the first receives a clone of the original element.
+ //
+ // The idea is that that the width, height, and general 'identity' of the
+ // text is constant no matter where it is placed; the placements are a
+ // secondary property.
+ //
+ // Canvas maintains a cache of recently-used text info objects; getTextInfo
+ // either returns the cached element or creates a new entry.
+ //
+ // @param {string} layer A string of space-separated CSS classes uniquely
+ // identifying the layer containing this text.
+ // @param {string} text Text string to retrieve info for.
+ // @param {(string|object)=} font Either a string of space-separated CSS
+ // classes or a font-spec object, defining the text's font and style.
+ // @param {number=} angle Angle at which to rotate the text, in degrees.
+ // Angle is currently unused, it will be implemented in the future.
+ // @param {number=} width Maximum width of the text before it wraps.
+ // @return {object} a text info object.
+
+ Canvas.prototype.getTextInfo = function (layer, text, font, angle, width) {
+
+ var textStyle, layerCache, styleCache, info;
+
+ // Cast the value to a string, in case we were given a number or such
+
+ text = "" + text;
+
+ // If the font is a font-spec object, generate a CSS font definition
+
+ if (typeof font === "object") {
+ textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
+ } else {
+ textStyle = font;
+ }
+
+ // Retrieve (or create) the cache for the text's layer and styles
+
+ layerCache = this._textCache[layer];
+
+ if (layerCache == null) {
+ layerCache = this._textCache[layer] = {};
+ }
+
+ styleCache = layerCache[textStyle];
+
+ if (styleCache == null) {
+ styleCache = layerCache[textStyle] = {};
+ }
+
+ info = styleCache[text];
+
+ // If we can't find a matching element in our cache, create a new one
+
+ if (info == null) {
+
+ var element = $("
").html(text)
+ .css({
+ position: "absolute",
+ 'max-width': width,
+ top: -9999
+ })
+ .appendTo(this.getTextLayer(layer));
+
+ if (typeof font === "object") {
+ element.css({
+ font: textStyle,
+ color: font.color
+ });
+ } else if (typeof font === "string") {
+ element.addClass(font);
+ }
+
+ info = styleCache[text] = {
+ width: element.outerWidth(true),
+ height: element.outerHeight(true),
+ element: element,
+ positions: []
+ };
+
+ element.detach();
+ }
+
+ return info;
+ };
+
+ // Adds a text string to the canvas text overlay.
+ //
+ // The text isn't drawn immediately; it is marked as rendering, which will
+ // result in its addition to the canvas on the next render pass.
+ //
+ // @param {string} layer A string of space-separated CSS classes uniquely
+ // identifying the layer containing this text.
+ // @param {number} x X coordinate at which to draw the text.
+ // @param {number} y Y coordinate at which to draw the text.
+ // @param {string} text Text string to draw.
+ // @param {(string|object)=} font Either a string of space-separated CSS
+ // classes or a font-spec object, defining the text's font and style.
+ // @param {number=} angle Angle at which to rotate the text, in degrees.
+ // Angle is currently unused, it will be implemented in the future.
+ // @param {number=} width Maximum width of the text before it wraps.
+ // @param {string=} halign Horizontal alignment of the text; either "left",
+ // "center" or "right".
+ // @param {string=} valign Vertical alignment of the text; either "top",
+ // "middle" or "bottom".
+
+ Canvas.prototype.addText = function (layer, x, y, text, font, angle, width, halign, valign) {
+
+ var info = this.getTextInfo(layer, text, font, angle, width),
+ positions = info.positions;
+
+ // Tweak the div's position to match the text's alignment
+
+ if (halign == "center") {
+ x -= info.width / 2;
+ } else if (halign == "right") {
+ x -= info.width;
+ }
+
+ if (valign == "middle") {
+ y -= info.height / 2;
+ } else if (valign == "bottom") {
+ y -= info.height;
+ }
+
+ // Determine whether this text already exists at this position.
+ // If so, mark it for inclusion in the next render pass.
+
+ for (var i = 0, position; position = positions[i]; i++) {
+ if (position.x == x && position.y == y) {
+ position.active = true;
+ return;
+ }
+ }
+
+ // If the text doesn't exist at this position, create a new entry
+
+ // For the very first position we'll re-use the original element,
+ // while for subsequent ones we'll clone it.
+
+ position = {
+ active: true,
+ rendered: false,
+ element: positions.length ? info.element.clone() : info.element,
+ x: x,
+ y: y
+ };
+
+ positions.push(position);
+
+ // Move the element to its final position within the container
+
+ position.element.css({
+ top: Math.round(y),
+ left: Math.round(x),
+ 'text-align': halign // In case the text wraps
+ });
+ };
+
+ // Removes one or more text strings from the canvas text overlay.
+ //
+ // If no parameters are given, all text within the layer is removed.
+ //
+ // Note that the text is not immediately removed; it is simply marked as
+ // inactive, which will result in its removal on the next render pass.
+ // This avoids the performance penalty for 'clear and redraw' behavior,
+ // where we potentially get rid of all text on a layer, but will likely
+ // add back most or all of it later, as when redrawing axes, for example.
+ //
+ // @param {string} layer A string of space-separated CSS classes uniquely
+ // identifying the layer containing this text.
+ // @param {number=} x X coordinate of the text.
+ // @param {number=} y Y coordinate of the text.
+ // @param {string=} text Text string to remove.
+ // @param {(string|object)=} font Either a string of space-separated CSS
+ // classes or a font-spec object, defining the text's font and style.
+ // @param {number=} angle Angle at which the text is rotated, in degrees.
+ // Angle is currently unused, it will be implemented in the future.
+
+ Canvas.prototype.removeText = function (layer, x, y, text, font, angle) {
+ if (text == null) {
+ var layerCache = this._textCache[layer];
+ if (layerCache != null) {
+ for (var styleKey in layerCache) {
+ if (hasOwnProperty.call(layerCache, styleKey)) {
+ var styleCache = layerCache[styleKey];
+ for (var key in styleCache) {
+ if (hasOwnProperty.call(styleCache, key)) {
+ var positions = styleCache[key].positions;
+ for (var i = 0, position; position = positions[i]; i++) {
+ position.active = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ var positions = this.getTextInfo(layer, text, font, angle).positions;
+ for (var i = 0, position; position = positions[i]; i++) {
+ if (position.x == x && position.y == y) {
+ position.active = false;
+ }
+ }
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The top-level container for the entire plot.
+
+ function Plot(placeholder, data_, options_, plugins) {
+ // data is on the form:
+ // [ series1, series2 ... ]
+ // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
+ // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
+
+ var series = [],
+ options = {
+ // the color theme used for graphs
+ colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
+ legend: {
+ show: true,
+ noColumns: 1, // number of colums in legend table
+ labelFormatter: null, // fn: string -> string
+ labelBoxBorderColor: "#ccc", // border color for the little label boxes
+ container: null, // container (as jQuery object) to put legend in, null means default on top of graph
+ position: "ne", // position of default legend container within plot
+ margin: 5, // distance from grid edge to default legend container within plot
+ backgroundColor: null, // null means auto-detect
+ backgroundOpacity: 0.85, // set to 0 to avoid background
+ sorted: null // default to no legend sorting
+ },
+ xaxis: {
+ show: null, // null = auto-detect, true = always, false = never
+ position: "bottom", // or "top"
+ mode: null, // null or "time"
+ font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
+ color: null, // base color, labels, ticks
+ tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
+ transform: null, // null or f: number -> number to transform axis
+ inverseTransform: null, // if transform is set, this should be the inverse function
+ min: null, // min. value to show, null means set automatically
+ max: null, // max. value to show, null means set automatically
+ autoscaleMargin: null, // margin in % to add if auto-setting min/max
+ ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
+ tickFormatter: null, // fn: number -> string
+ labelWidth: null, // size of tick labels in pixels
+ labelHeight: null,
+ reserveSpace: null, // whether to reserve space even if axis isn't shown
+ tickLength: null, // size in pixels of ticks, or "full" for whole line
+ alignTicksWithAxis: null, // axis number or null for no sync
+ tickDecimals: null, // no. of decimals, null means auto
+ tickSize: null, // number or [number, "unit"]
+ minTickSize: null // number or [number, "unit"]
+ },
+ yaxis: {
+ autoscaleMargin: 0.02,
+ position: "left" // or "right"
+ },
+ xaxes: [],
+ yaxes: [],
+ series: {
+ points: {
+ show: false,
+ radius: 3,
+ lineWidth: 2, // in pixels
+ fill: true,
+ fillColor: "#ffffff",
+ symbol: "circle" // or callback
+ },
+ lines: {
+ // we don't put in show: false so we can see
+ // whether lines were actively disabled
+ lineWidth: 2, // in pixels
+ fill: false,
+ fillColor: null,
+ steps: false
+ // Omit 'zero', so we can later default its value to
+ // match that of the 'fill' option.
+ },
+ bars: {
+ show: false,
+ lineWidth: 2, // in pixels
+ barWidth: 1, // in units of the x axis
+ fill: true,
+ fillColor: null,
+ align: "left", // "left", "right", or "center"
+ horizontal: false,
+ zero: true
+ },
+ shadowSize: 3,
+ highlightColor: null
+ },
+ grid: {
+ show: true,
+ aboveData: false,
+ color: "#545454", // primary color used for outline and labels
+ backgroundColor: null, // null for transparent, else color
+ borderColor: null, // set if different from the grid color
+ tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
+ margin: 0, // distance from the canvas edge to the grid
+ labelMargin: 5, // in pixels
+ axisMargin: 8, // in pixels
+ borderWidth: 2, // in pixels
+ minBorderMargin: null, // in pixels, null means taken from points radius
+ markings: null, // array of ranges or fn: axes -> array of ranges
+ markingsColor: "#f4f4f4",
+ markingsLineWidth: 2,
+ // interactive stuff
+ clickable: false,
+ hoverable: false,
+ autoHighlight: true, // highlight in case mouse is near
+ mouseActiveRadius: 10 // how far the mouse can be away to activate an item
+ },
+ interaction: {
+ redrawOverlayInterval: 1000 / 60 // time between updates, -1 means in same flow
+ },
+ hooks: {}
+ },
+ surface = null, // the canvas for the plot itself
+ overlay = null, // canvas for interactive stuff on top of plot
+ eventHolder = null, // jQuery object that events should be bound to
+ ctx = null, octx = null,
+ xaxes = [], yaxes = [],
+ plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
+ plotWidth = 0, plotHeight = 0,
+ hooks = {
+ processOptions: [],
+ processRawData: [],
+ processDatapoints: [],
+ processOffset: [],
+ drawBackground: [],
+ drawSeries: [],
+ draw: [],
+ bindEvents: [],
+ drawOverlay: [],
+ shutdown: []
+ },
+ plot = this;
+
+ // public functions
+ plot.setData = setData;
+ plot.setupGrid = setupGrid;
+ plot.draw = draw;
+ plot.getPlaceholder = function () {
+ return placeholder;
+ };
+ plot.getCanvas = function () {
+ return surface.element;
+ };
+ plot.getPlotOffset = function () {
+ return plotOffset;
+ };
+ plot.width = function () {
+ return plotWidth;
+ };
+ plot.height = function () {
+ return plotHeight;
+ };
+ plot.offset = function () {
+ var o = eventHolder.offset();
+ o.left += plotOffset.left;
+ o.top += plotOffset.top;
+ return o;
+ };
+ plot.getData = function () {
+ return series;
+ };
+ plot.getAxes = function () {
+ var res = {}, i;
+ $.each(xaxes.concat(yaxes), function (_, axis) {
+ if (axis)
+ res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
+ });
+ return res;
+ };
+ plot.getXAxes = function () {
+ return xaxes;
+ };
+ plot.getYAxes = function () {
+ return yaxes;
+ };
+ plot.c2p = canvasToAxisCoords;
+ plot.p2c = axisToCanvasCoords;
+ plot.getOptions = function () {
+ return options;
+ };
+ plot.highlight = highlight;
+ plot.unhighlight = unhighlight;
+ plot.triggerRedrawOverlay = triggerRedrawOverlay;
+ plot.pointOffset = function (point) {
+ return {
+ left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
+ top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
+ };
+ };
+ plot.shutdown = shutdown;
+ plot.destroy = function () {
+ shutdown();
+ placeholder.removeData("plot").empty();
+
+ series = [];
+ options = null;
+ surface = null;
+ overlay = null;
+ eventHolder = null;
+ ctx = null;
+ octx = null;
+ xaxes = [];
+ yaxes = [];
+ hooks = null;
+ highlights = [];
+ plot = null;
+ };
+ plot.resize = function () {
+ var width = placeholder.width(),
+ height = placeholder.height();
+ surface.resize(width, height);
+ overlay.resize(width, height);
+ };
+
+ // public attributes
+ plot.hooks = hooks;
+
+ // initialize
+ initPlugins(plot);
+ parseOptions(options_);
+ setupCanvases();
+ setData(data_);
+ setupGrid();
+ draw();
+ bindEvents();
+
+
+ function executeHooks(hook, args) {
+ args = [plot].concat(args);
+ for (var i = 0; i < hook.length; ++i)
+ hook[i].apply(this, args);
+ }
+
+ function initPlugins() {
+
+ // References to key classes, allowing plugins to modify them
+
+ var classes = {
+ Canvas: Canvas
+ };
+
+ for (var i = 0; i < plugins.length; ++i) {
+ var p = plugins[i];
+ p.init(plot, classes);
+ if (p.options)
+ $.extend(true, options, p.options);
+ }
+ }
+
+ function parseOptions(opts) {
+
+ $.extend(true, options, opts);
+
+ // $.extend merges arrays, rather than replacing them. When less
+ // colors are provided than the size of the default palette, we
+ // end up with those colors plus the remaining defaults, which is
+ // not expected behavior; avoid it by replacing them here.
+
+ if (opts && opts.colors) {
+ options.colors = opts.colors;
+ }
+
+ if (options.xaxis.color == null)
+ options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+ if (options.yaxis.color == null)
+ options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+
+ if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
+ options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
+ if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
+ options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
+
+ if (options.grid.borderColor == null)
+ options.grid.borderColor = options.grid.color;
+ if (options.grid.tickColor == null)
+ options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+
+ // Fill in defaults for axis options, including any unspecified
+ // font-spec fields, if a font-spec was provided.
+
+ // If no x/y axis options were provided, create one of each anyway,
+ // since the rest of the code assumes that they exist.
+
+ var i, axisOptions, axisCount,
+ fontSize = placeholder.css("font-size"),
+ fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
+ fontDefaults = {
+ style: placeholder.css("font-style"),
+ size: Math.round(0.8 * fontSizeDefault),
+ variant: placeholder.css("font-variant"),
+ weight: placeholder.css("font-weight"),
+ family: placeholder.css("font-family")
+ };
+
+ axisCount = options.xaxes.length || 1;
+ for (i = 0; i < axisCount; ++i) {
+
+ axisOptions = options.xaxes[i];
+ if (axisOptions && !axisOptions.tickColor) {
+ axisOptions.tickColor = axisOptions.color;
+ }
+
+ axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
+ options.xaxes[i] = axisOptions;
+
+ if (axisOptions.font) {
+ axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
+ if (!axisOptions.font.color) {
+ axisOptions.font.color = axisOptions.color;
+ }
+ if (!axisOptions.font.lineHeight) {
+ axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
+ }
+ }
+ }
+
+ axisCount = options.yaxes.length || 1;
+ for (i = 0; i < axisCount; ++i) {
+
+ axisOptions = options.yaxes[i];
+ if (axisOptions && !axisOptions.tickColor) {
+ axisOptions.tickColor = axisOptions.color;
+ }
+
+ axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
+ options.yaxes[i] = axisOptions;
+
+ if (axisOptions.font) {
+ axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
+ if (!axisOptions.font.color) {
+ axisOptions.font.color = axisOptions.color;
+ }
+ if (!axisOptions.font.lineHeight) {
+ axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
+ }
+ }
+ }
+
+ // backwards compatibility, to be removed in future
+ if (options.xaxis.noTicks && options.xaxis.ticks == null)
+ options.xaxis.ticks = options.xaxis.noTicks;
+ if (options.yaxis.noTicks && options.yaxis.ticks == null)
+ options.yaxis.ticks = options.yaxis.noTicks;
+ if (options.x2axis) {
+ options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
+ options.xaxes[1].position = "top";
+ // Override the inherit to allow the axis to auto-scale
+ if (options.x2axis.min == null) {
+ options.xaxes[1].min = null;
+ }
+ if (options.x2axis.max == null) {
+ options.xaxes[1].max = null;
+ }
+ }
+ if (options.y2axis) {
+ options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
+ options.yaxes[1].position = "right";
+ // Override the inherit to allow the axis to auto-scale
+ if (options.y2axis.min == null) {
+ options.yaxes[1].min = null;
+ }
+ if (options.y2axis.max == null) {
+ options.yaxes[1].max = null;
+ }
+ }
+ if (options.grid.coloredAreas)
+ options.grid.markings = options.grid.coloredAreas;
+ if (options.grid.coloredAreasColor)
+ options.grid.markingsColor = options.grid.coloredAreasColor;
+ if (options.lines)
+ $.extend(true, options.series.lines, options.lines);
+ if (options.points)
+ $.extend(true, options.series.points, options.points);
+ if (options.bars)
+ $.extend(true, options.series.bars, options.bars);
+ if (options.shadowSize != null)
+ options.series.shadowSize = options.shadowSize;
+ if (options.highlightColor != null)
+ options.series.highlightColor = options.highlightColor;
+
+ // save options on axes for future reference
+ for (i = 0; i < options.xaxes.length; ++i)
+ getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
+ for (i = 0; i < options.yaxes.length; ++i)
+ getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
+
+ // add hooks from options
+ for (var n in hooks)
+ if (options.hooks[n] && options.hooks[n].length)
+ hooks[n] = hooks[n].concat(options.hooks[n]);
+
+ executeHooks(hooks.processOptions, [options]);
+ }
+
+ function setData(d) {
+ series = parseData(d);
+ fillInSeriesOptions();
+ processData();
+ }
+
+ function parseData(d) {
+ var res = [];
+ for (var i = 0; i < d.length; ++i) {
+ var s = $.extend(true, {}, options.series);
+
+ if (d[i].data != null) {
+ s.data = d[i].data; // move the data instead of deep-copy
+ delete d[i].data;
+
+ $.extend(true, s, d[i]);
+
+ d[i].data = s.data;
+ }
+ else
+ s.data = d[i];
+ res.push(s);
+ }
+
+ return res;
+ }
+
+ function axisNumber(obj, coord) {
+ var a = obj[coord + "axis"];
+ if (typeof a == "object") // if we got a real axis, extract number
+ a = a.n;
+ if (typeof a != "number")
+ a = 1; // default to first axis
+ return a;
+ }
+
+ function allAxes() {
+ // return flat array without annoying null entries
+ return $.grep(xaxes.concat(yaxes), function (a) {
+ return a;
+ });
+ }
+
+ function canvasToAxisCoords(pos) {
+ // return an object with x/y corresponding to all used axes
+ var res = {}, i, axis;
+ for (i = 0; i < xaxes.length; ++i) {
+ axis = xaxes[i];
+ if (axis && axis.used)
+ res["x" + axis.n] = axis.c2p(pos.left);
+ }
+
+ for (i = 0; i < yaxes.length; ++i) {
+ axis = yaxes[i];
+ if (axis && axis.used)
+ res["y" + axis.n] = axis.c2p(pos.top);
+ }
+
+ if (res.x1 !== undefined)
+ res.x = res.x1;
+ if (res.y1 !== undefined)
+ res.y = res.y1;
+
+ return res;
+ }
+
+ function axisToCanvasCoords(pos) {
+ // get canvas coords from the first pair of x/y found in pos
+ var res = {}, i, axis, key;
+
+ for (i = 0; i < xaxes.length; ++i) {
+ axis = xaxes[i];
+ if (axis && axis.used) {
+ key = "x" + axis.n;
+ if (pos[key] == null && axis.n == 1)
+ key = "x";
+
+ if (pos[key] != null) {
+ res.left = axis.p2c(pos[key]);
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < yaxes.length; ++i) {
+ axis = yaxes[i];
+ if (axis && axis.used) {
+ key = "y" + axis.n;
+ if (pos[key] == null && axis.n == 1)
+ key = "y";
+
+ if (pos[key] != null) {
+ res.top = axis.p2c(pos[key]);
+ break;
+ }
+ }
+ }
+
+ return res;
+ }
+
+ function getOrCreateAxis(axes, number) {
+ if (!axes[number - 1])
+ axes[number - 1] = {
+ n: number, // save the number for future reference
+ direction: axes == xaxes ? "x" : "y",
+ options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
+ };
+
+ return axes[number - 1];
+ }
+
+ function fillInSeriesOptions() {
+
+ var neededColors = series.length, maxIndex = -1, i;
+
+ // Subtract the number of series that already have fixed colors or
+ // color indexes from the number that we still need to generate.
+
+ for (i = 0; i < series.length; ++i) {
+ var sc = series[i].color;
+ if (sc != null) {
+ neededColors--;
+ if (typeof sc == "number" && sc > maxIndex) {
+ maxIndex = sc;
+ }
+ }
+ }
+
+ // If any of the series have fixed color indexes, then we need to
+ // generate at least as many colors as the highest index.
+
+ if (neededColors <= maxIndex) {
+ neededColors = maxIndex + 1;
+ }
+
+ // Generate all the colors, using first the option colors and then
+ // variations on those colors once they're exhausted.
+
+ var c, colors = [], colorPool = options.colors,
+ colorPoolSize = colorPool.length, variation = 0;
+
+ for (i = 0; i < neededColors; i++) {
+
+ c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
+
+ // Each time we exhaust the colors in the pool we adjust
+ // a scaling factor used to produce more variations on
+ // those colors. The factor alternates negative/positive
+ // to produce lighter/darker colors.
+
+ // Reset the variation after every few cycles, or else
+ // it will end up producing only white or black colors.
+
+ if (i % colorPoolSize == 0 && i) {
+ if (variation >= 0) {
+ if (variation < 0.5) {
+ variation = -variation - 0.2;
+ } else variation = 0;
+ } else variation = -variation;
+ }
+
+ colors[i] = c.scale('rgb', 1 + variation);
+ }
+
+ // Finalize the series options, filling in their colors
+
+ var colori = 0, s;
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ // assign colors
+ if (s.color == null) {
+ s.color = colors[colori].toString();
+ ++colori;
+ }
+ else if (typeof s.color == "number")
+ s.color = colors[s.color].toString();
+
+ // turn on lines automatically in case nothing is set
+ if (s.lines.show == null) {
+ var v, show = true;
+ for (v in s)
+ if (s[v] && s[v].show) {
+ show = false;
+ break;
+ }
+ if (show)
+ s.lines.show = true;
+ }
+
+ // If nothing was provided for lines.zero, default it to match
+ // lines.fill, since areas by default should extend to zero.
+
+ if (s.lines.zero == null) {
+ s.lines.zero = !!s.lines.fill;
+ }
+
+ // setup axes
+ s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
+ s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
+ }
+ }
+
+ function processData() {
+ var topSentry = Number.POSITIVE_INFINITY,
+ bottomSentry = Number.NEGATIVE_INFINITY,
+ fakeInfinity = Number.MAX_VALUE,
+ i, j, k, m, length,
+ s, points, ps, x, y, axis, val, f, p,
+ data, format;
+
+ function updateAxis(axis, min, max) {
+ if (min < axis.datamin && min != -fakeInfinity)
+ axis.datamin = min;
+ if (max > axis.datamax && max != fakeInfinity)
+ axis.datamax = max;
+ }
+
+ $.each(allAxes(), function (_, axis) {
+ // init axis
+ axis.datamin = topSentry;
+ axis.datamax = bottomSentry;
+ axis.used = false;
+ });
+
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ s.datapoints = { points: [] };
+
+ executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
+ }
+
+ // first pass: clean and copy data
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ data = s.data;
+ format = s.datapoints.format;
+
+ if (!format) {
+ format = [];
+ // find out how to copy
+ format.push({ x: true, number: true, required: true });
+ format.push({ y: true, number: true, required: true });
+
+ if (s.bars.show || (s.lines.show && s.lines.fill)) {
+ var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
+ format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
+ if (s.bars.horizontal) {
+ delete format[format.length - 1].y;
+ format[format.length - 1].x = true;
+ }
+ }
+
+ s.datapoints.format = format;
+ }
+
+ if (s.datapoints.pointsize != null)
+ continue; // already filled in
+
+ s.datapoints.pointsize = format.length;
+
+ ps = s.datapoints.pointsize;
+ points = s.datapoints.points;
+
+ var insertSteps = s.lines.show && s.lines.steps;
+ s.xaxis.used = s.yaxis.used = true;
+
+ for (j = k = 0; j < data.length; ++j, k += ps) {
+ p = data[j];
+
+ var nullify = p == null;
+ if (!nullify) {
+ for (m = 0; m < ps; ++m) {
+ val = p[m];
+ f = format[m];
+
+ if (f) {
+ if (f.number && val != null) {
+ val = +val; // convert to number
+ if (isNaN(val))
+ val = null;
+ else if (val == Infinity)
+ val = fakeInfinity;
+ else if (val == -Infinity)
+ val = -fakeInfinity;
+ }
+
+ if (val == null) {
+ if (f.required)
+ nullify = true;
+
+ if (f.defaultValue != null)
+ val = f.defaultValue;
+ }
+ }
+
+ points[k + m] = val;
+ }
+ }
+
+ if (nullify) {
+ for (m = 0; m < ps; ++m) {
+ val = points[k + m];
+ if (val != null) {
+ f = format[m];
+ // extract min/max info
+ if (f.autoscale !== false) {
+ if (f.x) {
+ updateAxis(s.xaxis, val, val);
+ }
+ if (f.y) {
+ updateAxis(s.yaxis, val, val);
+ }
+ }
+ }
+ points[k + m] = null;
+ }
+ }
+ else {
+ // a little bit of line specific stuff that
+ // perhaps shouldn't be here, but lacking
+ // better means...
+ if (insertSteps && k > 0
+ && points[k - ps] != null
+ && points[k - ps] != points[k]
+ && points[k - ps + 1] != points[k + 1]) {
+ // copy the point to make room for a middle point
+ for (m = 0; m < ps; ++m)
+ points[k + ps + m] = points[k + m];
+
+ // middle point has same y
+ points[k + 1] = points[k - ps + 1];
+
+ // we've added a point, better reflect that
+ k += ps;
+ }
+ }
+ }
+ }
+
+ // give the hooks a chance to run
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
+ }
+
+ // second pass: find datamax/datamin for auto-scaling
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ points = s.datapoints.points;
+ ps = s.datapoints.pointsize;
+ format = s.datapoints.format;
+
+ var xmin = topSentry, ymin = topSentry,
+ xmax = bottomSentry, ymax = bottomSentry;
+
+ for (j = 0; j < points.length; j += ps) {
+ if (points[j] == null)
+ continue;
+
+ for (m = 0; m < ps; ++m) {
+ val = points[j + m];
+ f = format[m];
+ if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
+ continue;
+
+ if (f.x) {
+ if (val < xmin)
+ xmin = val;
+ if (val > xmax)
+ xmax = val;
+ }
+ if (f.y) {
+ if (val < ymin)
+ ymin = val;
+ if (val > ymax)
+ ymax = val;
+ }
+ }
+ }
+
+ if (s.bars.show) {
+ // make sure we got room for the bar on the dancing floor
+ var delta;
+
+ switch (s.bars.align) {
+ case "left":
+ delta = 0;
+ break;
+ case "right":
+ delta = -s.bars.barWidth;
+ break;
+ default:
+ delta = -s.bars.barWidth / 2;
+ }
+
+ if (s.bars.horizontal) {
+ ymin += delta;
+ ymax += delta + s.bars.barWidth;
+ }
+ else {
+ xmin += delta;
+ xmax += delta + s.bars.barWidth;
+ }
+ }
+
+ updateAxis(s.xaxis, xmin, xmax);
+ updateAxis(s.yaxis, ymin, ymax);
+ }
+
+ $.each(allAxes(), function (_, axis) {
+ if (axis.datamin == topSentry)
+ axis.datamin = null;
+ if (axis.datamax == bottomSentry)
+ axis.datamax = null;
+ });
+ }
+
+ function setupCanvases() {
+
+ // Make sure the placeholder is clear of everything except canvases
+ // from a previous plot in this container that we'll try to re-use.
+
+ placeholder.css("padding", 0) // padding messes up the positioning
+ .children().filter(function () {
+ return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
+ }).remove();
+
+ if (placeholder.css("position") == 'static')
+ placeholder.css("position", "relative"); // for positioning labels and overlay
+
+ surface = new Canvas("flot-base", placeholder);
+ overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
+
+ ctx = surface.context;
+ octx = overlay.context;
+
+ // define which element we're listening for events on
+ eventHolder = $(overlay.element).unbind();
+
+ // If we're re-using a plot object, shut down the old one
+
+ var existing = placeholder.data("plot");
+
+ if (existing) {
+ existing.shutdown();
+ overlay.clear();
+ }
+
+ // save in case we get replotted
+ placeholder.data("plot", plot);
+ }
+
+ function bindEvents() {
+ // bind events
+ if (options.grid.hoverable) {
+ eventHolder.mousemove(onMouseMove);
+
+ // Use bind, rather than .mouseleave, because we officially
+ // still support jQuery 1.2.6, which doesn't define a shortcut
+ // for mouseenter or mouseleave. This was a bug/oversight that
+ // was fixed somewhere around 1.3.x. We can return to using
+ // .mouseleave when we drop support for 1.2.6.
+
+ eventHolder.bind("mouseleave", onMouseLeave);
+ }
+
+ if (options.grid.clickable)
+ eventHolder.click(onClick);
+
+ executeHooks(hooks.bindEvents, [eventHolder]);
+ }
+
+ function shutdown() {
+ if (redrawTimeout)
+ clearTimeout(redrawTimeout);
+
+ eventHolder.unbind("mousemove", onMouseMove);
+ eventHolder.unbind("mouseleave", onMouseLeave);
+ eventHolder.unbind("click", onClick);
+
+ executeHooks(hooks.shutdown, [eventHolder]);
+ }
+
+ function setTransformationHelpers(axis) {
+ // set helper functions on the axis, assumes plot area
+ // has been computed already
+
+ function identity(x) {
+ return x;
+ }
+
+ var s, m, t = axis.options.transform || identity,
+ it = axis.options.inverseTransform;
+
+ // precompute how much the axis is scaling a point
+ // in canvas space
+ if (axis.direction == "x") {
+ s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
+ m = Math.min(t(axis.max), t(axis.min));
+ }
+ else {
+ s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
+ s = -s;
+ m = Math.max(t(axis.max), t(axis.min));
+ }
+
+ // data point to canvas coordinate
+ if (t == identity) // slight optimization
+ axis.p2c = function (p) {
+ return (p - m) * s;
+ };
+ else
+ axis.p2c = function (p) {
+ return (t(p) - m) * s;
+ };
+ // canvas coordinate to data point
+ if (!it)
+ axis.c2p = function (c) {
+ return m + c / s;
+ };
+ else
+ axis.c2p = function (c) {
+ return it(m + c / s);
+ };
+ }
+
+ function measureTickLabels(axis) {
+
+ var opts = axis.options,
+ ticks = axis.ticks || [],
+ labelWidth = opts.labelWidth || 0,
+ labelHeight = opts.labelHeight || 0,
+ maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
+ legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
+ layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
+ font = opts.font || "flot-tick-label tickLabel";
+
+ for (var i = 0; i < ticks.length; ++i) {
+
+ var t = ticks[i];
+
+ if (!t.label)
+ continue;
+
+ var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
+
+ labelWidth = Math.max(labelWidth, info.width);
+ labelHeight = Math.max(labelHeight, info.height);
+ }
+
+ axis.labelWidth = opts.labelWidth || labelWidth;
+ axis.labelHeight = opts.labelHeight || labelHeight;
+ }
+
+ function allocateAxisBoxFirstPhase(axis) {
+ // find the bounding box of the axis by looking at label
+ // widths/heights and ticks, make room by diminishing the
+ // plotOffset; this first phase only looks at one
+ // dimension per axis, the other dimension depends on the
+ // other axes so will have to wait
+
+ var lw = axis.labelWidth,
+ lh = axis.labelHeight,
+ pos = axis.options.position,
+ isXAxis = axis.direction === "x",
+ tickLength = axis.options.tickLength,
+ axisMargin = options.grid.axisMargin,
+ padding = options.grid.labelMargin,
+ innermost = true,
+ outermost = true,
+ first = true,
+ found = false;
+
+ // Determine the axis's position in its direction and on its side
+
+ $.each(isXAxis ? xaxes : yaxes, function (i, a) {
+ if (a && (a.show || a.reserveSpace)) {
+ if (a === axis) {
+ found = true;
+ } else if (a.options.position === pos) {
+ if (found) {
+ outermost = false;
+ } else {
+ innermost = false;
+ }
+ }
+ if (!found) {
+ first = false;
+ }
+ }
+ });
+
+ // The outermost axis on each side has no margin
+
+ if (outermost) {
+ axisMargin = 0;
+ }
+
+ // The ticks for the first axis in each direction stretch across
+
+ if (tickLength == null) {
+ tickLength = first ? "full" : 5;
+ }
+
+ if (!isNaN(+tickLength))
+ padding += +tickLength;
+
+ if (isXAxis) {
+ lh += padding;
+
+ if (pos == "bottom") {
+ plotOffset.bottom += lh + axisMargin;
+ axis.box = { top: surface.height - plotOffset.bottom, height: lh };
+ }
+ else {
+ axis.box = { top: plotOffset.top + axisMargin, height: lh };
+ plotOffset.top += lh + axisMargin;
+ }
+ }
+ else {
+ lw += padding;
+
+ if (pos == "left") {
+ axis.box = { left: plotOffset.left + axisMargin, width: lw };
+ plotOffset.left += lw + axisMargin;
+ }
+ else {
+ plotOffset.right += lw + axisMargin;
+ axis.box = { left: surface.width - plotOffset.right, width: lw };
+ }
+ }
+
+ // save for future reference
+ axis.position = pos;
+ axis.tickLength = tickLength;
+ axis.box.padding = padding;
+ axis.innermost = innermost;
+ }
+
+ function allocateAxisBoxSecondPhase(axis) {
+ // now that all axis boxes have been placed in one
+ // dimension, we can set the remaining dimension coordinates
+ if (axis.direction == "x") {
+ axis.box.left = plotOffset.left - axis.labelWidth / 2;
+ axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
+ }
+ else {
+ axis.box.top = plotOffset.top - axis.labelHeight / 2;
+ axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
+ }
+ }
+
+ function adjustLayoutForThingsStickingOut() {
+ // possibly adjust plot offset to ensure everything stays
+ // inside the canvas and isn't clipped off
+
+ var minMargin = options.grid.minBorderMargin,
+ axis, i;
+
+ // check stuff from the plot (FIXME: this should just read
+ // a value from the series, otherwise it's impossible to
+ // customize)
+ if (minMargin == null) {
+ minMargin = 0;
+ for (i = 0; i < series.length; ++i)
+ minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth / 2));
+ }
+
+ var margins = {
+ left: minMargin,
+ right: minMargin,
+ top: minMargin,
+ bottom: minMargin
+ };
+
+ // check axis labels, note we don't check the actual
+ // labels but instead use the overall width/height to not
+ // jump as much around with replots
+ $.each(allAxes(), function (_, axis) {
+ if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
+ if (axis.direction === "x") {
+ margins.left = Math.max(margins.left, axis.labelWidth / 2);
+ margins.right = Math.max(margins.right, axis.labelWidth / 2);
+ } else {
+ margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
+ margins.top = Math.max(margins.top, axis.labelHeight / 2);
+ }
+ }
+ });
+
+ plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
+ plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
+ plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
+ plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
+ }
+
+ function setupGrid() {
+ var i, axes = allAxes(), showGrid = options.grid.show;
+
+ // Initialize the plot's offset from the edge of the canvas
+
+ for (var a in plotOffset) {
+ var margin = options.grid.margin || 0;
+ plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
+ }
+
+ executeHooks(hooks.processOffset, [plotOffset]);
+
+ // If the grid is visible, add its border width to the offset
+
+ for (var a in plotOffset) {
+ if (typeof(options.grid.borderWidth) == "object") {
+ plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
+ }
+ else {
+ plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
+ }
+ }
+
+ $.each(axes, function (_, axis) {
+ var axisOpts = axis.options;
+ axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
+ axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
+ setRange(axis);
+ });
+
+ if (showGrid) {
+
+ var allocatedAxes = $.grep(axes, function (axis) {
+ return axis.show || axis.reserveSpace;
+ });
+
+ $.each(allocatedAxes, function (_, axis) {
+ // make the ticks
+ setupTickGeneration(axis);
+ setTicks(axis);
+ snapRangeToTicks(axis, axis.ticks);
+ // find labelWidth/Height for axis
+ measureTickLabels(axis);
+ });
+
+ // with all dimensions calculated, we can compute the
+ // axis bounding boxes, start from the outside
+ // (reverse order)
+ for (i = allocatedAxes.length - 1; i >= 0; --i)
+ allocateAxisBoxFirstPhase(allocatedAxes[i]);
+
+ // make sure we've got enough space for things that
+ // might stick out
+ adjustLayoutForThingsStickingOut();
+
+ $.each(allocatedAxes, function (_, axis) {
+ allocateAxisBoxSecondPhase(axis);
+ });
+ }
+
+ plotWidth = surface.width - plotOffset.left - plotOffset.right;
+ plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
+
+ // now we got the proper plot dimensions, we can compute the scaling
+ $.each(axes, function (_, axis) {
+ setTransformationHelpers(axis);
+ });
+
+ if (showGrid) {
+ drawAxisLabels();
+ }
+
+ insertLegend();
+ }
+
+ function setRange(axis) {
+ var opts = axis.options,
+ min = +(opts.min != null ? opts.min : axis.datamin),
+ max = +(opts.max != null ? opts.max : axis.datamax),
+ delta = max - min;
+
+ if (delta == 0.0) {
+ // degenerate case
+ var widen = max == 0 ? 1 : 0.01;
+
+ if (opts.min == null)
+ min -= widen;
+ // always widen max if we couldn't widen min to ensure we
+ // don't fall into min == max which doesn't work
+ if (opts.max == null || opts.min != null)
+ max += widen;
+ }
+ else {
+ // consider autoscaling
+ var margin = opts.autoscaleMargin;
+ if (margin != null) {
+ if (opts.min == null) {
+ min -= delta * margin;
+ // make sure we don't go below zero if all values
+ // are positive
+ if (min < 0 && axis.datamin != null && axis.datamin >= 0)
+ min = 0;
+ }
+ if (opts.max == null) {
+ max += delta * margin;
+ if (max > 0 && axis.datamax != null && axis.datamax <= 0)
+ max = 0;
+ }
+ }
+ }
+ axis.min = min;
+ axis.max = max;
+ }
+
+ function setupTickGeneration(axis) {
+ var opts = axis.options;
+
+ // estimate number of ticks
+ var noTicks;
+ if (typeof opts.ticks == "number" && opts.ticks > 0)
+ noTicks = opts.ticks;
+ else
+ // heuristic based on the model a*sqrt(x) fitted to
+ // some data points that seemed reasonable
+ noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
+
+ var delta = (axis.max - axis.min) / noTicks,
+ dec = -Math.floor(Math.log(delta) / Math.LN10),
+ maxDec = opts.tickDecimals;
+
+ if (maxDec != null && dec > maxDec) {
+ dec = maxDec;
+ }
+
+ var magn = Math.pow(10, -dec),
+ norm = delta / magn, // norm is between 1.0 and 10.0
+ size;
+
+ if (norm < 1.5) {
+ size = 1;
+ } else if (norm < 3) {
+ size = 2;
+ // special case for 2.5, requires an extra decimal
+ if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+ size = 2.5;
+ ++dec;
+ }
+ } else if (norm < 7.5) {
+ size = 5;
+ } else {
+ size = 10;
+ }
+
+ size *= magn;
+
+ if (opts.minTickSize != null && size < opts.minTickSize) {
+ size = opts.minTickSize;
+ }
+
+ axis.delta = delta;
+ axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
+ axis.tickSize = opts.tickSize || size;
+
+ // Time mode was moved to a plug-in in 0.8, and since so many people use it
+ // we'll add an especially friendly reminder to make sure they included it.
+
+ if (opts.mode == "time" && !axis.tickGenerator) {
+ throw new Error("Time mode requires the flot.time plugin.");
+ }
+
+ // Flot supports base-10 axes; any other mode else is handled by a plug-in,
+ // like flot.time.js.
+
+ if (!axis.tickGenerator) {
+
+ axis.tickGenerator = function (axis) {
+
+ var ticks = [],
+ start = floorInBase(axis.min, axis.tickSize),
+ i = 0,
+ v = Number.NaN,
+ prev;
+
+ do {
+ prev = v;
+ v = start + i * axis.tickSize;
+ ticks.push(v);
+ ++i;
+ } while (v < axis.max && v != prev);
+ return ticks;
+ };
+
+ axis.tickFormatter = function (value, axis) {
+
+ var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
+ var formatted = "" + Math.round(value * factor) / factor;
+
+ // If tickDecimals was specified, ensure that we have exactly that
+ // much precision; otherwise default to the value's own precision.
+
+ if (axis.tickDecimals != null) {
+ var decimal = formatted.indexOf(".");
+ var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
+ if (precision < axis.tickDecimals) {
+ return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
+ }
+ }
+
+ return formatted;
+ };
+ }
+
+ if ($.isFunction(opts.tickFormatter))
+ axis.tickFormatter = function (v, axis) {
+ return "" + opts.tickFormatter(v, axis);
+ };
+
+ if (opts.alignTicksWithAxis != null) {
+ var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
+ if (otherAxis && otherAxis.used && otherAxis != axis) {
+ // consider snapping min/max to outermost nice ticks
+ var niceTicks = axis.tickGenerator(axis);
+ if (niceTicks.length > 0) {
+ if (opts.min == null)
+ axis.min = Math.min(axis.min, niceTicks[0]);
+ if (opts.max == null && niceTicks.length > 1)
+ axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
+ }
+
+ axis.tickGenerator = function (axis) {
+ // copy ticks, scaled to this axis
+ var ticks = [], v, i;
+ for (i = 0; i < otherAxis.ticks.length; ++i) {
+ v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
+ v = axis.min + v * (axis.max - axis.min);
+ ticks.push(v);
+ }
+ return ticks;
+ };
+
+ // we might need an extra decimal since forced
+ // ticks don't necessarily fit naturally
+ if (!axis.mode && opts.tickDecimals == null) {
+ var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
+ ts = axis.tickGenerator(axis);
+
+ // only proceed if the tick interval rounded
+ // with an extra decimal doesn't give us a
+ // zero at end
+ if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
+ axis.tickDecimals = extraDec;
+ }
+ }
+ }
+ }
+
+ function setTicks(axis) {
+ var oticks = axis.options.ticks, ticks = [];
+ if (oticks == null || (typeof oticks == "number" && oticks > 0))
+ ticks = axis.tickGenerator(axis);
+ else if (oticks) {
+ if ($.isFunction(oticks))
+ // generate the ticks
+ ticks = oticks(axis);
+ else
+ ticks = oticks;
+ }
+
+ // clean up/labelify the supplied ticks, copy them over
+ var i, v;
+ axis.ticks = [];
+ for (i = 0; i < ticks.length; ++i) {
+ var label = null;
+ var t = ticks[i];
+ if (typeof t == "object") {
+ v = +t[0];
+ if (t.length > 1)
+ label = t[1];
+ }
+ else
+ v = +t;
+ if (label == null)
+ label = axis.tickFormatter(v, axis);
+ if (!isNaN(v))
+ axis.ticks.push({ v: v, label: label });
+ }
+ }
+
+ function snapRangeToTicks(axis, ticks) {
+ if (axis.options.autoscaleMargin && ticks.length > 0) {
+ // snap to ticks
+ if (axis.options.min == null)
+ axis.min = Math.min(axis.min, ticks[0].v);
+ if (axis.options.max == null && ticks.length > 1)
+ axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
+ }
+ }
+
+ function draw() {
+
+ surface.clear();
+
+ executeHooks(hooks.drawBackground, [ctx]);
+
+ var grid = options.grid;
+
+ // draw background, if any
+ if (grid.show && grid.backgroundColor)
+ drawBackground();
+
+ if (grid.show && !grid.aboveData) {
+ drawGrid();
+ }
+
+ for (var i = 0; i < series.length; ++i) {
+ executeHooks(hooks.drawSeries, [ctx, series[i]]);
+ drawSeries(series[i]);
+ }
+
+ executeHooks(hooks.draw, [ctx]);
+
+ if (grid.show && grid.aboveData) {
+ drawGrid();
+ }
+
+ surface.render();
+
+ // A draw implies that either the axes or data have changed, so we
+ // should probably update the overlay highlights as well.
+
+ triggerRedrawOverlay();
+ }
+
+ function extractRange(ranges, coord) {
+ var axis, from, to, key, axes = allAxes();
+
+ for (var i = 0; i < axes.length; ++i) {
+ axis = axes[i];
+ if (axis.direction == coord) {
+ key = coord + axis.n + "axis";
+ if (!ranges[key] && axis.n == 1)
+ key = coord + "axis"; // support x1axis as xaxis
+ if (ranges[key]) {
+ from = ranges[key].from;
+ to = ranges[key].to;
+ break;
+ }
+ }
+ }
+
+ // backwards-compat stuff - to be removed in future
+ if (!ranges[key]) {
+ axis = coord == "x" ? xaxes[0] : yaxes[0];
+ from = ranges[coord + "1"];
+ to = ranges[coord + "2"];
+ }
+
+ // auto-reverse as an added bonus
+ if (from != null && to != null && from > to) {
+ var tmp = from;
+ from = to;
+ to = tmp;
+ }
+
+ return { from: from, to: to, axis: axis };
+ }
+
+ function drawBackground() {
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
+ ctx.fillRect(0, 0, plotWidth, plotHeight);
+ ctx.restore();
+ }
+
+ function drawGrid() {
+ var i, axes, bw, bc;
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // draw markings
+ var markings = options.grid.markings;
+ if (markings) {
+ if ($.isFunction(markings)) {
+ axes = plot.getAxes();
+ // xmin etc. is backwards compatibility, to be
+ // removed in the future
+ axes.xmin = axes.xaxis.min;
+ axes.xmax = axes.xaxis.max;
+ axes.ymin = axes.yaxis.min;
+ axes.ymax = axes.yaxis.max;
+
+ markings = markings(axes);
+ }
+
+ for (i = 0; i < markings.length; ++i) {
+ var m = markings[i],
+ xrange = extractRange(m, "x"),
+ yrange = extractRange(m, "y");
+
+ // fill in missing
+ if (xrange.from == null)
+ xrange.from = xrange.axis.min;
+ if (xrange.to == null)
+ xrange.to = xrange.axis.max;
+ if (yrange.from == null)
+ yrange.from = yrange.axis.min;
+ if (yrange.to == null)
+ yrange.to = yrange.axis.max;
+
+ // clip
+ if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
+ yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
+ continue;
+
+ xrange.from = Math.max(xrange.from, xrange.axis.min);
+ xrange.to = Math.min(xrange.to, xrange.axis.max);
+ yrange.from = Math.max(yrange.from, yrange.axis.min);
+ yrange.to = Math.min(yrange.to, yrange.axis.max);
+
+ var xequal = xrange.from === xrange.to,
+ yequal = yrange.from === yrange.to;
+
+ if (xequal && yequal) {
+ continue;
+ }
+
+ // then draw
+ xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
+ xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
+ yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
+ yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
+
+ if (xequal || yequal) {
+ var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
+ subPixel = lineWidth % 2 ? 0.5 : 0;
+ ctx.beginPath();
+ ctx.strokeStyle = m.color || options.grid.markingsColor;
+ ctx.lineWidth = lineWidth;
+ if (xequal) {
+ ctx.moveTo(xrange.to + subPixel, yrange.from);
+ ctx.lineTo(xrange.to + subPixel, yrange.to);
+ } else {
+ ctx.moveTo(xrange.from, yrange.to + subPixel);
+ ctx.lineTo(xrange.to, yrange.to + subPixel);
+ }
+ ctx.stroke();
+ } else {
+ ctx.fillStyle = m.color || options.grid.markingsColor;
+ ctx.fillRect(xrange.from, yrange.to,
+ xrange.to - xrange.from,
+ yrange.from - yrange.to);
+ }
+ }
+ }
+
+ // draw the ticks
+ axes = allAxes();
+ bw = options.grid.borderWidth;
+
+ for (var j = 0; j < axes.length; ++j) {
+ var axis = axes[j], box = axis.box,
+ t = axis.tickLength, x, y, xoff, yoff;
+ if (!axis.show || axis.ticks.length == 0)
+ continue;
+
+ ctx.lineWidth = 1;
+
+ // find the edges
+ if (axis.direction == "x") {
+ x = 0;
+ if (t == "full")
+ y = (axis.position == "top" ? 0 : plotHeight);
+ else
+ y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
+ }
+ else {
+ y = 0;
+ if (t == "full")
+ x = (axis.position == "left" ? 0 : plotWidth);
+ else
+ x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
+ }
+
+ // draw tick bar
+ if (!axis.innermost) {
+ ctx.strokeStyle = axis.options.color;
+ ctx.beginPath();
+ xoff = yoff = 0;
+ if (axis.direction == "x")
+ xoff = plotWidth + 1;
+ else
+ yoff = plotHeight + 1;
+
+ if (ctx.lineWidth == 1) {
+ if (axis.direction == "x") {
+ y = Math.floor(y) + 0.5;
+ } else {
+ x = Math.floor(x) + 0.5;
+ }
+ }
+
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + xoff, y + yoff);
+ ctx.stroke();
+ }
+
+ // draw ticks
+
+ ctx.strokeStyle = axis.options.tickColor;
+
+ ctx.beginPath();
+ for (i = 0; i < axis.ticks.length; ++i) {
+ var v = axis.ticks[i].v;
+
+ xoff = yoff = 0;
+
+ if (isNaN(v) || v < axis.min || v > axis.max
+ // skip those lying on the axes if we got a border
+ || (t == "full"
+ && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
+ && (v == axis.min || v == axis.max)))
+ continue;
+
+ if (axis.direction == "x") {
+ x = axis.p2c(v);
+ yoff = t == "full" ? -plotHeight : t;
+
+ if (axis.position == "top")
+ yoff = -yoff;
+ }
+ else {
+ y = axis.p2c(v);
+ xoff = t == "full" ? -plotWidth : t;
+
+ if (axis.position == "left")
+ xoff = -xoff;
+ }
+
+ if (ctx.lineWidth == 1) {
+ if (axis.direction == "x")
+ x = Math.floor(x) + 0.5;
+ else
+ y = Math.floor(y) + 0.5;
+ }
+
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + xoff, y + yoff);
+ }
+
+ ctx.stroke();
+ }
+
+
+ // draw border
+ if (bw) {
+ // If either borderWidth or borderColor is an object, then draw the border
+ // line by line instead of as one rectangle
+ bc = options.grid.borderColor;
+ if (typeof bw == "object" || typeof bc == "object") {
+ if (typeof bw !== "object") {
+ bw = {top: bw, right: bw, bottom: bw, left: bw};
+ }
+ if (typeof bc !== "object") {
+ bc = {top: bc, right: bc, bottom: bc, left: bc};
+ }
+
+ if (bw.top > 0) {
+ ctx.strokeStyle = bc.top;
+ ctx.lineWidth = bw.top;
+ ctx.beginPath();
+ ctx.moveTo(0 - bw.left, 0 - bw.top / 2);
+ ctx.lineTo(plotWidth, 0 - bw.top / 2);
+ ctx.stroke();
+ }
+
+ if (bw.right > 0) {
+ ctx.strokeStyle = bc.right;
+ ctx.lineWidth = bw.right;
+ ctx.beginPath();
+ ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
+ ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
+ ctx.stroke();
+ }
+
+ if (bw.bottom > 0) {
+ ctx.strokeStyle = bc.bottom;
+ ctx.lineWidth = bw.bottom;
+ ctx.beginPath();
+ ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
+ ctx.lineTo(0, plotHeight + bw.bottom / 2);
+ ctx.stroke();
+ }
+
+ if (bw.left > 0) {
+ ctx.strokeStyle = bc.left;
+ ctx.lineWidth = bw.left;
+ ctx.beginPath();
+ ctx.moveTo(0 - bw.left / 2, plotHeight + bw.bottom);
+ ctx.lineTo(0 - bw.left / 2, 0);
+ ctx.stroke();
+ }
+ }
+ else {
+ ctx.lineWidth = bw;
+ ctx.strokeStyle = options.grid.borderColor;
+ ctx.strokeRect(-bw / 2, -bw / 2, plotWidth + bw, plotHeight + bw);
+ }
+ }
+
+ ctx.restore();
+ }
+
+ function drawAxisLabels() {
+
+ $.each(allAxes(), function (_, axis) {
+ var box = axis.box,
+ legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
+ layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
+ font = axis.options.font || "flot-tick-label tickLabel",
+ tick, x, y, halign, valign;
+
+ // Remove text before checking for axis.show and ticks.length;
+ // otherwise plugins, like flot-tickrotor, that draw their own
+ // tick labels will end up with both theirs and the defaults.
+
+ surface.removeText(layer);
+
+ if (!axis.show || axis.ticks.length == 0)
+ return;
+
+ for (var i = 0; i < axis.ticks.length; ++i) {
+
+ tick = axis.ticks[i];
+ if (!tick.label || tick.v < axis.min || tick.v > axis.max)
+ continue;
+
+ if (axis.direction == "x") {
+ halign = "center";
+ x = plotOffset.left + axis.p2c(tick.v);
+ if (axis.position == "bottom") {
+ y = box.top + box.padding;
+ } else {
+ y = box.top + box.height - box.padding;
+ valign = "bottom";
+ }
+ } else {
+ valign = "middle";
+ y = plotOffset.top + axis.p2c(tick.v);
+ if (axis.position == "left") {
+ x = box.left + box.width - box.padding;
+ halign = "right";
+ } else {
+ x = box.left + box.padding;
+ }
+ }
+
+ surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
+ }
+ });
+ }
+
+ function drawSeries(series) {
+ if (series.lines.show)
+ drawSeriesLines(series);
+ if (series.bars.show)
+ drawSeriesBars(series);
+ if (series.points.show)
+ drawSeriesPoints(series);
+ }
+
+ function drawSeriesLines(series) {
+ function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ prevx = null, prevy = null;
+
+ ctx.beginPath();
+ for (var i = ps; i < points.length; i += ps) {
+ var x1 = points[i - ps], y1 = points[i - ps + 1],
+ x2 = points[i], y2 = points[i + 1];
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min) {
+ if (y2 < axisy.min)
+ continue; // line segment is outside
+ // compute new intersection point
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min) {
+ if (y1 < axisy.min)
+ continue;
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max) {
+ if (y2 > axisy.max)
+ continue;
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max) {
+ if (y1 > axisy.max)
+ continue;
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (x1 != prevx || y1 != prevy)
+ ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+
+ prevx = x2;
+ prevy = y2;
+ ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+ }
+ ctx.stroke();
+ }
+
+ function plotLineArea(datapoints, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+ i = 0, top, areaOpen = false,
+ ypos = 1, segmentStart = 0, segmentEnd = 0;
+
+ // we process each segment in two turns, first forward
+ // direction to sketch out top, then once we hit the
+ // end we go backwards to sketch the bottom
+ while (true) {
+ if (ps > 0 && i > points.length + ps)
+ break;
+
+ i += ps; // ps is negative if going backwards
+
+ var x1 = points[i - ps],
+ y1 = points[i - ps + ypos],
+ x2 = points[i], y2 = points[i + ypos];
+
+ if (areaOpen) {
+ if (ps > 0 && x1 != null && x2 == null) {
+ // at turning point
+ segmentEnd = i;
+ ps = -ps;
+ ypos = 2;
+ continue;
+ }
+
+ if (ps < 0 && i == segmentStart + ps) {
+ // done with the reverse sweep
+ ctx.fill();
+ areaOpen = false;
+ ps = -ps;
+ ypos = 1;
+ i = segmentStart = segmentEnd + ps;
+ continue;
+ }
+ }
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip x values
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (!areaOpen) {
+ // open area
+ ctx.beginPath();
+ ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
+ areaOpen = true;
+ }
+
+ // now first check the case where both is outside
+ if (y1 >= axisy.max && y2 >= axisy.max) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
+ continue;
+ }
+ else if (y1 <= axisy.min && y2 <= axisy.min) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
+ continue;
+ }
+
+ // else it's a bit more complicated, there might
+ // be a flat maxed out rectangle first, then a
+ // triangular cutout or reverse; to find these
+ // keep track of the current x values
+ var x1old = x1, x2old = x2;
+
+ // clip the y values, without shortcutting, we
+ // go through all cases in turn
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+ // if the x value was changed we got a rectangle
+ // to fill
+ if (x1 != x1old) {
+ ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
+ // it goes to (x1, y1), but we fill that below
+ }
+
+ // fill triangular section, this sometimes result
+ // in redundant points if (x1, y1) hasn't changed
+ // from previous line to, but we just ignore that
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+
+ // fill the other rectangle if it's there
+ if (x2 != x2old) {
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+ ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
+ }
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+ ctx.lineJoin = "round";
+
+ var lw = series.lines.lineWidth,
+ sw = series.shadowSize;
+ // FIXME: consider another form of shadow when filling is turned on
+ if (lw > 0 && sw > 0) {
+ // draw shadow as a thick and thin line with transparency
+ ctx.lineWidth = sw;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ // position shadow at angle from the mid of line
+ var angle = Math.PI / 18;
+ plotLine(series.datapoints, Math.sin(angle) * (lw / 2 + sw / 2), Math.cos(angle) * (lw / 2 + sw / 2), series.xaxis, series.yaxis);
+ ctx.lineWidth = sw / 2;
+ plotLine(series.datapoints, Math.sin(angle) * (lw / 2 + sw / 4), Math.cos(angle) * (lw / 2 + sw / 4), series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ plotLineArea(series.datapoints, series.xaxis, series.yaxis);
+ }
+
+ if (lw > 0)
+ plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawSeriesPoints(series) {
+ function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ var x = points[i], y = points[i + 1];
+ if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ continue;
+
+ ctx.beginPath();
+ x = axisx.p2c(x);
+ y = axisy.p2c(y) + offset;
+ if (symbol == "circle")
+ ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
+ else
+ symbol(ctx, x, y, radius, shadow);
+ ctx.closePath();
+
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ ctx.fill();
+ }
+ ctx.stroke();
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ var lw = series.points.lineWidth,
+ sw = series.shadowSize,
+ radius = series.points.radius,
+ symbol = series.points.symbol;
+
+ // If the user sets the line width to 0, we change it to a very
+ // small value. A line width of 0 seems to force the default of 1.
+ // Doing the conditional here allows the shadow setting to still be
+ // optional even with a lineWidth of 0.
+
+ if (lw == 0)
+ lw = 0.0001;
+
+ if (lw > 0 && sw > 0) {
+ // draw shadow in two steps
+ var w = sw / 2;
+ ctx.lineWidth = w;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ plotPoints(series.datapoints, radius, null, w + w / 2, true,
+ series.xaxis, series.yaxis, symbol);
+
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
+ plotPoints(series.datapoints, radius, null, w / 2, true,
+ series.xaxis, series.yaxis, symbol);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ plotPoints(series.datapoints, radius,
+ getFillStyle(series.points, series.color), 0, false,
+ series.xaxis, series.yaxis, symbol);
+ ctx.restore();
+ }
+
+ function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
+ var left, right, bottom, top,
+ drawLeft, drawRight, drawTop, drawBottom,
+ tmp;
+
+ // in horizontal mode, we start the bar from the left
+ // instead of from the bottom so it appears to be
+ // horizontal rather than vertical
+ if (horizontal) {
+ drawBottom = drawRight = drawTop = true;
+ drawLeft = false;
+ left = b;
+ right = x;
+ top = y + barLeft;
+ bottom = y + barRight;
+
+ // account for negative bars
+ if (right < left) {
+ tmp = right;
+ right = left;
+ left = tmp;
+ drawLeft = true;
+ drawRight = false;
+ }
+ }
+ else {
+ drawLeft = drawRight = drawTop = true;
+ drawBottom = false;
+ left = x + barLeft;
+ right = x + barRight;
+ bottom = b;
+ top = y;
+
+ // account for negative bars
+ if (top < bottom) {
+ tmp = top;
+ top = bottom;
+ bottom = tmp;
+ drawBottom = true;
+ drawTop = false;
+ }
+ }
+
+ // clip
+ if (right < axisx.min || left > axisx.max ||
+ top < axisy.min || bottom > axisy.max)
+ return;
+
+ if (left < axisx.min) {
+ left = axisx.min;
+ drawLeft = false;
+ }
+
+ if (right > axisx.max) {
+ right = axisx.max;
+ drawRight = false;
+ }
+
+ if (bottom < axisy.min) {
+ bottom = axisy.min;
+ drawBottom = false;
+ }
+
+ if (top > axisy.max) {
+ top = axisy.max;
+ drawTop = false;
+ }
+
+ left = axisx.p2c(left);
+ bottom = axisy.p2c(bottom);
+ right = axisx.p2c(right);
+ top = axisy.p2c(top);
+
+ // fill the bar
+ if (fillStyleCallback) {
+ c.fillStyle = fillStyleCallback(bottom, top);
+ c.fillRect(left, top, right - left, bottom - top)
+ }
+
+ // draw outline
+ if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
+ c.beginPath();
+
+ // FIXME: inline moveTo is buggy with excanvas
+ c.moveTo(left, bottom);
+ if (drawLeft)
+ c.lineTo(left, top);
+ else
+ c.moveTo(left, top);
+ if (drawTop)
+ c.lineTo(right, top);
+ else
+ c.moveTo(right, top);
+ if (drawRight)
+ c.lineTo(right, bottom);
+ else
+ c.moveTo(right, bottom);
+ if (drawBottom)
+ c.lineTo(left, bottom);
+ else
+ c.moveTo(left, bottom);
+ c.stroke();
+ }
+ }
+
+ function drawSeriesBars(series) {
+ function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ if (points[i] == null)
+ continue;
+ drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // FIXME: figure out a way to add shadows (for instance along the right edge)
+ ctx.lineWidth = series.bars.lineWidth;
+ ctx.strokeStyle = series.color;
+
+ var barLeft;
+
+ switch (series.bars.align) {
+ case "left":
+ barLeft = 0;
+ break;
+ case "right":
+ barLeft = -series.bars.barWidth;
+ break;
+ default:
+ barLeft = -series.bars.barWidth / 2;
+ }
+
+ var fillStyleCallback = series.bars.fill ? function (bottom, top) {
+ return getFillStyle(series.bars, series.color, bottom, top);
+ } : null;
+ plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function getFillStyle(filloptions, seriesColor, bottom, top) {
+ var fill = filloptions.fill;
+ if (!fill)
+ return null;
+
+ if (filloptions.fillColor)
+ return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
+
+ var c = $.color.parse(seriesColor);
+ c.a = typeof fill == "number" ? fill : 0.4;
+ c.normalize();
+ return c.toString();
+ }
+
+ function insertLegend() {
+
+ if (options.legend.container != null) {
+ $(options.legend.container).html("");
+ } else {
+ placeholder.find(".legend").remove();
+ }
+
+ if (!options.legend.show) {
+ return;
+ }
+
+ var fragments = [], entries = [], rowStarted = false,
+ lf = options.legend.labelFormatter, s, label;
+
+ // Build a list of legend entries, with each having a label and a color
+
+ for (var i = 0; i < series.length; ++i) {
+ s = series[i];
+ if (s.label) {
+ label = lf ? lf(s.label, s) : s.label;
+ if (label) {
+ entries.push({
+ label: label,
+ color: s.color
+ });
+ }
+ }
+ }
+
+ // Sort the legend using either the default or a custom comparator
+
+ if (options.legend.sorted) {
+ if ($.isFunction(options.legend.sorted)) {
+ entries.sort(options.legend.sorted);
+ } else if (options.legend.sorted == "reverse") {
+ entries.reverse();
+ } else {
+ var ascending = options.legend.sorted != "descending";
+ entries.sort(function (a, b) {
+ return a.label == b.label ? 0 : (
+ (a.label < b.label) != ascending ? 1 : -1 // Logical XOR
+ );
+ });
+ }
+ }
+
+ // Generate markup for the list of entries, in their final order
+
+ for (var i = 0; i < entries.length; ++i) {
+
+ var entry = entries[i];
+
+ if (i % options.legend.noColumns == 0) {
+ if (rowStarted)
+ fragments.push('');
+ fragments.push('');
+ rowStarted = true;
+ }
+
+ fragments.push(
+ ' ' +
+ '' + entry.label + ' '
+ );
+ }
+
+ if (rowStarted)
+ fragments.push(' ');
+
+ if (fragments.length == 0)
+ return;
+
+ var table = '' + fragments.join("") + '
';
+ if (options.legend.container != null)
+ $(options.legend.container).html(table);
+ else {
+ var pos = "",
+ p = options.legend.position,
+ m = options.legend.margin;
+ if (m[0] == null)
+ m = [m, m];
+ if (p.charAt(0) == "n")
+ pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
+ else if (p.charAt(0) == "s")
+ pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
+ if (p.charAt(1) == "e")
+ pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
+ else if (p.charAt(1) == "w")
+ pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
+ var legend = $('' + table.replace('style="', 'style="position:absolute;' + pos + ';') + '
').appendTo(placeholder);
+ if (options.legend.backgroundOpacity != 0.0) {
+ // put in the transparent background
+ // separately to avoid blended labels and
+ // label boxes
+ var c = options.legend.backgroundColor;
+ if (c == null) {
+ c = options.grid.backgroundColor;
+ if (c && typeof c == "string")
+ c = $.color.parse(c);
+ else
+ c = $.color.extract(legend, 'background-color');
+ c.a = 1;
+ c = c.toString();
+ }
+ var div = legend.children();
+ $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
+ }
+ }
+ }
+
+
+ // interactive features
+
+ var highlights = [],
+ redrawTimeout = null;
+
+ // returns the data item the mouse is over, or null if none is found
+ function findNearbyItem(mouseX, mouseY, seriesFilter) {
+ var maxDistance = options.grid.mouseActiveRadius,
+ smallestDistance = maxDistance * maxDistance + 1,
+ item = null, foundPoint = false, i, j, ps;
+
+ for (i = series.length - 1; i >= 0; --i) {
+ if (!seriesFilter(series[i]))
+ continue;
+
+ var s = series[i],
+ axisx = s.xaxis,
+ axisy = s.yaxis,
+ points = s.datapoints.points,
+ mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+ my = axisy.c2p(mouseY),
+ maxx = maxDistance / axisx.scale,
+ maxy = maxDistance / axisy.scale;
+
+ ps = s.datapoints.pointsize;
+ // with inverse transforms, we can't use the maxx/maxy
+ // optimization, sadly
+ if (axisx.options.inverseTransform)
+ maxx = Number.MAX_VALUE;
+ if (axisy.options.inverseTransform)
+ maxy = Number.MAX_VALUE;
+
+ if (s.lines.show || s.points.show) {
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1];
+ if (x == null)
+ continue;
+
+ // For points and lines, the cursor must be within a
+ // certain distance to the data point
+ if (x - mx > maxx || x - mx < -maxx ||
+ y - my > maxy || y - my < -maxy)
+ continue;
+
+ // We have to calculate distances in pixels, not in
+ // data units, because the scales of the axes may be different
+ var dx = Math.abs(axisx.p2c(x) - mouseX),
+ dy = Math.abs(axisy.p2c(y) - mouseY),
+ dist = dx * dx + dy * dy; // we save the sqrt
+
+ // use <= to ensure last point takes precedence
+ // (last generally means on top of)
+ if (dist < smallestDistance) {
+ smallestDistance = dist;
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (s.bars.show && !item) { // no other point can be nearby
+
+ var barLeft, barRight;
+
+ switch (s.bars.align) {
+ case "left":
+ barLeft = 0;
+ break;
+ case "right":
+ barLeft = -s.bars.barWidth;
+ break;
+ default:
+ barLeft = -s.bars.barWidth / 2;
+ }
+
+ barRight = barLeft + s.bars.barWidth;
+
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1], b = points[j + 2];
+ if (x == null)
+ continue;
+
+ // for a bar graph, the cursor must be inside the bar
+ if (series[i].bars.horizontal ?
+ (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
+ my >= y + barLeft && my <= y + barRight) :
+ (mx >= x + barLeft && mx <= x + barRight &&
+ my >= Math.min(b, y) && my <= Math.max(b, y)))
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (item) {
+ i = item[0];
+ j = item[1];
+ ps = series[i].datapoints.pointsize;
+
+ return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
+ dataIndex: j,
+ series: series[i],
+ seriesIndex: i };
+ }
+
+ return null;
+ }
+
+ function onMouseMove(e) {
+ if (options.grid.hoverable)
+ triggerClickHoverEvent("plothover", e,
+ function (s) {
+ return s["hoverable"] != false;
+ });
+ }
+
+ function onMouseLeave(e) {
+ if (options.grid.hoverable)
+ triggerClickHoverEvent("plothover", e,
+ function (s) {
+ return false;
+ });
+ }
+
+ function onClick(e) {
+ triggerClickHoverEvent("plotclick", e,
+ function (s) {
+ return s["clickable"] != false;
+ });
+ }
+
+ // trigger click or hover event (they send the same parameters
+ // so we share their code)
+ function triggerClickHoverEvent(eventname, event, seriesFilter) {
+ var offset = eventHolder.offset(),
+ canvasX = event.pageX - offset.left - plotOffset.left,
+ canvasY = event.pageY - offset.top - plotOffset.top,
+ pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
+
+ pos.pageX = event.pageX;
+ pos.pageY = event.pageY;
+
+ var item = findNearbyItem(canvasX, canvasY, seriesFilter);
+
+ if (item) {
+ // fill in mouse pos for any listeners out there
+ item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
+ item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
+ }
+
+ if (options.grid.autoHighlight) {
+ // clear auto-highlights
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.auto == eventname && !(item && h.series == item.series &&
+ h.point[0] == item.datapoint[0] &&
+ h.point[1] == item.datapoint[1]))
+ unhighlight(h.series, h.point);
+ }
+
+ if (item)
+ highlight(item.series, item.datapoint, eventname);
+ }
+
+ placeholder.trigger(eventname, [ pos, item ]);
+ }
+
+ function triggerRedrawOverlay() {
+ var t = options.interaction.redrawOverlayInterval;
+ if (t == -1) { // skip event queue
+ drawOverlay();
+ return;
+ }
+
+ if (!redrawTimeout)
+ redrawTimeout = setTimeout(drawOverlay, t);
+ }
+
+ function drawOverlay() {
+ redrawTimeout = null;
+
+ // draw highlights
+ octx.save();
+ overlay.clear();
+ octx.translate(plotOffset.left, plotOffset.top);
+
+ var i, hi;
+ for (i = 0; i < highlights.length; ++i) {
+ hi = highlights[i];
+
+ if (hi.series.bars.show)
+ drawBarHighlight(hi.series, hi.point);
+ else
+ drawPointHighlight(hi.series, hi.point);
+ }
+ octx.restore();
+
+ executeHooks(hooks.drawOverlay, [octx]);
+ }
+
+ function highlight(s, point, auto) {
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number") {
+ var ps = s.datapoints.pointsize;
+ point = s.datapoints.points.slice(ps * point, ps * (point + 1));
+ }
+
+ var i = indexOfHighlight(s, point);
+ if (i == -1) {
+ highlights.push({ series: s, point: point, auto: auto });
+
+ triggerRedrawOverlay();
+ }
+ else if (!auto)
+ highlights[i].auto = false;
+ }
+
+ function unhighlight(s, point) {
+ if (s == null && point == null) {
+ highlights = [];
+ triggerRedrawOverlay();
+ return;
+ }
+
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number") {
+ var ps = s.datapoints.pointsize;
+ point = s.datapoints.points.slice(ps * point, ps * (point + 1));
+ }
+
+ var i = indexOfHighlight(s, point);
+ if (i != -1) {
+ highlights.splice(i, 1);
+
+ triggerRedrawOverlay();
+ }
+ }
+
+ function indexOfHighlight(s, p) {
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.series == s && h.point[0] == p[0]
+ && h.point[1] == p[1])
+ return i;
+ }
+ return -1;
+ }
+
+ function drawPointHighlight(series, point) {
+ var x = point[0], y = point[1],
+ axisx = series.xaxis, axisy = series.yaxis,
+ highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
+
+ if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ return;
+
+ var pointRadius = series.points.radius + series.points.lineWidth / 2;
+ octx.lineWidth = pointRadius;
+ octx.strokeStyle = highlightColor;
+ var radius = 1.5 * pointRadius;
+ x = axisx.p2c(x);
+ y = axisy.p2c(y);
+
+ octx.beginPath();
+ if (series.points.symbol == "circle")
+ octx.arc(x, y, radius, 0, 2 * Math.PI, false);
+ else
+ series.points.symbol(octx, x, y, radius, false);
+ octx.closePath();
+ octx.stroke();
+ }
+
+ function drawBarHighlight(series, point) {
+ var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
+ fillStyle = highlightColor,
+ barLeft;
+
+ switch (series.bars.align) {
+ case "left":
+ barLeft = 0;
+ break;
+ case "right":
+ barLeft = -series.bars.barWidth;
+ break;
+ default:
+ barLeft = -series.bars.barWidth / 2;
+ }
+
+ octx.lineWidth = series.bars.lineWidth;
+ octx.strokeStyle = highlightColor;
+
+ drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
+ function () {
+ return fillStyle;
+ }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
+ }
+
+ function getColorOrGradient(spec, bottom, top, defaultColor) {
+ if (typeof spec == "string")
+ return spec;
+ else {
+ // assume this is a gradient spec; IE currently only
+ // supports a simple vertical gradient properly, so that's
+ // what we support too
+ var gradient = ctx.createLinearGradient(0, top, 0, bottom);
+
+ for (var i = 0, l = spec.colors.length; i < l; ++i) {
+ var c = spec.colors[i];
+ if (typeof c != "string") {
+ var co = $.color.parse(defaultColor);
+ if (c.brightness != null)
+ co = co.scale('rgb', c.brightness);
+ if (c.opacity != null)
+ co.a *= c.opacity;
+ c = co.toString();
+ }
+ gradient.addColorStop(i / (l - 1), c);
+ }
+
+ return gradient;
+ }
+ }
+ }
+
+ // Add the plot function to the top level of the jQuery object
+
+ $.plot = function (placeholder, data, options) {
+ //var t0 = new Date();
+ var plot = new Plot($(placeholder), data, options, $.plot.plugins);
+ //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
+ return plot;
+ };
+
+ $.plot.version = "0.8.3";
+
+ $.plot.plugins = [];
+
+ // Also add the plot function as a chainable property
+
+ $.fn.plot = function (data, options) {
+ return this.each(function () {
+ $.plot(this, data, options);
+ });
+ };
+
+ // round to nearby lower multiple of base
+ function floorInBase(n, base) {
+ return base * Math.floor(n / base);
+ }
+
+})(jQuery);
diff --git a/src/main/resources/webapp/js/jquery.flot.pie.js b/src/main/resources/webapp/js/jquery.flot.pie.js
new file mode 100755
index 0000000..c421c51
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.flot.pie.js
@@ -0,0 +1,831 @@
+/* Flot plugin for rendering pie charts.
+
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
+ Licensed under the MIT license.
+
+ The plugin assumes that each series has a single data value, and that each
+ value is a positive integer or zero. Negative numbers don't make sense for a
+ pie chart, and have unpredictable results. The values do NOT need to be
+ passed in as percentages; the plugin will calculate the total and per-slice
+ percentages internally.
+
+ * Created by Brian Medendorp
+
+ * Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
+
+ The plugin supports these options:
+
+ series: {
+ pie: {
+ show: true/false
+ radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
+ innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
+ startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
+ tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
+ offset: {
+ top: integer value to move the pie up or down
+ left: integer value to move the pie left or right, or 'auto'
+ },
+ stroke: {
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
+ width: integer pixel width of the stroke
+ },
+ label: {
+ show: true/false, or 'auto'
+ formatter: a user-defined function that modifies the text/style of the label text
+ radius: 0-1 for percentage of fullsize, or a specified pixel length
+ background: {
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
+ opacity: 0-1
+ },
+ threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
+ },
+ combine: {
+ threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
+ label: any text value of what the combined slice should be labeled
+ }
+ highlight: {
+ opacity: 0-1
+ }
+ }
+ }
+
+ More detail and specific examples can be found in the included HTML file.
+
+ */
+
+(function ($) {
+
+ // Maximum redraw attempts when fitting labels within the plot
+
+ var REDRAW_ATTEMPTS = 10;
+
+ // Factor by which to shrink the pie when fitting labels within the plot
+
+ var REDRAW_SHRINK = 0.95;
+
+ function init(plot) {
+
+ var canvas = null,
+ target = null,
+ options = null,
+ maxRadius = null,
+ centerLeft = null,
+ centerTop = null,
+ processed = false,
+ ctx = null;
+
+ // interactive variables
+
+ var highlights = [];
+
+ // add hook to determine if pie plugin in enabled, and then perform necessary operations
+
+ plot.hooks.processOptions.push(function (plot, options) {
+ if (options.series.pie.show) {
+
+ options.grid.show = false;
+
+ // set labels.show
+
+ if (options.series.pie.label.show == "auto") {
+ if (options.legend.show) {
+ options.series.pie.label.show = false;
+ } else {
+ options.series.pie.label.show = true;
+ }
+ }
+
+ // set radius
+
+ if (options.series.pie.radius == "auto") {
+ if (options.series.pie.label.show) {
+ options.series.pie.radius = 3 / 4;
+ } else {
+ options.series.pie.radius = 1;
+ }
+ }
+
+ // ensure sane tilt
+
+ if (options.series.pie.tilt > 1) {
+ options.series.pie.tilt = 1;
+ } else if (options.series.pie.tilt < 0) {
+ options.series.pie.tilt = 0;
+ }
+ }
+ });
+
+ plot.hooks.bindEvents.push(function (plot, eventHolder) {
+ var options = plot.getOptions();
+ if (options.series.pie.show) {
+ if (options.grid.hoverable) {
+ eventHolder.unbind("mousemove").mousemove(onMouseMove);
+ }
+ if (options.grid.clickable) {
+ eventHolder.unbind("click").click(onClick);
+ }
+ }
+ });
+
+ plot.hooks.processDatapoints.push(function (plot, series, data, datapoints) {
+ var options = plot.getOptions();
+ if (options.series.pie.show) {
+ processDatapoints(plot, series, data, datapoints);
+ }
+ });
+
+ plot.hooks.drawOverlay.push(function (plot, octx) {
+ var options = plot.getOptions();
+ if (options.series.pie.show) {
+ drawOverlay(plot, octx);
+ }
+ });
+
+ plot.hooks.draw.push(function (plot, newCtx) {
+ var options = plot.getOptions();
+ if (options.series.pie.show) {
+ draw(plot, newCtx);
+ }
+ });
+
+ function processDatapoints(plot, series, datapoints) {
+ if (!processed) {
+ processed = true;
+ canvas = plot.getCanvas();
+ target = $(canvas).parent();
+ options = plot.getOptions();
+ plot.setData(combine(plot.getData()));
+ }
+ }
+
+ function combine(data) {
+
+ var total = 0,
+ combined = 0,
+ numCombined = 0,
+ color = options.series.pie.combine.color,
+ newdata = [];
+
+ // Fix up the raw data from Flot, ensuring the data is numeric
+
+ for (var i = 0; i < data.length; ++i) {
+
+ var value = data[i].data;
+
+ // If the data is an array, we'll assume that it's a standard
+ // Flot x-y pair, and are concerned only with the second value.
+
+ // Note how we use the original array, rather than creating a
+ // new one; this is more efficient and preserves any extra data
+ // that the user may have stored in higher indexes.
+
+ if ($.isArray(value) && value.length == 1) {
+ value = value[0];
+ }
+
+ if ($.isArray(value)) {
+ // Equivalent to $.isNumeric() but compatible with jQuery < 1.7
+ if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
+ value[1] = +value[1];
+ } else {
+ value[1] = 0;
+ }
+ } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
+ value = [1, +value];
+ } else {
+ value = [1, 0];
+ }
+
+ data[i].data = [value];
+ }
+
+ // Sum up all the slices, so we can calculate percentages for each
+
+ for (var i = 0; i < data.length; ++i) {
+ total += data[i].data[0][1];
+ }
+
+ // Count the number of slices with percentages below the combine
+ // threshold; if it turns out to be just one, we won't combine.
+
+ for (var i = 0; i < data.length; ++i) {
+ var value = data[i].data[0][1];
+ if (value / total <= options.series.pie.combine.threshold) {
+ combined += value;
+ numCombined++;
+ if (!color) {
+ color = data[i].color;
+ }
+ }
+ }
+
+ for (var i = 0; i < data.length; ++i) {
+ var value = data[i].data[0][1];
+ if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
+ newdata.push(
+ $.extend(data[i], { /* extend to allow keeping all other original data values
+ and using them e.g. in labelFormatter. */
+ data: [
+ [1, value]
+ ],
+ color: data[i].color,
+ label: data[i].label,
+ angle: value * Math.PI * 2 / total,
+ percent: value / (total / 100)
+ })
+ );
+ }
+ }
+
+ if (numCombined > 1) {
+ newdata.push({
+ data: [
+ [1, combined]
+ ],
+ color: color,
+ label: options.series.pie.combine.label,
+ angle: combined * Math.PI * 2 / total,
+ percent: combined / (total / 100)
+ });
+ }
+
+ return newdata;
+ }
+
+ function draw(plot, newCtx) {
+
+ if (!target) {
+ return; // if no series were passed
+ }
+
+ var canvasWidth = plot.getPlaceholder().width(),
+ canvasHeight = plot.getPlaceholder().height(),
+ legendWidth = target.children().filter(".legend").children().width() || 0;
+
+ ctx = newCtx;
+
+ // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
+
+ // When combining smaller slices into an 'other' slice, we need to
+ // add a new series. Since Flot gives plugins no way to modify the
+ // list of series, the pie plugin uses a hack where the first call
+ // to processDatapoints results in a call to setData with the new
+ // list of series, then subsequent processDatapoints do nothing.
+
+ // The plugin-global 'processed' flag is used to control this hack;
+ // it starts out false, and is set to true after the first call to
+ // processDatapoints.
+
+ // Unfortunately this turns future setData calls into no-ops; they
+ // call processDatapoints, the flag is true, and nothing happens.
+
+ // To fix this we'll set the flag back to false here in draw, when
+ // all series have been processed, so the next sequence of calls to
+ // processDatapoints once again starts out with a slice-combine.
+ // This is really a hack; in 0.9 we need to give plugins a proper
+ // way to modify series before any processing begins.
+
+ processed = false;
+
+ // calculate maximum radius and center point
+
+ maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
+ centerTop = canvasHeight / 2 + options.series.pie.offset.top;
+ centerLeft = canvasWidth / 2;
+
+ if (options.series.pie.offset.left == "auto") {
+ if (options.legend.position.match("w")) {
+ centerLeft += legendWidth / 2;
+ } else {
+ centerLeft -= legendWidth / 2;
+ }
+ if (centerLeft < maxRadius) {
+ centerLeft = maxRadius;
+ } else if (centerLeft > canvasWidth - maxRadius) {
+ centerLeft = canvasWidth - maxRadius;
+ }
+ } else {
+ centerLeft += options.series.pie.offset.left;
+ }
+
+ var slices = plot.getData(),
+ attempts = 0;
+
+ // Keep shrinking the pie's radius until drawPie returns true,
+ // indicating that all the labels fit, or we try too many times.
+
+ do {
+ if (attempts > 0) {
+ maxRadius *= REDRAW_SHRINK;
+ }
+ attempts += 1;
+ clear();
+ if (options.series.pie.tilt <= 0.8) {
+ drawShadow();
+ }
+ } while (!drawPie() && attempts < REDRAW_ATTEMPTS)
+
+ if (attempts >= REDRAW_ATTEMPTS) {
+ clear();
+ target.prepend("Could not draw pie with labels contained inside canvas
");
+ }
+
+ if (plot.setSeries && plot.insertLegend) {
+ plot.setSeries(slices);
+ plot.insertLegend();
+ }
+
+ // we're actually done at this point, just defining internal functions at this point
+
+ function clear() {
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+ target.children().filter(".pieLabel, .pieLabelBackground").remove();
+ }
+
+ function drawShadow() {
+
+ var shadowLeft = options.series.pie.shadow.left;
+ var shadowTop = options.series.pie.shadow.top;
+ var edge = 10;
+ var alpha = options.series.pie.shadow.alpha;
+ var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+ if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
+ return; // shadow would be outside canvas, so don't draw it
+ }
+
+ ctx.save();
+ ctx.translate(shadowLeft, shadowTop);
+ ctx.globalAlpha = alpha;
+ ctx.fillStyle = "#000";
+
+ // center and rotate to starting position
+
+ ctx.translate(centerLeft, centerTop);
+ ctx.scale(1, options.series.pie.tilt);
+
+ //radius -= edge;
+
+ for (var i = 1; i <= edge; i++) {
+ ctx.beginPath();
+ ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
+ ctx.fill();
+ radius -= i;
+ }
+
+ ctx.restore();
+ }
+
+ function drawPie() {
+
+ var startAngle = Math.PI * options.series.pie.startAngle;
+ var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+ // center and rotate to starting position
+
+ ctx.save();
+ ctx.translate(centerLeft, centerTop);
+ ctx.scale(1, options.series.pie.tilt);
+ //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
+
+ // draw slices
+
+ ctx.save();
+ var currentAngle = startAngle;
+ for (var i = 0; i < slices.length; ++i) {
+ slices[i].startAngle = currentAngle;
+ drawSlice(slices[i].angle, slices[i].color, true);
+ }
+ ctx.restore();
+
+ // draw slice outlines
+
+ if (options.series.pie.stroke.width > 0) {
+ ctx.save();
+ ctx.lineWidth = options.series.pie.stroke.width;
+ currentAngle = startAngle;
+ for (var i = 0; i < slices.length; ++i) {
+ drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
+ }
+ ctx.restore();
+ }
+
+ // draw donut hole
+
+ drawDonutHole(ctx);
+
+ ctx.restore();
+
+ // Draw the labels, returning true if they fit within the plot
+
+ if (options.series.pie.label.show) {
+ return drawLabels();
+ } else return true;
+
+ function drawSlice(angle, color, fill) {
+
+ if (angle <= 0 || isNaN(angle)) {
+ return;
+ }
+
+ if (fill) {
+ ctx.fillStyle = color;
+ } else {
+ ctx.strokeStyle = color;
+ ctx.lineJoin = "round";
+ }
+
+ ctx.beginPath();
+ if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
+ ctx.moveTo(0, 0); // Center of the pie
+ }
+
+ //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
+ ctx.arc(0, 0, radius, currentAngle, currentAngle + angle / 2, false);
+ ctx.arc(0, 0, radius, currentAngle + angle / 2, currentAngle + angle, false);
+ ctx.closePath();
+ //ctx.rotate(angle); // This doesn't work properly in Opera
+ currentAngle += angle;
+
+ if (fill) {
+ ctx.fill();
+ } else {
+ ctx.stroke();
+ }
+ }
+
+ function drawLabels() {
+
+ var currentAngle = startAngle;
+ var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
+
+ for (var i = 0; i < slices.length; ++i) {
+ if (slices[i].percent >= options.series.pie.label.threshold * 100) {
+ if (!drawLabel(slices[i], currentAngle, i)) {
+ return false;
+ }
+ }
+ currentAngle += slices[i].angle;
+ }
+
+ return true;
+
+ function drawLabel(slice, startAngle, index) {
+
+ if (slice.data[0][1] == 0) {
+ return true;
+ }
+
+ // format label text
+
+ var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
+
+ if (lf) {
+ text = lf(slice.label, slice);
+ } else {
+ text = slice.label;
+ }
+
+ if (plf) {
+ text = plf(text, slice);
+ }
+
+ var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
+ var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
+ var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
+
+ var html = "" + text + " ";
+ target.append(html);
+
+ var label = target.children("#pieLabel" + index);
+ var labelTop = (y - label.height() / 2);
+ var labelLeft = (x - label.width() / 2);
+
+ label.css("top", labelTop);
+ label.css("left", labelLeft);
+
+ // check to make sure that the label is not outside the canvas
+
+ if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
+ return false;
+ }
+
+ if (options.series.pie.label.background.opacity != 0) {
+
+ // put in the transparent background separately to avoid blended labels and label boxes
+
+ var c = options.series.pie.label.background.color;
+
+ if (c == null) {
+ c = slice.color;
+ }
+
+ var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
+ $("
")
+ .css("opacity", options.series.pie.label.background.opacity)
+ .insertBefore(label);
+ }
+
+ return true;
+ } // end individual label function
+ } // end drawLabels function
+ } // end drawPie function
+ } // end draw function
+
+ // Placed here because it needs to be accessed from multiple locations
+
+ function drawDonutHole(layer) {
+ if (options.series.pie.innerRadius > 0) {
+
+ // subtract the center
+
+ layer.save();
+ var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
+ layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
+ layer.beginPath();
+ layer.fillStyle = options.series.pie.stroke.color;
+ layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
+ layer.fill();
+ layer.closePath();
+ layer.restore();
+
+ // add inner stroke
+
+ layer.save();
+ layer.beginPath();
+ layer.strokeStyle = options.series.pie.stroke.color;
+ layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
+ layer.stroke();
+ layer.closePath();
+ layer.restore();
+
+ // TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
+ }
+ }
+
+ //-- Additional Interactive related functions --
+
+ function isPointInPoly(poly, pt) {
+ for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
+ ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1] < poly[i][1]))
+ && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
+ && (c = !c);
+ return c;
+ }
+
+ function findNearbySlice(mouseX, mouseY) {
+
+ var slices = plot.getData(),
+ options = plot.getOptions(),
+ radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
+ x, y;
+
+ for (var i = 0; i < slices.length; ++i) {
+
+ var s = slices[i];
+
+ if (s.pie.show) {
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(0, 0); // Center of the pie
+ //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
+ ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
+ ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
+ ctx.closePath();
+ x = mouseX - centerLeft;
+ y = mouseY - centerTop;
+
+ if (ctx.isPointInPath) {
+ if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
+ ctx.restore();
+ return {
+ datapoint: [s.percent, s.data],
+ dataIndex: 0,
+ series: s,
+ seriesIndex: i
+ };
+ }
+ } else {
+
+ // excanvas for IE doesn;t support isPointInPath, this is a workaround.
+
+ var p1X = radius * Math.cos(s.startAngle),
+ p1Y = radius * Math.sin(s.startAngle),
+ p2X = radius * Math.cos(s.startAngle + s.angle / 4),
+ p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
+ p3X = radius * Math.cos(s.startAngle + s.angle / 2),
+ p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
+ p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
+ p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
+ p5X = radius * Math.cos(s.startAngle + s.angle),
+ p5Y = radius * Math.sin(s.startAngle + s.angle),
+ arrPoly = [
+ [0, 0],
+ [p1X, p1Y],
+ [p2X, p2Y],
+ [p3X, p3Y],
+ [p4X, p4Y],
+ [p5X, p5Y]
+ ],
+ arrPoint = [x, y];
+
+ // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
+
+ if (isPointInPoly(arrPoly, arrPoint)) {
+ ctx.restore();
+ return {
+ datapoint: [s.percent, s.data],
+ dataIndex: 0,
+ series: s,
+ seriesIndex: i
+ };
+ }
+ }
+
+ ctx.restore();
+ }
+ }
+
+ return null;
+ }
+
+ function onMouseMove(e) {
+ triggerClickHoverEvent("plothover", e);
+ }
+
+ function onClick(e) {
+ triggerClickHoverEvent("plotclick", e);
+ }
+
+ // trigger click or hover event (they send the same parameters so we share their code)
+
+ function triggerClickHoverEvent(eventname, e) {
+
+ var offset = plot.offset();
+ var canvasX = parseInt(e.pageX - offset.left);
+ var canvasY = parseInt(e.pageY - offset.top);
+ var item = findNearbySlice(canvasX, canvasY);
+
+ if (options.grid.autoHighlight) {
+
+ // clear auto-highlights
+
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.auto == eventname && !(item && h.series == item.series)) {
+ unhighlight(h.series);
+ }
+ }
+ }
+
+ // highlight the slice
+
+ if (item) {
+ highlight(item.series, eventname);
+ }
+
+ // trigger any hover bind events
+
+ var pos = { pageX: e.pageX, pageY: e.pageY };
+ target.trigger(eventname, [pos, item]);
+ }
+
+ function highlight(s, auto) {
+ //if (typeof s == "number") {
+ // s = series[s];
+ //}
+
+ var i = indexOfHighlight(s);
+
+ if (i == -1) {
+ highlights.push({ series: s, auto: auto });
+ plot.triggerRedrawOverlay();
+ } else if (!auto) {
+ highlights[i].auto = false;
+ }
+ }
+
+ function unhighlight(s) {
+ if (s == null) {
+ highlights = [];
+ plot.triggerRedrawOverlay();
+ }
+
+ //if (typeof s == "number") {
+ // s = series[s];
+ //}
+
+ var i = indexOfHighlight(s);
+
+ if (i != -1) {
+ highlights.splice(i, 1);
+ plot.triggerRedrawOverlay();
+ }
+ }
+
+ function indexOfHighlight(s) {
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.series == s)
+ return i;
+ }
+ return -1;
+ }
+
+ function drawOverlay(plot, octx) {
+
+ var options = plot.getOptions();
+
+ var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+ octx.save();
+ octx.translate(centerLeft, centerTop);
+ octx.scale(1, options.series.pie.tilt);
+
+ for (var i = 0; i < highlights.length; ++i) {
+ drawHighlight(highlights[i].series);
+ }
+
+ drawDonutHole(octx);
+
+ octx.restore();
+
+ function drawHighlight(series) {
+
+ if (series.angle <= 0 || isNaN(series.angle)) {
+ return;
+ }
+
+ //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
+ octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
+ octx.beginPath();
+ if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
+ octx.moveTo(0, 0); // Center of the pie
+ }
+ octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
+ octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
+ octx.closePath();
+ octx.fill();
+ }
+ }
+ } // end init (plugin body)
+
+ // define pie specific options and their default values
+
+ var options = {
+ series: {
+ pie: {
+ show: false,
+ radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
+ innerRadius: 0, /* for donut */
+ startAngle: 3 / 2,
+ tilt: 1,
+ shadow: {
+ left: 5, // shadow left offset
+ top: 15, // shadow top offset
+ alpha: 0.02 // shadow alpha
+ },
+ offset: {
+ top: 0,
+ left: "auto"
+ },
+ stroke: {
+ color: "#fff",
+ width: 1
+ },
+ label: {
+ show: "auto",
+ formatter: function (label, slice) {
+ return "" + label + " " + Math.round(slice.percent) + "%
";
+ }, // formatter function
+ radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
+ background: {
+ color: null,
+ opacity: 0
+ },
+ threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
+ },
+ combine: {
+ threshold: -1, // percentage at which to combine little slices into one larger slice
+ color: null, // color to give the new slice (auto-generated if null)
+ label: "Other" // label to give the new slice
+ },
+ highlight: {
+ //color: "#fff", // will add this functionality once parseColor is available
+ opacity: 0.5
+ }
+ }
+ }
+ };
+
+ $.plot.plugins.push({
+ init: init,
+ options: options,
+ name: "pie",
+ version: "1.1"
+ });
+
+})(jQuery);
diff --git a/src/main/resources/webapp/js/jquery.flot.resize.js b/src/main/resources/webapp/js/jquery.flot.resize.js
new file mode 100755
index 0000000..adcda57
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.flot.resize.js
@@ -0,0 +1,159 @@
+/* Flot plugin for automatically redrawing plots as the placeholder resizes.
+
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
+ Licensed under the MIT license.
+
+ It works by listening for changes on the placeholder div (through the jQuery
+ resize event plugin) - if the size changes, it will redraw the plot.
+
+ There are no options. If you need to disable the plugin for some plots, you
+ can just fix the size of their placeholders.
+
+ */
+
+/* Inline dependency:
+ * jQuery resize event - v1.1 - 3/14/2010
+ * http://benalman.com/projects/jquery-resize-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function ($, e, t) {
+ "$:nomunge";
+ var i = [], n = $.resize = $.extend($.resize, {}), a, r = false, s = "setTimeout", u = "resize", m = u + "-special-event", o = "pendingDelay", l = "activeDelay", f = "throttleWindow";
+ n[o] = 200;
+ n[l] = 20;
+ n[f] = true;
+ $.event.special[u] = {setup: function () {
+ if (!n[f] && this[s]) {
+ return false
+ }
+ var e = $(this);
+ i.push(this);
+ e.data(m, {w: e.width(), h: e.height()});
+ if (i.length === 1) {
+ a = t;
+ h()
+ }
+ }, teardown: function () {
+ if (!n[f] && this[s]) {
+ return false
+ }
+ var e = $(this);
+ for (var t = i.length - 1; t >= 0; t--) {
+ if (i[t] == this) {
+ i.splice(t, 1);
+ break
+ }
+ }
+ e.removeData(m);
+ if (!i.length) {
+ if (r) {
+ cancelAnimationFrame(a)
+ } else {
+ clearTimeout(a)
+ }
+ a = null
+ }
+ }, add: function (e) {
+ if (!n[f] && this[s]) {
+ return false
+ }
+ var i;
+
+ function a(e, n, a) {
+ var r = $(this), s = r.data(m) || {};
+ s.w = n !== t ? n : r.width();
+ s.h = a !== t ? a : r.height();
+ i.apply(this, arguments)
+ }
+
+ if ($.isFunction(e)) {
+ i = e;
+ return a
+ } else {
+ i = e.handler;
+ e.handler = a
+ }
+ }};
+ function h(t) {
+ if (r === true) {
+ r = t || 1
+ }
+ for (var s = i.length - 1; s >= 0; s--) {
+ var l = $(i[s]);
+ if (l[0] == e || l.is(":visible")) {
+ var f = l.width(), c = l.height(), d = l.data(m);
+ if (d && (f !== d.w || c !== d.h)) {
+ l.trigger(u, [d.w = f, d.h = c]);
+ r = t || true
+ }
+ } else {
+ d = l.data(m);
+ d.w = 0;
+ d.h = 0
+ }
+ }
+ if (a !== null) {
+ if (r && (t == null || t - r < 1e3)) {
+ a = e.requestAnimationFrame(h)
+ } else {
+ a = setTimeout(h, n[o]);
+ r = false
+ }
+ }
+ }
+
+ if (!e.requestAnimationFrame) {
+ e.requestAnimationFrame = function () {
+ return e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (t, i) {
+ return e.setTimeout(function () {
+ t((new Date).getTime())
+ }, n[l])
+ }
+ }()
+ }
+ if (!e.cancelAnimationFrame) {
+ e.cancelAnimationFrame = function () {
+ return e.webkitCancelRequestAnimationFrame || e.mozCancelRequestAnimationFrame || e.oCancelRequestAnimationFrame || e.msCancelRequestAnimationFrame || clearTimeout
+ }()
+ }
+})(jQuery, this);
+
+(function ($) {
+ var options = { }; // no options
+
+ function init(plot) {
+ function onResize() {
+ var placeholder = plot.getPlaceholder();
+
+ // somebody might have hidden us and we can't plot
+ // when we don't have the dimensions
+ if (placeholder.width() == 0 || placeholder.height() == 0)
+ return;
+
+ plot.resize();
+ plot.setupGrid();
+ plot.draw();
+ }
+
+ function bindEvents(plot, eventHolder) {
+ plot.getPlaceholder().resize(onResize);
+ }
+
+ function shutdown(plot, eventHolder) {
+ plot.getPlaceholder().unbind("resize", onResize);
+ }
+
+ plot.hooks.bindEvents.push(bindEvents);
+ plot.hooks.shutdown.push(shutdown);
+ }
+
+ $.plot.plugins.push({
+ init: init,
+ options: options,
+ name: 'resize',
+ version: '1.0'
+ });
+})(jQuery);
diff --git a/src/main/resources/webapp/js/jquery.flot.time.js b/src/main/resources/webapp/js/jquery.flot.time.js
new file mode 100755
index 0000000..76d4b10
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.flot.time.js
@@ -0,0 +1,482 @@
+/* Pretty handling of time axes.
+
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
+ Licensed under the MIT license.
+
+ Set axis.mode to "time" to enable. See the section "Time series data" in
+ API.txt for details.
+
+ */
+
+(function ($) {
+
+ var options = {
+ xaxis: {
+ timezone: null, // "browser" for local to the client or timezone for timezone-js
+ timeformat: null, // format string to use
+ twelveHourClock: false, // 12 or 24 time in time mode
+ monthNames: null // list of names of months
+ }
+ };
+
+ // round to nearby lower multiple of base
+
+ function floorInBase(n, base) {
+ return base * Math.floor(n / base);
+ }
+
+ // Returns a string with the date d formatted according to fmt.
+ // A subset of the Open Group's strftime format is supported.
+
+ function formatDate(d, fmt, monthNames, dayNames) {
+
+ if (typeof d.strftime == "function") {
+ return d.strftime(fmt);
+ }
+
+ var leftPad = function (n, pad) {
+ n = "" + n;
+ pad = "" + (pad == null ? "0" : pad);
+ return n.length == 1 ? pad + n : n;
+ };
+
+ var r = [];
+ var escape = false;
+ var hours = d.getHours();
+ var isAM = hours < 12;
+
+ if (monthNames == null) {
+ monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+ }
+
+ if (dayNames == null) {
+ dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+ }
+
+ var hours12;
+
+ if (hours > 12) {
+ hours12 = hours - 12;
+ } else if (hours == 0) {
+ hours12 = 12;
+ } else {
+ hours12 = hours;
+ }
+
+ for (var i = 0; i < fmt.length; ++i) {
+
+ var c = fmt.charAt(i);
+
+ if (escape) {
+ switch (c) {
+ case 'a':
+ c = "" + dayNames[d.getDay()];
+ break;
+ case 'b':
+ c = "" + monthNames[d.getMonth()];
+ break;
+ case 'd':
+ c = leftPad(d.getDate());
+ break;
+ case 'e':
+ c = leftPad(d.getDate(), " ");
+ break;
+ case 'h': // For back-compat with 0.7; remove in 1.0
+ case 'H':
+ c = leftPad(hours);
+ break;
+ case 'I':
+ c = leftPad(hours12);
+ break;
+ case 'l':
+ c = leftPad(hours12, " ");
+ break;
+ case 'm':
+ c = leftPad(d.getMonth() + 1);
+ break;
+ case 'M':
+ c = leftPad(d.getMinutes());
+ break;
+ // quarters not in Open Group's strftime specification
+ case 'q':
+ c = "" + (Math.floor(d.getMonth() / 3) + 1);
+ break;
+ case 'S':
+ c = leftPad(d.getSeconds());
+ break;
+ case 'y':
+ c = leftPad(d.getFullYear() % 100);
+ break;
+ case 'Y':
+ c = "" + d.getFullYear();
+ break;
+ case 'p':
+ c = (isAM) ? ("" + "am") : ("" + "pm");
+ break;
+ case 'P':
+ c = (isAM) ? ("" + "AM") : ("" + "PM");
+ break;
+ case 'w':
+ c = "" + d.getDay();
+ break;
+ }
+ r.push(c);
+ escape = false;
+ } else {
+ if (c == "%") {
+ escape = true;
+ } else {
+ r.push(c);
+ }
+ }
+ }
+
+ return r.join("");
+ }
+
+ // To have a consistent view of time-based data independent of which time
+ // zone the client happens to be in we need a date-like object independent
+ // of time zones. This is done through a wrapper that only calls the UTC
+ // versions of the accessor methods.
+
+ function makeUtcWrapper(d) {
+
+ function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
+ sourceObj[sourceMethod] = function () {
+ return targetObj[targetMethod].apply(targetObj, arguments);
+ };
+ };
+
+ var utc = {
+ date: d
+ };
+
+ // support strftime, if found
+
+ if (d.strftime != undefined) {
+ addProxyMethod(utc, "strftime", d, "strftime");
+ }
+
+ addProxyMethod(utc, "getTime", d, "getTime");
+ addProxyMethod(utc, "setTime", d, "setTime");
+
+ var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
+
+ for (var p = 0; p < props.length; p++) {
+ addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
+ addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
+ }
+
+ return utc;
+ };
+
+ // select time zone strategy. This returns a date-like object tied to the
+ // desired timezone
+
+ function dateGenerator(ts, opts) {
+ if (opts.timezone == "browser") {
+ return new Date(ts);
+ } else if (!opts.timezone || opts.timezone == "utc") {
+ return makeUtcWrapper(new Date(ts));
+ } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
+ var d = new timezoneJS.Date();
+ // timezone-js is fickle, so be sure to set the time zone before
+ // setting the time.
+ d.setTimezone(opts.timezone);
+ d.setTime(ts);
+ return d;
+ } else {
+ return makeUtcWrapper(new Date(ts));
+ }
+ }
+
+ // map of app. size of time units in milliseconds
+
+ var timeUnitSize = {
+ "second": 1000,
+ "minute": 60 * 1000,
+ "hour": 60 * 60 * 1000,
+ "day": 24 * 60 * 60 * 1000,
+ "month": 30 * 24 * 60 * 60 * 1000,
+ "quarter": 3 * 30 * 24 * 60 * 60 * 1000,
+ "year": 365.2425 * 24 * 60 * 60 * 1000
+ };
+
+ // the allowed tick sizes, after 1 year we use
+ // an integer algorithm
+
+ var baseSpec = [
+ [1, "second"],
+ [2, "second"],
+ [5, "second"],
+ [10, "second"],
+ [30, "second"],
+ [1, "minute"],
+ [2, "minute"],
+ [5, "minute"],
+ [10, "minute"],
+ [30, "minute"],
+ [1, "hour"],
+ [2, "hour"],
+ [4, "hour"],
+ [8, "hour"],
+ [12, "hour"],
+ [1, "day"],
+ [2, "day"],
+ [3, "day"],
+ [0.25, "month"],
+ [0.5, "month"],
+ [1, "month"],
+ [2, "month"]
+ ];
+
+ // we don't know which variant(s) we'll need yet, but generating both is
+ // cheap
+
+ var specMonths = baseSpec.concat([
+ [3, "month"],
+ [6, "month"],
+ [1, "year"]
+ ]);
+ var specQuarters = baseSpec.concat([
+ [1, "quarter"],
+ [2, "quarter"],
+ [1, "year"]
+ ]);
+
+ function init(plot) {
+ plot.hooks.processOptions.push(function (plot, options) {
+ $.each(plot.getAxes(), function (axisName, axis) {
+
+ var opts = axis.options;
+
+ if (opts.mode == "time") {
+ axis.tickGenerator = function (axis) {
+
+ var ticks = [];
+ var d = dateGenerator(axis.min, opts);
+ var minSize = 0;
+
+ // make quarter use a possibility if quarters are
+ // mentioned in either of these options
+
+ var spec = (opts.tickSize && opts.tickSize[1] ===
+ "quarter") ||
+ (opts.minTickSize && opts.minTickSize[1] ===
+ "quarter") ? specQuarters : specMonths;
+
+ if (opts.minTickSize != null) {
+ if (typeof opts.tickSize == "number") {
+ minSize = opts.tickSize;
+ } else {
+ minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
+ }
+ }
+
+ for (var i = 0; i < spec.length - 1; ++i) {
+ if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+ + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
+ && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
+ break;
+ }
+ }
+
+ var size = spec[i][0];
+ var unit = spec[i][1];
+
+ // special-case the possibility of several years
+
+ if (unit == "year") {
+
+ // if given a minTickSize in years, just use it,
+ // ensuring that it's an integer
+
+ if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
+ size = Math.floor(opts.minTickSize[0]);
+ } else {
+
+ var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
+ var norm = (axis.delta / timeUnitSize.year) / magn;
+
+ if (norm < 1.5) {
+ size = 1;
+ } else if (norm < 3) {
+ size = 2;
+ } else if (norm < 7.5) {
+ size = 5;
+ } else {
+ size = 10;
+ }
+
+ size *= magn;
+ }
+
+ // minimum size for years is 1
+
+ if (size < 1) {
+ size = 1;
+ }
+ }
+
+ axis.tickSize = opts.tickSize || [size, unit];
+ var tickSize = axis.tickSize[0];
+ unit = axis.tickSize[1];
+
+ var step = tickSize * timeUnitSize[unit];
+
+ if (unit == "second") {
+ d.setSeconds(floorInBase(d.getSeconds(), tickSize));
+ } else if (unit == "minute") {
+ d.setMinutes(floorInBase(d.getMinutes(), tickSize));
+ } else if (unit == "hour") {
+ d.setHours(floorInBase(d.getHours(), tickSize));
+ } else if (unit == "month") {
+ d.setMonth(floorInBase(d.getMonth(), tickSize));
+ } else if (unit == "quarter") {
+ d.setMonth(3 * floorInBase(d.getMonth() / 3,
+ tickSize));
+ } else if (unit == "year") {
+ d.setFullYear(floorInBase(d.getFullYear(), tickSize));
+ }
+
+ // reset smaller components
+
+ d.setMilliseconds(0);
+
+ if (step >= timeUnitSize.minute) {
+ d.setSeconds(0);
+ }
+ if (step >= timeUnitSize.hour) {
+ d.setMinutes(0);
+ }
+ if (step >= timeUnitSize.day) {
+ d.setHours(0);
+ }
+ if (step >= timeUnitSize.day * 4) {
+ d.setDate(1);
+ }
+ if (step >= timeUnitSize.month * 2) {
+ d.setMonth(floorInBase(d.getMonth(), 3));
+ }
+ if (step >= timeUnitSize.quarter * 2) {
+ d.setMonth(floorInBase(d.getMonth(), 6));
+ }
+ if (step >= timeUnitSize.year) {
+ d.setMonth(0);
+ }
+
+ var carry = 0;
+ var v = Number.NaN;
+ var prev;
+
+ do {
+
+ prev = v;
+ v = d.getTime();
+ ticks.push(v);
+
+ if (unit == "month" || unit == "quarter") {
+ if (tickSize < 1) {
+
+ // a bit complicated - we'll divide the
+ // month/quarter up but we need to take
+ // care of fractions so we don't end up in
+ // the middle of a day
+
+ d.setDate(1);
+ var start = d.getTime();
+ d.setMonth(d.getMonth() +
+ (unit == "quarter" ? 3 : 1));
+ var end = d.getTime();
+ d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
+ carry = d.getHours();
+ d.setHours(0);
+ } else {
+ d.setMonth(d.getMonth() +
+ tickSize * (unit == "quarter" ? 3 : 1));
+ }
+ } else if (unit == "year") {
+ d.setFullYear(d.getFullYear() + tickSize);
+ } else {
+ d.setTime(v + step);
+ }
+ } while (v < axis.max && v != prev);
+
+ return ticks;
+ };
+
+ axis.tickFormatter = function (v, axis) {
+
+ var d = dateGenerator(v, axis.options);
+
+ // first check global format
+
+ if (opts.timeformat != null) {
+ return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
+ }
+
+ // possibly use quarters if quarters are mentioned in
+ // any of these places
+
+ var useQuarters = (axis.options.tickSize &&
+ axis.options.tickSize[1] == "quarter") ||
+ (axis.options.minTickSize &&
+ axis.options.minTickSize[1] == "quarter");
+
+ var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+ var span = axis.max - axis.min;
+ var suffix = (opts.twelveHourClock) ? " %p" : "";
+ var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
+ var fmt;
+
+ if (t < timeUnitSize.minute) {
+ fmt = hourCode + ":%M:%S" + suffix;
+ } else if (t < timeUnitSize.day) {
+ if (span < 2 * timeUnitSize.day) {
+ fmt = hourCode + ":%M" + suffix;
+ } else {
+ fmt = "%b %d " + hourCode + ":%M" + suffix;
+ }
+ } else if (t < timeUnitSize.month) {
+ fmt = "%b %d";
+ } else if ((useQuarters && t < timeUnitSize.quarter) ||
+ (!useQuarters && t < timeUnitSize.year)) {
+ if (span < timeUnitSize.year) {
+ fmt = "%b";
+ } else {
+ fmt = "%b %Y";
+ }
+ } else if (useQuarters && t < timeUnitSize.year) {
+ if (span < timeUnitSize.year) {
+ fmt = "Q%q";
+ } else {
+ fmt = "Q%q %Y";
+ }
+ } else {
+ fmt = "%Y";
+ }
+
+ var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
+
+ return rt;
+ };
+ }
+ });
+ });
+ }
+
+ $.plot.plugins.push({
+ init: init,
+ options: options,
+ name: 'time',
+ version: '1.0'
+ });
+
+ // Time-axis support used to be in Flot core, which exposed the
+ // formatDate function on the plot object. Various plugins depend
+ // on the function, so we need to re-expose it here.
+
+ $.plot.formatDate = formatDate;
+ $.plot.dateGenerator = dateGenerator;
+
+})(jQuery);
diff --git a/src/main/resources/webapp/js/jquery.min.js b/src/main/resources/webapp/js/jquery.min.js
new file mode 100755
index 0000000..ec2b8be
--- /dev/null
+++ b/src/main/resources/webapp/js/jquery.min.js
@@ -0,0 +1,2058 @@
+/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function (a, b) {
+ "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function (a) {
+ if (!a.document)throw new Error("jQuery requires a window with a document");
+ return b(a)
+ } : b(a)
+}("undefined" != typeof window ? window : this, function (a, b) {
+ var c = [], d = c.slice, e = c.concat, f = c.push, g = c.indexOf, h = {}, i = h.toString, j = h.hasOwnProperty, k = {}, l = a.document, m = "2.1.3", n = function (a, b) {
+ return new n.fn.init(a, b)
+ }, o = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, p = /^-ms-/, q = /-([\da-z])/gi, r = function (a, b) {
+ return b.toUpperCase()
+ };
+ n.fn = n.prototype = {jquery: m, constructor: n, selector: "", length: 0, toArray: function () {
+ return d.call(this)
+ }, get: function (a) {
+ return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this)
+ }, pushStack: function (a) {
+ var b = n.merge(this.constructor(), a);
+ return b.prevObject = this, b.context = this.context, b
+ }, each: function (a, b) {
+ return n.each(this, a, b)
+ }, map: function (a) {
+ return this.pushStack(n.map(this, function (b, c) {
+ return a.call(b, c, b)
+ }))
+ }, slice: function () {
+ return this.pushStack(d.apply(this, arguments))
+ }, first: function () {
+ return this.eq(0)
+ }, last: function () {
+ return this.eq(-1)
+ }, eq: function (a) {
+ var b = this.length, c = +a + (0 > a ? b : 0);
+ return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
+ }, end: function () {
+ return this.prevObject || this.constructor(null)
+ }, push: f, sort: c.sort, splice: c.splice}, n.extend = n.fn.extend = function () {
+ var a, b, c, d, e, f, g = arguments[0] || {}, h = 1, i = arguments.length, j = !1;
+ for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || n.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)if (null != (a = arguments[h]))for (b in a)c = g[b], d = a[b], g !== d && (j && d && (n.isPlainObject(d) || (e = n.isArray(d))) ? (e ? (e = !1, f = c && n.isArray(c) ? c : []) : f = c && n.isPlainObject(c) ? c : {}, g[b] = n.extend(j, f, d)) : void 0 !== d && (g[b] = d));
+ return g
+ }, n.extend({expando: "jQuery" + (m + Math.random()).replace(/\D/g, ""), isReady: !0, error: function (a) {
+ throw new Error(a)
+ }, noop: function () {
+ }, isFunction: function (a) {
+ return"function" === n.type(a)
+ }, isArray: Array.isArray, isWindow: function (a) {
+ return null != a && a === a.window
+ }, isNumeric: function (a) {
+ return!n.isArray(a) && a - parseFloat(a) + 1 >= 0
+ }, isPlainObject: function (a) {
+ return"object" !== n.type(a) || a.nodeType || n.isWindow(a) ? !1 : a.constructor && !j.call(a.constructor.prototype, "isPrototypeOf") ? !1 : !0
+ }, isEmptyObject: function (a) {
+ var b;
+ for (b in a)return!1;
+ return!0
+ }, type: function (a) {
+ return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a
+ }, globalEval: function (a) {
+ var b, c = eval;
+ a = n.trim(a), a && (1 === a.indexOf("use strict") ? (b = l.createElement("script"), b.text = a, l.head.appendChild(b).parentNode.removeChild(b)) : c(a))
+ }, camelCase: function (a) {
+ return a.replace(p, "ms-").replace(q, r)
+ }, nodeName: function (a, b) {
+ return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
+ }, each: function (a, b, c) {
+ var d, e = 0, f = a.length, g = s(a);
+ if (c) {
+ if (g) {
+ for (; f > e; e++)if (d = b.apply(a[e], c), d === !1)break
+ } else for (e in a)if (d = b.apply(a[e], c), d === !1)break
+ } else if (g) {
+ for (; f > e; e++)if (d = b.call(a[e], e, a[e]), d === !1)break
+ } else for (e in a)if (d = b.call(a[e], e, a[e]), d === !1)break;
+ return a
+ }, trim: function (a) {
+ return null == a ? "" : (a + "").replace(o, "")
+ }, makeArray: function (a, b) {
+ var c = b || [];
+ return null != a && (s(Object(a)) ? n.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c
+ }, inArray: function (a, b, c) {
+ return null == b ? -1 : g.call(b, a, c)
+ }, merge: function (a, b) {
+ for (var c = +b.length, d = 0, e = a.length; c > d; d++)a[e++] = b[d];
+ return a.length = e, a
+ }, grep: function (a, b, c) {
+ for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++)d = !b(a[f], f), d !== h && e.push(a[f]);
+ return e
+ }, map: function (a, b, c) {
+ var d, f = 0, g = a.length, h = s(a), i = [];
+ if (h)for (; g > f; f++)d = b(a[f], f, c), null != d && i.push(d); else for (f in a)d = b(a[f], f, c), null != d && i.push(d);
+ return e.apply([], i)
+ }, guid: 1, proxy: function (a, b) {
+ var c, e, f;
+ return"string" == typeof b && (c = a[b], b = a, a = c), n.isFunction(a) ? (e = d.call(arguments, 2), f = function () {
+ return a.apply(b || this, e.concat(d.call(arguments)))
+ }, f.guid = a.guid = a.guid || n.guid++, f) : void 0
+ }, now: Date.now, support: k}), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (a, b) {
+ h["[object " + b + "]"] = b.toLowerCase()
+ });
+ function s(a) {
+ var b = a.length, c = n.type(a);
+ return"function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
+ }
+
+ var t = function (a) {
+ var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + 1 * new Date, v = a.document, w = 0, x = 0, y = hb(), z = hb(), A = hb(), B = function (a, b) {
+ return a === b && (l = !0), 0
+ }, C = 1 << 31, D = {}.hasOwnProperty, E = [], F = E.pop, G = E.push, H = E.push, I = E.slice, J = function (a, b) {
+ for (var c = 0, d = a.length; d > c; c++)if (a[c] === b)return c;
+ return-1
+ }, K = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", L = "[\\x20\\t\\r\\n\\f]", M = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", N = M.replace("w", "w#"), O = "\\[" + L + "*(" + M + ")(?:" + L + "*([*^$|!~]?=)" + L + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + N + "))|)" + L + "*\\]", P = ":(" + M + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + O + ")*)|.*)\\)|)", Q = new RegExp(L + "+", "g"), R = new RegExp("^" + L + "+|((?:^|[^\\\\])(?:\\\\.)*)" + L + "+$", "g"), S = new RegExp("^" + L + "*," + L + "*"), T = new RegExp("^" + L + "*([>+~]|" + L + ")" + L + "*"), U = new RegExp("=" + L + "*([^\\]'\"]*?)" + L + "*\\]", "g"), V = new RegExp(P), W = new RegExp("^" + N + "$"), X = {ID: new RegExp("^#(" + M + ")"), CLASS: new RegExp("^\\.(" + M + ")"), TAG: new RegExp("^(" + M.replace("w", "w*") + ")"), ATTR: new RegExp("^" + O), PSEUDO: new RegExp("^" + P), CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + L + "*(even|odd|(([+-]|)(\\d*)n|)" + L + "*(?:([+-]|)" + L + "*(\\d+)|))" + L + "*\\)|)", "i"), bool: new RegExp("^(?:" + K + ")$", "i"), needsContext: new RegExp("^" + L + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + L + "*((?:-\\d)?\\d*)" + L + "*\\)|)(?=[^-]|$)", "i")}, Y = /^(?:input|select|textarea|button)$/i, Z = /^h\d$/i, $ = /^[^{]+\{\s*\[native \w/, _ = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, ab = /[+~]/, bb = /'|\\/g, cb = new RegExp("\\\\([\\da-f]{1,6}" + L + "?|(" + L + ")|.)", "ig"), db = function (a, b, c) {
+ var d = "0x" + b - 65536;
+ return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
+ }, eb = function () {
+ m()
+ };
+ try {
+ H.apply(E = I.call(v.childNodes), v.childNodes), E[v.childNodes.length].nodeType
+ } catch (fb) {
+ H = {apply: E.length ? function (a, b) {
+ G.apply(a, I.call(b))
+ } : function (a, b) {
+ var c = a.length, d = 0;
+ while (a[c++] = b[d++]);
+ a.length = c - 1
+ }}
+ }
+ function gb(a, b, d, e) {
+ var f, h, j, k, l, o, r, s, w, x;
+ if ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, d = d || [], k = b.nodeType, "string" != typeof a || !a || 1 !== k && 9 !== k && 11 !== k)return d;
+ if (!e && p) {
+ if (11 !== k && (f = _.exec(a)))if (j = f[1]) {
+ if (9 === k) {
+ if (h = b.getElementById(j), !h || !h.parentNode)return d;
+ if (h.id === j)return d.push(h), d
+ } else if (b.ownerDocument && (h = b.ownerDocument.getElementById(j)) && t(b, h) && h.id === j)return d.push(h), d
+ } else {
+ if (f[2])return H.apply(d, b.getElementsByTagName(a)), d;
+ if ((j = f[3]) && c.getElementsByClassName)return H.apply(d, b.getElementsByClassName(j)), d
+ }
+ if (c.qsa && (!q || !q.test(a))) {
+ if (s = r = u, w = b, x = 1 !== k && a, 1 === k && "object" !== b.nodeName.toLowerCase()) {
+ o = g(a), (r = b.getAttribute("id")) ? s = r.replace(bb, "\\$&") : b.setAttribute("id", s), s = "[id='" + s + "'] ", l = o.length;
+ while (l--)o[l] = s + rb(o[l]);
+ w = ab.test(a) && pb(b.parentNode) || b, x = o.join(",")
+ }
+ if (x)try {
+ return H.apply(d, w.querySelectorAll(x)), d
+ } catch (y) {
+ } finally {
+ r || b.removeAttribute("id")
+ }
+ }
+ }
+ return i(a.replace(R, "$1"), b, d, e)
+ }
+
+ function hb() {
+ var a = [];
+
+ function b(c, e) {
+ return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
+ }
+
+ return b
+ }
+
+ function ib(a) {
+ return a[u] = !0, a
+ }
+
+ function jb(a) {
+ var b = n.createElement("div");
+ try {
+ return!!a(b)
+ } catch (c) {
+ return!1
+ } finally {
+ b.parentNode && b.parentNode.removeChild(b), b = null
+ }
+ }
+
+ function kb(a, b) {
+ var c = a.split("|"), e = a.length;
+ while (e--)d.attrHandle[c[e]] = b
+ }
+
+ function lb(a, b) {
+ var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || C) - (~a.sourceIndex || C);
+ if (d)return d;
+ if (c)while (c = c.nextSibling)if (c === b)return-1;
+ return a ? 1 : -1
+ }
+
+ function mb(a) {
+ return function (b) {
+ var c = b.nodeName.toLowerCase();
+ return"input" === c && b.type === a
+ }
+ }
+
+ function nb(a) {
+ return function (b) {
+ var c = b.nodeName.toLowerCase();
+ return("input" === c || "button" === c) && b.type === a
+ }
+ }
+
+ function ob(a) {
+ return ib(function (b) {
+ return b = +b, ib(function (c, d) {
+ var e, f = a([], c.length, b), g = f.length;
+ while (g--)c[e = f[g]] && (c[e] = !(d[e] = c[e]))
+ })
+ })
+ }
+
+ function pb(a) {
+ return a && "undefined" != typeof a.getElementsByTagName && a
+ }
+
+ c = gb.support = {}, f = gb.isXML = function (a) {
+ var b = a && (a.ownerDocument || a).documentElement;
+ return b ? "HTML" !== b.nodeName : !1
+ }, m = gb.setDocument = function (a) {
+ var b, e, g = a ? a.ownerDocument || a : v;
+ return g !== n && 9 === g.nodeType && g.documentElement ? (n = g, o = g.documentElement, e = g.defaultView, e && e !== e.top && (e.addEventListener ? e.addEventListener("unload", eb, !1) : e.attachEvent && e.attachEvent("onunload", eb)), p = !f(g), c.attributes = jb(function (a) {
+ return a.className = "i", !a.getAttribute("className")
+ }), c.getElementsByTagName = jb(function (a) {
+ return a.appendChild(g.createComment("")), !a.getElementsByTagName("*").length
+ }), c.getElementsByClassName = $.test(g.getElementsByClassName), c.getById = jb(function (a) {
+ return o.appendChild(a).id = u, !g.getElementsByName || !g.getElementsByName(u).length
+ }), c.getById ? (d.find.ID = function (a, b) {
+ if ("undefined" != typeof b.getElementById && p) {
+ var c = b.getElementById(a);
+ return c && c.parentNode ? [c] : []
+ }
+ }, d.filter.ID = function (a) {
+ var b = a.replace(cb, db);
+ return function (a) {
+ return a.getAttribute("id") === b
+ }
+ }) : (delete d.find.ID, d.filter.ID = function (a) {
+ var b = a.replace(cb, db);
+ return function (a) {
+ var c = "undefined" != typeof a.getAttributeNode && a.getAttributeNode("id");
+ return c && c.value === b
+ }
+ }), d.find.TAG = c.getElementsByTagName ? function (a, b) {
+ return"undefined" != typeof b.getElementsByTagName ? b.getElementsByTagName(a) : c.qsa ? b.querySelectorAll(a) : void 0
+ } : function (a, b) {
+ var c, d = [], e = 0, f = b.getElementsByTagName(a);
+ if ("*" === a) {
+ while (c = f[e++])1 === c.nodeType && d.push(c);
+ return d
+ }
+ return f
+ }, d.find.CLASS = c.getElementsByClassName && function (a, b) {
+ return p ? b.getElementsByClassName(a) : void 0
+ }, r = [], q = [], (c.qsa = $.test(g.querySelectorAll)) && (jb(function (a) {
+ o.appendChild(a).innerHTML = " ", a.querySelectorAll("[msallowcapture^='']").length && q.push("[*^$]=" + L + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + L + "*(?:value|" + K + ")"), a.querySelectorAll("[id~=" + u + "-]").length || q.push("~="), a.querySelectorAll(":checked").length || q.push(":checked"), a.querySelectorAll("a#" + u + "+*").length || q.push(".#.+[+~]")
+ }), jb(function (a) {
+ var b = g.createElement("input");
+ b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + L + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:")
+ })), (c.matchesSelector = $.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && jb(function (a) {
+ c.disconnectedMatch = s.call(a, "div"), s.call(a, "[s!='']:x"), r.push("!=", P)
+ }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = $.test(o.compareDocumentPosition), t = b || $.test(o.contains) ? function (a, b) {
+ var c = 9 === a.nodeType ? a.documentElement : a, d = b && b.parentNode;
+ return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
+ } : function (a, b) {
+ if (b)while (b = b.parentNode)if (b === a)return!0;
+ return!1
+ }, B = b ? function (a, b) {
+ if (a === b)return l = !0, 0;
+ var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === g || a.ownerDocument === v && t(v, a) ? -1 : b === g || b.ownerDocument === v && t(v, b) ? 1 : k ? J(k, a) - J(k, b) : 0 : 4 & d ? -1 : 1)
+ } : function (a, b) {
+ if (a === b)return l = !0, 0;
+ var c, d = 0, e = a.parentNode, f = b.parentNode, h = [a], i = [b];
+ if (!e || !f)return a === g ? -1 : b === g ? 1 : e ? -1 : f ? 1 : k ? J(k, a) - J(k, b) : 0;
+ if (e === f)return lb(a, b);
+ c = a;
+ while (c = c.parentNode)h.unshift(c);
+ c = b;
+ while (c = c.parentNode)i.unshift(c);
+ while (h[d] === i[d])d++;
+ return d ? lb(h[d], i[d]) : h[d] === v ? -1 : i[d] === v ? 1 : 0
+ }, g) : n
+ }, gb.matches = function (a, b) {
+ return gb(a, null, null, b)
+ }, gb.matchesSelector = function (a, b) {
+ if ((a.ownerDocument || a) !== n && m(a), b = b.replace(U, "='$1']"), !(!c.matchesSelector || !p || r && r.test(b) || q && q.test(b)))try {
+ var d = s.call(a, b);
+ if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType)return d
+ } catch (e) {
+ }
+ return gb(b, n, null, [a]).length > 0
+ }, gb.contains = function (a, b) {
+ return(a.ownerDocument || a) !== n && m(a), t(a, b)
+ }, gb.attr = function (a, b) {
+ (a.ownerDocument || a) !== n && m(a);
+ var e = d.attrHandle[b.toLowerCase()], f = e && D.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0;
+ return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
+ }, gb.error = function (a) {
+ throw new Error("Syntax error, unrecognized expression: " + a)
+ }, gb.uniqueSort = function (a) {
+ var b, d = [], e = 0, f = 0;
+ if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) {
+ while (b = a[f++])b === a[f] && (e = d.push(f));
+ while (e--)a.splice(d[e], 1)
+ }
+ return k = null, a
+ }, e = gb.getText = function (a) {
+ var b, c = "", d = 0, f = a.nodeType;
+ if (f) {
+ if (1 === f || 9 === f || 11 === f) {
+ if ("string" == typeof a.textContent)return a.textContent;
+ for (a = a.firstChild; a; a = a.nextSibling)c += e(a)
+ } else if (3 === f || 4 === f)return a.nodeValue
+ } else while (b = a[d++])c += e(b);
+ return c
+ }, d = gb.selectors = {cacheLength: 50, createPseudo: ib, match: X, attrHandle: {}, find: {}, relative: {">": {dir: "parentNode", first: !0}, " ": {dir: "parentNode"}, "+": {dir: "previousSibling", first: !0}, "~": {dir: "previousSibling"}}, preFilter: {ATTR: function (a) {
+ return a[1] = a[1].replace(cb, db), a[3] = (a[3] || a[4] || a[5] || "").replace(cb, db), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
+ }, CHILD: function (a) {
+ return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || gb.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && gb.error(a[0]), a
+ }, PSEUDO: function (a) {
+ var b, c = !a[6] && a[2];
+ return X.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && V.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
+ }}, filter: {TAG: function (a) {
+ var b = a.replace(cb, db).toLowerCase();
+ return"*" === a ? function () {
+ return!0
+ } : function (a) {
+ return a.nodeName && a.nodeName.toLowerCase() === b
+ }
+ }, CLASS: function (a) {
+ var b = y[a + " "];
+ return b || (b = new RegExp("(^|" + L + ")" + a + "(" + L + "|$)")) && y(a, function (a) {
+ return b.test("string" == typeof a.className && a.className || "undefined" != typeof a.getAttribute && a.getAttribute("class") || "")
+ })
+ }, ATTR: function (a, b, c) {
+ return function (d) {
+ var e = gb.attr(d, a);
+ return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e.replace(Q, " ") + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
+ }
+ }, CHILD: function (a, b, c, d, e) {
+ var f = "nth" !== a.slice(0, 3), g = "last" !== a.slice(-4), h = "of-type" === b;
+ return 1 === d && 0 === e ? function (a) {
+ return!!a.parentNode
+ } : function (b, c, i) {
+ var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling", q = b.parentNode, r = h && b.nodeName.toLowerCase(), s = !i && !h;
+ if (q) {
+ if (f) {
+ while (p) {
+ l = b;
+ while (l = l[p])if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType)return!1;
+ o = p = "only" === a && !o && "nextSibling"
+ }
+ return!0
+ }
+ if (o = [g ? q.firstChild : q.lastChild], g && s) {
+ k = q[u] || (q[u] = {}), j = k[a] || [], n = j[0] === w && j[1], m = j[0] === w && j[2], l = n && q.childNodes[n];
+ while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if (1 === l.nodeType && ++m && l === b) {
+ k[a] = [w, n, m];
+ break
+ }
+ } else if (s && (j = (b[u] || (b[u] = {}))[a]) && j[0] === w)m = j[1]; else while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (s && ((l[u] || (l[u] = {}))[a] = [w, m]), l === b))break;
+ return m -= e, m === d || m % d === 0 && m / d >= 0
+ }
+ }
+ }, PSEUDO: function (a, b) {
+ var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || gb.error("unsupported pseudo: " + a);
+ return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? ib(function (a, c) {
+ var d, f = e(a, b), g = f.length;
+ while (g--)d = J(a, f[g]), a[d] = !(c[d] = f[g])
+ }) : function (a) {
+ return e(a, 0, c)
+ }) : e
+ }}, pseudos: {not: ib(function (a) {
+ var b = [], c = [], d = h(a.replace(R, "$1"));
+ return d[u] ? ib(function (a, b, c, e) {
+ var f, g = d(a, null, e, []), h = a.length;
+ while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
+ }) : function (a, e, f) {
+ return b[0] = a, d(b, null, f, c), b[0] = null, !c.pop()
+ }
+ }), has: ib(function (a) {
+ return function (b) {
+ return gb(a, b).length > 0
+ }
+ }), contains: ib(function (a) {
+ return a = a.replace(cb, db), function (b) {
+ return(b.textContent || b.innerText || e(b)).indexOf(a) > -1
+ }
+ }), lang: ib(function (a) {
+ return W.test(a || "") || gb.error("unsupported lang: " + a), a = a.replace(cb, db).toLowerCase(), function (b) {
+ var c;
+ do if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang"))return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
+ return!1
+ }
+ }), target: function (b) {
+ var c = a.location && a.location.hash;
+ return c && c.slice(1) === b.id
+ }, root: function (a) {
+ return a === o
+ }, focus: function (a) {
+ return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
+ }, enabled: function (a) {
+ return a.disabled === !1
+ }, disabled: function (a) {
+ return a.disabled === !0
+ }, checked: function (a) {
+ var b = a.nodeName.toLowerCase();
+ return"input" === b && !!a.checked || "option" === b && !!a.selected
+ }, selected: function (a) {
+ return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
+ }, empty: function (a) {
+ for (a = a.firstChild; a; a = a.nextSibling)if (a.nodeType < 6)return!1;
+ return!0
+ }, parent: function (a) {
+ return!d.pseudos.empty(a)
+ }, header: function (a) {
+ return Z.test(a.nodeName)
+ }, input: function (a) {
+ return Y.test(a.nodeName)
+ }, button: function (a) {
+ var b = a.nodeName.toLowerCase();
+ return"input" === b && "button" === a.type || "button" === b
+ }, text: function (a) {
+ var b;
+ return"input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
+ }, first: ob(function () {
+ return[0]
+ }), last: ob(function (a, b) {
+ return[b - 1]
+ }), eq: ob(function (a, b, c) {
+ return[0 > c ? c + b : c]
+ }), even: ob(function (a, b) {
+ for (var c = 0; b > c; c += 2)a.push(c);
+ return a
+ }), odd: ob(function (a, b) {
+ for (var c = 1; b > c; c += 2)a.push(c);
+ return a
+ }), lt: ob(function (a, b, c) {
+ for (var d = 0 > c ? c + b : c; --d >= 0;)a.push(d);
+ return a
+ }), gt: ob(function (a, b, c) {
+ for (var d = 0 > c ? c + b : c; ++d < b;)a.push(d);
+ return a
+ })}}, d.pseudos.nth = d.pseudos.eq;
+ for (b in{radio: !0, checkbox: !0, file: !0, password: !0, image: !0})d.pseudos[b] = mb(b);
+ for (b in{submit: !0, reset: !0})d.pseudos[b] = nb(b);
+ function qb() {
+ }
+
+ qb.prototype = d.filters = d.pseudos, d.setFilters = new qb, g = gb.tokenize = function (a, b) {
+ var c, e, f, g, h, i, j, k = z[a + " "];
+ if (k)return b ? 0 : k.slice(0);
+ h = a, i = [], j = d.preFilter;
+ while (h) {
+ (!c || (e = S.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = T.exec(h)) && (c = e.shift(), f.push({value: c, type: e[0].replace(R, " ")}), h = h.slice(c.length));
+ for (g in d.filter)!(e = X[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({value: c, type: g, matches: e}), h = h.slice(c.length));
+ if (!c)break
+ }
+ return b ? h.length : h ? gb.error(a) : z(a, i).slice(0)
+ };
+ function rb(a) {
+ for (var b = 0, c = a.length, d = ""; c > b; b++)d += a[b].value;
+ return d
+ }
+
+ function sb(a, b, c) {
+ var d = b.dir, e = c && "parentNode" === d, f = x++;
+ return b.first ? function (b, c, f) {
+ while (b = b[d])if (1 === b.nodeType || e)return a(b, c, f)
+ } : function (b, c, g) {
+ var h, i, j = [w, f];
+ if (g) {
+ while (b = b[d])if ((1 === b.nodeType || e) && a(b, c, g))return!0
+ } else while (b = b[d])if (1 === b.nodeType || e) {
+ if (i = b[u] || (b[u] = {}), (h = i[d]) && h[0] === w && h[1] === f)return j[2] = h[2];
+ if (i[d] = j, j[2] = a(b, c, g))return!0
+ }
+ }
+ }
+
+ function tb(a) {
+ return a.length > 1 ? function (b, c, d) {
+ var e = a.length;
+ while (e--)if (!a[e](b, c, d))return!1;
+ return!0
+ } : a[0]
+ }
+
+ function ub(a, b, c) {
+ for (var d = 0, e = b.length; e > d; d++)gb(a, b[d], c);
+ return c
+ }
+
+ function vb(a, b, c, d, e) {
+ for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h));
+ return g
+ }
+
+ function wb(a, b, c, d, e, f) {
+ return d && !d[u] && (d = wb(d)), e && !e[u] && (e = wb(e, f)), ib(function (f, g, h, i) {
+ var j, k, l, m = [], n = [], o = g.length, p = f || ub(b || "*", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : vb(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q;
+ if (c && c(q, r, h, i), d) {
+ j = vb(r, n), d(j, [], h, i), k = j.length;
+ while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
+ }
+ if (f) {
+ if (e || a) {
+ if (e) {
+ j = [], k = r.length;
+ while (k--)(l = r[k]) && j.push(q[k] = l);
+ e(null, r = [], j, i)
+ }
+ k = r.length;
+ while (k--)(l = r[k]) && (j = e ? J(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
+ }
+ } else r = vb(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : H.apply(g, r)
+ })
+ }
+
+ function xb(a) {
+ for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = sb(function (a) {
+ return a === b
+ }, h, !0), l = sb(function (a) {
+ return J(b, a) > -1
+ }, h, !0), m = [function (a, c, d) {
+ var e = !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d));
+ return b = null, e
+ }]; f > i; i++)if (c = d.relative[a[i].type])m = [sb(tb(m), c)]; else {
+ if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) {
+ for (e = ++i; f > e; e++)if (d.relative[a[e].type])break;
+ return wb(i > 1 && tb(m), i > 1 && rb(a.slice(0, i - 1).concat({value: " " === a[i - 2].type ? "*" : ""})).replace(R, "$1"), c, e > i && xb(a.slice(i, e)), f > e && xb(a = a.slice(e)), f > e && rb(a))
+ }
+ m.push(c)
+ }
+ return tb(m)
+ }
+
+ function yb(a, b) {
+ var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) {
+ var l, m, o, p = 0, q = "0", r = f && [], s = [], t = j, u = f || e && d.find.TAG("*", k), v = w += null == t ? 1 : Math.random() || .1, x = u.length;
+ for (k && (j = g !== n && g); q !== x && null != (l = u[q]); q++) {
+ if (e && l) {
+ m = 0;
+ while (o = a[m++])if (o(l, g, h)) {
+ i.push(l);
+ break
+ }
+ k && (w = v)
+ }
+ c && ((l = !o && l) && p--, f && r.push(l))
+ }
+ if (p += q, c && q !== p) {
+ m = 0;
+ while (o = b[m++])o(r, s, g, h);
+ if (f) {
+ if (p > 0)while (q--)r[q] || s[q] || (s[q] = F.call(i));
+ s = vb(s)
+ }
+ H.apply(i, s), k && !f && s.length > 0 && p + b.length > 1 && gb.uniqueSort(i)
+ }
+ return k && (w = v, j = t), r
+ };
+ return c ? ib(f) : f
+ }
+
+ return h = gb.compile = function (a, b) {
+ var c, d = [], e = [], f = A[a + " "];
+ if (!f) {
+ b || (b = g(a)), c = b.length;
+ while (c--)f = xb(b[c]), f[u] ? d.push(f) : e.push(f);
+ f = A(a, yb(e, d)), f.selector = a
+ }
+ return f
+ }, i = gb.select = function (a, b, e, f) {
+ var i, j, k, l, m, n = "function" == typeof a && a, o = !f && g(a = n.selector || a);
+ if (e = e || [], 1 === o.length) {
+ if (j = o[0] = o[0].slice(0), j.length > 2 && "ID" === (k = j[0]).type && c.getById && 9 === b.nodeType && p && d.relative[j[1].type]) {
+ if (b = (d.find.ID(k.matches[0].replace(cb, db), b) || [])[0], !b)return e;
+ n && (b = b.parentNode), a = a.slice(j.shift().value.length)
+ }
+ i = X.needsContext.test(a) ? 0 : j.length;
+ while (i--) {
+ if (k = j[i], d.relative[l = k.type])break;
+ if ((m = d.find[l]) && (f = m(k.matches[0].replace(cb, db), ab.test(j[0].type) && pb(b.parentNode) || b))) {
+ if (j.splice(i, 1), a = f.length && rb(j), !a)return H.apply(e, f), e;
+ break
+ }
+ }
+ }
+ return(n || h(a, o))(f, b, !p, e, ab.test(a) && pb(b.parentNode) || b), e
+ }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = jb(function (a) {
+ return 1 & a.compareDocumentPosition(n.createElement("div"))
+ }), jb(function (a) {
+ return a.innerHTML = " ", "#" === a.firstChild.getAttribute("href")
+ }) || kb("type|href|height|width", function (a, b, c) {
+ return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
+ }), c.attributes && jb(function (a) {
+ return a.innerHTML = " ", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
+ }) || kb("value", function (a, b, c) {
+ return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
+ }), jb(function (a) {
+ return null == a.getAttribute("disabled")
+ }) || kb(K, function (a, b, c) {
+ var d;
+ return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
+ }), gb
+ }(a);
+ n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains;
+ var u = n.expr.match.needsContext, v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, w = /^.[^:#\[\.,]*$/;
+
+ function x(a, b, c) {
+ if (n.isFunction(b))return n.grep(a, function (a, d) {
+ return!!b.call(a, d, a) !== c
+ });
+ if (b.nodeType)return n.grep(a, function (a) {
+ return a === b !== c
+ });
+ if ("string" == typeof b) {
+ if (w.test(b))return n.filter(b, a, c);
+ b = n.filter(b, a)
+ }
+ return n.grep(a, function (a) {
+ return g.call(b, a) >= 0 !== c
+ })
+ }
+
+ n.filter = function (a, b, c) {
+ var d = b[0];
+ return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? n.find.matchesSelector(d, a) ? [d] : [] : n.find.matches(a, n.grep(b, function (a) {
+ return 1 === a.nodeType
+ }))
+ }, n.fn.extend({find: function (a) {
+ var b, c = this.length, d = [], e = this;
+ if ("string" != typeof a)return this.pushStack(n(a).filter(function () {
+ for (b = 0; c > b; b++)if (n.contains(e[b], this))return!0
+ }));
+ for (b = 0; c > b; b++)n.find(a, e[b], d);
+ return d = this.pushStack(c > 1 ? n.unique(d) : d), d.selector = this.selector ? this.selector + " " + a : a, d
+ }, filter: function (a) {
+ return this.pushStack(x(this, a || [], !1))
+ }, not: function (a) {
+ return this.pushStack(x(this, a || [], !0))
+ }, is: function (a) {
+ return!!x(this, "string" == typeof a && u.test(a) ? n(a) : a || [], !1).length
+ }});
+ var y, z = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, A = n.fn.init = function (a, b) {
+ var c, d;
+ if (!a)return this;
+ if ("string" == typeof a) {
+ if (c = "<" === a[0] && ">" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : z.exec(a), !c || !c[1] && b)return!b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a);
+ if (c[1]) {
+ if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : l, !0)), v.test(c[1]) && n.isPlainObject(b))for (c in b)n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]);
+ return this
+ }
+ return d = l.getElementById(c[2]), d && d.parentNode && (this.length = 1, this[0] = d), this.context = l, this.selector = a, this
+ }
+ return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? "undefined" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this))
+ };
+ A.prototype = n.fn, y = n(l);
+ var B = /^(?:parents|prev(?:Until|All))/, C = {children: !0, contents: !0, next: !0, prev: !0};
+ n.extend({dir: function (a, b, c) {
+ var d = [], e = void 0 !== c;
+ while ((a = a[b]) && 9 !== a.nodeType)if (1 === a.nodeType) {
+ if (e && n(a).is(c))break;
+ d.push(a)
+ }
+ return d
+ }, sibling: function (a, b) {
+ for (var c = []; a; a = a.nextSibling)1 === a.nodeType && a !== b && c.push(a);
+ return c
+ }}), n.fn.extend({has: function (a) {
+ var b = n(a, this), c = b.length;
+ return this.filter(function () {
+ for (var a = 0; c > a; a++)if (n.contains(this, b[a]))return!0
+ })
+ }, closest: function (a, b) {
+ for (var c, d = 0, e = this.length, f = [], g = u.test(a) || "string" != typeof a ? n(a, b || this.context) : 0; e > d; d++)for (c = this[d]; c && c !== b; c = c.parentNode)if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && n.find.matchesSelector(c, a))) {
+ f.push(c);
+ break
+ }
+ return this.pushStack(f.length > 1 ? n.unique(f) : f)
+ }, index: function (a) {
+ return a ? "string" == typeof a ? g.call(n(a), this[0]) : g.call(this, a.jquery ? a[0] : a) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
+ }, add: function (a, b) {
+ return this.pushStack(n.unique(n.merge(this.get(), n(a, b))))
+ }, addBack: function (a) {
+ return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
+ }});
+ function D(a, b) {
+ while ((a = a[b]) && 1 !== a.nodeType);
+ return a
+ }
+
+ n.each({parent: function (a) {
+ var b = a.parentNode;
+ return b && 11 !== b.nodeType ? b : null
+ }, parents: function (a) {
+ return n.dir(a, "parentNode")
+ }, parentsUntil: function (a, b, c) {
+ return n.dir(a, "parentNode", c)
+ }, next: function (a) {
+ return D(a, "nextSibling")
+ }, prev: function (a) {
+ return D(a, "previousSibling")
+ }, nextAll: function (a) {
+ return n.dir(a, "nextSibling")
+ }, prevAll: function (a) {
+ return n.dir(a, "previousSibling")
+ }, nextUntil: function (a, b, c) {
+ return n.dir(a, "nextSibling", c)
+ }, prevUntil: function (a, b, c) {
+ return n.dir(a, "previousSibling", c)
+ }, siblings: function (a) {
+ return n.sibling((a.parentNode || {}).firstChild, a)
+ }, children: function (a) {
+ return n.sibling(a.firstChild)
+ }, contents: function (a) {
+ return a.contentDocument || n.merge([], a.childNodes)
+ }}, function (a, b) {
+ n.fn[a] = function (c, d) {
+ var e = n.map(this, b, c);
+ return"Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = n.filter(d, e)), this.length > 1 && (C[a] || n.unique(e), B.test(a) && e.reverse()), this.pushStack(e)
+ }
+ });
+ var E = /\S+/g, F = {};
+
+ function G(a) {
+ var b = F[a] = {};
+ return n.each(a.match(E) || [], function (a, c) {
+ b[c] = !0
+ }), b
+ }
+
+ n.Callbacks = function (a) {
+ a = "string" == typeof a ? F[a] || G(a) : n.extend({}, a);
+ var b, c, d, e, f, g, h = [], i = !a.once && [], j = function (l) {
+ for (b = a.memory && l, c = !0, g = e || 0, e = 0, f = h.length, d = !0; h && f > g; g++)if (h[g].apply(l[0], l[1]) === !1 && a.stopOnFalse) {
+ b = !1;
+ break
+ }
+ d = !1, h && (i ? i.length && j(i.shift()) : b ? h = [] : k.disable())
+ }, k = {add: function () {
+ if (h) {
+ var c = h.length;
+ !function g(b) {
+ n.each(b, function (b, c) {
+ var d = n.type(c);
+ "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && g(c)
+ })
+ }(arguments), d ? f = h.length : b && (e = c, j(b))
+ }
+ return this
+ }, remove: function () {
+ return h && n.each(arguments, function (a, b) {
+ var c;
+ while ((c = n.inArray(b, h, c)) > -1)h.splice(c, 1), d && (f >= c && f--, g >= c && g--)
+ }), this
+ }, has: function (a) {
+ return a ? n.inArray(a, h) > -1 : !(!h || !h.length)
+ }, empty: function () {
+ return h = [], f = 0, this
+ }, disable: function () {
+ return h = i = b = void 0, this
+ }, disabled: function () {
+ return!h
+ }, lock: function () {
+ return i = void 0, b || k.disable(), this
+ }, locked: function () {
+ return!i
+ }, fireWith: function (a, b) {
+ return!h || c && !i || (b = b || [], b = [a, b.slice ? b.slice() : b], d ? i.push(b) : j(b)), this
+ }, fire: function () {
+ return k.fireWith(this, arguments), this
+ }, fired: function () {
+ return!!c
+ }};
+ return k
+ }, n.extend({Deferred: function (a) {
+ var b = [
+ ["resolve", "done", n.Callbacks("once memory"), "resolved"],
+ ["reject", "fail", n.Callbacks("once memory"), "rejected"],
+ ["notify", "progress", n.Callbacks("memory")]
+ ], c = "pending", d = {state: function () {
+ return c
+ }, always: function () {
+ return e.done(arguments).fail(arguments), this
+ }, then: function () {
+ var a = arguments;
+ return n.Deferred(function (c) {
+ n.each(b, function (b, f) {
+ var g = n.isFunction(a[b]) && a[b];
+ e[f[1]](function () {
+ var a = g && g.apply(this, arguments);
+ a && n.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
+ })
+ }), a = null
+ }).promise()
+ }, promise: function (a) {
+ return null != a ? n.extend(a, d) : d
+ }}, e = {};
+ return d.pipe = d.then, n.each(b, function (a, f) {
+ var g = f[2], h = f[3];
+ d[f[1]] = g.add, h && g.add(function () {
+ c = h
+ }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function () {
+ return e[f[0] + "With"](this === e ? d : this, arguments), this
+ }, e[f[0] + "With"] = g.fireWith
+ }), d.promise(e), a && a.call(e, e), e
+ }, when: function (a) {
+ var b = 0, c = d.call(arguments), e = c.length, f = 1 !== e || a && n.isFunction(a.promise) ? e : 0, g = 1 === f ? a : n.Deferred(), h = function (a, b, c) {
+ return function (e) {
+ b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
+ }
+ }, i, j, k;
+ if (e > 1)for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++)c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f;
+ return f || g.resolveWith(k, c), g.promise()
+ }});
+ var H;
+ n.fn.ready = function (a) {
+ return n.ready.promise().done(a), this
+ }, n.extend({isReady: !1, readyWait: 1, holdReady: function (a) {
+ a ? n.readyWait++ : n.ready(!0)
+ }, ready: function (a) {
+ (a === !0 ? --n.readyWait : n.isReady) || (n.isReady = !0, a !== !0 && --n.readyWait > 0 || (H.resolveWith(l, [n]), n.fn.triggerHandler && (n(l).triggerHandler("ready"), n(l).off("ready"))))
+ }});
+ function I() {
+ l.removeEventListener("DOMContentLoaded", I, !1), a.removeEventListener("load", I, !1), n.ready()
+ }
+
+ n.ready.promise = function (b) {
+ return H || (H = n.Deferred(), "complete" === l.readyState ? setTimeout(n.ready) : (l.addEventListener("DOMContentLoaded", I, !1), a.addEventListener("load", I, !1))), H.promise(b)
+ }, n.ready.promise();
+ var J = n.access = function (a, b, c, d, e, f, g) {
+ var h = 0, i = a.length, j = null == c;
+ if ("object" === n.type(c)) {
+ e = !0;
+ for (h in c)n.access(a, b, h, c[h], !0, f, g)
+ } else if (void 0 !== d && (e = !0, n.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function (a, b, c) {
+ return j.call(n(a), c)
+ })), b))for (; i > h; h++)b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
+ return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
+ };
+ n.acceptData = function (a) {
+ return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType
+ };
+ function K() {
+ Object.defineProperty(this.cache = {}, 0, {get: function () {
+ return{}
+ }}), this.expando = n.expando + K.uid++
+ }
+
+ K.uid = 1, K.accepts = n.acceptData, K.prototype = {key: function (a) {
+ if (!K.accepts(a))return 0;
+ var b = {}, c = a[this.expando];
+ if (!c) {
+ c = K.uid++;
+ try {
+ b[this.expando] = {value: c}, Object.defineProperties(a, b)
+ } catch (d) {
+ b[this.expando] = c, n.extend(a, b)
+ }
+ }
+ return this.cache[c] || (this.cache[c] = {}), c
+ }, set: function (a, b, c) {
+ var d, e = this.key(a), f = this.cache[e];
+ if ("string" == typeof b)f[b] = c; else if (n.isEmptyObject(f))n.extend(this.cache[e], b); else for (d in b)f[d] = b[d];
+ return f
+ }, get: function (a, b) {
+ var c = this.cache[this.key(a)];
+ return void 0 === b ? c : c[b]
+ }, access: function (a, b, c) {
+ var d;
+ return void 0 === b || b && "string" == typeof b && void 0 === c ? (d = this.get(a, b), void 0 !== d ? d : this.get(a, n.camelCase(b))) : (this.set(a, b, c), void 0 !== c ? c : b)
+ }, remove: function (a, b) {
+ var c, d, e, f = this.key(a), g = this.cache[f];
+ if (void 0 === b)this.cache[f] = {}; else {
+ n.isArray(b) ? d = b.concat(b.map(n.camelCase)) : (e = n.camelCase(b), b in g ? d = [b, e] : (d = e, d = d in g ? [d] : d.match(E) || [])), c = d.length;
+ while (c--)delete g[d[c]]
+ }
+ }, hasData: function (a) {
+ return!n.isEmptyObject(this.cache[a[this.expando]] || {})
+ }, discard: function (a) {
+ a[this.expando] && delete this.cache[a[this.expando]]
+ }};
+ var L = new K, M = new K, N = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, O = /([A-Z])/g;
+
+ function P(a, b, c) {
+ var d;
+ if (void 0 === c && 1 === a.nodeType)if (d = "data-" + b.replace(O, "-$1").toLowerCase(), c = a.getAttribute(d), "string" == typeof c) {
+ try {
+ c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c
+ } catch (e) {
+ }
+ M.set(a, b, c)
+ } else c = void 0;
+ return c
+ }
+
+ n.extend({hasData: function (a) {
+ return M.hasData(a) || L.hasData(a)
+ }, data: function (a, b, c) {
+ return M.access(a, b, c)
+ }, removeData: function (a, b) {
+ M.remove(a, b)
+ }, _data: function (a, b, c) {
+ return L.access(a, b, c)
+ }, _removeData: function (a, b) {
+ L.remove(a, b)
+ }}), n.fn.extend({data: function (a, b) {
+ var c, d, e, f = this[0], g = f && f.attributes;
+ if (void 0 === a) {
+ if (this.length && (e = M.get(f), 1 === f.nodeType && !L.get(f, "hasDataAttrs"))) {
+ c = g.length;
+ while (c--)g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), P(f, d, e[d])));
+ L.set(f, "hasDataAttrs", !0)
+ }
+ return e
+ }
+ return"object" == typeof a ? this.each(function () {
+ M.set(this, a)
+ }) : J(this, function (b) {
+ var c, d = n.camelCase(a);
+ if (f && void 0 === b) {
+ if (c = M.get(f, a), void 0 !== c)return c;
+ if (c = M.get(f, d), void 0 !== c)return c;
+ if (c = P(f, d, void 0), void 0 !== c)return c
+ } else this.each(function () {
+ var c = M.get(this, d);
+ M.set(this, d, b), -1 !== a.indexOf("-") && void 0 !== c && M.set(this, a, b)
+ })
+ }, null, b, arguments.length > 1, null, !0)
+ }, removeData: function (a) {
+ return this.each(function () {
+ M.remove(this, a)
+ })
+ }}), n.extend({queue: function (a, b, c) {
+ var d;
+ return a ? (b = (b || "fx") + "queue", d = L.get(a, b), c && (!d || n.isArray(c) ? d = L.access(a, b, n.makeArray(c)) : d.push(c)), d || []) : void 0
+ }, dequeue: function (a, b) {
+ b = b || "fx";
+ var c = n.queue(a, b), d = c.length, e = c.shift(), f = n._queueHooks(a, b), g = function () {
+ n.dequeue(a, b)
+ };
+ "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
+ }, _queueHooks: function (a, b) {
+ var c = b + "queueHooks";
+ return L.get(a, c) || L.access(a, c, {empty: n.Callbacks("once memory").add(function () {
+ L.remove(a, [b + "queue", c])
+ })})
+ }}), n.fn.extend({queue: function (a, b) {
+ var c = 2;
+ return"string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function () {
+ var c = n.queue(this, a, b);
+ n._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && n.dequeue(this, a)
+ })
+ }, dequeue: function (a) {
+ return this.each(function () {
+ n.dequeue(this, a)
+ })
+ }, clearQueue: function (a) {
+ return this.queue(a || "fx", [])
+ }, promise: function (a, b) {
+ var c, d = 1, e = n.Deferred(), f = this, g = this.length, h = function () {
+ --d || e.resolveWith(f, [f])
+ };
+ "string" != typeof a && (b = a, a = void 0), a = a || "fx";
+ while (g--)c = L.get(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
+ return h(), e.promise(b)
+ }});
+ var Q = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, R = ["Top", "Right", "Bottom", "Left"], S = function (a, b) {
+ return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a)
+ }, T = /^(?:checkbox|radio)$/i;
+ !function () {
+ var a = l.createDocumentFragment(), b = a.appendChild(l.createElement("div")), c = l.createElement("input");
+ c.setAttribute("type", "radio"), c.setAttribute("checked", "checked"), c.setAttribute("name", "t"), b.appendChild(c), k.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = "", k.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue
+ }();
+ var U = "undefined";
+ k.focusinBubbles = "onfocusin"in a;
+ var V = /^key/, W = /^(?:mouse|pointer|contextmenu)|click/, X = /^(?:focusinfocus|focusoutblur)$/, Y = /^([^.]*)(?:\.(.+)|)$/;
+
+ function Z() {
+ return!0
+ }
+
+ function $() {
+ return!1
+ }
+
+ function _() {
+ try {
+ return l.activeElement
+ } catch (a) {
+ }
+ }
+
+ n.event = {global: {}, add: function (a, b, c, d, e) {
+ var f, g, h, i, j, k, l, m, o, p, q, r = L.get(a);
+ if (r) {
+ c.handler && (f = c, c = f.handler, e = f.selector), c.guid || (c.guid = n.guid++), (i = r.events) || (i = r.events = {}), (g = r.handle) || (g = r.handle = function (b) {
+ return typeof n !== U && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0
+ }), b = (b || "").match(E) || [""], j = b.length;
+ while (j--)h = Y.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o && (l = n.event.special[o] || {}, o = (e ? l.delegateType : l.bindType) || o, l = n.event.special[o] || {}, k = n.extend({type: o, origType: q, data: d, handler: c, guid: c.guid, selector: e, needsContext: e && n.expr.match.needsContext.test(e), namespace: p.join(".")}, f), (m = i[o]) || (m = i[o] = [], m.delegateCount = 0, l.setup && l.setup.call(a, d, p, g) !== !1 || a.addEventListener && a.addEventListener(o, g, !1)), l.add && (l.add.call(a, k), k.handler.guid || (k.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, k) : m.push(k), n.event.global[o] = !0)
+ }
+ }, remove: function (a, b, c, d, e) {
+ var f, g, h, i, j, k, l, m, o, p, q, r = L.hasData(a) && L.get(a);
+ if (r && (i = r.events)) {
+ b = (b || "").match(E) || [""], j = b.length;
+ while (j--)if (h = Y.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
+ l = n.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, m = i[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), g = f = m.length;
+ while (f--)k = m[f], !e && q !== k.origType || c && c.guid !== k.guid || h && !h.test(k.namespace) || d && d !== k.selector && ("**" !== d || !k.selector) || (m.splice(f, 1), k.selector && m.delegateCount--, l.remove && l.remove.call(a, k));
+ g && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete i[o])
+ } else for (o in i)n.event.remove(a, o + b[j], c, d, !0);
+ n.isEmptyObject(i) && (delete r.handle, L.remove(a, "events"))
+ }
+ }, trigger: function (b, c, d, e) {
+ var f, g, h, i, k, m, o, p = [d || l], q = j.call(b, "type") ? b.type : b, r = j.call(b, "namespace") ? b.namespace.split(".") : [];
+ if (g = h = d = d || l, 3 !== d.nodeType && 8 !== d.nodeType && !X.test(q + n.event.triggered) && (q.indexOf(".") >= 0 && (r = q.split("."), q = r.shift(), r.sort()), k = q.indexOf(":") < 0 && "on" + q, b = b[n.expando] ? b : new n.Event(q, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = r.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + r.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), o = n.event.special[q] || {}, e || !o.trigger || o.trigger.apply(d, c) !== !1)) {
+ if (!e && !o.noBubble && !n.isWindow(d)) {
+ for (i = o.delegateType || q, X.test(i + q) || (g = g.parentNode); g; g = g.parentNode)p.push(g), h = g;
+ h === (d.ownerDocument || l) && p.push(h.defaultView || h.parentWindow || a)
+ }
+ f = 0;
+ while ((g = p[f++]) && !b.isPropagationStopped())b.type = f > 1 ? i : o.bindType || q, m = (L.get(g, "events") || {})[b.type] && L.get(g, "handle"), m && m.apply(g, c), m = k && g[k], m && m.apply && n.acceptData(g) && (b.result = m.apply(g, c), b.result === !1 && b.preventDefault());
+ return b.type = q, e || b.isDefaultPrevented() || o._default && o._default.apply(p.pop(), c) !== !1 || !n.acceptData(d) || k && n.isFunction(d[q]) && !n.isWindow(d) && (h = d[k], h && (d[k] = null), n.event.triggered = q, d[q](), n.event.triggered = void 0, h && (d[k] = h)), b.result
+ }
+ }, dispatch: function (a) {
+ a = n.event.fix(a);
+ var b, c, e, f, g, h = [], i = d.call(arguments), j = (L.get(this, "events") || {})[a.type] || [], k = n.event.special[a.type] || {};
+ if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
+ h = n.event.handlers.call(this, a, j), b = 0;
+ while ((f = h[b++]) && !a.isPropagationStopped()) {
+ a.currentTarget = f.elem, c = 0;
+ while ((g = f.handlers[c++]) && !a.isImmediatePropagationStopped())(!a.namespace_re || a.namespace_re.test(g.namespace)) && (a.handleObj = g, a.data = g.data, e = ((n.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== e && (a.result = e) === !1 && (a.preventDefault(), a.stopPropagation()))
+ }
+ return k.postDispatch && k.postDispatch.call(this, a), a.result
+ }
+ }, handlers: function (a, b) {
+ var c, d, e, f, g = [], h = b.delegateCount, i = a.target;
+ if (h && i.nodeType && (!a.button || "click" !== a.type))for (; i !== this; i = i.parentNode || this)if (i.disabled !== !0 || "click" !== a.type) {
+ for (d = [], c = 0; h > c; c++)f = b[c], e = f.selector + " ", void 0 === d[e] && (d[e] = f.needsContext ? n(e, this).index(i) >= 0 : n.find(e, this, null, [i]).length), d[e] && d.push(f);
+ d.length && g.push({elem: i, handlers: d})
+ }
+ return h < b.length && g.push({elem: this, handlers: b.slice(h)}), g
+ }, props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: {props: "char charCode key keyCode".split(" "), filter: function (a, b) {
+ return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
+ }}, mouseHooks: {props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function (a, b) {
+ var c, d, e, f = b.button;
+ return null == a.pageX && null != b.clientX && (c = a.target.ownerDocument || l, d = c.documentElement, e = c.body, a.pageX = b.clientX + (d && d.scrollLeft || e && e.scrollLeft || 0) - (d && d.clientLeft || e && e.clientLeft || 0), a.pageY = b.clientY + (d && d.scrollTop || e && e.scrollTop || 0) - (d && d.clientTop || e && e.clientTop || 0)), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a
+ }}, fix: function (a) {
+ if (a[n.expando])return a;
+ var b, c, d, e = a.type, f = a, g = this.fixHooks[e];
+ g || (this.fixHooks[e] = g = W.test(e) ? this.mouseHooks : V.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length;
+ while (b--)c = d[b], a[c] = f[c];
+ return a.target || (a.target = l), 3 === a.target.nodeType && (a.target = a.target.parentNode), g.filter ? g.filter(a, f) : a
+ }, special: {load: {noBubble: !0}, focus: {trigger: function () {
+ return this !== _() && this.focus ? (this.focus(), !1) : void 0
+ }, delegateType: "focusin"}, blur: {trigger: function () {
+ return this === _() && this.blur ? (this.blur(), !1) : void 0
+ }, delegateType: "focusout"}, click: {trigger: function () {
+ return"checkbox" === this.type && this.click && n.nodeName(this, "input") ? (this.click(), !1) : void 0
+ }, _default: function (a) {
+ return n.nodeName(a.target, "a")
+ }}, beforeunload: {postDispatch: function (a) {
+ void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result)
+ }}}, simulate: function (a, b, c, d) {
+ var e = n.extend(new n.Event, c, {type: a, isSimulated: !0, originalEvent: {}});
+ d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault()
+ }}, n.removeEvent = function (a, b, c) {
+ a.removeEventListener && a.removeEventListener(b, c, !1)
+ }, n.Event = function (a, b) {
+ return this instanceof n.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? Z : $) : this.type = a, b && n.extend(this, b), this.timeStamp = a && a.timeStamp || n.now(), void(this[n.expando] = !0)) : new n.Event(a, b)
+ }, n.Event.prototype = {isDefaultPrevented: $, isPropagationStopped: $, isImmediatePropagationStopped: $, preventDefault: function () {
+ var a = this.originalEvent;
+ this.isDefaultPrevented = Z, a && a.preventDefault && a.preventDefault()
+ }, stopPropagation: function () {
+ var a = this.originalEvent;
+ this.isPropagationStopped = Z, a && a.stopPropagation && a.stopPropagation()
+ }, stopImmediatePropagation: function () {
+ var a = this.originalEvent;
+ this.isImmediatePropagationStopped = Z, a && a.stopImmediatePropagation && a.stopImmediatePropagation(), this.stopPropagation()
+ }}, n.each({mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout"}, function (a, b) {
+ n.event.special[a] = {delegateType: b, bindType: b, handle: function (a) {
+ var c, d = this, e = a.relatedTarget, f = a.handleObj;
+ return(!e || e !== d && !n.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
+ }}
+ }), k.focusinBubbles || n.each({focus: "focusin", blur: "focusout"}, function (a, b) {
+ var c = function (a) {
+ n.event.simulate(b, a.target, n.event.fix(a), !0)
+ };
+ n.event.special[b] = {setup: function () {
+ var d = this.ownerDocument || this, e = L.access(d, b);
+ e || d.addEventListener(a, c, !0), L.access(d, b, (e || 0) + 1)
+ }, teardown: function () {
+ var d = this.ownerDocument || this, e = L.access(d, b) - 1;
+ e ? L.access(d, b, e) : (d.removeEventListener(a, c, !0), L.remove(d, b))
+ }}
+ }), n.fn.extend({on: function (a, b, c, d, e) {
+ var f, g;
+ if ("object" == typeof a) {
+ "string" != typeof b && (c = c || b, b = void 0);
+ for (g in a)this.on(g, b, c, a[g], e);
+ return this
+ }
+ if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1)d = $; else if (!d)return this;
+ return 1 === e && (f = d, d = function (a) {
+ return n().off(a), f.apply(this, arguments)
+ }, d.guid = f.guid || (f.guid = n.guid++)), this.each(function () {
+ n.event.add(this, a, d, c, b)
+ })
+ }, one: function (a, b, c, d) {
+ return this.on(a, b, c, d, 1)
+ }, off: function (a, b, c) {
+ var d, e;
+ if (a && a.preventDefault && a.handleObj)return d = a.handleObj, n(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
+ if ("object" == typeof a) {
+ for (e in a)this.off(e, b, a[e]);
+ return this
+ }
+ return(b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = $), this.each(function () {
+ n.event.remove(this, a, c, b)
+ })
+ }, trigger: function (a, b) {
+ return this.each(function () {
+ n.event.trigger(a, b, this)
+ })
+ }, triggerHandler: function (a, b) {
+ var c = this[0];
+ return c ? n.event.trigger(a, b, c, !0) : void 0
+ }});
+ var ab = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, bb = /<([\w:]+)/, cb = /<|?\w+;/, db = /<(?:script|style|link)/i, eb = /checked\s*(?:[^=]|=\s*.checked.)/i, fb = /^$|\/(?:java|ecma)script/i, gb = /^true\/(.*)/, hb = /^\s*\s*$/g, ib = {option: [1, "", " "], thead: [1, ""], col: [2, ""], tr: [2, ""], td: [3, ""], _default: [0, "", ""]};
+ ib.optgroup = ib.option, ib.tbody = ib.tfoot = ib.colgroup = ib.caption = ib.thead, ib.th = ib.td;
+ function jb(a, b) {
+ return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
+ }
+
+ function kb(a) {
+ return a.type = (null !== a.getAttribute("type")) + "/" + a.type, a
+ }
+
+ function lb(a) {
+ var b = gb.exec(a.type);
+ return b ? a.type = b[1] : a.removeAttribute("type"), a
+ }
+
+ function mb(a, b) {
+ for (var c = 0, d = a.length; d > c; c++)L.set(a[c], "globalEval", !b || L.get(b[c], "globalEval"))
+ }
+
+ function nb(a, b) {
+ var c, d, e, f, g, h, i, j;
+ if (1 === b.nodeType) {
+ if (L.hasData(a) && (f = L.access(a), g = L.set(b, f), j = f.events)) {
+ delete g.handle, g.events = {};
+ for (e in j)for (c = 0, d = j[e].length; d > c; c++)n.event.add(b, e, j[e][c])
+ }
+ M.hasData(a) && (h = M.access(a), i = n.extend({}, h), M.set(b, i))
+ }
+ }
+
+ function ob(a, b) {
+ var c = a.getElementsByTagName ? a.getElementsByTagName(b || "*") : a.querySelectorAll ? a.querySelectorAll(b || "*") : [];
+ return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], c) : c
+ }
+
+ function pb(a, b) {
+ var c = b.nodeName.toLowerCase();
+ "input" === c && T.test(a.type) ? b.checked = a.checked : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue)
+ }
+
+ n.extend({clone: function (a, b, c) {
+ var d, e, f, g, h = a.cloneNode(!0), i = n.contains(a.ownerDocument, a);
+ if (!(k.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))for (g = ob(h), f = ob(a), d = 0, e = f.length; e > d; d++)pb(f[d], g[d]);
+ if (b)if (c)for (f = f || ob(a), g = g || ob(h), d = 0, e = f.length; e > d; d++)nb(f[d], g[d]); else nb(a, h);
+ return g = ob(h, "script"), g.length > 0 && mb(g, !i && ob(a, "script")), h
+ }, buildFragment: function (a, b, c, d) {
+ for (var e, f, g, h, i, j, k = b.createDocumentFragment(), l = [], m = 0, o = a.length; o > m; m++)if (e = a[m], e || 0 === e)if ("object" === n.type(e))n.merge(l, e.nodeType ? [e] : e); else if (cb.test(e)) {
+ f = f || k.appendChild(b.createElement("div")), g = (bb.exec(e) || ["", ""])[1].toLowerCase(), h = ib[g] || ib._default, f.innerHTML = h[1] + e.replace(ab, "<$1>$2>") + h[2], j = h[0];
+ while (j--)f = f.lastChild;
+ n.merge(l, f.childNodes), f = k.firstChild, f.textContent = ""
+ } else l.push(b.createTextNode(e));
+ k.textContent = "", m = 0;
+ while (e = l[m++])if ((!d || -1 === n.inArray(e, d)) && (i = n.contains(e.ownerDocument, e), f = ob(k.appendChild(e), "script"), i && mb(f), c)) {
+ j = 0;
+ while (e = f[j++])fb.test(e.type || "") && c.push(e)
+ }
+ return k
+ }, cleanData: function (a) {
+ for (var b, c, d, e, f = n.event.special, g = 0; void 0 !== (c = a[g]); g++) {
+ if (n.acceptData(c) && (e = c[L.expando], e && (b = L.cache[e]))) {
+ if (b.events)for (d in b.events)f[d] ? n.event.remove(c, d) : n.removeEvent(c, d, b.handle);
+ L.cache[e] && delete L.cache[e]
+ }
+ delete M.cache[c[M.expando]]
+ }
+ }}), n.fn.extend({text: function (a) {
+ return J(this, function (a) {
+ return void 0 === a ? n.text(this) : this.empty().each(function () {
+ (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) && (this.textContent = a)
+ })
+ }, null, a, arguments.length)
+ }, append: function () {
+ return this.domManip(arguments, function (a) {
+ if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
+ var b = jb(this, a);
+ b.appendChild(a)
+ }
+ })
+ }, prepend: function () {
+ return this.domManip(arguments, function (a) {
+ if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
+ var b = jb(this, a);
+ b.insertBefore(a, b.firstChild)
+ }
+ })
+ }, before: function () {
+ return this.domManip(arguments, function (a) {
+ this.parentNode && this.parentNode.insertBefore(a, this)
+ })
+ }, after: function () {
+ return this.domManip(arguments, function (a) {
+ this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
+ })
+ }, remove: function (a, b) {
+ for (var c, d = a ? n.filter(a, this) : this, e = 0; null != (c = d[e]); e++)b || 1 !== c.nodeType || n.cleanData(ob(c)), c.parentNode && (b && n.contains(c.ownerDocument, c) && mb(ob(c, "script")), c.parentNode.removeChild(c));
+ return this
+ }, empty: function () {
+ for (var a, b = 0; null != (a = this[b]); b++)1 === a.nodeType && (n.cleanData(ob(a, !1)), a.textContent = "");
+ return this
+ }, clone: function (a, b) {
+ return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function () {
+ return n.clone(this, a, b)
+ })
+ }, html: function (a) {
+ return J(this, function (a) {
+ var b = this[0] || {}, c = 0, d = this.length;
+ if (void 0 === a && 1 === b.nodeType)return b.innerHTML;
+ if ("string" == typeof a && !db.test(a) && !ib[(bb.exec(a) || ["", ""])[1].toLowerCase()]) {
+ a = a.replace(ab, "<$1>$2>");
+ try {
+ for (; d > c; c++)b = this[c] || {}, 1 === b.nodeType && (n.cleanData(ob(b, !1)), b.innerHTML = a);
+ b = 0
+ } catch (e) {
+ }
+ }
+ b && this.empty().append(a)
+ }, null, a, arguments.length)
+ }, replaceWith: function () {
+ var a = arguments[0];
+ return this.domManip(arguments, function (b) {
+ a = this.parentNode, n.cleanData(ob(this)), a && a.replaceChild(b, this)
+ }), a && (a.length || a.nodeType) ? this : this.remove()
+ }, detach: function (a) {
+ return this.remove(a, !0)
+ }, domManip: function (a, b) {
+ a = e.apply([], a);
+ var c, d, f, g, h, i, j = 0, l = this.length, m = this, o = l - 1, p = a[0], q = n.isFunction(p);
+ if (q || l > 1 && "string" == typeof p && !k.checkClone && eb.test(p))return this.each(function (c) {
+ var d = m.eq(c);
+ q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b)
+ });
+ if (l && (c = n.buildFragment(a, this[0].ownerDocument, !1, this), d = c.firstChild, 1 === c.childNodes.length && (c = d), d)) {
+ for (f = n.map(ob(c, "script"), kb), g = f.length; l > j; j++)h = c, j !== o && (h = n.clone(h, !0, !0), g && n.merge(f, ob(h, "script"))), b.call(this[j], h, j);
+ if (g)for (i = f[f.length - 1].ownerDocument, n.map(f, lb), j = 0; g > j; j++)h = f[j], fb.test(h.type || "") && !L.access(h, "globalEval") && n.contains(i, h) && (h.src ? n._evalUrl && n._evalUrl(h.src) : n.globalEval(h.textContent.replace(hb, "")))
+ }
+ return this
+ }}), n.each({appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith"}, function (a, b) {
+ n.fn[a] = function (a) {
+ for (var c, d = [], e = n(a), g = e.length - 1, h = 0; g >= h; h++)c = h === g ? this : this.clone(!0), n(e[h])[b](c), f.apply(d, c.get());
+ return this.pushStack(d)
+ }
+ });
+ var qb, rb = {};
+
+ function sb(b, c) {
+ var d, e = n(c.createElement(b)).appendTo(c.body), f = a.getDefaultComputedStyle && (d = a.getDefaultComputedStyle(e[0])) ? d.display : n.css(e[0], "display");
+ return e.detach(), f
+ }
+
+ function tb(a) {
+ var b = l, c = rb[a];
+ return c || (c = sb(a, b), "none" !== c && c || (qb = (qb || n("")).appendTo(b.documentElement), b = qb[0].contentDocument, b.write(), b.close(), c = sb(a, b), qb.detach()), rb[a] = c), c
+ }
+
+ var ub = /^margin/, vb = new RegExp("^(" + Q + ")(?!px)[a-z%]+$", "i"), wb = function (b) {
+ return b.ownerDocument.defaultView.opener ? b.ownerDocument.defaultView.getComputedStyle(b, null) : a.getComputedStyle(b, null)
+ };
+
+ function xb(a, b, c) {
+ var d, e, f, g, h = a.style;
+ return c = c || wb(a), c && (g = c.getPropertyValue(b) || c[b]), c && ("" !== g || n.contains(a.ownerDocument, a) || (g = n.style(a, b)), vb.test(g) && ub.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 !== g ? g + "" : g
+ }
+
+ function yb(a, b) {
+ return{get: function () {
+ return a() ? void delete this.get : (this.get = b).apply(this, arguments)
+ }}
+ }
+
+ !function () {
+ var b, c, d = l.documentElement, e = l.createElement("div"), f = l.createElement("div");
+ if (f.style) {
+ f.style.backgroundClip = "content-box", f.cloneNode(!0).style.backgroundClip = "", k.clearCloneStyle = "content-box" === f.style.backgroundClip, e.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute", e.appendChild(f);
+ function g() {
+ f.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute", f.innerHTML = "", d.appendChild(e);
+ var g = a.getComputedStyle(f, null);
+ b = "1%" !== g.top, c = "4px" === g.width, d.removeChild(e)
+ }
+
+ a.getComputedStyle && n.extend(k, {pixelPosition: function () {
+ return g(), b
+ }, boxSizingReliable: function () {
+ return null == c && g(), c
+ }, reliableMarginRight: function () {
+ var b, c = f.appendChild(l.createElement("div"));
+ return c.style.cssText = f.style.cssText = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0", c.style.marginRight = c.style.width = "0", f.style.width = "1px", d.appendChild(e), b = !parseFloat(a.getComputedStyle(c, null).marginRight), d.removeChild(e), f.removeChild(c), b
+ }})
+ }
+ }(), n.swap = function (a, b, c, d) {
+ var e, f, g = {};
+ for (f in b)g[f] = a.style[f], a.style[f] = b[f];
+ e = c.apply(a, d || []);
+ for (f in b)a.style[f] = g[f];
+ return e
+ };
+ var zb = /^(none|table(?!-c[ea]).+)/, Ab = new RegExp("^(" + Q + ")(.*)$", "i"), Bb = new RegExp("^([+-])=(" + Q + ")", "i"), Cb = {position: "absolute", visibility: "hidden", display: "block"}, Db = {letterSpacing: "0", fontWeight: "400"}, Eb = ["Webkit", "O", "Moz", "ms"];
+
+ function Fb(a, b) {
+ if (b in a)return b;
+ var c = b[0].toUpperCase() + b.slice(1), d = b, e = Eb.length;
+ while (e--)if (b = Eb[e] + c, b in a)return b;
+ return d
+ }
+
+ function Gb(a, b, c) {
+ var d = Ab.exec(b);
+ return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b
+ }
+
+ function Hb(a, b, c, d, e) {
+ for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2)"margin" === c && (g += n.css(a, c + R[f], !0, e)), d ? ("content" === c && (g -= n.css(a, "padding" + R[f], !0, e)), "margin" !== c && (g -= n.css(a, "border" + R[f] + "Width", !0, e))) : (g += n.css(a, "padding" + R[f], !0, e), "padding" !== c && (g += n.css(a, "border" + R[f] + "Width", !0, e)));
+ return g
+ }
+
+ function Ib(a, b, c) {
+ var d = !0, e = "width" === b ? a.offsetWidth : a.offsetHeight, f = wb(a), g = "border-box" === n.css(a, "boxSizing", !1, f);
+ if (0 >= e || null == e) {
+ if (e = xb(a, b, f), (0 > e || null == e) && (e = a.style[b]), vb.test(e))return e;
+ d = g && (k.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
+ }
+ return e + Hb(a, b, c || (g ? "border" : "content"), d, f) + "px"
+ }
+
+ function Jb(a, b) {
+ for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++)d = a[g], d.style && (f[g] = L.get(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && S(d) && (f[g] = L.access(d, "olddisplay", tb(d.nodeName)))) : (e = S(d), "none" === c && e || L.set(d, "olddisplay", e ? c : n.css(d, "display"))));
+ for (g = 0; h > g; g++)d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
+ return a
+ }
+
+ n.extend({cssHooks: {opacity: {get: function (a, b) {
+ if (b) {
+ var c = xb(a, "opacity");
+ return"" === c ? "1" : c
+ }
+ }}}, cssNumber: {columnCount: !0, fillOpacity: !0, flexGrow: !0, flexShrink: !0, fontWeight: !0, lineHeight: !0, opacity: !0, order: !0, orphans: !0, widows: !0, zIndex: !0, zoom: !0}, cssProps: {"float": "cssFloat"}, style: function (a, b, c, d) {
+ if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
+ var e, f, g, h = n.camelCase(b), i = a.style;
+ return b = n.cssProps[h] || (n.cssProps[h] = Fb(i, h)), g = n.cssHooks[b] || n.cssHooks[h], void 0 === c ? g && "get"in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b] : (f = typeof c, "string" === f && (e = Bb.exec(c)) && (c = (e[1] + 1) * e[2] + parseFloat(n.css(a, b)), f = "number"), null != c && c === c && ("number" !== f || n.cssNumber[h] || (c += "px"), k.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), g && "set"in g && void 0 === (c = g.set(a, c, d)) || (i[b] = c)), void 0)
+ }
+ }, css: function (a, b, c, d) {
+ var e, f, g, h = n.camelCase(b);
+ return b = n.cssProps[h] || (n.cssProps[h] = Fb(a.style, h)), g = n.cssHooks[b] || n.cssHooks[h], g && "get"in g && (e = g.get(a, !0, c)), void 0 === e && (e = xb(a, b, d)), "normal" === e && b in Db && (e = Db[b]), "" === c || c ? (f = parseFloat(e), c === !0 || n.isNumeric(f) ? f || 0 : e) : e
+ }}), n.each(["height", "width"], function (a, b) {
+ n.cssHooks[b] = {get: function (a, c, d) {
+ return c ? zb.test(n.css(a, "display")) && 0 === a.offsetWidth ? n.swap(a, Cb, function () {
+ return Ib(a, b, d)
+ }) : Ib(a, b, d) : void 0
+ }, set: function (a, c, d) {
+ var e = d && wb(a);
+ return Gb(a, c, d ? Hb(a, b, d, "border-box" === n.css(a, "boxSizing", !1, e), e) : 0)
+ }}
+ }), n.cssHooks.marginRight = yb(k.reliableMarginRight, function (a, b) {
+ return b ? n.swap(a, {display: "inline-block"}, xb, [a, "marginRight"]) : void 0
+ }), n.each({margin: "", padding: "", border: "Width"}, function (a, b) {
+ n.cssHooks[a + b] = {expand: function (c) {
+ for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++)e[a + R[d] + b] = f[d] || f[d - 2] || f[0];
+ return e
+ }}, ub.test(a) || (n.cssHooks[a + b].set = Gb)
+ }), n.fn.extend({css: function (a, b) {
+ return J(this, function (a, b, c) {
+ var d, e, f = {}, g = 0;
+ if (n.isArray(b)) {
+ for (d = wb(a), e = b.length; e > g; g++)f[b[g]] = n.css(a, b[g], !1, d);
+ return f
+ }
+ return void 0 !== c ? n.style(a, b, c) : n.css(a, b)
+ }, a, b, arguments.length > 1)
+ }, show: function () {
+ return Jb(this, !0)
+ }, hide: function () {
+ return Jb(this)
+ }, toggle: function (a) {
+ return"boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function () {
+ S(this) ? n(this).show() : n(this).hide()
+ })
+ }});
+ function Kb(a, b, c, d, e) {
+ return new Kb.prototype.init(a, b, c, d, e)
+ }
+
+ n.Tween = Kb, Kb.prototype = {constructor: Kb, init: function (a, b, c, d, e, f) {
+ this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (n.cssNumber[c] ? "" : "px")
+ }, cur: function () {
+ var a = Kb.propHooks[this.prop];
+ return a && a.get ? a.get(this) : Kb.propHooks._default.get(this)
+ }, run: function (a) {
+ var b, c = Kb.propHooks[this.prop];
+ return this.pos = b = this.options.duration ? n.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : Kb.propHooks._default.set(this), this
+ }}, Kb.prototype.init.prototype = Kb.prototype, Kb.propHooks = {_default: {get: function (a) {
+ var b;
+ return null == a.elem[a.prop] || a.elem.style && null != a.elem.style[a.prop] ? (b = n.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) : a.elem[a.prop]
+ }, set: function (a) {
+ n.fx.step[a.prop] ? n.fx.step[a.prop](a) : a.elem.style && (null != a.elem.style[n.cssProps[a.prop]] || n.cssHooks[a.prop]) ? n.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now
+ }}}, Kb.propHooks.scrollTop = Kb.propHooks.scrollLeft = {set: function (a) {
+ a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
+ }}, n.easing = {linear: function (a) {
+ return a
+ }, swing: function (a) {
+ return.5 - Math.cos(a * Math.PI) / 2
+ }}, n.fx = Kb.prototype.init, n.fx.step = {};
+ var Lb, Mb, Nb = /^(?:toggle|show|hide)$/, Ob = new RegExp("^(?:([+-])=|)(" + Q + ")([a-z%]*)$", "i"), Pb = /queueHooks$/, Qb = [Vb], Rb = {"*": [function (a, b) {
+ var c = this.createTween(a, b), d = c.cur(), e = Ob.exec(b), f = e && e[3] || (n.cssNumber[a] ? "" : "px"), g = (n.cssNumber[a] || "px" !== f && +d) && Ob.exec(n.css(c.elem, a)), h = 1, i = 20;
+ if (g && g[3] !== f) {
+ f = f || g[3], e = e || [], g = +d || 1;
+ do h = h || ".5", g /= h, n.style(c.elem, a, g + f); while (h !== (h = c.cur() / d) && 1 !== h && --i)
+ }
+ return e && (g = c.start = +g || +d || 0, c.unit = f, c.end = e[1] ? g + (e[1] + 1) * e[2] : +e[2]), c
+ }]};
+
+ function Sb() {
+ return setTimeout(function () {
+ Lb = void 0
+ }), Lb = n.now()
+ }
+
+ function Tb(a, b) {
+ var c, d = 0, e = {height: a};
+ for (b = b ? 1 : 0; 4 > d; d += 2 - b)c = R[d], e["margin" + c] = e["padding" + c] = a;
+ return b && (e.opacity = e.width = a), e
+ }
+
+ function Ub(a, b, c) {
+ for (var d, e = (Rb[b] || []).concat(Rb["*"]), f = 0, g = e.length; g > f; f++)if (d = e[f].call(c, b, a))return d
+ }
+
+ function Vb(a, b, c) {
+ var d, e, f, g, h, i, j, k, l = this, m = {}, o = a.style, p = a.nodeType && S(a), q = L.get(a, "fxshow");
+ c.queue || (h = n._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function () {
+ h.unqueued || i()
+ }), h.unqueued++, l.always(function () {
+ l.always(function () {
+ h.unqueued--, n.queue(a, "fx").length || h.empty.fire()
+ })
+ })), 1 === a.nodeType && ("height"in b || "width"in b) && (c.overflow = [o.overflow, o.overflowX, o.overflowY], j = n.css(a, "display"), k = "none" === j ? L.get(a, "olddisplay") || tb(a.nodeName) : j, "inline" === k && "none" === n.css(a, "float") && (o.display = "inline-block")), c.overflow && (o.overflow = "hidden", l.always(function () {
+ o.overflow = c.overflow[0], o.overflowX = c.overflow[1], o.overflowY = c.overflow[2]
+ }));
+ for (d in b)if (e = b[d], Nb.exec(e)) {
+ if (delete b[d], f = f || "toggle" === e, e === (p ? "hide" : "show")) {
+ if ("show" !== e || !q || void 0 === q[d])continue;
+ p = !0
+ }
+ m[d] = q && q[d] || n.style(a, d)
+ } else j = void 0;
+ if (n.isEmptyObject(m))"inline" === ("none" === j ? tb(a.nodeName) : j) && (o.display = j); else {
+ q ? "hidden"in q && (p = q.hidden) : q = L.access(a, "fxshow", {}), f && (q.hidden = !p), p ? n(a).show() : l.done(function () {
+ n(a).hide()
+ }), l.done(function () {
+ var b;
+ L.remove(a, "fxshow");
+ for (b in m)n.style(a, b, m[b])
+ });
+ for (d in m)g = Ub(p ? q[d] : 0, d, l), d in q || (q[d] = g.start, p && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
+ }
+ }
+
+ function Wb(a, b) {
+ var c, d, e, f, g;
+ for (c in a)if (d = n.camelCase(c), e = b[d], f = a[c], n.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = n.cssHooks[d], g && "expand"in g) {
+ f = g.expand(f), delete a[d];
+ for (c in f)c in a || (a[c] = f[c], b[c] = e)
+ } else b[d] = e
+ }
+
+ function Xb(a, b, c) {
+ var d, e, f = 0, g = Qb.length, h = n.Deferred().always(function () {
+ delete i.elem
+ }), i = function () {
+ if (e)return!1;
+ for (var b = Lb || Sb(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++)j.tweens[g].run(f);
+ return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
+ }, j = h.promise({elem: a, props: n.extend({}, b), opts: n.extend(!0, {specialEasing: {}}, c), originalProperties: b, originalOptions: c, startTime: Lb || Sb(), duration: c.duration, tweens: [], createTween: function (b, c) {
+ var d = n.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
+ return j.tweens.push(d), d
+ }, stop: function (b) {
+ var c = 0, d = b ? j.tweens.length : 0;
+ if (e)return this;
+ for (e = !0; d > c; c++)j.tweens[c].run(1);
+ return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this
+ }}), k = j.props;
+ for (Wb(k, j.opts.specialEasing); g > f; f++)if (d = Qb[f].call(j, a, k, j.opts))return d;
+ return n.map(k, Ub, j), n.isFunction(j.opts.start) && j.opts.start.call(a, j), n.fx.timer(n.extend(i, {elem: a, anim: j, queue: j.opts.queue})), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
+ }
+
+ n.Animation = n.extend(Xb, {tweener: function (a, b) {
+ n.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" ");
+ for (var c, d = 0, e = a.length; e > d; d++)c = a[d], Rb[c] = Rb[c] || [], Rb[c].unshift(b)
+ }, prefilter: function (a, b) {
+ b ? Qb.unshift(a) : Qb.push(a)
+ }}), n.speed = function (a, b, c) {
+ var d = a && "object" == typeof a ? n.extend({}, a) : {complete: c || !c && b || n.isFunction(a) && a, duration: a, easing: c && b || b && !n.isFunction(b) && b};
+ return d.duration = n.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default, (null == d.queue || d.queue === !0) && (d.queue = "fx"), d.old = d.complete, d.complete = function () {
+ n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue)
+ }, d
+ }, n.fn.extend({fadeTo: function (a, b, c, d) {
+ return this.filter(S).css("opacity", 0).show().end().animate({opacity: b}, a, c, d)
+ }, animate: function (a, b, c, d) {
+ var e = n.isEmptyObject(a), f = n.speed(b, c, d), g = function () {
+ var b = Xb(this, n.extend({}, a), f);
+ (e || L.get(this, "finish")) && b.stop(!0)
+ };
+ return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
+ }, stop: function (a, b, c) {
+ var d = function (a) {
+ var b = a.stop;
+ delete a.stop, b(c)
+ };
+ return"string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function () {
+ var b = !0, e = null != a && a + "queueHooks", f = n.timers, g = L.get(this);
+ if (e)g[e] && g[e].stop && d(g[e]); else for (e in g)g[e] && g[e].stop && Pb.test(e) && d(g[e]);
+ for (e = f.length; e--;)f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
+ (b || !c) && n.dequeue(this, a)
+ })
+ }, finish: function (a) {
+ return a !== !1 && (a = a || "fx"), this.each(function () {
+ var b, c = L.get(this), d = c[a + "queue"], e = c[a + "queueHooks"], f = n.timers, g = d ? d.length : 0;
+ for (c.finish = !0, n.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;)f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
+ for (b = 0; g > b; b++)d[b] && d[b].finish && d[b].finish.call(this);
+ delete c.finish
+ })
+ }}), n.each(["toggle", "show", "hide"], function (a, b) {
+ var c = n.fn[b];
+ n.fn[b] = function (a, d, e) {
+ return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(Tb(b, !0), a, d, e)
+ }
+ }), n.each({slideDown: Tb("show"), slideUp: Tb("hide"), slideToggle: Tb("toggle"), fadeIn: {opacity: "show"}, fadeOut: {opacity: "hide"}, fadeToggle: {opacity: "toggle"}}, function (a, b) {
+ n.fn[a] = function (a, c, d) {
+ return this.animate(b, a, c, d)
+ }
+ }), n.timers = [], n.fx.tick = function () {
+ var a, b = 0, c = n.timers;
+ for (Lb = n.now(); b < c.length; b++)a = c[b], a() || c[b] !== a || c.splice(b--, 1);
+ c.length || n.fx.stop(), Lb = void 0
+ }, n.fx.timer = function (a) {
+ n.timers.push(a), a() ? n.fx.start() : n.timers.pop()
+ }, n.fx.interval = 13, n.fx.start = function () {
+ Mb || (Mb = setInterval(n.fx.tick, n.fx.interval))
+ }, n.fx.stop = function () {
+ clearInterval(Mb), Mb = null
+ }, n.fx.speeds = {slow: 600, fast: 200, _default: 400}, n.fn.delay = function (a, b) {
+ return a = n.fx ? n.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function (b, c) {
+ var d = setTimeout(b, a);
+ c.stop = function () {
+ clearTimeout(d)
+ }
+ })
+ }, function () {
+ var a = l.createElement("input"), b = l.createElement("select"), c = b.appendChild(l.createElement("option"));
+ a.type = "checkbox", k.checkOn = "" !== a.value, k.optSelected = c.selected, b.disabled = !0, k.optDisabled = !c.disabled, a = l.createElement("input"), a.value = "t", a.type = "radio", k.radioValue = "t" === a.value
+ }();
+ var Yb, Zb, $b = n.expr.attrHandle;
+ n.fn.extend({attr: function (a, b) {
+ return J(this, n.attr, a, b, arguments.length > 1)
+ }, removeAttr: function (a) {
+ return this.each(function () {
+ n.removeAttr(this, a)
+ })
+ }}), n.extend({attr: function (a, b, c) {
+ var d, e, f = a.nodeType;
+ if (a && 3 !== f && 8 !== f && 2 !== f)return typeof a.getAttribute === U ? n.prop(a, b, c) : (1 === f && n.isXMLDoc(a) || (b = b.toLowerCase(), d = n.attrHooks[b] || (n.expr.match.bool.test(b) ? Zb : Yb)), void 0 === c ? d && "get"in d && null !== (e = d.get(a, b)) ? e : (e = n.find.attr(a, b), null == e ? void 0 : e) : null !== c ? d && "set"in d && void 0 !== (e = d.set(a, c, b)) ? e : (a.setAttribute(b, c + ""), c) : void n.removeAttr(a, b))
+ }, removeAttr: function (a, b) {
+ var c, d, e = 0, f = b && b.match(E);
+ if (f && 1 === a.nodeType)while (c = f[e++])d = n.propFix[c] || c, n.expr.match.bool.test(c) && (a[d] = !1), a.removeAttribute(c)
+ }, attrHooks: {type: {set: function (a, b) {
+ if (!k.radioValue && "radio" === b && n.nodeName(a, "input")) {
+ var c = a.value;
+ return a.setAttribute("type", b), c && (a.value = c), b
+ }
+ }}}}), Zb = {set: function (a, b, c) {
+ return b === !1 ? n.removeAttr(a, c) : a.setAttribute(c, c), c
+ }}, n.each(n.expr.match.bool.source.match(/\w+/g), function (a, b) {
+ var c = $b[b] || n.find.attr;
+ $b[b] = function (a, b, d) {
+ var e, f;
+ return d || (f = $b[b], $b[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, $b[b] = f), e
+ }
+ });
+ var _b = /^(?:input|select|textarea|button)$/i;
+ n.fn.extend({prop: function (a, b) {
+ return J(this, n.prop, a, b, arguments.length > 1)
+ }, removeProp: function (a) {
+ return this.each(function () {
+ delete this[n.propFix[a] || a]
+ })
+ }}), n.extend({propFix: {"for": "htmlFor", "class": "className"}, prop: function (a, b, c) {
+ var d, e, f, g = a.nodeType;
+ if (a && 3 !== g && 8 !== g && 2 !== g)return f = 1 !== g || !n.isXMLDoc(a), f && (b = n.propFix[b] || b, e = n.propHooks[b]), void 0 !== c ? e && "set"in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get"in e && null !== (d = e.get(a, b)) ? d : a[b]
+ }, propHooks: {tabIndex: {get: function (a) {
+ return a.hasAttribute("tabindex") || _b.test(a.nodeName) || a.href ? a.tabIndex : -1
+ }}}}), k.optSelected || (n.propHooks.selected = {get: function (a) {
+ var b = a.parentNode;
+ return b && b.parentNode && b.parentNode.selectedIndex, null
+ }}), n.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
+ n.propFix[this.toLowerCase()] = this
+ });
+ var ac = /[\t\r\n\f]/g;
+ n.fn.extend({addClass: function (a) {
+ var b, c, d, e, f, g, h = "string" == typeof a && a, i = 0, j = this.length;
+ if (n.isFunction(a))return this.each(function (b) {
+ n(this).addClass(a.call(this, b, this.className))
+ });
+ if (h)for (b = (a || "").match(E) || []; j > i; i++)if (c = this[i], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(ac, " ") : " ")) {
+ f = 0;
+ while (e = b[f++])d.indexOf(" " + e + " ") < 0 && (d += e + " ");
+ g = n.trim(d), c.className !== g && (c.className = g)
+ }
+ return this
+ }, removeClass: function (a) {
+ var b, c, d, e, f, g, h = 0 === arguments.length || "string" == typeof a && a, i = 0, j = this.length;
+ if (n.isFunction(a))return this.each(function (b) {
+ n(this).removeClass(a.call(this, b, this.className))
+ });
+ if (h)for (b = (a || "").match(E) || []; j > i; i++)if (c = this[i], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(ac, " ") : "")) {
+ f = 0;
+ while (e = b[f++])while (d.indexOf(" " + e + " ") >= 0)d = d.replace(" " + e + " ", " ");
+ g = a ? n.trim(d) : "", c.className !== g && (c.className = g)
+ }
+ return this
+ }, toggleClass: function (a, b) {
+ var c = typeof a;
+ return"boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : this.each(n.isFunction(a) ? function (c) {
+ n(this).toggleClass(a.call(this, c, this.className, b), b)
+ } : function () {
+ if ("string" === c) {
+ var b, d = 0, e = n(this), f = a.match(E) || [];
+ while (b = f[d++])e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
+ } else(c === U || "boolean" === c) && (this.className && L.set(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : L.get(this, "__className__") || "")
+ })
+ }, hasClass: function (a) {
+ for (var b = " " + a + " ", c = 0, d = this.length; d > c; c++)if (1 === this[c].nodeType && (" " + this[c].className + " ").replace(ac, " ").indexOf(b) >= 0)return!0;
+ return!1
+ }});
+ var bc = /\r/g;
+ n.fn.extend({val: function (a) {
+ var b, c, d, e = this[0];
+ {
+ if (arguments.length)return d = n.isFunction(a), this.each(function (c) {
+ var e;
+ 1 === this.nodeType && (e = d ? a.call(this, c, n(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : n.isArray(e) && (e = n.map(e, function (a) {
+ return null == a ? "" : a + ""
+ })), b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()], b && "set"in b && void 0 !== b.set(this, e, "value") || (this.value = e))
+ });
+ if (e)return b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()], b && "get"in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(bc, "") : null == c ? "" : c)
+ }
+ }}), n.extend({valHooks: {option: {get: function (a) {
+ var b = n.find.attr(a, "value");
+ return null != b ? b : n.trim(n.text(a))
+ }}, select: {get: function (a) {
+ for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)if (c = d[i], !(!c.selected && i !== e || (k.optDisabled ? c.disabled : null !== c.getAttribute("disabled")) || c.parentNode.disabled && n.nodeName(c.parentNode, "optgroup"))) {
+ if (b = n(c).val(), f)return b;
+ g.push(b)
+ }
+ return g
+ }, set: function (a, b) {
+ var c, d, e = a.options, f = n.makeArray(b), g = e.length;
+ while (g--)d = e[g], (d.selected = n.inArray(d.value, f) >= 0) && (c = !0);
+ return c || (a.selectedIndex = -1), f
+ }}}}), n.each(["radio", "checkbox"], function () {
+ n.valHooks[this] = {set: function (a, b) {
+ return n.isArray(b) ? a.checked = n.inArray(n(a).val(), b) >= 0 : void 0
+ }}, k.checkOn || (n.valHooks[this].get = function (a) {
+ return null === a.getAttribute("value") ? "on" : a.value
+ })
+ }), n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function (a, b) {
+ n.fn[b] = function (a, c) {
+ return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
+ }
+ }), n.fn.extend({hover: function (a, b) {
+ return this.mouseenter(a).mouseleave(b || a)
+ }, bind: function (a, b, c) {
+ return this.on(a, null, b, c)
+ }, unbind: function (a, b) {
+ return this.off(a, null, b)
+ }, delegate: function (a, b, c, d) {
+ return this.on(b, a, c, d)
+ }, undelegate: function (a, b, c) {
+ return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
+ }});
+ var cc = n.now(), dc = /\?/;
+ n.parseJSON = function (a) {
+ return JSON.parse(a + "")
+ }, n.parseXML = function (a) {
+ var b, c;
+ if (!a || "string" != typeof a)return null;
+ try {
+ c = new DOMParser, b = c.parseFromString(a, "text/xml")
+ } catch (d) {
+ b = void 0
+ }
+ return(!b || b.getElementsByTagName("parsererror").length) && n.error("Invalid XML: " + a), b
+ };
+ var ec = /#.*$/, fc = /([?&])_=[^&]*/, gc = /^(.*?):[ \t]*([^\r\n]*)$/gm, hc = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, ic = /^(?:GET|HEAD)$/, jc = /^\/\//, kc = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, lc = {}, mc = {}, nc = "*/".concat("*"), oc = a.location.href, pc = kc.exec(oc.toLowerCase()) || [];
+
+ function qc(a) {
+ return function (b, c) {
+ "string" != typeof b && (c = b, b = "*");
+ var d, e = 0, f = b.toLowerCase().match(E) || [];
+ if (n.isFunction(c))while (d = f[e++])"+" === d[0] ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
+ }
+ }
+
+ function rc(a, b, c, d) {
+ var e = {}, f = a === mc;
+
+ function g(h) {
+ var i;
+ return e[h] = !0, n.each(a[h] || [], function (a, h) {
+ var j = h(b, c, d);
+ return"string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
+ }), i
+ }
+
+ return g(b.dataTypes[0]) || !e["*"] && g("*")
+ }
+
+ function sc(a, b) {
+ var c, d, e = n.ajaxSettings.flatOptions || {};
+ for (c in b)void 0 !== b[c] && ((e[c] ? a : d || (d = {}))[c] = b[c]);
+ return d && n.extend(!0, a, d), a
+ }
+
+ function tc(a, b, c) {
+ var d, e, f, g, h = a.contents, i = a.dataTypes;
+ while ("*" === i[0])i.shift(), void 0 === d && (d = a.mimeType || b.getResponseHeader("Content-Type"));
+ if (d)for (e in h)if (h[e] && h[e].test(d)) {
+ i.unshift(e);
+ break
+ }
+ if (i[0]in c)f = i[0]; else {
+ for (e in c) {
+ if (!i[0] || a.converters[e + " " + i[0]]) {
+ f = e;
+ break
+ }
+ g || (g = e)
+ }
+ f = f || g
+ }
+ return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
+ }
+
+ function uc(a, b, c, d) {
+ var e, f, g, h, i, j = {}, k = a.dataTypes.slice();
+ if (k[1])for (g in a.converters)j[g.toLowerCase()] = a.converters[g];
+ f = k.shift();
+ while (f)if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())if ("*" === f)f = i; else if ("*" !== i && i !== f) {
+ if (g = j[i + " " + f] || j["* " + f], !g)for (e in j)if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
+ g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
+ break
+ }
+ if (g !== !0)if (g && a["throws"])b = g(b); else try {
+ b = g(b)
+ } catch (l) {
+ return{state: "parsererror", error: g ? l : "No conversion from " + i + " to " + f}
+ }
+ }
+ return{state: "success", data: b}
+ }
+
+ n.extend({active: 0, lastModified: {}, etag: {}, ajaxSettings: {url: oc, type: "GET", isLocal: hc.test(pc[1]), global: !0, processData: !0, async: !0, contentType: "application/x-www-form-urlencoded; charset=UTF-8", accepts: {"*": nc, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript"}, contents: {xml: /xml/, html: /html/, json: /json/}, responseFields: {xml: "responseXML", text: "responseText", json: "responseJSON"}, converters: {"* text": String, "text html": !0, "text json": n.parseJSON, "text xml": n.parseXML}, flatOptions: {url: !0, context: !0}}, ajaxSetup: function (a, b) {
+ return b ? sc(sc(a, n.ajaxSettings), b) : sc(n.ajaxSettings, a)
+ }, ajaxPrefilter: qc(lc), ajaxTransport: qc(mc), ajax: function (a, b) {
+ "object" == typeof a && (b = a, a = void 0), b = b || {};
+ var c, d, e, f, g, h, i, j, k = n.ajaxSetup({}, b), l = k.context || k, m = k.context && (l.nodeType || l.jquery) ? n(l) : n.event, o = n.Deferred(), p = n.Callbacks("once memory"), q = k.statusCode || {}, r = {}, s = {}, t = 0, u = "canceled", v = {readyState: 0, getResponseHeader: function (a) {
+ var b;
+ if (2 === t) {
+ if (!f) {
+ f = {};
+ while (b = gc.exec(e))f[b[1].toLowerCase()] = b[2]
+ }
+ b = f[a.toLowerCase()]
+ }
+ return null == b ? null : b
+ }, getAllResponseHeaders: function () {
+ return 2 === t ? e : null
+ }, setRequestHeader: function (a, b) {
+ var c = a.toLowerCase();
+ return t || (a = s[c] = s[c] || a, r[a] = b), this
+ }, overrideMimeType: function (a) {
+ return t || (k.mimeType = a), this
+ }, statusCode: function (a) {
+ var b;
+ if (a)if (2 > t)for (b in a)q[b] = [q[b], a[b]]; else v.always(a[v.status]);
+ return this
+ }, abort: function (a) {
+ var b = a || u;
+ return c && c.abort(b), x(0, b), this
+ }};
+ if (o.promise(v).complete = p.add, v.success = v.done, v.error = v.fail, k.url = ((a || k.url || oc) + "").replace(ec, "").replace(jc, pc[1] + "//"), k.type = b.method || b.type || k.method || k.type, k.dataTypes = n.trim(k.dataType || "*").toLowerCase().match(E) || [""], null == k.crossDomain && (h = kc.exec(k.url.toLowerCase()), k.crossDomain = !(!h || h[1] === pc[1] && h[2] === pc[2] && (h[3] || ("http:" === h[1] ? "80" : "443")) === (pc[3] || ("http:" === pc[1] ? "80" : "443")))), k.data && k.processData && "string" != typeof k.data && (k.data = n.param(k.data, k.traditional)), rc(lc, k, b, v), 2 === t)return v;
+ i = n.event && k.global, i && 0 === n.active++ && n.event.trigger("ajaxStart"), k.type = k.type.toUpperCase(), k.hasContent = !ic.test(k.type), d = k.url, k.hasContent || (k.data && (d = k.url += (dc.test(d) ? "&" : "?") + k.data, delete k.data), k.cache === !1 && (k.url = fc.test(d) ? d.replace(fc, "$1_=" + cc++) : d + (dc.test(d) ? "&" : "?") + "_=" + cc++)), k.ifModified && (n.lastModified[d] && v.setRequestHeader("If-Modified-Since", n.lastModified[d]), n.etag[d] && v.setRequestHeader("If-None-Match", n.etag[d])), (k.data && k.hasContent && k.contentType !== !1 || b.contentType) && v.setRequestHeader("Content-Type", k.contentType), v.setRequestHeader("Accept", k.dataTypes[0] && k.accepts[k.dataTypes[0]] ? k.accepts[k.dataTypes[0]] + ("*" !== k.dataTypes[0] ? ", " + nc + "; q=0.01" : "") : k.accepts["*"]);
+ for (j in k.headers)v.setRequestHeader(j, k.headers[j]);
+ if (k.beforeSend && (k.beforeSend.call(l, v, k) === !1 || 2 === t))return v.abort();
+ u = "abort";
+ for (j in{success: 1, error: 1, complete: 1})v[j](k[j]);
+ if (c = rc(mc, k, b, v)) {
+ v.readyState = 1, i && m.trigger("ajaxSend", [v, k]), k.async && k.timeout > 0 && (g = setTimeout(function () {
+ v.abort("timeout")
+ }, k.timeout));
+ try {
+ t = 1, c.send(r, x)
+ } catch (w) {
+ if (!(2 > t))throw w;
+ x(-1, w)
+ }
+ } else x(-1, "No Transport");
+ function x(a, b, f, h) {
+ var j, r, s, u, w, x = b;
+ 2 !== t && (t = 2, g && clearTimeout(g), c = void 0, e = h || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a, f && (u = tc(k, v, f)), u = uc(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"), w && (n.lastModified[d] = w), w = v.getResponseHeader("etag"), w && (n.etag[d] = w)), 204 === a || "HEAD" === k.type ? x = "nocontent" : 304 === a ? x = "notmodified" : (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, i && m.trigger(j ? "ajaxSuccess" : "ajaxError", [v, k, j ? r : s]), p.fireWith(l, [v, x]), i && (m.trigger("ajaxComplete", [v, k]), --n.active || n.event.trigger("ajaxStop")))
+ }
+
+ return v
+ }, getJSON: function (a, b, c) {
+ return n.get(a, b, c, "json")
+ }, getScript: function (a, b) {
+ return n.get(a, void 0, b, "script")
+ }}), n.each(["get", "post"], function (a, b) {
+ n[b] = function (a, c, d, e) {
+ return n.isFunction(c) && (e = e || d, d = c, c = void 0), n.ajax({url: a, type: b, dataType: e, data: c, success: d})
+ }
+ }), n._evalUrl = function (a) {
+ return n.ajax({url: a, type: "GET", dataType: "script", async: !1, global: !1, "throws": !0})
+ }, n.fn.extend({wrapAll: function (a) {
+ var b;
+ return n.isFunction(a) ? this.each(function (b) {
+ n(this).wrapAll(a.call(this, b))
+ }) : (this[0] && (b = n(a, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && b.insertBefore(this[0]), b.map(function () {
+ var a = this;
+ while (a.firstElementChild)a = a.firstElementChild;
+ return a
+ }).append(this)), this)
+ }, wrapInner: function (a) {
+ return this.each(n.isFunction(a) ? function (b) {
+ n(this).wrapInner(a.call(this, b))
+ } : function () {
+ var b = n(this), c = b.contents();
+ c.length ? c.wrapAll(a) : b.append(a)
+ })
+ }, wrap: function (a) {
+ var b = n.isFunction(a);
+ return this.each(function (c) {
+ n(this).wrapAll(b ? a.call(this, c) : a)
+ })
+ }, unwrap: function () {
+ return this.parent().each(function () {
+ n.nodeName(this, "body") || n(this).replaceWith(this.childNodes)
+ }).end()
+ }}), n.expr.filters.hidden = function (a) {
+ return a.offsetWidth <= 0 && a.offsetHeight <= 0
+ }, n.expr.filters.visible = function (a) {
+ return!n.expr.filters.hidden(a)
+ };
+ var vc = /%20/g, wc = /\[\]$/, xc = /\r?\n/g, yc = /^(?:submit|button|image|reset|file)$/i, zc = /^(?:input|select|textarea|keygen)/i;
+
+ function Ac(a, b, c, d) {
+ var e;
+ if (n.isArray(b))n.each(b, function (b, e) {
+ c || wc.test(a) ? d(a, e) : Ac(a + "[" + ("object" == typeof e ? b : "") + "]", e, c, d)
+ }); else if (c || "object" !== n.type(b))d(a, b); else for (e in b)Ac(a + "[" + e + "]", b[e], c, d)
+ }
+
+ n.param = function (a, b) {
+ var c, d = [], e = function (a, b) {
+ b = n.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
+ };
+ if (void 0 === b && (b = n.ajaxSettings && n.ajaxSettings.traditional), n.isArray(a) || a.jquery && !n.isPlainObject(a))n.each(a, function () {
+ e(this.name, this.value)
+ }); else for (c in a)Ac(c, a[c], b, e);
+ return d.join("&").replace(vc, "+")
+ }, n.fn.extend({serialize: function () {
+ return n.param(this.serializeArray())
+ }, serializeArray: function () {
+ return this.map(function () {
+ var a = n.prop(this, "elements");
+ return a ? n.makeArray(a) : this
+ }).filter(function () {
+ var a = this.type;
+ return this.name && !n(this).is(":disabled") && zc.test(this.nodeName) && !yc.test(a) && (this.checked || !T.test(a))
+ }).map(function (a, b) {
+ var c = n(this).val();
+ return null == c ? null : n.isArray(c) ? n.map(c, function (a) {
+ return{name: b.name, value: a.replace(xc, "\r\n")}
+ }) : {name: b.name, value: c.replace(xc, "\r\n")}
+ }).get()
+ }}), n.ajaxSettings.xhr = function () {
+ try {
+ return new XMLHttpRequest
+ } catch (a) {
+ }
+ };
+ var Bc = 0, Cc = {}, Dc = {0: 200, 1223: 204}, Ec = n.ajaxSettings.xhr();
+ a.attachEvent && a.attachEvent("onunload", function () {
+ for (var a in Cc)Cc[a]()
+ }), k.cors = !!Ec && "withCredentials"in Ec, k.ajax = Ec = !!Ec, n.ajaxTransport(function (a) {
+ var b;
+ return k.cors || Ec && !a.crossDomain ? {send: function (c, d) {
+ var e, f = a.xhr(), g = ++Bc;
+ if (f.open(a.type, a.url, a.async, a.username, a.password), a.xhrFields)for (e in a.xhrFields)f[e] = a.xhrFields[e];
+ a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType), a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
+ for (e in c)f.setRequestHeader(e, c[e]);
+ b = function (a) {
+ return function () {
+ b && (delete Cc[g], b = f.onload = f.onerror = null, "abort" === a ? f.abort() : "error" === a ? d(f.status, f.statusText) : d(Dc[f.status] || f.status, f.statusText, "string" == typeof f.responseText ? {text: f.responseText} : void 0, f.getAllResponseHeaders()))
+ }
+ }, f.onload = b(), f.onerror = b("error"), b = Cc[g] = b("abort");
+ try {
+ f.send(a.hasContent && a.data || null)
+ } catch (h) {
+ if (b)throw h
+ }
+ }, abort: function () {
+ b && b()
+ }} : void 0
+ }), n.ajaxSetup({accepts: {script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"}, contents: {script: /(?:java|ecma)script/}, converters: {"text script": function (a) {
+ return n.globalEval(a), a
+ }}}), n.ajaxPrefilter("script", function (a) {
+ void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET")
+ }), n.ajaxTransport("script", function (a) {
+ if (a.crossDomain) {
+ var b, c;
+ return{send: function (d, e) {
+ b = n("
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SPIM datasets
+
+
+
+
+
+
+
+ Active
+ Category
+ Index
+ Name
+ Description
+ Path
+
+
+
+
+
+
+
Dataset deployment
+
+
+
+
+ Error:
+ Error message
+
+
+
+ Success:
+ Successful message
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+