Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 140 → Rev 141

/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/excanvas.js
0,0 → 1,1415
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 
 
// Known Issues:
//
// * Patterns only support repeat.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
 
// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {
 
(function() {
 
// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;
 
// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;
 
/**
* This funtion is assigned to the <canvas> elements as element.getContext().
* @this {HTMLElement}
* @return {CanvasRenderingContext2D_}
*/
function getContext() {
return this.context_ ||
(this.context_ = new CanvasRenderingContext2D_(this));
}
 
var slice = Array.prototype.slice;
 
/**
* Binds a function to an object. The returned function will always use the
* passed in {@code obj} as {@code this}.
*
* Example:
*
* g = bind(f, obj, a, b)
* g(c, d) // will do f.call(obj, a, b, c, d)
*
* @param {Function} f The function to bind the object to
* @param {Object} obj The object that should act as this when the function
* is called
* @param {*} var_args Rest arguments that will be used as the initial
* arguments when the function is called
* @return {Function} A new function that has bound this
*/
function bind(f, obj, var_args) {
var a = slice.call(arguments, 2);
return function() {
return f.apply(obj, a.concat(slice.call(arguments)));
};
}
 
function encodeHtmlAttribute(s) {
return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
}
 
function addNamespacesAndStylesheet(doc) {
// create xmlns
if (!doc.namespaces['g_vml_']) {
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
'#default#VML');
 
}
if (!doc.namespaces['g_o_']) {
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
'#default#VML');
}
 
// Setup default CSS. Only add one style sheet per document
if (!doc.styleSheets['ex_canvas_']) {
var ss = doc.createStyleSheet();
ss.owningElement.id = 'ex_canvas_';
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
// default size is 300x150 in Gecko and Opera
'text-align:left;width:300px;height:150px}';
}
}
 
// Add namespaces and stylesheet at startup.
addNamespacesAndStylesheet(document);
 
var G_vmlCanvasManager_ = {
init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
}
},
 
init_: function(doc) {
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
this.initElement(els[i]);
}
},
 
/**
* Public initializes a canvas element so that it can be used as canvas
* element from now on. This is called automatically before the page is
* loaded but if you are creating elements using createElement you need to
* make sure this is called on the element.
* @param {HTMLElement} el The canvas element to initialize.
* @return {HTMLElement} the element that was created.
*/
initElement: function(el) {
if (!el.getContext) {
el.getContext = getContext;
 
// Add namespaces and stylesheet to document of the element.
addNamespacesAndStylesheet(el.ownerDocument);
 
// Remove fallback content. There is no way to hide text nodes so we
// just remove all childNodes. We could hide all elements and remove
// text nodes but who really cares about the fallback content.
el.innerHTML = '';
 
// do not use inline function because that will leak memory
el.attachEvent('onpropertychange', onPropertyChange);
el.attachEvent('onresize', onResize);
 
var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + 'px';
} else {
el.width = el.clientWidth;
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + 'px';
} else {
el.height = el.clientHeight;
}
//el.getContext().setCoordsize_()
}
return el;
}
};
 
function onPropertyChange(e) {
var el = e.srcElement;
 
switch (e.propertyName) {
case 'width':
el.getContext().clearRect();
el.style.width = el.attributes.width.nodeValue + 'px';
// In IE8 this does not trigger onresize.
el.firstChild.style.width = el.clientWidth + 'px';
break;
case 'height':
el.getContext().clearRect();
el.style.height = el.attributes.height.nodeValue + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
break;
}
}
 
function onResize(e) {
var el = e.srcElement;
if (el.firstChild) {
el.firstChild.style.width = el.clientWidth + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
}
}
 
G_vmlCanvasManager_.init();
 
// precompute "00" to "FF"
var decToHex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
 
function createMatrixIdentity() {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
];
}
 
function matrixMultiply(m1, m2) {
var result = createMatrixIdentity();
 
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var sum = 0;
 
for (var z = 0; z < 3; z++) {
sum += m1[x][z] * m2[z][y];
}
 
result[x][y] = sum;
}
}
return result;
}
 
function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha;
o2.font = o1.font;
o2.textAlign = o1.textAlign;
o2.textBaseline = o1.textBaseline;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
}
 
var colorData = {
aliceblue: '#F0F8FF',
antiquewhite: '#FAEBD7',
aquamarine: '#7FFFD4',
azure: '#F0FFFF',
beige: '#F5F5DC',
bisque: '#FFE4C4',
black: '#000000',
blanchedalmond: '#FFEBCD',
blueviolet: '#8A2BE2',
brown: '#A52A2A',
burlywood: '#DEB887',
cadetblue: '#5F9EA0',
chartreuse: '#7FFF00',
chocolate: '#D2691E',
coral: '#FF7F50',
cornflowerblue: '#6495ED',
cornsilk: '#FFF8DC',
crimson: '#DC143C',
cyan: '#00FFFF',
darkblue: '#00008B',
darkcyan: '#008B8B',
darkgoldenrod: '#B8860B',
darkgray: '#A9A9A9',
darkgreen: '#006400',
darkgrey: '#A9A9A9',
darkkhaki: '#BDB76B',
darkmagenta: '#8B008B',
darkolivegreen: '#556B2F',
darkorange: '#FF8C00',
darkorchid: '#9932CC',
darkred: '#8B0000',
darksalmon: '#E9967A',
darkseagreen: '#8FBC8F',
darkslateblue: '#483D8B',
darkslategray: '#2F4F4F',
darkslategrey: '#2F4F4F',
darkturquoise: '#00CED1',
darkviolet: '#9400D3',
deeppink: '#FF1493',
deepskyblue: '#00BFFF',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1E90FF',
firebrick: '#B22222',
floralwhite: '#FFFAF0',
forestgreen: '#228B22',
gainsboro: '#DCDCDC',
ghostwhite: '#F8F8FF',
gold: '#FFD700',
goldenrod: '#DAA520',
grey: '#808080',
greenyellow: '#ADFF2F',
honeydew: '#F0FFF0',
hotpink: '#FF69B4',
indianred: '#CD5C5C',
indigo: '#4B0082',
ivory: '#FFFFF0',
khaki: '#F0E68C',
lavender: '#E6E6FA',
lavenderblush: '#FFF0F5',
lawngreen: '#7CFC00',
lemonchiffon: '#FFFACD',
lightblue: '#ADD8E6',
lightcoral: '#F08080',
lightcyan: '#E0FFFF',
lightgoldenrodyellow: '#FAFAD2',
lightgreen: '#90EE90',
lightgrey: '#D3D3D3',
lightpink: '#FFB6C1',
lightsalmon: '#FFA07A',
lightseagreen: '#20B2AA',
lightskyblue: '#87CEFA',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#B0C4DE',
lightyellow: '#FFFFE0',
limegreen: '#32CD32',
linen: '#FAF0E6',
magenta: '#FF00FF',
mediumaquamarine: '#66CDAA',
mediumblue: '#0000CD',
mediumorchid: '#BA55D3',
mediumpurple: '#9370DB',
mediumseagreen: '#3CB371',
mediumslateblue: '#7B68EE',
mediumspringgreen: '#00FA9A',
mediumturquoise: '#48D1CC',
mediumvioletred: '#C71585',
midnightblue: '#191970',
mintcream: '#F5FFFA',
mistyrose: '#FFE4E1',
moccasin: '#FFE4B5',
navajowhite: '#FFDEAD',
oldlace: '#FDF5E6',
olivedrab: '#6B8E23',
orange: '#FFA500',
orangered: '#FF4500',
orchid: '#DA70D6',
palegoldenrod: '#EEE8AA',
palegreen: '#98FB98',
paleturquoise: '#AFEEEE',
palevioletred: '#DB7093',
papayawhip: '#FFEFD5',
peachpuff: '#FFDAB9',
peru: '#CD853F',
pink: '#FFC0CB',
plum: '#DDA0DD',
powderblue: '#B0E0E6',
rosybrown: '#BC8F8F',
royalblue: '#4169E1',
saddlebrown: '#8B4513',
salmon: '#FA8072',
sandybrown: '#F4A460',
seagreen: '#2E8B57',
seashell: '#FFF5EE',
sienna: '#A0522D',
skyblue: '#87CEEB',
slateblue: '#6A5ACD',
slategray: '#708090',
slategrey: '#708090',
snow: '#FFFAFA',
springgreen: '#00FF7F',
steelblue: '#4682B4',
tan: '#D2B48C',
thistle: '#D8BFD8',
tomato: '#FF6347',
turquoise: '#40E0D0',
violet: '#EE82EE',
wheat: '#F5DEB3',
whitesmoke: '#F5F5F5',
yellowgreen: '#9ACD32'
};
 
 
function getRgbHslContent(styleString) {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var parts = styleString.substring(start + 1, end).split(',');
// add alpha if needed
if (parts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = Number(parts[3]);
} else {
parts[3] = 1;
}
return parts;
}
 
