﻿/*!
* jQuery JavaScript Library v1.4
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://docs.jquery.com/License
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Wed Jan 13 15:23:05 2010 -0500
*/
(function(A, w) {
    function oa() { if (!c.isReady) { try { s.documentElement.doScroll("left") } catch (a) { setTimeout(oa, 1); return } c.ready() } } function La(a, b) { b.src ? c.ajax({ url: b.src, async: false, dataType: "script" }) : c.globalEval(b.text || b.textContent || b.innerHTML || ""); b.parentNode && b.parentNode.removeChild(b) } function $(a, b, d, f, e, i) {
        var j = a.length; if (typeof b === "object") { for (var o in b) $(a, o, b[o], f, e, d); return a } if (d !== w) { f = !i && f && c.isFunction(d); for (o = 0; o < j; o++) e(a[o], b, f ? d.call(a[o], o, e(a[o], b)) : d, i); return a } return j ?
e(a[0], b) : null
    } function K() { return (new Date).getTime() } function aa() { return false } function ba() { return true } function pa(a, b, d) { d[0].type = a; return c.event.handle.apply(b, d) } function qa(a) {
        var b = true, d = [], f = [], e = arguments, i, j, o, p, n, t = c.extend({}, c.data(this, "events").live); for (p in t) { j = t[p]; if (j.live === a.type || j.altLive && c.inArray(a.type, j.altLive) > -1) { i = j.data; i.beforeFilter && i.beforeFilter[a.type] && !i.beforeFilter[a.type](a) || f.push(j.selector) } else delete t[p] } i = c(a.target).closest(f, a.currentTarget);
        n = 0; for (l = i.length; n < l; n++) for (p in t) { j = t[p]; o = i[n].elem; f = null; if (i[n].selector === j.selector) { if (j.live === "mouseenter" || j.live === "mouseleave") f = c(a.relatedTarget).closest(j.selector)[0]; if (!f || f !== o) d.push({ elem: o, fn: j }) } } n = 0; for (l = d.length; n < l; n++) { i = d[n]; a.currentTarget = i.elem; a.data = i.fn.data; if (i.fn.apply(i.elem, e) === false) { b = false; break } } return b
    } function ra(a, b) { return ["live", a, b.replace(/\./g, "`").replace(/ /g, "&")].join(".") } function sa(a) {
        return !a || !a.parentNode || a.parentNode.nodeType ===
11
    } function ta(a, b) { var d = 0; b.each(function() { if (this.nodeName === (a[d] && a[d].nodeName)) { var f = c.data(a[d++]), e = c.data(this, f); if (f = f && f.events) { delete e.handle; e.events = {}; for (var i in f) for (var j in f[i]) c.event.add(this, i, f[i][j], f[i][j].data) } } }) } function ua(a, b, d) {
        var f, e, i; if (a.length === 1 && typeof a[0] === "string" && a[0].length < 512 && a[0].indexOf("<option") < 0) { e = true; if (i = c.fragments[a[0]]) if (i !== 1) f = i } if (!f) { b = b && b[0] ? b[0].ownerDocument || b[0] : s; f = b.createDocumentFragment(); c.clean(a, b, f, d) } if (e) c.fragments[a[0]] =
i ? f : 1; return { fragment: f, cacheable: e}
    } function T(a) { for (var b = 0, d, f; (d = a[b]) != null; b++) if (!c.noData[d.nodeName.toLowerCase()] && (f = d[H])) delete c.cache[f] } function L(a, b) { var d = {}; c.each(va.concat.apply([], va.slice(0, b)), function() { d[this] = a }); return d } function wa(a) { return "scrollTo" in a && a.document ? a : a.nodeType === 9 ? a.defaultView || a.parentWindow : false } var c = function(a, b) { return new c.fn.init(a, b) }, Ma = A.jQuery, Na = A.$, s = A.document, U, Oa = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, Pa = /^.[^:#\[\.,]*$/, Qa = /\S/,
Ra = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, Sa = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, P = navigator.userAgent, xa = false, Q = [], M, ca = Object.prototype.toString, da = Object.prototype.hasOwnProperty, ea = Array.prototype.push, R = Array.prototype.slice, V = Array.prototype.indexOf; c.fn = c.prototype = { init: function(a, b) {
    var d, f; if (!a) return this; if (a.nodeType) { this.context = this[0] = a; this.length = 1; return this } if (typeof a === "string") if ((d = Oa.exec(a)) && (d[1] || !b)) if (d[1]) {
        f = b ? b.ownerDocument || b : s; if (a = Sa.exec(a)) if (c.isPlainObject(b)) {
            a = [s.createElement(a[1])];
            c.fn.attr.call(a, b, true)
        } else a = [f.createElement(a[1])]; else { a = ua([d[1]], [f]); a = (a.cacheable ? a.fragment.cloneNode(true) : a.fragment).childNodes } 
    } else { if (b = s.getElementById(d[2])) { if (b.id !== d[2]) return U.find(a); this.length = 1; this[0] = b } this.context = s; this.selector = a; return this } else if (!b && /^\w+$/.test(a)) { this.selector = a; this.context = s; a = s.getElementsByTagName(a) } else return !b || b.jquery ? (b || U).find(a) : c(b).find(a); else if (c.isFunction(a)) return U.ready(a); if (a.selector !== w) {
        this.selector = a.selector;
        this.context = a.context
    } return c.isArray(a) ? this.setArray(a) : c.makeArray(a, this)
}, selector: "", jquery: "1.4", length: 0, size: function() { return this.length }, toArray: function() { return R.call(this, 0) }, get: function(a) { return a == null ? this.toArray() : a < 0 ? this.slice(a)[0] : this[a] }, pushStack: function(a, b, d) { a = c(a || null); a.prevObject = this; a.context = this.context; if (b === "find") a.selector = this.selector + (this.selector ? " " : "") + d; else if (b) a.selector = this.selector + "." + b + "(" + d + ")"; return a }, setArray: function(a) {
    this.length =
0; ea.apply(this, a); return this
}, each: function(a, b) { return c.each(this, a, b) }, ready: function(a) { c.bindReady(); if (c.isReady) a.call(s, c); else Q && Q.push(a); return this }, eq: function(a) { return a === -1 ? this.slice(a) : this.slice(a, +a + 1) }, first: function() { return this.eq(0) }, last: function() { return this.eq(-1) }, slice: function() { return this.pushStack(R.apply(this, arguments), "slice", R.call(arguments).join(",")) }, map: function(a) { return this.pushStack(c.map(this, function(b, d) { return a.call(b, d, b) })) }, end: function() {
    return this.prevObject ||
c(null)
}, push: ea, sort: [].sort, splice: [].splice
}; c.fn.init.prototype = c.fn; c.extend = c.fn.extend = function() {
    var a = arguments[0] || {}, b = 1, d = arguments.length, f = false, e, i, j, o; if (typeof a === "boolean") { f = a; a = arguments[1] || {}; b = 2 } if (typeof a !== "object" && !c.isFunction(a)) a = {}; if (d === b) { a = this; --b } for (; b < d; b++) if ((e = arguments[b]) != null) for (i in e) {
        j = a[i]; o = e[i]; if (a !== o) if (f && o && (c.isPlainObject(o) || c.isArray(o))) { j = j && (c.isPlainObject(j) || c.isArray(j)) ? j : c.isArray(o) ? [] : {}; a[i] = c.extend(f, j, o) } else if (o !== w) a[i] =
o
    } return a
}; c.extend({ noConflict: function(a) { A.$ = Na; if (a) A.jQuery = Ma; return c }, isReady: false, ready: function() { if (!c.isReady) { if (!s.body) return setTimeout(c.ready, 13); c.isReady = true; if (Q) { for (var a, b = 0; a = Q[b++]; ) a.call(s, c); Q = null } c.fn.triggerHandler && c(s).triggerHandler("ready") } }, bindReady: function() {
    if (!xa) {
        xa = true; if (s.readyState === "complete") return c.ready(); if (s.addEventListener) { s.addEventListener("DOMContentLoaded", M, false); A.addEventListener("load", c.ready, false) } else if (s.attachEvent) {
            s.attachEvent("onreadystatechange",
M); A.attachEvent("onload", c.ready); var a = false; try { a = A.frameElement == null } catch (b) { } s.documentElement.doScroll && a && oa()
        } 
    } 
}, isFunction: function(a) { return ca.call(a) === "[object Function]" }, isArray: function(a) { return ca.call(a) === "[object Array]" }, isPlainObject: function(a) { if (!a || ca.call(a) !== "[object Object]" || a.nodeType || a.setInterval) return false; if (a.constructor && !da.call(a, "constructor") && !da.call(a.constructor.prototype, "isPrototypeOf")) return false; var b; for (b in a); return b === w || da.call(a, b) },
    isEmptyObject: function(a) { for (var b in a) return false; return true }, noop: function() { }, globalEval: function(a) { if (a && Qa.test(a)) { var b = s.getElementsByTagName("head")[0] || s.documentElement, d = s.createElement("script"); d.type = "text/javascript"; if (c.support.scriptEval) d.appendChild(s.createTextNode(a)); else d.text = a; b.insertBefore(d, b.firstChild); b.removeChild(d) } }, nodeName: function(a, b) { return a.nodeName && a.nodeName.toUpperCase() === b.toUpperCase() }, each: function(a, b, d) {
        var f, e = 0, i = a.length, j = i === w || c.isFunction(a);
        if (d) if (j) for (f in a) { if (b.apply(a[f], d) === false) break } else for (; e < i; ) { if (b.apply(a[e++], d) === false) break } else if (j) for (f in a) { if (b.call(a[f], f, a[f]) === false) break } else for (d = a[0]; e < i && b.call(d, e, d) !== false; d = a[++e]); return a
    }, trim: function(a) { return (a || "").replace(Ra, "") }, makeArray: function(a, b) { b = b || []; if (a != null) a.length == null || typeof a === "string" || c.isFunction(a) || typeof a !== "function" && a.setInterval ? ea.call(b, a) : c.merge(b, a); return b }, inArray: function(a, b) {
        if (b.indexOf) return b.indexOf(a); for (var d =
0, f = b.length; d < f; d++) if (b[d] === a) return d; return -1
    }, merge: function(a, b) { var d = a.length, f = 0; if (typeof b.length === "number") for (var e = b.length; f < e; f++) a[d++] = b[f]; else for (; b[f] !== w; ) a[d++] = b[f++]; a.length = d; return a }, grep: function(a, b, d) { for (var f = [], e = 0, i = a.length; e < i; e++) !d !== !b(a[e], e) && f.push(a[e]); return f }, map: function(a, b, d) { for (var f = [], e, i = 0, j = a.length; i < j; i++) { e = b(a[i], i, d); if (e != null) f[f.length] = e } return f.concat.apply([], f) }, guid: 1, proxy: function(a, b, d) {
        if (arguments.length === 2) if (typeof b ===
"string") { d = a; a = d[b]; b = w } else if (b && !c.isFunction(b)) { d = b; b = w } if (!b && a) b = function() { return a.apply(d || this, arguments) }; if (a) b.guid = a.guid = a.guid || b.guid || c.guid++; return b
    }, uaMatch: function(a) {
        var b = { browser: "" }; a = a.toLowerCase(); if (/webkit/.test(a)) b = { browser: "webkit", version: /webkit[\/ ]([\w.]+)/ }; else if (/opera/.test(a)) b = { browser: "opera", version: /version/.test(a) ? /version[\/ ]([\w.]+)/ : /opera[\/ ]([\w.]+)/ }; else if (/msie/.test(a)) b = { browser: "msie", version: /msie ([\w.]+)/ }; else if (/mozilla/.test(a) &&
!/compatible/.test(a)) b = { browser: "mozilla", version: /rv:([\w.]+)/ }; b.version = (b.version && b.version.exec(a) || [0, "0"])[1]; return b
    }, browser: {}
}); P = c.uaMatch(P); if (P.browser) { c.browser[P.browser] = true; c.browser.version = P.version } if (c.browser.webkit) c.browser.safari = true; if (V) c.inArray = function(a, b) { return V.call(b, a) }; U = c(s); if (s.addEventListener) M = function() { s.removeEventListener("DOMContentLoaded", M, false); c.ready() }; else if (s.attachEvent) M = function() {
    if (s.readyState === "complete") {
        s.detachEvent("onreadystatechange",
M); c.ready()
    } 
}; if (V) c.inArray = function(a, b) { return V.call(b, a) }; (function() {
    c.support = {}; var a = s.documentElement, b = s.createElement("script"), d = s.createElement("div"), f = "script" + K(); d.style.display = "none"; d.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; var e = d.getElementsByTagName("*"), i = d.getElementsByTagName("a")[0]; if (!(!e || !e.length || !i)) {
        c.support = { leadingWhitespace: d.firstChild.nodeType === 3, tbody: !d.getElementsByTagName("tbody").length,
            htmlSerialize: !!d.getElementsByTagName("link").length, style: /red/.test(i.getAttribute("style")), hrefNormalized: i.getAttribute("href") === "/a", opacity: /^0.55$/.test(i.style.opacity), cssFloat: !!i.style.cssFloat, checkOn: d.getElementsByTagName("input")[0].value === "on", optSelected: s.createElement("select").appendChild(s.createElement("option")).selected, scriptEval: false, noCloneEvent: true, boxModel: null
        }; b.type = "text/javascript"; try { b.appendChild(s.createTextNode("window." + f + "=1;")) } catch (j) { } a.insertBefore(b,
a.firstChild); if (A[f]) { c.support.scriptEval = true; delete A[f] } a.removeChild(b); if (d.attachEvent && d.fireEvent) { d.attachEvent("onclick", function o() { c.support.noCloneEvent = false; d.detachEvent("onclick", o) }); d.cloneNode(true).fireEvent("onclick") } c(function() { var o = s.createElement("div"); o.style.width = o.style.paddingLeft = "1px"; s.body.appendChild(o); c.boxModel = c.support.boxModel = o.offsetWidth === 2; s.body.removeChild(o).style.display = "none" }); a = function(o) {
    var p = s.createElement("div"); o = "on" + o; var n = o in
p; if (!n) { p.setAttribute(o, "return;"); n = typeof p[o] === "function" } return n
}; c.support.submitBubbles = a("submit"); c.support.changeBubbles = a("change"); a = b = d = e = i = null
    } 
})(); c.props = { "for": "htmlFor", "class": "className", readonly: "readOnly", maxlength: "maxLength", cellspacing: "cellSpacing", rowspan: "rowSpan", colspan: "colSpan", tabindex: "tabIndex", usemap: "useMap", frameborder: "frameBorder" }; var H = "jQuery" + K(), Ta = 0, ya = {}, Ua = {}; c.extend({ cache: {}, expando: H, noData: { embed: true, object: true, applet: true }, data: function(a,
b, d) { if (!(a.nodeName && c.noData[a.nodeName.toLowerCase()])) { a = a == A ? ya : a; var f = a[H], e = c.cache; if (!b && !f) return null; f || (f = ++Ta); if (typeof b === "object") { a[H] = f; e = e[f] = c.extend(true, {}, b) } else e = e[f] ? e[f] : typeof d === "undefined" ? Ua : (e[f] = {}); if (d !== w) { a[H] = f; e[b] = d } return typeof b === "string" ? e[b] : e } }, removeData: function(a, b) {
    if (!(a.nodeName && c.noData[a.nodeName.toLowerCase()])) {
        a = a == A ? ya : a; var d = a[H], f = c.cache, e = f[d]; if (b) { if (e) { delete e[b]; c.isEmptyObject(e) && c.removeData(a) } } else {
            try { delete a[H] } catch (i) {
                a.removeAttribute &&
a.removeAttribute(H)
            } delete f[d]
        } 
    } 
} 
}); c.fn.extend({ data: function(a, b) { if (typeof a === "undefined" && this.length) return c.data(this[0]); else if (typeof a === "object") return this.each(function() { c.data(this, a) }); var d = a.split("."); d[1] = d[1] ? "." + d[1] : ""; if (b === w) { var f = this.triggerHandler("getData" + d[1] + "!", [d[0]]); if (f === w && this.length) f = c.data(this[0], a); return f === w && d[1] ? this.data(d[0]) : f } else return this.trigger("setData" + d[1] + "!", [d[0], b]).each(function() { c.data(this, a, b) }) }, removeData: function(a) {
    return this.each(function() {
        c.removeData(this,
a)
    })
} 
}); c.extend({ queue: function(a, b, d) { if (a) { b = (b || "fx") + "queue"; var f = c.data(a, b); if (!d) return f || []; if (!f || c.isArray(d)) f = c.data(a, b, c.makeArray(d)); else f.push(d); return f } }, dequeue: function(a, b) { b = b || "fx"; var d = c.queue(a, b), f = d.shift(); if (f === "inprogress") f = d.shift(); if (f) { b === "fx" && d.unshift("inprogress"); f.call(a, function() { c.dequeue(a, b) }) } } }); c.fn.extend({ queue: function(a, b) {
    if (typeof a !== "string") { b = a; a = "fx" } if (b === w) return c.queue(this[0], a); return this.each(function() {
        var d = c.queue(this,
a, b); a === "fx" && d[0] !== "inprogress" && c.dequeue(this, a)
    })
}, dequeue: function(a) { return this.each(function() { c.dequeue(this, a) }) }, delay: function(a, b) { a = c.fx ? c.fx.speeds[a] || a : a; b = b || "fx"; return this.queue(b, function() { var d = this; setTimeout(function() { c.dequeue(d, b) }, a) }) }, clearQueue: function(a) { return this.queue(a || "fx", []) } 
}); var za = /[\n\t]/g, fa = /\s+/, Va = /\r/g, Wa = /href|src|style/, Xa = /(button|input)/i, Ya = /(button|input|object|select|textarea)/i, Za = /^(a|area)$/i, Aa = /radio|checkbox/; c.fn.extend({ attr: function(a,
b) { return $(this, a, b, true, c.attr) }, removeAttr: function(a) { return this.each(function() { c.attr(this, a, ""); this.nodeType === 1 && this.removeAttribute(a) }) }, addClass: function(a) {
    if (c.isFunction(a)) return this.each(function(p) { var n = c(this); n.addClass(a.call(this, p, n.attr("class"))) }); if (a && typeof a === "string") for (var b = (a || "").split(fa), d = 0, f = this.length; d < f; d++) {
        var e = this[d]; if (e.nodeType === 1) if (e.className) for (var i = " " + e.className + " ", j = 0, o = b.length; j < o; j++) {
            if (i.indexOf(" " + b[j] + " ") < 0) e.className +=
" " + b[j]
        } else e.className = a
    } return this
}, removeClass: function(a) { if (c.isFunction(a)) return this.each(function(p) { var n = c(this); n.removeClass(a.call(this, p, n.attr("class"))) }); if (a && typeof a === "string" || a === w) for (var b = (a || "").split(fa), d = 0, f = this.length; d < f; d++) { var e = this[d]; if (e.nodeType === 1 && e.className) if (a) { for (var i = (" " + e.className + " ").replace(za, " "), j = 0, o = b.length; j < o; j++) i = i.replace(" " + b[j] + " ", " "); e.className = i.substring(1, i.length - 1) } else e.className = "" } return this }, toggleClass: function(a,
b) { var d = typeof a, f = typeof b === "boolean"; if (c.isFunction(a)) return this.each(function(e) { var i = c(this); i.toggleClass(a.call(this, e, i.attr("class"), b), b) }); return this.each(function() { if (d === "string") for (var e, i = 0, j = c(this), o = b, p = a.split(fa); e = p[i++]; ) { o = f ? o : !j.hasClass(e); j[o ? "addClass" : "removeClass"](e) } else if (d === "undefined" || d === "boolean") { this.className && c.data(this, "__className__", this.className); this.className = this.className || a === false ? "" : c.data(this, "__className__") || "" } }) }, hasClass: function(a) {
    a =
" " + a + " "; for (var b = 0, d = this.length; b < d; b++) if ((" " + this[b].className + " ").replace(za, " ").indexOf(a) > -1) return true; return false
}, val: function(a) {
    if (a === w) {
        var b = this[0]; if (b) {
            if (c.nodeName(b, "option")) return (b.attributes.value || {}).specified ? b.value : b.text; if (c.nodeName(b, "select")) { var d = b.selectedIndex, f = [], e = b.options; b = b.type === "select-one"; if (d < 0) return null; var i = b ? d : 0; for (d = b ? d + 1 : e.length; i < d; i++) { var j = e[i]; if (j.selected) { a = c(j).val(); if (b) return a; f.push(a) } } return f } if (Aa.test(b.type) &&
!c.support.checkOn) return b.getAttribute("value") === null ? "on" : b.value; return (b.value || "").replace(Va, "")
        } return w
    } var o = c.isFunction(a); return this.each(function(p) {
        var n = c(this), t = a; if (this.nodeType === 1) {
            if (o) t = a.call(this, p, n.val()); if (typeof t === "number") t += ""; if (c.isArray(t) && Aa.test(this.type)) this.checked = c.inArray(n.val(), t) >= 0; else if (c.nodeName(this, "select")) {
                var z = c.makeArray(t); c("option", this).each(function() { this.selected = c.inArray(c(this).val(), z) >= 0 }); if (!z.length) this.selectedIndex =
-1
            } else this.value = t
        } 
    })
} 
}); c.extend({ attrFn: { val: true, css: true, html: true, text: true, data: true, width: true, height: true, offset: true }, attr: function(a, b, d, f) {
    if (!a || a.nodeType === 3 || a.nodeType === 8) return w; if (f && b in c.attrFn) return c(a)[b](d); f = a.nodeType !== 1 || !c.isXMLDoc(a); var e = d !== w; b = f && c.props[b] || b; if (a.nodeType === 1) {
        var i = Wa.test(b); if (b in a && f && !i) {
            if (e) { if (b === "type" && Xa.test(a.nodeName) && a.parentNode) throw "type property can't be changed"; a[b] = d } if (c.nodeName(a, "form") && a.getAttributeNode(b)) return a.getAttributeNode(b).nodeValue;
            if (b === "tabIndex") return (b = a.getAttributeNode("tabIndex")) && b.specified ? b.value : Ya.test(a.nodeName) || Za.test(a.nodeName) && a.href ? 0 : w; return a[b]
        } if (!c.support.style && f && b === "style") { if (e) a.style.cssText = "" + d; return a.style.cssText } e && a.setAttribute(b, "" + d); a = !c.support.hrefNormalized && f && i ? a.getAttribute(b, 2) : a.getAttribute(b); return a === null ? w : a
    } return c.style(a, b, d)
} 
}); var $a = function(a) { return a.replace(/[^\w\s\.\|`]/g, function(b) { return "\\" + b }) }; c.event = { add: function(a, b, d, f) {
    if (!(a.nodeType ===
3 || a.nodeType === 8)) {
        if (a.setInterval && a !== A && !a.frameElement) a = A; if (!d.guid) d.guid = c.guid++; if (f !== w) { d = c.proxy(d); d.data = f } var e = c.data(a, "events") || c.data(a, "events", {}), i = c.data(a, "handle"), j; if (!i) { j = function() { return typeof c !== "undefined" && !c.event.triggered ? c.event.handle.apply(j.elem, arguments) : w }; i = c.data(a, "handle", j) } if (i) {
            i.elem = a; b = b.split(/\s+/); for (var o, p = 0; o = b[p++]; ) {
                var n = o.split("."); o = n.shift(); d.type = n.slice(0).sort().join("."); var t = e[o], z = this.special[o] || {}; if (!t) {
                    t = e[o] = {};
                    if (!z.setup || z.setup.call(a, f, n, d) === false) if (a.addEventListener) a.addEventListener(o, i, false); else a.attachEvent && a.attachEvent("on" + o, i)
                } if (z.add) if ((n = z.add.call(a, d, f, n, t)) && c.isFunction(n)) { n.guid = n.guid || d.guid; d = n } t[d.guid] = d; this.global[o] = true
            } a = null
        } 
    } 
}, global: {}, remove: function(a, b, d) {
    if (!(a.nodeType === 3 || a.nodeType === 8)) {
        var f = c.data(a, "events"), e, i, j; if (f) {
            if (b === w || typeof b === "string" && b.charAt(0) === ".") for (i in f) this.remove(a, i + (b || "")); else {
                if (b.type) { d = b.handler; b = b.type } b = b.split(/\s+/);
                for (var o = 0; i = b[o++]; ) {
                    var p = i.split("."); i = p.shift(); var n = !p.length, t = c.map(p.slice(0).sort(), $a); t = new RegExp("(^|\\.)" + t.join("\\.(?:.*\\.)?") + "(\\.|$)"); var z = this.special[i] || {}; if (f[i]) {
                        if (d) { j = f[i][d.guid]; delete f[i][d.guid] } else for (var B in f[i]) if (n || t.test(f[i][B].type)) delete f[i][B]; z.remove && z.remove.call(a, p, j); for (e in f[i]) break; if (!e) {
                            if (!z.teardown || z.teardown.call(a, p) === false) if (a.removeEventListener) a.removeEventListener(i, c.data(a, "handle"), false); else a.detachEvent && a.detachEvent("on" +
i, c.data(a, "handle")); e = null; delete f[i]
                        } 
                    } 
                } 
            } for (e in f) break; if (!e) { if (B = c.data(a, "handle")) B.elem = null; c.removeData(a, "events"); c.removeData(a, "handle") } 
        } 
    } 
}, trigger: function(a, b, d, f) {
    var e = a.type || a; if (!f) {
        a = typeof a === "object" ? a[H] ? a : c.extend(c.Event(e), a) : c.Event(e); if (e.indexOf("!") >= 0) { a.type = e = e.slice(0, -1); a.exclusive = true } if (!d) { a.stopPropagation(); this.global[e] && c.each(c.cache, function() { this.events && this.events[e] && c.event.trigger(a, b, this.handle.elem) }) } if (!d || d.nodeType === 3 || d.nodeType ===
8) return w; a.result = w; a.target = d; b = c.makeArray(b); b.unshift(a)
    } a.currentTarget = d; var i = c.data(d, "handle"); i && i.apply(d, b); var j, o; try { if (!(d && d.nodeName && c.noData[d.nodeName.toLowerCase()])) { j = d[e]; o = d["on" + e] } } catch (p) { } i = c.nodeName(d, "a") && e === "click"; if (!f && j && !a.isDefaultPrevented() && !i) { this.triggered = true; try { d[e]() } catch (n) { } } else if (o && d["on" + e].apply(d, b) === false) a.result = false; this.triggered = false; if (!a.isPropagationStopped()) (d = d.parentNode || d.ownerDocument) && c.event.trigger(a, b, d, true)
},
    handle: function(a) { var b, d; a = arguments[0] = c.event.fix(a || A.event); a.currentTarget = this; d = a.type.split("."); a.type = d.shift(); b = !d.length && !a.exclusive; var f = new RegExp("(^|\\.)" + d.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); d = (c.data(this, "events") || {})[a.type]; for (var e in d) { var i = d[e]; if (b || f.test(i.type)) { a.handler = i; a.data = i.data; i = i.apply(this, arguments); if (i !== w) { a.result = i; if (i === false) { a.preventDefault(); a.stopPropagation() } } if (a.isImmediatePropagationStopped()) break } } return a.result },
    props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), fix: function(a) {
        if (a[H]) return a; var b = a; a = c.Event(b); for (var d = this.props.length, f; d; ) { f = this.props[--d]; a[f] = b[f] } if (!a.target) a.target = a.srcElement ||
s; if (a.target.nodeType === 3) a.target = a.target.parentNode; if (!a.relatedTarget && a.fromElement) a.relatedTarget = a.fromElement === a.target ? a.toElement : a.fromElement; if (a.pageX == null && a.clientX != null) { b = s.documentElement; d = s.body; a.pageX = a.clientX + (b && b.scrollLeft || d && d.scrollLeft || 0) - (b && b.clientLeft || d && d.clientLeft || 0); a.pageY = a.clientY + (b && b.scrollTop || d && d.scrollTop || 0) - (b && b.clientTop || d && d.clientTop || 0) } if (!a.which && (a.charCode || a.charCode === 0 ? a.charCode : a.keyCode)) a.which = a.charCode || a.keyCode; if (!a.metaKey &&
a.ctrlKey) a.metaKey = a.ctrlKey; if (!a.which && a.button !== w) a.which = a.button & 1 ? 1 : a.button & 2 ? 3 : a.button & 4 ? 2 : 0; return a
    }, guid: 1E8, proxy: c.proxy, special: { ready: { setup: c.bindReady, teardown: c.noop }, live: { add: function(a, b) { c.extend(a, b || {}); a.guid += b.selector + b.live; c.event.add(this, b.live, qa, b) }, remove: function(a) { if (a.length) { var b = 0, d = new RegExp("(^|\\.)" + a[0] + "(\\.|$)"); c.each(c.data(this, "events").live || {}, function() { d.test(this.type) && b++ }); b < 1 && c.event.remove(this, a[0], qa) } }, special: {} }, beforeunload: { setup: function(a,
b, d) { if (this.setInterval) this.onbeforeunload = d; return false }, teardown: function(a, b) { if (this.onbeforeunload === b) this.onbeforeunload = null } }}
    }; c.Event = function(a) { if (!this.preventDefault) return new c.Event(a); if (a && a.type) { this.originalEvent = a; this.type = a.type } else this.type = a; this.timeStamp = K(); this[H] = true }; c.Event.prototype = { preventDefault: function() { this.isDefaultPrevented = ba; var a = this.originalEvent; if (a) { a.preventDefault && a.preventDefault(); a.returnValue = false } }, stopPropagation: function() {
        this.isPropagationStopped =
ba; var a = this.originalEvent; if (a) { a.stopPropagation && a.stopPropagation(); a.cancelBubble = true } 
    }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = ba; this.stopPropagation() }, isDefaultPrevented: aa, isPropagationStopped: aa, isImmediatePropagationStopped: aa
    }; var Ba = function(a) { for (var b = a.relatedTarget; b && b !== this; ) try { b = b.parentNode } catch (d) { break } if (b !== this) { a.type = a.data; c.event.handle.apply(this, arguments) } }, Ca = function(a) { a.type = a.data; c.event.handle.apply(this, arguments) }; c.each({ mouseenter: "mouseover",
        mouseleave: "mouseout"
    }, function(a, b) { c.event.special[a] = { setup: function(d) { c.event.add(this, b, d && d.selector ? Ca : Ba, a) }, teardown: function(d) { c.event.remove(this, b, d && d.selector ? Ca : Ba) } } }); if (!c.support.submitBubbles) c.event.special.submit = { setup: function(a, b, d) {
        if (this.nodeName.toLowerCase() !== "form") {
            c.event.add(this, "click.specialSubmit." + d.guid, function(f) { var e = f.target, i = e.type; if ((i === "submit" || i === "image") && c(e).closest("form").length) return pa("submit", this, arguments) }); c.event.add(this, "keypress.specialSubmit." +
d.guid, function(f) { var e = f.target, i = e.type; if ((i === "text" || i === "password") && c(e).closest("form").length && f.keyCode === 13) return pa("submit", this, arguments) })
        } else return false
    }, remove: function(a, b) { c.event.remove(this, "click.specialSubmit" + (b ? "." + b.guid : "")); c.event.remove(this, "keypress.specialSubmit" + (b ? "." + b.guid : "")) } 
    }; if (!c.support.changeBubbles) {
        var ga = /textarea|input|select/i; function Da(a) {
            var b = a.type, d = a.value; if (b === "radio" || b === "checkbox") d = a.checked; else if (b === "select-multiple") d = a.selectedIndex >
-1 ? c.map(a.options, function(f) { return f.selected }).join("-") : ""; else if (a.nodeName.toLowerCase() === "select") d = a.selectedIndex; return d
        } function ha(a, b) { var d = a.target, f, e; if (!(!ga.test(d.nodeName) || d.readOnly)) { f = c.data(d, "_change_data"); e = Da(d); if (e !== f) { if (a.type !== "focusout" || d.type !== "radio") c.data(d, "_change_data", e); if (d.type !== "select" && (f != null || e)) { a.type = "change"; return c.event.trigger(a, b, this) } } } } c.event.special.change = { filters: { focusout: ha, click: function(a) {
            var b = a.target, d = b.type; if (d ===
"radio" || d === "checkbox" || b.nodeName.toLowerCase() === "select") return ha.call(this, a)
        }, keydown: function(a) { var b = a.target, d = b.type; if (a.keyCode === 13 && b.nodeName.toLowerCase() !== "textarea" || a.keyCode === 32 && (d === "checkbox" || d === "radio") || d === "select-multiple") return ha.call(this, a) }, beforeactivate: function(a) { a = a.target; a.nodeName.toLowerCase() === "input" && a.type === "radio" && c.data(a, "_change_data", Da(a)) } 
        }, setup: function(a, b, d) { for (var f in W) c.event.add(this, f + ".specialChange." + d.guid, W[f]); return ga.test(this.nodeName) },
            remove: function(a, b) { for (var d in W) c.event.remove(this, d + ".specialChange" + (b ? "." + b.guid : ""), W[d]); return ga.test(this.nodeName) } 
        }; var W = c.event.special.change.filters
    } s.addEventListener && c.each({ focus: "focusin", blur: "focusout" }, function(a, b) { function d(f) { f = c.event.fix(f); f.type = b; return c.event.handle.call(this, f) } c.event.special[b] = { setup: function() { this.addEventListener(a, d, true) }, teardown: function() { this.removeEventListener(a, d, true) } } }); c.each(["bind", "one"], function(a, b) {
        c.fn[b] = function(d,
f, e) { if (typeof d === "object") { for (var i in d) this[b](i, f, d[i], e); return this } if (c.isFunction(f)) { thisObject = e; e = f; f = w } var j = b === "one" ? c.proxy(e, function(o) { c(this).unbind(o, j); return e.apply(this, arguments) }) : e; return d === "unload" && b !== "one" ? this.one(d, f, e, thisObject) : this.each(function() { c.event.add(this, d, j, f) }) } 
    }); c.fn.extend({ unbind: function(a, b) { if (typeof a === "object" && !a.preventDefault) { for (var d in a) this.unbind(d, a[d]); return this } return this.each(function() { c.event.remove(this, a, b) }) }, trigger: function(a,
b) { return this.each(function() { c.event.trigger(a, b, this) }) }, triggerHandler: function(a, b) { if (this[0]) { a = c.Event(a); a.preventDefault(); a.stopPropagation(); c.event.trigger(a, b, this[0]); return a.result } }, toggle: function(a) { for (var b = arguments, d = 1; d < b.length; ) c.proxy(a, b[d++]); return this.click(c.proxy(a, function(f) { var e = (c.data(this, "lastToggle" + a.guid) || 0) % d; c.data(this, "lastToggle" + a.guid, e + 1); f.preventDefault(); return b[e].apply(this, arguments) || false })) }, hover: function(a, b) {
    return this.mouseenter(a).mouseleave(b ||
a)
}, live: function(a, b, d) { if (c.isFunction(b)) { d = b; b = w } c(this.context).bind(ra(a, this.selector), { data: b, selector: this.selector, live: a }, d); return this }, die: function(a, b) { c(this.context).unbind(ra(a, this.selector), b ? { guid: b.guid + this.selector + a} : null); return this } 
    }); c.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".split(" "), function(a, b) {
        c.fn[b] = function(d) {
            return d ?
this.bind(b, d) : this.trigger(b)
        }; if (c.attrFn) c.attrFn[b] = true
    }); A.attachEvent && !A.addEventListener && A.attachEvent("onunload", function() { for (var a in c.cache) if (c.cache[a].handle) try { c.event.remove(c.cache[a].handle.elem) } catch (b) { } }); (function() {
        function a(g) { for (var h = "", k, m = 0; g[m]; m++) { k = g[m]; if (k.nodeType === 3 || k.nodeType === 4) h += k.nodeValue; else if (k.nodeType !== 8) h += a(k.childNodes) } return h } function b(g, h, k, m, r, q) {
            r = 0; for (var v = m.length; r < v; r++) {
                var u = m[r]; if (u) {
                    u = u[g]; for (var y = false; u; ) {
                        if (u.sizcache ===
k) { y = m[u.sizset]; break } if (u.nodeType === 1 && !q) { u.sizcache = k; u.sizset = r } if (u.nodeName.toLowerCase() === h) { y = u; break } u = u[g]
                    } m[r] = y
                } 
            } 
        } function d(g, h, k, m, r, q) { r = 0; for (var v = m.length; r < v; r++) { var u = m[r]; if (u) { u = u[g]; for (var y = false; u; ) { if (u.sizcache === k) { y = m[u.sizset]; break } if (u.nodeType === 1) { if (!q) { u.sizcache = k; u.sizset = r } if (typeof h !== "string") { if (u === h) { y = true; break } } else if (p.filter(h, [u]).length > 0) { y = u; break } } u = u[g] } m[r] = y } } } var f = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e = 0, i = Object.prototype.toString, j = false, o = true; [0, 0].sort(function() { o = false; return 0 }); var p = function(g, h, k, m) {
    k = k || []; var r = h = h || s; if (h.nodeType !== 1 && h.nodeType !== 9) return []; if (!g || typeof g !== "string") return k; for (var q = [], v, u, y, S, I = true, N = x(h), J = g; (f.exec(""), v = f.exec(J)) !== null; ) { J = v[3]; q.push(v[1]); if (v[2]) { S = v[3]; break } } if (q.length > 1 && t.exec(g)) if (q.length === 2 && n.relative[q[0]]) u = ia(q[0] + q[1], h); else for (u = n.relative[q[0]] ? [h] : p(q.shift(), h); q.length; ) {
        g = q.shift(); if (n.relative[g]) g += q.shift();
        u = ia(g, u)
    } else { if (!m && q.length > 1 && h.nodeType === 9 && !N && n.match.ID.test(q[0]) && !n.match.ID.test(q[q.length - 1])) { v = p.find(q.shift(), h, N); h = v.expr ? p.filter(v.expr, v.set)[0] : v.set[0] } if (h) { v = m ? { expr: q.pop(), set: B(m)} : p.find(q.pop(), q.length === 1 && (q[0] === "~" || q[0] === "+") && h.parentNode ? h.parentNode : h, N); u = v.expr ? p.filter(v.expr, v.set) : v.set; if (q.length > 0) y = B(u); else I = false; for (; q.length; ) { var E = q.pop(); v = E; if (n.relative[E]) v = q.pop(); else E = ""; if (v == null) v = h; n.relative[E](y, v, N) } } else y = [] } y || (y = u); if (!y) throw "Syntax error, unrecognized expression: " +
(E || g); if (i.call(y) === "[object Array]") if (I) if (h && h.nodeType === 1) for (g = 0; y[g] != null; g++) { if (y[g] && (y[g] === true || y[g].nodeType === 1 && F(h, y[g]))) k.push(u[g]) } else for (g = 0; y[g] != null; g++) y[g] && y[g].nodeType === 1 && k.push(u[g]); else k.push.apply(k, y); else B(y, k); if (S) { p(S, r, k, m); p.uniqueSort(k) } return k
}; p.uniqueSort = function(g) { if (D) { j = o; g.sort(D); if (j) for (var h = 1; h < g.length; h++) g[h] === g[h - 1] && g.splice(h--, 1) } return g }; p.matches = function(g, h) { return p(g, null, null, h) }; p.find = function(g, h, k) {
    var m, r; if (!g) return [];
    for (var q = 0, v = n.order.length; q < v; q++) { var u = n.order[q]; if (r = n.leftMatch[u].exec(g)) { var y = r[1]; r.splice(1, 1); if (y.substr(y.length - 1) !== "\\") { r[1] = (r[1] || "").replace(/\\/g, ""); m = n.find[u](r, h, k); if (m != null) { g = g.replace(n.match[u], ""); break } } } } m || (m = h.getElementsByTagName("*")); return { set: m, expr: g}
}; p.filter = function(g, h, k, m) {
    for (var r = g, q = [], v = h, u, y, S = h && h[0] && x(h[0]); g && h.length; ) {
        for (var I in n.filter) if ((u = n.leftMatch[I].exec(g)) != null && u[2]) {
            var N = n.filter[I], J, E; E = u[1]; y = false; u.splice(1, 1); if (E.substr(E.length -
1) !== "\\") { if (v === q) q = []; if (n.preFilter[I]) if (u = n.preFilter[I](u, v, k, q, m, S)) { if (u === true) continue } else y = J = true; if (u) for (var X = 0; (E = v[X]) != null; X++) if (E) { J = N(E, u, X, v); var Ea = m ^ !!J; if (k && J != null) if (Ea) y = true; else v[X] = false; else if (Ea) { q.push(E); y = true } } if (J !== w) { k || (v = q); g = g.replace(n.match[I], ""); if (!y) return []; break } } 
        } if (g === r) if (y == null) throw "Syntax error, unrecognized expression: " + g; else break; r = g
    } return v
}; var n = p.selectors = { order: ["ID", "NAME", "TAG"], match: { ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
    CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
}, leftMatch: {}, attrMap: { "class": "className", "for": "htmlFor" }, attrHandle: { href: function(g) { return g.getAttribute("href") } },
    relative: { "+": function(g, h) { var k = typeof h === "string", m = k && !/\W/.test(h); k = k && !m; if (m) h = h.toLowerCase(); m = 0; for (var r = g.length, q; m < r; m++) if (q = g[m]) { for (; (q = q.previousSibling) && q.nodeType !== 1; ); g[m] = k || q && q.nodeName.toLowerCase() === h ? q || false : q === h } k && p.filter(h, g, true) }, ">": function(g, h) {
        var k = typeof h === "string"; if (k && !/\W/.test(h)) { h = h.toLowerCase(); for (var m = 0, r = g.length; m < r; m++) { var q = g[m]; if (q) { k = q.parentNode; g[m] = k.nodeName.toLowerCase() === h ? k : false } } } else {
            m = 0; for (r = g.length; m < r; m++) if (q = g[m]) g[m] =
k ? q.parentNode : q.parentNode === h; k && p.filter(h, g, true)
        } 
    }, "": function(g, h, k) { var m = e++, r = d; if (typeof h === "string" && !/\W/.test(h)) { var q = h = h.toLowerCase(); r = b } r("parentNode", h, m, g, q, k) }, "~": function(g, h, k) { var m = e++, r = d; if (typeof h === "string" && !/\W/.test(h)) { var q = h = h.toLowerCase(); r = b } r("previousSibling", h, m, g, q, k) } 
    }, find: { ID: function(g, h, k) { if (typeof h.getElementById !== "undefined" && !k) return (g = h.getElementById(g[1])) ? [g] : [] }, NAME: function(g, h) {
        if (typeof h.getElementsByName !== "undefined") {
            var k = [];
            h = h.getElementsByName(g[1]); for (var m = 0, r = h.length; m < r; m++) h[m].getAttribute("name") === g[1] && k.push(h[m]); return k.length === 0 ? null : k
        } 
    }, TAG: function(g, h) { return h.getElementsByTagName(g[1]) } 
    }, preFilter: { CLASS: function(g, h, k, m, r, q) { g = " " + g[1].replace(/\\/g, "") + " "; if (q) return g; q = 0; for (var v; (v = h[q]) != null; q++) if (v) if (r ^ (v.className && (" " + v.className + " ").replace(/[\t\n]/g, " ").indexOf(g) >= 0)) k || m.push(v); else if (k) h[q] = false; return false }, ID: function(g) { return g[1].replace(/\\/g, "") }, TAG: function(g) { return g[1].toLowerCase() },
        CHILD: function(g) { if (g[1] === "nth") { var h = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2] === "even" && "2n" || g[2] === "odd" && "2n+1" || !/\D/.test(g[2]) && "0n+" + g[2] || g[2]); g[2] = h[1] + (h[2] || 1) - 0; g[3] = h[3] - 0 } g[0] = e++; return g }, ATTR: function(g, h, k, m, r, q) { h = g[1].replace(/\\/g, ""); if (!q && n.attrMap[h]) g[1] = n.attrMap[h]; if (g[2] === "~=") g[4] = " " + g[4] + " "; return g }, PSEUDO: function(g, h, k, m, r) {
            if (g[1] === "not") if ((f.exec(g[3]) || "").length > 1 || /^\w/.test(g[3])) g[3] = p(g[3], null, null, h); else {
                g = p.filter(g[3], h, k, true ^ r); k || m.push.apply(m,
g); return false
            } else if (n.match.POS.test(g[0]) || n.match.CHILD.test(g[0])) return true; return g
        }, POS: function(g) { g.unshift(true); return g } 
    }, filters: { enabled: function(g) { return g.disabled === false && g.type !== "hidden" }, disabled: function(g) { return g.disabled === true }, checked: function(g) { return g.checked === true }, selected: function(g) { return g.selected === true }, parent: function(g) { return !!g.firstChild }, empty: function(g) { return !g.firstChild }, has: function(g, h, k) { return !!p(k[3], g).length }, header: function(g) { return /h\d/i.test(g.nodeName) },
        text: function(g) { return "text" === g.type }, radio: function(g) { return "radio" === g.type }, checkbox: function(g) { return "checkbox" === g.type }, file: function(g) { return "file" === g.type }, password: function(g) { return "password" === g.type }, submit: function(g) { return "submit" === g.type }, image: function(g) { return "image" === g.type }, reset: function(g) { return "reset" === g.type }, button: function(g) { return "button" === g.type || g.nodeName.toLowerCase() === "button" }, input: function(g) { return /input|select|textarea|button/i.test(g.nodeName) } 
    },
    setFilters: { first: function(g, h) { return h === 0 }, last: function(g, h, k, m) { return h === m.length - 1 }, even: function(g, h) { return h % 2 === 0 }, odd: function(g, h) { return h % 2 === 1 }, lt: function(g, h, k) { return h < k[3] - 0 }, gt: function(g, h, k) { return h > k[3] - 0 }, nth: function(g, h, k) { return k[3] - 0 === h }, eq: function(g, h, k) { return k[3] - 0 === h } }, filter: { PSEUDO: function(g, h, k, m) {
        var r = h[1], q = n.filters[r]; if (q) return q(g, k, h, m); else if (r === "contains") return (g.textContent || g.innerText || a([g]) || "").indexOf(h[3]) >= 0; else if (r === "not") {
            h =
h[3]; k = 0; for (m = h.length; k < m; k++) if (h[k] === g) return false; return true
        } else throw "Syntax error, unrecognized expression: " + r;
    }, CHILD: function(g, h) {
        var k = h[1], m = g; switch (k) {
            case "only": case "first": for (; m = m.previousSibling; ) if (m.nodeType === 1) return false; if (k === "first") return true; m = g; case "last": for (; m = m.nextSibling; ) if (m.nodeType === 1) return false; return true; case "nth": k = h[2]; var r = h[3]; if (k === 1 && r === 0) return true; h = h[0]; var q = g.parentNode; if (q && (q.sizcache !== h || !g.nodeIndex)) {
                    var v = 0; for (m = q.firstChild; m; m =
m.nextSibling) if (m.nodeType === 1) m.nodeIndex = ++v; q.sizcache = h
                } g = g.nodeIndex - r; return k === 0 ? g === 0 : g % k === 0 && g / k >= 0
        } 
    }, ID: function(g, h) { return g.nodeType === 1 && g.getAttribute("id") === h }, TAG: function(g, h) { return h === "*" && g.nodeType === 1 || g.nodeName.toLowerCase() === h }, CLASS: function(g, h) { return (" " + (g.className || g.getAttribute("class")) + " ").indexOf(h) > -1 }, ATTR: function(g, h) {
        var k = h[1]; g = n.attrHandle[k] ? n.attrHandle[k](g) : g[k] != null ? g[k] : g.getAttribute(k); k = g + ""; var m = h[2]; h = h[4]; return g == null ? m === "!=" : m ===
"=" ? k === h : m === "*=" ? k.indexOf(h) >= 0 : m === "~=" ? (" " + k + " ").indexOf(h) >= 0 : !h ? k && g !== false : m === "!=" ? k !== h : m === "^=" ? k.indexOf(h) === 0 : m === "$=" ? k.substr(k.length - h.length) === h : m === "|=" ? k === h || k.substr(0, h.length + 1) === h + "-" : false
    }, POS: function(g, h, k, m) { var r = n.setFilters[h[2]]; if (r) return r(g, k, h, m) } }
    }, t = n.match.POS; for (var z in n.match) {
            n.match[z] = new RegExp(n.match[z].source + /(?![^\[]*\])(?![^\(]*\))/.source); n.leftMatch[z] = new RegExp(/(^(?:.|\r|\n)*?)/.source + n.match[z].source.replace(/\\(\d+)/g, function(g,
h) { return "\\" + (h - 0 + 1) }))
        } var B = function(g, h) { g = Array.prototype.slice.call(g, 0); if (h) { h.push.apply(h, g); return h } return g }; try { Array.prototype.slice.call(s.documentElement.childNodes, 0) } catch (C) { B = function(g, h) { h = h || []; if (i.call(g) === "[object Array]") Array.prototype.push.apply(h, g); else if (typeof g.length === "number") for (var k = 0, m = g.length; k < m; k++) h.push(g[k]); else for (k = 0; g[k]; k++) h.push(g[k]); return h } } var D; if (s.documentElement.compareDocumentPosition) D = function(g, h) {
            if (!g.compareDocumentPosition ||
!h.compareDocumentPosition) { if (g == h) j = true; return g.compareDocumentPosition ? -1 : 1 } g = g.compareDocumentPosition(h) & 4 ? -1 : g === h ? 0 : 1; if (g === 0) j = true; return g
        }; else if ("sourceIndex" in s.documentElement) D = function(g, h) { if (!g.sourceIndex || !h.sourceIndex) { if (g == h) j = true; return g.sourceIndex ? -1 : 1 } g = g.sourceIndex - h.sourceIndex; if (g === 0) j = true; return g }; else if (s.createRange) D = function(g, h) {
            if (!g.ownerDocument || !h.ownerDocument) { if (g == h) j = true; return g.ownerDocument ? -1 : 1 } var k = g.ownerDocument.createRange(), m =
h.ownerDocument.createRange(); k.setStart(g, 0); k.setEnd(g, 0); m.setStart(h, 0); m.setEnd(h, 0); g = k.compareBoundaryPoints(Range.START_TO_END, m); if (g === 0) j = true; return g
        }; (function() {
            var g = s.createElement("div"), h = "script" + (new Date).getTime(); g.innerHTML = "<a name='" + h + "'/>"; var k = s.documentElement; k.insertBefore(g, k.firstChild); if (s.getElementById(h)) {
                n.find.ID = function(m, r, q) {
                    if (typeof r.getElementById !== "undefined" && !q) return (r = r.getElementById(m[1])) ? r.id === m[1] || typeof r.getAttributeNode !== "undefined" &&
r.getAttributeNode("id").nodeValue === m[1] ? [r] : w : []
                }; n.filter.ID = function(m, r) { var q = typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id"); return m.nodeType === 1 && q && q.nodeValue === r } 
            } k.removeChild(g); k = g = null
        })(); (function() {
            var g = s.createElement("div"); g.appendChild(s.createComment("")); if (g.getElementsByTagName("*").length > 0) n.find.TAG = function(h, k) { k = k.getElementsByTagName(h[1]); if (h[1] === "*") { h = []; for (var m = 0; k[m]; m++) k[m].nodeType === 1 && h.push(k[m]); k = h } return k }; g.innerHTML = "<a href='#'></a>";
            if (g.firstChild && typeof g.firstChild.getAttribute !== "undefined" && g.firstChild.getAttribute("href") !== "#") n.attrHandle.href = function(h) { return h.getAttribute("href", 2) }; g = null
        })(); s.querySelectorAll && function() { var g = p, h = s.createElement("div"); h.innerHTML = "<p class='TEST'></p>"; if (!(h.querySelectorAll && h.querySelectorAll(".TEST").length === 0)) { p = function(m, r, q, v) { r = r || s; if (!v && r.nodeType === 9 && !x(r)) try { return B(r.querySelectorAll(m), q) } catch (u) { } return g(m, r, q, v) }; for (var k in g) p[k] = g[k]; h = null } } ();
        (function() { var g = s.createElement("div"); g.innerHTML = "<div class='test e'></div><div class='test'></div>"; if (!(!g.getElementsByClassName || g.getElementsByClassName("e").length === 0)) { g.lastChild.className = "e"; if (g.getElementsByClassName("e").length !== 1) { n.order.splice(1, 0, "CLASS"); n.find.CLASS = function(h, k, m) { if (typeof k.getElementsByClassName !== "undefined" && !m) return k.getElementsByClassName(h[1]) }; g = null } } })(); var F = s.compareDocumentPosition ? function(g, h) { return g.compareDocumentPosition(h) & 16 } : function(g,
h) { return g !== h && (g.contains ? g.contains(h) : true) }, x = function(g) { return (g = (g ? g.ownerDocument || g : 0).documentElement) ? g.nodeName !== "HTML" : false }, ia = function(g, h) { var k = [], m = "", r; for (h = h.nodeType ? [h] : h; r = n.match.PSEUDO.exec(g); ) { m += r[0]; g = g.replace(n.match.PSEUDO, "") } g = n.relative[g] ? g + "*" : g; r = 0; for (var q = h.length; r < q; r++) p(g, h[r], k); return p.filter(m, k) }; c.find = p; c.expr = p.selectors; c.expr[":"] = c.expr.filters; c.unique = p.uniqueSort; c.getText = a; c.isXMLDoc = x; c.contains = F
    })(); var ab = /Until$/, bb = /^(?:parents|prevUntil|prevAll)/,
cb = /,/; R = Array.prototype.slice; var Fa = function(a, b, d) { if (c.isFunction(b)) return c.grep(a, function(e, i) { return !!b.call(e, i, e) === d }); else if (b.nodeType) return c.grep(a, function(e) { return e === b === d }); else if (typeof b === "string") { var f = c.grep(a, function(e) { return e.nodeType === 1 }); if (Pa.test(b)) return c.filter(b, f, !d); else b = c.filter(b, a) } return c.grep(a, function(e) { return c.inArray(e, b) >= 0 === d }) }; c.fn.extend({ find: function(a) {
    for (var b = this.pushStack("", "find", a), d = 0, f = 0, e = this.length; f < e; f++) {
        d = b.length;
        c.find(a, this[f], b); if (f > 0) for (var i = d; i < b.length; i++) for (var j = 0; j < d; j++) if (b[j] === b[i]) { b.splice(i--, 1); break } 
    } return b
}, has: function(a) { var b = c(a); return this.filter(function() { for (var d = 0, f = b.length; d < f; d++) if (c.contains(this, b[d])) return true }) }, not: function(a) { return this.pushStack(Fa(this, a, false), "not", a) }, filter: function(a) { return this.pushStack(Fa(this, a, true), "filter", a) }, is: function(a) { return !!a && c.filter(a, this).length > 0 }, closest: function(a, b) {
    if (c.isArray(a)) {
        var d = [], f = this[0], e, i =
{}, j; if (f && a.length) { e = 0; for (var o = a.length; e < o; e++) { j = a[e]; i[j] || (i[j] = c.expr.match.POS.test(j) ? c(j, b || this.context) : j) } for (; f && f.ownerDocument && f !== b; ) { for (j in i) { e = i[j]; if (e.jquery ? e.index(f) > -1 : c(f).is(e)) { d.push({ selector: j, elem: f }); delete i[j] } } f = f.parentNode } } return d
    } var p = c.expr.match.POS.test(a) ? c(a, b || this.context) : null; return this.map(function(n, t) { for (; t && t.ownerDocument && t !== b; ) { if (p ? p.index(t) > -1 : c(t).is(a)) return t; t = t.parentNode } return null })
}, index: function(a) {
    if (!a || typeof a ===
"string") return c.inArray(this[0], a ? c(a) : this.parent().children()); return c.inArray(a.jquery ? a[0] : a, this)
}, add: function(a, b) { a = typeof a === "string" ? c(a, b || this.context) : c.makeArray(a); b = c.merge(this.get(), a); return this.pushStack(sa(a[0]) || sa(b[0]) ? b : c.unique(b)) }, andSelf: function() { return this.add(this.prevObject) } 
}); c.each({ parent: function(a) { return (a = a.parentNode) && a.nodeType !== 11 ? a : null }, parents: function(a) { return c.dir(a, "parentNode") }, parentsUntil: function(a, b, d) {
    return c.dir(a, "parentNode",
d)
}, next: function(a) { return c.nth(a, 2, "nextSibling") }, prev: function(a) { return c.nth(a, 2, "previousSibling") }, nextAll: function(a) { return c.dir(a, "nextSibling") }, prevAll: function(a) { return c.dir(a, "previousSibling") }, nextUntil: function(a, b, d) { return c.dir(a, "nextSibling", d) }, prevUntil: function(a, b, d) { return c.dir(a, "previousSibling", d) }, siblings: function(a) { return c.sibling(a.parentNode.firstChild, a) }, children: function(a) { return c.sibling(a.firstChild) }, contents: function(a) {
    return c.nodeName(a, "iframe") ?
a.contentDocument || a.contentWindow.document : c.makeArray(a.childNodes)
} 
}, function(a, b) { c.fn[a] = function(d, f) { var e = c.map(this, b, d); ab.test(a) || (f = d); if (f && typeof f === "string") e = c.filter(f, e); e = this.length > 1 ? c.unique(e) : e; if ((this.length > 1 || cb.test(f)) && bb.test(a)) e = e.reverse(); return this.pushStack(e, a, R.call(arguments).join(",")) } }); c.extend({ filter: function(a, b, d) { if (d) a = ":not(" + a + ")"; return c.find.matches(a, b) }, dir: function(a, b, d) {
    var f = []; for (a = a[b]; a && a.nodeType !== 9 && (d === w || !c(a).is(d)); ) {
        a.nodeType ===
1 && f.push(a); a = a[b]
    } return f
}, nth: function(a, b, d) { b = b || 1; for (var f = 0; a; a = a[d]) if (a.nodeType === 1 && ++f === b) break; return a }, sibling: function(a, b) { for (var d = []; a; a = a.nextSibling) a.nodeType === 1 && a !== b && d.push(a); return d } 
}); var Ga = / jQuery\d+="(?:\d+|null)"/g, Y = /^\s+/, db = /(<([\w:]+)[^>]*?)\/>/g, eb = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, Ha = /<([\w:]+)/, fb = /<tbody/i, gb = /<|&\w+;/, hb = function(a, b, d) { return eb.test(d) ? a : b + "></" + d + ">" }, G = { option: [1, "<select multiple='multiple'>", "</select>"],
    legend: [1, "<fieldset>", "</fieldset>"], thead: [1, "<table>", "</table>"], tr: [2, "<table><tbody>", "</tbody></table>"], td: [3, "<table><tbody><tr>", "</tr></tbody></table>"], col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"], area: [1, "<map>", "</map>"], _default: [0, "", ""]
}; G.optgroup = G.option; G.tbody = G.tfoot = G.colgroup = G.caption = G.thead; G.th = G.td; if (!c.support.htmlSerialize) G._default = [1, "div<div>", "</div>"]; c.fn.extend({ text: function(a) {
    if (c.isFunction(a)) return this.each(function(b) {
        var d = c(this);
        return d.text(a.call(this, b, d.text()))
    }); if (typeof a !== "object" && a !== w) return this.empty().append((this[0] && this[0].ownerDocument || s).createTextNode(a)); return c.getText(this)
}, wrapAll: function(a) { if (c.isFunction(a)) return this.each(function(d) { c(this).wrapAll(a.call(this, d)) }); if (this[0]) { var b = c(a, this[0].ownerDocument).eq(0).clone(true); this[0].parentNode && b.insertBefore(this[0]); b.map(function() { for (var d = this; d.firstChild && d.firstChild.nodeType === 1; ) d = d.firstChild; return d }).append(this) } return this },
    wrapInner: function(a) { return this.each(function() { var b = c(this), d = b.contents(); d.length ? d.wrapAll(a) : b.append(a) }) }, wrap: function(a) { return this.each(function() { c(this).wrapAll(a) }) }, unwrap: function() { return this.parent().each(function() { c.nodeName(this, "body") || c(this).replaceWith(this.childNodes) }).end() }, append: function() { return this.domManip(arguments, true, function(a) { this.nodeType === 1 && this.appendChild(a) }) }, prepend: function() {
        return this.domManip(arguments, true, function(a) {
            this.nodeType === 1 &&
this.insertBefore(a, this.firstChild)
        })
    }, before: function() { if (this[0] && this[0].parentNode) return this.domManip(arguments, false, function(b) { this.parentNode.insertBefore(b, this) }); else if (arguments.length) { var a = c(arguments[0]); a.push.apply(a, this.toArray()); return this.pushStack(a, "before", arguments) } }, after: function() {
        if (this[0] && this[0].parentNode) return this.domManip(arguments, false, function(b) { this.parentNode.insertBefore(b, this.nextSibling) }); else if (arguments.length) {
            var a = this.pushStack(this,
"after", arguments); a.push.apply(a, c(arguments[0]).toArray()); return a
        } 
    }, clone: function(a) { var b = this.map(function() { if (!c.support.noCloneEvent && !c.isXMLDoc(this)) { var d = this.outerHTML, f = this.ownerDocument; if (!d) { d = f.createElement("div"); d.appendChild(this.cloneNode(true)); d = d.innerHTML } return c.clean([d.replace(Ga, "").replace(Y, "")], f)[0] } else return this.cloneNode(true) }); if (a === true) { ta(this, b); ta(this.find("*"), b.find("*")) } return b }, html: function(a) {
        if (a === w) return this[0] && this[0].nodeType ===
1 ? this[0].innerHTML.replace(Ga, "") : null; else if (typeof a === "string" && !/<script/i.test(a) && (c.support.leadingWhitespace || !Y.test(a)) && !G[(Ha.exec(a) || ["", ""])[1].toLowerCase()]) try { for (var b = 0, d = this.length; b < d; b++) if (this[b].nodeType === 1) { T(this[b].getElementsByTagName("*")); this[b].innerHTML = a } } catch (f) { this.empty().append(a) } else c.isFunction(a) ? this.each(function(e) { var i = c(this), j = i.html(); i.empty().append(function() { return a.call(this, e, j) }) }) : this.empty().append(a); return this
    }, replaceWith: function(a) {
        if (this[0] &&
this[0].parentNode) { c.isFunction(a) || (a = c(a).detach()); return this.each(function() { var b = this.nextSibling, d = this.parentNode; c(this).remove(); b ? c(b).before(a) : c(d).append(a) }) } else return this.pushStack(c(c.isFunction(a) ? a() : a), "replaceWith", a)
    }, detach: function(a) { return this.remove(a, true) }, domManip: function(a, b, d) {
        function f(t) { return c.nodeName(t, "table") ? t.getElementsByTagName("tbody")[0] || t.appendChild(t.ownerDocument.createElement("tbody")) : t } var e, i, j = a[0], o = []; if (c.isFunction(j)) return this.each(function(t) {
            var z =
c(this); a[0] = j.call(this, t, b ? z.html() : w); return z.domManip(a, b, d)
        }); if (this[0]) { e = a[0] && a[0].parentNode && a[0].parentNode.nodeType === 11 ? { fragment: a[0].parentNode} : ua(a, this, o); if (i = e.fragment.firstChild) { b = b && c.nodeName(i, "tr"); for (var p = 0, n = this.length; p < n; p++) d.call(b ? f(this[p], i) : this[p], e.cacheable || this.length > 1 || p > 0 ? e.fragment.cloneNode(true) : e.fragment) } o && c.each(o, La) } return this
    } 
}); c.fragments = {}; c.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" },
function(a, b) { c.fn[a] = function(d) { var f = []; d = c(d); for (var e = 0, i = d.length; e < i; e++) { var j = (e > 0 ? this.clone(true) : this).get(); c.fn[b].apply(c(d[e]), j); f = f.concat(j) } return this.pushStack(f, a, d.selector) } }); c.each({ remove: function(a, b) { if (!a || c.filter(a, [this]).length) { if (!b && this.nodeType === 1) { T(this.getElementsByTagName("*")); T([this]) } this.parentNode && this.parentNode.removeChild(this) } }, empty: function() { for (this.nodeType === 1 && T(this.getElementsByTagName("*")); this.firstChild; ) this.removeChild(this.firstChild) } },
function(a, b) { c.fn[a] = function() { return this.each(b, arguments) } }); c.extend({ clean: function(a, b, d, f) {
    b = b || s; if (typeof b.createElement === "undefined") b = b.ownerDocument || b[0] && b[0].ownerDocument || s; var e = []; c.each(a, function(i, j) {
        if (typeof j === "number") j += ""; if (j) {
            if (typeof j === "string" && !gb.test(j)) j = b.createTextNode(j); else if (typeof j === "string") {
                j = j.replace(db, hb); var o = (Ha.exec(j) || ["", ""])[1].toLowerCase(), p = G[o] || G._default, n = p[0]; i = b.createElement("div"); for (i.innerHTML = p[1] + j + p[2]; n--; ) i = i.lastChild;
                if (!c.support.tbody) { n = fb.test(j); o = o === "table" && !n ? i.firstChild && i.firstChild.childNodes : p[1] === "<table>" && !n ? i.childNodes : []; for (p = o.length - 1; p >= 0; --p) c.nodeName(o[p], "tbody") && !o[p].childNodes.length && o[p].parentNode.removeChild(o[p]) } !c.support.leadingWhitespace && Y.test(j) && i.insertBefore(b.createTextNode(Y.exec(j)[0]), i.firstChild); j = c.makeArray(i.childNodes)
            } if (j.nodeType) e.push(j); else e = c.merge(e, j)
        } 
    }); if (d) for (a = 0; e[a]; a++) if (f && c.nodeName(e[a], "script") && (!e[a].type || e[a].type.toLowerCase() ===
"text/javascript")) f.push(e[a].parentNode ? e[a].parentNode.removeChild(e[a]) : e[a]); else { e[a].nodeType === 1 && e.splice.apply(e, [a + 1, 0].concat(c.makeArray(e[a].getElementsByTagName("script")))); d.appendChild(e[a]) } return e
} 
}); var ib = /z-?index|font-?weight|opacity|zoom|line-?height/i, Ia = /alpha\([^)]*\)/, Ja = /opacity=([^)]*)/, ja = /float/i, ka = /-([a-z])/ig, jb = /([A-Z])/g, kb = /^-?\d+(?:px)?$/i, lb = /^-?\d/, mb = { position: "absolute", visibility: "hidden", display: "block" }, nb = ["Left", "Right"], ob = ["Top", "Bottom"], pb = s.defaultView &&
s.defaultView.getComputedStyle, Ka = c.support.cssFloat ? "cssFloat" : "styleFloat", la = function(a, b) { return b.toUpperCase() }; c.fn.css = function(a, b) { return $(this, a, b, true, function(d, f, e) { if (e === w) return c.curCSS(d, f); if (typeof e === "number" && !ib.test(f)) e += "px"; c.style(d, f, e) }) }; c.extend({ style: function(a, b, d) {
    if (!a || a.nodeType === 3 || a.nodeType === 8) return w; if ((b === "width" || b === "height") && parseFloat(d) < 0) d = w; var f = a.style || a, e = d !== w; if (!c.support.opacity && b === "opacity") {
        if (e) {
            f.zoom = 1; b = parseInt(d, 10) + "" ===
"NaN" ? "" : "alpha(opacity=" + d * 100 + ")"; a = f.filter || c.curCSS(a, "filter") || ""; f.filter = Ia.test(a) ? a.replace(Ia, b) : b
        } return f.filter && f.filter.indexOf("opacity=") >= 0 ? parseFloat(Ja.exec(f.filter)[1]) / 100 + "" : ""
    } if (ja.test(b)) b = Ka; b = b.replace(ka, la); if (e) f[b] = d; return f[b]
}, css: function(a, b, d, f) {
    if (b === "width" || b === "height") {
        var e, i = b === "width" ? nb : ob; function j() {
            e = b === "width" ? a.offsetWidth : a.offsetHeight; f !== "border" && c.each(i, function() {
                f || (e -= parseFloat(c.curCSS(a, "padding" + this, true)) || 0); if (f === "margin") e +=
parseFloat(c.curCSS(a, "margin" + this, true)) || 0; else e -= parseFloat(c.curCSS(a, "border" + this + "Width", true)) || 0
            })
        } a.offsetWidth !== 0 ? j() : c.swap(a, mb, j); return Math.max(0, Math.round(e))
    } return c.curCSS(a, b, d)
}, curCSS: function(a, b, d) {
    var f, e = a.style; if (!c.support.opacity && b === "opacity" && a.currentStyle) { f = Ja.test(a.currentStyle.filter || "") ? parseFloat(RegExp.$1) / 100 + "" : ""; return f === "" ? "1" : f } if (ja.test(b)) b = Ka; if (!d && e && e[b]) f = e[b]; else if (pb) {
        if (ja.test(b)) b = "float"; b = b.replace(jb, "-$1").toLowerCase(); e =
a.ownerDocument.defaultView; if (!e) return null; if (a = e.getComputedStyle(a, null)) f = a.getPropertyValue(b); if (b === "opacity" && f === "") f = "1"
    } else if (a.currentStyle) { d = b.replace(ka, la); f = a.currentStyle[b] || a.currentStyle[d]; if (!kb.test(f) && lb.test(f)) { b = e.left; var i = a.runtimeStyle.left; a.runtimeStyle.left = a.currentStyle.left; e.left = d === "fontSize" ? "1em" : f || 0; f = e.pixelLeft + "px"; e.left = b; a.runtimeStyle.left = i } } return f
}, swap: function(a, b, d) {
    var f = {}; for (var e in b) { f[e] = a.style[e]; a.style[e] = b[e] } d.call(a); for (e in b) a.style[e] =
f[e]
} 
}); if (c.expr && c.expr.filters) { c.expr.filters.hidden = function(a) { var b = a.offsetWidth, d = a.offsetHeight, f = a.nodeName.toLowerCase() === "tr"; return b === 0 && d === 0 && !f ? true : b > 0 && d > 0 && !f ? false : c.curCSS(a, "display") === "none" }; c.expr.filters.visible = function(a) { return !c.expr.filters.hidden(a) } } var qb = K(), rb = /<script(.|\s)*?\/script>/gi, sb = /select|textarea/i, tb = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i, O = /=\?(&|$)/, ma = /\?/, ub = /(\?|&)_=.*?(&|$)/, vb = /^(\w+:)?\/\/([^\/?#]+)/,
wb = /%20/g; c.fn.extend({ _load: c.fn.load, load: function(a, b, d) {
    if (typeof a !== "string") return this._load(a); else if (!this.length) return this; var f = a.indexOf(" "); if (f >= 0) { var e = a.slice(f, a.length); a = a.slice(0, f) } f = "GET"; if (b) if (c.isFunction(b)) { d = b; b = null } else if (typeof b === "object") { b = c.param(b, c.ajaxSettings.traditional); f = "POST" } c.ajax({ url: a, type: f, dataType: "html", data: b, context: this, complete: function(i, j) {
        if (j === "success" || j === "notmodified") this.html(e ? c("<div />").append(i.responseText.replace(rb,
"")).find(e) : i.responseText); d && this.each(d, [i.responseText, j, i])
    } 
    }); return this
}, serialize: function() { return c.param(this.serializeArray()) }, serializeArray: function() { return this.map(function() { return this.elements ? c.makeArray(this.elements) : this }).filter(function() { return this.name && !this.disabled && (this.checked || sb.test(this.nodeName) || tb.test(this.type)) }).map(function(a, b) { a = c(this).val(); return a == null ? null : c.isArray(a) ? c.map(a, function(d) { return { name: b.name, value: d} }) : { name: b.name, value: a} }).get() } 
});
    c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(a, b) { c.fn[b] = function(d) { return this.bind(b, d) } }); c.extend({ get: function(a, b, d, f) { if (c.isFunction(b)) { f = f || d; d = b; b = null } return c.ajax({ type: "GET", url: a, data: b, success: d, dataType: f }) }, getScript: function(a, b) { return c.get(a, null, b, "script") }, getJSON: function(a, b, d) { return c.get(a, b, d, "json") }, post: function(a, b, d, f) { if (c.isFunction(b)) { f = f || d; d = b; b = {} } return c.ajax({ type: "POST", url: a, data: b, success: d, dataType: f }) },
        ajaxSetup: function(a) { c.extend(c.ajaxSettings, a) }, ajaxSettings: { url: location.href, global: true, type: "GET", contentType: "application/x-www-form-urlencoded", processData: true, async: true, xhr: A.XMLHttpRequest && (A.location.protocol !== "file:" || !A.ActiveXObject) ? function() { return new A.XMLHttpRequest } : function() { try { return new A.ActiveXObject("Microsoft.XMLHTTP") } catch (a) { } }, accepts: { xml: "application/xml, text/xml", html: "text/html", script: "text/javascript, application/javascript", json: "application/json, text/javascript",
            text: "text/plain", _default: "*/*"}
        }, lastModified: {}, etag: {}, ajax: function(a) {
            function b() { e.success && e.success.call(p, o, j, x); e.global && f("ajaxSuccess", [x, e]) } function d() { e.complete && e.complete.call(p, x, j); e.global && f("ajaxComplete", [x, e]); e.global && ! --c.active && c.event.trigger("ajaxStop") } function f(r, q) { (e.context ? c(e.context) : c.event).trigger(r, q) } var e = c.extend(true, {}, c.ajaxSettings, a), i, j, o, p = e.context || e, n = e.type.toUpperCase(); if (e.data && e.processData && typeof e.data !== "string") e.data = c.param(e.data,
e.traditional); if (e.dataType === "jsonp") { if (n === "GET") O.test(e.url) || (e.url += (ma.test(e.url) ? "&" : "?") + (e.jsonp || "callback") + "=?"); else if (!e.data || !O.test(e.data)) e.data = (e.data ? e.data + "&" : "") + (e.jsonp || "callback") + "=?"; e.dataType = "json" } if (e.dataType === "json" && (e.data && O.test(e.data) || O.test(e.url))) {
                i = e.jsonpCallback || "jsonp" + qb++; if (e.data) e.data = (e.data + "").replace(O, "=" + i + "$1"); e.url = e.url.replace(O, "=" + i + "$1"); e.dataType = "script"; A[i] = A[i] || function(r) {
                    o = r; b(); d(); A[i] = w; try { delete A[i] } catch (q) { } B &&
B.removeChild(C)
                } 
            } if (e.dataType === "script" && e.cache === null) e.cache = false; if (e.cache === false && n === "GET") { var t = K(), z = e.url.replace(ub, "$1_=" + t + "$2"); e.url = z + (z === e.url ? (ma.test(e.url) ? "&" : "?") + "_=" + t : "") } if (e.data && n === "GET") e.url += (ma.test(e.url) ? "&" : "?") + e.data; e.global && !c.active++ && c.event.trigger("ajaxStart"); t = (t = vb.exec(e.url)) && (t[1] && t[1] !== location.protocol || t[2] !== location.host); if (e.dataType === "script" && n === "GET" && t) {
                var B = s.getElementsByTagName("head")[0] || s.documentElement, C = s.createElement("script");
                C.src = e.url; if (e.scriptCharset) C.charset = e.scriptCharset; if (!i) { var D = false; C.onload = C.onreadystatechange = function() { if (!D && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { D = true; b(); d(); C.onload = C.onreadystatechange = null; B && C.parentNode && B.removeChild(C) } } } B.insertBefore(C, B.firstChild); return w
            } var F = false, x = e.xhr(); if (x) {
                e.username ? x.open(n, e.url, e.async, e.username, e.password) : x.open(n, e.url, e.async); try {
                    if (e.data || a && a.contentType) x.setRequestHeader("Content-Type",
e.contentType); if (e.ifModified) { c.lastModified[e.url] && x.setRequestHeader("If-Modified-Since", c.lastModified[e.url]); c.etag[e.url] && x.setRequestHeader("If-None-Match", c.etag[e.url]) } t || x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); x.setRequestHeader("Accept", e.dataType && e.accepts[e.dataType] ? e.accepts[e.dataType] + ", */*" : e.accepts._default)
                } catch (ia) { } if (e.beforeSend && e.beforeSend.call(p, x, e) === false) { e.global && ! --c.active && c.event.trigger("ajaxStop"); x.abort(); return false } e.global && f("ajaxSend",
[x, e]); var g = x.onreadystatechange = function(r) {
    if (!x || x.readyState === 0) { F || d(); F = true; if (x) x.onreadystatechange = c.noop } else if (!F && x && (x.readyState === 4 || r === "timeout")) {
        F = true; x.onreadystatechange = c.noop; j = r === "timeout" ? "timeout" : !c.httpSuccess(x) ? "error" : e.ifModified && c.httpNotModified(x, e.url) ? "notmodified" : "success"; if (j === "success") try { o = c.httpData(x, e.dataType, e) } catch (q) { j = "parsererror" } if (j === "success" || j === "notmodified") i || b(); else c.handleError(e, x, j); d(); r === "timeout" && x.abort(); if (e.async) x =
null
    } 
}; try { var h = x.abort; x.abort = function() { if (x) { h.call(x); if (x) x.readyState = 0 } g() } } catch (k) { } e.async && e.timeout > 0 && setTimeout(function() { x && !F && g("timeout") }, e.timeout); try { x.send(n === "POST" || n === "PUT" || n === "DELETE" ? e.data : null) } catch (m) { c.handleError(e, x, null, m); d() } e.async || g(); return x
            } 
        }, handleError: function(a, b, d, f) { if (a.error) a.error.call(a.context || A, b, d, f); if (a.global) (a.context ? c(a.context) : c.event).trigger("ajaxError", [b, a, f]) }, active: 0, httpSuccess: function(a) {
            try {
                return !a.status && location.protocol ===
"file:" || a.status >= 200 && a.status < 300 || a.status === 304 || a.status === 1223 || a.status === 0
            } catch (b) { } return false
        }, httpNotModified: function(a, b) { var d = a.getResponseHeader("Last-Modified"), f = a.getResponseHeader("Etag"); if (d) c.lastModified[b] = d; if (f) c.etag[b] = f; return a.status === 304 || a.status === 0 }, httpData: function(a, b, d) {
            var f = a.getResponseHeader("content-type") || "", e = b === "xml" || !b && f.indexOf("xml") >= 0; a = e ? a.responseXML : a.responseText; if (e && a.documentElement.nodeName === "parsererror") throw "parsererror"; if (d &&
d.dataFilter) a = d.dataFilter(a, b); if (typeof a === "string") if (b === "json" || !b && f.indexOf("json") >= 0) if (/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) a = A.JSON && A.JSON.parse ? A.JSON.parse(a) : (new Function("return " + a))(); else throw "Invalid JSON: " + a; else if (b === "script" || !b && f.indexOf("javascript") >= 0) c.globalEval(a); return a
        }, param: function(a, b) {
            function d(e, i) {
                i =
c.isFunction(i) ? i() : i; f[f.length] = encodeURIComponent(e) + "=" + encodeURIComponent(i)
            } var f = []; if (b === w) b = c.ajaxSettings.traditional; c.isArray(a) || a.jquery ? c.each(a, function() { d(this.name, this.value) }) : c.each(a, function e(i, j) { if (c.isArray(j)) c.each(j, function(o, p) { b ? d(i, p) : e(i + "[" + (typeof p === "object" || c.isArray(p) ? o : "") + "]", p) }); else !b && j != null && typeof j === "object" ? c.each(j, function(o, p) { e(i + "[" + o + "]", p) }) : d(i, j) }); return f.join("&").replace(wb, "+")
        } 
    }); var na = {}, xb = /toggle|show|hide/, yb = /^([+-]=)?([\d+-.]+)(.*)$/,
Z, va = [["height", "marginTop", "marginBottom", "paddingTop", "paddingBottom"], ["width", "marginLeft", "marginRight", "paddingLeft", "paddingRight"], ["opacity"]]; c.fn.extend({ show: function(a, b) {
    if (a != null) return this.animate(L("show", 3), a, b); else {
        a = 0; for (b = this.length; a < b; a++) {
            var d = c.data(this[a], "olddisplay"); this[a].style.display = d || ""; if (c.css(this[a], "display") === "none") {
                d = this[a].nodeName; var f; if (na[d]) f = na[d]; else {
                    var e = c("<" + d + " />").appendTo("body"); f = e.css("display"); if (f === "none") f = "block"; e.remove();
                    na[d] = f
                } c.data(this[a], "olddisplay", f)
            } 
        } a = 0; for (b = this.length; a < b; a++) this[a].style.display = c.data(this[a], "olddisplay") || ""; return this
    } 
}, hide: function(a, b) { if (a != null) return this.animate(L("hide", 3), a, b); else { a = 0; for (b = this.length; a < b; a++) { var d = c.data(this[a], "olddisplay"); !d && d !== "none" && c.data(this[a], "olddisplay", c.css(this[a], "display")) } a = 0; for (b = this.length; a < b; a++) this[a].style.display = "none"; return this } }, _toggle: c.fn.toggle, toggle: function(a, b) {
    var d = typeof a === "boolean"; if (c.isFunction(a) &&
c.isFunction(b)) this._toggle.apply(this, arguments); else a == null || d ? this.each(function() { var f = d ? a : c(this).is(":hidden"); c(this)[f ? "show" : "hide"]() }) : this.animate(L("toggle", 3), a, b); return this
}, fadeTo: function(a, b, d) { return this.filter(":hidden").css("opacity", 0).show().end().animate({ opacity: b }, a, d) }, animate: function(a, b, d, f) {
    var e = c.speed(b, d, f); if (c.isEmptyObject(a)) return this.each(e.complete); return this[e.queue === false ? "each" : "queue"](function() {
        var i = c.extend({}, e), j, o = this.nodeType === 1 && c(this).is(":hidden"),
p = this; for (j in a) { var n = j.replace(ka, la); if (j !== n) { a[n] = a[j]; delete a[j]; j = n } if (a[j] === "hide" && o || a[j] === "show" && !o) return i.complete.call(this); if ((j === "height" || j === "width") && this.style) { i.display = c.css(this, "display"); i.overflow = this.style.overflow } if (c.isArray(a[j])) { (i.specialEasing = i.specialEasing || {})[j] = a[j][1]; a[j] = a[j][0] } } if (i.overflow != null) this.style.overflow = "hidden"; i.curAnim = c.extend({}, a); c.each(a, function(t, z) {
    var B = new c.fx(p, i, t); if (xb.test(z)) B[z === "toggle" ? o ? "show" : "hide" : z](a);
    else { var C = yb.exec(z), D = B.cur(true) || 0; if (C) { z = parseFloat(C[2]); var F = C[3] || "px"; if (F !== "px") { p.style[t] = (z || 1) + F; D = (z || 1) / B.cur(true) * D; p.style[t] = D + F } if (C[1]) z = (C[1] === "-=" ? -1 : 1) * z + D; B.custom(D, z, F) } else B.custom(D, z, "") } 
}); return true
    })
}, stop: function(a, b) { var d = c.timers; a && this.queue([]); this.each(function() { for (var f = d.length - 1; f >= 0; f--) if (d[f].elem === this) { b && d[f](true); d.splice(f, 1) } }); b || this.dequeue(); return this } 
}); c.each({ slideDown: L("show", 1), slideUp: L("hide", 1), slideToggle: L("toggle",
1), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide"}
}, function(a, b) { c.fn[a] = function(d, f) { return this.animate(b, d, f) } }); c.extend({ speed: function(a, b, d) { var f = a && typeof a === "object" ? a : { complete: d || !d && b || c.isFunction(a) && a, duration: a, easing: d && b || b && !c.isFunction(b) && b }; f.duration = c.fx.off ? 0 : typeof f.duration === "number" ? f.duration : c.fx.speeds[f.duration] || c.fx.speeds._default; f.old = f.complete; f.complete = function() { f.queue !== false && c(this).dequeue(); c.isFunction(f.old) && f.old.call(this) }; return f }, easing: { linear: function(a,
b, d, f) { return d + f * a }, swing: function(a, b, d, f) { return (-Math.cos(a * Math.PI) / 2 + 0.5) * f + d } 
}, timers: [], fx: function(a, b, d) { this.options = b; this.elem = a; this.prop = d; if (!b.orig) b.orig = {} } 
}); c.fx.prototype = { update: function() { this.options.step && this.options.step.call(this.elem, this.now, this); (c.fx.step[this.prop] || c.fx.step._default)(this); if ((this.prop === "height" || this.prop === "width") && this.elem.style) this.elem.style.display = "block" }, cur: function(a) {
    if (this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] ==
null)) return this.elem[this.prop]; return (a = parseFloat(c.css(this.elem, this.prop, a))) && a > -10000 ? a : parseFloat(c.curCSS(this.elem, this.prop)) || 0
}, custom: function(a, b, d) { function f(i) { return e.step(i) } this.startTime = K(); this.start = a; this.end = b; this.unit = d || this.unit || "px"; this.now = this.start; this.pos = this.state = 0; var e = this; f.elem = this.elem; if (f() && c.timers.push(f) && !Z) Z = setInterval(c.fx.tick, 13) }, show: function() {
    this.options.orig[this.prop] = c.style(this.elem, this.prop); this.options.show = true; this.custom(this.prop ===
"width" || this.prop === "height" ? 1 : 0, this.cur()); c(this.elem).show()
}, hide: function() { this.options.orig[this.prop] = c.style(this.elem, this.prop); this.options.hide = true; this.custom(this.cur(), 0) }, step: function(a) {
    var b = K(), d = true; if (a || b >= this.options.duration + this.startTime) {
        this.now = this.end; this.pos = this.state = 1; this.update(); this.options.curAnim[this.prop] = true; for (var f in this.options.curAnim) if (this.options.curAnim[f] !== true) d = false; if (d) {
            if (this.options.display != null) {
                this.elem.style.overflow =
this.options.overflow; a = c.data(this.elem, "olddisplay"); this.elem.style.display = a ? a : this.options.display; if (c.css(this.elem, "display") === "none") this.elem.style.display = "block"
            } this.options.hide && c(this.elem).hide(); if (this.options.hide || this.options.show) for (var e in this.options.curAnim) c.style(this.elem, e, this.options.orig[e]); this.options.complete.call(this.elem)
        } return false
    } else {
        e = b - this.startTime; this.state = e / this.options.duration; a = this.options.easing || (c.easing.swing ? "swing" : "linear"); this.pos =
c.easing[this.options.specialEasing && this.options.specialEasing[this.prop] || a](this.state, e, 0, 1, this.options.duration); this.now = this.start + (this.end - this.start) * this.pos; this.update()
    } return true
} 
}; c.extend(c.fx, { tick: function() { for (var a = c.timers, b = 0; b < a.length; b++) a[b]() || a.splice(b--, 1); a.length || c.fx.stop() }, stop: function() { clearInterval(Z); Z = null }, speeds: { slow: 600, fast: 200, _default: 400 }, step: { opacity: function(a) { c.style(a.elem, "opacity", a.now) }, _default: function(a) {
    if (a.elem.style && a.elem.style[a.prop] !=
null) a.elem.style[a.prop] = (a.prop === "width" || a.prop === "height" ? Math.max(0, a.now) : a.now) + a.unit; else a.elem[a.prop] = a.now
} }
}); if (c.expr && c.expr.filters) c.expr.filters.animated = function(a) { return c.grep(c.timers, function(b) { return a === b.elem }).length }; c.fn.offset = "getBoundingClientRect" in s.documentElement ? function(a) {
    var b = this[0]; if (!b || !b.ownerDocument) return null; if (a) return this.each(function(e) { c.offset.setOffset(this, a, e) }); if (b === b.ownerDocument.body) return c.offset.bodyOffset(b); var d = b.getBoundingClientRect(),
f = b.ownerDocument; b = f.body; f = f.documentElement; return { top: d.top + (self.pageYOffset || c.support.boxModel && f.scrollTop || b.scrollTop) - (f.clientTop || b.clientTop || 0), left: d.left + (self.pageXOffset || c.support.boxModel && f.scrollLeft || b.scrollLeft) - (f.clientLeft || b.clientLeft || 0)}
} : function(a) {
    var b = this[0]; if (!b || !b.ownerDocument) return null; if (a) return this.each(function(t) { c.offset.setOffset(this, a, t) }); if (b === b.ownerDocument.body) return c.offset.bodyOffset(b); c.offset.initialize(); var d = b.offsetParent, f =
b, e = b.ownerDocument, i, j = e.documentElement, o = e.body; f = (e = e.defaultView) ? e.getComputedStyle(b, null) : b.currentStyle; for (var p = b.offsetTop, n = b.offsetLeft; (b = b.parentNode) && b !== o && b !== j; ) {
        if (c.offset.supportsFixedPosition && f.position === "fixed") break; i = e ? e.getComputedStyle(b, null) : b.currentStyle; p -= b.scrollTop; n -= b.scrollLeft; if (b === d) {
            p += b.offsetTop; n += b.offsetLeft; if (c.offset.doesNotAddBorder && !(c.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(b.nodeName))) {
                p += parseFloat(i.borderTopWidth) ||
0; n += parseFloat(i.borderLeftWidth) || 0
            } f = d; d = b.offsetParent
        } if (c.offset.subtractsBorderForOverflowNotVisible && i.overflow !== "visible") { p += parseFloat(i.borderTopWidth) || 0; n += parseFloat(i.borderLeftWidth) || 0 } f = i
    } if (f.position === "relative" || f.position === "static") { p += o.offsetTop; n += o.offsetLeft } if (c.offset.supportsFixedPosition && f.position === "fixed") { p += Math.max(j.scrollTop, o.scrollTop); n += Math.max(j.scrollLeft, o.scrollLeft) } return { top: p, left: n}
}; c.offset = { initialize: function() {
    var a = s.body, b = s.createElement("div"),
d, f, e, i = parseFloat(c.curCSS(a, "marginTop", true)) || 0; c.extend(b.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" }); b.innerHTML = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>"; a.insertBefore(b, a.firstChild);
    d = b.firstChild; f = d.firstChild; e = d.nextSibling.firstChild.firstChild; this.doesNotAddBorder = f.offsetTop !== 5; this.doesAddBorderForTableAndCells = e.offsetTop === 5; f.style.position = "fixed"; f.style.top = "20px"; this.supportsFixedPosition = f.offsetTop === 20 || f.offsetTop === 15; f.style.position = f.style.top = ""; d.style.overflow = "hidden"; d.style.position = "relative"; this.subtractsBorderForOverflowNotVisible = f.offsetTop === -5; this.doesNotIncludeMarginInBodyOffset = a.offsetTop !== i; a.removeChild(b); c.offset.initialize = c.noop
},
    bodyOffset: function(a) { var b = a.offsetTop, d = a.offsetLeft; c.offset.initialize(); if (c.offset.doesNotIncludeMarginInBodyOffset) { b += parseFloat(c.curCSS(a, "marginTop", true)) || 0; d += parseFloat(c.curCSS(a, "marginLeft", true)) || 0 } return { top: b, left: d} }, setOffset: function(a, b, d) {
        if (/static/.test(c.curCSS(a, "position"))) a.style.position = "relative"; var f = c(a), e = f.offset(), i = parseInt(c.curCSS(a, "top", true), 10) || 0, j = parseInt(c.curCSS(a, "left", true), 10) || 0; if (c.isFunction(b)) b = b.call(a, d, e); d = { top: b.top - e.top + i, left: b.left -
e.left + j
        }; "using" in b ? b.using.call(a, d) : f.css(d)
    } 
}; c.fn.extend({ position: function() { if (!this[0]) return null; var a = this[0], b = this.offsetParent(), d = this.offset(), f = /^body|html$/i.test(b[0].nodeName) ? { top: 0, left: 0} : b.offset(); d.top -= parseFloat(c.curCSS(a, "marginTop", true)) || 0; d.left -= parseFloat(c.curCSS(a, "marginLeft", true)) || 0; f.top += parseFloat(c.curCSS(b[0], "borderTopWidth", true)) || 0; f.left += parseFloat(c.curCSS(b[0], "borderLeftWidth", true)) || 0; return { top: d.top - f.top, left: d.left - f.left} }, offsetParent: function() {
    return this.map(function() {
        for (var a =
this.offsetParent || s.body; a && !/^body|html$/i.test(a.nodeName) && c.css(a, "position") === "static"; ) a = a.offsetParent; return a
    })
} 
}); c.each(["Left", "Top"], function(a, b) { var d = "scroll" + b; c.fn[d] = function(f) { var e = this[0], i; if (!e) return null; if (f !== w) return this.each(function() { if (i = wa(this)) i.scrollTo(!a ? f : c(i).scrollLeft(), a ? f : c(i).scrollTop()); else this[d] = f }); else return (i = wa(e)) ? "pageXOffset" in i ? i[a ? "pageYOffset" : "pageXOffset"] : c.support.boxModel && i.document.documentElement[d] || i.document.body[d] : e[d] } });
    c.each(["Height", "Width"], function(a, b) {
        var d = b.toLowerCase(); c.fn["inner" + b] = function() { return this[0] ? c.css(this[0], d, false, "padding") : null }; c.fn["outer" + b] = function(f) { return this[0] ? c.css(this[0], d, false, f ? "margin" : "border") : null }; c.fn[d] = function(f) {
            var e = this[0]; if (!e) return f == null ? null : this; return "scrollTo" in e && e.document ? e.document.compatMode === "CSS1Compat" && e.document.documentElement["client" + b] || e.document.body["client" + b] : e.nodeType === 9 ? Math.max(e.documentElement["client" + b], e.body["scroll" +
b], e.documentElement["scroll" + b], e.body["offset" + b], e.documentElement["offset" + b]) : f === w ? c.css(e, d) : this.css(d, typeof f === "string" ? f : f + "px")
        } 
    }); A.jQuery = A.$ = c
})(window);



/*
* jQuery Cycle Plugin (with Transition Definitions)
* Examples and documentation at: http://jquery.malsup.com/cycle/
* Copyright (c) 2007-2009 M. Alsup
* Version: 2.73 (04-NOV-2009)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
* Requires: jQuery v1.2.6 or later
*
* Originally based on the work of:
*	1) Matt Oakes
*	2) Torsten Baldes (http://medienfreunde.com/lab/innerfade/)
*	3) Benjamin Sterling (http://www.benjaminsterling.com/experiments/jqShuffle/)
*/
(function(i) { var l = "2.73"; if (i.support == undefined) { i.support = { opacity: !(i.browser.msie)} } function a(q) { if (i.fn.cycle.debug) { f(q) } } function f() { if (window.console && window.console.log) { window.console.log("[cycle] " + Array.prototype.join.call(arguments, " ")) } } i.fn.cycle = function(r, q) { var s = { s: this.selector, c: this.context }; if (this.length === 0 && r != "stop") { if (!i.isReady && s.s) { f("DOM not ready, queuing slideshow"); i(function() { i(s.s, s.c).cycle(r, q) }); return this } f("terminating; zero elements found by selector" + (i.isReady ? "" : " (DOM not ready)")); return this } return this.each(function() { var w = m(this, r, q); if (w === false) { return } if (this.cycleTimeout) { clearTimeout(this.cycleTimeout) } this.cycleTimeout = this.cyclePause = 0; var x = i(this); var y = w.slideExpr ? i(w.slideExpr, this) : x.children(); var u = y.get(); if (u.length < 2) { f("terminating; too few slides: " + u.length); return } var t = k(x, y, u, w, s); if (t === false) { return } var v = t.continuous ? 10 : h(t.currSlide, t.nextSlide, t, !t.rev); if (v) { v += (t.delay || 0); if (v < 10) { v = 10 } a("first timeout: " + v); this.cycleTimeout = setTimeout(function() { e(u, t, 0, !t.rev) }, v) } }) }; function m(q, t, r) { if (q.cycleStop == undefined) { q.cycleStop = 0 } if (t === undefined || t === null) { t = {} } if (t.constructor == String) { switch (t) { case "stop": q.cycleStop++; if (q.cycleTimeout) { clearTimeout(q.cycleTimeout) } q.cycleTimeout = 0; i(q).removeData("cycle.opts"); return false; case "pause": q.cyclePause = 1; return false; case "resume": q.cyclePause = 0; if (r === true) { t = i(q).data("cycle.opts"); if (!t) { f("options not found, can not resume"); return false } if (q.cycleTimeout) { clearTimeout(q.cycleTimeout); q.cycleTimeout = 0 } e(t.elements, t, 1, 1) } return false; case "prev": case "next": var u = i(q).data("cycle.opts"); if (!u) { f('options not found, "prev/next" ignored'); return false } i.fn.cycle[t](u); return false; default: t = { fx: t} } return t } else { if (t.constructor == Number) { var s = t; t = i(q).data("cycle.opts"); if (!t) { f("options not found, can not advance slide"); return false } if (s < 0 || s >= t.elements.length) { f("invalid slide index: " + s); return false } t.nextSlide = s; if (q.cycleTimeout) { clearTimeout(q.cycleTimeout); q.cycleTimeout = 0 } if (typeof r == "string") { t.oneTimeFx = r } e(t.elements, t, 1, s >= t.currSlide); return false } } return t } function b(q, r) { if (!i.support.opacity && r.cleartype && q.style.filter) { try { q.style.removeAttribute("filter") } catch (s) { } } } function k(y, J, u, t, E) { var C = i.extend({}, i.fn.cycle.defaults, t || {}, i.metadata ? y.metadata() : i.meta ? y.data() : {}); if (C.autostop) { C.countdown = C.autostopCount || u.length } var r = y[0]; y.data("cycle.opts", C); C.$cont = y; C.stopCount = r.cycleStop; C.elements = u; C.before = C.before ? [C.before] : []; C.after = C.after ? [C.after] : []; C.after.unshift(function() { C.busy = 0 }); if (!i.support.opacity && C.cleartype) { C.after.push(function() { b(this, C) }) } if (C.continuous) { C.after.push(function() { e(u, C, 0, !C.rev) }) } n(C); if (!i.support.opacity && C.cleartype && !C.cleartypeNoBg) { g(J) } if (y.css("position") == "static") { y.css("position", "relative") } if (C.width) { y.width(C.width) } if (C.height && C.height != "auto") { y.height(C.height) } if (C.startingSlide) { C.startingSlide = parseInt(C.startingSlide) } if (C.random) { C.randomMap = []; for (var H = 0; H < u.length; H++) { C.randomMap.push(H) } C.randomMap.sort(function(L, w) { return Math.random() - 0.5 }); C.randomIndex = 0; C.startingSlide = C.randomMap[0] } else { if (C.startingSlide >= u.length) { C.startingSlide = 0 } } C.currSlide = C.startingSlide = C.startingSlide || 0; var x = C.startingSlide; J.css({ position: "absolute", top: 0, left: 0 }).hide().each(function(w) { var L = x ? w >= x ? u.length - (w - x) : x - w : u.length - w; i(this).css("z-index", L) }); i(u[x]).css("opacity", 1).show(); b(u[x], C); if (C.fit && C.width) { J.width(C.width) } if (C.fit && C.height && C.height != "auto") { J.height(C.height) } var D = C.containerResize && !y.innerHeight(); if (D) { var v = 0, B = 0; for (var F = 0; F < u.length; F++) { var q = i(u[F]), K = q[0], A = q.outerWidth(), I = q.outerHeight(); if (!A) { A = K.offsetWidth } if (!I) { I = K.offsetHeight } v = A > v ? A : v; B = I > B ? I : B } if (v > 0 && B > 0) { y.css({ width: v + "px", height: B + "px" }) } } if (C.pause) { y.hover(function() { this.cyclePause++ }, function() { this.cyclePause-- }) } if (c(C) === false) { return false } var s = false; t.requeueAttempts = t.requeueAttempts || 0; J.each(function() { var N = i(this); this.cycleH = (C.fit && C.height) ? C.height : N.height(); this.cycleW = (C.fit && C.width) ? C.width : N.width(); if (N.is("img")) { var L = (i.browser.msie && this.cycleW == 28 && this.cycleH == 30 && !this.complete); var O = (i.browser.mozilla && this.cycleW == 34 && this.cycleH == 19 && !this.complete); var M = (i.browser.opera && ((this.cycleW == 42 && this.cycleH == 19) || (this.cycleW == 37 && this.cycleH == 17)) && !this.complete); var w = (this.cycleH == 0 && this.cycleW == 0 && !this.complete); if (L || O || M || w) { if (E.s && C.requeueOnImageNotLoaded && ++t.requeueAttempts < 100) { f(t.requeueAttempts, " - img slide not loaded, requeuing slideshow: ", this.src, this.cycleW, this.cycleH); setTimeout(function() { i(E.s, E.c).cycle(t) }, C.requeueTimeout); s = true; return false } else { f("could not determine size of image: " + this.src, this.cycleW, this.cycleH) } } } return true }); if (s) { return false } C.cssBefore = C.cssBefore || {}; C.animIn = C.animIn || {}; C.animOut = C.animOut || {}; J.not(":eq(" + x + ")").css(C.cssBefore); if (C.cssFirst) { i(J[x]).css(C.cssFirst) } if (C.timeout) { C.timeout = parseInt(C.timeout); if (C.speed.constructor == String) { C.speed = i.fx.speeds[C.speed] || parseInt(C.speed) } if (!C.sync) { C.speed = C.speed / 2 } while ((C.timeout - C.speed) < 250) { C.timeout += C.speed } } if (C.easing) { C.easeIn = C.easeOut = C.easing } if (!C.speedIn) { C.speedIn = C.speed } if (!C.speedOut) { C.speedOut = C.speed } C.slideCount = u.length; C.currSlide = C.lastSlide = x; if (C.random) { C.nextSlide = C.currSlide; if (++C.randomIndex == u.length) { C.randomIndex = 0 } C.nextSlide = C.randomMap[C.randomIndex] } else { C.nextSlide = C.startingSlide >= (u.length - 1) ? 0 : C.startingSlide + 1 } if (!C.multiFx) { var G = i.fn.cycle.transitions[C.fx]; if (i.isFunction(G)) { G(y, J, C) } else { if (C.fx != "custom" && !C.multiFx) { f("unknown transition: " + C.fx, "; slideshow terminating"); return false } } } var z = J[x]; if (C.before.length) { C.before[0].apply(z, [z, z, C, true]) } if (C.after.length > 1) { C.after[1].apply(z, [z, z, C, true]) } if (C.next) { i(C.next).bind(C.prevNextEvent, function() { return o(C, C.rev ? -1 : 1) }) } if (C.prev) { i(C.prev).bind(C.prevNextEvent, function() { return o(C, C.rev ? 1 : -1) }) } if (C.pager) { d(u, C) } j(C, u); return C } function n(q) { q.original = { before: [], after: [] }; q.original.cssBefore = i.extend({}, q.cssBefore); q.original.cssAfter = i.extend({}, q.cssAfter); q.original.animIn = i.extend({}, q.animIn); q.original.animOut = i.extend({}, q.animOut); i.each(q.before, function() { q.original.before.push(this) }); i.each(q.after, function() { q.original.after.push(this) }) } function c(w) { var u, s, r = i.fn.cycle.transitions; if (w.fx.indexOf(",") > 0) { w.multiFx = true; w.fxs = w.fx.replace(/\s*/g, "").split(","); for (u = 0; u < w.fxs.length; u++) { var v = w.fxs[u]; s = r[v]; if (!s || !r.hasOwnProperty(v) || !i.isFunction(s)) { f("discarding unknown transition: ", v); w.fxs.splice(u, 1); u-- } } if (!w.fxs.length) { f("No valid transitions named; slideshow terminating."); return false } } else { if (w.fx == "all") { w.multiFx = true; w.fxs = []; for (p in r) { s = r[p]; if (r.hasOwnProperty(p) && i.isFunction(s)) { w.fxs.push(p) } } } } if (w.multiFx && w.randomizeEffects) { var t = Math.floor(Math.random() * 20) + 30; for (u = 0; u < t; u++) { var q = Math.floor(Math.random() * w.fxs.length); w.fxs.push(w.fxs.splice(q, 1)[0]) } a("randomized fx sequence: ", w.fxs) } return true } function j(r, q) { r.addSlide = function(u, v) { var t = i(u), w = t[0]; if (!r.autostopCount) { r.countdown++ } q[v ? "unshift" : "push"](w); if (r.els) { r.els[v ? "unshift" : "push"](w) } r.slideCount = q.length; t.css("position", "absolute"); t[v ? "prependTo" : "appendTo"](r.$cont); if (v) { r.currSlide++; r.nextSlide++ } if (!i.support.opacity && r.cleartype && !r.cleartypeNoBg) { g(t) } if (r.fit && r.width) { t.width(r.width) } if (r.fit && r.height && r.height != "auto") { $slides.height(r.height) } w.cycleH = (r.fit && r.height) ? r.height : t.height(); w.cycleW = (r.fit && r.width) ? r.width : t.width(); t.css(r.cssBefore); if (r.pager) { i.fn.cycle.createPagerAnchor(q.length - 1, w, i(r.pager), q, r) } if (i.isFunction(r.onAddSlide)) { r.onAddSlide(t) } else { t.hide() } } } i.fn.cycle.resetState = function(r, q) { q = q || r.fx; r.before = []; r.after = []; r.cssBefore = i.extend({}, r.original.cssBefore); r.cssAfter = i.extend({}, r.original.cssAfter); r.animIn = i.extend({}, r.original.animIn); r.animOut = i.extend({}, r.original.animOut); r.fxFn = null; i.each(r.original.before, function() { r.before.push(this) }); i.each(r.original.after, function() { r.after.push(this) }); var s = i.fn.cycle.transitions[q]; if (i.isFunction(s)) { s(r.$cont, i(r.elements), r) } }; function e(x, q, w, y) { if (w && q.busy && q.manualTrump) { i(x).stop(true, true); q.busy = false } if (q.busy) { return } var u = q.$cont[0], A = x[q.currSlide], z = x[q.nextSlide]; if (u.cycleStop != q.stopCount || u.cycleTimeout === 0 && !w) { return } if (!w && !u.cyclePause && ((q.autostop && (--q.countdown <= 0)) || (q.nowrap && !q.random && q.nextSlide < q.currSlide))) { if (q.end) { q.end(q) } return } if (w || !u.cyclePause) { var v = q.fx; A.cycleH = A.cycleH || i(A).height(); A.cycleW = A.cycleW || i(A).width(); z.cycleH = z.cycleH || i(z).height(); z.cycleW = z.cycleW || i(z).width(); if (q.multiFx) { if (q.lastFx == undefined || ++q.lastFx >= q.fxs.length) { q.lastFx = 0 } v = q.fxs[q.lastFx]; q.currFx = v } if (q.oneTimeFx) { v = q.oneTimeFx; q.oneTimeFx = null } i.fn.cycle.resetState(q, v); if (q.before.length) { i.each(q.before, function(B, C) { if (u.cycleStop != q.stopCount) { return } C.apply(z, [A, z, q, y]) }) } var s = function() { i.each(q.after, function(B, C) { if (u.cycleStop != q.stopCount) { return } C.apply(z, [A, z, q, y]) }) }; if (q.nextSlide != q.currSlide) { q.busy = 1; if (q.fxFn) { q.fxFn(A, z, q, s, y) } else { if (i.isFunction(i.fn.cycle[q.fx])) { i.fn.cycle[q.fx](A, z, q, s) } else { i.fn.cycle.custom(A, z, q, s, w && q.fastOnEvent) } } } q.lastSlide = q.currSlide; if (q.random) { q.currSlide = q.nextSlide; if (++q.randomIndex == x.length) { q.randomIndex = 0 } q.nextSlide = q.randomMap[q.randomIndex] } else { var t = (q.nextSlide + 1) == x.length; q.nextSlide = t ? 0 : q.nextSlide + 1; q.currSlide = t ? x.length - 1 : q.nextSlide - 1 } if (q.pager) { i.fn.cycle.updateActivePagerLink(q.pager, q.currSlide) } } var r = 0; if (q.timeout && !q.continuous) { r = h(A, z, q, y) } else { if (q.continuous && u.cyclePause) { r = 10 } } if (r > 0) { u.cycleTimeout = setTimeout(function() { e(x, q, 0, !q.rev) }, r) } } i.fn.cycle.updateActivePagerLink = function(q, r) { i(q).each(function() { i(this).find("a").removeClass("activeSlide").filter("a:eq(" + r + ")").addClass("activeSlide") }) }; function h(v, s, u, r) { if (u.timeoutFn) { var q = u.timeoutFn(v, s, u, r); while ((q - u.speed) < 250) { q += u.speed } a("calculated timeout: " + q + "; speed: " + u.speed); if (q !== false) { return q } } return u.timeout } i.fn.cycle.next = function(q) { o(q, q.rev ? -1 : 1) }; i.fn.cycle.prev = function(q) { o(q, q.rev ? 1 : -1) }; function o(r, u) { var q = r.elements; var t = r.$cont[0], s = t.cycleTimeout; if (s) { clearTimeout(s); t.cycleTimeout = 0 } if (r.random && u < 0) { r.randomIndex--; if (--r.randomIndex == -2) { r.randomIndex = q.length - 2 } else { if (r.randomIndex == -1) { r.randomIndex = q.length - 1 } } r.nextSlide = r.randomMap[r.randomIndex] } else { if (r.random) { if (++r.randomIndex == q.length) { r.randomIndex = 0 } r.nextSlide = r.randomMap[r.randomIndex] } else { r.nextSlide = r.currSlide + u; if (r.nextSlide < 0) { if (r.nowrap) { return false } r.nextSlide = q.length - 1 } else { if (r.nextSlide >= q.length) { if (r.nowrap) { return false } r.nextSlide = 0 } } } } if (i.isFunction(r.prevNextClick)) { r.prevNextClick(u > 0, r.nextSlide, q[r.nextSlide]) } e(q, r, 1, u >= 0); return false } function d(r, s) { var q = i(s.pager); i.each(r, function(t, u) { i.fn.cycle.createPagerAnchor(t, u, q, r, s) }); i.fn.cycle.updateActivePagerLink(s.pager, s.startingSlide) } i.fn.cycle.createPagerAnchor = function(u, v, s, t, w) { var r; if (i.isFunction(w.pagerAnchorBuilder)) { r = w.pagerAnchorBuilder(u, v) } else { r = '<a href="#">' + (u + 1) + "</a>" } if (!r) { return } var x = i(r); if (x.parents("body").length === 0) { var q = []; if (s.length > 1) { s.each(function() { var y = x.clone(true); i(this).append(y); q.push(y[0]) }); x = i(q) } else { x.appendTo(s) } } x.bind(w.pagerEvent, function(A) { A.preventDefault(); w.nextSlide = u; var z = w.$cont[0], y = z.cycleTimeout; if (y) { clearTimeout(y); z.cycleTimeout = 0 } if (i.isFunction(w.pagerClick)) { w.pagerClick(w.nextSlide, t[w.nextSlide]) } e(t, w, 1, w.currSlide < u); return false }); if (w.pagerEvent != "click") { x.click(function() { return false }) } if (w.pauseOnPagerHover) { x.hover(function() { w.$cont[0].cyclePause++ }, function() { w.$cont[0].cyclePause-- }) } }; i.fn.cycle.hopsFromLast = function(t, s) { var r, q = t.lastSlide, u = t.currSlide; if (s) { r = u > q ? u - q : t.slideCount - q } else { r = u < q ? q - u : q + t.slideCount - u } return r }; function g(s) { function r(t) { t = parseInt(t).toString(16); return t.length < 2 ? "0" + t : t } function q(w) { for (; w && w.nodeName.toLowerCase() != "html"; w = w.parentNode) { var t = i.css(w, "background-color"); if (t.indexOf("rgb") >= 0) { var u = t.match(/\d+/g); return "#" + r(u[0]) + r(u[1]) + r(u[2]) } if (t && t != "transparent") { return t } } return "#ffffff" } s.each(function() { i(this).css("background-color", q(this)) }) } i.fn.cycle.commonReset = function(v, t, u, r, s, q) { i(u.elements).not(v).hide(); u.cssBefore.opacity = 1; u.cssBefore.display = "block"; if (r !== false && t.cycleW > 0) { u.cssBefore.width = t.cycleW } if (s !== false && t.cycleH > 0) { u.cssBefore.height = t.cycleH } u.cssAfter = u.cssAfter || {}; u.cssAfter.display = "none"; i(v).css("zIndex", u.slideCount + (q === true ? 1 : 0)); i(t).css("zIndex", u.slideCount + (q === true ? 0 : 1)) }; i.fn.cycle.custom = function(B, v, q, s, r) { var A = i(B), w = i(v); var t = q.speedIn, z = q.speedOut, u = q.easeIn, y = q.easeOut; w.css(q.cssBefore); if (r) { if (typeof r == "number") { t = z = r } else { t = z = 1 } u = y = null } var x = function() { w.animate(q.animIn, t, u, s) }; A.animate(q.animOut, z, y, function() { if (q.cssAfter) { A.css(q.cssAfter) } if (!q.sync) { x() } }); if (q.sync) { x() } }; i.fn.cycle.transitions = { fade: function(r, s, q) { s.not(":eq(" + q.currSlide + ")").css("opacity", 0); q.before.push(function(v, t, u) { i.fn.cycle.commonReset(v, t, u); u.cssBefore.opacity = 0 }); q.animIn = { opacity: 1 }; q.animOut = { opacity: 0 }; q.cssBefore = { top: 0, left: 0} } }; i.fn.cycle.ver = function() { return l }; i.fn.cycle.defaults = { fx: "fade", timeout: 4000, timeoutFn: null, continuous: 0, speed: 1000, speedIn: null, speedOut: null, next: null, prev: null, prevNextClick: null, prevNextEvent: "click", pager: null, pagerClick: null, pagerEvent: "click", pagerAnchorBuilder: null, before: null, after: null, end: null, easing: null, easeIn: null, easeOut: null, shuffle: null, animIn: null, animOut: null, cssBefore: null, cssAfter: null, fxFn: null, height: "auto", startingSlide: 0, sync: 1, random: 0, fit: 0, containerResize: 1, pause: 0, pauseOnPagerHover: 0, autostop: 0, autostopCount: 0, delay: 0, slideExpr: null, cleartype: !i.support.opacity, cleartypeNoBg: false, nowrap: 0, fastOnEvent: 0, randomizeEffects: 1, rev: 0, manualTrump: true, requeueOnImageNotLoaded: true, requeueTimeout: 250} })(jQuery);


function MM_findObj(n, d) { //v4.01
    var p, i, x; if (!d) d = document; if ((p = n.indexOf("?")) > 0 && parent.frames.length) {
        d = parent.frames[n.substring(p + 1)].document; n = n.substring(0, p);
    }
    if (!(x = d[n]) && d.all) x = d.all[n]; for (i = 0; !x && i < d.forms.length; i++) x = d.forms[i][n];
    for (i = 0; !x && d.layers && i < d.layers.length; i++) x = MM_findObj(n, d.layers[i].document);
    if (!x && d.getElementById) x = d.getElementById(n); return x;
}

function MM_validateForm() { //v4.0
    var i, p, q, nm, test, num, min, max, errors = '', args = MM_validateForm.arguments;

    for (i = 0; i < (args.length - 2); i += 3) {
        test = args[i + 2]; val = MM_findObj(args[i]);
        if (val) {
            nm = val.name; if ((val = val.value) != "") {
                if (test.indexOf('isEmail') != -1) {
                    p = val.indexOf('@');
                    if (p < 1 || p == (val.length - 1)) errors += '- ' + nm + ' must contain an e-mail address.\n';
                } else if (test != 'R') {
                    num = parseFloat(val);
                    if (isNaN(val)) errors += '- ' + nm + ' must contain a number.\n';
                    if (test.indexOf('inRange') != -1) {
                        p = test.indexOf(':');
                        min = test.substring(8, p); max = test.substring(p + 1);
                        if (num < min || max < num) errors += '- ' + nm + ' must contain a number between ' + min + ' and ' + max + '.\n';
                    } 
                } 
            } else if (test.charAt(0) == 'R') errors += '- ' + nm + ' is required.\n';
        }
    }

    if (errors) alert('The following error(s) occurred:\n\n' + errors);
    document.MM_returnValue = (errors == '');
}

/**
* This script contains embed functions for common plugins. This scripts are complety free to use for any purpose.
*/

function writeFlash(p) {
    writeEmbed(
		'D27CDB6E-AE6D-11cf-96B8-444553540000',
		'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',
		'application/x-shockwave-flash',
		p
	);
}

function writeShockWave(p) {
    writeEmbed(
	'166B1BCA-3F9C-11CF-8075-444553540000',
	'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0',
	'application/x-director',
		p
	);
}

function writeQuickTime(p) {
    writeEmbed(
		'02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
		'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
		'video/quicktime',
		p
	);
}

function writeRealMedia(p) {
    writeEmbed(
		'CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA',
		'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0',
		'audio/x-pn-realaudio-plugin',
		p
	);
}

function writeWindowsMedia(p) {
    p.url = p.src;
    writeEmbed(
		'6BF52A52-394A-11D3-B153-00C04F79FAA6',
		'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701',
		'application/x-mplayer2',
		p
	);
}

function writeEmbed(cls, cb, mt, p) {
    var h = '', n;

    h += '<object classid="clsid:' + cls + '" codebase="' + cb + '"';
    h += typeof (p.id) != "undefined" ? 'id="' + p.id + '"' : '';
    h += typeof (p.name) != "undefined" ? 'name="' + p.name + '"' : '';
    h += typeof (p.width) != "undefined" ? 'width="' + p.width + '"' : '';
    h += typeof (p.height) != "undefined" ? 'height="' + p.height + '"' : '';
    h += typeof (p.align) != "undefined" ? 'align="' + p.align + '"' : '';
    h += '>';

    for (n in p)
        h += '<param name="' + n + '" value="' + p[n] + '">';

    h += '<embed type="' + mt + '"';

    for (n in p)
        h += n + '="' + p[n] + '" ';

    h += '></embed></object>';

    document.write(h);
}





//jQuery Plugin: Drop Shadow Text
// call like this: $(element).textDropShadow();
(function($) {
    $.fn.textDropShadow = function() {
        $(this).html('<span class="jq-shadow">' + $(this).html() + '</span><span>' + $(this).html() + '</span>');
        return $(this);
    }
})(jQuery);




$(document).ready(function() { var a = navigator.userAgent.toLowerCase(); $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase()); if ($.browser.msie) { $('body').addClass('browserIE'); $('body').addClass('browserIE' + $.browser.version.substring(0, 1)) } if ($.browser.chrome) { $('body').addClass('browserChrome'); a = a.substring(a.indexOf('chrome/') + 7); a = a.substring(0, 1); $('body').addClass('browserChrome' + a); $.browser.safari = false } if ($.browser.safari) { $('body').addClass('browserSafari'); a = a.substring(a.indexOf('version/') + 8); a = a.substring(0, 1); $('body').addClass('browserSafari' + a) } if ($.browser.mozilla) { if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) { $('body').addClass('browserFirefox'); a = a.substring(a.indexOf('firefox/') + 8); a = a.substring(0, 1); $('body').addClass('browserFirefox' + a) } else { $('body').addClass('browserMozilla') } } if ($.browser.opera) { $('body').addClass('browserOpera') } });

$(document).ready(function() {

    $('.browserFirefox .menu li').hover(function() {
        $(this).find("> ul").hide().fadeIn("slow");
    }, function() {
    });

    $(".hoveritem").hover(function() {
        $(this).find("h2").animate({ top: "-5px" }, "fast");
    }, function() {
        $(this).find("h2").animate({ top: "0px" }, "fast");
    });

    // FADE PHOTO
    $('#slideshow').cycle({
        timeout: 12000,
        speed: 700,
        random: 0,
        pause: 1
    });

    $('#hover0').hover(function() {
        $('#slideshow').cycle(0);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover1').hover(function() {
        $('#slideshow').cycle(1);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover2').hover(function() {
        $('#slideshow').cycle(2);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover3').hover(function() {
        $('#slideshow').cycle(3);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover4').hover(function() {
        $('#slideshow').cycle(4);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover5').hover(function() {
        $('#slideshow').cycle(5);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $('#hover6').hover(function() {
        $('#slideshow').cycle(6);
        $('#slideshow').cycle('pause');
    }, function() {
        $('#slideshow').cycle('resume');
    });

    $("#submenu ul li").find(".selected").parent().parent().addClass("selected");

    $("#submenu ul li ul li").parent().hide();
    $("#submenu ul li ul li.selected").parent().show();
    $("#submenu ul li.selected").children().show();



});



(function($) {
    $.formatCurrency = {}; $.formatCurrency.regions = []; $.formatCurrency.regions[""] = { symbol: "$", positiveFormat: "%s%n", negativeFormat: "(%s%n)", decimalSymbol: ".", digitGroupSymbol: ",", groupDigits: true };
    $.fn.formatCurrency = function(destination, settings) {
        if (arguments.length == 1 && typeof destination !== "string") {
            settings = destination; destination = false
        } var defaults = { name: "formatCurrency", colorize: false, region: "", global: true, roundToDecimalPlace: 2, eventOnDecimalsEntered: false }; defaults = $.extend(defaults, $.formatCurrency.regions[""]);
        settings = $.extend(defaults, settings); if (settings.region.length > 0) { settings = $.extend(settings, getRegionOrCulture(settings.region)) } settings.regex = generateRegex(settings);
        return this.each(function() {
            $this = $(this); var num = "0"; num = $this[$this.is("input, select, textarea") ? "val" : "html"](); if (num.search("\\(") >= 0) {
                num = "-" + num
            } if (num === "") { return } if (isNaN(num)) {
                num = num.replace(settings.regex, ""); if (num === "") { return } if (settings.decimalSymbol != ".") {
                    num = num.replace(settings.decimalSymbol, ".")
                } if (isNaN(num)) { num = "0" } 
            } var numParts = String(num).split("."); var isPositive = (num == Math.abs(num)); var hasDecimals = (numParts.length > 1); var decimals = (hasDecimals ? numParts[1].toString() : "0");
            var originalDecimals = decimals; num = Math.abs(numParts[0]); if (settings.roundToDecimalPlace >= 0) {
                decimals = parseFloat("1." + decimals); decimals = decimals.toFixed(settings.roundToDecimalPlace);
                if (decimals.substring(0, 1) == "2") { num = Number(num) + 1 } decimals = decimals.substring(2)
            } num = String(num); if (settings.groupDigits) {
                for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3);
i++) { num = num.substring(0, num.length - (4 * i + 3)) + settings.digitGroupSymbol + num.substring(num.length - (4 * i + 3)) } 
            } if ((hasDecimals && settings.roundToDecimalPlace == -1) || settings.roundToDecimalPlace > 0) {
                num += settings.decimalSymbol + decimals
            } var format = isPositive ? settings.positiveFormat : settings.negativeFormat; var money = format.replace(/%s/g, settings.symbol); money = money.replace(/%n/g, num);
            var $destination = $([]); if (!destination) { $destination = $this } else { $destination = $(destination) } $destination[$destination.is("input, select, textarea") ? "val" : "html"](money);
            if (hasDecimals && settings.eventOnDecimalsEntered) { $destination.trigger("decimalsEntered", originalDecimals) } if (settings.colorize) {
                $destination.css("color", isPositive ? "black" : "red")
            } 
        })
    }; $.fn.toNumber = function(settings) {
        var defaults = $.extend({ name: "toNumber", region: "", global: true }, $.formatCurrency.regions[""]); settings = jQuery.extend(defaults, settings);
        if (settings.region.length > 0) { settings = $.extend(settings, getRegionOrCulture(settings.region)) } settings.regex = generateRegex(settings); return this.each(function() {
            var method = $(this).is("input, select, textarea") ? "val" : "html";
            $(this)[method]($(this)[method]().replace("(", "(-").replace(settings.regex, ""))
        })
    }; $.fn.asNumber = function(settings) {
        var defaults = $.extend({ name: "asNumber", region: "", parse: true, parseType: "Float", global: true }, $.formatCurrency.regions[""]);
        settings = jQuery.extend(defaults, settings); if (settings.region.length > 0) { settings = $.extend(settings, getRegionOrCulture(settings.region)) } settings.regex = generateRegex(settings);
        settings.parseType = validateParseType(settings.parseType); var method = $(this).is("input, select, textarea") ? "val" : "html"; var num = $(this)[method]();
        num = num ? num : ""; num = num.replace("(", "(-"); num = num.replace(settings.regex, ""); if (!settings.parse) { return num } if (num.length == 0) { num = "0" } if (settings.decimalSymbol != ".") {
            num = num.replace(settings.decimalSymbol, ".")
        } return window["parse" + settings.parseType](num)
    }; function getRegionOrCulture(region) {
        var regionInfo = $.formatCurrency.regions[region]; if (regionInfo) {
            return regionInfo
        } else { if (/(\w+)-(\w+)/g.test(region)) { var culture = region.replace(/(\w+)-(\w+)/g, "$1"); return $.formatCurrency.regions[culture] } } return null
    } function validateParseType(parseType) {
        switch (parseType.toLowerCase()) {
            case "int": return "Int";
            case "float": return "Float"; default: throw "invalid parseType"
        } 
    } function generateRegex(settings) {
        if (settings.symbol === "") {
            return new RegExp("[^\\d" + settings.decimalSymbol + "-]", "g")
        } else { var symbol = settings.symbol.replace("$", "\\$").replace(".", "\\."); return new RegExp(symbol + "|[^\\d" + settings.decimalSymbol + "-]", "g") } 
    } 
})(jQuery);


/**
* Title: jqPlot Charts
* 
* Pure JavaScript plotting plugin for jQuery.
* 
* About: Version
* 
* 0.9.6 
* 
* About: Copyright & License
* 
* Copyright (c) 2009 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects 
* under both the MIT and GPL version 2.0 licenses. This means that you can 
* choose the license that best suits your project and use it accordingly.
* 
* See <GPL Version 2> and <MIT License> contained within this distribution for further information. 
*
* The author would appreciate an email letting him know of any substantial
* use of jqPlot.  You can reach the author at: chris dot leonello at gmail 
* dot com or see http://www.jqplot.com/info.php.  This is, of course, not required.
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php.
*
* 
* About: Introduction
* 
* jqPlot requires jQuery (tested with 1.3.2 or better). jQuery 1.3.2 is included in the distribution.  
* To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and optionally 
* the excanvas script for IE support in your web page:
* 
* > <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
* > <script language="javascript" type="text/javascript" src="jquery-1.3.2.min.js"></script>
* > <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script>
* > <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" />
* 
* jqPlot can be customized by overriding the defaults of any of the objects which make
* up the plot. The general usage of jqplot is:
* 
* > chart = $.jqplot('targetElemId', [dataArray,...], {optionsObject});
* 
* The options available to jqplot are detailed in <jqPlot Options> in the jqPlotOptions.txt file.
* 
* An actual call to $.jqplot() may look like the 
* examples below:
* 
* > chart = $.jqplot('chartdiv',  [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]);
* 
* or
* 
* > dataArray = [34,12,43,55,77];
* > chart = $.jqplot('targetElemId', [dataArray, ...], {title:'My Plot', axes:{yaxis:{min:20, max:100}}});
* 
* For more inforrmation, see <jqPlot Usage>.
* 
* About: Usage
* 
* See <jqPlot Usage>
* 
* About: Available Options 
* 
* See <jqPlot Options> for a list of options available thorugh the options object (not complete yet!)
* 
* About: Options Usage
* 
* See <Options Tutorial>
* 
* About: Changes
* 
* See <Change Log>
* 
*/

(function($) {
    // make sure undefined is undefined
    var undefined;

    /**
    * Class: $.jqplot
    * jQuery function called by the user to create a plot.
    *  
    * Parameters:
    * target - ID of target element to render the plot into.
    * data - an array of data series.
    * options - user defined options object.  See the individual classes for available options.
    * 
    * Properties:
    * config - object to hold configuration information for jqPlot plot object.
    * 
    * attributes:
    * enablePlugins - False to disable plugins by default.  Plugins must then be explicitly 
    *   enabled in the individual plot options.  Default: true.
    *   This property sets the "show" property of certain plugins to true or false.
    *   Only plugins that can be immediately active upon loading are affected.  This includes
    *   non-renderer plugins like cursor, dragable, highlighter, and trendline.
    * defaultHeight - Default height for plots where no css height specification exists.  This
    *   is a jqplot wide default.
    * defaultWidth - Default height for plots where no css height specification exists.  This
    *   is a jqplot wide default.
    */

    $.jqplot = function(target, data, options) {
        var _data, _options;

        // check to see if only 2 arguments were specified, what is what.
        if (data == null) {
            throw "No data specified";
        }
        if (data.constructor == Array && data.length == 0 || data[0].constructor != Array) {
            throw "Improper Data Array";
        }
        if (options == null) {
            if (data instanceof Array) {
                _data = data;
                _options = null;
            }

            else if (data.constructor == Object) {
                _data = null;
                _options = data;
            }
        }
        else {
            _data = data;
            _options = options;
        }
        var plot = new jqPlot();
        plot.init(target, _data, _options);
        plot.draw();
        return plot;
    };

    $.jqplot.debug = 1;
    $.jqplot.config = {
        debug: 1,
        enablePlugins: true,
        defaultHeight: 300,
        defaultWidth: 400
    };

    $.jqplot.enablePlugins = $.jqplot.config.enablePlugins;

    /**
    * 
    * Hooks: jqPlot Pugin Hooks
    * 
    * $.jqplot.preInitHooks - called before initialization.
    * $.jqplot.postInitHooks - called after initialization.
    * $.jqplot.preParseOptionsHooks - called before user options are parsed.
    * $.jqplot.postParseOptionsHooks - called after user options are parsed.
    * $.jqplot.preDrawHooks - called before plot draw.
    * $.jqplot.postDrawHooks - called after plot draw.
    * $.jqplot.preDrawSeriesHooks - called before each series is drawn.
    * $.jqplot.postDrawSeriesHooks - called after each series is drawn.
    * $.jqplot.preDrawLegendHooks - called before the legend is drawn.
    * $.jqplot.addLegendRowHooks - called at the end of legend draw, so plugins
    *     can add rows to the legend table.
    * $.jqplot.preSeriesInitHooks - called before series is initialized.
    * $.jqplot.postSeriesInitHooks - called after series is initialized.
    * $.jqplot.preParseSeriesOptionsHooks - called before series related options
    *     are parsed.
    * $.jqplot.postParseSeriesOptionsHooks - called after series related options
    *     are parsed.
    * $.jqplot.eventListenerHooks - called at the end of plot drawing, binds
    *     listeners to the event canvas which lays on top of the grid area.
    * $.jqplot.preDrawSeriesShadowHooks - called before series shadows are drawn.
    * $.jqplot.postDrawSeriesShadowHooks - called after series shadows are drawn.
    * 
    */

    $.jqplot.preInitHooks = [];
    $.jqplot.postInitHooks = [];
    $.jqplot.preParseOptionsHooks = [];
    $.jqplot.postParseOptionsHooks = [];
    $.jqplot.preDrawHooks = [];
    $.jqplot.postDrawHooks = [];
    $.jqplot.preDrawSeriesHooks = [];
    $.jqplot.postDrawSeriesHooks = [];
    $.jqplot.preDrawLegendHooks = [];
    $.jqplot.addLegendRowHooks = [];
    $.jqplot.preSeriesInitHooks = [];
    $.jqplot.postSeriesInitHooks = [];
    $.jqplot.preParseSeriesOptionsHooks = [];
    $.jqplot.postParseSeriesOptionsHooks = [];
    $.jqplot.eventListenerHooks = [];
    $.jqplot.preDrawSeriesShadowHooks = [];
    $.jqplot.postDrawSeriesShadowHooks = [];

    // A superclass holding some common properties and methods.
    $.jqplot.ElemContainer = function() {
        this._elem;
        this._plotWidth;
        this._plotHeight;
        this._plotDimensions = { height: null, width: null };
    };

    $.jqplot.ElemContainer.prototype.getWidth = function() {
        if (this._elem) {
            return this._elem.outerWidth(true);
        }
        else {
            return null;
        }
    };

    $.jqplot.ElemContainer.prototype.getHeight = function() {
        if (this._elem) {
            return this._elem.outerHeight(true);
        }
        else {
            return null;
        }
    };

    $.jqplot.ElemContainer.prototype.getPosition = function() {
        if (this._elem) {
            return this._elem.position();
        }
        else {
            return { top: null, left: null, bottom: null, right: null };
        }
    };


    $.jqplot.ElemContainer.prototype.getTop = function() {
        return this.getPosition().top;
    };

    $.jqplot.ElemContainer.prototype.getLeft = function() {
        return this.getPosition().left;
    };

    $.jqplot.ElemContainer.prototype.getBottom = function() {
        return this._elem.css('bottom');
    };

    $.jqplot.ElemContainer.prototype.getRight = function() {
        return this._elem.css('right');
    };


    /**
    * Class: Axis
    * An individual axis object.  Cannot be instantiated directly, but created
    * by the Plot oject.  Axis properties can be set or overriden by the 
    * options passed in from the user.
    * 
    */
    function Axis(name) {
        $.jqplot.ElemContainer.call(this);
        // Group: Properties
        //
        // Axes options are specified within an axes object at the top level of the 
        // plot options like so:
        // > {
        // >    axes: {
        // >        xaxis: {min: 5},
        // >        yaxis: {min: 2, max: 8, numberTicks:4},
        // >        x2axis: {pad: 1.5},
        // >        y2axis: {ticks:[22, 44, 66, 88]}
        // >        }
        // > }
        // There are 4 axes, 'xaxis', 'yaxis', 'x2axis', 'y2axis'.  Any or all of 
        // which may be specified.
        this.name = name;
        this._series = [];
        // prop: show
        // Wether to display the axis on the graph.
        this.show = false;
        // prop: tickRenderer
        // A class of a rendering engine for creating the ticks labels displayed on the plot, 
        // See <$.jqplot.AxisTickRenderer>.
        this.tickRenderer = $.jqplot.AxisTickRenderer;
        // prop: tickOptions
        // Options that will be passed to the tickRenderer, see <$.jqplot.AxisTickRenderer> options.
        this.tickOptions = {};
        // prop: labelRenderer
        // A class of a rendering engine for creating an axis label.
        this.labelRenderer = $.jqplot.AxisLabelRenderer;
        // prop: labelOptions
        // Options passed to the label renderer.
        this.labelOptions = {};
        // prop: label
        // Label for the axis
        this.label = null;
        // prop: showLabel
        // true to show the axis label.
        this.showLabel = true;
        // prop: min
        // minimum value of the axis (in data units, not pixels).
        this.min = null;
        // prop: max
        // maximum value of the axis (in data units, not pixels).
        this.max = null;
        // prop: autoscale
        // Autoscale the axis min and max values to provide sensible tick spacing.
        // If axis min or max are set, autoscale will be turned off.
        // The numberTicks, tickInterval and pad options do work with 
        // autoscale, although tickInterval has not been tested yet.
        // padMin and padMax do nothing when autoscale is on.
        this.autoscale = false;
        // prop: pad
        // Padding to extend the range above and below the data bounds.
        // The data range is multiplied by this factor to determine minimum and maximum axis bounds.
        // A value of 0 will be interpreted to mean no padding, and pad will be set to 1.0.
        this.pad = 1.2;
        // prop: padMax
        // Padding to extend the range above data bounds.
        // The top of the data range is multiplied by this factor to determine maximum axis bounds.
        // A value of 0 will be interpreted to mean no padding, and padMax will be set to 1.0.
        this.padMax = null;
        // prop: padMin
        // Padding to extend the range below data bounds.
        // The bottom of the data range is multiplied by this factor to determine minimum axis bounds.
        // A value of 0 will be interpreted to mean no padding, and padMin will be set to 1.0.
        this.padMin = null;
        // prop: ticks
        // 1D [val, val, ...] or 2D [[val, label], [val, label], ...] array of ticks for the axis.
        // If no label is specified, the value is formatted into an appropriate label.
        this.ticks = [];
        // prop: numberTicks
        // Desired number of ticks.  Default is to compute automatically.
        this.numberTicks;
        // prop: tickInterval
        // number of units between ticks.  Mutually exclusive with numberTicks.
        this.tickInterval;
        // prop: renderer
        // A class of a rendering engine that handles tick generation, 
        // scaling input data to pixel grid units and drawing the axis element.
        this.renderer = $.jqplot.LinearAxisRenderer;
        // prop: rendererOptions
        // renderer specific options.  See <$.jqplot.LinearAxisRenderer> for options.
        this.rendererOptions = {};
        // prop: showTicks
        // wether to show the ticks (both marks and labels) or not.
        this.showTicks = true;
        // prop: showTickMarks
        // wether to show the tick marks (line crossing grid) or not.
        this.showTickMarks = true;
        // prop: showMinorTicks
        // Wether or not to show minor ticks.  This is renderer dependent.
        // The default <$.jqplot.LinearAxisRenderer> does not have minor ticks.
        this.showMinorTicks = true;
        // prop: useSeriesColor
        // Use the color of the first series associated with this axis for the
        // tick marks and line bordering this axis.
        this.useSeriesColor = false;
        // prop: borderWidth
        // width of line stroked at the border of the axis.  Defaults
        // to the width of the grid boarder.
        this.borderWidth = null;
        // prop: borderColor
        // color of the border adjacent to the axis.  Defaults to grid border color.
        this.borderColor = null;
        // minimum and maximum values on the axis.
        this._dataBounds = { min: null, max: null };
        // pixel position from the top left of the min value and max value on the axis.
        this._offsets = { min: null, max: null };
        this._ticks = [];
        this._label = null;
        // prop: syncTicks
        // true to try and synchronize tick spacing across multiple axes so that ticks and
        // grid lines line up.  This has an impact on autoscaling algorithm, however.
        // In general, autoscaling an individual axis will work better if it does not
        // have to sync ticks.
        this.syncTicks = null;
        // prop: tickSpacing
        // Approximate pixel spacing between ticks on graph.  Used during autoscaling.
        // This number will be an upper bound, actual spacing will be less.
        this.tickSpacing = 75;
        // Properties to hold the original values for min, max, ticks, tickInterval and numberTicks
        // so they can be restored if altered by plugins.
        this._min = null;
        this._max = null;
        this._tickInterval = null;
        this._numberTicks = null;
        this.__ticks = null;
    }

    Axis.prototype = new $.jqplot.ElemContainer();
    Axis.prototype.constructor = Axis;

    Axis.prototype.init = function() {
        this.renderer = new this.renderer();
        // set the axis name
        this.tickOptions.axis = this.name;
        if (this.label == null || this.label == '') {
            this.showLabel = false;
        }
        else {
            this.labelOptions.label = this.label;
        }
        if (this.showLabel == false) {
            this.labelOptions.show = false;
        }
        // set the default padMax, padMin if not specified
        // special check, if no padding desired, padding
        // should be set to 1.0
        if (this.pad == 0) {
            this.pad = 1.0;
        }
        if (this.padMax == 0) {
            this.padMax = 1.0;
        }
        if (this.padMin == 0) {
            this.padMin = 1.0;
        }
        if (this.padMax == null) {
            this.padMax = (this.pad - 1) / 2 + 1;
        }
        if (this.padMin == null) {
            this.padMin = (this.pad - 1) / 2 + 1;
        }
        // now that padMin and padMax are correctly set, reset pad in case user has supplied 
        // padMin and/or padMax
        this.pad = this.padMax + this.padMin - 1;
        if (this.min != null || this.max != null) {
            this.autoscale = false;
        }
        // if not set, sync ticks for y axes but not x by default.
        if (this.syncTicks == null && this.name.indexOf('y') > -1) {
            this.syncTicks = true;
        }
        else if (this.syncTicks == null) {
            this.syncTicks = false;
        }
        this.renderer.init.call(this, this.rendererOptions);

    };

    Axis.prototype.draw = function(ctx) {
        return this.renderer.draw.call(this, ctx);

    };

    Axis.prototype.set = function() {
        this.renderer.set.call(this);
    };

    Axis.prototype.pack = function(pos, offsets) {
        if (this.show) {
            this.renderer.pack.call(this, pos, offsets);
        }
        // these properties should all be available now.
        if (this._min == null) {
            this._min = this.min;
            this._max = this.max;
            this._tickInterval = this.tickInterval;
            this._numberTicks = this.numberTicks;
            this.__ticks = this._ticks;
        }
    };

    // reset the axis back to original values if it has been scaled, zoomed, etc.
    Axis.prototype.reset = function() {
        this.renderer.reset.call(this);
    };

    Axis.prototype.resetScale = function() {
        this.min = null;
        this.max = null;
        this.numberTicks = null;
        this.tickInterval = null;
    };

    /**
    * Class: Legend
    * Legend object.  Cannot be instantiated directly, but created
    * by the Plot oject.  Legend properties can be set or overriden by the 
    * options passed in from the user.
    */
    function Legend(options) {
        $.jqplot.ElemContainer.call(this);
        // Group: Properties

        // prop: show
        // Wether to display the legend on the graph.
        this.show = false;
        // prop: location
        // Placement of the legend.  one of the compass directions: nw, n, ne, e, se, s, sw, w
        this.location = 'ne';
        // prop: xoffset
        // offset from the inside edge of the plot in the x direction in pixels.
        this.xoffset = 12;
        // prop: yoffset
        // offset from the inside edge of the plot in the y direction in pixels.
        this.yoffset = 12;
        // prop: border
        // css spec for the border around the legend box.
        this.border;
        // prop: background
        // css spec for the background of the legend box.
        this.background;
        // prop: textColor
        // css color spec for the legend text.
        this.textColor;
        // prop: fontFamily
        // css font-family spec for the legend text.
        this.fontFamily;
        // prop: fontSize
        // css font-size spec for the legend text.
        this.fontSize;
        // prop: rowSpacing
        // css padding-top spec for the rows in the legend.
        this.rowSpacing = '0.5em';
        // renderer
        // A class that will create a DOM object for the legend,
        // see <$.jqplot.TableLegendRenderer>.
        this.renderer = $.jqplot.TableLegendRenderer;
        // prop: rendererOptions
        // renderer specific options passed to the renderer.
        this.rendererOptions = {};
        // prop: predraw
        // Wether to draw the legend before the series or not.
        this.preDraw = false;
        this.escapeHtml = false;
        this._series = [];

        $.extend(true, this, options);
    }

    Legend.prototype = new $.jqplot.ElemContainer();
    Legend.prototype.constructor = Legend;

    Legend.prototype.init = function() {
        this.renderer = new this.renderer();
        this.renderer.init.call(this, this.rendererOptions);
    };

    Legend.prototype.draw = function(offsets) {
        for (var i = 0; i < $.jqplot.preDrawLegendHooks.length; i++) {
            $.jqplot.preDrawLegendHooks[i].call(this, offsets);
        }
        return this.renderer.draw.call(this, offsets);
    };

    Legend.prototype.pack = function(offsets) {
        this.renderer.pack.call(this, offsets);
    };

    /**
    * Class: Title
    * Plot Title object.  Cannot be instantiated directly, but created
    * by the Plot oject.  Title properties can be set or overriden by the 
    * options passed in from the user.
    * 
    * Parameters:
    * text - text of the title.
    */
    function Title(text) {
        $.jqplot.ElemContainer.call(this);
        // Group: Properties

        // prop: text
        // text of the title;
        this.text = text;
        // prop: show
        // wether or not to show the title
        this.show = true;
        // prop: fontFamily
        // css font-family spec for the text.
        this.fontFamily;
        // prop: fontSize
        // css font-size spec for the text.
        this.fontSize;
        // prop: textAlign
        // css text-align spec for the text.
        this.textAlign;
        // prop: textColor
        // css color spec for the text.
        this.textColor;
        // prop: renderer
        // A class for creating a DOM element for the title,
        // see <$.jqplot.DivTitleRenderer>.
        this.renderer = $.jqplot.DivTitleRenderer;
        // prop: rendererOptions
        // renderer specific options passed to the renderer.
        this.rendererOptions = {};
    }

    Title.prototype = new $.jqplot.ElemContainer();
    Title.prototype.constructor = Title;

    Title.prototype.init = function() {
        this.renderer = new this.renderer();
        this.renderer.init.call(this, this.rendererOptions);
    };

    Title.prototype.draw = function(width) {
        return this.renderer.draw.call(this, width);
    };

    Title.prototype.pack = function() {
        this.renderer.pack.call(this);
    };


    /**
    * Class: Series
    * An individual data series object.  Cannot be instantiated directly, but created
    * by the Plot oject.  Series properties can be set or overriden by the 
    * options passed in from the user.
    */
    function Series() {
        $.jqplot.ElemContainer.call(this);
        // Group: Properties
        // Properties will be assigned from a series array at the top level of the
        // options.  If you had two series and wanted to change the color and line
        // width of the first and set the second to use the secondary y axis with
        // no shadow and supply custom labels for each:
        // > {
        // >    series:[
        // >        {color: '#ff4466', lineWidth: 5, label:'good line'},
        // >        {yaxis: 'y2axis', shadow: false, label:'bad line'}
        // >    ]
        // > }

        // prop: show
        // wether or not to draw the series.
        this.show = true;
        // prop: xaxis
        // which x axis to use with this series, either 'xaxis' or 'x2axis'.
        this.xaxis = 'xaxis';
        this._xaxis;
        // prop: yaxis
        // which y axis to use with this series, either 'yaxis' or 'y2axis'.
        this.yaxis = 'yaxis';
        this._yaxis;
        this.gridBorderWidth = 2.0;
        // prop: renderer
        // A class of a renderer which will draw the series, 
        // see <$.jqplot.LineRenderer>.
        this.renderer = $.jqplot.LineRenderer;
        // prop: rendererOptions
        // Options to pass on to the renderer.
        this.rendererOptions = {};
        this.data = [];
        this.gridData = [];
        // prop: label
        // Line label to use in the legend.
        this.label = '';
        // prop: showLabel
        // true to show label for this series in the legend.
        this.showLabel = true;
        // prop: color
        // css color spec for the series
        this.color;
        // prop: lineWidth
        // width of the line in pixels.  May have different meanings depending on renderer.
        this.lineWidth = 2.5;
        // prop: shadow
        // wether or not to draw a shadow on the line
        this.shadow = true;
        // prop: shadowAngle
        // Shadow angle in degrees
        this.shadowAngle = 45;
        // prop: shadowOffset
        // Shadow offset from line in pixels
        this.shadowOffset = 1.25;
        // prop: shadowDepth
        // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
        this.shadowDepth = 3;
        // prop: shadowAlpha
        // Alpha channel transparency of shadow.  0 = transparent.
        this.shadowAlpha = '0.1';
        // prop: breakOnNull
        // Not implemented. wether line segments should be be broken at null value.
        // False will join point on either side of line.
        this.breakOnNull = false;
        // prop: markerRenderer
        // A class of a renderer which will draw marker (e.g. circle, square, ...) at the data points,
        // see <$.jqplot.MarkerRenderer>.
        this.markerRenderer = $.jqplot.MarkerRenderer;
        // prop: markerOptions
        // renderer specific options to pass to the markerRenderer,
        // see <$.jqplot.MarkerRenderer>.
        this.markerOptions = {};
        // prop: showLine
        // wether to actually draw the line or not.  Series will still be renderered, even if no line is drawn.
        this.showLine = true;
        // prop: showMarker
        // wether or not to show the markers at the data points.
        this.showMarker = true;
        // prop: index
        // 0 based index of this series in the plot series array.
        this.index;
        // prop: fill
        // true or false, wether to fill under lines or in bars.
        // May not be implemented in all renderers.
        this.fill = false;
        // prop: fillColor
        // CSS color spec to use for fill under line.  Defaults to line color.
        this.fillColor;
        // prop: fillAlpha
        // Alpha transparency to apply to the fill under the line.
        // Use this to adjust alpha separate from fill color.
        this.fillAlpha;
        // prop: fillAndStroke
        // If true will stroke the line (with color this.color) as well as fill under it.
        // Applies only when fill is true.
        this.fillAndStroke = false;
        // prop: disableStack
        // true to not stack this series with other series in the plot.
        // To render properly, non-stacked series must come after any stacked series
        // in the plot's data series array.  So, the plot's data series array would look like:
        // > [stackedSeries1, stackedSeries2, ..., nonStackedSeries1, nonStackedSeries2, ...]
        // disableStack will put a gap in the stacking order of series, and subsequent
        // stacked series will not fill down through the non-stacked series and will
        // most likely not stack properly on top of the non-stacked series.
        this.disableStack = false;
        // _stack is set by the Plot if the plot is a stacked chart.
        // will stack lines or bars on top of one another to build a "mountain" style chart.
        // May not be implemented in all renderers.
        this._stack = false;
        // prop: neighborThreshold
        // how close or far (in pixels) the cursor must be from a point marker to detect the point.
        this.neighborThreshold = 4;
        // prop: fillToZero
        // true will force bar and filled series to fill toward zero on the fill Axis.
        this.fillToZero = false;
        // prop: fillAxis
        // Either 'x' or 'y'.  Which axis to fill the line toward if fillToZero is true.
        // 'y' means fill up/down to 0 on the y axis for this series.
        this.fillAxis = 'y';
        this._stackData = [];
        // _plotData accounts for stacking.  If plots not stacked, _plotData and data are same.  If
        // stacked, _plotData is accumulation of stacking data.
        this._plotData = [];
        // _plotValues hold the individual x and y values that will be plotted for this series.
        this._plotValues = { x: [], y: [] };
        // statistics about the intervals between data points.  Used for auto scaling.
        this._intervals = { x: {}, y: {} };
        // data from the previous series, for stacked charts.
        this._prevPlotData = [];
        this._prevGridData = [];
        this._stackAxis = 'y';
        this._primaryAxis = '_xaxis';
        this.plugins = {};
    }

    Series.prototype = new $.jqplot.ElemContainer();
    Series.prototype.constructor = Series;

    Series.prototype.init = function(index, gridbw) {
        // weed out any null values in the data.
        this.index = index;
        this.gridBorderWidth = gridbw;
        var d = this.data;
        for (var i = 0; i < d.length; i++) {
            if (!this.breakOnNull) {
                if (d[i] == null || d[i][0] == null || d[i][1] == null) {
                    d.splice(i, 1);
                    continue;
                }
            }
            else {
                if (d[i] == null || d[i][0] == null || d[i][1] == null) {
                    // TODO: figure out what to do with null values
                    var undefined;
                }
            }
        }
        if (!this.fillColor) {
            this.fillColor = this.color;
        }
        if (this.fillAlpha) {
            var comp = $.jqplot.normalize2rgb(this.fillColor);
            var comp = $.jqplot.getColorComponents(comp);
            this.fillColor = 'rgba(' + comp[0] + ',' + comp[1] + ',' + comp[2] + ',' + this.fillAlpha + ')';
        }
        this.renderer = new this.renderer();
        this.renderer.init.call(this, this.rendererOptions);
        this.markerRenderer = new this.markerRenderer();
        if (!this.markerOptions.color) {
            this.markerOptions.color = this.color;
        }
        if (this.markerOptions.show == null) {
            this.markerOptions.show = this.showMarker;
        }
        // the markerRenderer is called within it's own scaope, don't want to overwrite series options!!
        this.markerRenderer.init(this.markerOptions);
    };

    // data - optional data point array to draw using this series renderer
    // gridData - optional grid data point array to draw using this series renderer
    // stackData - array of cumulative data for stacked plots.
    Series.prototype.draw = function(sctx, opts) {
        var options = (opts == undefined) ? {} : opts;
        // hooks get called even if series not shown
        // we don't clear canvas here, it would wipe out all other series as well.
        for (var j = 0; j < $.jqplot.preDrawSeriesHooks.length; j++) {
            $.jqplot.preDrawSeriesHooks[j].call(this, sctx, options);
        }
        if (this.show) {
            this.renderer.setGridData.call(this);
            if (!options.preventJqPlotSeriesDrawTrigger) {
                $(sctx.canvas).trigger('jqplotSeriesDraw', [this.data, this.gridData]);
            }
            var data = [];
            if (options.data) {
                data = options.data;
            }
            else if (!this._stack) {
                data = this.data;
            }
            else {
                data = this._plotData;
            }
            var gridData = options.gridData || this.renderer.makeGridData.call(this, data);

            this.renderer.draw.call(this, sctx, gridData, options);
        }

        for (var j = 0; j < $.jqplot.postDrawSeriesHooks.length; j++) {
            $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options);
        }
    };

    Series.prototype.drawShadow = function(sctx, opts) {
        var options = (opts == undefined) ? {} : opts;
        // hooks get called even if series not shown
        // we don't clear canvas here, it would wipe out all other series as well.
        for (var j = 0; j < $.jqplot.preDrawSeriesShadowHooks.length; j++) {
            $.jqplot.preDrawSeriesShadowHooks[j].call(this, sctx, options);
        }
        if (this.shadow) {
            this.renderer.setGridData.call(this);

            var data = [];
            if (options.data) {
                data = options.data;
            }
            else if (!this._stack) {
                data = this.data;
            }
            else {
                data = this._plotData;
            }
            var gridData = options.gridData || this.renderer.makeGridData.call(this, data);

            this.renderer.drawShadow.call(this, sctx, gridData, options);
        }

        for (var j = 0; j < $.jqplot.postDrawSeriesShadowHooks.length; j++) {
            $.jqplot.postDrawSeriesShadowHooks[j].call(this, sctx, options);
        }

    };



    /**
    * Class: Grid
    * 
    * Object representing the grid on which the plot is drawn.  The grid in this
    * context is the area bounded by the axes, the area which will contain the series.
    * Note, the series are drawn on their own canvas.
    * The Grid object cannot be instantiated directly, but is created by the Plot oject.  
    * Grid properties can be set or overriden by the options passed in from the user.
    */
    function Grid() {
        $.jqplot.ElemContainer.call(this);
        // Group: Properties

        // prop: drawGridlines
        // wether to draw the gridlines on the plot.
        this.drawGridlines = true;
        // prop: gridLineColor
        // color of the grid lines.
        this.gridLineColor = '#cccccc';
        // prop: gridLineWidth
        // width of the grid lines.
        this.gridLineWidth = 1.0;
        // prop: background
        // css spec for the background color.
        this.background = '#fffdf6';
        // prop: borderColor
        // css spec for the color of the grid border.
        this.borderColor = '#999999';
        // prop: borderWidth
        // width of the border in pixels.
        this.borderWidth = 2.0;
        // prop: shadow
        // wether to show a shadow behind the grid.
        this.shadow = true;
        // prop: shadowAngle
        // shadow angle in degrees
        this.shadowAngle = 45;
        // prop: shadowOffset
        // Offset of each shadow stroke from the border in pixels
        this.shadowOffset = 1.5;
        // prop: shadowWidth
        // width of the stoke for the shadow
        this.shadowWidth = 3;
        // prop: shadowDepth
        // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
        this.shadowDepth = 3;
        // prop: shadowAlpha
        // Alpha channel transparency of shadow.  0 = transparent.
        this.shadowAlpha = '0.07';
        this._left;
        this._top;
        this._right;
        this._bottom;
        this._width;
        this._height;
        this._axes = [];
        // prop: renderer
        // Instance of a renderer which will actually render the grid,
        // see <$.jqplot.CanvasGridRenderer>.
        this.renderer = $.jqplot.CanvasGridRenderer;
        // prop: rendererOptions
        // Options to pass on to the renderer,
        // see <$.jqplot.CanvasGridRenderer>.
        this.rendererOptions = {};
        this._offsets = { top: null, bottom: null, left: null, right: null };
    }

    Grid.prototype = new $.jqplot.ElemContainer();
    Grid.prototype.constructor = Grid;

    Grid.prototype.init = function() {
        this.renderer = new this.renderer();
        this.renderer.init.call(this, this.rendererOptions);
    };

    Grid.prototype.createElement = function(offsets) {
        this._offsets = offsets;
        return this.renderer.createElement.call(this);
    };

    Grid.prototype.draw = function() {
        this.renderer.draw.call(this);
    };

    $.jqplot.GenericCanvas = function() {
        $.jqplot.ElemContainer.call(this);
        this._ctx;
    };

    $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer();
    $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas;

    $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions) {
        this._offsets = offsets;
        var klass = 'jqplot';
        if (clss != undefined) {
            klass = clss;
        }
        var elem = document.createElement('canvas');
        // if new plotDimensions supplied, use them.
        if (plotDimensions != undefined) {
            this._plotDimensions = plotDimensions;
        }
        elem.width = this._plotDimensions.width - this._offsets.left - this._offsets.right;
        elem.height = this._plotDimensions.height - this._offsets.top - this._offsets.bottom;
        this._elem = $(elem);
        this._elem.addClass(klass);
        this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top });
        // borrowed from flot by Ole Laursen
        if ($.browser.msie) {
            window.G_vmlCanvasManager.init_(document);
        }
        if ($.browser.msie) {
            elem = window.G_vmlCanvasManager.initElement(elem);
        }
        return this._elem;
    };

    $.jqplot.GenericCanvas.prototype.setContext = function() {
        this._ctx = this._elem.get(0).getContext("2d");
        return this._ctx;
    };

    /**
    * Class: jqPlot
    * Plot object returned by call to $.jqplot.  Handles parsing user options,
    * creating sub objects (Axes, legend, title, series) and rendering the plot.
    */
    function jqPlot() {
        // Group: Properties
        // These properties are specified at the top of the options object
        // like so:
        // > {
        // >     axesDefaults:{min:0},
        // >     series:[{color:'#6633dd'}],
        // >     title: 'A Plot'
        // > }
        //
        // prop: data
        // user's data.  Data should *NOT* be specified in the options object,
        // but be passed in as the second argument to the $.jqplot() function.
        // The data property is described here soley for reference. 
        // The data should be in the form of an array of 2D or 1D arrays like
        // > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ].
        this.data = [];
        // The id of the dom element to render the plot into
        this.targetId = null;
        // the jquery object for the dom target.
        this.target = null;
        this.defaults = {
            // prop: axesDefaults
            // default options that will be applied to all axes.
            // see <Axis> for axes options.
            axesDefaults: {},
            axes: { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {}, y3axis: {}, y4axis: {}, y5axis: {}, y6axis: {}, y7axis: {}, y8axis: {}, y9axis: {} },
            // prop: seriesDefaults
            // default options that will be applied to all series.
            // see <Series> for series options.
            seriesDefaults: {},
            gridPadding: { top: 10, right: 10, bottom: 23, left: 10 },
            series: []
        };
        // prop: series
        // Array of series object options.
        // see <Series> for series specific options.
        this.series = [];
        // prop: axes
        // up to 4 axes are supported, each with it's own options, 
        // See <Axis> for axis specific options.
        this.axes = { xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis') };
        // prop: grid
        // See <Grid> for grid specific options.
        this.grid = new Grid();
        // prop: legend
        // see <$.jqplot.TableLegendRenderer>
        this.legend = new Legend();
        this.baseCanvas = new $.jqplot.GenericCanvas();
        this.seriesCanvas = new $.jqplot.GenericCanvas();
        this.eventCanvas = new $.jqplot.GenericCanvas();
        this._width = null;
        this._height = null;
        this._plotDimensions = { height: null, width: null };
        this._gridPadding = { top: 10, right: 10, bottom: 10, left: 10 };
        // a shortcut for axis syncTicks options.  Not implemented yet.
        this.syncXTicks = true;
        // a shortcut for axis syncTicks options.  Not implemented yet.
        this.syncYTicks = true;
        // prop: seriesColors
        // Ann array of CSS color specifications that will be applied, in order,
        // to the series in the plot.  Colors will wrap around so, if their
        // are more series than colors, colors will be reused starting at the
        // beginning.  For pie charts, this specifies the colors of the slices.
        this.seriesColors = ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc"];
        // this.negativeSeriesColors = [ "#9653C4", "#1CE540", "#7BC28F", "#525A94", "#529386", "#00914A", "#967C33", "#E650A8", "#37D46A", "#1BF800", "#AD25CC"];
        this.negativeSeriesColors = ["#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399"];
        // prop: sortData
        // false to not sort the data passed in by the user.
        // Many bar, stakced and other graphs as well as many plugins depend on
        // having sorted data.
        this.sortData = true;
        var seriesColorsIndex = 0;
        // prop textColor
        // css spec for the css color attribute.  Default for the entire plot.
        this.textColor;
        // prop; fontFamily
        // css spec for the font-family attribute.  Default for the entire plot.
        this.fontFamily;
        // prop: fontSize
        // css spec for the font-size attribute.  Default for the entire plot.
        this.fontSize;
        // prop: title
        // Title object.  See <Title> for specific options.  As a shortcut, you
        // can specify the title option as just a string like: title: 'My Plot'
        // and this will create a new title object with the specified text.
        this.title = new Title();
        // container to hold all of the merged options.  Convienence for plugins.
        this.options = {};
        // prop: stackSeries
        // true or false, creates a stack or "mountain" plot.
        // Not all series renderers may implement this option.
        this.stackSeries = false;
        // array to hold the cumulative stacked series data.
        // used to ajust the individual series data, which won't have access to other
        // series data.
        this._stackData = [];
        // array that holds the data to be plotted. This will be the series data
        // merged with the the appropriate data from _stackData according to the stackAxis.
        this._plotData = [];
        // Namespece to hold plugins.  Generally non-renderer plugins add themselves to here.
        this.plugins = {};
        // Count how many times the draw method has been called while the plot is visible.
        // Mostly used to test if plot has never been dran (=0), has been successfully drawn
        // into a visible container once (=1) or draw more than once into a visible container.
        // Can use this in tests to see if plot has been visibly drawn at least one time.
        // After plot has been visibly drawn once, it generally doesn't need redrawn if its
        // container is hidden and shown.
        this._drawCount = 0;
        // prop: drawIfHidden
        // True to execute the draw method even if the plot target is hidden.
        // Generally, this should be false.  Most plot elements will not be sized/
        // positioned correclty if renderered into a hidden container.  To render into
        // a hidden container, call the replot method when the container is shown.
        this.drawIfHidden = false;

        this.colorGenerator = $.jqplot.ColorGenerator;

        // Group: methods
        //
        // method: init
        // sets the plot target, checks data and applies user
        // options to plot.
        this.init = function(target, data, options) {
            for (var i = 0; i < $.jqplot.preInitHooks.length; i++) {
                $.jqplot.preInitHooks[i].call(this, target, data, options);
            }
            this.targetId = '#' + target;
            this.target = $('#' + target);
            if (!this.target.get(0)) {
                throw "No plot target specified";
            }

            // make sure the target is positioned by some means and set css
            if (this.target.css('position') == 'static') {
                this.target.css('position', 'relative');
            }
            if (!this.target.hasClass('jqplot-target')) {
                this.target.addClass('jqplot-target');
            }

            // if no height or width specified, use a default.
            if (!this.target.height()) {
                var h;
                if (options && options.height) {
                    h = parseInt(options.height, 10);
                }
                else if (this.target.attr('data-height')) {
                    h = parseInt(this.target.attr('data-height'), 10);
                }
                else {
                    h = parseInt($.jqplot.config.defaultHeight, 10);
                }
                this._height = h;
                this.target.css('height', h + 'px');
            }
            else {
                this._height = this.target.height();
            }
            if (!this.target.width()) {
                var w;
                if (options && options.width) {
                    w = parseInt(options.width, 10);
                }
                else if (this.target.attr('data-width')) {
                    w = parseInt(this.target.attr('data-width'), 10);
                }
                else {
                    w = parseInt($.jqplot.config.defaultWidth, 10);
                }
                this._width = w;
                this.target.css('width', w + 'px');
            }
            else {
                this._width = this.target.width();
            }

            this._plotDimensions.height = this._height;
            this._plotDimensions.width = this._width;
            this.grid._plotDimensions = this._plotDimensions;
            this.title._plotDimensions = this._plotDimensions;
            this.baseCanvas._plotDimensions = this._plotDimensions;
            this.seriesCanvas._plotDimensions = this._plotDimensions;
            this.eventCanvas._plotDimensions = this._plotDimensions;
            this.legend._plotDimensions = this._plotDimensions;
            if (this._height <= 0 || this._width <= 0 || !this._height || !this._width) {
                throw "Canvas dimension not set";
            }

            this.data = data;

            this.parseOptions(options);

            if (this.textColor) {
                this.target.css('color', this.textColor);
            }
            if (this.fontFamily) {
                this.target.css('font-family', this.fontFamily);
            }
            if (this.fontSize) {
                this.target.css('font-size', this.fontSize);
            }

            this.title.init();
            this.legend.init();
            for (var i = 0; i < this.series.length; i++) {
                for (var j = 0; j < $.jqplot.preSeriesInitHooks.length; j++) {
                    $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i]);
                }
                this.populatePlotData(this.series[i], i);
                this.series[i]._plotDimensions = this._plotDimensions;
                this.series[i].init(i, this.grid.borderWidth);
                for (var j = 0; j < $.jqplot.postSeriesInitHooks.length; j++) {
                    $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i]);
                }
            }

            for (var name in this.axes) {
                this.axes[name]._plotDimensions = this._plotDimensions;
                this.axes[name].init();
            }

            if (this.sortData) {
                sortData(this.series);
            }
            this.grid.init();
            this.grid._axes = this.axes;

            this.legend._series = this.series;

            for (var i = 0; i < $.jqplot.postInitHooks.length; i++) {
                $.jqplot.postInitHooks[i].call(this, target, data, options);
            }
        };

        // method: resetAxesScale
        // Reset the specified axes min, max, numberTicks and tickInterval properties to null
        // or reset these properties on all axes if no list of axes is provided.
        //
        // Parameters:
        // axes - Boolean to reset or not reset all axes or an array or object of axis names to reset.
        this.resetAxesScale = function(axes) {
            var ax = (axes != undefined) ? axes : this.axes;
            if (ax === true) {
                ax = this.axes;
            }
            if (ax.constructor === Array) {
                for (var i = 0; i < ax.length; i++) {
                    this.axes[ax[i]].resetScale();
                }
            }
            else if (ax.constructor === Object) {
                for (var name in ax) {
                    this.axes[name].resetScale();
                }
            }
        };
        // method: reInitialize
        // reinitialize plot for replotting.
        // not called directly.
        this.reInitialize = function() {
            // Plot should be visible and have a height and width.
            // If plot doesn't have height and width for some
            // reason, set it by other means.  Plot must not have
            // a display:none attribute, however.
            if (!this.target.height()) {
                var h;
                if (options && options.height) {
                    h = parseInt(options.height, 10);
                }
                else if (this.target.attr('data-height')) {
                    h = parseInt(this.target.attr('data-height'), 10);
                }
                else {
                    h = parseInt($.jqplot.config.defaultHeight, 10);
                }
                this._height = h;
                this.target.css('height', h + 'px');
            }
            else {
                this._height = this.target.height();
            }
            if (!this.target.width()) {
                var w;
                if (options && options.width) {
                    w = parseInt(options.width, 10);
                }
                else if (this.target.attr('data-width')) {
                    w = parseInt(this.target.attr('data-width'), 10);
                }
                else {
                    w = parseInt($.jqplot.config.defaultWidth, 10);
                }
                this._width = w;
                this.target.css('width', w + 'px');
            }
            else {
                this._width = this.target.width();
            }

            if (this._height <= 0 || this._width <= 0 || !this._height || !this._width) {
                throw "Target dimension not set";
            }

            this._plotDimensions.height = this._height;
            this._plotDimensions.width = this._width;
            this.grid._plotDimensions = this._plotDimensions;
            this.title._plotDimensions = this._plotDimensions;
            this.baseCanvas._plotDimensions = this._plotDimensions;
            this.seriesCanvas._plotDimensions = this._plotDimensions;
            this.eventCanvas._plotDimensions = this._plotDimensions;
            this.legend._plotDimensions = this._plotDimensions;

            for (var n in this.axes) {
                var axis = this.axes[n];
                axis._plotWidth = this._width;
                axis._plotHeight = this._height;
            }

            this.title._plotWidth = this._width;

            if (this.textColor) {
                this.target.css('color', this.textColor);
            }
            if (this.fontFamily) {
                this.target.css('font-family', this.fontFamily);
            }
            if (this.fontSize) {
                this.target.css('font-size', this.fontSize);
            }

            for (var i = 0; i < this.series.length; i++) {
                this.populatePlotData(this.series[i], i);
                this.series[i]._plotDimensions = this._plotDimensions;
                //this.series[i].init(i, this.grid.borderWidth);
            }

            for (var name in this.axes) {
                this.axes[name]._plotDimensions = this._plotDimensions;
                this.axes[name]._ticks = [];
                this.axes[name].renderer.init.call(this.axes[name], {});
            }

            if (this.sortData) {
                sortData(this.series);
            }

            this.grid._axes = this.axes;

            this.legend._series = this.series;
        };

        // sort the series data in increasing order.
        function sortData(series) {
            var d, ret;
            for (var i = 0; i < series.length; i++) {
                d = series[i].data;
                var check = true;
                if (series[i]._stackAxis == 'x') {
                    for (var j = 0; j < d.length; j++) {
                        if (typeof (d[j][1]) != "number") {
                            check = false;
                            break;
                        }
                    }
                    if (check) {
                        d.sort(function(a, b) { return a[1] - b[1]; });
                    }
                }
                else {
                    for (var j = 0; j < d.length; j++) {
                        if (typeof (d[j][0]) != "number") {
                            check = false;
                            break;
                        }
                    }
                    if (check) {
                        d.sort(function(a, b) { return a[0] - b[0]; });
                    }
                }
            }
        }

        // populate the _stackData and _plotData arrays for the plot and the series.
        this.populatePlotData = function(series, index) {
            // if a stacked chart, compute the stacked data
            this._plotData = [];
            this._stackData = [];
            series._stackData = [];
            series._plotData = [];
            var plotValues = { x: [], y: [] };
            if (this.stackSeries && !series.disableStack) {
                series._stack = true;
                var sidx = series._stackAxis == 'x' ? 0 : 1;
                var idx = sidx ? 0 : 1;
                // push the current data into stackData
                //this._stackData.push(this.series[i].data);
                var temp = $.extend(true, [], series.data);
                // create the data that will be plotted for this series
                var plotdata = $.extend(true, [], series.data);
                // for first series, nothing to add to stackData.
                for (var j = 0; j < index; j++) {
                    var cd = this.series[j].data;
                    for (var k = 0; k < cd.length; k++) {
                        temp[k][0] += cd[k][0];
                        temp[k][1] += cd[k][1];
                        // only need to sum up the stack axis column of data
                        plotdata[k][sidx] += cd[k][sidx];
                    }
                }
                for (var i = 0; i < plotdata.length; i++) {
                    plotValues.x.push(plotdata[i][0]);
                    plotValues.y.push(plotdata[i][1]);
                }
                this._plotData.push(plotdata);
                this._stackData.push(temp);
                series._stackData = temp;
                series._plotData = plotdata;
                series._plotValues = plotValues;
            }
            else {
                for (var i = 0; i < series.data.length; i++) {
                    plotValues.x.push(series.data[i][0]);
                    plotValues.y.push(series.data[i][1]);
                }
                this._stackData.push(series.data);
                this.series[index]._stackData = series.data;
                this._plotData.push(series.data);
                series._plotData = series.data;
                series._plotValues = plotValues;
            }
            if (index > 0) {
                series._prevPlotData = this.series[index - 1]._plotData;
            }
        };

        // function to safely return colors from the color array and wrap around at the end.
        this.getNextSeriesColor = (function(t) {
            var idx = 0;
            var sc = t.seriesColors;

            return function() {
                if (idx < sc.length) {
                    return sc[idx++];
                }
                else {
                    idx = 0;
                    return sc[idx++];
                }
            };
        })(this);

        this.parseOptions = function(options) {
            for (var i = 0; i < $.jqplot.preParseOptionsHooks.length; i++) {
                $.jqplot.preParseOptionsHooks[i].call(this, options);
            }
            this.options = $.extend(true, {}, this.defaults, options);
            this.stackSeries = this.options.stackSeries;
            if (this.options.seriesColors) {
                this.seriesColors = this.options.seriesColors;
            }
            var cg = new this.colorGenerator(this.seriesColors);
            // this._gridPadding = this.options.gridPadding;
            $.extend(true, this._gridPadding, this.options.gridPadding);
            this.sortData = (this.options.sortData != null) ? this.options.sortData : this.sortData;
            for (var n in this.axes) {
                var axis = this.axes[n];
                $.extend(true, axis, this.options.axesDefaults, this.options.axes[n]);
                axis._plotWidth = this._width;
                axis._plotHeight = this._height;
            }
            if (this.data.length == 0) {
                this.data = [];
                for (var i = 0; i < this.options.series.length; i++) {
                    this.data.push(this.options.series.data);
                }
            }

            var normalizeData = function(data) {
                // return data as an array of point arrays,
                // in form [[x1,y1...], [x2,y2...], ...]
                var temp = [];
                var i;
                if (!(data[0] instanceof Array)) {
                    // we have a series of scalars.  One line with just y values.
                    // turn the scalar list of data into a data array of form:
                    // [[1, data[0]], [2, data[1]], ...]
                    for (var i = 0; i < data.length; i++) {
                        temp.push([i + 1, data[i]]);
                    }
                }

                else {
                    // we have a properly formatted data series, copy it.
                    $.extend(true, temp, data);
                }
                return temp;
            };

            for (var i = 0; i < this.data.length; i++) {
                var temp = new Series();
                for (var j = 0; j < $.jqplot.preParseSeriesOptionsHooks.length; j++) {
                    $.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]);
                }
                $.extend(true, temp, { seriesColors: this.seriesColors, negativeSeriesColors: this.negativeSeriesColors }, this.options.seriesDefaults, this.options.series[i]);
                temp.data = normalizeData(this.data[i]);
                switch (temp.xaxis) {
                    case 'xaxis':
                        temp._xaxis = this.axes.xaxis;
                        break;
                    case 'x2axis':
                        temp._xaxis = this.axes.x2axis;
                        break;
                    default:
                        break;
                }
                temp._yaxis = this.axes[temp.yaxis];
                temp._xaxis._series.push(temp);
                temp._yaxis._series.push(temp);
                if (temp.show) {
                    temp._xaxis.show = true;
                    temp._yaxis.show = true;
                }

                // parse the renderer options and apply default colors if not provided
                if (!temp.color && temp.show != false) {
                    temp.color = cg.next();
                }
                if (!temp.label) {
                    temp.label = 'Series ' + (i + 1).toString();
                }
                // temp.rendererOptions.show = temp.show;
                // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions);
                this.series.push(temp);
                for (var j = 0; j < $.jqplot.postParseSeriesOptionsHooks.length; j++) {
                    $.jqplot.postParseSeriesOptionsHooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]);
                }
            }

            // copy the grid and title options into this object.
            $.extend(true, this.grid, this.options.grid);
            // if axis border properties aren't set, set default.
            for (var n in this.axes) {
                var axis = this.axes[n];
                if (axis.borderWidth == null) {
                    axis.borderWidth = this.grid.borderWidth;
                }
                if (axis.borderColor == null) {
                    if (n != 'xaxis' && n != 'x2axis' && axis.useSeriesColor === true && axis.show) {
                        axis.borderColor = axis._series[0].color;
                    }
                    else {
                        axis.borderColor = this.grid.borderColor;
                    }
                }
            }

            if (typeof this.options.title == 'string') {
                this.title.text = this.options.title;
            }
            else if (typeof this.options.title == 'object') {
                $.extend(true, this.title, this.options.title);
            }
            this.title._plotWidth = this._width;
            $.extend(true, this.legend, this.options.legend);

            for (var i = 0; i < $.jqplot.postParseOptionsHooks.length; i++) {
                $.jqplot.postParseOptionsHooks[i].call(this, options);
            }
        };

        // method: replot
        // Does a reinitialization of the plot followed by
        // a redraw.  Method could be used to interactively
        // change plot characteristics and then replot.
        //
        // Parameters:
        // options - Options used for replotting.
        //
        // Properties:
        // clear - false to not clear (empty) the plot container before replotting (default: true).
        // resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves.
        //             optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false).
        this.replot = function(options) {
            var opts = (options != undefined) ? options : {};
            var clear = (opts.clear != undefined) ? opts.clear : true;
            var resetAxes = (opts.resetAxes != undefined) ? opts.resetAxes : false;
            this.target.trigger('jqplotPreReplot');
            if (clear) {
                this.target.empty();
            }
            if (resetAxes) {
                this.resetAxesScale(resetAxes);
            }
            this.reInitialize();
            this.draw();
            this.target.trigger('jqplotPostReplot');
        };

        // method: redraw
        // Empties the plot target div and redraws the plot.
        // This enables plot data and properties to be changed
        // and then to comletely clear the plot and redraw.
        // redraw *will not* reinitialize any plot elements.
        // That is, axes will not be autoscaled and defaults
        // will not be reapplied to any plot elements.  redraw
        // is used primarily with zooming. 
        //
        // Parameters:
        // clear - false to not clear (empty) the plot container before redrawing (default: true).
        this.redraw = function(clear) {
            clear = (clear != null) ? clear : true;
            this.target.trigger('jqplotPreRedraw');
            if (clear) {
                this.target.empty();
            }
            for (var ax in this.axes) {
                this.axes[ax]._ticks = [];
            }
            for (var i = 0; i < this.series.length; i++) {
                this.populatePlotData(this.series[i], i);
            }
            this.draw();
            this.target.trigger('jqplotPostRedraw');
        };

        // method: draw
        // Draws all elements of the plot into the container.
        // Does not clear the container before drawing.
        this.draw = function() {
            if (this.drawIfHidden || this.target.is(':visible')) {
                this.target.trigger('jqplotPreDraw');
                for (var i = 0; i < $.jqplot.preDrawHooks.length; i++) {
                    $.jqplot.preDrawHooks[i].call(this);
                }
                // create an underlying canvas to be used for special features.
                this.target.append(this.baseCanvas.createElement({ left: 0, right: 0, top: 0, bottom: 0 }, 'jqplot-base-canvas'));
                var bctx = this.baseCanvas.setContext();
                this.target.append(this.title.draw());
                this.title.pack({ top: 0, left: 0 });
                for (var name in this.axes) {
                    this.target.append(this.axes[name].draw(bctx));
                    this.axes[name].set();
                }
                if (this.axes.yaxis.show) {
                    this._gridPadding.left = this.axes.yaxis.getWidth();
                }
                var ra = ['y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
                var rapad = [0, 0, 0, 0];
                var gpr = 0;
                for (var n = 8; n > 0; n--) {
                    var ax = this.axes[ra[n - 1]];
                    if (ax.show) {
                        rapad[n - 1] = gpr;
                        gpr += ax.getWidth();
                    }
                }
                if (gpr > this._gridPadding.right) {
                    this._gridPadding.right = gpr;
                }
                if (this.title.show && this.axes.x2axis.show) {
                    this._gridPadding.top = this.title.getHeight() + this.axes.x2axis.getHeight();
                }
                else if (this.title.show) {
                    this._gridPadding.top = this.title.getHeight();
                }
                else if (this.axes.x2axis.show) {
                    this._gridPadding.top = this.axes.x2axis.getHeight();
                }
                if (this.axes.xaxis.show) {
                    this._gridPadding.bottom = this.axes.xaxis.getHeight();
                }

                this.axes.xaxis.pack({ position: 'absolute', bottom: 0, left: 0, width: this._width }, { min: this._gridPadding.left, max: this._width - this._gridPadding.right });
                this.axes.yaxis.pack({ position: 'absolute', top: 0, left: 0, height: this._height }, { min: this._height - this._gridPadding.bottom, max: this._gridPadding.top });
                this.axes.x2axis.pack({ position: 'absolute', top: this.title.getHeight(), left: 0, width: this._width }, { min: this._gridPadding.left, max: this._width - this._gridPadding.right });
                for (var i = 8; i > 0; i--) {
                    this.axes[ra[i - 1]].pack({ position: 'absolute', top: 0, right: rapad[i - 1] }, { min: this._height - this._gridPadding.bottom, max: this._gridPadding.top });
                }
                // this.axes.y2axis.pack({position:'absolute', top:0, right:0}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});

                this.target.append(this.grid.createElement(this._gridPadding));
                this.grid.draw();
                this.target.append(this.seriesCanvas.createElement(this._gridPadding, 'jqplot-series-canvas'));
                var sctx = this.seriesCanvas.setContext();
                this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas'));
                var ectx = this.eventCanvas.setContext();
                ectx.fillStyle = 'rgba(0,0,0,0)';
                ectx.fillRect(0, 0, ectx.canvas.width, ectx.canvas.height);

                // bind custom event handlers to regular events.
                this.bindCustomEvents();

                // draw legend before series if the series needs to know the legend dimensions.
                if (this.legend.preDraw) {
                    this.target.append(this.legend.draw());
                    this.legend.pack(this._gridPadding);
                    if (this.legend._elem) {
                        this.drawSeries(sctx, { legendInfo: { location: this.legend.location, width: this.legend.getWidth(), height: this.legend.getHeight(), xoffset: this.legend.xoffset, yoffset: this.legend.yoffset} });
                    }
                    else {
                        this.drawSeries(sctx);
                    }
                }
                else {  // draw series before legend
                    this.drawSeries(sctx);
                    $(this.seriesCanvas._elem).after(this.legend.draw());
                    // this.target.append(this.legend.draw());
                    this.legend.pack(this._gridPadding);
                }

                // register event listeners on the overlay canvas
                for (var i = 0; i < $.jqplot.eventListenerHooks.length; i++) {
                    var h = $.jqplot.eventListenerHooks[i];
                    // in the handler, this will refer to the eventCanvas dom element.
                    // make sure there are references back into plot objects.
                    this.eventCanvas._elem.bind(h[0], { plot: this }, h[1]);
                }

                for (var i = 0; i < $.jqplot.postDrawHooks.length; i++) {
                    $.jqplot.postDrawHooks[i].call(this);
                }

                if (this.target.is(':visible')) {
                    this._drawCount += 1;
                }

                this.target.trigger('jqplotPostDraw', [this]);
            }
        };

        this.bindCustomEvents = function() {
            this.eventCanvas._elem.bind('click', { plot: this }, this.onClick);
            this.eventCanvas._elem.bind('dblclick', { plot: this }, this.onDblClick);
            this.eventCanvas._elem.bind('mousedown', { plot: this }, this.onMouseDown);
            this.eventCanvas._elem.bind('mouseup', { plot: this }, this.onMouseUp);
            this.eventCanvas._elem.bind('mousemove', { plot: this }, this.onMouseMove);
            this.eventCanvas._elem.bind('mouseenter', { plot: this }, this.onMouseEnter);
            this.eventCanvas._elem.bind('mouseleave', { plot: this }, this.onMouseLeave);
        };

        function getEventPosition(ev) {
            var plot = ev.data.plot;
            // var xaxis = plot.axes.xaxis;
            // var x2axis = plot.axes.x2axis;
            // var yaxis = plot.axes.yaxis;
            // var y2axis = plot.axes.y2axis;
            var offsets = plot.eventCanvas._elem.offset();
            var gridPos = { x: ev.pageX - offsets.left, y: ev.pageY - offsets.top };
            // var dataPos = {x1y1:{x:null, y:null}, x1y2:{x:null, y:null}, x2y1:{x:null, y:null}, x2y2:{x:null, y:null}};
            var dataPos = { xaxis: null, yaxis: null, x2axis: null, y2axis: null, y3axis: null, y4axis: null, y5axis: null, y6axis: null, y7axis: null, y8axis: null, y9axis: null };

            var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
            var ax = plot.axes;
            for (var n = 11; n > 0; n--) {
                var axis = an[n - 1];
                if (ax[axis].show) {
                    dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]);
                }
            }

            return ({ offsets: offsets, gridPos: gridPos, dataPos: dataPos });
        }

        function getNeighborPoint(plot, x, y) {
            var ret = null;
            var s, i, d0, d, j, r;
            var threshold;
            for (var i = 0; i < plot.series.length; i++) {
                s = plot.series[i];
                r = s.renderer;
                if (s.show) {
                    threshold = Math.abs(s.markerRenderer.size / 2 + s.neighborThreshold);
                    for (var j = 0; j < s.gridData.length; j++) {
                        p = s.gridData[j];
                        // neighbor looks different to OHLC chart.
                        if (r.constructor == $.jqplot.OHLCRenderer) {
                            if (r.candleStick) {
                                var yp = s._yaxis.series_u2p;
                                if (x >= p[0] - r._bodyWidth / 2 && x <= p[0] + r._bodyWidth / 2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) {
                                    ret = { seriesIndex: i, pointIndex: j, gridData: p, data: s.data[j] };
                                }
                            }
                            // if an open hi low close chart
                            else if (!r.hlc) {
                                var yp = s._yaxis.series_u2p;
                                if (x >= p[0] - r._tickLength && x <= p[0] + r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) {
                                    ret = { seriesIndex: i, pointIndex: j, gridData: p, data: s.data[j] };
                                }
                            }
                            // a hi low close chart
                            else {
                                var yp = s._yaxis.series_u2p;
                                if (x >= p[0] - r._tickLength && x <= p[0] + r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) {
                                    ret = { seriesIndex: i, pointIndex: j, gridData: p, data: s.data[j] };
                                }
                            }

                        }
                        else {
                            d = Math.sqrt((x - p[0]) * (x - p[0]) + (y - p[1]) * (y - p[1]));
                            if (d <= threshold && (d <= d0 || d0 == null)) {
                                d0 = d;
                                ret = { seriesIndex: i, pointIndex: j, gridData: p, data: s.data[j] };
                            }
                        }
                    }
                }
            }
            return ret;
        }

        this.onClick = function(ev) {
            // Event passed in is unnormalized and will have data attribute.
            // Event passed out in normalized and won't have data attribute.
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            var neighbor = getNeighborPoint(p, positions.gridPos.x, positions.gridPos.y);
            ev.data.plot.eventCanvas._elem.trigger('jqplotClick', [positions.gridPos, positions.dataPos, neighbor, p]);
        };

        this.onDblClick = function(ev) {
            // Event passed in is unnormalized and will have data attribute.
            // Event passed out in normalized and won't have data attribute.
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            var neighbor = getNeighborPoint(p, positions.gridPos.x, positions.gridPos.y);
            ev.data.plot.eventCanvas._elem.trigger('jqplotDblClick', [positions.gridPos, positions.dataPos, neighbor, p]);
        };

        this.onMouseDown = function(ev) {
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            var neighbor = getNeighborPoint(p, positions.gridPos.x, positions.gridPos.y);
            ev.data.plot.eventCanvas._elem.trigger('jqplotMouseDown', [positions.gridPos, positions.dataPos, neighbor, p]);
        };

        this.onMouseUp = function(ev) {
            var positions = getEventPosition(ev);
            ev.data.plot.eventCanvas._elem.trigger('jqplotMouseUp', [positions.gridPos, positions.dataPos, null, ev.data.plot]);
        };

        this.onMouseMove = function(ev) {
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            var neighbor = getNeighborPoint(p, positions.gridPos.x, positions.gridPos.y);
            ev.data.plot.eventCanvas._elem.trigger('jqplotMouseMove', [positions.gridPos, positions.dataPos, neighbor, p]);
        };

        this.onMouseEnter = function(ev) {
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            ev.data.plot.eventCanvas._elem.trigger('jqplotMouseEnter', [positions.gridPos, positions.dataPos, null, p]);
        };

        this.onMouseLeave = function(ev) {
            var positions = getEventPosition(ev);
            var p = ev.data.plot;
            ev.data.plot.eventCanvas._elem.trigger('jqplotMouseLeave', [positions.gridPos, positions.dataPos, null, p]);
        };

        this.drawSeries = function(sctx, options) {
            // first clear the canvas, since we are redrawing all series.
            sctx.clearRect(0, 0, sctx.canvas.width, sctx.canvas.height);
            // if call series drawShadow method first, in case all series shadows
            // should be drawn before any series.  This will ensure, like for 
            // stacked bar plots, that shadows don't overlap series.
            for (var i = 0; i < this.series.length; i++) {
                this.series[i].drawShadow(sctx, options);
            }
            for (var i = 0; i < this.series.length; i++) {
                this.series[i].draw(sctx, options);
            }
        };
    }


    $.jqplot.ColorGenerator = function(colors) {
        var idx = 0;

        this.next = function() {
            if (idx < colors.length) {
                return colors[idx++];
            }
            else {
                idx = 0;
                return colors[idx++];
            }
        };

        this.previous = function() {
            if (idx > 0) {
                return colors[idx--];
            }
            else {
                idx = colors.length - 1;
                return colors[idx];
            }
        };

        // get a color by index without advancing pointer.
        this.get = function(i) {
            return colors[i];
        };

        this.setColors = function(c) {
            colors = c;
        };

        this.reset = function() {
            idx = 0;
        };
    };

    // convert a hex color string to rgb string.
    // h - 3 or 6 character hex string, with or without leading #
    // a - optional alpha
    $.jqplot.hex2rgb = function(h, a) {
        h = h.replace('#', '');
        if (h.length == 3) {
            h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
        }
        var rgb;
        rgb = 'rgba(' + parseInt(h.slice(0, 2), 16) + ', ' + parseInt(h.slice(2, 4), 16) + ', ' + parseInt(h.slice(4, 6), 16);
        if (a) {
            rgb += ', ' + a;
        }
        rgb += ')';
        return rgb;
    };

    // convert an rgb color spec to a hex spec.  ignore any alpha specification.
    $.jqplot.rgb2hex = function(s) {
        var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;
        var m = s.match(pat);
        var h = '#';
        for (i = 1; i < 4; i++) {
            var temp;
            if (m[i].search(/%/) != -1) {
                temp = parseInt(255 * m[i] / 100, 10).toString(16);
                if (temp.length == 1) {
                    temp = '0' + temp;
                }
            }
            else {
                temp = parseInt(m[i], 10).toString(16);
                if (temp.length == 1) {
                    temp = '0' + temp;
                }
            }
            h += temp;
        }
        return h;
    };

    // given a css color spec, return an rgb css color spec
    $.jqplot.normalize2rgb = function(s, a) {
        if (s.search(/^ *rgba?\(/) != -1) {
            return s;
        }
        else if (s.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/) != -1) {
            return $.jqplot.hex2rgb(s, a);
        }
        else {
            throw 'invalid color spec';
        }
    };

    // extract the r, g, b, a color components out of a css color spec.
    $.jqplot.getColorComponents = function(s) {
        var rgb = $.jqplot.normalize2rgb(s);
        var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;
        var m = rgb.match(pat);
        var ret = [];
        for (i = 1; i < 4; i++) {
            if (m[i].search(/%/) != -1) {
                ret[i - 1] = parseInt(255 * m[i] / 100, 10);
            }
            else {
                ret[i - 1] = parseInt(m[i], 10);
            }
        }
        ret[3] = parseFloat(m[4]) ? parseFloat(m[4]) : 1.0;
        return ret;
    };

    // Convienence function that won't hang IE.
    $.jqplot.log = function() {
        if (window.console && $.jqplot.debug) {
            if (arguments.length == 1) {
                console.log(arguments[0]);
            }
            else {
                console.log(arguments);
            }
        }
    };
    var log = $.jqplot.log;


    // class: $.jqplot.AxisLabelRenderer
    // Renderer to place labels on the axes.
    $.jqplot.AxisLabelRenderer = function(options) {
        // Group: Properties
        $.jqplot.ElemContainer.call(this);
        // name of the axis associated with this tick
        this.axis;
        // prop: show
        // wether or not to show the tick (mark and label).
        this.show = true;
        // prop: label
        // The text or html for the label.
        this.label = '';
        this._elem;
        // prop: escapeHTML
        // true to escape HTML entities in the label.
        this.escapeHTML = false;

        $.extend(true, this, options);
    };

    $.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer();
    $.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer;

    $.jqplot.AxisLabelRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    $.jqplot.AxisLabelRenderer.prototype.draw = function() {
        this._elem = $('<div style="position:absolute;" class="jqplot-' + this.axis + '-label"></div>');

        if (Number(this.label)) {
            this._elem.css('white-space', 'nowrap');
        }

        if (!this.escapeHTML) {
            this._elem.html(this.label);
        }
        else {
            this._elem.text(this.label);
        }

        return this._elem;
    };

    $.jqplot.AxisLabelRenderer.prototype.pack = function() {
    };

    // class: $.jqplot.AxisTickRenderer
    // A "tick" object showing the value of a tick/gridline on the plot.
    $.jqplot.AxisTickRenderer = function(options) {
        // Group: Properties
        $.jqplot.ElemContainer.call(this);
        // prop: mark
        // tick mark on the axis.  One of 'inside', 'outside', 'cross', '' or null.
        this.mark = 'outside';
        // name of the axis associated with this tick
        this.axis;
        // prop: showMark
        // wether or not to show the mark on the axis.
        this.showMark = true;
        // prop: showGridline
        // wether or not to draw the gridline on the grid at this tick.
        this.showGridline = true;
        // prop: isMinorTick
        // if this is a minor tick.
        this.isMinorTick = false;
        // prop: size
        // Length of the tick beyond the grid in pixels.
        // DEPRECATED: This has been superceeded by markSize
        this.size = 4;
        // prop:  markSize
        // Length of the tick marks in pixels.  For 'cross' style, length
        // will be stoked above and below axis, so total length will be twice this.
        this.markSize = 6;
        // prop: show
        // wether or not to show the tick (mark and label).
        // Setting this to false requires more testing.  It is recommended
        // to set showLabel and showMark to false instead.
        this.show = true;
        // prop: showLabel
        // wether or not to show the label.
        this.showLabel = true;
        this.label = '';
        this.value = null;
        this._styles = {};
        // prop: formatter
        // A class of a formatter for the tick text.  sprintf by default.
        this.formatter = $.jqplot.DefaultTickFormatter;
        // prop: formatString
        // string passed to the formatter.
        this.formatString = '';
        // prop: fontFamily
        // css spec for the font-family css attribute.
        this.fontFamily;
        // prop: fontSize
        // css spec for the font-size css attribute.
        this.fontSize;
        // prop: textColor
        // css spec for the color attribute.
        this.textColor;
        this._elem;

        $.extend(true, this, options);
    };

    $.jqplot.AxisTickRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    $.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer();
    $.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer;

    $.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) {
        this.value = value;
        this.axis = axisName;
        if (isMinor) {
            this.isMinorTick = true;
        }
        return this;
    };

    $.jqplot.AxisTickRenderer.prototype.draw = function() {
        if (!this.label) {
            this.label = this.formatter(this.formatString, this.value);
        }
        style = 'style="position:absolute;';
        if (Number(this.label)) {
            style += 'white-space:nowrap;';
        }
        style += '"';
        this._elem = $('<div ' + style + ' class="jqplot-' + this.axis + '-tick">' + this.label + '</div>');
        for (var s in this._styles) {
            this._elem.css(s, this._styles[s]);
        }
        if (this.fontFamily) {
            this._elem.css('font-family', this.fontFamily);
        }
        if (this.fontSize) {
            this._elem.css('font-size', this.fontSize);
        }
        if (this.textColor) {
            this._elem.css('color', this.textColor);
        }
        return this._elem;
    };

    $.jqplot.DefaultTickFormatter = function(format, val) {
        if (typeof val == 'number') {
            if (!format) {
                format = '%.1f';
            }
            return $.jqplot.sprintf(format, val);
        }
        else {
            return String(val);
        }
    };

    $.jqplot.AxisTickRenderer.prototype.pack = function() {
    };

    // Class: $.jqplot.CanvasGridRenderer
    // The default jqPlot grid renderer, creating a grid on a canvas element.
    // The renderer has no additional options beyond the <Grid> class.
    $.jqplot.CanvasGridRenderer = function() {
        this.shadowRenderer = new $.jqplot.ShadowRenderer();
    };

    // called with context of Grid object
    $.jqplot.CanvasGridRenderer.prototype.init = function(options) {
        this._ctx;
        $.extend(true, this, options);
        // set the shadow renderer options
        var sopts = { lineJoin: 'miter', lineCap: 'round', fill: false, isarc: false, angle: this.shadowAngle, offset: this.shadowOffset, alpha: this.shadowAlpha, depth: this.shadowDepth, lineWidth: this.shadowWidth, closePath: false };
        this.renderer.shadowRenderer.init(sopts);
    };

    // called with context of Grid.
    $.jqplot.CanvasGridRenderer.prototype.createElement = function() {
        var elem = document.createElement('canvas');
        var w = this._plotDimensions.width;
        var h = this._plotDimensions.height;
        elem.width = w;
        elem.height = h;
        this._elem = $(elem);
        this._elem.addClass('jqplot-grid-canvas');
        this._elem.css({ position: 'absolute', left: 0, top: 0 });
        if ($.browser.msie) {
            window.G_vmlCanvasManager.init_(document);
        }
        if ($.browser.msie) {
            elem = window.G_vmlCanvasManager.initElement(elem);
        }
        this._top = this._offsets.top;
        this._bottom = h - this._offsets.bottom;
        this._left = this._offsets.left;
        this._right = w - this._offsets.right;
        this._width = this._right - this._left;
        this._height = this._bottom - this._top;
        return this._elem;
    };

    $.jqplot.CanvasGridRenderer.prototype.draw = function() {
        this._ctx = this._elem.get(0).getContext("2d");
        var ctx = this._ctx;
        var axes = this._axes;
        // Add the grid onto the grid canvas.  This is the bottom most layer.
        ctx.save();
        ctx.fillStyle = this.background;
        ctx.fillRect(this._left, this._top, this._width, this._height);

        if (this.drawGridlines) {
            ctx.save();
            ctx.lineJoin = 'miter';
            ctx.lineCap = 'butt';
            ctx.lineWidth = this.gridLineWidth;
            ctx.strokeStyle = this.gridLineColor;
            var b, e;
            var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis'];
            for (var i = 4; i > 0; i--) {
                var name = ax[i - 1];
                var axis = axes[name];
                var ticks = axis._ticks;
                if (axis.show) {
                    for (var j = ticks.length; j > 0; j--) {
                        var t = ticks[j - 1];
                        if (t.show) {
                            var pos = Math.round(axis.u2p(t.value)) + 0.5;
                            switch (name) {
                                case 'xaxis':
                                    // draw the grid line
                                    if (t.showGridline) {
                                        drawLine(pos, this._top, pos, this._bottom);
                                    }

                                    // draw the mark
                                    if (t.showMark && t.mark) {
                                        s = t.markSize;
                                        m = t.mark;
                                        var pos = Math.round(axis.u2p(t.value)) + 0.5;
                                        switch (m) {
                                            case 'outside':
                                                b = this._bottom;
                                                e = this._bottom + s;
                                                break;
                                            case 'inside':
                                                b = this._bottom - s;
                                                e = this._bottom;
                                                break;
                                            case 'cross':
                                                b = this._bottom - s;
                                                e = this._bottom + s;
                                                break;
                                            default:
                                                b = this._bottom;
                                                e = this._bottom + s;
                                                break;
                                        }
                                        // draw the shadow
                                        if (this.shadow) {
                                            this.renderer.shadowRenderer.draw(ctx, [[pos, b], [pos, e]], { lineCap: 'butt', lineWidth: this.gridLineWidth, offset: this.gridLineWidth * 0.75, depth: 2, fill: false, closePath: false });
                                        }
                                        // draw the line
                                        drawLine(pos, b, pos, e);
                                    }
                                    break;
                                case 'yaxis':
                                    // draw the grid line
                                    if (t.showGridline) {
                                        drawLine(this._right, pos, this._left, pos);
                                    }
                                    // draw the mark
                                    if (t.showMark && t.mark) {
                                        s = t.markSize;
                                        m = t.mark;
                                        var pos = Math.round(axis.u2p(t.value)) + 0.5;
                                        switch (m) {
                                            case 'outside':
                                                b = this._left - s;
                                                e = this._left;
                                                break;
                                            case 'inside':
                                                b = this._left;
                                                e = this._left + s;
                                                break;
                                            case 'cross':
                                                b = this._left - s;
                                                e = this._left + s;
                                                break;
                                            default:
                                                b = this._left - s;
                                                e = this._left;
                                                break;
                                        }
                                        // draw the shadow
                                        if (this.shadow) {
                                            this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], { lineCap: 'butt', lineWidth: this.gridLineWidth * 1.5, offset: this.gridLineWidth * 0.75, fill: false, closePath: false });
                                        }
                                        drawLine(b, pos, e, pos, { strokeStyle: axis.borderColor });
                                    }
                                    break;
                                case 'x2axis':
                                    // draw the grid line
                                    if (t.showGridline) {
                                        drawLine(pos, this._bottom, pos, this._top);
                                    }
                                    // draw the mark
                                    if (t.showMark && t.mark) {
                                        s = t.markSize;
                                        m = t.mark;
                                        var pos = Math.round(axis.u2p(t.value)) + 0.5;
                                        switch (m) {
                                            case 'outside':
                                                b = this._top - s;
                                                e = this._top;
                                                break;
                                            case 'inside':
                                                b = this._top;
                                                e = this._top + s;
                                                break;
                                            case 'cross':
                                                b = this._top - s;
                                                e = this._top + s;
                                                break;
                                            default:
                                                b = this._top - s;
                                                e = this._top;
                                                break;
                                        }
                                        // draw the shadow
                                        if (this.shadow) {
                                            this.renderer.shadowRenderer.draw(ctx, [[pos, b], [pos, e]], { lineCap: 'butt', lineWidth: this.gridLineWidth, offset: this.gridLineWidth * 0.75, depth: 2, fill: false, closePath: false });
                                        }
                                        drawLine(pos, b, pos, e);
                                    }
                                    break;
                                case 'y2axis':
                                    // draw the grid line
                                    if (t.showGridline) {
                                        drawLine(this._left, pos, this._right, pos);
                                    }
                                    // draw the mark
                                    if (t.showMark && t.mark) {
                                        s = t.markSize;
                                        m = t.mark;
                                        var pos = Math.round(axis.u2p(t.value)) + 0.5;
                                        switch (m) {
                                            case 'outside':
                                                b = this._right;
                                                e = this._right + s;
                                                break;
                                            case 'inside':
                                                b = this._right - s;
                                                e = this._right;
                                                break;
                                            case 'cross':
                                                b = this._right - s;
                                                e = this._right + s;
                                                break;
                                            default:
                                                b = this._right;
                                                e = this._right + s;
                                                break;
                                        }
                                        // draw the shadow
                                        if (this.shadow) {
                                            this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], { lineCap: 'butt', lineWidth: this.gridLineWidth * 1.5, offset: this.gridLineWidth * 0.75, fill: false, closePath: false });
                                        }
                                        drawLine(b, pos, e, pos, { strokeStyle: axis.borderColor });
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
            // Now draw grid lines for additional y axes
            ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis'];
            for (var i = 7; i > 0; i--) {
                var axis = axes[ax[i - 1]];
                var ticks = axis._ticks;
                if (axis.show) {
                    var tn = ticks[axis.numberTicks - 1];
                    var t0 = ticks[0];
                    var left = axis.getLeft();
                    var points = [[left, tn.getTop() + tn.getHeight() / 2], [left, t0.getTop() + t0.getHeight() / 2 + 1.0]];
                    // draw the shadow
                    if (this.shadow) {
                        this.renderer.shadowRenderer.draw(ctx, points, { lineCap: 'butt', fill: false, closePath: false });
                    }
                    // draw the line
                    drawLine(points[0][0], points[0][1], points[1][0], points[1][1], { lineCap: 'butt', strokeStyle: axis.borderColor, lineWidth: axis.borderWidth });
                    // draw the tick marks
                    for (var j = ticks.length; j > 0; j--) {
                        var t = ticks[j - 1];
                        s = t.markSize;
                        m = t.mark;
                        var pos = Math.round(axis.u2p(t.value)) + 0.5;
                        if (t.showMark && t.mark) {
                            switch (m) {
                                case 'outside':
                                    b = left;
                                    e = left + s;
                                    break;
                                case 'inside':
                                    b = left - s;
                                    e = left;
                                    break;
                                case 'cross':
                                    b = left - s;
                                    e = left + s;
                                    break;
                                default:
                                    b = left;
                                    e = left + s;
                                    break;
                            }
                            points = [[b, pos], [e, pos]];
                            // draw the shadow
                            if (this.shadow) {
                                this.renderer.shadowRenderer.draw(ctx, points, { lineCap: 'butt', lineWidth: this.gridLineWidth * 1.5, offset: this.gridLineWidth * 0.75, fill: false, closePath: false });
                            }
                            // draw the line
                            drawLine(b, pos, e, pos, { strokeStyle: axis.borderColor });
                        }
                    }
                }
            }

            ctx.restore();
        }

        function drawLine(bx, by, ex, ey, opts) {
            ctx.save();
            opts = opts || {};
            $.extend(true, ctx, opts);
            ctx.beginPath();
            ctx.moveTo(bx, by);
            ctx.lineTo(ex, ey);
            ctx.stroke();
            ctx.restore();
        }

        if (this.shadow) {
            var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]];
            this.renderer.shadowRenderer.draw(ctx, points);
        }
        // Now draw border around grid.  Use axis border definitions. start at
        // upper left and go clockwise.
        drawLine(this._left, this._top, this._right, this._top, { lineCap: 'round', strokeStyle: axes.x2axis.borderColor, lineWidth: axes.x2axis.borderWidth });
        drawLine(this._right, this._top, this._right, this._bottom, { lineCap: 'round', strokeStyle: axes.y2axis.borderColor, lineWidth: axes.y2axis.borderWidth });
        drawLine(this._right, this._bottom, this._left, this._bottom, { lineCap: 'round', strokeStyle: axes.xaxis.borderColor, lineWidth: axes.xaxis.borderWidth });
        drawLine(this._left, this._bottom, this._left, this._top, { lineCap: 'round', strokeStyle: axes.yaxis.borderColor, lineWidth: axes.yaxis.borderWidth });
        // ctx.lineWidth = this.borderWidth;
        // ctx.strokeStyle = this.borderColor;
        // ctx.strokeRect(this._left, this._top, this._width, this._height);


        ctx.restore();
    };

    // Class: $.jqplot.DivTitleRenderer
    // The default title renderer for jqPlot.  This class has no options beyond the <Title> class. 
    $.jqplot.DivTitleRenderer = function() {
    };

    $.jqplot.DivTitleRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    $.jqplot.DivTitleRenderer.prototype.draw = function() {
        var r = this.renderer;
        if (!this.text) {
            this.show = false;
            this._elem = $('<div style="height:0px;width:0px;"></div>');
        }
        else if (this.text) {
            // don't trust that a stylesheet is present, set the position.
            var styletext = 'position:absolute;top:0px;left:0px;';
            styletext += (this._plotWidth) ? 'width:' + this._plotWidth + 'px;' : '';
            styletext += (this.fontFamily) ? 'font-family:' + this.fontFamily + ';' : '';
            styletext += (this.fontSize) ? 'font-size:' + this.fontSize + ';' : '';
            styletext += (this.textAlign) ? 'text-align:' + this.textAlign + ';' : 'text-align:center;';
            styletext += (this.textColor) ? 'color:' + this.textColor + ';' : '';
            this._elem = $('<div class="jqplot-title" style="' + styletext + '">' + this.text + '</div>');
        }

        return this._elem;
    };

    $.jqplot.DivTitleRenderer.prototype.pack = function() {
        // nothing to do here
    };

    // Class: $.jqplot.LineRenderer
    // The default line renderer for jqPlot, this class has no options beyond the <Series> class.
    // Draws series as a line.
    $.jqplot.LineRenderer = function() {
        this.shapeRenderer = new $.jqplot.ShapeRenderer();
        this.shadowRenderer = new $.jqplot.ShadowRenderer();
    };

    // called with scope of series.
    $.jqplot.LineRenderer.prototype.init = function(options) {
        $.extend(true, this.renderer, options);
        // set the shape renderer options
        var opts = { lineJoin: 'round', lineCap: 'round', fill: this.fill, isarc: false, strokeStyle: this.color, fillStyle: this.fillColor, lineWidth: this.lineWidth, closePath: this.fill };
        this.renderer.shapeRenderer.init(opts);
        // set the shadow renderer options
        // scale the shadowOffset to the width of the line.
        if (this.lineWidth > 2.5) {
            var shadow_offset = this.shadowOffset * (1 + (Math.atan((this.lineWidth / 2.5)) / 0.785398163 - 1) * 0.6);
            // var shadow_offset = this.shadowOffset;
        }
        // for skinny lines, don't make such a big shadow.
        else {
            var shadow_offset = this.shadowOffset * Math.atan((this.lineWidth / 2.5)) / 0.785398163;
        }
        var sopts = { lineJoin: 'round', lineCap: 'round', fill: this.fill, isarc: false, angle: this.shadowAngle, offset: shadow_offset, alpha: this.shadowAlpha, depth: this.shadowDepth, lineWidth: this.lineWidth, closePath: this.fill };
        this.renderer.shadowRenderer.init(sopts);
    };

    // Method: setGridData
    // converts the user data values to grid coordinates and stores them
    // in the gridData array.
    // Called with scope of a series.
    $.jqplot.LineRenderer.prototype.setGridData = function() {
        // recalculate the grid data
        var xp = this._xaxis.series_u2p;
        var yp = this._yaxis.series_u2p;
        var data = this._plotData;
        var pdata = this._prevPlotData;
        this.gridData = [];
        this._prevGridData = [];
        for (var i = 0; i < this.data.length; i++) {
            if (data[i] != null) {
                this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]);
            }
            if (pdata[i] != null) {
                this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]);
            }
        }
    };

    // Method: makeGridData
    // converts any arbitrary data values to grid coordinates and
    // returns them.  This method exists so that plugins can use a series'
    // linerenderer to generate grid data points without overwriting the
    // grid data associated with that series.
    // Called with scope of a series.
    $.jqplot.LineRenderer.prototype.makeGridData = function(data) {
        // recalculate the grid data
        var xp = this._xaxis.series_u2p;
        var yp = this._yaxis.series_u2p;
        var gd = [];
        var pgd = [];
        for (var i = 0; i < data.length; i++) {
            if (data[i] != null) {
                gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]);
            }
        }
        return gd;
    };


    // called within scope of series.
    $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options) {
        var i;
        var opts = (options != undefined) ? options : {};
        var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
        var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
        var fill = (opts.fill != undefined) ? opts.fill : this.fill;
        var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke;
        ctx.save();
        if (gd.length) {
            if (showLine) {
                // if we fill, we'll have to add points to close the curve.
                if (fill) {
                    if (this.fillToZero) {
                        // have to break line up into shapes at axis crossings
                        var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors);
                        var negativeColor = negativeColors.get(this.index);
                        var isnegative = false;
                        var posfs = opts.fillStyle;

                        // if stoking line as well as filling, get a copy of line data.
                        if (fillAndStroke) {
                            var fasgd = gd.slice(0);
                        }
                        // if not stacked, fill down to axis
                        if (this.index == 0 || !this._stack) {

                            var tempgd = [];
                            var pyzero = this._yaxis.series_u2p(0);
                            var pxzero = this._xaxis.series_u2p(0);

                            if (this.fillAxis == 'y') {
                                tempgd.push([gd[0][0], pyzero]);

                                for (var i = 0; i < gd.length - 1; i++) {
                                    tempgd.push(gd[i]);
                                    // do we have an axis crossing?
                                    if (this._plotData[i][1] * this._plotData[i + 1][1] < 0) {
                                        if (this._plotData[i][1] < 0) {
                                            isnegative = true;
                                            opts.fillStyle = negativeColor;
                                        }
                                        else {
                                            isnegative = false;
                                            opts.fillStyle = posfs;
                                        }

                                        var xintercept = gd[i][0] + (gd[i + 1][0] - gd[i][0]) * (pyzero - gd[i][1]) / (gd[i + 1][1] - gd[i][1]);
                                        tempgd.push([xintercept, pyzero]);
                                        // now draw this shape and shadow.
                                        if (shadow) {
                                            this.renderer.shadowRenderer.draw(ctx, tempgd, opts);
                                        }
                                        this.renderer.shapeRenderer.draw(ctx, tempgd, opts);
                                        // now empty temp array and continue
                                        tempgd = [[xintercept, pyzero]];
                                    }
                                }
                                if (this._plotData[gd.length - 1][1] < 0) {
                                    isnegative = true;
                                    opts.fillStyle = negativeColor;
                                }
                                else {
                                    isnegative = false;
                                    opts.fillStyle = posfs;
                                }
                                tempgd.push(gd[gd.length - 1]);
                                tempgd.push([gd[gd.length - 1][0], pyzero]);
                            }
                            // now draw this shape and shadow.
                            if (shadow) {
                                this.renderer.shadowRenderer.draw(ctx, tempgd, opts);
                            }
                            this.renderer.shapeRenderer.draw(ctx, tempgd, opts);


                            // var gridymin = this._yaxis.series_u2p(0);
                            // // IE doesn't return new length on unshift
                            // gd.unshift([gd[0][0], gridymin]);
                            // len = gd.length;
                            // gd.push([gd[len - 1][0], gridymin]);                   
                        }
                        // if stacked, fill to line below 
                        else {
                            var prev = this._prevGridData;
                            for (var i = prev.length; i > 0; i--) {
                                gd.push(prev[i - 1]);
                            }
                            if (shadow) {
                                this.renderer.shadowRenderer.draw(ctx, gd, opts);
                            }

                            this.renderer.shapeRenderer.draw(ctx, gd, opts);
                        }
                    }
                    else {
                        // if stoking line as well as filling, get a copy of line data.
                        if (fillAndStroke) {
                            var fasgd = gd.slice(0);
                        }
                        // if not stacked, fill down to axis
                        if (this.index == 0 || !this._stack) {
                            // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2;
                            var gridymin = ctx.canvas.height;
                            // IE doesn't return new length on unshift
                            gd.unshift([gd[0][0], gridymin]);
                            len = gd.length;
                            gd.push([gd[len - 1][0], gridymin]);
                        }
                        // if stacked, fill to line below 
                        else {
                            var prev = this._prevGridData;
                            for (var i = prev.length; i > 0; i--) {
                                gd.push(prev[i - 1]);
                            }
                        }
                        if (shadow) {
                            this.renderer.shadowRenderer.draw(ctx, gd, opts);
                        }

                        this.renderer.shapeRenderer.draw(ctx, gd, opts);
                    }
                    if (fillAndStroke) {
                        var fasopts = $.extend(true, {}, opts, { fill: false, closePath: false });
                        this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts);
                        //////////
                        // TODO: figure out some way to do shadows nicely
                        // if (shadow) {
                        //     this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts);
                        // }
                        // now draw the markers
                        if (this.markerRenderer.show) {
                            for (i = 0; i < fasgd.length; i++) {
                                this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions);
                            }
                        }
                    }
                }
                else {
                    if (shadow) {
                        this.renderer.shadowRenderer.draw(ctx, gd, opts);
                    }

                    this.renderer.shapeRenderer.draw(ctx, gd, opts);
                }
            }

            // now draw the markers
            if (this.markerRenderer.show && !fill) {
                for (i = 0; i < gd.length; i++) {
                    this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions);
                }
            }
        }

        ctx.restore();
    };

    $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) {
        // This is a no-op, shadows drawn with lines.
    };


    // class: $.jqplot.LinearAxisRenderer
    // The default jqPlot axis renderer, creating a numeric axis.
    // The renderer has no additional options beyond the <Axis> object.
    $.jqplot.LinearAxisRenderer = function() {
    };

    // called with scope of axis object.
    $.jqplot.LinearAxisRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
        var db = this._dataBounds;
        // Go through all the series attached to this axis and find
        // the min/max bounds for this axis.
        for (var i = 0; i < this._series.length; i++) {
            var s = this._series[i];
            var d = s._plotData;

            for (var j = 0; j < d.length; j++) {
                if (this.name == 'xaxis' || this.name == 'x2axis') {
                    if (d[j][0] < db.min || db.min == null) {
                        db.min = d[j][0];
                    }
                    if (d[j][0] > db.max || db.max == null) {
                        db.max = d[j][0];
                    }
                }
                else {
                    if (d[j][1] < db.min || db.min == null) {
                        db.min = d[j][1];
                    }
                    if (d[j][1] > db.max || db.max == null) {
                        db.max = d[j][1];
                    }
                }
            }
        }
    };

    // called with scope of axis
    $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx) {
        if (this.show) {
            // populate the axis label and value properties.
            // createTicks is a method on the renderer, but
            // call it within the scope of the axis.
            this.renderer.createTicks.call(this);
            // fill a div with axes labels in the right direction.
            // Need to pregenerate each axis to get it's bounds and
            // position it and the labels correctly on the plot.
            var dim = 0;
            var temp;

            this._elem = $('<div class="jqplot-axis jqplot-' + this.name + '" style="position:absolute;"></div>');

            if (this.name == 'xaxis' || this.name == 'x2axis') {
                this._elem.width(this._plotDimensions.width);
            }
            else {
                this._elem.height(this._plotDimensions.height);
            }

            // create a _label object.
            this.labelOptions.axis = this.name;
            this._label = new this.labelRenderer(this.labelOptions);
            if (this._label.show) {
                var elem = this._label.draw(ctx);
                elem.appendTo(this._elem);
            }

            if (this.showTicks) {
                var t = this._ticks;
                for (var i = 0; i < t.length; i++) {
                    var tick = t[i];
                    if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                        var elem = tick.draw(ctx);
                        elem.appendTo(this._elem);
                    }
                }
            }
        }
        return this._elem;
    };

    // called with scope of an axis
    $.jqplot.LinearAxisRenderer.prototype.reset = function() {
        this.min = this._min;
        this.max = this._max;
        this.tickInterval = this._tickInterval;
        this.numberTicks = this._numberTicks;
        // this._ticks = this.__ticks;
    };

    // called with scope of axis
    $.jqplot.LinearAxisRenderer.prototype.set = function() {
        var dim = 0;
        var temp;
        var w = 0;
        var h = 0;
        var lshow = (this._label == null) ? false : this._label.show;
        if (this.show && this.showTicks) {
            var t = this._ticks;
            for (var i = 0; i < t.length; i++) {
                var tick = t[i];
                if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
                    if (this.name == 'xaxis' || this.name == 'x2axis') {
                        temp = tick._elem.outerHeight(true);
                    }
                    else {
                        temp = tick._elem.outerWidth(true);
                    }
                    if (temp > dim) {
                        dim = temp;
                    }
                }
            }

            if (lshow) {
                w = this._label._elem.outerWidth(true);
                h = this._label._elem.outerHeight(true);
            }
            if (this.name == 'xaxis') {
                dim = dim + h;
                this._elem.css({ 'height': dim + 'px', left: '0px', bottom: '0px' });
            }
            else if (this.name == 'x2axis') {
                dim = dim + h;
                this._elem.css({ 'height': dim + 'px', left: '0px', top: '0px' });
            }
            else if (this.name == 'yaxis') {
                dim = dim + w;
                this._elem.css({ 'width': dim + 'px', left: '0px', top: '0px' });
                if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
                    this._label._elem.css('width', w + 'px');
                }
            }
            else {
                dim = dim + w;
                this._elem.css({ 'width': dim + 'px', right: '0px', top: '0px' });
                if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
                    this._label._elem.css('width', w + 'px');
                }
            }
        }
    };

    // called with scope of axis
    $.jqplot.LinearAxisRenderer.prototype.createTicks = function() {
        // we're are operating on an axis here
        var ticks = this._ticks;
        var userTicks = this.ticks;
        var name = this.name;
        // databounds were set on axis initialization.
        var db = this._dataBounds;
        var dim, interval;
        var min, max;
        var pos1, pos2;
        var tt, i;

        // if we already have ticks, use them.
        // ticks must be in order of increasing value.

        if (userTicks.length) {
            // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
            for (i = 0; i < userTicks.length; i++) {
                var ut = userTicks[i];
                var t = new this.tickRenderer(this.tickOptions);
                if (ut.constructor == Array) {
                    t.value = ut[0];
                    t.label = ut[1];
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) {
                        t.showMark = false;
                    }
                    t.setTick(ut[0], this.name);
                    this._ticks.push(t);
                }

                else {
                    t.value = ut;
                    if (!this.showTicks) {
                        t.showLabel = false;
                        t.showMark = false;
                    }
                    else if (!this.showTickMarks) {
                        t.showMark = false;
                    }
                    t.setTick(ut, this.name);
                    this._ticks.push(t);
                }
            }
            this.numberTicks = userTicks.length;
            this.min = this._ticks[0].value;
            this.max = this._ticks[this.numberTicks - 1].value;
            this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
        }

        // we don't have any ticks yet, let's make some!
        else {
            if (name == 'xaxis' || name == 'x2axis') {
                dim = this._plotDimensions.width;
            }
            else {
                dim = this._plotDimensions.height;
            }

            // if min, max and number of ticks specified, user can't specify interval.
            if (!this.autoscale && this.min != null && this.max != null && this.numberTicks != null) {
                this.tickInterval = null;
            }

            // if max, min, and interval specified and interval won't fit, ignore interval.
            // if (this.min != null && this.max != null && this.tickInterval != null) {
            //     if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) {
            //         this.tickInterval = null;
            //     }
            // }

            min = ((this.min != null) ? this.min : db.min);
            max = ((this.max != null) ? this.max : db.max);

            // if min and max are same, space them out a bit
            if (min == max) {
                var adj = 0.05;
                if (min > 0) {
                    adj = Math.max(Math.log(min) / Math.LN10, 0.05);
                }
                min -= adj;
                max += adj;
            }

            var range = max - min;
            var rmin, rmax;
            var temp;

            // autoscale.  Can't autoscale if min or max is supplied.
            // Will use numberTicks and tickInterval if supplied.  Ticks
            // across multiple axes may not line up depending on how
            // bars are to be plotted.
            if (this.autoscale && this.min == null && this.max == null) {
                var rrange, ti, margin;
                var forceMinZero = false;
                var forceZeroLine = false;
                var intervals = { min: null, max: null, average: null, stddev: null };
                // if any series are bars, or if any are fill to zero, and if this
                // is the axis to fill toward, check to see if we can start axis at zero.
                for (var i = 0; i < this._series.length; i++) {
                    var s = this._series[i];
                    var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name;
                    // check to see if this is the fill axis
                    if (this.name == faname) {
                        var vals = s._plotValues[s.fillAxis];
                        var vmin = vals[0];
                        var vmax = vals[0];
                        for (var j = 1; j < vals.length; j++) {
                            if (vals[j] < vmin) {
                                vmin = vals[j];
                            }
                            else if (vals[j] > vmax) {
                                vmax = vals[j];
                            }
                        }
                        var dp = (vmax - vmin) / vmax;
                        // is this sries a bar?
                        if (s.renderer.constructor == $.jqplot.BarRenderer) {
                            // if no negative values and could also check range.
                            if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
                                forceMinZero = true;
                            }
                            else {
                                forceMinZero = false;
                                if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) {
                                    forceZeroLine = true;
                                }
                                else {
                                    forceZeroLine = false;
                                }
                            }
                        }

                        // if not a bar and filling, use appropriate method.
                        else if (s.fill) {
                            if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
                                forceMinZero = true;
                            }
                            else if (vmin < 0 && vmax > 0 && s.fillToZero) {
                                forceMinZero = false;
                                forceZeroLine = true;
                            }
                            else {
                                forceMinZero = false;
                                forceZeroLine = false;
                            }
                        }

                        // if not a bar and not filling, only change existing state
                        // if it doesn't make sense
                        else if (vmin < 0) {
                            forceMinZero = false;
                        }
                    }
                }

                // check if we need make axis min at 0.
                if (forceMinZero) {
                    // compute number of ticks
                    this.numberTicks = 2 + Math.ceil((dim - (this.tickSpacing - 1)) / this.tickSpacing);
                    this.min = 0;
                    // what order is this range?
                    // what tick interval does that give us?
                    ti = max / (this.numberTicks - 1);
                    temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti) / Math.LN10)));
                    if (ti / temp == parseInt(ti / temp, 10)) {
                        ti += temp;
                    }
                    this.tickInterval = Math.ceil(ti / temp) * temp;
                    this.max = this.tickInterval * (this.numberTicks - 1);
                }

                // check if we need to make sure there is a tick at 0.
                else if (forceZeroLine) {
                    // compute number of ticks
                    this.numberTicks = 2 + Math.ceil((dim - (this.tickSpacing - 1)) / this.tickSpacing);
                    var ntmin = Math.ceil(Math.abs(min) / range * (this.numberTicks - 1));
                    var ntmax = this.numberTicks - 1 - ntmin;
                    ti = Math.max(Math.abs(min / ntmin), Math.abs(max / ntmax));
                    temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti) / Math.LN10)));
                    this.tickInterval = Math.ceil(ti / temp) * temp;
                    this.max = this.tickInterval * ntmax;
                    this.min = -this.tickInterval * ntmin;
                }

                // if nothing else, do autoscaling which will try to line up ticks across axes.
                else {
                    if (this.numberTicks == null) {
                        if (this.tickInterval) {
                            this.numberTicks = 3 + Math.ceil(range / this.tickInterval);
                        }
                        else {
                            this.numberTicks = 2 + Math.ceil((dim - (this.tickSpacing - 1)) / this.tickSpacing);
                        }
                    }

                    if (this.tickInterval == null) {
                        // get a tick interval
                        ti = range / (this.numberTicks - 1);

                        if (ti < 1) {
                            temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti) / Math.LN10)));
                        }
                        else {
                            temp = 1;
                        }
                        this.tickInterval = Math.ceil(ti * temp * this.pad) / temp;
                    }
                    else {
                        temp = 1 / this.tickInterval;
                    }

                    // try to compute a nicer, more even tick interval
                    // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10));
                    // this.tickInterval = Math.ceil(ti/temp) * temp;
                    rrange = this.tickInterval * (this.numberTicks - 1);
                    margin = (rrange - range) / 2;

                    if (this.min == null) {
                        this.min = Math.floor(temp * (min - margin)) / temp;
                    }
                    if (this.max == null) {
                        this.max = this.min + rrange;
                    }
                }
            }

            else {
                rmin = (this.min != null) ? this.min : min - range * (this.padMin - 1);
                rmax = (this.max != null) ? this.max : max + range * (this.padMax - 1);
                this.min = rmin;
                this.max = rmax;
                range = this.max - this.min;

                if (this.numberTicks == null) {
                    // if tickInterval is specified by user, we will ignore computed maximum.
                    // max will be equal or greater to fit even # of ticks.
                    if (this.tickInterval != null) {
                        this.numberTicks = Math.ceil((this.max - this.min) / this.tickInterval) + 1;
                        this.max = this.min + this.tickInterval * (this.numberTicks - 1);
                    }
                    else if (dim > 100) {
                        this.numberTicks = parseInt(3 + (dim - 100) / 75, 10);
                    }
                    else {
                        this.numberTicks = 2;
                    }
                }

                if (this.tickInterval == null) {
                    this.tickInterval = range / (this.numberTicks - 1);
                }
            }

            for (var i = 0; i < this.numberTicks; i++) {
                tt = this.min + i * this.tickInterval;
                var t = new this.tickRenderer(this.tickOptions);
                // var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
                if (!this.showTicks) {
                    t.showLabel = false;
                    t.showMark = false;
                }
                else if (!this.showTickMarks) {
                    t.showMark = false;
                }
                t.setTick(tt, this.name);
                this._ticks.push(t);
            }
        }
    };

    // called with scope of axis
    $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) {
        var ticks = this._ticks;
        var max = this.max;
        var min = this.min;
        var offmax = offsets.max;
        var offmin = offsets.min;
        var lshow = (this._label == null) ? false : this._label.show;

        for (var p in pos) {
            this._elem.css(p, pos[p]);
        }

        this._offsets = offsets;
        // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
        var pixellength = offmax - offmin;
        var unitlength = max - min;

        // point to unit and unit to point conversions references to Plot DOM element top left corner.
        this.p2u = function(p) {
            return (p - offmin) * unitlength / pixellength + min;
        };

        this.u2p = function(u) {
            return (u - min) * pixellength / unitlength + offmin;
        };

        if (this.name == 'xaxis' || this.name == 'x2axis') {
            this.series_u2p = function(u) {
                return (u - min) * pixellength / unitlength;
            };
            this.series_p2u = function(p) {
                return p * unitlength / pixellength + min;
            };
        }

        else {
            this.series_u2p = function(u) {
                return (u - max) * pixellength / unitlength;
            };
            this.series_p2u = function(p) {
                return p * unitlength / pixellength + max;
            };
        }

        if (this.show) {
            if (this.name == 'xaxis' || this.name == 'x2axis') {
                for (i = 0; i < ticks.length; i++) {
                    var t = ticks[i];
                    if (t.show && t.showLabel) {
                        var shim;

                        if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
                            // will need to adjust auto positioning based on which axis this is.
                            var temp = (this.name == 'xaxis') ? 1 : -1;
                            switch (t.labelPosition) {
                                case 'auto':
                                    // position at end
                                    if (temp * t.angle < 0) {
                                        shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
                                    }
                                    // position at start
                                    else {
                                        shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
                                    }
                                    break;
                                case 'end':
                                    shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
                                    break;
                                case 'start':
                                    shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
                                    break;
                                case 'middle':
                                    shim = -t.getWidth() / 2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
                                    break;
                                default:
                                    shim = -t.getWidth() / 2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
                                    break;
                            }
                        }
                        else {
                            shim = -t.getWidth() / 2;
                        }
                        var val = this.u2p(t.value) + shim + 'px';
                        t._elem.css('left', val);
                        t.pack();
                    }
                }
                if (lshow) {
                    var w = this._label._elem.outerWidth(true);
                    this._label._elem.css('left', offmin + pixellength / 2 - w / 2 + 'px');
                    if (this.name == 'xaxis') {
                        this._label._elem.css('bottom', '0px');
                    }
                    else {
                        this._label._elem.css('top', '0px');
                    }
                    this._label.pack();
                }
            }
            else {
                for (i = 0; i < ticks.length; i++) {
                    var t = ticks[i];
                    if (t.show && t.showLabel) {
                        var shim;
                        if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
                            // will need to adjust auto positioning based on which axis this is.
                            var temp = (this.name == 'yaxis') ? 1 : -1;
                            switch (t.labelPosition) {
                                case 'auto':
                                    // position at end
                                case 'end':
                                    if (temp * t.angle < 0) {
                                        shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
                                    }
                                    else {
                                        shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
                                    }
                                    break;
                                case 'start':
                                    if (t.angle > 0) {
                                        shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
                                    }
                                    else {
                                        shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
                                    }
                                    break;
                                case 'middle':
                                    // if (t.angle > 0) {
                                    //     shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
                                    // }
                                    // else {
                                    //     shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
                                    // }
                                    shim = -t.getHeight() / 2;
                                    break;
                                default:
                                    shim = -t.getHeight() / 2;
                                    break;
                            }
                        }
                        else {
                            shim = -t.getHeight() / 2;
                        }

                        var val = this.u2p(t.value) + shim + 'px';
                        t._elem.css('top', val);
                        t.pack();
                    }
                }
                if (lshow) {
                    var h = this._label._elem.outerHeight(true);
                    this._label._elem.css('top', offmax - pixellength / 2 - h / 2 + 'px');
                    if (this.name == 'yaxis') {
                        this._label._elem.css('left', '0px');
                    }
                    else {
                        this._label._elem.css('right', '0px');
                    }
                    this._label.pack();
                }
            }
        }
    };


    // class: $.jqplot.MarkerRenderer
    // The default jqPlot marker renderer, rendering the points on the line.
    $.jqplot.MarkerRenderer = function(options) {
        // Group: Properties

        // prop: show
        // wether or not to show the marker.
        this.show = true;
        // prop: style
        // One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare
        this.style = 'filledCircle';
        // prop: lineWidth
        // size of the line for non-filled markers.
        this.lineWidth = 2;
        // prop: size
        // Size of the marker (diameter or circle, length of edge of square, etc.)
        this.size = 9.0;
        // prop: color
        // color of marker.  Will be set to color of series by default on init.
        this.color = '#666666';
        // prop: shadow
        // wether or not to draw a shadow on the line
        this.shadow = true;
        // prop: shadowAngle
        // Shadow angle in degrees
        this.shadowAngle = 45;
        // prop: shadowOffset
        // Shadow offset from line in pixels
        this.shadowOffset = 1;
        // prop: shadowDepth
        // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
        this.shadowDepth = 3;
        // prop: shadowAlpha
        // Alpha channel transparency of shadow.  0 = transparent.
        this.shadowAlpha = '0.07';
        // prop: shadowRenderer
        // Renderer that will draws the shadows on the marker.
        this.shadowRenderer = new $.jqplot.ShadowRenderer();
        // prop: shapeRenderer
        // Renderer that will draw the marker.
        this.shapeRenderer = new $.jqplot.ShapeRenderer();

        $.extend(true, this, options);
    };

    $.jqplot.MarkerRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
        var sdopt = { angle: this.shadowAngle, offset: this.shadowOffset, alpha: this.shadowAlpha, lineWidth: this.lineWidth, depth: this.shadowDepth, closePath: true };
        if (this.style.indexOf('filled') != -1) {
            sdopt.fill = true;
        }
        if (this.style.indexOf('ircle') != -1) {
            sdopt.isarc = true;
            sdopt.closePath = false;
        }
        this.shadowRenderer.init(sdopt);

        var shopt = { fill: false, isarc: false, strokeStyle: this.color, fillStyle: this.color, lineWidth: this.lineWidth, closePath: true };
        if (this.style.indexOf('filled') != -1) {
            shopt.fill = true;
        }
        if (this.style.indexOf('ircle') != -1) {
            shopt.isarc = true;
            shopt.closePath = false;
        }
        this.shapeRenderer.init(shopt);
    };

    $.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) {
        var stretch = 1.2;
        var dx = this.size / 2 / stretch;
        var dy = this.size / 2 * stretch;
        var points = [[x - dx, y], [x, y + dy], [x + dx, y], [x, y - dy]];
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points);
        }
        this.shapeRenderer.draw(ctx, points, options);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) {
        var stretch = 1.0;
        var dx = this.size / 2 * stretch;
        var dy = this.size / 2 * stretch;
        var points1 = [[x, y - dy], [x, y + dy]];
        var points2 = [[x + dx, y], [x - dx, y]];
        var opts = $.extend(true, {}, this.options, { closePath: false });
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points1, { closePath: false });
            this.shadowRenderer.draw(ctx, points2, { closePath: false });
        }
        this.shapeRenderer.draw(ctx, points1, opts);
        this.shapeRenderer.draw(ctx, points2, opts);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) {
        var stretch = 1.0;
        var dx = this.size / 2 * stretch;
        var dy = this.size / 2 * stretch;
        var opts = $.extend(true, {}, this.options, { closePath: false });
        var points1 = [[x - dx, y - dy], [x + dx, y + dy]];
        var points2 = [[x - dx, y + dy], [x + dx, y - dy]];
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points1, { closePath: false });
            this.shadowRenderer.draw(ctx, points2, { closePath: false });
        }
        this.shapeRenderer.draw(ctx, points1, opts);
        this.shapeRenderer.draw(ctx, points2, opts);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) {
        var stretch = 1.0;
        var dx = this.size / 2 * stretch;
        var dy = this.size / 2 * stretch;
        var points = [[x - dx, y], [x + dx, y]];
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points);
        }
        this.shapeRenderer.draw(ctx, points, options);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) {
        var stretch = 1.0;
        var dx = this.size / 2 / stretch;
        var dy = this.size / 2 * stretch;
        var points = [[x - dx, y - dy], [x - dx, y + dy], [x + dx, y + dy], [x + dx, y - dy]];
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points);
        }
        this.shapeRenderer.draw(ctx, points, options);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) {
        var radius = this.size / 2;
        var end = 2 * Math.PI;
        var points = [x, y, radius, 0, end, true];
        if (this.shadow) {
            this.shadowRenderer.draw(ctx, points);
        }
        this.shapeRenderer.draw(ctx, points, options);

        ctx.restore();
    };

    $.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) {
        options = options || {};
        switch (this.style) {
            case 'diamond':

                this.drawDiamond(x, y, ctx, false, options);
                break;
            case 'filledDiamond':
                this.drawDiamond(x, y, ctx, true, options);
                break;
            case 'circle':
                this.drawCircle(x, y, ctx, false, options);
                break;
            case 'filledCircle':
                this.drawCircle(x, y, ctx, true, options);
                break;
            case 'square':
                this.drawSquare(x, y, ctx, false, options);
                break;
            case 'filledSquare':
                this.drawSquare(x, y, ctx, true, options);
                break;
            case 'x':
                this.drawX(x, y, ctx, true, options);
                break;
            case 'plus':
                this.drawPlus(x, y, ctx, true, options);
                break;
            case 'dash':
                this.drawDash(x, y, ctx, true, options);
                break;
            default:
                this.drawDiamond(x, y, ctx, false, options);
                break;
        }
    };

    // class: $.jqplot.shadowRenderer
    // The default jqPlot shadow renderer, rendering shadows behind shapes.
    $.jqplot.ShadowRenderer = function(options) {
        // Group: Properties

        // prop: angle
        // Angle of the shadow in degrees.  Measured counter-clockwise from the x axis.
        this.angle = 45;
        // prop: offset
        // Pixel offset at the given shadow angle of each shadow stroke from the last stroke.
        this.offset = 1;
        // prop: alpha
        // alpha transparency of shadow stroke.
        this.alpha = 0.07;
        // prop: lineWidth
        // width of the shadow line stroke.
        this.lineWidth = 1.5;
        // prop: lineJoin
        // How line segments of the shadow are joined.
        this.lineJoin = 'miter';
        // prop: lineCap
        // how ends of the shadow line are rendered.
        this.lineCap = 'round';
        // prop; closePath
        // whether line path segment is closed upon itself.
        this.closePath = false;
        // prop: fill
        // whether to fill the shape.
        this.fill = false;
        // prop: depth
        // how many times the shadow is stroked.  Each stroke will be offset by offset at angle degrees.
        this.depth = 3;
        // prop: isarc
        // wether the shadow is an arc or not.
        this.isarc = false;

        $.extend(true, this, options);
    };

    $.jqplot.ShadowRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    // function: draw
    // draws an transparent black (i.e. gray) shadow.
    //
    // ctx - canvas drawing context
    // points - array of points or [x, y, radius, start angle (rad), end angle (rad)]
    $.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) {
        ctx.save();
        var opts = (options != null) ? options : {};
        var fill = (opts.fill != null) ? opts.fill : this.fill;
        var closePath = (opts.closePath != null) ? opts.closePath : this.closePath;
        var offset = (opts.offset != null) ? opts.offset : this.offset;
        var alpha = (opts.alpha != null) ? opts.alpha : this.alpha;
        var depth = (opts.depth != null) ? opts.depth : this.depth;
        ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth;
        ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin;
        ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap;
        ctx.strokeStyle = 'rgba(0,0,0,' + alpha + ')';
        ctx.fillStyle = 'rgba(0,0,0,' + alpha + ')';
        for (var j = 0; j < depth; j++) {
            ctx.translate(Math.cos(this.angle * Math.PI / 180) * offset, Math.sin(this.angle * Math.PI / 180) * offset);
            ctx.beginPath();
            if (this.isarc) {
                ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
            }
            else {
                ctx.moveTo(points[0][0], points[0][1]);
                for (var i = 1; i < points.length; i++) {
                    ctx.lineTo(points[i][0], points[i][1]);
                }

            }
            if (closePath) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fill();
            }
            else {
                ctx.stroke();
            }
        }
        ctx.restore();
    };

    // class: $.jqplot.shapeRenderer
    // The default jqPlot shape renderer.  Given a set of points will
    // plot them and either stroke a line (fill = false) or fill them (fill = true).
    // If a filled shape is desired, closePath = true must also be set to close
    // the shape.
    $.jqplot.ShapeRenderer = function(options) {

        this.lineWidth = 1.5;
        // prop: lineJoin
        // How line segments of the shadow are joined.
        this.lineJoin = 'miter';
        // prop: lineCap
        // how ends of the shadow line are rendered.
        this.lineCap = 'round';
        // prop; closePath
        // whether line path segment is closed upon itself.
        this.closePath = false;
        // prop: fill
        // whether to fill the shape.
        this.fill = false;
        // prop: isarc
        // wether the shadow is an arc or not.
        this.isarc = false;
        // prop: fillRect
        // true to draw shape as a filled rectangle.
        this.fillRect = false;
        // prop: strokeRect
        // true to draw shape as a stroked rectangle.
        this.strokeRect = false;
        // prop: clearRect
        // true to cear a rectangle.
        this.clearRect = false;
        // prop: strokeStyle
        // css color spec for the stoke style
        this.strokeStyle = '#999999';
        // prop: fillStyle
        // css color spec for the fill style.
        this.fillStyle = '#999999';

        $.extend(true, this, options);
    };

    $.jqplot.ShapeRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    // function: draw
    // draws the shape.
    //
    // ctx - canvas drawing context
    // points - array of points for shapes or 
    // [x, y, width, height] for rectangles or
    // [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs.
    $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) {
        ctx.save();
        var opts = (options != null) ? options : {};
        var fill = (opts.fill != null) ? opts.fill : this.fill;
        var closePath = (opts.closePath != null) ? opts.closePath : this.closePath;
        var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect;
        var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect;
        var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect;
        var isarc = (opts.isarc != null) ? opts.isarc : this.isarc;
        ctx.lineWidth = opts.lineWidth || this.lineWidth;
        ctx.lineJoin = opts.lineJoing || this.lineJoin;
        ctx.lineCap = opts.lineCap || this.lineCap;
        ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle;
        ctx.fillStyle = opts.fillStyle || this.fillStyle;
        ctx.beginPath();
        if (isarc) {
            ctx.arc(points[0], points[1], points[2], points[3], points[4], true);
            if (closePath) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fill();
            }
            else {
                ctx.stroke();
            }
        }
        else if (fillRect) {
            ctx.fillRect(points[0], points[1], points[2], points[3]);
        }
        else if (strokeRect) {
            ctx.strokeRect(points[0], points[1], points[2], points[3]);
        }
        else if (clearRect) {
            ctx.clearRect(points[0], points[1], points[2], points[3]);
        }
        else {
            ctx.moveTo(points[0][0], points[0][1]);
            for (var i = 1; i < points.length; i++) {
                ctx.lineTo(points[i][0], points[i][1]);
            }
            if (closePath) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fill();
            }
            else {
                ctx.stroke();
            }
        }
        ctx.restore();
    };

    // class $.jqplot.TableLegendRenderer
    // The default legend renderer for jqPlot, this class has no options beyond the <Legend> class.
    $.jqplot.TableLegendRenderer = function() {
        //
    };

    $.jqplot.TableLegendRenderer.prototype.init = function(options) {
        $.extend(true, this, options);
    };

    $.jqplot.TableLegendRenderer.prototype.addrow = function(label, color, pad) {
        var rs = (pad) ? this.rowSpacing : '0';
        var tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem);
        $('<td class="jqplot-table-legend" style="text-align:center;padding-top:' + rs + ';">' +
            '<div><div class="jqplot-table-legend-swatch" style="border-color:' + color + ';"></div>' +
            '</div></td>').appendTo(tr);
        var elem = $('<td class="jqplot-table-legend" style="padding-top:' + rs + ';"></td>');
        elem.appendTo(tr);
        if (this.escapeHtml) {
            elem.text(label);
        }
        else {
            elem.html(label);
        }
    };

    // called with scope of legend
    $.jqplot.TableLegendRenderer.prototype.draw = function() {
        var legend = this;
        if (this.show) {
            var series = this._series;
            // make a table.  one line label per row.
            var ss = 'position:absolute;';
            ss += (this.background) ? 'background:' + this.background + ';' : '';
            ss += (this.border) ? 'border:' + this.border + ';' : '';
            ss += (this.fontSize) ? 'font-size:' + this.fontSize + ';' : '';
            ss += (this.fontFamily) ? 'font-family:' + this.fontFamily + ';' : '';
            ss += (this.textColor) ? 'color:' + this.textColor + ';' : '';
            this._elem = $('<table class="jqplot-table-legend" style="' + ss + '"></table>');

            var pad = false;
            for (var i = 0; i < series.length; i++) {
                s = series[i];
                if (s.show && s.showLabel) {
                    var lt = s.label.toString();
                    if (lt) {
                        var color = s.color;
                        if (s._stack && !s.fill) {
                            color = '';
                        }
                        this.renderer.addrow.call(this, lt, color, pad);
                        pad = true;
                    }
                    // let plugins add more rows to legend.  Used by trend line plugin.
                    for (var j = 0; j < $.jqplot.addLegendRowHooks.length; j++) {
                        var item = $.jqplot.addLegendRowHooks[j].call(this, s);
                        if (item) {
                            this.renderer.addrow.call(this, item.label, item.color, pad);
                            pad = true;
                        }
                    }
                }
            }
        }
        return this._elem;
    };

    $.jqplot.TableLegendRenderer.prototype.pack = function(offsets) {
        if (this.show) {
            // fake a grid for positioning
            var grid = { _top: offsets.top, _left: offsets.left, _right: offsets.right, _bottom: this._plotDimensions.height - offsets.bottom };
            switch (this.location) {
                case 'nw':
                    var a = grid._left + this.xoffset;
                    var b = grid._top + this.yoffset;
                    this._elem.css('left', a);
                    this._elem.css('top', b);
                    break;
                case 'n':
                    var a = (offsets.left + (this._plotDimensions.width - offsets.right)) / 2 - this.getWidth() / 2;
                    var b = grid._top + this.yoffset;
                    this._elem.css('left', a);
                    this._elem.css('top', b);
                    break;
                case 'ne':
                    var a = offsets.right + this.xoffset;
                    var b = grid._top + this.yoffset;
                    this._elem.css({ right: a, top: b });
                    break;
                case 'e':
                    var a = offsets.right + this.xoffset;
                    var b = (offsets.top + (this._plotDimensions.height - offsets.bottom)) / 2 - this.getHeight() / 2;
                    this._elem.css({ right: a, top: b });
                    break;
                case 'se':
                    var a = offsets.right + this.xoffset;
                    var b = offsets.bottom + this.yoffset;
                    this._elem.css({ right: a, bottom: b });
                    break;
                case 's':
                    var a = (offsets.left + (this._plotDimensions.width - offsets.right)) / 2 - this.getWidth() / 2;
                    var b = offsets.bottom + this.yoffset;
                    this._elem.css({ left: a, bottom: b });
                    break;
                case 'sw':
                    var a = grid._left + this.xoffset;
                    var b = offsets.bottom + this.yoffset;
                    this._elem.css({ left: a, bottom: b });
                    break;
                case 'w':
                    var a = grid._left + this.xoffset;
                    var b = (offsets.top + (this._plotDimensions.height - offsets.bottom)) / 2 - this.getHeight() / 2;
                    this._elem.css({ left: a, top: b });
                    break;
                default:  // same as 'se'
                    var a = grid._right - this.xoffset;
                    var b = grid._bottom + this.yoffset;
                    this._elem.css({ right: a, bottom: b });
                    break;
            }
        }
    };

    /**
    * JavaScript printf/sprintf functions.
    *
    * This code is unrestricted: you are free to use it however you like.
    * 
    * The functions should work as expected, performing left or right alignment,
    * truncating strings, outputting numbers with a required precision etc.
    *
    * For complex cases, these functions follow the Perl implementations of
    * (s)printf, allowing arguments to be passed out-of-order, and to set the
    * precision or length of the output based on arguments instead of fixed
    * numbers.
    *
    * See http://perldoc.perl.org/functions/sprintf.html for more information.
    *
    * Implemented:
    * - zero and space-padding
    * - right and left-alignment,
    * - base X prefix (binary, octal and hex)
    * - positive number prefix
    * - (minimum) width
    * - precision / truncation / maximum width
    * - out of order arguments
    *
    * Not implemented (yet):
    * - vector flag
    * - size (bytes, words, long-words etc.)
    * 
    * Will not implement:
    * - %n or %p (no pass-by-reference in JavaScript)
    *
    * @version 2007.04.27
    * @author Ash Searle
    */

    /**
    * @Modifications 2009.05.26
    * @author Chris Leonello
    * 
    * Added %p %P specifier
    * Acts like %g or %G but will not add more significant digits to the output than present in the input.
    * Example:
    * Format: '%.3p', Input: 0.012, Output: 0.012
    * Format: '%.3g', Input: 0.012, Output: 0.0120
    * Format: '%.4p', Input: 12.0, Output: 12.0
    * Format: '%.4g', Input: 12.0, Output: 12.00
    * Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5
    * Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5
    */
    $.jqplot.sprintf = function() {
        function pad(str, len, chr, leftJustify) {
            var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
            return leftJustify ? str + padding : padding + str;

        }

        function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) {
            var diff = minWidth - value.length;
            if (diff > 0) {
                var spchar = ' ';
                if (htmlSpace) { spchar = '&nbsp;'; }
                if (leftJustify || !zeroPad) {
                    value = pad(value, minWidth, spchar, leftJustify);
                } else {
                    value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
                }
            }
            return value;
        }

        function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) {
            // Note: casts negative numbers to positive ones
            var number = value >>> 0;
            prefix = prefix && number && { '2': '0b', '8': '0', '16': '0x'}[base] || '';
            value = prefix + pad(number.toString(base), precision || 0, '0', false);
            return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace);
        }

        function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) {
            if (precision != null) {
                value = value.slice(0, precision);
            }
            return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace);
        }

        var a = arguments, i = 0, format = a[i++];

        return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) {
            if (substring == '%%') { return '%'; }

            // parse flags
            var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false;
            for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
                case ' ': positivePrefix = ' '; break;
                case '+': positivePrefix = '+'; break;
                case '-': leftJustify = true; break;
                case '0': zeroPad = true; break;
                case '#': prefixBaseX = true; break;
                case '&': htmlSpace = true; break;
            }

            // parameters may be null, undefined, empty-string or real valued
            // we want to ignore null, undefined and empty-string values

            if (!minWidth) {
                minWidth = 0;
            }
            else if (minWidth == '*') {
                minWidth = +a[i++];
            }
            else if (minWidth.charAt(0) == '*') {
                minWidth = +a[minWidth.slice(1, -1)];
            }
            else {
                minWidth = +minWidth;
            }

            // Note: undocumented perl feature:
            if (minWidth < 0) {
                minWidth = -minWidth;
                leftJustify = true;
            }

            if (!isFinite(minWidth)) {
                throw new Error('$.jqplot.sprintf: (minimum-)width must be finite');
            }

            if (!precision) {
                precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void (0);
            }
            else if (precision == '*') {
                precision = +a[i++];
            }
            else if (precision.charAt(0) == '*') {
                precision = +a[precision.slice(1, -1)];
            }
            else {
                precision = +precision;
            }

            // grab value using valueIndex if required?
            var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];

            switch (type) {
                case 's': 
                    {
                        if (value == null) {
                            return '';
                        }
                        return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace);
                    }
                case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace);
                case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
                case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
                case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
                case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase();
                case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace);
                case 'i':
                case 'd': 
                    {
                        var number = parseInt(+value, 10);
                        if (isNaN(number)) {
                            return '';
                        }
                        var prefix = number < 0 ? '-' : positivePrefix;
                        value = prefix + pad(String(Math.abs(number)), precision, '0', false);
                        return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace);
                    }
                case 'e':
                case 'E':
                case 'f':
                case 'F':
                case 'g':
                case 'G':
                    {
                        var number = +value;
                        if (isNaN(number)) {
                            return '';
                        }
                        var prefix = number < 0 ? '-' : positivePrefix;
                        var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
                        var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
                        value = prefix + Math.abs(number)[method](precision);
                        return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
                    }
                case 'p':
                case 'P':
                    {
                        // make sure number is a number
                        var number = +value;
                        if (isNaN(number)) {
                            return '';
                        }
                        var prefix = number < 0 ? '-' : positivePrefix;

                        var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/);
                        var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length;
                        var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0;

                        if (Math.abs(number) < 1) {
                            if (sd + zeros <= precision) {
                                value = prefix + Math.abs(number).toPrecision(sd);
                            }
                            else {
                                if (sd <= precision - 1) {
                                    value = prefix + Math.abs(number).toExponential(sd - 1);
                                }
                                else {
                                    value = prefix + Math.abs(number).toExponential(precision - 1);
                                }
                            }
                        }
                        else {
                            var prec = (sd <= precision) ? sd : precision;
                            value = prefix + Math.abs(number).toPrecision(prec);
                        }
                        var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2];
                        return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform]();
                    }
                case 'n': return '';
                default: return substring;
            }
        });
    };

    $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0& ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;

})(jQuery);


/**
* Copyright (c) 2009 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects 
* under both the MIT and GPL version 2.0 licenses. This means that you can 
* choose the license that best suits your project and use it accordingly. 
*
* Although not required, the author would appreciate an email letting him 
* know of any substantial use of jqPlot.  You can reach the author at: 
* chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*/
(function(b) { b.jqplot.BarRenderer = function() { b.jqplot.LineRenderer.call(this) }; b.jqplot.BarRenderer.prototype = new b.jqplot.LineRenderer(); b.jqplot.BarRenderer.prototype.constructor = b.jqplot.BarRenderer; b.jqplot.BarRenderer.prototype.init = function(d) { this.barPadding = 8; this.barMargin = 10; this.barDirection = "vertical"; this.barWidth = null; this.shadowOffset = 2; this.shadowDepth = 5; this.shadowAlpha = 0.08; b.extend(true, this, d); this.fill = true; if (this.barDirection == "vertical") { this._primaryAxis = "_xaxis"; this._stackAxis = "y"; this.fillAxis = "y" } else { this._primaryAxis = "_yaxis"; this._stackAxis = "x"; this.fillAxis = "x" } var e = { lineJoin: "miter", lineCap: "round", fill: true, isarc: false, strokeStyle: this.color, fillStyle: this.color, closePath: this.fill }; this.renderer.shapeRenderer.init(e); var c = { lineJoin: "miter", lineCap: "round", fill: true, isarc: false, angle: this.shadowAngle, offset: this.shadowOffset, alpha: this.shadowAlpha, depth: this.shadowDepth, closePath: this.fill }; this.renderer.shadowRenderer.init(c) }; function a(f, e, d, c) { if (this.rendererOptions.barDirection == "horizontal") { this._stackAxis = "x"; this._primaryAxis = "_yaxis" } } b.jqplot.preSeriesInitHooks.push(a); b.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { var g = 0; var h = 0; var f = this[this._primaryAxis]; var e, d, j; for (var c = 0; c < f._series.length; c++) { d = f._series[c]; if (d === this) { j = c } if (d.renderer.constructor == b.jqplot.BarRenderer) { g += d.data.length; h += 1 } } return [g, h, j] }; b.jqplot.BarRenderer.prototype.setBarWidth = function() { var f; var c = 0; var d = 0; var h = this[this._primaryAxis]; var m, g, k; var l = this.renderer.calcSeriesNumbers.call(this); c = l[0]; d = l[1]; var j = h.numberTicks; var e = (j - 1) / 2; if (h.name == "xaxis" || h.name == "x2axis") { if (this._stack) { this.barWidth = (h._offsets.max - h._offsets.min) / c * d - this.barMargin } else { this.barWidth = ((h._offsets.max - h._offsets.min) / e - this.barPadding * (d - 1) - this.barMargin * 2) / d } } else { if (this._stack) { this.barWidth = (h._offsets.min - h._offsets.max) / c * d - this.barMargin } else { this.barWidth = ((h._offsets.min - h._offsets.max) / e - this.barPadding * (d - 1) - this.barMargin * 2) / d } } return [c, d] }; b.jqplot.BarRenderer.prototype.draw = function(t, y, f) { var v; var q = (f != undefined) ? f : {}; var k = (q.shadow != undefined) ? q.shadow : this.shadow; var B = (q.showLine != undefined) ? q.showLine : this.showLine; var u = (q.fill != undefined) ? q.fill : this.fill; var e = this.xaxis; var w = this.yaxis; var n = this._xaxis.series_u2p; var x = this._yaxis.series_u2p; var s, r, m, l, h; if (this.barWidth == null) { this.renderer.setBarWidth.call(this) } var A = this.renderer.calcSeriesNumbers.call(this); m = A[0]; l = A[1]; h = A[2]; if (this._stack) { this._barNudge = 0 } else { this._barNudge = (-Math.abs(l / 2 - 0.5) + h) * (this.barWidth + this.barPadding) } if (B) { var j = new b.jqplot.ColorGenerator(this.negativeSeriesColors); var z = j.get(this.index); var o = false; var p = q.fillStyle; var c; if (this.barDirection == "vertical") { for (var v = 0; v < y.length; v++) { points = []; var g = y[v][0] + this._barNudge; var d; if (this._stack && this._prevGridData.length) { d = this._prevGridData[v][1] } else { if (this.fillToZero) { d = this._yaxis.series_u2p(0) } else { d = t.canvas.height } } if (this.fillToZero && this._plotData[v][1] < 0) { o = true; q.fillStyle = z } else { q.fillStyle = p; o = false } points.push([g - this.barWidth / 2, d]); points.push([g - this.barWidth / 2, y[v][1]]); points.push([g + this.barWidth / 2, y[v][1]]); points.push([g + this.barWidth / 2, d]); if (k && !this._stack) { this.renderer.shadowRenderer.draw(t, points, q) } this.renderer.shapeRenderer.draw(t, points, q) } } else { if (this.barDirection == "horizontal") { for (var v = 0; v < y.length; v++) { points = []; var g = y[v][1] - this._barNudge; var C; if (this._stack && this._prevGridData.length) { C = this._prevGridData[v][0] } else { C = 0 } points.push([C, g + this.barWidth / 2]); points.push([y[v][0], g + this.barWidth / 2]); points.push([y[v][0], g - this.barWidth / 2]); points.push([C, g - this.barWidth / 2]); if (k && !this._stack) { this.renderer.shadowRenderer.draw(t, points, q) } this.renderer.shapeRenderer.draw(t, points, q) } } } } }; b.jqplot.BarRenderer.prototype.drawShadow = function(p, u, e) { var r; var m = (e != undefined) ? e : {}; var h = (m.shadow != undefined) ? m.shadow : this.shadow; var w = (m.showLine != undefined) ? m.showLine : this.showLine; var q = (m.fill != undefined) ? m.fill : this.fill; var d = this.xaxis; var s = this.yaxis; var l = this._xaxis.series_u2p; var t = this._yaxis.series_u2p; var o, n, k, j, g; if (this._stack && this.shadow) { if (this.barWidth == null) { this.renderer.setBarWidth.call(this) } var v = this.renderer.calcSeriesNumbers.call(this); k = v[0]; j = v[1]; g = v[2]; if (this._stack) { this._barNudge = 0 } else { this._barNudge = (-Math.abs(j / 2 - 0.5) + g) * (this.barWidth + this.barPadding) } if (w) { if (this.barDirection == "vertical") { for (var r = 0; r < u.length; r++) { points = []; var f = u[r][0] + this._barNudge; var c; if (this._stack && this._prevGridData.length) { c = this._prevGridData[r][1] } else { if (this.fillToZero) { c = this._yaxis.series_u2p(0) } else { c = p.canvas.height } } points.push([f - this.barWidth / 2, c]); points.push([f - this.barWidth / 2, u[r][1]]); points.push([f + this.barWidth / 2, u[r][1]]); points.push([f + this.barWidth / 2, c]); this.renderer.shadowRenderer.draw(p, points, m) } } else { if (this.barDirection == "horizontal") { for (var r = 0; r < u.length; r++) { points = []; var f = u[r][1] - this._barNudge; var x; if (this._stack && this._prevGridData.length) { x = this._prevGridData[r][0] } else { x = 0 } points.push([x, f + this.barWidth / 2]); points.push([u[r][0], f + this.barWidth / 2]); points.push([u[r][0], f - this.barWidth / 2]); points.push([x, f - this.barWidth / 2]); this.renderer.shadowRenderer.draw(p, points, m) } } } } } } })(jQuery);

/**
* Copyright (c) 2009 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects 
* under both the MIT and GPL version 2.0 licenses. This means that you can 
* choose the license that best suits your project and use it accordingly. 
*
* Although not required, the author would appreciate an email letting him 
* know of any substantial use of jqPlot.  You can reach the author at: 
* chris dot leonello at gmail dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*/
(function(a) { a.jqplot.CategoryAxisRenderer = function() { a.jqplot.LinearAxisRenderer.call(this) }; a.jqplot.CategoryAxisRenderer.prototype = new a.jqplot.LinearAxisRenderer(); a.jqplot.CategoryAxisRenderer.prototype.constructor = a.jqplot.CategoryAxisRenderer; a.jqplot.CategoryAxisRenderer.prototype.init = function(e) { a.extend(true, this, { tickOptions: { formatString: "%d"} }, e); var b = this._dataBounds; for (var f = 0; f < this._series.length; f++) { var g = this._series[f]; var h = g.data; for (var c = 0; c < h.length; c++) { if (this.name == "xaxis" || this.name == "x2axis") { if (h[c][0] < b.min || b.min == null) { b.min = h[c][0] } if (h[c][0] > b.max || b.max == null) { b.max = h[c][0] } } else { if (h[c][1] < b.min || b.min == null) { b.min = h[c][1] } if (h[c][1] > b.max || b.max == null) { b.max = h[c][1] } } } } }; a.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { var y = this._ticks; var v = this.ticks; var B = this.name; var x = this._dataBounds; var p, w; var n, q; var d, c; var b, r; if (v.length) { this.min = 0.5; this.max = v.length + 0.5; var h = this.max - this.min; this.numberTicks = 2 * v.length + 1; for (r = 0; r < v.length; r++) { b = this.min + 2 * r * h / (this.numberTicks - 1); var f = new this.tickRenderer(this.tickOptions); f.showLabel = false; f.showMark = true; f.setTick(b, this.name); this._ticks.push(f); var f = new this.tickRenderer(this.tickOptions); f.label = v[r]; f.showLabel = true; f.showMark = false; f.showGridline = false; f.setTick(b + 0.5, this.name); this._ticks.push(f) } var f = new this.tickRenderer(this.tickOptions); f.showLabel = false; f.showMark = true; f.setTick(b + 1, this.name); this._ticks.push(f) } else { if (B == "xaxis" || B == "x2axis") { p = this._plotDimensions.width } else { p = this._plotDimensions.height } if (this.min != null && this.max != null && this.numberTicks != null) { this.tickInterval = null } if (this.min != null && this.max != null && this.tickInterval != null) { if (parseInt((this.max - this.min) / this.tickInterval, 10) != (this.max - this.min) / this.tickInterval) { this.tickInterval = null } } var u = []; var z = 0; var n = 0.5; var q, A; for (var r = 0; r < this._series.length; r++) { var g = this._series[r]; for (var o = 0; o < g.data.length; o++) { if (this.name == "xaxis" || this.name == "x2axis") { A = g.data[o][0] } else { A = g.data[o][1] } if (a.inArray(A, u) == -1) { z += 1; u.push(A) } } } this.ticks = u; for (var r = 0; r < this._series.length; r++) { var g = this._series[r]; for (var o = 0; o < g.data.length; o++) { if (this.name == "xaxis" || this.name == "x2axis") { A = g.data[o][0] } else { A = g.data[o][1] } var k = a.inArray(A, u) + 1; if (this.name == "xaxis" || this.name == "x2axis") { g.data[o][0] = k } else { g.data[o][1] = k } } } q = z + 0.5; if (this.numberTicks == null) { this.numberTicks = 2 * z + 1 } var h = q - n; this.min = n; this.max = q; var l = 0; var e = parseInt(3 + p / 20, 10); var m = parseInt(z / e, 10); if (this.tickInterval == null) { this.tickInterval = h / (this.numberTicks - 1) } for (var r = 0; r < this.numberTicks; r++) { b = this.min + r * this.tickInterval; var f = new this.tickRenderer(this.tickOptions); if (r / 2 == parseInt(r / 2, 10)) { f.showLabel = false; f.showMark = true } else { if (m > 0 && l < m) { f.showLabel = false; l += 1 } else { f.showLabel = true; l = 0 } f.label = f.formatter(f.formatString, u[(r - 1) / 2]); f.showMark = false; f.showGridline = false } if (!this.showTicks) { f.showLabel = false; f.showMark = false } else { if (!this.showTickMarks) { f.showMark = false } } f.setTick(b, this.name); this._ticks.push(f) } } } })(jQuery);