function percent(s) {
return parseFloat(s) / 100;
}
 
function clamp(v, min, max) {
return Math.min(max, Math.max(min, v));
}
 
function hslToRgb(parts){
var r, g, b;
h = parseFloat(parts[0]) / 360 % 360;
if (h < 0)
h++;
s = clamp(percent(parts[1]), 0, 1);
l = clamp(percent(parts[2]), 0, 1);
if (s == 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hueToRgb(p, q, h + 1 / 3);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1 / 3);
}
 
return '#' + decToHex[Math.floor(r * 255)] +
decToHex[Math.floor(g * 255)] +
decToHex[Math.floor(b * 255)];
}
 
function hueToRgb(m1, m2, h) {
if (h < 0)
h++;
if (h > 1)
h--;
 
if (6 * h < 1)
return m1 + (m2 - m1) * 6 * h;
else if (2 * h < 1)
return m2;
else if (3 * h < 2)
return m1 + (m2 - m1) * (2 / 3 - h) * 6;
else
return m1;
}
 
function processStyle(styleString) {
var str, alpha = 1;
 
styleString = String(styleString);
if (styleString.charAt(0) == '#') {
str = styleString;
} else if (/^rgb/.test(styleString)) {
var parts = getRgbHslContent(styleString);
var str = '#', n;
for (var i = 0; i < 3; i++) {
if (parts[i].indexOf('%') != -1) {
n = Math.floor(percent(parts[i]) * 255);
} else {
n = Number(parts[i]);
}
str += decToHex[clamp(n, 0, 255)];
}
alpha = parts[3];
} else if (/^hsl/.test(styleString)) {
var parts = getRgbHslContent(styleString);
str = hslToRgb(parts);
alpha = parts[3];
} else {
str = colorData[styleString] || styleString;
}
return {color: str, alpha: alpha};
}
 
var DEFAULT_STYLE = {
style: 'normal',
variant: 'normal',
weight: 'normal',
size: 10,
family: 'sans-serif'
};
 
// Internal text style cache
var fontStyleCache = {};
 
function processFontStyle(styleString) {
if (fontStyleCache[styleString]) {
return fontStyleCache[styleString];
}
 
var el = document.createElement('div');
var style = el.style;
try {
style.font = styleString;
} catch (ex) {
// Ignore failures to set to invalid font.
}
 
return fontStyleCache[styleString] = {
style: style.fontStyle || DEFAULT_STYLE.style,
variant: style.fontVariant || DEFAULT_STYLE.variant,
weight: style.fontWeight || DEFAULT_STYLE.weight,
size: style.fontSize || DEFAULT_STYLE.size,
family: style.fontFamily || DEFAULT_STYLE.family
};
}
 
function getComputedStyle(style, element) {
var computedStyle = {};
 
for (var p in style) {
computedStyle[p] = style[p];
}
 
// Compute the size
var canvasFontSize = parseFloat(element.currentStyle.fontSize),
fontSize = parseFloat(style.size);
 
if (typeof style.size == 'number') {
computedStyle.size = style.size;
} else if (style.size.indexOf('px') != -1) {
computedStyle.size = fontSize;
} else if (style.size.indexOf('em') != -1) {
computedStyle.size = canvasFontSize * fontSize;
} else if(style.size.indexOf('%') != -1) {
computedStyle.size = (canvasFontSize / 100) * fontSize;
} else if (style.size.indexOf('pt') != -1) {
computedStyle.size = canvasFontSize * (4/3) * fontSize;
} else {
computedStyle.size = canvasFontSize;
}
 
// Different scaling between normal text and VML text. This was found using
// trial and error to get the same size as non VML text.
computedStyle.size *= 0.981;
 
return computedStyle;
}
 
function buildStyle(style) {
return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
style.size + 'px ' + style.family;
}
 
function processLineCap(lineCap) {
switch (lineCap) {
case 'butt':
return 'flat';
case 'round':
return 'round';
case 'square':
default:
return 'square';
}
}
 
/**
* This class implements CanvasRenderingContext2D interface as described by
* the WHATWG.
* @param {HTMLElement} surfaceElement The element that the 2D context should
* be associated with
*/
function CanvasRenderingContext2D_(surfaceElement) {
this.m_ = createMatrixIdentity();
 
this.mStack_ = [];
this.aStack_ = [];
this.currentPath_ = [];
 
// Canvas context properties
this.strokeStyle = '#000';
this.fillStyle = '#000';
 
this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
this.miterLimit = Z * 1;
this.globalAlpha = 1;
this.font = '10px sans-serif';
this.textAlign = 'left';
this.textBaseline = 'alphabetic';
this.canvas = surfaceElement;
 
var el = surfaceElement.ownerDocument.createElement('div');
el.style.width = surfaceElement.clientWidth + 'px';
el.style.height = surfaceElement.clientHeight + 'px';
el.style.overflow = 'hidden';
el.style.position = 'absolute';
surfaceElement.appendChild(el);
 
this.element_ = el;
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
}
 
var contextPrototype = CanvasRenderingContext2D_.prototype;
contextPrototype.clearRect = function() {
if (this.textMeasureEl_) {
this.textMeasureEl_.removeNode(true);
this.textMeasureEl_ = null;
}
this.element_.innerHTML = '';
};
 
contextPrototype.beginPath = function() {
// TODO: Branch current matrix so that save/restore has no effect
// as per safari docs.
this.currentPath_ = [];
};
 
contextPrototype.moveTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
 
contextPrototype.lineTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
 
this.currentX_ = p.x;
this.currentY_ = p.y;
};
 
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
var p = this.getCoords_(aX, aY);
var cp1 = this.getCoords_(aCP1x, aCP1y);
var cp2 = this.getCoords_(aCP2x, aCP2y);
bezierCurveTo(this, cp1, cp2, p);
};
 
// Helper function that takes the already fixed cordinates.
function bezierCurveTo(self, cp1, cp2, p) {
self.currentPath_.push({
type: 'bezierCurveTo',
cp1x: cp1.x,
cp1y: cp1.y,
cp2x: cp2.x,
cp2y: cp2.y,
x: p.x,
y: p.y
});
self.currentX_ = p.x;
self.currentY_ = p.y;
}
 
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
// the following is lifted almost directly from
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
 
var cp = this.getCoords_(aCPx, aCPy);
var p = this.getCoords_(aX, aY);
 
var cp1 = {
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
};
var cp2 = {
x: cp1.x + (p.x - this.currentX_) / 3.0,
y: cp1.y + (p.y - this.currentY_) / 3.0
};
 
bezierCurveTo(this, cp1, cp2, p);
};
 
contextPrototype.arc = function(aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise) {
aRadius *= Z;
var arcType = aClockwise ? 'at' : 'wa';
 
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
 
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
 
// IE won't render arches drawn counter clockwise if xStart == xEnd.
if (xStart == xEnd && !aClockwise) {
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
// that can be represented in binary
}
 
var p = this.getCoords_(aX, aY);
var pStart = this.getCoords_(xStart, yStart);
var pEnd = this.getCoords_(xEnd, yEnd);
 
this.currentPath_.push({type: arcType,
x: p.x,
y: p.y,
radius: aRadius,
xStart: pStart.x,
yStart: pStart.y,
xEnd: pEnd.x,
yEnd: pEnd.y});
 
};
 
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
};
 
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
 
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
 
this.currentPath_ = oldPath;
};
 
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
 
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
 
this.currentPath_ = oldPath;
};
 
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
var gradient = new CanvasGradient_('gradient');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
return gradient;
};
 
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
aX1, aY1, aR1) {
var gradient = new CanvasGradient_('gradientradial');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.r0_ = aR0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
gradient.r1_ = aR1;
return gradient;
};
 
contextPrototype.drawImage = function(image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
 
// to find the original width we overide the width and height
var oldRuntimeWidth = image.runtimeStyle.width;
var oldRuntimeHeight = image.runtimeStyle.height;
image.runtimeStyle.width = 'auto';
image.runtimeStyle.height = 'auto';
 
// get the original size
var w = image.width;
var h = image.height;
 
// and remove overides
image.runtimeStyle.width = oldRuntimeWidth;
image.runtimeStyle.height = oldRuntimeHeight;
 
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
sx = sy = 0;
sw = dw = w;
sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
sx = sy = 0;
sw = w;
sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
sw = arguments[3];
sh = arguments[4];
dx = arguments[5];
dy = arguments[6];
dw = arguments[7];
dh = arguments[8];
} else {
throw Error('Invalid number of arguments');
}
 
var d = this.getCoords_(dx, dy);
 
var w2 = sw / 2;
var h2 = sh / 2;
 
var vmlStr = [];
 
var W = 10;
var H = 10;
 
// For some reason that I've now forgotten, using divs didn't work
vmlStr.push(' <g_vml_:group',
' coordsize="', Z * W, ',', Z * H, '"',
' coordorigin="0,0"' ,
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
 
// If filters are necessary (rotation exists), create them
// filters are bog-slow, so only create them if abbsolutely necessary
// The following check doesn't account for skews (which don't exist
// in the canvas spec (yet) anyway.
 
if (this.m_[0][0] != 1 || this.m_[0][1] ||
this.m_[1][1] != 1 || this.m_[1][0]) {
var filter = [];
 
// Note the 12/21 reversal
filter.push('M11=', this.m_[0][0], ',',
'M12=', this.m_[1][0], ',',
'M21=', this.m_[0][1], ',',
'M22=', this.m_[1][1], ',',
'Dx=', mr(d.x / Z), ',',
'Dy=', mr(d.y / Z), '');
 
// Bounding box calculation (need to minimize displayed area so that
// filters don't waste time on unused pixels.
var max = d;
var c2 = this.getCoords_(dx + dw, dy);
var c3 = this.getCoords_(dx, dy + dh);
var c4 = this.getCoords_(dx + dw, dy + dh);
 
max.x = m.max(max.x, c2.x, c3.x, c4.x);
max.y = m.max(max.y, c2.y, c3.y, c4.y);
 
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
filter.join(''), ", sizingmethod='clip');");
 
} else {
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
}
 
vmlStr.push(' ">' ,
'<g_vml_:image src="', image.src, '"',
' style="width:', Z * dw, 'px;',
' height:', Z * dh, 'px"',
' cropleft="', sx / w, '"',
' croptop="', sy / h, '"',
' cropright="', (w - sx - sw) / w, '"',
' cropbottom="', (h - sy - sh) / h, '"',
' />',
'</g_vml_:group>');
 
this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
};
 
contextPrototype.stroke = function(aFill) {
var lineStr = [];
var lineOpen = false;
 
var W = 10;
var H = 10;
 
lineStr.push('<g_vml_:shape',
' filled="', !!aFill, '"',
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
' coordorigin="0,0"',
' coordsize="', Z * W, ',', Z * H, '"',
' stroked="', !aFill, '"',
' path="');
 
var newSeq = false;
var min = {x: null, y: null};
var max = {x: null, y: null};
 
for (var i = 0; i < this.currentPath_.length; i++) {
var p = this.currentPath_[i];
var c;
 
switch (p.type) {
case 'moveTo':
c = p;
lineStr.push(' m ', mr(p.x), ',', mr(p.y));
break;
case 'lineTo':
lineStr.push(' l ', mr(p.x), ',', mr(p.y));
break;
case 'close':
lineStr.push(' x ');
p = null;
break;
case 'bezierCurveTo':
lineStr.push(' c ',
mr(p.cp1x), ',', mr(p.cp1y), ',',
mr(p.cp2x), ',', mr(p.cp2y), ',',
mr(p.x), ',', mr(p.y));
break;
case 'at':
case 'wa':
lineStr.push(' ', p.type, ' ',
mr(p.x - this.arcScaleX_ * p.radius), ',',
mr(p.y - this.arcScaleY_ * p.radius), ' ',
mr(p.x + this.arcScaleX_ * p.radius), ',',
mr(p.y + this.arcScaleY_ * p.radius), ' ',
mr(p.xStart), ',', mr(p.yStart), ' ',
mr(p.xEnd), ',', mr(p.yEnd));
break;
}
 
 
// TODO: Following is broken for curves due to
// move to proper paths.
 
// Figure out dimensions so we can do gradient fills
// properly
if (p) {
if (min.x == null || p.x < min.x) {
min.x = p.x;
}
if (max.x == null || p.x > max.x) {
max.x = p.x;
}
if (min.y == null || p.y < min.y) {
min.y = p.y;
}
if (max.y == null || p.y > max.y) {
max.y = p.y;
}
}
}
lineStr.push(' ">');
 
if (!aFill) {
appendStroke(this, lineStr);
} else {
appendFill(this, lineStr, min, max);
}
 
lineStr.push('</g_vml_:shape>');
 
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
 
function appendStroke(ctx, lineStr) {
var a = processStyle(ctx.strokeStyle);
var color = a.color;
var opacity = a.alpha * ctx.globalAlpha;
var lineWidth = ctx.lineScale_ * ctx.lineWidth;
 
// VML cannot correctly render a line if the width is less than 1px.
// In that case, we dilute the color to make the line look thinner.
if (lineWidth < 1) {
opacity *= lineWidth;
}
 
lineStr.push(
'<g_vml_:stroke',
' opacity="', opacity, '"',
' joinstyle="', ctx.lineJoin, '"',
' miterlimit="', ctx.miterLimit, '"',
' endcap="', processLineCap(ctx.lineCap), '"',
' weight="', lineWidth, 'px"',
' color="', color, '" />'
);
}
 
function appendFill(ctx, lineStr, min, max) {
var fillStyle = ctx.fillStyle;
var arcScaleX = ctx.arcScaleX_;
var arcScaleY = ctx.arcScaleY_;
var width = max.x - min.x;
var height = max.y - min.y;
if (fillStyle instanceof CanvasGradient_) {
// TODO: Gradients transformed with the transformation matrix.
var angle = 0;
var focus = {x: 0, y: 0};
 
// additional offset
var shift = 0;
// scale factor for offset
var expansion = 1;
 
if (fillStyle.type_ == 'gradient') {
var x0 = fillStyle.x0_ / arcScaleX;
var y0 = fillStyle.y0_ / arcScaleY;
var x1 = fillStyle.x1_ / arcScaleX;
var y1 = fillStyle.y1_ / arcScaleY;
var p0 = ctx.getCoords_(x0, y0);
var p1 = ctx.getCoords_(x1, y1);
var dx = p1.x - p0.x;
var dy = p1.y - p0.y;
angle = Math.atan2(dx, dy) * 180 / Math.PI;
 
// The angle should be a non-negative number.
if (angle < 0) {
angle += 360;
}
 
// Very small angles produce an unexpected result because they are
// converted to a scientific notation string.
if (angle < 1e-6) {
angle = 0;
}
} else {
var p0 = ctx.getCoords_(fillStyle.x0_, fillStyle.y0_);
focus = {
x: (p0.x - min.x) / width,
y: (p0.y - min.y) / height
};
 
width /= arcScaleX * Z;
height /= arcScaleY * Z;
var dimension = m.max(width, height);
shift = 2 * fillStyle.r0_ / dimension;
expansion = 2 * fillStyle.r1_ / dimension - shift;
}
 
// We need to sort the color stops in ascending order by offset,
// otherwise IE won't interpret it correctly.
var stops = fillStyle.colors_;
stops.sort(function(cs1, cs2) {
return cs1.offset - cs2.offset;
});
 
var length = stops.length;
var color1 = stops[0].color;
var color2 = stops[length - 1].color;
var opacity1 = stops[0].alpha * ctx.globalAlpha;
var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
 
var colors = [];
for (var i = 0; i < length; i++) {
var stop = stops[i];
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
}
 
// When colors attribute is used, the meanings of opacity and o:opacity2
// are reversed.
lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
' method="none" focus="100%"',
' color="', color1, '"',
' color2="', color2, '"',
' colors="', colors.join(','), '"',
' opacity="', opacity2, '"',
' g_o_:opacity2="', opacity1, '"',
' angle="', angle, '"',
' focusposition="', focus.x, ',', focus.y, '" />');
} else if (fillStyle instanceof CanvasPattern_) {
if (width && height) {
var deltaLeft = -min.x;
var deltaTop = -min.y;
lineStr.push('<g_vml_:fill',
' position="',
deltaLeft / width * arcScaleX * arcScaleX, ',',
deltaTop / height * arcScaleY * arcScaleY, '"',
' type="tile"',
// TODO: Figure out the correct size to fit the scale.
//' size="', w, 'px ', h, 'px"',
' src="', fillStyle.src_, '" />');
}
} else {
var a = processStyle(ctx.fillStyle);
var color = a.color;
var opacity = a.alpha * ctx.globalAlpha;
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
'" />');
}
}
 
contextPrototype.fill = function() {
this.stroke(true);
};
 
contextPrototype.closePath = function() {
this.currentPath_.push({type: 'close'});
};
 
/**
* @private
*/
contextPrototype.getCoords_ = function(aX, aY) {
var m = this.m_;
return {
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
};
};
 
contextPrototype.save = function() {
var o = {};
copyState(this, o);
this.aStack_.push(o);
this.mStack_.push(this.m_);
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
};
 
contextPrototype.restore = function() {
if (this.aStack_.length) {
copyState(this.aStack_.pop(), this);
this.m_ = this.mStack_.pop();
}
};
 
function matrixIsFinite(m) {
return isFinite(m[0][0]) && isFinite(m[0][1]) &&
isFinite(m[1][0]) && isFinite(m[1][1]) &&
isFinite(m[2][0]) && isFinite(m[2][1]);
}
 
function setM(ctx, m, updateLineScale) {
if (!matrixIsFinite(m)) {
return;
}
ctx.m_ = m;
 
if (updateLineScale) {
// Get the line scale.
// Determinant of this.m_ means how much the area is enlarged by the
// transformation. So its square root can be used as a scale factor
// for width.
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
ctx.lineScale_ = sqrt(abs(det));
}
}
 
contextPrototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
[0, 1, 0],
[aX, aY, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), false);
};
 
contextPrototype.rotate = function(aRot) {
var c = mc(aRot);
var s = ms(aRot);
 
var m1 = [
[c, s, 0],
[-s, c, 0],
[0, 0, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), false);
};
 
contextPrototype.scale = function(aX, aY) {
this.arcScaleX_ *= aX;
this.arcScaleY_ *= aY;
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), true);
};
 
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
var m1 = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
 
setM(this, matrixMultiply(m1, this.m_), true);
};
 
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
var m = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
 
setM(this, m, true);
};
 
/**
* The text drawing function.
* The maxWidth argument isn't taken in account, since no browser supports
* it yet.
*/
contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
var m = this.m_,
delta = 1000,
left = 0,
right = delta,
offset = {x: 0, y: 0},
lineStr = [];
 
var fontStyle = getComputedStyle(processFontStyle(this.font),
this.element_);
 
var fontStyleString = buildStyle(fontStyle);
 
var elementStyle = this.element_.currentStyle;
var textAlign = this.textAlign.toLowerCase();
switch (textAlign) {
case 'left':
case 'center':
case 'right':
break;
case 'end':
textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
break;
case 'start':
textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
break;
default:
textAlign = 'left';
}
 
// 1.75 is an arbitrary number, as there is no info about the text baseline
switch (this.textBaseline) {
case 'hanging':
case 'top':
offset.y = fontStyle.size / 1.75;
break;
case 'middle':
break;
default:
case null:
case 'alphabetic':
case 'ideographic':
case 'bottom':
offset.y = -fontStyle.size / 2.25;
break;
}
 
switch(textAlign) {
case 'right':
left = delta;
right = 0.05;
break;
case 'center':
left = right = delta / 2;
break;
}
 
var d = this.getCoords_(x + offset.x, y + offset.y);
 
lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
' coordsize="100 100" coordorigin="0 0"',
' filled="', !stroke, '" stroked="', !!stroke,
'" style="position:absolute;width:1px;height:1px;">');
 
if (stroke) {
appendStroke(this, lineStr);
} else {
// TODO: Fix the min and max params.
appendFill(this, lineStr, {x: -left, y: 0},
{x: right, y: fontStyle.size});
}
 
var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
 
var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);
 
lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
' offset="', skewOffset, '" origin="', left ,' 0" />',
'<g_vml_:path textpathok="true" />',
'<g_vml_:textpath on="true" string="',
encodeHtmlAttribute(text),
'" style="v-text-align:', textAlign,
';font:', encodeHtmlAttribute(fontStyleString),
'" /></g_vml_:line>');
 
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
 
contextPrototype.fillText = function(text, x, y, maxWidth) {
this.drawText_(text, x, y, maxWidth, false);
};
 
contextPrototype.strokeText = function(text, x, y, maxWidth) {
this.drawText_(text, x, y, maxWidth, true);
};
 
contextPrototype.measureText = function(text) {
if (!this.textMeasureEl_) {
var s = '<span style="position:absolute;' +
'top:-20000px;left:0;padding:0;margin:0;border:none;' +
'white-space:pre;"></span>';
this.element_.insertAdjacentHTML('beforeEnd', s);
this.textMeasureEl_ = this.element_.lastChild;
}
var doc = this.element_.ownerDocument;
this.textMeasureEl_.innerHTML = '';
this.textMeasureEl_.style.font = this.font;
// Don't use innerHTML or innerText because they allow markup/whitespace.
this.textMeasureEl_.appendChild(doc.createTextNode(text));
return {width: this.textMeasureEl_.offsetWidth};
};
 
/******** STUBS ********/
contextPrototype.clip = function() {
// TODO: Implement
};
 
contextPrototype.arcTo = function() {
// TODO: Implement
};
 
contextPrototype.createPattern = function(image, repetition) {
return new CanvasPattern_(image, repetition);
};
 
// Gradient / Pattern Stubs
function CanvasGradient_(aType) {
this.type_ = aType;
this.x0_ = 0;
this.y0_ = 0;
this.r0_ = 0;
this.x1_ = 0;
this.y1_ = 0;
this.r1_ = 0;
this.colors_ = [];
}
 
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
aColor = processStyle(aColor);
this.colors_.push({offset: aOffset,
color: aColor.color,
alpha: aColor.alpha});
};
 
function CanvasPattern_(image, repetition) {
assertImageIsValid(image);
switch (repetition) {
case 'repeat':
case null:
case '':
this.repetition_ = 'repeat';
break
case 'repeat-x':
case 'repeat-y':
case 'no-repeat':
this.repetition_ = repetition;
break;
default:
throwException('SYNTAX_ERR');
}
 
this.src_ = image.src;
this.width_ = image.width;
this.height_ = image.height;
}
 
function throwException(s) {
throw new DOMException_(s);
}
 
function assertImageIsValid(img) {
if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
throwException('TYPE_MISMATCH_ERR');
}
if (img.readyState != 'complete') {
throwException('INVALID_STATE_ERR');
}
}
 
function DOMException_(s) {
this.code = this[s];
this.message = s +': DOM Exception ' + this.code;
}
var p = DOMException_.prototype = new Error;
p.INDEX_SIZE_ERR = 1;
p.DOMSTRING_SIZE_ERR = 2;
p.HIERARCHY_REQUEST_ERR = 3;
p.WRONG_DOCUMENT_ERR = 4;
p.INVALID_CHARACTER_ERR = 5;
p.NO_DATA_ALLOWED_ERR = 6;
p.NO_MODIFICATION_ALLOWED_ERR = 7;
p.NOT_FOUND_ERR = 8;
p.NOT_SUPPORTED_ERR = 9;
p.INUSE_ATTRIBUTE_ERR = 10;
p.INVALID_STATE_ERR = 11;
p.SYNTAX_ERR = 12;
p.INVALID_MODIFICATION_ERR = 13;
p.NAMESPACE_ERR = 14;
p.INVALID_ACCESS_ERR = 15;
p.VALIDATION_ERR = 16;
p.TYPE_MISMATCH_ERR = 17;
 
// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_;
DOMException = DOMException_;
})();
 
} // if
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/index.html
0,0 → 1,80
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
 
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
 
<title>Sysstat Widgets Demo</title>
 
<!--
The widgets are <div> and <span> elements with classes memstat
and loadavg, respectively.
Change the 'url' attribute to point to your web service.
-->
<script language="javascript" type="text/javascript" src="sysstatwidgets.js">
</script>
<script type="text/javascript">
function send(url, rselector) {
var $ = jQuerySysStatWidget;
$.get(url, function (response) {
$(rselector).html(response);
});
}
</script>
</head>
 
<body>
<p>This page display two widgets that display the physical memory
usage and the overall CPU load average of the machine that runs your
web service. Examine the HTML to see how these 'widgets' are embedded
into the page. </p>
<p>
<script>var count = 0;</script>
<a href="#" onclick="javascript:send('/runloop', '#responsemsg');">Click here</a> to run a 15 second loop on this machine (which will result in an increase in the load average).
<span id="responsemsg"></span>
</p>
 
<p>
<a href="#" onclick="javascript:send('/allocanon', '#responsemsg2');">Click here</a> to force allocation of 64MB of physical
memory used as application (anonymous) memory.
<span id="responsemsg2"></span>
</p>
 
<p>
<a href="#" onclick="javascript:send('/freeanon', '#responsemsg3');">Click here</a> to force deallocation of last
chunk of allocated physical memory.
<span id="responsemsg3"></span>
</p>
 
<table>
<tr>
<th>Memory</th>
 
<th>CPU Load Average</th>
</tr>
 
<tr>
<td>
<div id="meminfo" url="http://ec2-107-20-99-126.compute-1.amazonaws.com:80" update="1000"
style="margin-top:20px; margin-left:20px; width:180px; height:400px;">
</div>
</td>
 
<td>
<div id="loadavg" url="http://ec2-107-20-99-126.compute-1.amazonaws.com:80" update="1000"
style="margin-top:20px; margin-left:20px; width:600px; height:400px;">
Loading, please wait...
</div>
</td>
</tr>
</table>
 
<p>A text-only version of the load average widget:
<span class="loadavg-text" url="http://ec2-107-20-99-126.compute-1.amazonaws.com:80" update="1000"
style="font-weight: bold">
</span>
</p>
</body>
</html>
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/jquery.jqplot.js
0,0 → 1,4026
/**
* 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;
 
})(jQuerySysStatWidget || jQuery);
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/jquery.jqplot.min.css
0,0 → 1,0
.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em;}.jqplot-axis{font-size:.75em;}.jqplot-xaxis{margin-top:10px;}.jqplot-x2axis{margin-bottom:10px;}.jqplot-yaxis{margin-right:10px;}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis{margin-left:10px;margin-right:10px;}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{position:absolute;}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top;}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom;}.jqplot-yaxis-tick{right:0;top:15px;text-align:right;}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left;}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute;}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute;}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute;}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;position:absolute;}table.jqplot-table-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em;}td.jqplot-table-legend{vertical-align:middle;}td.jqplot-table-legend>div{border:1px solid #ccc;padding:.2em;}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:.35em;border-bottom-width:.35em;border-left-width:.6em;border-right-width:.6em;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid;}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em;}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-highlighter-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-point-label{font-size:.75em;}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center;}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em;}
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/jquery.min.js
0,0 → 1,154
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(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 X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(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 j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(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)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=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(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.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=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.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);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",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){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},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:ba,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,j,i,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(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;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",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);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,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.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,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.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,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,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){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},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(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();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("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);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 Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(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(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}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 j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[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(Aa," ").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 j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});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 j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("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:bb.test(a.nodeName)||cb.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&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=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;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?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();c.event.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;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.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[G])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){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},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}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};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=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=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?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(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},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.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 fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=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 j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},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)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}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="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.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 l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=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,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||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,l){return!!k(l[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,l,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,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=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 l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=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){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};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=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];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,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=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},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,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(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}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 j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,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(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(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,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.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(qa(a[0])||qa(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);eb.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||gb.test(f))&&fb.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||a.nodeType!==1||!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 Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={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,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);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.text(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){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});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}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},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(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")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(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}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);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});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;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.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=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,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?i():c.swap(a,ob,i);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=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$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(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=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=j}}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 sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,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"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,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||ub.test(this.nodeName)||vb.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(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.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")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=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])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,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(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&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;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("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(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[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||a===0)return this.animate(K("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(K("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 j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});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:K("show",1),slideUp:K("hide",1),slideToggle:K("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(j){return e.step(j)}this.startTime=J();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)&&!W)W=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=J(),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(W);W=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(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;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(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=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!==j;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(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"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],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.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;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});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);
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/plugins/jqplot.barRenderer.js
0,0 → 1,334
/**
* 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.
*
* 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 .
*
* Thanks for using jqPlot!
*
*/
(function($) {
// Class: $.jqplot.BarRenderer
// A plugin renderer for jqPlot to draw a bar plot.
// Draws series as a line.
$.jqplot.BarRenderer = function(){
$.jqplot.LineRenderer.call(this);
};
$.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer();
$.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer;
// called with scope of series.
$.jqplot.BarRenderer.prototype.init = function(options) {
// Group: Properties
//
// prop: barPadding
// Number of pixels between adjacent bars at the same axis value.
this.barPadding = 8;
// prop: barMargin
// Number of pixels between groups of bars at adjacent axis values.
this.barMargin = 10;
// prop: barDirection
// 'vertical' = up and down bars, 'horizontal' = side to side bars
this.barDirection = 'vertical';
// prop: barWidth
// Width of the bar in pixels (auto by devaul). null = calculated automatically.
this.barWidth = null;
// prop: shadowOffset
// offset of the shadow from the slice and offset of
// each succesive stroke of the shadow from the last.
this.shadowOffset = 2;
// prop: shadowDepth
// number of strokes to apply to the shadow,
// each stroke offset shadowOffset from the last.
this.shadowDepth = 5;
// prop: shadowAlpha
// transparency of the shadow (0 = transparent, 1 = opaque)
this.shadowAlpha = 0.08;
$.extend(true, this, options);
// fill is still needed to properly draw the legend.
// bars have to be filled.
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';
}
// set the shape renderer options
var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill};
this.renderer.shapeRenderer.init(opts);
// set the shadow renderer options
var sopts = {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(sopts);
};
// called with scope of series
function barPreInit(target, data, seriesDefaults, options) {
if (this.rendererOptions.barDirection == 'horizontal') {
this._stackAxis = 'x';
this._primaryAxis = '_yaxis';
}
}
$.jqplot.preSeriesInitHooks.push(barPreInit);
// needs to be called with scope of series, not renderer.
$.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() {
var nvals = 0;
var nseries = 0;
var paxis = this[this._primaryAxis];
var s, series, pos;
// loop through all series on this axis
for (var i=0; i < paxis._series.length; i++) {
series = paxis._series[i];
if (series === this) {
pos = i;
}
// is the series rendered as a bar?
if (series.renderer.constructor == $.jqplot.BarRenderer) {
// gridData may not be computed yet, use data length insted
nvals += series.data.length;
nseries += 1;
}
}
return [nvals, nseries, pos];
};
 
$.jqplot.BarRenderer.prototype.setBarWidth = function() {
// need to know how many data values we have on the approprate axis and figure it out.
var i;
var nvals = 0;
var nseries = 0;
var paxis = this[this._primaryAxis];
var s, series, pos;
var temp = this.renderer.calcSeriesNumbers.call(this);
nvals = temp[0];
nseries = temp[1];
var nticks = paxis.numberTicks;
var nbins = (nticks-1)/2;
// so, now we have total number of axis values.
if (paxis.name == 'xaxis' || paxis.name == 'x2axis') {
if (this._stack) {
this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin;
}
else {
this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
// this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries;
}
}
else {
if (this._stack) {
this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin;
}
else {
this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries;
// this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries;
}
}
return [nvals, nseries];
};
$.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, 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 xaxis = this.xaxis;
var yaxis = this.yaxis;
var xp = this._xaxis.series_u2p;
var yp = this._yaxis.series_u2p;
var pointx, pointy, nvals, nseries, pos;
if (this.barWidth == null) {
this.renderer.setBarWidth.call(this);
}
var temp = this.renderer.calcSeriesNumbers.call(this);
nvals = temp[0];
nseries = temp[1];
pos = temp[2];
if (this._stack) {
this._barNudge = 0;
}
else {
this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
}
if (showLine) {
var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors);
var negativeColor = negativeColors.get(this.index);
var isnegative = false;
var posfs = opts.fillStyle;
var tempfs;
if (this.barDirection == 'vertical') {
for (var i=0; i<gridData.length; i++) {
points = [];
var base = gridData[i][0] + this._barNudge;
var ystart;
// stacked
if (this._stack && this._prevGridData.length) {
ystart = this._prevGridData[i][1];
}
// not stacked and first series in stack
else {
if (this.fillToZero) {
ystart = this._yaxis.series_u2p(0);
}
else {
ystart = ctx.canvas.height;
}
}
if (this.fillToZero && this._plotData[i][1] < 0) {
isnegative = true;
opts.fillStyle = negativeColor;
}
else {
opts.fillStyle = posfs;
isnegative = false;
}
points.push([base-this.barWidth/2, ystart]);
points.push([base-this.barWidth/2, gridData[i][1]]);
points.push([base+this.barWidth/2, gridData[i][1]]);
points.push([base+this.barWidth/2, ystart]);
// now draw the shadows if not stacked.
// for stacked plots, they are predrawn by drawShadow
if (shadow && !this._stack) {
this.renderer.shadowRenderer.draw(ctx, points, opts);
}
this.renderer.shapeRenderer.draw(ctx, points, opts);
}
}
else if (this.barDirection == 'horizontal'){
for (var i=0; i<gridData.length; i++) {
points = [];
var base = gridData[i][1] - this._barNudge;
var xstart;
if (this._stack && this._prevGridData.length) {
xstart = this._prevGridData[i][0];
}
else {
xstart = 0;
}
points.push([xstart, base+this.barWidth/2]);
points.push([gridData[i][0], base+this.barWidth/2]);
points.push([gridData[i][0], base-this.barWidth/2]);
points.push([xstart, base-this.barWidth/2]);
// now draw the shadows if not stacked.
// for stacked plots, they are predrawn by drawShadow
if (shadow && !this._stack) {
this.renderer.shadowRenderer.draw(ctx, points, opts);
}
this.renderer.shapeRenderer.draw(ctx, points, opts);
}
}
}
 
};
// for stacked plots, shadows will be pre drawn by drawShadow.
$.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, 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 xaxis = this.xaxis;
var yaxis = this.yaxis;
var xp = this._xaxis.series_u2p;
var yp = this._yaxis.series_u2p;
var pointx, pointy, nvals, nseries, pos;
if (this._stack && this.shadow) {
if (this.barWidth == null) {
this.renderer.setBarWidth.call(this);
}
var temp = this.renderer.calcSeriesNumbers.call(this);
nvals = temp[0];
nseries = temp[1];
pos = temp[2];
if (this._stack) {
this._barNudge = 0;
}
else {
this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding);
}
if (showLine) {
if (this.barDirection == 'vertical') {
for (var i=0; i<gridData.length; i++) {
points = [];
var base = gridData[i][0] + this._barNudge;
var ystart;
if (this._stack && this._prevGridData.length) {
ystart = this._prevGridData[i][1];
}
else {
if (this.fillToZero) {
ystart = this._yaxis.series_u2p(0);
}
else {
ystart = ctx.canvas.height;
}
}
points.push([base-this.barWidth/2, ystart]);
points.push([base-this.barWidth/2, gridData[i][1]]);
points.push([base+this.barWidth/2, gridData[i][1]]);
points.push([base+this.barWidth/2, ystart]);
this.renderer.shadowRenderer.draw(ctx, points, opts);
}
}
else if (this.barDirection == 'horizontal'){
for (var i=0; i<gridData.length; i++) {
points = [];
var base = gridData[i][1] - this._barNudge;
var xstart;
if (this._stack && this._prevGridData.length) {
xstart = this._prevGridData[i][0];
}
else {
xstart = 0;
}
points.push([xstart, base+this.barWidth/2]);
points.push([gridData[i][0], base+this.barWidth/2]);
points.push([gridData[i][0], base-this.barWidth/2]);
points.push([xstart, base-this.barWidth/2]);
this.renderer.shadowRenderer.draw(ctx, points, opts);
}
}
}
}
 
};
})(jQuerySysStatWidget || jQuery);
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/plugins/jqplot.categoryAxisRenderer.js
0,0 → 1,238
/**
* 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.
*
* 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 .
*
* Thanks for using jqPlot!
*
*/
(function($) {
/**
* class: $.jqplot.CategoryAxisRenderer
* A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series.
* This renderer has no options beyond those supplied by the <Axis> class.
*
* To use this renderer, include the plugin in your source
* > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script>
*
* and supply the appropriate options to your plot
*
* > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}}
**/
$.jqplot.CategoryAxisRenderer = function() {
$.jqplot.LinearAxisRenderer.call(this);
};
$.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
$.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer;
$.jqplot.CategoryAxisRenderer.prototype.init = function(options){
// prop: tickRenderer
// A class of a rendering engine for creating the ticks labels displayed on the plot,
// See <$.jqplot.AxisTickRenderer>.
// this.tickRenderer = $.jqplot.AxisTickRenderer;
// this.labelRenderer = $.jqplot.AxisLabelRenderer;
$.extend(true, this, {tickOptions:{formatString:'%d'}}, 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.data;
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];
}
}
}
}
};
 
$.jqplot.CategoryAxisRenderer.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.
if (userTicks.length) {
this.min = 0.5;
this.max = userTicks.length + 0.5;
var range = this.max - this.min;
this.numberTicks = 2*userTicks.length + 1;
for (i=0; i<userTicks.length; i++){
tt = this.min + 2 * i * range / (this.numberTicks-1);
// need a marker before and after the tick
var t = new this.tickRenderer(this.tickOptions);
t.showLabel = false;
t.showMark = true;
t.setTick(tt, this.name);
this._ticks.push(t);
var t = new this.tickRenderer(this.tickOptions);
t.label = userTicks[i];
t.showLabel = true;
t.showMark = false;
t.showGridline = false;
t.setTick(tt+0.5, this.name);
this._ticks.push(t);
}
// now add the last tick at the end
var t = new this.tickRenderer(this.tickOptions);
t.showLabel = false;
t.showMark = true;
t.setTick(tt+1, this.name);
this._ticks.push(t);
}
 
// 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.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;
}
}
// find out how many categories are in the lines and collect labels
var labels = [];
var numcats = 0;
var min = 0.5;
var max, val;
for (var i=0; i<this._series.length; i++) {
var s = this._series[i];
for (var j=0; j<s.data.length; j++) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
val = s.data[j][0];
}
else {
val = s.data[j][1];
}
if ($.inArray(val, labels) == -1) {
numcats += 1;
labels.push(val);
}
}
}
// keep a reference to these tick labels to use for redrawing plot (see bug #57)
this.ticks = labels;
// now bin the data values to the right lables.
for (var i=0; i<this._series.length; i++) {
var s = this._series[i];
for (var j=0; j<s.data.length; j++) {
if (this.name == 'xaxis' || this.name == 'x2axis') {
val = s.data[j][0];
}
else {
val = s.data[j][1];
}
// for category axis, force the values into category bins.
// we should have the value in the label array now.
var idx = $.inArray(val, labels)+1;
if (this.name == 'xaxis' || this.name == 'x2axis') {
s.data[j][0] = idx;
}
else {
s.data[j][1] = idx;
}
}
}
max = numcats + 0.5;
if (this.numberTicks == null) {
this.numberTicks = 2*numcats + 1;
}
 
var range = max - min;
this.min = min;
this.max = max;
var track = 0;
// todo: adjust this so more ticks displayed.
var maxVisibleTicks = parseInt(3+dim/20, 10);
var skip = parseInt(numcats/maxVisibleTicks, 10);
 
if (this.tickInterval == null) {
 
this.tickInterval = range / (this.numberTicks-1);
 
}
// if tickInterval is specified, we will ignore any computed maximum.
for (var i=0; i<this.numberTicks; i++){
tt = this.min + i * this.tickInterval;
var t = new this.tickRenderer(this.tickOptions);
// if even tick, it isn't a category, it's a divider
if (i/2 == parseInt(i/2, 10)) {
t.showLabel = false;
t.showMark = true;
}
else {
if (skip>0 && track<skip) {
t.showLabel = false;
track += 1;
}
else {
t.showLabel = true;
track = 0;
}
t.label = t.formatter(t.formatString, labels[(i-1)/2]);
t.showMark = false;
t.showGridline = false;
}
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);
}
}
};
})(jQuerySysStatWidget || jQuery);
/Classwork/CS3214 - Computer Systems/Project 5 - Web Service/webfiles/sysstatwidgets.js
0,0 → 1,272
/*
* Widgets that plot data obtained from the sys stat web service.
*
* Supports
*
* <div id="meminfo"> </div>
* <div id="loadavg"> </div>
*
* Written by Godmar Back for CS 3214 Fall 2009
*/
(function () {
 
var jqplotbase = "/files/";
 
// loadScript taken from
// http://devblog.techhead.biz/2009/04/dynamically-load-external-javascript-in.html
// (code mirrors $.getScript)
function loadScript(src, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var loaded = false;
script.setAttribute('src', src);
script.onload = script.onreadystatechange = function() {
if (!loaded && (!this.readyState || this.readyState == 'complete'
|| this.readyState == 'loaded') ) {
loaded = true;
callback();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
}
head.appendChild(script);
}
 
/*
* A Delayer object invokes a callback passed to the constructor
* after the following two conditions are true:
* - every function returned from a call to add() has been called
* - the ready() method has been called.
*/
var Delayer = function (cb) {
var count = 0;
var finalized = false;
 
this.add = function () {
count++;
 
return function () {
count--;
if (count == 0 && finalized)
cb();
}
}
 
this.ready = function () {
finalized = true;
if (count == 0)
cb();
}
}
 
function dowithJQuery($) {
 
function updateLoadaveragePlot(plot, divid, value, nvalues, title) {
if (plot) {
var data = plot.series[0].data;
for (var i = 0; i < data.length - 1; i++)
data[i][1] = data[i+1][1];
data[i][1] = value;
 
var ymax = 1.0;
$.each(data, function (index, el) {
if (el[1] > ymax) ymax = el[1];
});
 
plot.axes.yaxis.max = ymax;
plot.title.text = title;
plot.replot();
return plot;
}
 
var data = [value];
for (var i = 2; i < nvalues; i++)
data.push(0.0);
 
return $.jqplot(divid, [data], {
seriesDefaults:{neighborThreshold:0, showMarker: false},
series:[
{
fill: true, fillAlpha:0.8,
shadow:false, showLabel: false,
}
],
legend: {
location:'nw',
xoffset: 310,
yoffset: 100
},
axesDefaults:{
autoscale: true,
useSeriesColor: true
},
title : title,
axes: {
yaxis: {
tickOptions: {formatString:"%.1f"},
min: -0.001
},
xaxis: {
min: 1, max: nvalues,
showTicks: false
}
}
});
}
 
function showMemory(plot, divid, vallabel, axismax, title) {
 
if (plot) {
for (var i = 0; i < vallabel.length; i++)
plot.series[i].data[0][1] = vallabel[i].value;
 
plot.axes.yaxis.max = axismax;
plot.replot();
return plot;
}
 
var data = [];
for (var i = 0; i < vallabel.length; i++)
data.push([ vallabel[i].value ]);
 
var labels = [];
for (var i = 0; i < vallabel.length; i++)
labels.push({ label: vallabel[i].label });
 
return $.jqplot(divid, data, {
seriesColors: [ "#8B3A3A", "#CD5555", "#000080", "#008B00" ],
stackSeries: true,
legend: {
show: true,
location: 'nw',
// xoffset: 115
},
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barPadding: 2,
barMargin: 10
}
},
series: labels,
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: [title]
},
yaxis: {
numberTicks: 6,
tickOptions: {
formatString: "%.0dM"
},
min: 0,
max: axismax
}
}
});
}
 
function renderWidgets($) {
$('#meminfo').each(function () {
var $div = $(this);
var url = $div.attr('url');
var updateInterval = Number($div.attr('update'));
var plot = undefined;
 
function update () {
$.getJSON(url + "/meminfo?callback=?", function (data) {
var MB = 1024;
plot = showMemory(plot, $div.attr('id'),
[
{ value: data.Cached / MB, label: "Cached" },
{ value: data.Buffers / MB, label: "Buffers" },
{ value: (data.MemTotal
- data.MemFree
- data.Cached
- data.Buffers) / MB, label: "Anonymous" },
{ value: data.MemFree / MB, label: "Free" }
],
data.MemTotal / MB, url.match(/http:\/\/(.*):\d+/)[1]
);
});
}
update ();
setInterval(update, updateInterval);
});
 
$('.loadavg-text').each(function () {
var $span = $(this);
var url = $span.attr('url');
var updateInterval = Number($span.attr('update'));
 
function update () {
$.getJSON(url + "/loadavg?callback=?", function (data) {
$span.text(
"Load Average: " + data.loadavg.join(" ")
+ " Threads: " + data.running_threads
+ "/" + data.total_threads
);
});
}
update ();
setInterval(update, updateInterval);
});
 
$('#loadavg').each(function () {
var $div = $(this);
var url = $div.attr('url');
var updateInterval = Number($div.attr('update'));
var plot = undefined;
 
function update () {
$.getJSON(url + "/loadavg?callback=?", function (data) {
plot = updateLoadaveragePlot(
plot, $div.attr('id'), Number(data.loadavg[0]),
$div.width(), // # values, 1 per pixel
url.match(/http:\/\/(.*):\d+/)[1] + ": " +
data.running_threads + "/" + data.total_threads);
});
}
update ();
setInterval(update, updateInterval);
});
};
 
var delay = new Delayer(function () {
renderWidgets($);
});
 
$('head').append('<link rel="stylesheet" type="text/css"'
+' href="' + jqplotbase + 'jquery.jqplot.min.css" />');
 
if ($.browser.msie)
$.getScript(jqplotbase + "excanvas.js", delay.add());
 
var jqplotloaded = delay.add();
$.getScript(jqplotbase + "jquery.jqplot.js", function () {
$.each([ "plugins/jqplot.barRenderer.js",
"plugins/jqplot.categoryAxisRenderer.js"
],
function (index, jsfile) {
$.getScript(jqplotbase + jsfile, delay.add());
});
 
jqplotloaded();
});
 
$(document).ready(delay.add());
delay.ready();
}
 
loadScript(
jqplotbase + 'jquery.min.js',
function() {
// rename jQuery to jQuerySysStatWidget, remove both reference
// to jQuery and $; the jqplot plug-ins were changed to attach to
// jQuerySysStatWidget instead of jQuery
jQuerySysStatWidget = jQuery.noConflict(true);
dowithJQuery(jQuerySysStatWidget);
}
);
 
}) ();