definicao de layout

This commit is contained in:
2026-02-06 14:37:54 +00:00
parent 872a5bb3ea
commit a4f80c85c2
2686 changed files with 640668 additions and 294 deletions

124
public/assets/js/chart/Chart.js vendored Normal file
View File

@@ -0,0 +1,124 @@
Chart.elements.Rectangle.prototype.draw = function() {
var ctx = this._chart.ctx;
var vm = this._view;
var left, right, top, bottom, signX, signY, borderSkipped, radius;
var borderWidth = vm.borderWidth;
// Set Radius Here
// If radius is large enough to cause drawing errors a max radius is imposed
var cornerRadius = 20;
if (!vm.horizontal) {
// bar
left = vm.x - vm.width / 2;
right = vm.x + vm.width / 2;
top = vm.y;
bottom = vm.base;
signX = 1;
signY = bottom > top? 1: -1;
borderSkipped = vm.borderSkipped || 'bottom';
} else {
// horizontal bar
left = vm.base;
right = vm.x;
top = vm.y - vm.height / 2;
bottom = vm.y + vm.height / 2;
signX = right > left? 1: -1;
signY = 1;
borderSkipped = vm.borderSkipped || 'left';
}
// Canvas doesn't allow us to stroke inside the width so we can
// adjust the sizes to fit if we're setting a stroke on the line
if (borderWidth) {
// borderWidth shold be less than bar width and bar height.
var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
borderWidth = borderWidth > barSize? barSize: borderWidth;
var halfStroke = borderWidth / 2;
// Adjust borderWidth when bar top position is near vm.base(zero).
var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
// not become a vertical line?
if (borderLeft !== borderRight) {
top = borderTop;
bottom = borderBottom;
}
// not become a horizontal line?
if (borderTop !== borderBottom) {
left = borderLeft;
right = borderRight;
}
}
ctx.beginPath();
ctx.fillStyle = vm.backgroundColor;
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = borderWidth;
// Corner points, from bottom-left to bottom-right clockwise
// | 1 2 |
// | 0 3 |
var corners = [
[left, bottom],
[left, top],
[right, top],
[right, bottom]
];
// Find first (starting) corner with fallback to 'bottom'
var borders = ['bottom', 'left', 'top', 'right'];
var startCorner = borders.indexOf(borderSkipped, 0);
if (startCorner === -1) {
startCorner = 0;
}
function cornerAt(index) {
return corners[(startCorner + index) % 4];
}
// Draw rectangle from 'startCorner'
var corner = cornerAt(0);
ctx.moveTo(corner[0], corner[1]);
for (var i = 1; i < 4; i++) {
corner = cornerAt(i);
nextCornerId = i+1;
if(nextCornerId == 4){
nextCornerId = 0
}
nextCorner = cornerAt(nextCornerId);
width = corners[2][0] - corners[1][0];
height = corners[0][1] - corners[1][1];
x = corners[1][0];
y = corners[1][1];
var radius = cornerRadius;
// Fix radius being too large
if(radius > height/2){
radius = height/2;
}if(radius > width/2){
radius = width/2;
}
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
}
ctx.fill();
if (borderWidth) {
ctx.stroke();
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,347 @@
var series =
{
"monthDataSeries1": {
"prices": [
8107.85,
8128.0,
8122.9,
8165.5,
8340.7,
8423.7,
8423.5,
8514.3,
8481.85,
8487.7,
8506.9,
8626.2,
8668.95,
8602.3,
8607.55,
8512.9,
8496.25,
8600.65,
8881.1,
9340.85
],
"dates": [
"13 Nov 2017",
"14 Nov 2017",
"15 Nov 2017",
"16 Nov 2017",
"17 Nov 2017",
"20 Nov 2017",
"21 Nov 2017",
"22 Nov 2017",
"23 Nov 2017",
"24 Nov 2017",
"27 Nov 2017",
"28 Nov 2017",
"29 Nov 2017",
"30 Nov 2017",
"01 Dec 2017",
"04 Dec 2017",
"05 Dec 2017",
"06 Dec 2017",
"07 Dec 2017",
"08 Dec 2017"
]
},
"monthDataSeries2": {
"prices": [
8423.7,
8423.5,
8514.3,
8481.85,
8487.7,
8506.9,
8626.2,
8668.95,
8602.3,
8607.55,
8512.9,
8496.25,
8600.65,
8881.1,
9040.85,
8340.7,
8165.5,
8122.9,
8107.85,
8128.0
],
"dates": [
"13 Nov 2017",
"14 Nov 2017",
"15 Nov 2017",
"16 Nov 2017",
"17 Nov 2017",
"20 Nov 2017",
"21 Nov 2017",
"22 Nov 2017",
"23 Nov 2017",
"24 Nov 2017",
"27 Nov 2017",
"28 Nov 2017",
"29 Nov 2017",
"30 Nov 2017",
"01 Dec 2017",
"04 Dec 2017",
"05 Dec 2017",
"06 Dec 2017",
"07 Dec 2017",
"08 Dec 2017"
]
},
"monthDataSeries3": {
"prices": [
7114.25,
7126.6,
7116.95,
7203.7,
7233.75,
7451.0,
7381.15,
7348.95,
7347.75,
7311.25,
7266.4,
7253.25,
7215.45,
7266.35,
7315.25,
7237.2,
7191.4,
7238.95,
7222.6,
7217.9,
7359.3,
7371.55,
7371.15,
7469.2,
7429.25,
7434.65,
7451.1,
7475.25,
7566.25,
7556.8,
7525.55,
7555.45,
7560.9,
7490.7,
7527.6,
7551.9,
7514.85,
7577.95,
7592.3,
7621.95,
7707.95,
7859.1,
7815.7,
7739.0,
7778.7,
7839.45,
7756.45,
7669.2,
7580.45,
7452.85,
7617.25,
7701.6,
7606.8,
7620.05,
7513.85,
7498.45,
7575.45,
7601.95,
7589.1,
7525.85,
7569.5,
7702.5,
7812.7,
7803.75,
7816.3,
7851.15,
7912.2,
7972.8,
8145.0,
8161.1,
8121.05,
8071.25,
8088.2,
8154.45,
8148.3,
8122.05,
8132.65,
8074.55,
7952.8,
7885.55,
7733.9,
7897.15,
7973.15,
7888.5,
7842.8,
7838.4,
7909.85,
7892.75,
7897.75,
7820.05,
7904.4,
7872.2,
7847.5,
7849.55,
7789.6,
7736.35,
7819.4,
7875.35,
7871.8,
8076.5,
8114.8,
8193.55,
8217.1,
8235.05,
8215.3,
8216.4,
8301.55,
8235.25,
8229.75,
8201.95,
8164.95,
8107.85,
8128.0,
8122.9,
8165.5,
8340.7,
8423.7,
8423.5,
8514.3,
8481.85,
8487.7,
8506.9,
8626.2
],
"dates": [
"02 Jun 2017",
"05 Jun 2017",
"06 Jun 2017",
"07 Jun 2017",
"08 Jun 2017",
"09 Jun 2017",
"12 Jun 2017",
"13 Jun 2017",
"14 Jun 2017",
"15 Jun 2017",
"16 Jun 2017",
"19 Jun 2017",
"20 Jun 2017",
"21 Jun 2017",
"22 Jun 2017",
"23 Jun 2017",
"27 Jun 2017",
"28 Jun 2017",
"29 Jun 2017",
"30 Jun 2017",
"03 Jul 2017",
"04 Jul 2017",
"05 Jul 2017",
"06 Jul 2017",
"07 Jul 2017",
"10 Jul 2017",
"11 Jul 2017",
"12 Jul 2017",
"13 Jul 2017",
"14 Jul 2017",
"17 Jul 2017",
"18 Jul 2017",
"19 Jul 2017",
"20 Jul 2017",
"21 Jul 2017",
"24 Jul 2017",
"25 Jul 2017",
"26 Jul 2017",
"27 Jul 2017",
"28 Jul 2017",
"31 Jul 2017",
"01 Aug 2017",
"02 Aug 2017",
"03 Aug 2017",
"04 Aug 2017",
"07 Aug 2017",
"08 Aug 2017",
"09 Aug 2017",
"10 Aug 2017",
"11 Aug 2017",
"14 Aug 2017",
"16 Aug 2017",
"17 Aug 2017",
"18 Aug 2017",
"21 Aug 2017",
"22 Aug 2017",
"23 Aug 2017",
"24 Aug 2017",
"28 Aug 2017",
"29 Aug 2017",
"30 Aug 2017",
"31 Aug 2017",
"01 Sep 2017",
"04 Sep 2017",
"05 Sep 2017",
"06 Sep 2017",
"07 Sep 2017",
"08 Sep 2017",
"11 Sep 2017",
"12 Sep 2017",
"13 Sep 2017",
"14 Sep 2017",
"15 Sep 2017",
"18 Sep 2017",
"19 Sep 2017",
"20 Sep 2017",
"21 Sep 2017",
"22 Sep 2017",
"25 Sep 2017",
"26 Sep 2017",
"27 Sep 2017",
"28 Sep 2017",
"29 Sep 2017",
"03 Oct 2017",
"04 Oct 2017",
"05 Oct 2017",
"06 Oct 2017",
"09 Oct 2017",
"10 Oct 2017",
"11 Oct 2017",
"12 Oct 2017",
"13 Oct 2017",
"16 Oct 2017",
"17 Oct 2017",
"18 Oct 2017",
"19 Oct 2017",
"23 Oct 2017",
"24 Oct 2017",
"25 Oct 2017",
"26 Oct 2017",
"27 Oct 2017",
"30 Oct 2017",
"31 Oct 2017",
"01 Nov 2017",
"02 Nov 2017",
"03 Nov 2017",
"06 Nov 2017",
"07 Nov 2017",
"08 Nov 2017",
"09 Nov 2017",
"10 Nov 2017",
"13 Nov 2017",
"14 Nov 2017",
"15 Nov 2017",
"16 Nov 2017",
"17 Nov 2017",
"20 Nov 2017",
"21 Nov 2017",
"22 Nov 2017",
"23 Nov 2017",
"24 Nov 2017",
"27 Nov 2017",
"28 Nov 2017"
]
}
}

View File

@@ -0,0 +1,347 @@
(function($) {
"use strict";
new Chartist.Line('.ct-1', {
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
series: [
[12, 9, 7, 8, 5],
[2, 1, 3.5, 7, 3],
[1, 3, 4, 5, 6]
]
}, {
fullWidth: true,
chartPadding: {
right: 40
}
});
var chart = new Chartist.Line('.ct-2', {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
series: [
[5, 5, 10, 8, 7, 5, 4, null, null, null, 10, 10, 7, 8, 6, 9],
[10, 15, null, 12, null, 10, 12, 15, null, null, 12, null, 14, null, null, null],
[null, null, null, null, 3, 4, 1, 3, 4, 6, 7, 9, 5, null, null, null],
[{x:3, y: 3},{x: 4, y: 3}, {x: 5, y: undefined}, {x: 6, y: 4}, {x: 7, y: null}, {x: 8, y: 4}, {x: 9, y: 4}]
]
}, {
fullWidth: true,
chartPadding: {
right: 10
},
low: 0
});
var chart = new Chartist.Line('.ct-3', {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
series: [
[5, 5, 10, 8, 7, 5, 4, null, null, null, 10, 10, 7, 8, 6, 9],
[10, 15, null, 12, null, 10, 12, 15, null, null, 12, null, 14, null, null, null],
[null, null, null, null, 3, 4, 1, 3, 4, 6, 7, 9, 5, null, null, null],
[{x:3, y: 3},{x: 4, y: 3}, {x: 5, y: undefined}, {x: 6, y: 4}, {x: 7, y: null}, {x: 8, y: 4}, {x: 9, y: 4}]
]
}, {
fullWidth: true,
chartPadding: {
right: 10
},
lineSmooth: Chartist.Interpolation.cardinal({
fillHoles: true,
}),
low: 0
});
new Chartist.Line('.ct-4', {
labels: [1, 2, 3, 4, 5, 6, 7, 8],
series: [
[5, 9, 7, 8, 5, 3, 5, 4]
]
}, {
low: 0,
showArea: true
});
new Chartist.Line('.ct-5', {
labels: [1, 2, 3, 4, 5, 6, 7, 8],
series: [
[1, 2, 3, 1, -2, 0, 1, 0],
[-2, -1, -2, -1, -2.5, -1, -2, -1],
[0, 0, 0, 1, 2, 2.5, 2, 1],
[2.5, 2, 1, 0.5, 1, 0.5, -1, -2.5]
]
}, {
high: 3,
low: -3,
showArea: true,
showLine: false,
showPoint: false,
fullWidth: true,
axisX: {
showLabel: false,
showGrid: false
}
});
var chart = new Chartist.Line('.ct-6', {
labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
series: [
[12, 9, 7, 8, 5, 4, 6, 2, 3, 3, 4, 6],
[4, 5, 3, 7, 3, 5, 5, 3, 4, 4, 5, 5],
[5, 3, 4, 5, 6, 3, 3, 4, 5, 6, 3, 4],
[3, 4, 5, 6, 7, 6, 4, 5, 6, 7, 6, 3]
]
}, {
low: 0
});
var seq = 0,
delays = 80,
durations = 500;
chart.on('created', function() {
seq = 0;
});
chart.on('draw', function(data) {
seq++;
if(data.type === 'line') {
data.element.animate({
opacity: {
begin: seq * delays + 1000,
dur: durations,
from: 0,
to: 1
}
});
} else if(data.type === 'label' && data.axis === 'x') {
data.element.animate({
y: {
begin: seq * delays,
dur: durations,
from: data.y + 100,
to: data.y,
easing: 'easeOutQuart'
}
});
} else if(data.type === 'label' && data.axis === 'y') {
data.element.animate({
x: {
begin: seq * delays,
dur: durations,
from: data.x - 100,
to: data.x,
easing: 'easeOutQuart'
}
});
} else if(data.type === 'point') {
data.element.animate({
x1: {
begin: seq * delays,
dur: durations,
from: data.x - 10,
to: data.x,
easing: 'easeOutQuart'
},
x2: {
begin: seq * delays,
dur: durations,
from: data.x - 10,
to: data.x,
easing: 'easeOutQuart'
},
opacity: {
begin: seq * delays,
dur: durations,
from: 0,
to: 1,
easing: 'easeOutQuart'
}
});
} else if(data.type === 'grid') {
var pos1Animation = {
begin: seq * delays,
dur: durations,
from: data[data.axis.units.pos + '1'] - 30,
to: data[data.axis.units.pos + '1'],
easing: 'easeOutQuart'
};
var pos2Animation = {
begin: seq * delays,
dur: durations,
from: data[data.axis.units.pos + '2'] - 100,
to: data[data.axis.units.pos + '2'],
easing: 'easeOutQuart'
};
var animations = {};
animations[data.axis.units.pos + '1'] = pos1Animation;
animations[data.axis.units.pos + '2'] = pos2Animation;
animations['opacity'] = {
begin: seq * delays,
dur: durations,
from: 0,
to: 1,
easing: 'easeOutQuart'
};
data.element.animate(animations);
}
});
chart.on('created', function() {
if(window.__exampleAnimateTimeout) {
clearTimeout(window.__exampleAnimateTimeout);
window.__exampleAnimateTimeout = null;
}
window.__exampleAnimateTimeout = setTimeout(chart.update.bind(chart), 12000);
});
var chart = new Chartist.Line('.ct-7', {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
series: [
[1, 5, 2, 5, 4, 3],
[2, 3, 4, 8, 1, 2],
[5, 4, 3, 2, 1, 0.5]
]
}, {
low: 0,
showArea: true,
showPoint: false,
fullWidth: true
});
chart.on('draw', function(data) {
if(data.type === 'line' || data.type === 'area') {
data.element.animate({
d: {
begin: 2000 * data.index,
dur: 2000,
from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height()).stringify(),
to: data.path.clone().stringify(),
easing: Chartist.Svg.Easing.easeOutQuint
}
});
}
});
var chart = new Chartist.Pie('.ct-8', {
series: [10, 20, 50, 20, 5, 50, 15],
labels: [1, 2, 3, 4, 5, 6, 7]
}, {
donut: true,
showLabel: false
});
chart.on('draw', function(data) {
if(data.type === 'slice') {
var pathLength = data.element._node.getTotalLength();
data.element.attr({
'stroke-dasharray': pathLength + 'px ' + pathLength + 'px'
});
var animationDefinition = {
'stroke-dashoffset': {
id: 'anim' + data.index,
dur: 1000,
from: -pathLength + 'px',
to: '0px',
easing: Chartist.Svg.Easing.easeOutQuint,
fill: 'freeze'
}
};
if(data.index !== 0) {
animationDefinition['stroke-dashoffset'].begin = 'anim' + (data.index - 1) + '.end';
}
data.element.attr({
'stroke-dashoffset': -pathLength + 'px'
});
data.element.animate(animationDefinition, false);
}
});
chart.on('created', function() {
if(window.__anim21278907124) {
clearTimeout(window.__anim21278907124);
window.__anim21278907124 = null;
}
window.__anim21278907124 = setTimeout(chart.update.bind(chart), 10000);
});
var data = {
labels: ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10'],
series: [
[1, 2, 4, 8, 6, -2, -1, -4, -6, -2]
]
};
var options = {
high: 10,
low: -10,
axisX: {
labelInterpolationFnc: function(value, index) {
return index % 2 === 0 ? value : null;
}
}
};
new Chartist.Bar('.ct-9', data, options);
new Chartist.Bar('.ct-10', {
labels: ['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6', 'Q7', 'Q8', 'Q9', 'Q10', 'Q11', 'Q13', 'Q14'],
series: [
[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300],
[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300],
[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300]
]
}, {
stackBars: true,
axisY: {
labelInterpolationFnc: function(value) {
return (value / 1000) + 'k';
}
}
}).on('draw', function(data) {
if(data.type === 'bar') {
data.element.attr({
style: 'stroke-width: 14px'
});
}
});
new Chartist.Bar('.ct-11', {
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
series: [
[5, 4, 3, 7, 5, 10, 3],
[3, 2, 9, 5, 4, 6, 4]
]
}, {
seriesBarDistance: 10,
reverseData: true,
horizontalBars: true,
axisY: {
offset: 70
}
});
new Chartist.Bar('.ct-12', {
labels: ['2010-11', '2011-12', '2012-13', '2013-13', '2014-15', '2015-16', '2016-17', '2017-18'],
series: [
[0.9, 0.4, 1.5, 4.9, 3, 3.8, 3.8, 1.9],
[6.4, 5.7, 7, 4.95, 3, 3.8, 3.8, 1.9],
[4.3, 2.3, 3.6, 4.5, 5, 2.8, 3.3, 4.3],
[3.8, 4.1, 2.8, 1.8, 2.2, 1.9, 6.7, 2.9]
]
},
{
stackBars: true,
axisX: {
labelInterpolationFnc: function(value) {
return value.split(/\s+/).map(function(word) {
return word[0];
}).join('');
}
},
axisY: {
offset: 20
}
}, [
['screen and (min-width: 400px)', {
reverseData: true,
horizontalBars: true,
axisX: {
labelInterpolationFnc: Chartist.noop
},
axisY: {
offset: 60
}
}],
['screen and (min-width: 800px)', {
stackBars: false,
seriesBarDistance: 10
}],
['screen and (min-width: 1000px)', {
reverseData: false,
horizontalBars: false,
seriesBarDistance: 15
}]
]);
})(jQuery);

View File

@@ -0,0 +1,182 @@
/**
* Chartist.js plugin to display a data label on top of the points in a line chart.
*
*/
/* global Chartist */
(function (window, document, Chartist) {
'use strict';
var defaultOptions = {
currency: undefined,
currencyFormatCallback: undefined,
tooltipOffset: {
x: 0,
y: -20
},
anchorToPoint: false,
appendToBody: false,
class: undefined,
pointClass: 'ct-point'
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.tooltip = function (options) {
options = Chartist.extend({}, defaultOptions, options);
return function tooltip(chart) {
var tooltipSelector = options.pointClass;
if (chart.constructor.name == Chartist.Bar.prototype.constructor.name) {
tooltipSelector = 'ct-bar';
} else if (chart.constructor.name == Chartist.Pie.prototype.constructor.name) {
// Added support for donut graph
if (chart.options.donut) {
tooltipSelector = 'ct-slice-donut';
} else {
tooltipSelector = 'ct-slice-pie';
}
}
var $chart = chart.container;
var $toolTip = $chart.querySelector('.chartist-tooltip');
if (!$toolTip) {
$toolTip = document.createElement('div');
$toolTip.className = (!options.class) ? 'chartist-tooltip' : 'chartist-tooltip ' + options.class;
if (!options.appendToBody) {
$chart.appendChild($toolTip);
} else {
document.body.appendChild($toolTip);
}
}
var height = $toolTip.offsetHeight;
var width = $toolTip.offsetWidth;
hide($toolTip);
function on(event, selector, callback) {
$chart.addEventListener(event, function (e) {
if (!selector || hasClass(e.target, selector))
callback(e);
});
}
on('mouseover', null, function () {
var $point = event.target;
var tooltipText = '';
var isPieChart = (chart instanceof Chartist.Pie) ? $point : $point.parentNode;
var seriesName = (isPieChart) ? $point.parentNode.getAttribute('ct:meta') || $point.parentNode.getAttribute('ct:series-name') : '';
var meta = $point.getAttribute('ct:meta') || seriesName || '';
var hasMeta = !!meta;
var value = $point.getAttribute('ct:value');
if (options.transformTooltipTextFnc && typeof options.transformTooltipTextFnc === 'function') {
value = options.transformTooltipTextFnc(value);
}
if (options.tooltipFnc && typeof options.tooltipFnc === 'function') {
tooltipText = options.tooltipFnc(meta, value);
} else {
if (options.metaIsHTML) {
var txt = document.createElement('textarea');
txt.innerHTML = meta;
meta = txt.value;
}
meta = '<span class="chartist-tooltip-meta">' + meta + '</span>';
if (hasMeta) {
tooltipText += meta + '<br>';
} else {
// For Pie Charts also take the labels into account
// Could add support for more charts here as well!
if (chart instanceof Chartist.Pie) {
var label = next($point, 'ct-label');
if (label.length > 0) {
tooltipText += text(label) + '<br>';
}
}
}
if (value) {
if (options.currency) {
if (options.currencyFormatCallback != undefined) {
value = options.currencyFormatCallback(value, options);
} else {
value = options.currency + value.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, '$1,');
}
}
value = '<span class="chartist-tooltip-value">' + value + '</span>';
tooltipText += value;
}
}
if(tooltipText) {
$toolTip.innerHTML = tooltipText;
setPosition(event);
show($toolTip);
// Remember height and width to avoid wrong position in IE
height = $toolTip.offsetHeight;
width = $toolTip.offsetWidth;
}
});
on('mouseout', null, function () {
hide($toolTip);
});
function setPosition(event) {
height = height || $toolTip.offsetHeight;
width = width || $toolTip.offsetWidth;
var offsetX = - width / 2 + options.tooltipOffset.x
var offsetY = - height + options.tooltipOffset.y;
var anchorX, anchorY;
if (!options.appendToBody) {
var box = $chart.getBoundingClientRect();
var left = event.pageX - box.left - window.pageXOffset ;
var top = event.pageY - box.top - window.pageYOffset ;
if (true === options.anchorToPoint && event.target.x2 && event.target.y2) {
anchorX = parseInt(event.target.x2.baseVal.value);
anchorY = parseInt(event.target.y2.baseVal.value);
}
$toolTip.style.top = (anchorY || top) + offsetY + 'px';
$toolTip.style.left = (anchorX || left) + offsetX + 'px';
} else {
$toolTip.style.top = event.pageY + offsetY + 'px';
$toolTip.style.left = event.pageX + offsetX + 'px';
}
}
}
};
function show(element) {
if(!hasClass(element, 'tooltip-show')) {
element.className = element.className + ' tooltip-show';
}
}
function hide(element) {
// var regex = new RegExp('tooltip-show' + '\\s*', 'gi');
// element.className = element.className.replace(regex, '').trim();
element.classList.remove('tooltip-show');
}
function hasClass(element, className) {
return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + className + ' ') > -1;
}
function next(element, className) {
do {
element = element.nextSibling;
} while (element && !hasClass(element, className));
return element;
}
function text(element) {
return element.innerText || element.textContent;
}
} (window, document, Chartist));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,285 @@
Chart.defaults.global = {
animation: true,
animationSteps: 60,
animationEasing: "easeOutIn",
showScale: true,
scaleOverride: false,
scaleSteps: null,
scaleStepWidth: null,
scaleStartValue: null,
scaleLineColor: "#eeeeee",
scaleLineWidth: 1,
scaleShowLabels: true,
scaleLabel: "<%=value%>",
scaleIntegersOnly: true,
scaleBeginAtZero: false,
scaleFontSize: 12,
scaleFontStyle: "normal",
scaleFontColor: "#717171",
responsive: true,
maintainAspectRatio: true,
showTooltips: true,
multiTooltipTemplate: "<%= value %>",
tooltipFillColor: "#333333",
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
tooltipFontSize: 14,
tooltipFontStyle: "normal",
tooltipFontColor: "#fff",
tooltipTitleFontSize: 16,
TitleFontStyle : "Raleway",
tooltipTitleFontStyle: "bold",
tooltipTitleFontColor: "#ffffff",
tooltipYPadding: 10,
tooltipXPadding: 10,
tooltipCaretSize: 8,
tooltipCornerRadius: 6,
tooltipXOffset: 5,
onAnimationProgress: function() {},
onAnimationComplete: function() {}
};
var barData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(36, 105, 92, 0.4)",
strokeColor: vihoAdminConfig.primary,
highlightFill: "rgba(36, 105, 92, 0.6)",
highlightStroke: vihoAdminConfig.primary,
data: [35, 59, 80, 81, 56, 55, 40]
}, {
label: "My Second dataset",
fillColor: "rgba(186, 137, 93, 0.4)",
strokeColor: vihoAdminConfig.secondary,
highlightFill: "rgba(186, 137, 93, 0.6)",
highlightStroke: vihoAdminConfig.secondary,
data: [28, 48, 40, 19, 86, 27, 90]
}]
};
var barOptions = {
scaleBeginAtZero: true,
scaleShowGridLines: true,
scaleGridLineColor: "rgba(0,0,0,0.1)",
scaleGridLineWidth: 1,
scaleShowHorizontalLines: true,
scaleShowVerticalLines: true,
barShowStroke: true,
barStrokeWidth: 2,
barValueSpacing: 5,
barDatasetSpacing: 1,
};
var barCtx = document.getElementById("myBarGraph").getContext("2d");
var myBarChart = new Chart(barCtx).Bar(barData, barOptions);
var polarData = [
{
value: 300,
color: vihoAdminConfig.primary,
highlight: "rgba(36, 105, 92, 1)",
label: "Yellow"
}, {
value: 50,
color: vihoAdminConfig.secondary,
highlight: "rgba(186, 137, 93, 1)",
label: "Sky"
}, {
value: 100,
color: "#222222",
highlight: "rgba(34,34,34,1)",
label: "Black"
}, {
value: 40,
color: "#717171",
highlight: "rgba(113, 113, 113, 1)",
label: "Grey"
}, {
value: 120,
color: "#e2c636",
highlight: "#616774",
label: "Dark Grey"
}
];
var polarOptions = {
scaleShowLabelBackdrop: true,
scaleBackdropColor: "rgba(255,255,255,0.75)",
scaleBeginAtZero: true,
scaleBackdropPaddingY: 2,
scaleBackdropPaddingX: 2,
scaleShowLine: true,
segmentShowStroke: true,
segmentStrokeColor: "#fff",
segmentStrokeWidth: 2,
animationSteps: 100,
animationEasing: "easeOutBounce",
animateRotate: true,
animateScale: false,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
var polarCtx = document.getElementById("myPolarGraph").getContext("2d");
var myPolarChart = new Chart(polarCtx).PolarArea(polarData, polarOptions);
var lineGraphData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(36, 105, 92, 0.5)",
strokeColor: vihoAdminConfig.primary,
pointColor: vihoAdminConfig.primary,
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "#000",
data: [10, 59, 80, 81, 56, 55, 40]
}, {
label: "My Second dataset",
fillColor: "rgba(186, 137, 93, 0.3)",
strokeColor: vihoAdminConfig.secondary,
pointColor: vihoAdminConfig.secondary,
pointStrokeColor: "#fff",
pointHighlightFill: "#000",
pointHighlightStroke: "rgba(30, 166, 236, 1)",
data: [28, 48, 40, 19, 86, 27, 90]
}]
};
var lineGraphOptions = {
scaleShowGridLines: true,
scaleGridLineColor: "rgba(0,0,0,.05)",
scaleGridLineWidth: 1,
scaleShowHorizontalLines: true,
scaleShowVerticalLines: true,
bezierCurve: true,
bezierCurveTension: 0.4,
pointDot: true,
pointDotRadius: 4,
pointDotStrokeWidth: 1,
pointHitDetectionRadius: 20,
datasetStroke: true,
datasetStrokeWidth: 2,
datasetFill: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
};
var lineCtx = document.getElementById("myGraph").getContext("2d");
var myLineCharts = new Chart(lineCtx).Line(lineGraphData, lineGraphOptions);
var radarData = {
labels: ["Ford", "Chevy", "Toyota", "Honda", "Mazda"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(36, 105, 92, 0.4)",
strokeColor: vihoAdminConfig.primary,
pointColor: vihoAdminConfig.primary,
pointStrokeColor: vihoAdminConfig.primary,
pointHighlightFill: vihoAdminConfig.primary,
pointHighlightStroke: "rgba(68, 102, 242, 0.4)",
data: [12, 3, 5, 18, 7]
}]
};
var radarOptions = {
scaleShowGridLines: true,
scaleGridLineColor: "rgba(0,0,0,.2)",
scaleGridLineWidth: 1,
scaleShowHorizontalLines: true,
scaleShowVerticalLines: true,
bezierCurve: true,
bezierCurveTension: 0.4,
pointDot: true,
pointDotRadius: 3,
pointDotStrokeWidth: 1,
pointHitDetectionRadius: 20,
datasetStroke: true,
datasetStrokeWidth: 2,
datasetFill: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
};
var radarCtx = document.getElementById("myRadarGraph").getContext("2d");
var myRadarChart = new Chart(radarCtx).Radar(radarData, radarOptions);
var pieData = [
{
value: 300,
color: vihoAdminConfig.primary,
highlight: vihoAdminConfig.primary,
label: "Primary"
},
{
value: 50,
color: vihoAdminConfig.secondary,
highlight: vihoAdminConfig.secondary,
label: "Secondary"
},
{
value: 100,
color: "#d22d3d",
highlight: "#d22d3d",
label: "Danger"
}
];
var pieOptions = {
segmentShowStroke: true,
segmentStrokeColor: "#fff",
segmentStrokeWidth: 2,
percentageInnerCutout: 0,
animationSteps: 100,
animationEasing: "easeOutBounce",
animateRotate: true,
animateScale: false,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
var doughnutData = [
{
value: 300,
color: vihoAdminConfig.primary,
highlight: vihoAdminConfig.primary,
label: "Primary"
},
{
value: 50,
color: vihoAdminConfig.secondary,
highlight: vihoAdminConfig.secondary,
label: "Secondary"
},
{
value: 100,
color: "#222222",
highlight: "#222222",
label: "Success"
}
];
var doughnutOptions = {
segmentShowStroke: true,
segmentStrokeColor: "#fff",
segmentStrokeWidth: 2,
percentageInnerCutout: 50,
animationSteps: 100,
animationEasing: "easeOutBounce",
animateRotate: true,
animateScale: false,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
var doughnutCtx = document.getElementById("myDoughnutGraph").getContext("2d");
var myDoughnutChart = new Chart(doughnutCtx).Doughnut(doughnutData, doughnutOptions);
var myLineChart = {
labels: ["","10", "20", "30", "40", "50", "60", "70", "80"],
datasets: [{
fillColor: "rgba(113, 113, 113, 0.2)",
strokeColor: "#717171",
pointColor: "#717171",
data: [10, 20, 40, 30, 0, 20, 10, 30, 10]
},{
fillColor: "rgba(186, 137, 93, 0.2)",
strokeColor: vihoAdminConfig.secondary,
pointColor: vihoAdminConfig.secondary,
data: [20, 40, 10, 20, 40, 30, 40, 10, 20]
}, {
fillColor: "rgb(36, 105, 92, 0.2)",
strokeColor: vihoAdminConfig.primary,
pointColor: vihoAdminConfig.primary,
data: [60, 10, 40, 30, 80, 30, 20, 90, 0]
}]
}
var ctx = document.getElementById("myLineCharts").getContext("2d");
var LineChartDemo = new Chart(ctx).Line(myLineChart, {
pointDotRadius: 2,
pointDotStrokeWidth: 5,
pointDotStrokeColor: "#ffffff",
bezierCurve: false,
scaleShowVerticalLines: false,
scaleGridLineColor: "#eeeeee"
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,617 @@
(function($) {
"use strict";
var data = [],
totalPoints = 300;
function getRandomData() {
if (data.length > 0)
data = data.slice(1);
while (data.length < totalPoints) {
var prev = data.length > 0 ? data[data.length - 1] : 50,
y = prev + Math.random() * 10 - 5;
if (y < 0) {
y = 0;
} else if (y > 100) {
y = 100;
}
data.push(y);
}
var res = [];
for (var i = 0; i < data.length; ++i) {
res.push([i, data[i]])
}
return res;
}
var updateInterval = 30;
$("#updateInterval").val(updateInterval).change(function () {
var v = $(this).val();
if (v && !isNaN(+v)) {
updateInterval = +v;
if (updateInterval < 1) {
updateInterval = 1;
} else if (updateInterval > 2000) {
updateInterval = 2000;
}
$(this).val("" + updateInterval);
}
});
var plot = $.plot("#real-time-update", [ getRandomData() ], {
series: {
shadowSize: 0
},
yaxis: {
min: 0,
max: 100
},
xaxis: {
show: !1
},
background:{
color:'#469dff'
},
grid: {
borderWidth: 0
},
colors: [vihoAdminConfig.primary]
});
function update() {
plot.setData([getRandomData()]);
plot.draw();
setTimeout(update, updateInterval);
}
update();
})(jQuery);
if ($("#flot-categories").length > 0) {
var a = {
color: vihoAdminConfig.primary,
data: [
["Jan", 25],
["Feb", 8],
["Mar", 4],
["Apr", 13],
["May", 17],
["Jun", 9],
["Jul", 5],
["Aug", 11],
["Sep", 17],
["Oct", 8],
["Nov", 26],
]
};
$.plot("#flot-categories", [a], {
series: {
bars: {
show: !0,
barWidth: .8,
align: "center",
fillColor: {
colors: [{
opacity: 1
}, {
opacity: 1
}]
}
}
},
xaxis: {
mode: "categories",
tickLength: 0
},
grid: {
borderWidth: 0
}
})
}
if ($("#annotations-chart").length > 0) {
for (var a = [], b = 0; b < 20; ++b) a.push([b, Math.sin(b)]);
var c = [{
data: a,
label: "Pressure",
color: vihoAdminConfig.primary
}],
d = [{
color: "#ffffff",
yaxis: {
from: 1
}
}, {
color: "#ffffff",
yaxis: {
to: -1
}
}, {
color: "#ffffff",
lineWidth: 1,
xaxis: {
from: 1,
to: 1
}
}, {
color: "#ffffff",
lineWidth: 1,
xaxis: {
from: 9,
to: 9
}
}],
e = $("#annotations-chart"),
f = $.plot(e, c, {
bars: {
show: !0,
barWidth: .7,
fill: 1
},
xaxis: {
ticks: [],
autoscaleMargin: .02
},
yaxis: {
min: -2,
max: 2
},
grid: {
markings: d,
borderWidth: 0
}
}),
g = f.pointOffset({
x: 2,
y: -1.2
});
e.append("<div style='position:absolute;left:" + (g.left + 4) + "px;top:" + g.top + "px;color:#666;font-size:smaller'>Warming up</div>"), g = f.pointOffset({
x: 8,
y: -1.2
}), e.append("<div style='position:absolute;left:" + (g.left + 4) + "px;top:" + g.top + "px;color:#666;font-size:smaller'>Actual measurements</div>");
var h = f.getCanvas().getContext("2d");
h.beginPath(), g.left += 4, h.moveTo(g.left, g.top), h.lineTo(g.left, g.top - 10), h.lineTo(g.left + 10, g.top - 5), h.lineTo(g.left, g.top), h.fillStyle = "#5e6db3", h.fill()
}
if ($("#flot-basic-chart").length > 0) {
for (var a = [], b = 0; b < 14; b += .5) a.push([b, Math.sin(b)]);
var c = {
color: "#e2c636",
data: [
[0, 3],
[4, 8],
[8, 5],
[9, 13]
]
},
d = {
color: vihoAdminConfig.primary,
data: [
[0, 12],
[7, 0],
null,
[0, 2.5],
[12, 10.5]
]
};
$.plot("#flot-basic-chart", [a, c, d], {
grid: {
borderWidth: 0
},
bars: {
show: !0,
lineWidth: 0,
fill: !0,
fillColor: {
colors: [{
opacity: 1
}, {
opacity: 1
}]
}
},
colors: [vihoAdminConfig.secondary, vihoAdminConfig.secondary ,vihoAdminConfig.secondary ,vihoAdminConfig.secondary]
})
}
$(function() {
var datasets = {
"usa": {
label: "USA",
data: [[1988, 483994], [1989, 479060], [1990, 457648], [1991, 401949], [1992, 424705], [1993, 402375], [1994, 377867], [1995, 357382], [1996, 337946], [1997, 336185], [1998, 328611], [1999, 329421], [2000, 342172], [2001, 344932], [2002, 387303], [2003, 440813], [2004, 480451], [2005, 504638], [2006, 528692]]
},
"russia": {
label: "Russia",
data: [[1988, 218000], [1989, 203000], [1990, 171000], [1992, 42500], [1993, 37600], [1994, 36600], [1995, 21700], [1996, 19200], [1997, 21300], [1998, 13600], [1999, 14000], [2000, 19100], [2001, 21300], [2002, 23600], [2003, 25100], [2004, 26100], [2005, 31100], [2006, 34700]]
},
"uk": {
label: "UK",
data: [[1988, 62982], [1989, 62027], [1990, 60696], [1991, 62348], [1992, 58560], [1993, 56393], [1994, 54579], [1995, 50818], [1996, 50554], [1997, 48276], [1998, 47691], [1999, 47529], [2000, 47778], [2001, 48760], [2002, 50949], [2003, 57452], [2004, 60234], [2005, 60076], [2006, 59213]]
},
"germany": {
label: "Germany",
data: [[1988, 55627], [1989, 55475], [1990, 58464], [1991, 55134], [1992, 52436], [1993, 47139], [1994, 43962], [1995, 43238], [1996, 42395], [1997, 40854], [1998, 40993], [1999, 41822], [2000, 41147], [2001, 40474], [2002, 40604], [2003, 40044], [2004, 38816], [2005, 38060], [2006, 36984]]
},
"denmark": {
label: "Denmark",
data: [[1988, 3813], [1989, 3719], [1990, 3722], [1991, 3789], [1992, 3720], [1993, 3730], [1994, 3636], [1995, 3598], [1996, 3610], [1997, 3655], [1998, 3695], [1999, 3673], [2000, 3553], [2001, 3774], [2002, 3728], [2003, 3618], [2004, 3638], [2005, 3467], [2006, 3770]]
},
"sweden": {
label: "Sweden",
data: [[1988, 6402], [1989, 6474], [1990, 6605], [1991, 6209], [1992, 6035], [1993, 6020], [1994, 6000], [1995, 6018], [1996, 3958], [1997, 5780], [1998, 5954], [1999, 6178], [2000, 6411], [2001, 5993], [2002, 5833], [2003, 5791], [2004, 5450], [2005, 5521], [2006, 5271]]
},
"norway": {
label: "Norway",
data: [[1988, 4382], [1989, 4498], [1990, 4535], [1991, 4398], [1992, 4766], [1993, 4441], [1994, 4670], [1995, 4217], [1996, 4275], [1997, 4203], [1998, 4482], [1999, 4506], [2000, 4358], [2001, 4385], [2002, 5269], [2003, 5066], [2004, 5194], [2005, 4887], [2006, 4891]]
}
};
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append("<div class='checkbox checkbox-primary m-squar'><input type='checkbox' name='" + key +
"' checked='checked' id='id" + key + "'></input>" +
"<label for='id" + key + "'>"
+ val.label + "</label></div>");
});
choiceContainer.find("input").click(plotAccordingToChoices);
function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
data.push(datasets[key]);
}
});
if (data.length > 0) {
$.plot("#toggling-series-flot", data, {
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0
},
grid: {
borderWidth: 0
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#e6edef"]
});
}
}
plotAccordingToChoices();
});
$(function() {
function a() {
$("#stacking-flot-chart").length > 0 && $.plot("#stacking-flot-chart", j, {
series: {
stack: f,
lines: {
show: h,
fill: !0,
steps: i
},
bars: {
show: g,
barWidth: .6
}
},
grid: {
borderWidth: 0
}
})
}
for (var b = [], c = 0; c <= 10; c += 1) b.push([c, parseInt(30 * Math.random(), 30)]);
for (var d = [], c = 0; c <= 10; c += 1) d.push([c, parseInt(30 * Math.random(), 30)]);
for (var e = [], c = 0; c <= 10; c += 1) e.push([c, parseInt(30 * Math.random(), 30)]);
var f = 0,
g = !0,
h = !1,
i = !1,
j = [{
color: vihoAdminConfig.secondary,
data: b
}, {
color: vihoAdminConfig.primary,
data: d
}, {
color: "#222222",
data: e
}];
a(), $(".stackControls button").click( function(b) {
b.preventDefault(), f = "With stacking" == $(this).text() || null, a()
}), $(".graphControls button").on("click", function(b) {
b.preventDefault(), g = $(this).text().indexOf("Bars") != -1, h = $(this).text().indexOf("Lines") != -1, i = $(this).text().indexOf("steps") != -1, a()
})
});
$(function() {
function drawArrow(ctx, x, y, radius){
ctx.beginPath();
ctx.moveTo(x + radius, y + radius);
ctx.lineTo(x, y);
ctx.lineTo(x - radius, y + radius);
ctx.stroke();
}
function drawSemiCircle(ctx, x, y, radius){
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI, false);
ctx.moveTo(x - radius, y);
ctx.lineTo(x + radius, y);
ctx.stroke();
}
var data1 = [
[1,1,.5,.1,.3],
[2,2,.3,.5,.2],
[3,3,.9,.5,.2],
[1.5,-.05,.5,.1,.3],
[3.15,1.,.5,.1,.3],
[2.5,-1.,.5,.1,.3]
];
var data1_points = {
show: true,
radius: 5,
fillColor: "#007bff",
errorbars: "xy",
xerr: {show: true, asymmetric: true, upperCap: "-", lowerCap: "-"},
yerr: {show: true, color: "red", upperCap: "-"}
};
var data2 = [
[.7,3,.2,.4],
[1.5,2.2,.3,.4],
[2.3,1,.5,.2]
];
var data2_points = {
show: true,
radius: 5,
errorbars: "y",
yerr: {show:true, asymmetric:true, upperCap: drawArrow, lowerCap: drawSemiCircle}
};
var data3 = [
[1,2,.4],
[2,0.5,.3],
[2.7,2,.5]
];
var data3_points = {
radius: 0,
errorbars: "y",
yerr: {show:true, upperCap: "-", lowerCap: "-", radius: 5}
};
var data4 = [
[1.3, 1],
[1.75, 2.5],
[2.5, 0.5]
];
var data4_errors = [0.1, 0.4, 0.2];
for (var i = 0; i < data4.length; i++) {
data4_errors[i] = data4[i].concat(data4_errors[i])
}
var data = [
{color: "#717171", points: data1_points, data: data1, label: "data1"},
{color: "#222222", points: data2_points, data: data2, label: "data2"},
{color: vihoAdminConfig.secondary, lines: {show: true}, points: data3_points, data: data3, label: "data3"},
{color: vihoAdminConfig.primary, bars: {show: true, align: "center", barWidth: 0.25}, data: data4, label: "data4"},
{color: "#e2c636", points: data3_points, data: data4_errors}
];
$.plot($("#error-flot-chart"), data , {
legend: {
position: "sw",
show: true
},
series: {
lines: {
show: false
}
},
xaxis: {
min: 0.6,
max: 3.1
},
yaxis: {
min: 0,
max: 3.5
},
zoom: {
interactive: true
},
pan: {
interactive: true
},
grid: {
borderWidth: 0
}
});
});
$(function() {
var data = [],
series = Math.floor(Math.random() * 6) + 3;
for (var i = 0; i < series; i++) {
data[i] = {
label: "Series" + (i + 1),
data: Math.floor(Math.random() * 100) + 1
}
}
$.plot('#default-pie-flot-chart', data, {
series: {
pie: {
show: true
}
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#default-pie-legend-flot-chart', data, {
series: {
pie: {
show: true
}
},
legend: {
show: false
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#hidden-label-radius-flot-chart', data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 2/3,
threshold: 0.1
}
}
},
legend: {
show: false
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#default-pie-flot-chart-hover', data, {
series: {
pie: {
show: true
}
},
grid: {
hoverable: true,
clickable: true
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#custom-label1pie', data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 1,
background: {
opacity: 0.8
}
}
}
},
legend: {
show: false
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#label-radius-flot-chart', data, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 3/4,
background: {
opacity: 0.8
}
}
}
},
legend: {
show: false
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#title-pie-flot-chart', data, {
series: {
pie: {
show: true,
radius: 1,
tilt: 0.5,
label: {
show: true,
radius: 1,
background: {
opacity: 0.8
}
},
combine: {
color: '#ddd',
threshold: 0.1
}
}
},
legend: {
show: false
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
$.plot('#dount-hole-flot-chart', data, {
series: {
pie: {
innerRadius: 0.5,
show: true
}
},
colors: [vihoAdminConfig.primary, "#ba895" ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#efefef"]
});
});
if ($("#multiple-real-timeupdate ").length > 0) {
var a = [],
b = 300,
c = function() {
for (a.length > 0 && (a = a.slice(1)); a.length < b;) {
var c = a.length > 0 ? a[a.length - 1] : 50,
d = c + 10 * Math.random() - 5;
d < 0 ? d = 0 : d > 100 && (d = 100), a.push(d)
}
for (var e = [], f = 0; f < a.length; ++f) e.push([f, a[f]]);
return e
},
d = [],
b = 300,
e = function() {
for (d.length > 0 && (d = d.slice(1)); d.length < b;) {
var a = d.length > 0 ? d[d.length - 1] : 50,
c = a + 10 * Math.random() - 5;
c < 0 ? c = 0 : c > 100 && (c = 100), d.push(c)
}
for (var e = [], f = 0; f < d.length; ++f) e.push([f, d[f]]);
return e
},
f = 30,
g = 30;
g && !isNaN(+g) && (f = +g, f < 1 ? f = 1 : f > 2e3 && (f = 2e3), $(this).val("" + f));
var h = {
color: "#544fff",
data: c()
},
i = {
color: "#000000",
data: e()
},
j = $.plot("#multiple-real-timeupdate", [h, i], {
series: {
shadowSize: 0
},
yaxis: {
min: 0,
max: 100
},
xaxis: {
show: !1
},
grid: {
borderWidth: 0
},
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary]
}),
k = function() {
j.setData([c(), e()]), j.draw(), setTimeout(k, f)
};
k()
}

View File

@@ -0,0 +1,345 @@
/* Flot plugin for drawing all elements of a plot on the canvas.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Flot normally produces certain elements, like axis labels and the legend, using
HTML elements. This permits greater interactivity and customization, and often
looks better, due to cross-browser canvas text inconsistencies and limitations.
It can also be desirable to render the plot entirely in canvas, particularly
if the goal is to save it as an image, or if Flot is being used in a context
where the HTML DOM does not exist, as is the case within Node.js. This plugin
switches out Flot's standard drawing operations for canvas-only replacements.
Currently the plugin supports only axis labels, but it will eventually allow
every element of the plot to be rendered directly to canvas.
The plugin supports these options:
{
canvas: boolean
}
The "canvas" option controls whether full canvas drawing is enabled, making it
possible to toggle on and off. This is useful when a plot uses HTML text in the
browser, but needs to redraw with canvas text when exporting as an image.
*/
(function($) {
var options = {
canvas: true
};
var render, getTextInfo, addText;
// Cache the prototype hasOwnProperty for faster access
var hasOwnProperty = Object.prototype.hasOwnProperty;
function init(plot, classes) {
var Canvas = classes.Canvas;
// We only want to replace the functions once; the second time around
// we would just get our new function back. This whole replacing of
// prototype functions is a disaster, and needs to be changed ASAP.
if (render == null) {
getTextInfo = Canvas.prototype.getTextInfo,
addText = Canvas.prototype.addText,
render = Canvas.prototype.render;
}
// Finishes rendering the canvas, including overlaid text
Canvas.prototype.render = function() {
if (!plot.getOptions().canvas) {
return render.call(this);
}
var context = this.context,
cache = this._textCache;
// For each text layer, render elements marked as active
context.save();
context.textBaseline = "middle";
for (var layerKey in cache) {
if (hasOwnProperty.call(cache, layerKey)) {
var layerCache = cache[layerKey];
for (var styleKey in layerCache) {
if (hasOwnProperty.call(layerCache, styleKey)) {
var styleCache = layerCache[styleKey],
updateStyles = true;
for (var key in styleCache) {
if (hasOwnProperty.call(styleCache, key)) {
var info = styleCache[key],
positions = info.positions,
lines = info.lines;
// Since every element at this level of the cache have the
// same font and fill styles, we can just change them once
// using the values from the first element.
if (updateStyles) {
context.fillStyle = info.font.color;
context.font = info.font.definition;
updateStyles = false;
}
for (var i = 0, position; position = positions[i]; i++) {
if (position.active) {
for (var j = 0, line; line = position.lines[j]; j++) {
context.fillText(lines[j].text, line[0], line[1]);
}
} else {
positions.splice(i--, 1);
}
}
if (positions.length == 0) {
delete styleCache[key];
}
}
}
}
}
}
}
context.restore();
};
// Creates (if necessary) and returns a text info object.
//
// When the canvas option is set, the object looks like this:
//
// {
// width: Width of the text's bounding box.
// height: Height of the text's bounding box.
// positions: Array of positions at which this text is drawn.
// lines: [{
// height: Height of this line.
// widths: Width of this line.
// text: Text on this line.
// }],
// font: {
// definition: Canvas font property string.
// color: Color of the text.
// },
// }
//
// The positions array contains objects that look like this:
//
// {
// active: Flag indicating whether the text should be visible.
// lines: Array of [x, y] coordinates at which to draw the line.
// x: X coordinate at which to draw the text.
// y: Y coordinate at which to draw the text.
// }
Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
if (!plot.getOptions().canvas) {
return getTextInfo.call(this, layer, text, font, angle, width);
}
var textStyle, layerCache, styleCache, info;
// Cast the value to a string, in case we were given a number
text = "" + text;
// If the font is a font-spec object, generate a CSS definition
if (typeof font === "object") {
textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
} else {
textStyle = font;
}
// Retrieve (or create) the cache for the text's layer and styles
layerCache = this._textCache[layer];
if (layerCache == null) {
layerCache = this._textCache[layer] = {};
}
styleCache = layerCache[textStyle];
if (styleCache == null) {
styleCache = layerCache[textStyle] = {};
}
info = styleCache[text];
if (info == null) {
var context = this.context;
// If the font was provided as CSS, create a div with those
// classes and examine it to generate a canvas font spec.
if (typeof font !== "object") {
var element = $("<div>&nbsp;</div>")
.css("position", "absolute")
.addClass(typeof font === "string" ? font : null)
.appendTo(this.getTextLayer(layer));
font = {
lineHeight: element.height(),
style: element.css("font-style"),
variant: element.css("font-variant"),
weight: element.css("font-weight"),
family: element.css("font-family"),
color: element.css("color")
};
// Setting line-height to 1, without units, sets it equal
// to the font-size, even if the font-size is abstract,
// like 'smaller'. This enables us to read the real size
// via the element's height, working around browsers that
// return the literal 'smaller' value.
font.size = element.css("line-height", 1).height();
element.remove();
}
textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
// Create a new info object, initializing the dimensions to
// zero so we can count them up line-by-line.
info = styleCache[text] = {
width: 0,
height: 0,
positions: [],
lines: [],
font: {
definition: textStyle,
color: font.color
}
};
context.save();
context.font = textStyle;
// Canvas can't handle multi-line strings; break on various
// newlines, including HTML brs, to build a list of lines.
// Note that we could split directly on regexps, but IE < 9 is
// broken; revisit when we drop IE 7/8 support.
var lines = (text + "").replace(/<br ?\/?>|\r\n|\r/g, "\n").split("\n");
for (var i = 0; i < lines.length; ++i) {
var lineText = lines[i],
measured = context.measureText(lineText);
info.width = Math.max(measured.width, info.width);
info.height += font.lineHeight;
info.lines.push({
text: lineText,
width: measured.width,
height: font.lineHeight
});
}
context.restore();
}
return info;
};
// Adds a text string to the canvas text overlay.
Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
if (!plot.getOptions().canvas) {
return addText.call(this, layer, x, y, text, font, angle, width, halign, valign);
}
var info = this.getTextInfo(layer, text, font, angle, width),
positions = info.positions,
lines = info.lines;
// Text is drawn with baseline 'middle', which we need to account
// for by adding half a line's height to the y position.
y += info.height / lines.length / 2;
// Tweak the initial y-position to match vertical alignment
if (valign == "middle") {
y = Math.round(y - info.height / 2);
} else if (valign == "bottom") {
y = Math.round(y - info.height);
} else {
y = Math.round(y);
}
// FIXME: LEGACY BROWSER FIX
// AFFECTS: Opera < 12.00
// Offset the y coordinate, since Opera is off pretty
// consistently compared to the other browsers.
if (!!(window.opera && window.opera.version().split(".")[0] < 12)) {
y -= 2;
}
// Determine whether this text already exists at this position.
// If so, mark it for inclusion in the next render pass.
for (var i = 0, position; position = positions[i]; i++) {
if (position.x == x && position.y == y) {
position.active = true;
return;
}
}
// If the text doesn't exist at this position, create a new entry
position = {
active: true,
lines: [],
x: x,
y: y
};
positions.push(position);
// Fill in the x & y positions of each line, adjusting them
// individually for horizontal alignment.
for (var i = 0, line; line = lines[i]; i++) {
if (halign == "center") {
position.lines.push([Math.round(x - line.width / 2), y]);
} else if (halign == "right") {
position.lines.push([Math.round(x - line.width), y]);
} else {
position.lines.push([Math.round(x), y]);
}
y += line.height;
}
};
}
$.plot.plugins.push({
init: init,
options: options,
name: "canvas",
version: "1.0"
});
})(jQuery);

View File

@@ -0,0 +1,190 @@
/* Flot plugin for plotting textual data or categories.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
allows you to plot such a dataset directly.
To enable it, you must specify mode: "categories" on the axis with the textual
labels, e.g.
$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
By default, the labels are ordered as they are met in the data series. If you
need a different ordering, you can specify "categories" on the axis options
and list the categories there:
xaxis: {
mode: "categories",
categories: ["February", "March", "April"]
}
If you need to customize the distances between the categories, you can specify
"categories" as an object mapping labels to values
xaxis: {
mode: "categories",
categories: { "February": 1, "March": 3, "April": 4 }
}
If you don't specify all categories, the remaining categories will be numbered
from the max value plus 1 (with a spacing of 1 between each).
Internally, the plugin works by transforming the input data through an auto-
generated mapping where the first category becomes 0, the second 1, etc.
Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
is visible in hover and click events that return numbers rather than the
category labels). The plugin also overrides the tick generator to spit out the
categories as ticks instead of the values.
If you need to map a value back to its label, the mapping is always accessible
as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
*/
(function ($) {
var options = {
xaxis: {
categories: null
},
yaxis: {
categories: null
}
};
function processRawData(plot, series, data, datapoints) {
// if categories are enabled, we need to disable
// auto-transformation to numbers so the strings are intact
// for later processing
var xCategories = series.xaxis.options.mode == "categories",
yCategories = series.yaxis.options.mode == "categories";
if (!(xCategories || yCategories))
return;
var format = datapoints.format;
if (!format) {
// FIXME: auto-detection should really not be defined here
var s = series;
format = [];
format.push({ x: true, number: true, required: true });
format.push({ y: true, number: true, required: true });
if (s.bars.show || (s.lines.show && s.lines.fill)) {
var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
if (s.bars.horizontal) {
delete format[format.length - 1].y;
format[format.length - 1].x = true;
}
}
datapoints.format = format;
}
for (var m = 0; m < format.length; ++m) {
if (format[m].x && xCategories)
format[m].number = false;
if (format[m].y && yCategories)
format[m].number = false;
}
}
function getNextIndex(categories) {
var index = -1;
for (var v in categories)
if (categories[v] > index)
index = categories[v];
return index + 1;
}
function categoriesTickGenerator(axis) {
var res = [];
for (var label in axis.categories) {
var v = axis.categories[label];
if (v >= axis.min && v <= axis.max)
res.push([v, label]);
}
res.sort(function (a, b) { return a[0] - b[0]; });
return res;
}
function setupCategoriesForAxis(series, axis, datapoints) {
if (series[axis].options.mode != "categories")
return;
if (!series[axis].categories) {
// parse options
var c = {}, o = series[axis].options.categories || {};
if ($.isArray(o)) {
for (var i = 0; i < o.length; ++i)
c[o[i]] = i;
}
else {
for (var v in o)
c[v] = o[v];
}
series[axis].categories = c;
}
// fix ticks
if (!series[axis].options.ticks)
series[axis].options.ticks = categoriesTickGenerator;
transformPointsOnAxis(datapoints, axis, series[axis].categories);
}
function transformPointsOnAxis(datapoints, axis, categories) {
// go through the points, transforming them
var points = datapoints.points,
ps = datapoints.pointsize,
format = datapoints.format,
formatColumn = axis.charAt(0),
index = getNextIndex(categories);
for (var i = 0; i < points.length; i += ps) {
if (points[i] == null)
continue;
for (var m = 0; m < ps; ++m) {
var val = points[i + m];
if (val == null || !format[m][formatColumn])
continue;
if (!(val in categories)) {
categories[val] = index;
++index;
}
points[i + m] = categories[val];
}
}
}
function processDatapoints(plot, series, datapoints) {
setupCategoriesForAxis(series, "xaxis", datapoints);
setupCategoriesForAxis(series, "yaxis", datapoints);
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.processDatapoints.push(processDatapoints);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'categories',
version: '1.0'
});
})(jQuery);

View File

@@ -0,0 +1,176 @@
/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
crosshair: {
mode: null or "x" or "y" or "xy"
color: color
lineWidth: number
}
Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
crosshair that lets you trace the values on the x axis, "y" enables a
horizontal crosshair and "xy" enables them both. "color" is the color of the
crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
the drawn lines (default is 1).
The plugin also adds four public methods:
- setCrosshair( pos )
Set the position of the crosshair. Note that this is cleared if the user
moves the mouse. "pos" is in coordinates of the plot and should be on the
form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
axes), which is coincidentally the same format as what you get from a
"plothover" event. If "pos" is null, the crosshair is cleared.
- clearCrosshair()
Clear the crosshair.
- lockCrosshair(pos)
Cause the crosshair to lock to the current location, no longer updating if
the user moves the mouse. Optionally supply a position (passed on to
setCrosshair()) to move it to.
Example usage:
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
$("#graph").bind( "plothover", function ( evt, position, item ) {
if ( item ) {
// Lock the crosshair to the data point being hovered
myFlot.lockCrosshair({
x: item.datapoint[ 0 ],
y: item.datapoint[ 1 ]
});
} else {
// Return normal crosshair operation
myFlot.unlockCrosshair();
}
});
- unlockCrosshair()
Free the crosshair to move again after locking it.
*/
(function ($) {
var options = {
crosshair: {
mode: null, // one of null, "x", "y" or "xy",
color: "rgba(170, 0, 0, 0.80)",
lineWidth: 1
}
};
function init(plot) {
// position of crosshair in pixels
var crosshair = { x: -1, y: -1, locked: false };
plot.setCrosshair = function setCrosshair(pos) {
if (!pos)
crosshair.x = -1;
else {
var o = plot.p2c(pos);
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
}
plot.triggerRedrawOverlay();
};
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
plot.lockCrosshair = function lockCrosshair(pos) {
if (pos)
plot.setCrosshair(pos);
crosshair.locked = true;
};
plot.unlockCrosshair = function unlockCrosshair() {
crosshair.locked = false;
};
function onMouseOut(e) {
if (crosshair.locked)
return;
if (crosshair.x != -1) {
crosshair.x = -1;
plot.triggerRedrawOverlay();
}
}
function onMouseMove(e) {
if (crosshair.locked)
return;
if (plot.getSelection && plot.getSelection()) {
crosshair.x = -1; // hide the crosshair while selecting
return;
}
var offset = plot.offset();
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
plot.triggerRedrawOverlay();
}
plot.hooks.bindEvents.push(function (plot, eventHolder) {
if (!plot.getOptions().crosshair.mode)
return;
eventHolder.mouseout(onMouseOut);
eventHolder.mousemove(onMouseMove);
});
plot.hooks.drawOverlay.push(function (plot, ctx) {
var c = plot.getOptions().crosshair;
if (!c.mode)
return;
var plotOffset = plot.getPlotOffset();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
if (crosshair.x != -1) {
var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
ctx.strokeStyle = c.color;
ctx.lineWidth = c.lineWidth;
ctx.lineJoin = "round";
ctx.beginPath();
if (c.mode.indexOf("x") != -1) {
var drawX = Math.floor(crosshair.x) + adj;
ctx.moveTo(drawX, 0);
ctx.lineTo(drawX, plot.height());
}
if (c.mode.indexOf("y") != -1) {
var drawY = Math.floor(crosshair.y) + adj;
ctx.moveTo(0, drawY);
ctx.lineTo(plot.width(), drawY);
}
ctx.stroke();
}
ctx.restore();
});
plot.hooks.shutdown.push(function (plot, eventHolder) {
eventHolder.unbind("mouseout", onMouseOut);
eventHolder.unbind("mousemove", onMouseMove);
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'crosshair',
version: '1.0'
});
})(jQuery);

View File

@@ -0,0 +1,353 @@
/* Flot plugin for plotting error bars.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Error bars are used to show standard deviation and other statistical
properties in a plot.
* Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
This plugin allows you to plot error-bars over points. Set "errorbars" inside
the points series to the axis name over which there will be error values in
your data array (*even* if you do not intend to plot them later, by setting
"show: null" on xerr/yerr).
The plugin supports these options:
series: {
points: {
errorbars: "x" or "y" or "xy",
xerr: {
show: null/false or true,
asymmetric: null/false or true,
upperCap: null or "-" or function,
lowerCap: null or "-" or function,
color: null or color,
radius: null or number
},
yerr: { same options as xerr }
}
}
Each data point array is expected to be of the type:
"x" [ x, y, xerr ]
"y" [ x, y, yerr ]
"xy" [ x, y, xerr, yerr ]
Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
error-bars on X and asymmetric on Y would be:
[ x, y, xerr, yerr_lower, yerr_upper ]
By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
draw a small cap perpendicular to the error bar. They can also be set to a
user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
function drawSemiCircle( ctx, x, y, radius ) {
ctx.beginPath();
ctx.arc( x, y, radius, 0, Math.PI, false );
ctx.moveTo( x - radius, y );
ctx.lineTo( x + radius, y );
ctx.stroke();
}
Color and radius both default to the same ones of the points series if not
set. The independent radius parameter on xerr/yerr is useful for the case when
we may want to add error-bars to a line, without showing the interconnecting
points (with radius: 0), and still showing end caps on the error-bars.
shadowSize and lineWidth are derived as well from the points series.
*/
(function ($) {
var options = {
series: {
points: {
errorbars: null, //should be 'x', 'y' or 'xy'
xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
}
}
};
function processRawData(plot, series, data, datapoints){
if (!series.points.errorbars)
return;
// x,y values
var format = [
{ x: true, number: true, required: true },
{ y: true, number: true, required: true }
];
var errors = series.points.errorbars;
// error bars - first X then Y
if (errors == 'x' || errors == 'xy') {
// lower / upper error
if (series.points.xerr.asymmetric) {
format.push({ x: true, number: true, required: true });
format.push({ x: true, number: true, required: true });
} else
format.push({ x: true, number: true, required: true });
}
if (errors == 'y' || errors == 'xy') {
// lower / upper error
if (series.points.yerr.asymmetric) {
format.push({ y: true, number: true, required: true });
format.push({ y: true, number: true, required: true });
} else
format.push({ y: true, number: true, required: true });
}
datapoints.format = format;
}
function parseErrors(series, i){
var points = series.datapoints.points;
// read errors from points array
var exl = null,
exu = null,
eyl = null,
eyu = null;
var xerr = series.points.xerr,
yerr = series.points.yerr;
var eb = series.points.errorbars;
// error bars - first X
if (eb == 'x' || eb == 'xy') {
if (xerr.asymmetric) {
exl = points[i + 2];
exu = points[i + 3];
if (eb == 'xy')
if (yerr.asymmetric){
eyl = points[i + 4];
eyu = points[i + 5];
} else eyl = points[i + 4];
} else {
exl = points[i + 2];
if (eb == 'xy')
if (yerr.asymmetric) {
eyl = points[i + 3];
eyu = points[i + 4];
} else eyl = points[i + 3];
}
// only Y
} else if (eb == 'y')
if (yerr.asymmetric) {
eyl = points[i + 2];
eyu = points[i + 3];
} else eyl = points[i + 2];
// symmetric errors?
if (exu == null) exu = exl;
if (eyu == null) eyu = eyl;
var errRanges = [exl, exu, eyl, eyu];
// nullify if not showing
if (!xerr.show){
errRanges[0] = null;
errRanges[1] = null;
}
if (!yerr.show){
errRanges[2] = null;
errRanges[3] = null;
}
return errRanges;
}
function drawSeriesErrors(plot, ctx, s){
var points = s.datapoints.points,
ps = s.datapoints.pointsize,
ax = [s.xaxis, s.yaxis],
radius = s.points.radius,
err = [s.points.xerr, s.points.yerr];
//sanity check, in case some inverted axis hack is applied to flot
var invertX = false;
if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
invertX = true;
var tmp = err[0].lowerCap;
err[0].lowerCap = err[0].upperCap;
err[0].upperCap = tmp;
}
var invertY = false;
if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
invertY = true;
var tmp = err[1].lowerCap;
err[1].lowerCap = err[1].upperCap;
err[1].upperCap = tmp;
}
for (var i = 0; i < s.datapoints.points.length; i += ps) {
//parse
var errRanges = parseErrors(s, i);
//cycle xerr & yerr
for (var e = 0; e < err.length; e++){
var minmax = [ax[e].min, ax[e].max];
//draw this error?
if (errRanges[e * err.length]){
//data coordinates
var x = points[i],
y = points[i + 1];
//errorbar ranges
var upper = [x, y][e] + errRanges[e * err.length + 1],
lower = [x, y][e] - errRanges[e * err.length];
//points outside of the canvas
if (err[e].err == 'x')
if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
continue;
if (err[e].err == 'y')
if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
continue;
// prevent errorbars getting out of the canvas
var drawUpper = true,
drawLower = true;
if (upper > minmax[1]) {
drawUpper = false;
upper = minmax[1];
}
if (lower < minmax[0]) {
drawLower = false;
lower = minmax[0];
}
//sanity check, in case some inverted axis hack is applied to flot
if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
//swap coordinates
var tmp = lower;
lower = upper;
upper = tmp;
tmp = drawLower;
drawLower = drawUpper;
drawUpper = tmp;
tmp = minmax[0];
minmax[0] = minmax[1];
minmax[1] = tmp;
}
// convert to pixels
x = ax[0].p2c(x),
y = ax[1].p2c(y),
upper = ax[e].p2c(upper);
lower = ax[e].p2c(lower);
minmax[0] = ax[e].p2c(minmax[0]);
minmax[1] = ax[e].p2c(minmax[1]);
//same style as points by default
var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
//shadow as for points
if (lw > 0 && sw > 0) {
var w = sw / 2;
ctx.lineWidth = w;
ctx.strokeStyle = "rgba(0,0,0,0.1)";
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
ctx.strokeStyle = "rgba(0,0,0,0.2)";
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
}
ctx.strokeStyle = err[e].color? err[e].color: s.color;
ctx.lineWidth = lw;
//draw it
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
}
}
}
}
function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
//shadow offset
y += offset;
upper += offset;
lower += offset;
// error bar - avoid plotting over circles
if (err.err == 'x'){
if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
else drawUpper = false;
if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
else drawLower = false;
}
else {
if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
else drawUpper = false;
if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
else drawLower = false;
}
//internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
//this is a way to get errorbars on lines without visible connecting dots
radius = err.radius != null? err.radius: radius;
// upper cap
if (drawUpper) {
if (err.upperCap == '-'){
if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
} else if ($.isFunction(err.upperCap)){
if (err.err=='x') err.upperCap(ctx, upper, y, radius);
else err.upperCap(ctx, x, upper, radius);
}
}
// lower cap
if (drawLower) {
if (err.lowerCap == '-'){
if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
} else if ($.isFunction(err.lowerCap)){
if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
else err.lowerCap(ctx, x, lower, radius);
}
}
}
function drawPath(ctx, pts){
ctx.beginPath();
ctx.moveTo(pts[0][0], pts[0][1]);
for (var p=1; p < pts.length; p++)
ctx.lineTo(pts[p][0], pts[p][1]);
ctx.stroke();
}
function draw(plot, ctx){
var plotOffset = plot.getPlotOffset();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
$.each(plot.getData(), function (i, s) {
if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
drawSeriesErrors(plot, ctx, s);
});
ctx.restore();
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.draw.push(draw);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'errorbars',
version: '1.0'
});
})(jQuery);

View File

@@ -0,0 +1,226 @@
/* Flot plugin for computing bottoms for filled line and bar charts.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The case: you've got two series that you want to fill the area between. In Flot
terms, you need to use one as the fill bottom of the other. You can specify the
bottom of each data point as the third coordinate manually, or you can use this
plugin to compute it for you.
In order to name the other series, you need to give it an id, like this:
var dataset = [
{ data: [ ... ], id: "foo" } , // use default bottom
{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
];
$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
As a convenience, if the id given is a number that doesn't appear as an id in
the series, it is interpreted as the index in the array instead (so fillBetween:
0 can also mean the first series).
Internally, the plugin modifies the datapoints in each series. For line series,
extra data points might be inserted through interpolation. Note that at points
where the bottom line is not defined (due to a null point or start/end of line),
the current line will show a gap too. The algorithm comes from the
jquery.flot.stack.js plugin, possibly some code could be shared.
*/
(function ( $ ) {
var options = {
series: {
fillBetween: null // or number
}
};
function init( plot ) {
function findBottomSeries( s, allseries ) {
var i;
for ( i = 0; i < allseries.length; ++i ) {
if ( allseries[ i ].id === s.fillBetween ) {
return allseries[ i ];
}
}
if ( typeof s.fillBetween === "number" ) {
if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
return null;
}
return allseries[ s.fillBetween ];
}
return null;
}
function computeFillBottoms( plot, s, datapoints ) {
if ( s.fillBetween == null ) {
return;
}
var other = findBottomSeries( s, plot.getData() );
if ( !other ) {
return;
}
var ps = datapoints.pointsize,
points = datapoints.points,
otherps = other.datapoints.pointsize,
otherpoints = other.datapoints.points,
newpoints = [],
px, py, intery, qx, qy, bottom,
withlines = s.lines.show,
withbottom = ps > 2 && datapoints.format[2].y,
withsteps = withlines && s.lines.steps,
fromgap = true,
i = 0,
j = 0,
l, m;
while ( true ) {
if ( i >= points.length ) {
break;
}
l = newpoints.length;
if ( points[ i ] == null ) {
// copy gaps
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
i += ps;
} else if ( j >= otherpoints.length ) {
// for lines, we can't use the rest of the points
if ( !withlines ) {
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
}
i += ps;
} else if ( otherpoints[ j ] == null ) {
// oops, got a gap
for ( m = 0; m < ps; ++m ) {
newpoints.push( null );
}
fromgap = true;
j += otherps;
} else {
// cases where we actually got two points
px = points[ i ];
py = points[ i + 1 ];
qx = otherpoints[ j ];
qy = otherpoints[ j + 1 ];
bottom = 0;
if ( px === qx ) {
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
//newpoints[ l + 1 ] += qy;
bottom = qy;
i += ps;
j += otherps;
} else if ( px > qx ) {
// we got past point below, might need to
// insert interpolated extra point
if ( withlines && i > 0 && points[ i - ps ] != null ) {
intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
newpoints.push( qx );
newpoints.push( intery );
for ( m = 2; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
bottom = qy;
}
j += otherps;
} else { // px < qx
// if we come from a gap, we just skip this point
if ( fromgap && withlines ) {
i += ps;
continue;
}
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
// we might be able to interpolate a point below,
// this can give us a better y
if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
}
//newpoints[l + 1] += bottom;
i += ps;
}
fromgap = false;
if ( l !== newpoints.length && withbottom ) {
newpoints[ l + 2 ] = bottom;
}
}
// maintain the line steps invariant
if ( withsteps && l !== newpoints.length && l > 0 &&
newpoints[ l ] !== null &&
newpoints[ l ] !== newpoints[ l - ps ] &&
newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
for (m = 0; m < ps; ++m) {
newpoints[ l + ps + m ] = newpoints[ l + m ];
}
newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
}
}
datapoints.points = newpoints;
}
plot.hooks.processDatapoints.push( computeFillBottoms );
}
$.plot.plugins.push({
init: init,
options: options,
name: "fillbetween",
version: "1.0"
});
})(jQuery);

View File

@@ -0,0 +1,241 @@
/* Flot plugin for plotting images.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
(x2, y2) are where you intend the two opposite corners of the image to end up
in the plot. Image must be a fully loaded Javascript image (you can make one
with new Image()). If the image is not complete, it's skipped when plotting.
There are two helpers included for retrieving images. The easiest work the way
that you put in URLs instead of images in the data, like this:
[ "myimage.png", 0, 0, 10, 10 ]
Then call $.plot.image.loadData( data, options, callback ) where data and
options are the same as you pass in to $.plot. This loads the images, replaces
the URLs in the data with the corresponding images and calls "callback" when
all images are loaded (or failed loading). In the callback, you can then call
$.plot with the data set. See the included example.
A more low-level helper, $.plot.image.load(urls, callback) is also included.
Given a list of URLs, it calls callback with an object mapping from URL to
Image object when all images are loaded or have failed loading.
The plugin supports these options:
series: {
images: {
show: boolean
anchor: "corner" or "center"
alpha: [ 0, 1 ]
}
}
They can be specified for a specific series:
$.plot( $("#placeholder"), [{
data: [ ... ],
images: { ... }
])
Note that because the data format is different from usual data points, you
can't use images with anything else in a specific data series.
Setting "anchor" to "center" causes the pixels in the image to be anchored at
the corner pixel centers inside of at the pixel corners, effectively letting
half a pixel stick out to each side in the plot.
A possible future direction could be support for tiling for large images (like
Google Maps).
*/
(function ($) {
var options = {
series: {
images: {
show: false,
alpha: 1,
anchor: "corner" // or "center"
}
}
};
$.plot.image = {};
$.plot.image.loadDataImages = function (series, options, callback) {
var urls = [], points = [];
var defaultShow = options.series.images.show;
$.each(series, function (i, s) {
if (!(defaultShow || s.images.show))
return;
if (s.data)
s = s.data;
$.each(s, function (i, p) {
if (typeof p[0] == "string") {
urls.push(p[0]);
points.push(p);
}
});
});
$.plot.image.load(urls, function (loadedImages) {
$.each(points, function (i, p) {
var url = p[0];
if (loadedImages[url])
p[0] = loadedImages[url];
});
callback();
});
}
$.plot.image.load = function (urls, callback) {
var missing = urls.length, loaded = {};
if (missing == 0)
callback({});
$.each(urls, function (i, url) {
var handler = function () {
--missing;
loaded[url] = this;
if (missing == 0)
callback(loaded);
};
$('<img />').load(handler).error(handler).attr('src', url);
});
};
function drawSeries(plot, ctx, series) {
var plotOffset = plot.getPlotOffset();
if (!series.images || !series.images.show)
return;
var points = series.datapoints.points,
ps = series.datapoints.pointsize;
for (var i = 0; i < points.length; i += ps) {
var img = points[i],
x1 = points[i + 1], y1 = points[i + 2],
x2 = points[i + 3], y2 = points[i + 4],
xaxis = series.xaxis, yaxis = series.yaxis,
tmp;
// actually we should check img.complete, but it
// appears to be a somewhat unreliable indicator in
// IE6 (false even after load event)
if (!img || img.width <= 0 || img.height <= 0)
continue;
if (x1 > x2) {
tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y1 > y2) {
tmp = y2;
y2 = y1;
y1 = tmp;
}
// if the anchor is at the center of the pixel, expand the
// image by 1/2 pixel in each direction
if (series.images.anchor == "center") {
tmp = 0.5 * (x2-x1) / (img.width - 1);
x1 -= tmp;
x2 += tmp;
tmp = 0.5 * (y2-y1) / (img.height - 1);
y1 -= tmp;
y2 += tmp;
}
// clip
if (x1 == x2 || y1 == y2 ||
x1 >= xaxis.max || x2 <= xaxis.min ||
y1 >= yaxis.max || y2 <= yaxis.min)
continue;
var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
if (x1 < xaxis.min) {
sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
x1 = xaxis.min;
}
if (x2 > xaxis.max) {
sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
x2 = xaxis.max;
}
if (y1 < yaxis.min) {
sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
y1 = yaxis.min;
}
if (y2 > yaxis.max) {
sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
y2 = yaxis.max;
}
x1 = xaxis.p2c(x1);
x2 = xaxis.p2c(x2);
y1 = yaxis.p2c(y1);
y2 = yaxis.p2c(y2);
// the transformation may have swapped us
if (x1 > x2) {
tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y1 > y2) {
tmp = y2;
y2 = y1;
y1 = tmp;
}
tmp = ctx.globalAlpha;
ctx.globalAlpha *= series.images.alpha;
ctx.drawImage(img,
sx1, sy1, sx2 - sx1, sy2 - sy1,
x1 + plotOffset.left, y1 + plotOffset.top,
x2 - x1, y2 - y1);
ctx.globalAlpha = tmp;
}
}
function processRawData(plot, series, data, datapoints) {
if (!series.images.show)
return;
// format is Image, x1, y1, x2, y2 (opposite corners)
datapoints.format = [
{ required: true },
{ x: true, number: true, required: true },
{ y: true, number: true, required: true },
{ x: true, number: true, required: true },
{ y: true, number: true, required: true }
];
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.drawSeries.push(drawSeries);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'image',
version: '1.1'
});
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
/* Flot plugin for adding the ability to pan and zoom the plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The default behaviour is double click and scrollwheel up/down to zoom in, drag
to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
plot.pan( offset ) so you easily can add custom controls. It also fires
"plotpan" and "plotzoom" events, useful for synchronizing plots.
The plugin supports these options:
zoom: {
interactive: false
trigger: "dblclick" // or "click" for single click
amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
}
pan: {
interactive: false
cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
frameRate: 20
}
xaxis, yaxis, x2axis, y2axis: {
zoomRange: null // or [ number, number ] (min range, max range) or false
panRange: null // or [ number, number ] (min, max) or false
}
"interactive" enables the built-in drag/click behaviour. If you enable
interactive for pan, then you'll have a basic plot that supports moving
around; the same for zoom.
"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
the current viewport.
"cursor" is a standard CSS mouse cursor string used for visual feedback to the
user when dragging.
"frameRate" specifies the maximum number of times per second the plot will
update itself while the user is panning around on it (set to null to disable
intermediate pans, the plot will then not update until the mouse button is
released).
"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
[1, 100] the zoom will never scale the axis so that the difference between min
and max is smaller than 1 or larger than 100. You can set either end to null
to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
will be disabled.
"panRange" confines the panning to stay within a range, e.g. with panRange:
[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
will be disabled.
Example API usage:
plot = $.plot(...);
// zoom default amount in on the pixel ( 10, 20 )
plot.zoom({ center: { left: 10, top: 20 } });
// zoom out again
plot.zoomOut({ center: { left: 10, top: 20 } });
// zoom 200% in on the pixel (10, 20)
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
// pan 100 pixels to the left and 20 down
plot.pan({ left: -100, top: 20 })
Here, "center" specifies where the center of the zooming should happen. Note
that this is defined in pixel space, not the space of the data points (you can
use the p2c helpers on the axes in Flot to help you convert between these).
"amount" is the amount to zoom the viewport relative to the current range, so
1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
can set the default in the options.
*/
// First two dependencies, jquery.event.drag.js and
// jquery.mousewheel.js, we put them inline here to save people the
// effort of downloading them.
/*
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);
/* jquery.mousewheel.min.js
* Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.6
*
* Requires: 1.2.2+
*/
(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
(function ($) {
var options = {
xaxis: {
zoomRange: null, // or [number, number] (min range, max range)
panRange: null // or [number, number] (min, max)
},
zoom: {
interactive: false,
trigger: "dblclick", // or "click" for single click
amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
},
pan: {
interactive: false,
cursor: "move",
frameRate: 20
}
};
function init(plot) {
function onZoomClick(e, zoomOut) {
var c = plot.offset();
c.left = e.pageX - c.left;
c.top = e.pageY - c.top;
if (zoomOut)
plot.zoomOut({ center: c });
else
plot.zoom({ center: c });
}
function onMouseWheel(e, delta) {
e.preventDefault();
onZoomClick(e, delta < 0);
return false;
}
var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
panTimeout = null;
function onDragStart(e) {
if (e.which != 1) // only accept left-click
return false;
var c = plot.getPlaceholder().css('cursor');
if (c)
prevCursor = c;
plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
prevPageX = e.pageX;
prevPageY = e.pageY;
}
function onDrag(e) {
var frameRate = plot.getOptions().pan.frameRate;
if (panTimeout || !frameRate)
return;
panTimeout = setTimeout(function () {
plot.pan({ left: prevPageX - e.pageX,
top: prevPageY - e.pageY });
prevPageX = e.pageX;
prevPageY = e.pageY;
panTimeout = null;
}, 1 / frameRate * 1000);
}
function onDragEnd(e) {
if (panTimeout) {
clearTimeout(panTimeout);
panTimeout = null;
}
plot.getPlaceholder().css('cursor', prevCursor);
plot.pan({ left: prevPageX - e.pageX,
top: prevPageY - e.pageY });
}
function bindEvents(plot, eventHolder) {
var o = plot.getOptions();
if (o.zoom.interactive) {
eventHolder[o.zoom.trigger](onZoomClick);
eventHolder.mousewheel(onMouseWheel);
}
if (o.pan.interactive) {
eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
eventHolder.bind("drag", onDrag);
eventHolder.bind("dragend", onDragEnd);
}
}
plot.zoomOut = function (args) {
if (!args)
args = {};
if (!args.amount)
args.amount = plot.getOptions().zoom.amount;
args.amount = 1 / args.amount;
plot.zoom(args);
};
plot.zoom = function (args) {
if (!args)
args = {};
var c = args.center,
amount = args.amount || plot.getOptions().zoom.amount,
w = plot.width(), h = plot.height();
if (!c)
c = { left: w / 2, top: h / 2 };
var xf = c.left / w,
yf = c.top / h,
minmax = {
x: {
min: c.left - xf * w / amount,
max: c.left + (1 - xf) * w / amount
},
y: {
min: c.top - yf * h / amount,
max: c.top + (1 - yf) * h / amount
}
};
$.each(plot.getAxes(), function(_, axis) {
var opts = axis.options,
min = minmax[axis.direction].min,
max = minmax[axis.direction].max,
zr = opts.zoomRange,
pr = opts.panRange;
if (zr === false) // no zooming on this axis
return;
min = axis.c2p(min);
max = axis.c2p(max);
if (min > max) {
// make sure min < max
var tmp = min;
min = max;
max = tmp;
}
//Check that we are in panRange
if (pr) {
if (pr[0] != null && min < pr[0]) {
min = pr[0];
}
if (pr[1] != null && max > pr[1]) {
max = pr[1];
}
}
var range = max - min;
if (zr &&
((zr[0] != null && range < zr[0] && amount >1) ||
(zr[1] != null && range > zr[1] && amount <1)))
return;
opts.min = min;
opts.max = max;
});
plot.setupGrid();
plot.draw();
if (!args.preventEvent)
plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
};
plot.pan = function (args) {
var delta = {
x: +args.left,
y: +args.top
};
if (isNaN(delta.x))
delta.x = 0;
if (isNaN(delta.y))
delta.y = 0;
$.each(plot.getAxes(), function (_, axis) {
var opts = axis.options,
min, max, d = delta[axis.direction];
min = axis.c2p(axis.p2c(axis.min) + d),
max = axis.c2p(axis.p2c(axis.max) + d);
var pr = opts.panRange;
if (pr === false) // no panning on this axis
return;
if (pr) {
// check whether we hit the wall
if (pr[0] != null && pr[0] > min) {
d = pr[0] - min;
min += d;
max += d;
}
if (pr[1] != null && pr[1] < max) {
d = pr[1] - max;
min += d;
max += d;
}
}
opts.min = min;
opts.max = max;
});
plot.setupGrid();
plot.draw();
if (!args.preventEvent)
plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
};
function shutdown(plot, eventHolder) {
eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
eventHolder.unbind("mousewheel", onMouseWheel);
eventHolder.unbind("dragstart", onDragStart);
eventHolder.unbind("drag", onDrag);
eventHolder.unbind("dragend", onDragEnd);
if (panTimeout)
clearTimeout(panTimeout);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'navigate',
version: '1.3'
});
})(jQuery);

View File

@@ -0,0 +1,820 @@
/* Flot plugin for rendering pie charts.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin assumes that each series has a single data value, and that each
value is a positive integer or zero. Negative numbers don't make sense for a
pie chart, and have unpredictable results. The values do NOT need to be
passed in as percentages; the plugin will calculate the total and per-slice
percentages internally.
* Created by Brian Medendorp
* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
The plugin supports these options:
series: {
pie: {
show: true/false
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
offset: {
top: integer value to move the pie up or down
left: integer value to move the pie left or right, or 'auto'
},
stroke: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
width: integer pixel width of the stroke
},
label: {
show: true/false, or 'auto'
formatter: a user-defined function that modifies the text/style of the label text
radius: 0-1 for percentage of fullsize, or a specified pixel length
background: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
opacity: 0-1
},
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
},
combine: {
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
label: any text value of what the combined slice should be labeled
}
highlight: {
opacity: 0-1
}
}
}
More detail and specific examples can be found in the included HTML file.
*/
(function($) {
// Maximum redraw attempts when fitting labels within the plot
var REDRAW_ATTEMPTS = 10;
// Factor by which to shrink the pie when fitting labels within the plot
var REDRAW_SHRINK = 0.95;
function init(plot) {
var canvas = null,
target = null,
options = null,
maxRadius = null,
centerLeft = null,
centerTop = null,
processed = false,
ctx = null;
// interactive variables
var highlights = [];
// add hook to determine if pie plugin in enabled, and then perform necessary operations
plot.hooks.processOptions.push(function(plot, options) {
if (options.series.pie.show) {
options.grid.show = false;
// set labels.show
if (options.series.pie.label.show == "auto") {
if (options.legend.show) {
options.series.pie.label.show = false;
} else {
options.series.pie.label.show = true;
}
}
// set radius
if (options.series.pie.radius == "auto") {
if (options.series.pie.label.show) {
options.series.pie.radius = 3/4;
} else {
options.series.pie.radius = 1;
}
}
// ensure sane tilt
if (options.series.pie.tilt > 1) {
options.series.pie.tilt = 1;
} else if (options.series.pie.tilt < 0) {
options.series.pie.tilt = 0;
}
}
});
plot.hooks.bindEvents.push(function(plot, eventHolder) {
var options = plot.getOptions();
if (options.series.pie.show) {
if (options.grid.hoverable) {
eventHolder.unbind("mousemove").mousemove(onMouseMove);
}
if (options.grid.clickable) {
eventHolder.unbind("click").click(onClick);
}
}
});
plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
var options = plot.getOptions();
if (options.series.pie.show) {
processDatapoints(plot, series, data, datapoints);
}
});
plot.hooks.drawOverlay.push(function(plot, octx) {
var options = plot.getOptions();
if (options.series.pie.show) {
drawOverlay(plot, octx);
}
});
plot.hooks.draw.push(function(plot, newCtx) {
var options = plot.getOptions();
if (options.series.pie.show) {
draw(plot, newCtx);
}
});
function processDatapoints(plot, series, datapoints) {
if (!processed) {
processed = true;
canvas = plot.getCanvas();
target = $(canvas).parent();
options = plot.getOptions();
plot.setData(combine(plot.getData()));
}
}
function combine(data) {
var total = 0,
combined = 0,
numCombined = 0,
color = options.series.pie.combine.color,
newdata = [];
// Fix up the raw data from Flot, ensuring the data is numeric
for (var i = 0; i < data.length; ++i) {
var value = data[i].data;
// If the data is an array, we'll assume that it's a standard
// Flot x-y pair, and are concerned only with the second value.
// Note how we use the original array, rather than creating a
// new one; this is more efficient and preserves any extra data
// that the user may have stored in higher indexes.
if ($.isArray(value) && value.length == 1) {
value = value[0];
}
if ($.isArray(value)) {
// Equivalent to $.isNumeric() but compatible with jQuery < 1.7
if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
value[1] = +value[1];
} else {
value[1] = 0;
}
} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
value = [1, +value];
} else {
value = [1, 0];
}
data[i].data = [value];
}
// Sum up all the slices, so we can calculate percentages for each
for (var i = 0; i < data.length; ++i) {
total += data[i].data[0][1];
}
// Count the number of slices with percentages below the combine
// threshold; if it turns out to be just one, we won't combine.
for (var i = 0; i < data.length; ++i) {
var value = data[i].data[0][1];
if (value / total <= options.series.pie.combine.threshold) {
combined += value;
numCombined++;
if (!color) {
color = data[i].color;
}
}
}
for (var i = 0; i < data.length; ++i) {
var value = data[i].data[0][1];
if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
newdata.push(
$.extend(data[i], { /* extend to allow keeping all other original data values
and using them e.g. in labelFormatter. */
data: [[1, value]],
color: data[i].color,
label: data[i].label,
angle: value * Math.PI * 2 / total,
percent: value / (total / 100)
})
);
}
}
if (numCombined > 1) {
newdata.push({
data: [[1, combined]],
color: color,
label: options.series.pie.combine.label,
angle: combined * Math.PI * 2 / total,
percent: combined / (total / 100)
});
}
return newdata;
}
function draw(plot, newCtx) {
if (!target) {
return; // if no series were passed
}
var canvasWidth = plot.getPlaceholder().width(),
canvasHeight = plot.getPlaceholder().height(),
legendWidth = target.children().filter(".legend").children().width() || 0;
ctx = newCtx;
// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
// When combining smaller slices into an 'other' slice, we need to
// add a new series. Since Flot gives plugins no way to modify the
// list of series, the pie plugin uses a hack where the first call
// to processDatapoints results in a call to setData with the new
// list of series, then subsequent processDatapoints do nothing.
// The plugin-global 'processed' flag is used to control this hack;
// it starts out false, and is set to true after the first call to
// processDatapoints.
// Unfortunately this turns future setData calls into no-ops; they
// call processDatapoints, the flag is true, and nothing happens.
// To fix this we'll set the flag back to false here in draw, when
// all series have been processed, so the next sequence of calls to
// processDatapoints once again starts out with a slice-combine.
// This is really a hack; in 0.9 we need to give plugins a proper
// way to modify series before any processing begins.
processed = false;
// calculate maximum radius and center point
maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
centerTop = canvasHeight / 2 + options.series.pie.offset.top;
centerLeft = canvasWidth / 2;
if (options.series.pie.offset.left == "auto") {
if (options.legend.position.match("w")) {
centerLeft += legendWidth / 2;
} else {
centerLeft -= legendWidth / 2;
}
if (centerLeft < maxRadius) {
centerLeft = maxRadius;
} else if (centerLeft > canvasWidth - maxRadius) {
centerLeft = canvasWidth - maxRadius;
}
} else {
centerLeft += options.series.pie.offset.left;
}
var slices = plot.getData(),
attempts = 0;
// Keep shrinking the pie's radius until drawPie returns true,
// indicating that all the labels fit, or we try too many times.
do {
if (attempts > 0) {
maxRadius *= REDRAW_SHRINK;
}
attempts += 1;
clear();
if (options.series.pie.tilt <= 0.8) {
drawShadow();
}
} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
if (attempts >= REDRAW_ATTEMPTS) {
clear();
target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
}
if (plot.setSeries && plot.insertLegend) {
plot.setSeries(slices);
plot.insertLegend();
}
// we're actually done at this point, just defining internal functions at this point
function clear() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
target.children().filter(".pieLabel, .pieLabelBackground").remove();
}
function drawShadow() {
var shadowLeft = options.series.pie.shadow.left;
var shadowTop = options.series.pie.shadow.top;
var edge = 10;
var alpha = options.series.pie.shadow.alpha;
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
return; // shadow would be outside canvas, so don't draw it
}
ctx.save();
ctx.translate(shadowLeft,shadowTop);
ctx.globalAlpha = alpha;
ctx.fillStyle = "#000";
// center and rotate to starting position
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//radius -= edge;
for (var i = 1; i <= edge; i++) {
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
ctx.fill();
radius -= i;
}
ctx.restore();
}
function drawPie() {
var startAngle = Math.PI * options.series.pie.startAngle;
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
// center and rotate to starting position
ctx.save();
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
// draw slices
ctx.save();
var currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i) {
slices[i].startAngle = currentAngle;
drawSlice(slices[i].angle, slices[i].color, true);
}
ctx.restore();
// draw slice outlines
if (options.series.pie.stroke.width > 0) {
ctx.save();
ctx.lineWidth = options.series.pie.stroke.width;
currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i) {
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
}
ctx.restore();
}
// draw donut hole
drawDonutHole(ctx);
ctx.restore();
// Draw the labels, returning true if they fit within the plot
if (options.series.pie.label.show) {
return drawLabels();
} else return true;
function drawSlice(angle, color, fill) {
if (angle <= 0 || isNaN(angle)) {
return;
}
if (fill) {
ctx.fillStyle = color;
} else {
ctx.strokeStyle = color;
ctx.lineJoin = "round";
}
ctx.beginPath();
if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
ctx.moveTo(0, 0); // Center of the pie
}
//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
ctx.closePath();
//ctx.rotate(angle); // This doesn't work properly in Opera
currentAngle += angle;
if (fill) {
ctx.fill();
} else {
ctx.stroke();
}
}
function drawLabels() {
var currentAngle = startAngle;
var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
for (var i = 0; i < slices.length; ++i) {
if (slices[i].percent >= options.series.pie.label.threshold * 100) {
if (!drawLabel(slices[i], currentAngle, i)) {
return false;
}
}
currentAngle += slices[i].angle;
}
return true;
function drawLabel(slice, startAngle, index) {
if (slice.data[0][1] == 0) {
return true;
}
// format label text
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
if (lf) {
text = lf(slice.label, slice);
} else {
text = slice.label;
}
if (plf) {
text = plf(text, slice);
}
var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>";
target.append(html);
var label = target.children("#pieLabel" + index);
var labelTop = (y - label.height() / 2);
var labelLeft = (x - label.width() / 2);
label.css("top", labelTop);
label.css("left", labelLeft);
// check to make sure that the label is not outside the canvas
if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
return false;
}
if (options.series.pie.label.background.opacity != 0) {
// put in the transparent background separately to avoid blended labels and label boxes
var c = options.series.pie.label.background.color;
if (c == null) {
c = slice.color;
}
var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
$("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>")
.css("opacity", options.series.pie.label.background.opacity)
.insertBefore(label);
}
return true;
} // end individual label function
} // end drawLabels function
} // end drawPie function
} // end draw function
// Placed here because it needs to be accessed from multiple locations
function drawDonutHole(layer) {
if (options.series.pie.innerRadius > 0) {
// subtract the center
layer.save();
var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
layer.beginPath();
layer.fillStyle = options.series.pie.stroke.color;
layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
layer.fill();
layer.closePath();
layer.restore();
// add inner stroke
layer.save();
layer.beginPath();
layer.strokeStyle = options.series.pie.stroke.color;
layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
layer.stroke();
layer.closePath();
layer.restore();
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
}
}
//-- Additional Interactive related functions --
function isPointInPoly(poly, pt) {
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
function findNearbySlice(mouseX, mouseY) {
var slices = plot.getData(),
options = plot.getOptions(),
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
x, y;
for (var i = 0; i < slices.length; ++i) {
var s = slices[i];
if (s.pie.show) {
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0); // Center of the pie
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
ctx.closePath();
x = mouseX - centerLeft;
y = mouseY - centerTop;
if (ctx.isPointInPath) {
if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
ctx.restore();
return {
datapoint: [s.percent, s.data],
dataIndex: 0,
series: s,
seriesIndex: i
};
}
} else {
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
var p1X = radius * Math.cos(s.startAngle),
p1Y = radius * Math.sin(s.startAngle),
p2X = radius * Math.cos(s.startAngle + s.angle / 4),
p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
p3X = radius * Math.cos(s.startAngle + s.angle / 2),
p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
p5X = radius * Math.cos(s.startAngle + s.angle),
p5Y = radius * Math.sin(s.startAngle + s.angle),
arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
arrPoint = [x, y];
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
if (isPointInPoly(arrPoly, arrPoint)) {
ctx.restore();
return {
datapoint: [s.percent, s.data],
dataIndex: 0,
series: s,
seriesIndex: i
};
}
}
ctx.restore();
}
}
return null;
}
function onMouseMove(e) {
triggerClickHoverEvent("plothover", e);
}
function onClick(e) {
triggerClickHoverEvent("plotclick", e);
}
// trigger click or hover event (they send the same parameters so we share their code)
function triggerClickHoverEvent(eventname, e) {
var offset = plot.offset();
var canvasX = parseInt(e.pageX - offset.left);
var canvasY = parseInt(e.pageY - offset.top);
var item = findNearbySlice(canvasX, canvasY);
if (options.grid.autoHighlight) {
// clear auto-highlights
for (var i = 0; i < highlights.length; ++i) {
var h = highlights[i];
if (h.auto == eventname && !(item && h.series == item.series)) {
unhighlight(h.series);
}
}
}
// highlight the slice
if (item) {
highlight(item.series, eventname);
}
// trigger any hover bind events
var pos = { pageX: e.pageX, pageY: e.pageY };
target.trigger(eventname, [pos, item]);
}
function highlight(s, auto) {
//if (typeof s == "number") {
// s = series[s];
//}
var i = indexOfHighlight(s);
if (i == -1) {
highlights.push({ series: s, auto: auto });
plot.triggerRedrawOverlay();
} else if (!auto) {
highlights[i].auto = false;
}
}
function unhighlight(s) {
if (s == null) {
highlights = [];
plot.triggerRedrawOverlay();
}
//if (typeof s == "number") {
// s = series[s];
//}
var i = indexOfHighlight(s);
if (i != -1) {
highlights.splice(i, 1);
plot.triggerRedrawOverlay();
}
}
function indexOfHighlight(s) {
for (var i = 0; i < highlights.length; ++i) {
var h = highlights[i];
if (h.series == s)
return i;
}
return -1;
}
function drawOverlay(plot, octx) {
var options = plot.getOptions();
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
octx.save();
octx.translate(centerLeft, centerTop);
octx.scale(1, options.series.pie.tilt);
for (var i = 0; i < highlights.length; ++i) {
drawHighlight(highlights[i].series);
}
drawDonutHole(octx);
octx.restore();
function drawHighlight(series) {
if (series.angle <= 0 || isNaN(series.angle)) {
return;
}
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
octx.beginPath();
if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
octx.moveTo(0, 0); // Center of the pie
}
octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
octx.closePath();
octx.fill();
}
}
} // end init (plugin body)
// define pie specific options and their default values
var options = {
series: {
pie: {
show: false,
radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
innerRadius: 0, /* for donut */
startAngle: 3/2,
tilt: 1,
shadow: {
left: 5, // shadow left offset
top: 15, // shadow top offset
alpha: 0.02 // shadow alpha
},
offset: {
top: 0,
left: "auto"
},
stroke: {
color: "#fff",
width: 1
},
label: {
show: "auto",
formatter: function(label, slice) {
return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>";
}, // formatter function
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
background: {
color: null,
opacity: 0
},
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
},
combine: {
threshold: -1, // percentage at which to combine little slices into one larger slice
color: null, // color to give the new slice (auto-generated if null)
label: "Other" // label to give the new slice
},
highlight: {
//color: "#fff", // will add this functionality once parseColor is available
opacity: 0.5
}
}
}
};
$.plot.plugins.push({
init: init,
options: options,
name: "pie",
version: "1.1"
});
})(jQuery);

View File

@@ -0,0 +1,59 @@
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
It works by listening for changes on the placeholder div (through the jQuery
resize event plugin) - if the size changes, it will redraw the plot.
There are no options. If you need to disable the plugin for some plots, you
can just fix the size of their placeholders.
*/
/* Inline dependency:
* jQuery resize event - v1.1 - 3/14/2010
* http://benalman.com/projects/jquery-resize-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
(function ($) {
var options = { }; // no options
function init(plot) {
function onResize() {
var placeholder = plot.getPlaceholder();
// somebody might have hidden us and we can't plot
// when we don't have the dimensions
if (placeholder.width() == 0 || placeholder.height() == 0)
return;
plot.resize();
plot.setupGrid();
plot.draw();
}
function bindEvents(plot, eventHolder) {
plot.getPlaceholder().resize(onResize);
}
function shutdown(plot, eventHolder) {
plot.getPlaceholder().unbind("resize", onResize);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'resize',
version: '1.0'
});
})(jQuery);

View File

@@ -0,0 +1,360 @@
/* Flot plugin for selecting regions of a plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
selection: {
mode: null or "x" or "y" or "xy",
color: color,
shape: "round" or "miter" or "bevel",
minSize: number of pixels
}
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
In "x" mode, the user will only be able to specify the x range, similarly for
"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
specified. "color" is color of the selection (if you need to change the color
later on, you can get to it with plot.getOptions().selection.color). "shape"
is the shape of the corners of the selection.
"minSize" is the minimum size a selection can be in pixels. This value can
be customized to determine the smallest size a selection can be and still
have the selection rectangle be displayed. When customizing this value, the
fact that it refers to pixels, not axis units must be taken into account.
Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
minute, setting "minSize" to 1 will not make the minimum selection size 1
minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
"plotunselected" events from being fired when the user clicks the mouse without
dragging.
When selection support is enabled, a "plotselected" event will be emitted on
the DOM element you passed into the plot function. The event handler gets a
parameter with the ranges selected on the axes, like this:
placeholder.bind( "plotselected", function( event, ranges ) {
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
// similar for yaxis - with multiple axes, the extra ones are in
// x2axis, x3axis, ...
});
The "plotselected" event is only fired when the user has finished making the
selection. A "plotselecting" event is fired during the process with the same
parameters as the "plotselected" event, in case you want to know what's
happening while it's happening,
A "plotunselected" event with no arguments is emitted when the user clicks the
mouse to remove the selection. As stated above, setting "minSize" to 0 will
destroy this behavior.
The plugin allso adds the following methods to the plot object:
- setSelection( ranges, preventEvent )
Set the selection rectangle. The passed in ranges is on the same form as
returned in the "plotselected" event. If the selection mode is "x", you
should put in either an xaxis range, if the mode is "y" you need to put in
an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
this:
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
setSelection will trigger the "plotselected" event when called. If you don't
want that to happen, e.g. if you're inside a "plotselected" handler, pass
true as the second parameter. If you are using multiple axes, you can
specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
xaxis, the plugin picks the first one it sees.
- clearSelection( preventEvent )
Clear the selection rectangle. Pass in true to avoid getting a
"plotunselected" event.
- getSelection()
Returns the current selection in the same format as the "plotselected"
event. If there's currently no selection, the function returns null.
*/
(function ($) {
function init(plot) {
var selection = {
first: { x: -1, y: -1}, second: { x: -1, y: -1},
show: false,
active: false
};
// FIXME: The drag handling implemented here should be
// abstracted out, there's some similar code from a library in
// the navigation plugin, this should be massaged a bit to fit
// the Flot cases here better and reused. Doing this would
// make this plugin much slimmer.
var savedhandlers = {};
var mouseUpHandler = null;
function onMouseMove(e) {
if (selection.active) {
updateSelection(e);
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
}
}
function onMouseDown(e) {
if (e.which != 1) // only accept left-click
return;
// cancel out any text selections
document.body.focus();
// prevent text selection and drag in old-school browsers
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
savedhandlers.onselectstart = document.onselectstart;
document.onselectstart = function () { return false; };
}
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
savedhandlers.ondrag = document.ondrag;
document.ondrag = function () { return false; };
}
setSelectionPos(selection.first, e);
selection.active = true;
// this is a bit silly, but we have to use a closure to be
// able to whack the same handler again
mouseUpHandler = function (e) { onMouseUp(e); };
$(document).one("mouseup", mouseUpHandler);
}
function onMouseUp(e) {
mouseUpHandler = null;
// revert drag stuff for old-school browsers
if (document.onselectstart !== undefined)
document.onselectstart = savedhandlers.onselectstart;
if (document.ondrag !== undefined)
document.ondrag = savedhandlers.ondrag;
// no more dragging
selection.active = false;
updateSelection(e);
if (selectionIsSane())
triggerSelectedEvent();
else {
// this counts as a clear
plot.getPlaceholder().trigger("plotunselected", [ ]);
plot.getPlaceholder().trigger("plotselecting", [ null ]);
}
return false;
}
function getSelection() {
if (!selectionIsSane())
return null;
if (!selection.show) return null;
var r = {}, c1 = selection.first, c2 = selection.second;
$.each(plot.getAxes(), function (name, axis) {
if (axis.used) {
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
}
});
return r;
}
function triggerSelectedEvent() {
var r = getSelection();
plot.getPlaceholder().trigger("plotselected", [ r ]);
// backwards-compat stuff, to be removed in future
if (r.xaxis && r.yaxis)
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
}
function clamp(min, value, max) {
return value < min ? min: (value > max ? max: value);
}
function setSelectionPos(pos, e) {
var o = plot.getOptions();
var offset = plot.getPlaceholder().offset();
var plotOffset = plot.getPlotOffset();
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
if (o.selection.mode == "y")
pos.x = pos == selection.first ? 0 : plot.width();
if (o.selection.mode == "x")
pos.y = pos == selection.first ? 0 : plot.height();
}
function updateSelection(pos) {
if (pos.pageX == null)
return;
setSelectionPos(selection.second, pos);
if (selectionIsSane()) {
selection.show = true;
plot.triggerRedrawOverlay();
}
else
clearSelection(true);
}
function clearSelection(preventEvent) {
if (selection.show) {
selection.show = false;
plot.triggerRedrawOverlay();
if (!preventEvent)
plot.getPlaceholder().trigger("plotunselected", [ ]);
}
}
// function taken from markings support in Flot
function extractRange(ranges, coord) {
var axis, from, to, key, axes = plot.getAxes();
for (var k in axes) {
axis = axes[k];
if (axis.direction == coord) {
key = coord + axis.n + "axis";
if (!ranges[key] && axis.n == 1)
key = coord + "axis"; // support x1axis as xaxis
if (ranges[key]) {
from = ranges[key].from;
to = ranges[key].to;
break;
}
}
}
// backwards-compat stuff - to be removed in future
if (!ranges[key]) {
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
from = ranges[coord + "1"];
to = ranges[coord + "2"];
}
// auto-reverse as an added bonus
if (from != null && to != null && from > to) {
var tmp = from;
from = to;
to = tmp;
}
return { from: from, to: to, axis: axis };
}
function setSelection(ranges, preventEvent) {
var axis, range, o = plot.getOptions();
if (o.selection.mode == "y") {
selection.first.x = 0;
selection.second.x = plot.width();
}
else {
range = extractRange(ranges, "x");
selection.first.x = range.axis.p2c(range.from);
selection.second.x = range.axis.p2c(range.to);
}
if (o.selection.mode == "x") {
selection.first.y = 0;
selection.second.y = plot.height();
}
else {
range = extractRange(ranges, "y");
selection.first.y = range.axis.p2c(range.from);
selection.second.y = range.axis.p2c(range.to);
}
selection.show = true;
plot.triggerRedrawOverlay();
if (!preventEvent && selectionIsSane())
triggerSelectedEvent();
}
function selectionIsSane() {
var minSize = plot.getOptions().selection.minSize;
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
Math.abs(selection.second.y - selection.first.y) >= minSize;
}
plot.clearSelection = clearSelection;
plot.setSelection = setSelection;
plot.getSelection = getSelection;
plot.hooks.bindEvents.push(function(plot, eventHolder) {
var o = plot.getOptions();
if (o.selection.mode != null) {
eventHolder.mousemove(onMouseMove);
eventHolder.mousedown(onMouseDown);
}
});
plot.hooks.drawOverlay.push(function (plot, ctx) {
// draw selection
if (selection.show && selectionIsSane()) {
var plotOffset = plot.getPlotOffset();
var o = plot.getOptions();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
var c = $.color.parse(o.selection.color);
ctx.strokeStyle = c.scale('a', 0.8).toString();
ctx.lineWidth = 1;
ctx.lineJoin = o.selection.shape;
ctx.fillStyle = c.scale('a', 0.4).toString();
var x = Math.min(selection.first.x, selection.second.x) + 0.5,
y = Math.min(selection.first.y, selection.second.y) + 0.5,
w = Math.abs(selection.second.x - selection.first.x) - 1,
h = Math.abs(selection.second.y - selection.first.y) - 1;
ctx.fillRect(x, y, w, h);
ctx.strokeRect(x, y, w, h);
ctx.restore();
}
});
plot.hooks.shutdown.push(function (plot, eventHolder) {
eventHolder.unbind("mousemove", onMouseMove);
eventHolder.unbind("mousedown", onMouseDown);
if (mouseUpHandler)
$(document).unbind("mouseup", mouseUpHandler);
});
}
$.plot.plugins.push({
init: init,
options: {
selection: {
mode: null, // one of null, "x", "y" or "xy"
color: "#e8cfac",
shape: "round", // one of "round", "miter", or "bevel"
minSize: 5 // minimum number of pixels
}
},
name: 'selection',
version: '1.1'
});
})(jQuery);

View File

@@ -0,0 +1,188 @@
/* Flot plugin for stacking data sets rather than overlyaing them.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin assumes the data is sorted on x (or y if stacking horizontally).
For line charts, it is assumed that if a line has an undefined gap (from a
null point), then the line above it should have the same gap - insert zeros
instead of "null" if you want another behaviour. This also holds for the start
and end of the chart. Note that stacking a mix of positive and negative values
in most instances doesn't make sense (so it looks weird).
Two or more series are stacked when their "stack" attribute is set to the same
key (which can be any number or string or just "true"). To specify the default
stack, you can set the stack option like this:
series: {
stack: null/false, true, or a key (number/string)
}
You can also specify it for a single series, like this:
$.plot( $("#placeholder"), [{
data: [ ... ],
stack: true
}])
The stacking order is determined by the order of the data series in the array
(later series end up on top of the previous).
Internally, the plugin modifies the datapoints in each series, adding an
offset to the y value. For line series, extra data points are inserted through
interpolation. If there's a second y value, it's also adjusted (e.g for bar
charts or filled areas).
*/
(function ($) {
var options = {
series: { stack: null } // or number/string
};
function init(plot) {
function findMatchingSeries(s, allseries) {
var res = null;
for (var i = 0; i < allseries.length; ++i) {
if (s == allseries[i])
break;
if (allseries[i].stack == s.stack)
res = allseries[i];
}
return res;
}
function stackData(plot, s, datapoints) {
if (s.stack == null || s.stack === false)
return;
var other = findMatchingSeries(s, plot.getData());
if (!other)
return;
var ps = datapoints.pointsize,
points = datapoints.points,
otherps = other.datapoints.pointsize,
otherpoints = other.datapoints.points,
newpoints = [],
px, py, intery, qx, qy, bottom,
withlines = s.lines.show,
horizontal = s.bars.horizontal,
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
withsteps = withlines && s.lines.steps,
fromgap = true,
keyOffset = horizontal ? 1 : 0,
accumulateOffset = horizontal ? 0 : 1,
i = 0, j = 0, l, m;
while (true) {
if (i >= points.length)
break;
l = newpoints.length;
if (points[i] == null) {
// copy gaps
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
i += ps;
}
else if (j >= otherpoints.length) {
// for lines, we can't use the rest of the points
if (!withlines) {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
}
i += ps;
}
else if (otherpoints[j] == null) {
// oops, got a gap
for (m = 0; m < ps; ++m)
newpoints.push(null);
fromgap = true;
j += otherps;
}
else {
// cases where we actually got two points
px = points[i + keyOffset];
py = points[i + accumulateOffset];
qx = otherpoints[j + keyOffset];
qy = otherpoints[j + accumulateOffset];
bottom = 0;
if (px == qx) {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
newpoints[l + accumulateOffset] += qy;
bottom = qy;
i += ps;
j += otherps;
}
else if (px > qx) {
// we got past point below, might need to
// insert interpolated extra point
if (withlines && i > 0 && points[i - ps] != null) {
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
newpoints.push(qx);
newpoints.push(intery + qy);
for (m = 2; m < ps; ++m)
newpoints.push(points[i + m]);
bottom = qy;
}
j += otherps;
}
else { // px < qx
if (fromgap && withlines) {
// if we come from a gap, we just skip this point
i += ps;
continue;
}
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
// we might be able to interpolate a point below,
// this can give us a better y
if (withlines && j > 0 && otherpoints[j - otherps] != null)
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
newpoints[l + accumulateOffset] += bottom;
i += ps;
}
fromgap = false;
if (l != newpoints.length && withbottom)
newpoints[l + 2] += bottom;
}
// maintain the line steps invariant
if (withsteps && l != newpoints.length && l > 0
&& newpoints[l] != null
&& newpoints[l] != newpoints[l - ps]
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
for (m = 0; m < ps; ++m)
newpoints[l + ps + m] = newpoints[l + m];
newpoints[l + 1] = newpoints[l - ps + 1];
}
}
datapoints.points = newpoints;
}
plot.hooks.processDatapoints.push(stackData);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'stack',
version: '1.2'
});
})(jQuery);

View File

@@ -0,0 +1,71 @@
/* Flot plugin that adds some extra symbols for plotting points.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The symbols are accessed as strings through the standard symbol options:
series: {
points: {
symbol: "square" // or "diamond", "triangle", "cross"
}
}
*/
(function ($) {
function processRawData(plot, series, datapoints) {
// we normalize the area of each symbol so it is approximately the
// same as a circle of the given radius
var handlers = {
square: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
diamond: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
var size = radius * Math.sqrt(Math.PI / 2);
ctx.moveTo(x - size, y);
ctx.lineTo(x, y - size);
ctx.lineTo(x + size, y);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size, y);
},
triangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
var height = size * Math.sin(Math.PI / 3);
ctx.moveTo(x - size/2, y + height/2);
ctx.lineTo(x + size/2, y + height/2);
if (!shadow) {
ctx.lineTo(x, y - height/2);
ctx.lineTo(x - size/2, y + height/2);
}
},
cross: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
}
};
var s = series.points.symbol;
if (handlers[s])
series.points.symbol = handlers[s];
}
function init(plot) {
plot.hooks.processDatapoints.push(processRawData);
}
$.plot.plugins.push({
init: init,
name: 'symbols',
version: '1.0'
});
})(jQuery);

View File

@@ -0,0 +1,142 @@
/* Flot plugin for thresholding data.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
series: {
threshold: {
below: number
color: colorspec
}
}
It can also be applied to a single series, like this:
$.plot( $("#placeholder"), [{
data: [ ... ],
threshold: { ... }
}])
An array can be passed for multiple thresholding, like this:
threshold: [{
below: number1
color: color1
},{
below: number2
color: color2
}]
These multiple threshold objects can be passed in any order since they are
sorted by the processing function.
The data points below "below" are drawn with the specified color. This makes
it easy to mark points below 0, e.g. for budget data.
Internally, the plugin works by splitting the data into two series, above and
below the threshold. The extra series below the threshold will have its label
cleared and the special "originSeries" attribute set to the original series.
You may need to check for this in hover events.
*/
(function ($) {
var options = {
series: { threshold: null } // or { below: number, color: color spec}
};
function init(plot) {
function thresholdData(plot, s, datapoints, below, color) {
var ps = datapoints.pointsize, i, x, y, p, prevp,
thresholded = $.extend({}, s); // note: shallow copy
thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
thresholded.label = null;
thresholded.color = color;
thresholded.threshold = null;
thresholded.originSeries = s;
thresholded.data = [];
var origpoints = datapoints.points,
addCrossingPoints = s.lines.show;
var threspoints = [];
var newpoints = [];
var m;
for (i = 0; i < origpoints.length; i += ps) {
x = origpoints[i];
y = origpoints[i + 1];
prevp = p;
if (y < below)
p = threspoints;
else
p = newpoints;
if (addCrossingPoints && prevp != p && x != null
&& i > 0 && origpoints[i - ps] != null) {
var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
prevp.push(interx);
prevp.push(below);
for (m = 2; m < ps; ++m)
prevp.push(origpoints[i + m]);
p.push(null); // start new segment
p.push(null);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
p.push(interx);
p.push(below);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
}
p.push(x);
p.push(y);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
}
datapoints.points = newpoints;
thresholded.datapoints.points = threspoints;
if (thresholded.datapoints.points.length > 0) {
var origIndex = $.inArray(s, plot.getData());
// Insert newly-generated series right after original one (to prevent it from becoming top-most)
plot.getData().splice(origIndex + 1, 0, thresholded);
}
// FIXME: there are probably some edge cases left in bars
}
function processThresholds(plot, s, datapoints) {
if (!s.threshold)
return;
if (s.threshold instanceof Array) {
s.threshold.sort(function(a, b) {
return a.below - b.below;
});
$(s.threshold).each(function(i, th) {
thresholdData(plot, s, datapoints, th.below, th.color);
});
}
else {
thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
}
}
plot.hooks.processDatapoints.push(processThresholds);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'threshold',
version: '1.2'
});
})(jQuery);

View File

@@ -0,0 +1,432 @@
/* Pretty handling of time axes.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Set axis.mode to "time" to enable. See the section "Time series data" in
API.txt for details.
*/
(function($) {
var options = {
xaxis: {
timezone: null, // "browser" for local to the client or timezone for timezone-js
timeformat: null, // format string to use
twelveHourClock: false, // 12 or 24 time in time mode
monthNames: null // list of names of months
}
};
// round to nearby lower multiple of base
function floorInBase(n, base) {
return base * Math.floor(n / base);
}
// Returns a string with the date d formatted according to fmt.
// A subset of the Open Group's strftime format is supported.
function formatDate(d, fmt, monthNames, dayNames) {
if (typeof d.strftime == "function") {
return d.strftime(fmt);
}
var leftPad = function(n, pad) {
n = "" + n;
pad = "" + (pad == null ? "0" : pad);
return n.length == 1 ? pad + n : n;
};
var r = [];
var escape = false;
var hours = d.getHours();
var isAM = hours < 12;
if (monthNames == null) {
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
}
if (dayNames == null) {
dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
}
var hours12;
if (hours > 12) {
hours12 = hours - 12;
} else if (hours == 0) {
hours12 = 12;
} else {
hours12 = hours;
}
for (var i = 0; i < fmt.length; ++i) {
var c = fmt.charAt(i);
if (escape) {
switch (c) {
case 'a': c = "" + dayNames[d.getDay()]; break;
case 'b': c = "" + monthNames[d.getMonth()]; break;
case 'd': c = leftPad(d.getDate()); break;
case 'e': c = leftPad(d.getDate(), " "); break;
case 'h': // For back-compat with 0.7; remove in 1.0
case 'H': c = leftPad(hours); break;
case 'I': c = leftPad(hours12); break;
case 'l': c = leftPad(hours12, " "); break;
case 'm': c = leftPad(d.getMonth() + 1); break;
case 'M': c = leftPad(d.getMinutes()); break;
// quarters not in Open Group's strftime specification
case 'q':
c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
case 'S': c = leftPad(d.getSeconds()); break;
case 'y': c = leftPad(d.getFullYear() % 100); break;
case 'Y': c = "" + d.getFullYear(); break;
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
case 'w': c = "" + d.getDay(); break;
}
r.push(c);
escape = false;
} else {
if (c == "%") {
escape = true;
} else {
r.push(c);
}
}
}
return r.join("");
}
// To have a consistent view of time-based data independent of which time
// zone the client happens to be in we need a date-like object independent
// of time zones. This is done through a wrapper that only calls the UTC
// versions of the accessor methods.
function makeUtcWrapper(d) {
function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
sourceObj[sourceMethod] = function() {
return targetObj[targetMethod].apply(targetObj, arguments);
};
};
var utc = {
date: d
};
// support strftime, if found
if (d.strftime != undefined) {
addProxyMethod(utc, "strftime", d, "strftime");
}
addProxyMethod(utc, "getTime", d, "getTime");
addProxyMethod(utc, "setTime", d, "setTime");
var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
for (var p = 0; p < props.length; p++) {
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
}
return utc;
};
// select time zone strategy. This returns a date-like object tied to the
// desired timezone
function dateGenerator(ts, opts) {
if (opts.timezone == "browser") {
return new Date(ts);
} else if (!opts.timezone || opts.timezone == "utc") {
return makeUtcWrapper(new Date(ts));
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
var d = new timezoneJS.Date();
// timezone-js is fickle, so be sure to set the time zone before
// setting the time.
d.setTimezone(opts.timezone);
d.setTime(ts);
return d;
} else {
return makeUtcWrapper(new Date(ts));
}
}
// map of app. size of time units in milliseconds
var timeUnitSize = {
"second": 1000,
"minute": 60 * 1000,
"hour": 60 * 60 * 1000,
"day": 24 * 60 * 60 * 1000,
"month": 30 * 24 * 60 * 60 * 1000,
"quarter": 3 * 30 * 24 * 60 * 60 * 1000,
"year": 365.2425 * 24 * 60 * 60 * 1000
};
// the allowed tick sizes, after 1 year we use
// an integer algorithm
var baseSpec = [
[1, "second"], [2, "second"], [5, "second"], [10, "second"],
[30, "second"],
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
[30, "minute"],
[1, "hour"], [2, "hour"], [4, "hour"],
[8, "hour"], [12, "hour"],
[1, "day"], [2, "day"], [3, "day"],
[0.25, "month"], [0.5, "month"], [1, "month"],
[2, "month"]
];
// we don't know which variant(s) we'll need yet, but generating both is
// cheap
var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
[1, "year"]]);
var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
[1, "year"]]);
function init(plot) {
plot.hooks.processOptions.push(function (plot, options) {
$.each(plot.getAxes(), function(axisName, axis) {
var opts = axis.options;
if (opts.mode == "time") {
axis.tickGenerator = function(axis) {
var ticks = [];
var d = dateGenerator(axis.min, opts);
var minSize = 0;
// make quarter use a possibility if quarters are
// mentioned in either of these options
var spec = (opts.tickSize && opts.tickSize[1] ===
"quarter") ||
(opts.minTickSize && opts.minTickSize[1] ===
"quarter") ? specQuarters : specMonths;
if (opts.minTickSize != null) {
if (typeof opts.tickSize == "number") {
minSize = opts.tickSize;
} else {
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
}
}
for (var i = 0; i < spec.length - 1; ++i) {
if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+ spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
break;
}
}
var size = spec[i][0];
var unit = spec[i][1];
// special-case the possibility of several years
if (unit == "year") {
// if given a minTickSize in years, just use it,
// ensuring that it's an integer
if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
size = Math.floor(opts.minTickSize[0]);
} else {
var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
var norm = (axis.delta / timeUnitSize.year) / magn;
if (norm < 1.5) {
size = 1;
} else if (norm < 3) {
size = 2;
} else if (norm < 7.5) {
size = 5;
} else {
size = 10;
}
size *= magn;
}
// minimum size for years is 1
if (size < 1) {
size = 1;
}
}
axis.tickSize = opts.tickSize || [size, unit];
var tickSize = axis.tickSize[0];
unit = axis.tickSize[1];
var step = tickSize * timeUnitSize[unit];
if (unit == "second") {
d.setSeconds(floorInBase(d.getSeconds(), tickSize));
} else if (unit == "minute") {
d.setMinutes(floorInBase(d.getMinutes(), tickSize));
} else if (unit == "hour") {
d.setHours(floorInBase(d.getHours(), tickSize));
} else if (unit == "month") {
d.setMonth(floorInBase(d.getMonth(), tickSize));
} else if (unit == "quarter") {
d.setMonth(3 * floorInBase(d.getMonth() / 3,
tickSize));
} else if (unit == "year") {
d.setFullYear(floorInBase(d.getFullYear(), tickSize));
}
// reset smaller components
d.setMilliseconds(0);
if (step >= timeUnitSize.minute) {
d.setSeconds(0);
}
if (step >= timeUnitSize.hour) {
d.setMinutes(0);
}
if (step >= timeUnitSize.day) {
d.setHours(0);
}
if (step >= timeUnitSize.day * 4) {
d.setDate(1);
}
if (step >= timeUnitSize.month * 2) {
d.setMonth(floorInBase(d.getMonth(), 3));
}
if (step >= timeUnitSize.quarter * 2) {
d.setMonth(floorInBase(d.getMonth(), 6));
}
if (step >= timeUnitSize.year) {
d.setMonth(0);
}
var carry = 0;
var v = Number.NaN;
var prev;
do {
prev = v;
v = d.getTime();
ticks.push(v);
if (unit == "month" || unit == "quarter") {
if (tickSize < 1) {
// a bit complicated - we'll divide the
// month/quarter up but we need to take
// care of fractions so we don't end up in
// the middle of a day
d.setDate(1);
var start = d.getTime();
d.setMonth(d.getMonth() +
(unit == "quarter" ? 3 : 1));
var end = d.getTime();
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
carry = d.getHours();
d.setHours(0);
} else {
d.setMonth(d.getMonth() +
tickSize * (unit == "quarter" ? 3 : 1));
}
} else if (unit == "year") {
d.setFullYear(d.getFullYear() + tickSize);
} else {
d.setTime(v + step);
}
} while (v < axis.max && v != prev);
return ticks;
};
axis.tickFormatter = function (v, axis) {
var d = dateGenerator(v, axis.options);
// first check global format
if (opts.timeformat != null) {
return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
}
// possibly use quarters if quarters are mentioned in
// any of these places
var useQuarters = (axis.options.tickSize &&
axis.options.tickSize[1] == "quarter") ||
(axis.options.minTickSize &&
axis.options.minTickSize[1] == "quarter");
var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
var span = axis.max - axis.min;
var suffix = (opts.twelveHourClock) ? " %p" : "";
var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
var fmt;
if (t < timeUnitSize.minute) {
fmt = hourCode + ":%M:%S" + suffix;
} else if (t < timeUnitSize.day) {
if (span < 2 * timeUnitSize.day) {
fmt = hourCode + ":%M" + suffix;
} else {
fmt = "%b %d " + hourCode + ":%M" + suffix;
}
} else if (t < timeUnitSize.month) {
fmt = "%b %d";
} else if ((useQuarters && t < timeUnitSize.quarter) ||
(!useQuarters && t < timeUnitSize.year)) {
if (span < timeUnitSize.year) {
fmt = "%b";
} else {
fmt = "%b %Y";
}
} else if (useQuarters && t < timeUnitSize.year) {
if (span < timeUnitSize.year) {
fmt = "Q%q";
} else {
fmt = "Q%q %Y";
}
} else {
fmt = "%Y";
}
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
return rt;
};
}
});
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'time',
version: '1.0'
});
// Time-axis support used to be in Flot core, which exposed the
// formatDate function on the plot object. Various plugins depend
// on the function, so we need to re-expose it here.
$.plot.formatDate = formatDate;
$.plot.dateGenerator = dateGenerator;
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
(function(){var a="\n//# sourceURL=",k="' of type ",n='<script type="text/javascript" src="',p="SCRIPT",r="array",t="complete",u="function",v="google.charts.load",w="hasOwnProperty",x="number",y="object",z="pre-45",A="propertyIsEnumerable",B="string",C="text/javascript",D="toLocaleString";function E(){return function(b){return b}}function F(){return function(){}}function G(b){return function(){return this[b]}}var I,J=J||{};J.scope={};
J.Up=function(b,c,d){if(null==b)throw new TypeError("The 'this' value for String.prototype."+d+" must not be null or undefined");if(c instanceof RegExp)throw new TypeError("First argument to String.prototype."+d+" must not be a regular expression");return b+""};J.Gh=!1;J.fm=!1;J.gm=!1;J.defineProperty=J.Gh||typeof Object.defineProperties==u?Object.defineProperty:function(b,c,d){b!=Array.prototype&&b!=Object.prototype&&(b[c]=d.value)};
J.Ij=function(b){return"undefined"!=typeof window&&window===b?b:"undefined"!=typeof global&&null!=global?global:b};J.global=J.Ij(this);J.Sk=function(b){if(b){for(var c=J.global,d=["Promise"],e=0;e<d.length-1;e++){var f=d[e];f in c||(c[f]={});c=c[f]}d=d[d.length-1];e=c[d];b=b(e);b!=e&&null!=b&&J.defineProperty(c,d,{configurable:!0,writable:!0,value:b})}};
J.Fq=function(b,c,d){b instanceof String&&(b=String(b));for(var e=b.length,f=0;f<e;f++){var g=b[f];if(c.call(d,g,f,b))return{Zj:f,Ll:g}}return{Zj:-1,Ll:void 0}};J.yi="jscomp_symbol_";J.rg=function(){J.rg=F();J.global.Symbol||(J.global.Symbol=J.Symbol)};J.Symbol=function(){var b=0;return function(c){return J.yi+(c||"")+b++}}();
J.Fd=function(){J.rg();var b=J.global.Symbol.iterator;b||(b=J.global.Symbol.iterator=J.global.Symbol("iterator"));typeof Array.prototype[b]!=u&&J.defineProperty(Array.prototype,b,{configurable:!0,writable:!0,value:function(){return J.df(this)}});J.Fd=F()};J.df=function(b){var c=0;return J.uk(function(){return c<b.length?{done:!1,value:b[c++]}:{done:!0}})};J.uk=function(b){J.Fd();b={next:b};b[J.global.Symbol.iterator]=function(){return this};return b};
J.Qg=function(b){J.Fd();var c=b[Symbol.iterator];return c?c.call(b):J.df(b)};J.Yh=!1;
J.Sk(function(b){function c(b){this.$=g.wa;this.ia=void 0;this.Ub=[];var c=this.gd();try{b(c.resolve,c.reject)}catch(q){c.reject(q)}}function d(){this.Ma=null}function e(b){return b instanceof c?b:new c(function(c){c(b)})}if(b&&!J.Yh)return b;d.prototype.ef=function(b){null==this.Ma&&(this.Ma=[],this.Ni());this.Ma.push(b)};d.prototype.Ni=function(){var b=this;this.ff(function(){b.uj()})};var f=J.global.setTimeout;d.prototype.ff=function(b){f(b,0)};d.prototype.uj=function(){for(;this.Ma&&this.Ma.length;){var b=
this.Ma;this.Ma=[];for(var c=0;c<b.length;++c){var d=b[c];delete b[c];try{d()}catch(H){this.Oi(H)}}}this.Ma=null};d.prototype.Oi=function(b){this.ff(function(){throw b;})};var g={wa:0,Ja:1,ka:2};c.prototype.gd=function(){function b(b){return function(e){d||(d=!0,b.call(c,e))}}var c=this,d=!1;return{resolve:b(this.Xk),reject:b(this.Yd)}};c.prototype.Xk=function(b){if(b===this)this.Yd(new TypeError("A Promise cannot resolve to itself"));else if(b instanceof c)this.pl(b);else{a:switch(typeof b){case y:var d=
null!=b;break a;case u:d=!0;break a;default:d=!1}d?this.Wk(b):this.If(b)}};c.prototype.Wk=function(b){var c=void 0;try{c=b.then}catch(q){this.Yd(q);return}typeof c==u?this.ql(c,b):this.If(b)};c.prototype.Yd=function(b){this.mh(g.ka,b)};c.prototype.If=function(b){this.mh(g.Ja,b)};c.prototype.mh=function(b,c){if(this.$!=g.wa)throw Error("Cannot settle("+b+", "+c|"): Promise already settled in state"+this.$);this.$=b;this.ia=c;this.wj()};c.prototype.wj=function(){if(null!=this.Ub){for(var b=this.Ub,
c=0;c<b.length;++c)b[c].call(),b[c]=null;this.Ub=null}};var h=new d;c.prototype.pl=function(b){var c=this.gd();b.fc(c.resolve,c.reject)};c.prototype.ql=function(b,c){var d=this.gd();try{b.call(c,d.resolve,d.reject)}catch(H){d.reject(H)}};c.prototype.then=function(b,d){function e(b,c){return typeof b==u?function(c){try{f(b(c))}catch(ca){g(ca)}}:c}var f,g,h=new c(function(b,c){f=b;g=c});this.fc(e(b,f),e(d,g));return h};c.prototype["catch"]=function(b){return this.then(void 0,b)};c.prototype.fc=function(b,
c){function d(){switch(e.$){case g.Ja:b(e.ia);break;case g.ka:c(e.ia);break;default:throw Error("Unexpected state: "+e.$);}}var e=this;null==this.Ub?h.ef(d):this.Ub.push(function(){h.ef(d)})};c.resolve=e;c.reject=function(b){return new c(function(c,d){d(b)})};c.race=function(b){return new c(function(c,d){for(var f=J.Qg(b),g=f.next();!g.done;g=f.next())e(g.value).fc(c,d)})};c.all=function(b){var d=J.Qg(b),f=d.next();return f.done?e([]):new c(function(b,c){function g(c){return function(d){h[c]=d;l--;
0==l&&b(h)}}var h=[],l=0;do h.push(void 0),l++,e(f.value).fc(g(h.length-1),c),f=d.next();while(!f.done)})};return c});var K=K||{};K.global=this;K.R=function(b){return void 0!==b};K.L=function(b){return typeof b==B};K.ck=function(b){return"boolean"==typeof b};K.Rb=function(b){return typeof b==x};
K.md=function(b,c,d){b=b.split(".");d=d||K.global;b[0]in d||!d.execScript||d.execScript("var "+b[0]);for(var e;b.length&&(e=b.shift());)!b.length&&K.R(c)?d[e]=c:d=d[e]&&d[e]!==Object.prototype[e]?d[e]:d[e]={}};K.define=function(b,c){K.md(b,c)};K.ea=!0;K.ba="en";K.$c=!0;K.wi=!1;K.Uh=!K.ea;K.De=!1;K.Es=function(b){if(K.Kd())throw Error("goog.provide can not be used within a goog.module.");K.qf(b)};K.qf=function(b,c){K.md(b,c)};K.Di=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
K.Td=function(b){if(!K.L(b)||!b||-1==b.search(K.Di))throw Error("Invalid module identifier");if(!K.Kd())throw Error("Module "+b+" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.");
if(K.na.Ud)throw Error("goog.module may only be called once per module.");K.na.Ud=b};K.Td.get=function(){return null};K.Td.$q=function(){return null};K.na=null;K.Kd=function(){return null!=K.na};K.Td.jd=function(){K.na.jd=!0};K.rt=function(b){if(K.Uh)throw b=b||"",Error("Importing test-only code into non-debug environment"+(b?": "+b:"."));};K.Lq=F();K.rb=function(b){b=b.split(".");for(var c=K.global,d=0;d<b.length;d++)if(c=c[b[d]],!K.cb(c))return null;return c};
K.kr=function(b,c){c=c||K.global;for(var d in b)c[d]=b[d]};K.hp=function(b,c,d,e){if(K.Ae){var f;b=b.replace(/\\/g,"/");var g=K.la;e&&"boolean"!==typeof e||(e=e?{module:"goog"}:{});for(var h=0;f=c[h];h++)g.Sb[f]=b,g.Od[b]=e;for(e=0;c=d[e];e++)b in g.gb||(g.gb[b]={}),g.gb[b][c]=!0}};K.Ut=!1;K.Xm=!0;K.Ek=function(b){K.global.console&&K.global.console.error(b)};K.Qs=F();K.La="";K.eb=F();K.gp=function(){throw Error("unimplemented abstract method");};
K.ip=function(b){b.Gd=void 0;b.Zq=function(){if(b.Gd)return b.Gd;K.ea&&(K.wg[K.wg.length]=b);return b.Gd=new b}};K.wg=[];K.fi=!0;K.ti=K.ea;K.Ck={};K.Ae=!1;K.Ve="detect";K.zi="transpile.js";
K.Ae&&(K.la={Od:{},Sb:{},gb:{},zh:{},je:{},pb:{}},K.qg=function(){var b=K.global.document;return null!=b&&"write"in b},K.xj=function(){if(K.R(K.global.ye)&&K.L(K.global.ye))K.La=K.global.ye;else if(K.qg()){var b=K.global.document,c=b.currentScript;b=c?[c]:b.getElementsByTagName(p);for(c=b.length-1;0<=c;--c){var d=b[c].src,e=d.lastIndexOf("?");e=-1==e?d.length:e;if("base.js"==d.substr(e-7,7)){K.La=d.substr(0,e-7);break}}}},K.Ed=function(b,c){(K.global.zm||K.Tl)(b,c)&&(K.la.je[b]=!0)},K.di=!(K.global.atob||
!K.global.document||!K.global.document.all),K.$g=!1,K.ak=function(b,c,d){K.Ed("",'goog.retrieveAndExec_("'+b+'", '+c+", "+d+");")},K.Wd=[],K.Yt=function(b,c){return K.fi&&K.R(K.global.JSON)?"goog.loadModule("+K.global.JSON.stringify(c+a+b+"\n")+");":'goog.loadModule(function(exports) {"use strict";'+c+"\n;return exports});\n//# sourceURL="+b+"\n"},K.Ak=function(){var b=K.Wd.length;if(0<b){var c=K.Wd;K.Wd=[];for(var d=0;d<b;d++)K.Tg(c[d])}K.$g=!1},K.ks=function(b){K.Bg(b)&&K.Ji(b)&&K.Tg(K.La+K.zd(b))},
K.Bg=function(b){var c=(b=K.zd(b))&&K.la.Od[b]||{},d=c.lang||"es3";return b&&("goog"==c.module||K.Xg(d))?K.La+b in K.la.pb:!1},K.Ji=function(b){if((b=K.zd(b))&&b in K.la.gb)for(var c in K.la.gb[b])if(!K.mk(c)&&!K.Bg(c))return!1;return!0},K.Tg=function(b){if(b in K.la.pb){var c=K.la.pb[b];delete K.la.pb[b];K.Tj(c)}},K.es=F(),K.Sl=function(b){K.global.document.write(n+b+'">\x3c/script>')},K.Ki=function(b){var c=K.global.document,d=c.createElement("script");d.type=C;d.src=b;d.defer=!1;d.async=!1;c.head.appendChild(d)},
K.Tl=function(b,c){if(K.qg()){var d=K.global.document;if(!K.De&&d.readyState==t){if(/\bdeps.js$/.test(b))return!1;throw Error('Cannot write "'+b+'" after document load');}void 0===c?K.di?(K.$g=!0,c=" onreadystatechange='goog.onScriptLoad_(this, "+ ++K.Pg+")' ",d.write(n+b+'"'+c+">\x3c/script>")):K.De?K.Ki(b):K.Sl(b):d.write('<script type="text/javascript">'+K.Tk(c)+"\x3c/script>");return!0}return!1},K.Tk=function(b){return b.replace(/<\/(SCRIPT)/ig,"\\x3c/$1")},K.Xg=function(b){if("always"==K.Ve)return!0;
if("never"==K.Ve)return!1;K.Dc||(K.Dc=K.ej());if(b in K.Dc)return K.Dc[b];throw Error("Unknown language mode: "+b);},K.Dc=null,K.Pg=0,K.ys=function(b,c){b.readyState==t&&K.Pg==c&&K.Ak();return!0},K.Zt=function(b){function c(b){if(!(b in f.je||b in f.zh)){f.zh[b]=!0;if(b in f.gb)for(var g in f.gb[b])if(!K.mk(g))if(g in f.Sb)c(f.Sb[g]);else throw Error("Undefined nameToPath for "+g);b in e||(e[b]=!0,d.push(b))}}var d=[],e={},f=K.la;c(b);for(b=0;b<d.length;b++){var g=d[b];K.la.je[g]=!0}var h=K.na;K.na=
null;for(b=0;b<d.length;b++)if(g=d[b]){var l=f.Od[g]||{},m=K.Xg(l.lang||"es3");"goog"==l.module||m?K.ak(K.La+g,"goog"==l.module,m):K.Ed(K.La+g)}else throw K.na=h,Error("Undefined script input");K.na=h},K.zd=function(b){return b in K.la.Sb?K.la.Sb[b]:null},K.xj(),K.global.Am||K.Ed(K.La+"deps.js"));K.Cd=null;K.Jl=function(){if(null==K.Cd){try{var b=!eval('"use strict";let x = 1; function f() { return typeof x; };f() == "number";')}catch(c){b=!1}K.Cd=b}return K.Cd};
K.Ql=function(b){return"(function(){"+b+"\n;})();\n"};K.ds=function(b){var c=K.na;try{K.na={Ud:void 0,jd:!1};if(K.ya(b))var d=b.call(void 0,{});else if(K.L(b))K.Jl()&&(b=K.Ql(b)),d=K.zk.call(void 0,b);else throw Error("Invalid module definition");var e=K.na.Ud;if(!K.L(e)||!e)throw Error('Invalid module name "'+e+'"');K.na.jd?K.qf(e,d):K.ti&&Object.seal&&typeof d==y&&null!=d&&Object.seal(d);K.Ck[e]=d}finally{K.na=c}};K.zk=function(b){eval(b);return{}};
K.rs=function(b){b=b.split("/");for(var c=0;c<b.length;)"."==b[c]?b.splice(c,1):c&&".."==b[c]&&b[c-1]&&".."!=b[c-1]?b.splice(--c,2):c++;return b.join("/")};K.xk=function(b){if(K.global.Ph)return K.global.Ph(b);try{var c=new K.global.XMLHttpRequest;c.open("get",b,!1);c.send();return 0==c.status||200==c.status?c.responseText:null}catch(d){return null}};K.Ss=F();
K.Lt=function(b,c){var d=K.global.$jscomp;d||(K.global.$jscomp=d={});var e=d.he;if(!e){var f=K.La+K.zi,g=K.xk(f);if(g){eval(g+a+f);if(K.global.$gwtExport&&K.global.$gwtExport.$jscomp&&!K.global.$gwtExport.$jscomp.transpile)throw Error('The transpiler did not properly export the "transpile" method. $gwtExport: '+JSON.stringify(K.global.$gwtExport));K.global.$jscomp.he=K.global.$gwtExport.$jscomp.transpile;d=K.global.$jscomp;e=d.he}}if(!e){var h=" requires transpilation but no transpiler was found.";
h+=' Please add "//javascript/closure:transpiler" as a data dependency to ensure it is included.';e=d.he=function(b,c){K.Ek(c+h);return b}}return e(b,c)};
K.aa=function(b){var c=typeof b;if(c==y)if(b){if(b instanceof Array)return r;if(b instanceof Object)return c;var d=Object.prototype.toString.call(b);if("[object Window]"==d)return y;if("[object Array]"==d||typeof b.length==x&&"undefined"!=typeof b.splice&&"undefined"!=typeof b.propertyIsEnumerable&&!b.propertyIsEnumerable("splice"))return r;if("[object Function]"==d||"undefined"!=typeof b.call&&"undefined"!=typeof b.propertyIsEnumerable&&!b.propertyIsEnumerable("call"))return u}else return"null";
else if(c==u&&"undefined"==typeof b.call)return y;return c};K.Pr=function(b){return null===b};K.cb=function(b){return null!=b};K.isArray=function(b){return K.aa(b)==r};K.Nb=function(b){var c=K.aa(b);return c==r||c==y&&typeof b.length==x};K.Br=function(b){return K.ha(b)&&typeof b.getFullYear==u};K.ya=function(b){return K.aa(b)==u};K.ha=function(b){var c=typeof b;return c==y&&null!=b||c==u};K.kg=function(b){return b[K.Va]||(b[K.Va]=++K.Cl)};K.nr=function(b){return!!b[K.Va]};
K.Uk=function(b){null!==b&&"removeAttribute"in b&&b.removeAttribute(K.Va);try{delete b[K.Va]}catch(c){}};K.Va="closure_uid_"+(1E9*Math.random()>>>0);K.Cl=0;K.Yq=K.kg;K.Ms=K.Uk;K.aj=function(b){var c=K.aa(b);if(c==y||c==r){if(b.clone)return b.clone();c=c==r?[]:{};for(var d in b)c[d]=K.aj(b[d]);return c}return b};K.Si=function(b,c,d){return b.call.apply(b.bind,arguments)};
K.Ri=function(b,c,d){if(!b)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var d=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(d,e);return b.apply(c,d)}}return function(){return b.apply(c,arguments)}};K.bind=function(b,c,d){K.bind=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?K.Si:K.Ri;return K.bind.apply(null,arguments)};
K.fb=function(b,c){var d=Array.prototype.slice.call(arguments,1);return function(){var c=d.slice();c.push.apply(c,arguments);return b.apply(this,c)}};K.ms=function(b,c){for(var d in c)b[d]=c[d]};K.now=K.$c&&Date.now||function(){return+new Date};
K.Tj=function(b){if(K.global.execScript)K.global.execScript(b,"JavaScript");else if(K.global.eval){if(null==K.lc)if(K.global.eval("var _evalTest_ = 1;"),"undefined"!=typeof K.global._evalTest_){try{delete K.global._evalTest_}catch(e){}K.lc=!0}else K.lc=!1;if(K.lc)K.global.eval(b);else{var c=K.global.document,d=c.createElement(p);d.type=C;d.defer=!1;d.appendChild(c.createTextNode(b));c.body.appendChild(d);c.body.removeChild(d)}}else throw Error("goog.globalEval not available");};K.lc=null;
K.Wq=function(b,c){function d(b){b=b.split("-");for(var c=[],d=0;d<b.length;d++)c.push(e(b[d]));return c.join("-")}function e(b){return K.uf[b]||b}if("."==String(b).charAt(0))throw Error('className passed in goog.getCssName must not start with ".". You passed: '+b);var f=K.uf?"BY_WHOLE"==K.kj?e:d:E();b=c?b+"-"+f(c):f(b);return K.global.Oh?K.global.Oh(b):b};K.bt=function(b,c){K.uf=b;K.kj=c};K.ar=function(b,c){c&&(b=b.replace(/\{\$([^}]+)}/g,function(b,e){return null!=c&&e in c?c[e]:b}));return b};
K.cr=E();K.zf=function(b,c){K.md(b,c,void 0)};K.Eq=function(b,c,d){b[c]=d};K.ab=function(b,c){function d(){}d.prototype=c.prototype;b.Lc=c.prototype;b.prototype=new d;b.prototype.constructor=b;b.Qi=function(b,d,g){for(var e=Array(arguments.length-2),f=2;f<arguments.length;f++)e[f-2]=arguments[f];return c.prototype[d].apply(b,e)}};
K.Qi=function(b,c,d){var e=arguments.callee.caller;if(K.wi||K.ea&&!e)throw Error("arguments.caller not defined. goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C");if(e.Lc){for(var f=Array(arguments.length-1),g=1;g<arguments.length;g++)f[g-1]=arguments[g];return e.Lc.constructor.apply(b,f)}f=Array(arguments.length-2);for(g=2;g<arguments.length;g++)f[g-2]=arguments[g];g=!1;for(var h=b.constructor;h;h=h.Lc&&h.Lc.constructor)if(h.prototype[c]===
e)g=!0;else if(g)return h.prototype[c].apply(b,f);if(b[c]===e)return b.constructor.prototype[c].apply(b,f);throw Error("goog.base called from a method of one name to a method of a different name");};K.scope=function(b){if(K.Kd())throw Error("goog.scope is not supported within a goog.module.");b.call(K.global)};
K.oa=function(b,c){var d=c.constructor,e=c.ul;d&&d!=Object.prototype.constructor||(d=function(){throw Error("cannot instantiate an interface (no constructor defined).");});d=K.oa.fj(d,b);b&&K.ab(d,b);delete c.constructor;delete c.ul;K.oa.cf(d.prototype,c);null!=e&&(e instanceof Function?e(d):K.oa.cf(d,e));return d};K.oa.si=K.ea;
K.oa.fj=function(b,c){function d(){var c=b.apply(this,arguments)||this;c[K.Va]=c[K.Va];this.constructor===d&&e&&Object.seal instanceof Function&&Object.seal(c);return c}if(!K.oa.si)return b;var e=!K.oa.qk(c);return d};K.oa.qk=function(b){return b&&b.prototype&&b.prototype[K.Bi]};K.oa.Me=["constructor",w,"isPrototypeOf",A,D,"toString","valueOf"];
K.oa.cf=function(b,c){for(var d in c)Object.prototype.hasOwnProperty.call(c,d)&&(b[d]=c[d]);for(var e=0;e<K.oa.Me.length;e++)d=K.oa.Me[e],Object.prototype.hasOwnProperty.call(c,d)&&(b[d]=c[d])};K.Et=F();K.Bi="goog_defineClass_legacy_unsealable";
K.ej=function(){function b(b,c){e?d[b]=!0:c()?d[b]=!1:e=d[b]=!0}function c(b){try{return!!eval(b)}catch(h){return!1}}var d={es3:!1},e=!1,f=K.global.navigator&&K.global.navigator.userAgent?K.global.navigator.userAgent:"";b("es5",function(){return c("[1,].length==1")});b("es6",function(){var b=f.match(/Edge\/(\d+)(\.\d)*/i);return b&&15>Number(b[1])?!1:c('(()=>{"use strict";class X{constructor(){if(new.target!=String)throw 1;this.x=42}}let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a==2)continue;function f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()==3}})()')});
b("es6-impl",function(){return!0});b("es7",function(){return c("2 ** 2 == 4")});b("es8",function(){return c("async () => 1, true")});return d};K.debug={};K.debug.Error=function(b){if(Error.captureStackTrace)Error.captureStackTrace(this,K.debug.Error);else{var c=Error().stack;c&&(this.stack=c)}b&&(this.message=String(b))};K.ab(K.debug.Error,Error);K.debug.Error.prototype.name="CustomError";K.a={};K.a.fa={Ia:1,hm:2,cc:3,wm:4,Zm:5,Ym:6,oo:7,Fm:8,Xc:9,Rm:10,Vh:11,bo:12};K.f={};K.f.Wc=!1;K.f.Xh=!1;K.f.Ye={Ke:"\u00a0"};K.f.startsWith=function(b,c){return 0==b.lastIndexOf(c,0)};K.f.endsWith=function(b,c){var d=b.length-c.length;return 0<=d&&b.indexOf(c,d)==d};K.f.Zi=function(b){return 0==K.f.jf("tel:",b.substr(0,4))};K.f.Sp=function(b,c){return 0==K.f.jf(c,b.substr(b.length-c.length,c.length))};K.f.Tp=function(b,c){return b.toLowerCase()==c.toLowerCase()};
K.f.wl=function(b,c){for(var d=b.split("%s"),e="",f=Array.prototype.slice.call(arguments,1);f.length&&1<d.length;)e+=d.shift()+f.shift();return e+d.join("%s")};K.f.Zp=function(b){return b.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")};K.f.Id=function(b){return/^[\s\xa0]*$/.test(b)};K.f.Er=function(b){return 0==b.length};K.f.Qb=K.f.Id;K.f.ek=function(b){return K.f.Id(K.f.Jk(b))};K.f.Dr=K.f.ek;K.f.zr=function(b){return!/[^\t\n\r ]/.test(b)};K.f.wr=function(b){return!/[^a-zA-Z]/.test(b)};
K.f.Qr=function(b){return!/[^0-9]/.test(b)};K.f.xr=function(b){return!/[^a-zA-Z0-9]/.test(b)};K.f.Wr=function(b){return" "==b};K.f.Xr=function(b){return 1==b.length&&" "<=b&&"~">=b||"\u0080"<=b&&"\ufffd">=b};K.f.Ct=function(b){return b.replace(/(\r\n|\r|\n)+/g," ")};K.f.Yi=function(b){return b.replace(/(\r\n|\r|\n)/g,"\n")};K.f.ts=function(b){return b.replace(/\xa0|\s/g," ")};K.f.ss=function(b){return b.replace(/\xa0|[ \t]+/g," ")};
K.f.Yp=function(b){return b.replace(/[\t\r\n ]+/g," ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g,"")};K.f.trim=K.$c&&String.prototype.trim?function(b){return b.trim()}:function(b){return b.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};K.f.trimLeft=function(b){return b.replace(/^[\s\xa0]+/,"")};K.f.trimRight=function(b){return b.replace(/[\s\xa0]+$/,"")};K.f.jf=function(b,c){b=String(b).toLowerCase();c=String(c).toLowerCase();return b<c?-1:b==c?0:1};
K.f.Zg=function(b,c,d){if(b==c)return 0;if(!b)return-1;if(!c)return 1;for(var e=b.toLowerCase().match(d),f=c.toLowerCase().match(d),g=Math.min(e.length,f.length),h=0;h<g;h++){d=e[h];var l=f[h];if(d!=l)return b=parseInt(d,10),!isNaN(b)&&(c=parseInt(l,10),!isNaN(c)&&b-c)?b-c:d<l?-1:1}return e.length!=f.length?e.length-f.length:b<c?-1:1};K.f.ur=function(b,c){return K.f.Zg(b,c,/\d+|\D+/g)};K.f.Aj=function(b,c){return K.f.Zg(b,c,/\d+|\.\d+|\D+/g)};K.f.ws=K.f.Aj;K.f.Tt=function(b){return encodeURIComponent(String(b))};
K.f.St=function(b){return decodeURIComponent(b.replace(/\+/g," "))};K.f.Yg=function(b,c){return b.replace(/(\r\n|\r|\n)/g,c?"<br />":"<br>")};
K.f.ta=function(b,c){if(c)b=b.replace(K.f.ke,"&amp;").replace(K.f.Je,"&lt;").replace(K.f.Ge,"&gt;").replace(K.f.Qe,"&quot;").replace(K.f.Te,"&#39;").replace(K.f.Le,"&#0;"),K.f.Wc&&(b=b.replace(K.f.Ee,"&#101;"));else{if(!K.f.Eh.test(b))return b;-1!=b.indexOf("&")&&(b=b.replace(K.f.ke,"&amp;"));-1!=b.indexOf("<")&&(b=b.replace(K.f.Je,"&lt;"));-1!=b.indexOf(">")&&(b=b.replace(K.f.Ge,"&gt;"));-1!=b.indexOf('"')&&(b=b.replace(K.f.Qe,"&quot;"));-1!=b.indexOf("'")&&(b=b.replace(K.f.Te,"&#39;"));-1!=b.indexOf("\x00")&&
(b=b.replace(K.f.Le,"&#0;"));K.f.Wc&&-1!=b.indexOf("e")&&(b=b.replace(K.f.Ee,"&#101;"))}return b};K.f.ke=/&/g;K.f.Je=/</g;K.f.Ge=/>/g;K.f.Qe=/"/g;K.f.Te=/'/g;K.f.Le=/\x00/g;K.f.Ee=/e/g;K.f.Eh=K.f.Wc?/[\x00&<>"'e]/:/[\x00&<>"']/;K.f.vh=function(b){return K.f.contains(b,"&")?!K.f.Xh&&"document"in K.global?K.f.wh(b):K.f.Fl(b):b};K.f.Pt=function(b,c){return K.f.contains(b,"&")?K.f.wh(b,c):b};
K.f.wh=function(b,c){var d={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"'};var e=c?c.createElement("div"):K.global.document.createElement("div");return b.replace(K.f.bi,function(b,c){var f=d[b];if(f)return f;"#"==c.charAt(0)&&(c=Number("0"+c.substr(1)),isNaN(c)||(f=String.fromCharCode(c)));f||(e.innerHTML=b+" ",f=e.firstChild.nodeValue.slice(0,-1));return d[b]=f})};
K.f.Fl=function(b){return b.replace(/&([^;]+);/g,function(b,d){switch(d){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:return"#"!=d.charAt(0)||(d=Number("0"+d.substr(1)),isNaN(d))?b:String.fromCharCode(d)}})};K.f.bi=/&([^;\s<&]+);?/g;K.f.Ol=function(b){return K.f.Yg(b.replace(/ /g," &#160;"),void 0)};K.f.Ds=function(b){return b.replace(/(^|[\n ]) /g,"$1"+K.f.Ye.Ke)};
K.f.Dt=function(b,c){for(var d=c.length,e=0;e<d;e++){var f=1==d?c:c.charAt(e);if(b.charAt(0)==f&&b.charAt(b.length-1)==f)return b.substring(1,b.length-1)}return b};K.f.truncate=function(b,c,d){d&&(b=K.f.vh(b));b.length>c&&(b=b.substring(0,c-3)+"...");d&&(b=K.f.ta(b));return b};K.f.Nt=function(b,c,d,e){d&&(b=K.f.vh(b));e&&b.length>c?(e>c&&(e=c),b=b.substring(0,c-e)+"..."+b.substring(b.length-e)):b.length>c&&(e=Math.floor(c/2),b=b.substring(0,e+c%2)+"..."+b.substring(b.length-e));d&&(b=K.f.ta(b));return b};
K.f.de={"\x00":"\\0","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\x0B",'"':'\\"',"\\":"\\\\","<":"<"};K.f.vc={"'":"\\'"};K.f.quote=function(b){b=String(b);for(var c=['"'],d=0;d<b.length;d++){var e=b.charAt(d),f=e.charCodeAt(0);c[d+1]=K.f.de[e]||(31<f&&127>f?e:K.f.xf(e))}c.push('"');return c.join("")};K.f.Dq=function(b){for(var c=[],d=0;d<b.length;d++)c[d]=K.f.xf(b.charAt(d));return c.join("")};
K.f.xf=function(b){if(b in K.f.vc)return K.f.vc[b];if(b in K.f.de)return K.f.vc[b]=K.f.de[b];var c=b.charCodeAt(0);if(31<c&&127>c)var d=b;else{if(256>c){if(d="\\x",16>c||256<c)d+="0"}else d="\\u",4096>c&&(d+="0");d+=c.toString(16).toUpperCase()}return K.f.vc[b]=d};K.f.contains=function(b,c){return-1!=b.indexOf(c)};K.f.kf=function(b,c){return K.f.contains(b.toLowerCase(),c.toLowerCase())};K.f.gq=function(b,c){return b&&c?b.split(c).length-1:0};
K.f.yb=function(b,c,d){var e=b;0<=c&&c<b.length&&0<d&&(e=b.substr(0,c)+b.substr(c+d,b.length-c-d));return e};K.f.remove=function(b,c){return b.replace(c,"")};K.f.Js=function(b,c){c=new RegExp(K.f.Xd(c),"g");return b.replace(c,"")};K.f.Ps=function(b,c,d){c=new RegExp(K.f.Xd(c),"g");return b.replace(c,d.replace(/\$/g,"$$$$"))};K.f.Xd=function(b){return String(b).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")};
K.f.repeat=String.prototype.repeat?function(b,c){return b.repeat(c)}:function(b,c){return Array(c+1).join(b)};K.f.Bs=function(b,c,d){b=K.R(d)?b.toFixed(d):String(b);d=b.indexOf(".");-1==d&&(d=b.length);return K.f.repeat("0",Math.max(0,c-d))+b};K.f.Jk=function(b){return null==b?"":String(b)};K.f.Np=function(b){return Array.prototype.join.call(arguments,"")};K.f.fr=function(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^K.now()).toString(36)};
K.f.Eb=function(b,c){var d=0;b=K.f.trim(String(b)).split(".");c=K.f.trim(String(c)).split(".");for(var e=Math.max(b.length,c.length),f=0;0==d&&f<e;f++){var g=b[f]||"",h=c[f]||"";do{g=/(\d*)(\D*)(.*)/.exec(g)||["","","",""];h=/(\d*)(\D*)(.*)/.exec(h)||["","","",""];if(0==g[0].length&&0==h[0].length)break;d=K.f.dd(0==g[1].length?0:parseInt(g[1],10),0==h[1].length?0:parseInt(h[1],10))||K.f.dd(0==g[2].length,0==h[2].length)||K.f.dd(g[2],h[2]);g=g[3];h=h[3]}while(0==d)}return d};
K.f.dd=function(b,c){return b<c?-1:b>c?1:0};K.f.or=function(b){for(var c=0,d=0;d<b.length;++d)c=31*c+b.charCodeAt(d)>>>0;return c};K.f.Gl=2147483648*Math.random()|0;K.f.pq=function(){return"goog_"+K.f.Gl++};K.f.Ht=function(b){var c=Number(b);return 0==c&&K.f.Id(b)?NaN:c};K.f.Jr=function(b){return/^[a-z]+([A-Z][a-z]*)*$/.test(b)};K.f.Yr=function(b){return/^([A-Z][a-z]*)+$/.test(b)};K.f.Gt=function(b){return String(b).replace(/\-([a-z])/g,function(b,d){return d.toUpperCase()})};
K.f.Jt=function(b){return String(b).replace(/([A-Z])/g,"-$1").toLowerCase()};K.f.Kt=function(b,c){c=K.L(c)?K.f.Xd(c):"\\s";return b.replace(new RegExp("(^"+(c?"|["+c+"]+":"")+")([a-z])","g"),function(b,c,f){return c+f.toUpperCase()})};K.f.Rp=function(b){return String(b.charAt(0)).toUpperCase()+String(b.substr(1)).toLowerCase()};K.f.parseInt=function(b){isFinite(b)&&(b=String(b));return K.L(b)?/^\s*-?0x/i.test(b)?parseInt(b,16):parseInt(b,10):NaN};
K.f.xt=function(b,c,d){b=b.split(c);for(var e=[];0<d&&b.length;)e.push(b.shift()),d--;b.length&&e.push(b.join(c));return e};K.f.as=function(b,c){if(c)typeof c==B&&(c=[c]);else return b;for(var d=-1,e=0;e<c.length;e++)if(""!=c[e]){var f=b.lastIndexOf(c[e]);f>d&&(d=f)}return-1==d?b:b.slice(d+1)};
K.f.xq=function(b,c){var d=[],e=[];if(b==c)return 0;if(!b.length||!c.length)return Math.max(b.length,c.length);for(var f=0;f<c.length+1;f++)d[f]=f;for(f=0;f<b.length;f++){e[0]=f+1;for(var g=0;g<c.length;g++)e[g+1]=Math.min(e[g]+1,d[g+1]+1,d[g]+Number(b[f]!=c[g]));for(g=0;g<d.length;g++)d[g]=e[g]}return e[c.length]};K.m={};K.m.ja=K.ea;K.m.Xb=function(b,c){c.unshift(b);K.debug.Error.call(this,K.f.wl.apply(null,c));c.shift()};K.ab(K.m.Xb,K.debug.Error);K.m.Xb.prototype.name="AssertionError";K.m.Sh=function(b){throw b;};K.m.kd=K.m.Sh;K.m.xa=function(b,c,d,e){var f="Assertion failed";if(d){f+=": "+d;var g=e}else b&&(f+=": "+b,g=c);b=new K.m.Xb(""+f,g||[]);K.m.kd(b)};K.m.ft=function(b){K.m.ja&&(K.m.kd=b)};K.m.assert=function(b,c,d){K.m.ja&&!b&&K.m.xa("",null,c,Array.prototype.slice.call(arguments,2));return b};
K.m.ma=function(b,c){K.m.ja&&K.m.kd(new K.m.Xb("Failure"+(b?": "+b:""),Array.prototype.slice.call(arguments,1)))};K.m.Ep=function(b,c,d){K.m.ja&&!K.Rb(b)&&K.m.xa("Expected number but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};K.m.Hp=function(b,c,d){K.m.ja&&!K.L(b)&&K.m.xa("Expected string but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};
K.m.sp=function(b,c,d){K.m.ja&&!K.ya(b)&&K.m.xa("Expected function but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};K.m.Fp=function(b,c,d){K.m.ja&&!K.ha(b)&&K.m.xa("Expected object but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};K.m.op=function(b,c,d){K.m.ja&&!K.isArray(b)&&K.m.xa("Expected array but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};
K.m.pp=function(b,c,d){K.m.ja&&!K.ck(b)&&K.m.xa("Expected boolean but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};K.m.qp=function(b,c,d){!K.m.ja||K.ha(b)&&b.nodeType==K.a.fa.Ia||K.m.xa("Expected Element but got %s: %s.",[K.aa(b),b],c,Array.prototype.slice.call(arguments,2));return b};K.m.tp=function(b,c,d,e){!K.m.ja||b instanceof c||K.m.xa("Expected instanceof %s but got %s.",[K.m.jg(c),K.m.jg(b)],d,Array.prototype.slice.call(arguments,3));return b};
K.m.rp=function(b,c,d){!K.m.ja||typeof b==x&&isFinite(b)||K.m.xa("Expected %s to be a finite number but it is not.",[b],c,Array.prototype.slice.call(arguments,2));return b};K.m.Gp=function(){for(var b in Object.prototype)K.m.ma(b+" should not be enumerable in Object.prototype.")};K.m.jg=function(b){return b instanceof Function?b.displayName||b.name||"unknown type name":b instanceof Object?b.constructor.displayName||b.constructor.name||Object.prototype.toString.call(b):null===b?"null":typeof b};K.f.Yo=F();K.f.I=function(){this.Kc="";this.xi=K.f.I.We};K.f.I.prototype.ua=!0;K.f.I.prototype.ga=G("Kc");K.f.I.prototype.toString=function(){return"Const{"+this.Kc+"}"};K.f.I.u=function(b){if(b instanceof K.f.I&&b.constructor===K.f.I&&b.xi===K.f.I.We)return b.Kc;K.m.ma("expected object of type Const, got '"+b+"'");return"type_error:Const"};K.f.I.from=function(b){return K.f.I.jj(b)};K.f.I.We={};K.f.I.jj=function(b){var c=new K.f.I;c.Kc=b;return c};K.f.I.EMPTY=K.f.I.from("");K.j={};K.Ca=K.$c;K.j.za=!1;K.j.Rk=function(b){return b[b.length-1]};K.j.$r=K.j.Rk;K.j.indexOf=K.Ca&&(K.j.za||Array.prototype.indexOf)?function(b,c,d){return Array.prototype.indexOf.call(b,c,d)}:function(b,c,d){d=null==d?0:0>d?Math.max(0,b.length+d):d;if(K.L(b))return K.L(c)&&1==c.length?b.indexOf(c,d):-1;for(;d<b.length;d++)if(d in b&&b[d]===c)return d;return-1};
K.j.lastIndexOf=K.Ca&&(K.j.za||Array.prototype.lastIndexOf)?function(b,c,d){return Array.prototype.lastIndexOf.call(b,c,null==d?b.length-1:d)}:function(b,c,d){d=null==d?b.length-1:d;0>d&&(d=Math.max(0,b.length+d));if(K.L(b))return K.L(c)&&1==c.length?b.lastIndexOf(c,d):-1;for(;0<=d;d--)if(d in b&&b[d]===c)return d;return-1};
K.j.forEach=K.Ca&&(K.j.za||Array.prototype.forEach)?function(b,c,d){Array.prototype.forEach.call(b,c,d)}:function(b,c,d){for(var e=b.length,f=K.L(b)?b.split(""):b,g=0;g<e;g++)g in f&&c.call(d,f[g],g,b)};K.j.Gf=function(b,c){for(var d=K.L(b)?b.split(""):b,e=b.length-1;0<=e;--e)e in d&&c.call(void 0,d[e],e,b)};
K.j.filter=K.Ca&&(K.j.za||Array.prototype.filter)?function(b,c,d){return Array.prototype.filter.call(b,c,d)}:function(b,c,d){for(var e=b.length,f=[],g=0,h=K.L(b)?b.split(""):b,l=0;l<e;l++)if(l in h){var m=h[l];c.call(d,m,l,b)&&(f[g++]=m)}return f};K.j.map=K.Ca&&(K.j.za||Array.prototype.map)?function(b,c,d){return Array.prototype.map.call(b,c,d)}:function(b,c,d){for(var e=b.length,f=Array(e),g=K.L(b)?b.split(""):b,h=0;h<e;h++)h in g&&(f[h]=c.call(d,g[h],h,b));return f};
K.j.reduce=K.Ca&&(K.j.za||Array.prototype.reduce)?function(b,c,d,e){e&&(c=K.bind(c,e));return Array.prototype.reduce.call(b,c,d)}:function(b,c,d,e){var f=d;K.j.forEach(b,function(d,h){f=c.call(e,f,d,h,b)});return f};K.j.reduceRight=K.Ca&&(K.j.za||Array.prototype.reduceRight)?function(b,c,d,e){e&&(c=K.bind(c,e));return Array.prototype.reduceRight.call(b,c,d)}:function(b,c,d,e){var f=d;K.j.Gf(b,function(d,h){f=c.call(e,f,d,h,b)});return f};
K.j.some=K.Ca&&(K.j.za||Array.prototype.some)?function(b,c,d){return Array.prototype.some.call(b,c,d)}:function(b,c,d){for(var e=b.length,f=K.L(b)?b.split(""):b,g=0;g<e;g++)if(g in f&&c.call(d,f[g],g,b))return!0;return!1};K.j.every=K.Ca&&(K.j.za||Array.prototype.every)?function(b,c,d){return Array.prototype.every.call(b,c,d)}:function(b,c,d){for(var e=b.length,f=K.L(b)?b.split(""):b,g=0;g<e;g++)if(g in f&&!c.call(d,f[g],g,b))return!1;return!0};
K.j.count=function(b,c,d){var e=0;K.j.forEach(b,function(b,g,h){c.call(d,b,g,h)&&++e},d);return e};K.j.find=function(b,c,d){c=K.j.findIndex(b,c,d);return 0>c?null:K.L(b)?b.charAt(c):b[c]};K.j.findIndex=function(b,c,d){for(var e=b.length,f=K.L(b)?b.split(""):b,g=0;g<e;g++)if(g in f&&c.call(d,f[g],g,b))return g;return-1};K.j.Gq=function(b,c,d){c=K.j.yj(b,c,d);return 0>c?null:K.L(b)?b.charAt(c):b[c]};
K.j.yj=function(b,c,d){for(var e=K.L(b)?b.split(""):b,f=b.length-1;0<=f;f--)if(f in e&&c.call(d,e[f],f,b))return f;return-1};K.j.contains=function(b,c){return 0<=K.j.indexOf(b,c)};K.j.Qb=function(b){return 0==b.length};K.j.clear=function(b){if(!K.isArray(b))for(var c=b.length-1;0<=c;c--)delete b[c];b.length=0};K.j.rr=function(b,c){K.j.contains(b,c)||b.push(c)};K.j.sg=function(b,c,d){K.j.splice(b,d,0,c)};K.j.tr=function(b,c,d){K.fb(K.j.splice,b,d,0).apply(null,c)};
K.j.insertBefore=function(b,c,d){var e;2==arguments.length||0>(e=K.j.indexOf(b,d))?b.push(c):K.j.sg(b,c,e)};K.j.remove=function(b,c){c=K.j.indexOf(b,c);var d;(d=0<=c)&&K.j.yb(b,c);return d};K.j.Os=function(b,c){c=K.j.lastIndexOf(b,c);return 0<=c?(K.j.yb(b,c),!0):!1};K.j.yb=function(b,c){return 1==Array.prototype.splice.call(b,c,1).length};K.j.Ns=function(b,c,d){c=K.j.findIndex(b,c,d);return 0<=c?(K.j.yb(b,c),!0):!1};
K.j.Ks=function(b,c,d){var e=0;K.j.Gf(b,function(f,g){c.call(d,f,g,b)&&K.j.yb(b,g)&&e++});return e};K.j.concat=function(b){return Array.prototype.concat.apply([],arguments)};K.j.join=function(b){return Array.prototype.concat.apply([],arguments)};K.j.th=function(b){var c=b.length;if(0<c){for(var d=Array(c),e=0;e<c;e++)d[e]=b[e];return d}return[]};K.j.clone=K.j.th;
K.j.extend=function(b,c){for(var d=1;d<arguments.length;d++){var e=arguments[d];if(K.Nb(e)){var f=b.length||0,g=e.length||0;b.length=f+g;for(var h=0;h<g;h++)b[f+h]=e[h]}else b.push(e)}};K.j.splice=function(b,c,d,e){return Array.prototype.splice.apply(b,K.j.slice(arguments,1))};K.j.slice=function(b,c,d){return 2>=arguments.length?Array.prototype.slice.call(b,c):Array.prototype.slice.call(b,c,d)};
K.j.Ls=function(b,c,d){function e(b){return K.ha(b)?"o"+K.kg(b):(typeof b).charAt(0)+b}c=c||b;d=d||e;for(var f={},g=0,h=0;h<b.length;){var l=b[h++],m=d(l);Object.prototype.hasOwnProperty.call(f,m)||(f[m]=!0,c[g++]=l)}c.length=g};K.j.gf=function(b,c,d){return K.j.hf(b,d||K.j.Pa,!1,c)};K.j.Kp=function(b,c,d){return K.j.hf(b,c,!0,void 0,d)};K.j.hf=function(b,c,d,e,f){for(var g=0,h=b.length,l;g<h;){var m=g+h>>1;var q=d?c.call(f,b[m],m,b):c(e,b[m]);0<q?g=m+1:(h=m,l=!q)}return l?g:~g};
K.j.sort=function(b,c){b.sort(c||K.j.Pa)};K.j.zt=function(b,c){for(var d=Array(b.length),e=0;e<b.length;e++)d[e]={index:e,value:b[e]};var f=c||K.j.Pa;K.j.sort(d,function(b,c){return f(b.value,c.value)||b.index-c.index});for(e=0;e<b.length;e++)b[e]=d[e].value};K.j.sl=function(b,c,d){var e=d||K.j.Pa;K.j.sort(b,function(b,d){return e(c(b),c(d))})};K.j.wt=function(b,c,d){K.j.sl(b,function(b){return b[c]},d)};
K.j.Vr=function(b,c,d){c=c||K.j.Pa;for(var e=1;e<b.length;e++){var f=c(b[e-1],b[e]);if(0<f||0==f&&d)return!1}return!0};K.j.Ib=function(b,c,d){if(!K.Nb(b)||!K.Nb(c)||b.length!=c.length)return!1;var e=b.length;d=d||K.j.lj;for(var f=0;f<e;f++)if(!d(b[f],c[f]))return!1;return!0};K.j.$p=function(b,c,d){d=d||K.j.Pa;for(var e=Math.min(b.length,c.length),f=0;f<e;f++){var g=d(b[f],c[f]);if(0!=g)return g}return K.j.Pa(b.length,c.length)};K.j.Pa=function(b,c){return b>c?1:b<c?-1:0};
K.j.vr=function(b,c){return-K.j.Pa(b,c)};K.j.lj=function(b,c){return b===c};K.j.Ip=function(b,c,d){d=K.j.gf(b,c,d);return 0>d?(K.j.sg(b,c,-(d+1)),!0):!1};K.j.Jp=function(b,c,d){c=K.j.gf(b,c,d);return 0<=c?K.j.yb(b,c):!1};K.j.Mp=function(b,c,d){for(var e={},f=0;f<b.length;f++){var g=b[f],h=c.call(d,g,f,b);K.R(h)&&(e[h]||(e[h]=[])).push(g)}return e};K.j.It=function(b,c,d){var e={};K.j.forEach(b,function(f,g){e[c.call(d,f,g,b)]=f});return e};
K.j.Gs=function(b,c,d){var e=[],f=0,g=b;d=d||1;void 0!==c&&(f=b,g=c);if(0>d*(g-f))return[];if(0<d)for(b=f;b<g;b+=d)e.push(b);else for(b=f;b>g;b+=d)e.push(b);return e};K.j.repeat=function(b,c){for(var d=[],e=0;e<c;e++)d[e]=b;return d};K.j.flatten=function(b){for(var c=[],d=0;d<arguments.length;d++){var e=arguments[d];if(K.isArray(e))for(var f=0;f<e.length;f+=8192)for(var g=K.j.flatten.apply(null,K.j.slice(e,f,f+8192)),h=0;h<g.length;h++)c.push(g[h]);else c.push(e)}return c};
K.j.rotate=function(b,c){b.length&&(c%=b.length,0<c?Array.prototype.unshift.apply(b,b.splice(-c,c)):0>c&&Array.prototype.push.apply(b,b.splice(0,-c)));return b};K.j.os=function(b,c,d){c=Array.prototype.splice.call(b,c,1);Array.prototype.splice.call(b,d,0,c[0])};
K.j.$t=function(b){if(!arguments.length)return[];for(var c=[],d=arguments[0].length,e=1;e<arguments.length;e++)arguments[e].length<d&&(d=arguments[e].length);for(e=0;e<d;e++){for(var f=[],g=0;g<arguments.length;g++)f.push(arguments[g][e]);c.push(f)}return c};K.j.vt=function(b,c){c=c||Math.random;for(var d=b.length-1;0<d;d--){var e=Math.floor(c()*(d+1)),f=b[d];b[d]=b[e];b[e]=f}};K.j.fq=function(b,c){var d=[];K.j.forEach(c,function(c){d.push(b[c])});return d};
K.j.bq=function(b,c,d){return K.j.concat.apply([],K.j.map(b,c,d))};K.h={};K.h.i={};K.h.i.Zh=!1;
K.h.i.Ie=K.h.i.Zh||("ar"==K.ba.substring(0,2).toLowerCase()||"fa"==K.ba.substring(0,2).toLowerCase()||"he"==K.ba.substring(0,2).toLowerCase()||"iw"==K.ba.substring(0,2).toLowerCase()||"ps"==K.ba.substring(0,2).toLowerCase()||"sd"==K.ba.substring(0,2).toLowerCase()||"ug"==K.ba.substring(0,2).toLowerCase()||"ur"==K.ba.substring(0,2).toLowerCase()||"yi"==K.ba.substring(0,2).toLowerCase())&&(2==K.ba.length||"-"==K.ba.substring(2,3)||"_"==K.ba.substring(2,3))||3<=K.ba.length&&"ckb"==K.ba.substring(0,3).toLowerCase()&&
(3==K.ba.length||"-"==K.ba.substring(3,4)||"_"==K.ba.substring(3,4));K.h.i.mb={gi:"\u202a",ji:"\u202b",Oe:"\u202c",hi:"\u200e",ki:"\u200f"};K.h.i.O={Ta:1,Ua:-1,qa:0};K.h.i.bc="right";K.h.i.$b="left";K.h.i.yn=K.h.i.Ie?K.h.i.$b:K.h.i.bc;K.h.i.xn=K.h.i.Ie?K.h.i.bc:K.h.i.$b;K.h.i.Al=function(b){return typeof b==x?0<b?K.h.i.O.Ta:0>b?K.h.i.O.Ua:K.h.i.O.qa:null==b?null:b?K.h.i.O.Ua:K.h.i.O.Ta};K.h.i.vb="A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff";
K.h.i.zb="\u0591-\u06ef\u06fa-\u07ff\u200f\ufb1d-\ufdff\ufe70-\ufefc";K.h.i.Yj=/<[^>]*>|&[^;]+;/g;K.h.i.Sa=function(b,c){return c?b.replace(K.h.i.Yj,""):b};K.h.i.$k=new RegExp("["+K.h.i.zb+"]");K.h.i.Fk=new RegExp("["+K.h.i.vb+"]");K.h.i.Bd=function(b,c){return K.h.i.$k.test(K.h.i.Sa(b,c))};K.h.i.mr=K.h.i.Bd;K.h.i.og=function(b){return K.h.i.Fk.test(K.h.i.Sa(b,void 0))};K.h.i.Ik=new RegExp("^["+K.h.i.vb+"]");K.h.i.el=new RegExp("^["+K.h.i.zb+"]");K.h.i.nk=function(b){return K.h.i.el.test(b)};
K.h.i.jk=function(b){return K.h.i.Ik.test(b)};K.h.i.Nr=function(b){return!K.h.i.jk(b)&&!K.h.i.nk(b)};K.h.i.Gk=new RegExp("^[^"+K.h.i.zb+"]*["+K.h.i.vb+"]");K.h.i.bl=new RegExp("^[^"+K.h.i.vb+"]*["+K.h.i.zb+"]");K.h.i.nh=function(b,c){return K.h.i.bl.test(K.h.i.Sa(b,c))};K.h.i.Tr=K.h.i.nh;K.h.i.tl=function(b,c){return K.h.i.Gk.test(K.h.i.Sa(b,c))};K.h.i.Lr=K.h.i.tl;K.h.i.Jg=/^http:\/\/.*/;K.h.i.Or=function(b,c){b=K.h.i.Sa(b,c);return K.h.i.Jg.test(b)||!K.h.i.og(b)&&!K.h.i.Bd(b)};
K.h.i.Hk=new RegExp("["+K.h.i.vb+"][^"+K.h.i.zb+"]*$");K.h.i.cl=new RegExp("["+K.h.i.zb+"][^"+K.h.i.vb+"]*$");K.h.i.rj=function(b,c){return K.h.i.Hk.test(K.h.i.Sa(b,c))};K.h.i.Kr=K.h.i.rj;K.h.i.sj=function(b,c){return K.h.i.cl.test(K.h.i.Sa(b,c))};K.h.i.Rr=K.h.i.sj;K.h.i.dl=/^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)/i;K.h.i.Sr=function(b){return K.h.i.dl.test(b)};K.h.i.Ui=/(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
K.h.i.lr=function(b,c){c=(void 0===c?K.h.i.Bd(b):c)?K.h.i.mb.ki:K.h.i.mb.hi;return b.replace(K.h.i.Ui,c+"$&"+c)};K.h.i.Aq=function(b){return"<"==b.charAt(0)?b.replace(/<\w+/,"$& dir=rtl"):"\n<span dir=rtl>"+b+"</span>"};K.h.i.Bq=function(b){return K.h.i.mb.ji+b+K.h.i.mb.Oe};K.h.i.yq=function(b){return"<"==b.charAt(0)?b.replace(/<\w+/,"$& dir=ltr"):"\n<span dir=ltr>"+b+"</span>"};K.h.i.zq=function(b){return K.h.i.mb.gi+b+K.h.i.mb.Oe};K.h.i.pj=/:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;
K.h.i.vk=/left/gi;K.h.i.Zk=/right/gi;K.h.i.yl=/%%%%/g;K.h.i.ls=function(b){return b.replace(K.h.i.pj,":$1 $4 $3 $2").replace(K.h.i.vk,"%%%%").replace(K.h.i.Zk,K.h.i.$b).replace(K.h.i.yl,K.h.i.bc)};K.h.i.qj=/([\u0591-\u05f2])"/g;K.h.i.rl=/([\u0591-\u05f2])'/g;K.h.i.qs=function(b){return b.replace(K.h.i.qj,"$1\u05f4").replace(K.h.i.rl,"$1\u05f3")};K.h.i.Pl=/\s+/;K.h.i.Xj=/[\d\u06f0-\u06f9]/;K.h.i.al=.4;
K.h.i.yf=function(b,c){var d=0,e=0,f=!1;b=K.h.i.Sa(b,c).split(K.h.i.Pl);for(c=0;c<b.length;c++){var g=b[c];K.h.i.nh(g)?(d++,e++):K.h.i.Jg.test(g)?f=!0:K.h.i.og(g)?e++:K.h.i.Xj.test(g)&&(f=!0)}return 0==e?f?K.h.i.O.Ta:K.h.i.O.qa:d/e>K.h.i.al?K.h.i.O.Ua:K.h.i.O.Ta};K.h.i.tq=function(b,c){return K.h.i.yf(b,c)==K.h.i.O.Ua};K.h.i.ct=function(b,c){b&&(c=K.h.i.Al(c))&&(b.style.textAlign=c==K.h.i.O.Ua?K.h.i.bc:K.h.i.$b,b.dir=c==K.h.i.O.Ua?"rtl":"ltr")};
K.h.i.dt=function(b,c){switch(K.h.i.yf(c)){case K.h.i.O.Ta:b.dir="ltr";break;case K.h.i.O.Ua:b.dir="rtl";break;default:b.removeAttribute("dir")}};K.h.i.Tm=F();K.b={};K.b.C=function(){this.Bc="";this.Ai=K.b.C.ca};K.b.C.prototype.ua=!0;K.b.C.prototype.ga=G("Bc");K.b.C.prototype.Dd=!0;K.b.C.prototype.$a=function(){return K.h.i.O.Ta};K.ea&&(K.b.C.prototype.toString=function(){return"TrustedResourceUrl{"+this.Bc+"}"});K.b.C.u=function(b){if(b instanceof K.b.C&&b.constructor===K.b.C&&b.Ai===K.b.C.ca)return b.Bc;K.m.ma("expected object of type TrustedResourceUrl, got '"+b+k+K.aa(b));return"type_error:TrustedResourceUrl"};
K.b.C.format=function(b,c){b=K.b.C.Hf(b,c);return K.b.C.Hb(b)};K.b.C.Hf=function(b,c){var d=K.f.I.u(b);if(!K.b.C.Ih.test(d))throw Error("Invalid TrustedResourceUrl format: "+d);return d.replace(K.b.C.$h,function(b,f){if(!Object.prototype.hasOwnProperty.call(c,f))throw Error('Found marker, "'+f+'", in format string, "'+d+'", but no valid label mapping found in args: '+JSON.stringify(c));b=c[f];return b instanceof K.f.I?K.f.I.u(b):encodeURIComponent(String(b))})};K.b.C.$h=/%{(\w+)}/g;K.b.C.Ih=/^(?:https:)?\/\/[0-9a-z.:[\]-]+\/|^\/[^\/\\]|^about:blank(#|$)/i;
K.b.C.Kq=function(b,c,d){b=K.b.C.Hf(b,c);c=/\?/.test(b)?"&":"?";for(var e in d)for(var f=K.isArray(d[e])?d[e]:[d[e]],g=0;g<f.length;g++)null!=f[g]&&(b+=c+encodeURIComponent(e)+"="+encodeURIComponent(String(f[g])),c="&");return K.b.C.Hb(b)};K.b.C.mc=function(b){return K.b.C.Hb(K.f.I.u(b))};K.b.C.Nq=function(b){for(var c="",d=0;d<b.length;d++)c+=K.f.I.u(b[d]);return K.b.C.Hb(c)};K.b.C.ca={};K.b.C.Hb=function(b){var c=new K.b.C;c.Bc=b;return c};K.async={};K.async.Zb=function(b,c,d){this.wk=d;this.ij=b;this.Vk=c;this.xc=0;this.tc=null};K.async.Zb.prototype.get=function(){if(0<this.xc){this.xc--;var b=this.tc;this.tc=b.next;b.next=null}else b=this.ij();return b};K.async.Zb.prototype.put=function(b){this.Vk(b);this.xc<this.wk&&(this.xc++,b.next=this.tc,this.tc=b)};K.debug.Z={};K.debug.$m=F();K.debug.Z.xb=[];K.debug.Z.Vd=[];K.debug.Z.Wg=!1;K.debug.Z.register=function(b){K.debug.Z.xb[K.debug.Z.xb.length]=b;if(K.debug.Z.Wg)for(var c=K.debug.Z.Vd,d=0;d<c.length;d++)b(K.bind(c[d].Rl,c[d]))};K.debug.Z.ns=function(b){K.debug.Z.Wg=!0;for(var c=K.bind(b.Rl,b),d=0;d<K.debug.Z.xb.length;d++)K.debug.Z.xb[d](c);K.debug.Z.Vd.push(b)};K.debug.Z.Rt=function(b){var c=K.debug.Z.Vd;b=K.bind(b.u,b);for(var d=0;d<K.debug.Z.xb.length;d++)K.debug.Z.xb[d](b);c.length--};K.a.vn=F();K.a.c=function(b){this.xl=b};K.a.c.prototype.toString=G("xl");K.a.c.Ul=new K.a.c("A");K.a.c.Vl=new K.a.c("ABBR");K.a.c.Xl=new K.a.c("ACRONYM");K.a.c.Yl=new K.a.c("ADDRESS");K.a.c.bm=new K.a.c("APPLET");K.a.c.cm=new K.a.c("AREA");K.a.c.dm=new K.a.c("ARTICLE");K.a.c.em=new K.a.c("ASIDE");K.a.c.im=new K.a.c("AUDIO");K.a.c.jm=new K.a.c("B");K.a.c.km=new K.a.c("BASE");K.a.c.lm=new K.a.c("BASEFONT");K.a.c.mm=new K.a.c("BDI");K.a.c.nm=new K.a.c("BDO");K.a.c.qm=new K.a.c("BIG");K.a.c.rm=new K.a.c("BLOCKQUOTE");
K.a.c.sm=new K.a.c("BODY");K.a.c.we=new K.a.c("BR");K.a.c.tm=new K.a.c("BUTTON");K.a.c.um=new K.a.c("CANVAS");K.a.c.vm=new K.a.c("CAPTION");K.a.c.xm=new K.a.c("CENTER");K.a.c.ym=new K.a.c("CITE");K.a.c.Bm=new K.a.c("CODE");K.a.c.Cm=new K.a.c("COL");K.a.c.Dm=new K.a.c("COLGROUP");K.a.c.Em=new K.a.c("COMMAND");K.a.c.Gm=new K.a.c("DATA");K.a.c.Hm=new K.a.c("DATALIST");K.a.c.Im=new K.a.c("DD");K.a.c.Jm=new K.a.c("DEL");K.a.c.Km=new K.a.c("DETAILS");K.a.c.Lm=new K.a.c("DFN");K.a.c.Mm=new K.a.c("DIALOG");
K.a.c.Nm=new K.a.c("DIR");K.a.c.Om=new K.a.c("DIV");K.a.c.Pm=new K.a.c("DL");K.a.c.Sm=new K.a.c("DT");K.a.c.Vm=new K.a.c("EM");K.a.c.Wm=new K.a.c("EMBED");K.a.c.bn=new K.a.c("FIELDSET");K.a.c.cn=new K.a.c("FIGCAPTION");K.a.c.dn=new K.a.c("FIGURE");K.a.c.en=new K.a.c("FONT");K.a.c.fn=new K.a.c("FOOTER");K.a.c.gn=new K.a.c("FORM");K.a.c.hn=new K.a.c("FRAME");K.a.c.jn=new K.a.c("FRAMESET");K.a.c.kn=new K.a.c("H1");K.a.c.ln=new K.a.c("H2");K.a.c.mn=new K.a.c("H3");K.a.c.nn=new K.a.c("H4");K.a.c.on=new K.a.c("H5");
K.a.c.pn=new K.a.c("H6");K.a.c.qn=new K.a.c("HEAD");K.a.c.rn=new K.a.c("HEADER");K.a.c.sn=new K.a.c("HGROUP");K.a.c.tn=new K.a.c("HR");K.a.c.un=new K.a.c("HTML");K.a.c.wn=new K.a.c("I");K.a.c.zn=new K.a.c("IFRAME");K.a.c.An=new K.a.c("IMG");K.a.c.Bn=new K.a.c("INPUT");K.a.c.Cn=new K.a.c("INS");K.a.c.Hn=new K.a.c("ISINDEX");K.a.c.Jn=new K.a.c("KBD");K.a.c.Kn=new K.a.c("KEYGEN");K.a.c.Ln=new K.a.c("LABEL");K.a.c.Nn=new K.a.c("LEGEND");K.a.c.On=new K.a.c("LI");K.a.c.Pn=new K.a.c("LINK");K.a.c.Sn=new K.a.c("MAP");
K.a.c.Tn=new K.a.c("MARK");K.a.c.Un=new K.a.c("MATH");K.a.c.Vn=new K.a.c("MENU");K.a.c.Wn=new K.a.c("META");K.a.c.Xn=new K.a.c("METER");K.a.c.Zn=new K.a.c("NAV");K.a.c.$n=new K.a.c("NOFRAMES");K.a.c.ao=new K.a.c("NOSCRIPT");K.a.c.eo=new K.a.c("OBJECT");K.a.c.fo=new K.a.c("OL");K.a.c.ho=new K.a.c("OPTGROUP");K.a.c.io=new K.a.c("OPTION");K.a.c.jo=new K.a.c("OUTPUT");K.a.c.ko=new K.a.c("P");K.a.c.lo=new K.a.c("PARAM");K.a.c.no=new K.a.c("PRE");K.a.c.po=new K.a.c("PROGRESS");K.a.c.Q=new K.a.c("Q");
K.a.c.qo=new K.a.c("RP");K.a.c.ro=new K.a.c("RT");K.a.c.so=new K.a.c("RUBY");K.a.c.uo=new K.a.c("S");K.a.c.wo=new K.a.c("SAMP");K.a.c.xo=new K.a.c(p);K.a.c.yo=new K.a.c("SECTION");K.a.c.zo=new K.a.c("SELECT");K.a.c.Ao=new K.a.c("SMALL");K.a.c.Bo=new K.a.c("SOURCE");K.a.c.Co=new K.a.c("SPAN");K.a.c.Do=new K.a.c("STRIKE");K.a.c.Eo=new K.a.c("STRONG");K.a.c.Fo=new K.a.c("STYLE");K.a.c.Go=new K.a.c("SUB");K.a.c.Ho=new K.a.c("SUMMARY");K.a.c.Io=new K.a.c("SUP");K.a.c.Jo=new K.a.c("SVG");K.a.c.Ko=new K.a.c("TABLE");
K.a.c.Lo=new K.a.c("TBODY");K.a.c.Mo=new K.a.c("TD");K.a.c.No=new K.a.c("TEMPLATE");K.a.c.Oo=new K.a.c("TEXTAREA");K.a.c.Po=new K.a.c("TFOOT");K.a.c.Qo=new K.a.c("TH");K.a.c.Ro=new K.a.c("THEAD");K.a.c.So=new K.a.c("TIME");K.a.c.To=new K.a.c("TITLE");K.a.c.Uo=new K.a.c("TR");K.a.c.Vo=new K.a.c("TRACK");K.a.c.Xo=new K.a.c("TT");K.a.c.Zo=new K.a.c("U");K.a.c.$o=new K.a.c("UL");K.a.c.ap=new K.a.c("VAR");K.a.c.bp=new K.a.c("VIDEO");K.a.c.cp=new K.a.c("WBR");K.J={};K.J.ic=function(b){return function(){return b}};K.J.an=K.J.ic(!1);K.J.Wo=K.J.ic(!0);K.J.co=K.J.ic(null);K.J.$j=E();K.J.error=function(b){return function(){throw Error(b);}};K.J.ma=function(b){return function(){throw b;}};K.J.lock=function(b,c){c=c||0;return function(){return b.apply(this,Array.prototype.slice.call(arguments,0,c))}};K.J.vs=function(b){return function(){return arguments[b]}};
K.J.Cs=function(b,c){var d=Array.prototype.slice.call(arguments,1);return function(){var c=Array.prototype.slice.call(arguments);c.push.apply(c,d);return b.apply(this,c)}};K.J.Xt=function(b,c){return K.J.ll(b,K.J.ic(c))};K.J.Cq=function(b,c){return function(d){return c?b==d:b===d}};K.J.aq=function(b,c){var d=arguments,e=d.length;return function(){var b;e&&(b=d[e-1].apply(this,arguments));for(var c=e-2;0<=c;c--)b=d[c].call(this,b);return b}};
K.J.ll=function(b){var c=arguments,d=c.length;return function(){for(var b,f=0;f<d;f++)b=c[f].apply(this,arguments);return b}};K.J.kp=function(b){var c=arguments,d=c.length;return function(){for(var b=0;b<d;b++)if(!c[b].apply(this,arguments))return!1;return!0}};K.J.As=function(b){var c=arguments,d=c.length;return function(){for(var b=0;b<d;b++)if(c[b].apply(this,arguments))return!0;return!1}};K.J.us=function(b){return function(){return!b.apply(this,arguments)}};
K.J.create=function(b,c){function d(){}d.prototype=b.prototype;var e=new d;b.apply(e,Array.prototype.slice.call(arguments,1));return e};K.J.Kh=!0;K.J.Op=function(b){var c=!1,d;return function(){if(!K.J.Kh)return b();c||(d=b(),c=!0);return d}};K.J.once=function(b){var c=b;return function(){if(c){var b=c;c=null;b()}}};K.J.rq=function(b,c,d){var e=0;return function(f){K.global.clearTimeout(e);var g=arguments;e=K.global.setTimeout(function(){b.apply(d,g)},c)}};
K.J.Ft=function(b,c,d){function e(){g=K.global.setTimeout(f,c);b.apply(d,l)}function f(){g=0;h&&(h=!1,e())}var g=0,h=!1,l=[];return function(b){l=arguments;g?h=!0:e()}};K.J.Hs=function(b,c,d){function e(){f=0}var f=0;return function(g){f||(f=K.global.setTimeout(e,c),b.apply(d,arguments))}};K.g={};K.g.userAgent={};K.g.userAgent.A={};K.g.userAgent.A.Xf=function(){var b=K.g.userAgent.A.Kj();return b&&(b=b.userAgent)?b:""};K.g.userAgent.A.Kj=function(){return K.global.navigator};K.g.userAgent.A.xh=K.g.userAgent.A.Xf();K.g.userAgent.A.tt=function(b){K.g.userAgent.A.xh=b||K.g.userAgent.A.Xf()};K.g.userAgent.A.sb=function(){return K.g.userAgent.A.xh};K.g.userAgent.A.K=function(b){return K.f.contains(K.g.userAgent.A.sb(),b)};
K.g.userAgent.A.Pk=function(){return K.f.kf(K.g.userAgent.A.sb(),"WebKit")};K.g.userAgent.A.Af=function(b){for(var c=/(\w[\w ]+)\/([^\s]+)\s*(?:\((.*?)\))?/g,d=[],e;e=c.exec(b);)d.push([e[1],e[2],e[3]||void 0]);return d};K.object={};K.object.is=function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c};K.object.forEach=function(b,c,d){for(var e in b)c.call(d,b[e],e,b)};K.object.filter=function(b,c,d){var e={},f;for(f in b)c.call(d,b[f],f,b)&&(e[f]=b[f]);return e};K.object.map=function(b,c,d){var e={},f;for(f in b)e[f]=c.call(d,b[f],f,b);return e};K.object.some=function(b,c,d){for(var e in b)if(c.call(d,b[e],e,b))return!0;return!1};K.object.every=function(b,c,d){for(var e in b)if(!c.call(d,b[e],e,b))return!1;return!0};
K.object.Vq=function(b){var c=0,d;for(d in b)c++;return c};K.object.Tq=function(b){for(var c in b)return c};K.object.Uq=function(b){for(var c in b)return b[c]};K.object.contains=function(b,c){return K.object.cj(b,c)};K.object.jr=function(b){var c=[],d=0,e;for(e in b)c[d++]=b[e];return c};K.object.Vf=function(b){var c=[],d=0,e;for(e in b)c[d++]=e;return c};K.object.ir=function(b,c){var d=K.Nb(c),e=d?c:arguments;for(d=d?0:1;d<e.length;d++){if(null==b)return;b=b[e[d]]}return b};
K.object.bj=function(b,c){return null!==b&&c in b};K.object.cj=function(b,c){for(var d in b)if(b[d]==c)return!0;return!1};K.object.zj=function(b,c,d){for(var e in b)if(c.call(d,b[e],e,b))return e};K.object.Hq=function(b,c,d){return(c=K.object.zj(b,c,d))&&b[c]};K.object.Qb=function(b){for(var c in b)return!1;return!0};K.object.clear=function(b){for(var c in b)delete b[c]};K.object.remove=function(b,c){var d;(d=c in b)&&delete b[c];return d};
K.object.add=function(b,c,d){if(null!==b&&c in b)throw Error('The object already contains the key "'+c+'"');K.object.set(b,c,d)};K.object.get=function(b,c,d){return null!==b&&c in b?b[c]:d};K.object.set=function(b,c,d){b[c]=d};K.object.ht=function(b,c,d){return c in b?b[c]:b[c]=d};K.object.ut=function(b,c,d){if(c in b)return b[c];d=d();return b[c]=d};K.object.Ib=function(b,c){for(var d in b)if(!(d in c)||b[d]!==c[d])return!1;for(d in c)if(!(d in b))return!1;return!0};
K.object.clone=function(b){var c={},d;for(d in b)c[d]=b[d];return c};K.object.Hl=function(b){var c=K.aa(b);if(c==y||c==r){if(K.ya(b.clone))return b.clone();c=c==r?[]:{};for(var d in b)c[d]=K.object.Hl(b[d]);return c}return b};K.object.Mt=function(b){var c={},d;for(d in b)c[b[d]]=d;return c};K.object.Pe=["constructor",w,"isPrototypeOf",A,D,"toString","valueOf"];
K.object.extend=function(b,c){for(var d,e,f=1;f<arguments.length;f++){e=arguments[f];for(d in e)b[d]=e[d];for(var g=0;g<K.object.Pe.length;g++)d=K.object.Pe[g],Object.prototype.hasOwnProperty.call(e,d)&&(b[d]=e[d])}};K.object.create=function(b){var c=arguments.length;if(1==c&&K.isArray(arguments[0]))return K.object.create.apply(null,arguments[0]);if(c%2)throw Error("Uneven number of arguments");for(var d={},e=0;e<c;e+=2)d[arguments[e]]=arguments[e+1];return d};
K.object.gj=function(b){var c=arguments.length;if(1==c&&K.isArray(arguments[0]))return K.object.gj.apply(null,arguments[0]);for(var d={},e=0;e<c;e++)d[arguments[e]]=!0;return d};K.object.iq=function(b){var c=b;Object.isFrozen&&!Object.isFrozen(b)&&(c=Object.create(b),Object.freeze(c));return c};K.object.Gr=function(b){return!!Object.isFrozen&&Object.isFrozen(b)};
K.object.Sq=function(b,c,d){if(!b)return[];if(!Object.getOwnPropertyNames||!Object.getPrototypeOf)return K.object.Vf(b);for(var e={};b&&(b!==Object.prototype||c)&&(b!==Function.prototype||d);){for(var f=Object.getOwnPropertyNames(b),g=0;g<f.length;g++)e[f[g]]=!0;b=Object.getPrototypeOf(b)}return K.object.Vf(e)};K.g.userAgent.v={};K.g.userAgent.v.Rg=function(){return K.g.userAgent.A.K("Opera")};K.g.userAgent.v.Nk=function(){return K.g.userAgent.A.K("Trident")||K.g.userAgent.A.K("MSIE")};K.g.userAgent.v.Sd=function(){return K.g.userAgent.A.K("Edge")};K.g.userAgent.v.Mk=function(){return K.g.userAgent.A.K("Firefox")};K.g.userAgent.v.Sg=function(){return K.g.userAgent.A.K("Safari")&&!(K.g.userAgent.v.Qd()||K.g.userAgent.v.Rd()||K.g.userAgent.v.Rg()||K.g.userAgent.v.Sd()||K.g.userAgent.v.Kg()||K.g.userAgent.A.K("Android"))};
K.g.userAgent.v.Rd=function(){return K.g.userAgent.A.K("Coast")};K.g.userAgent.v.Ok=function(){return(K.g.userAgent.A.K("iPad")||K.g.userAgent.A.K("iPhone"))&&!K.g.userAgent.v.Sg()&&!K.g.userAgent.v.Qd()&&!K.g.userAgent.v.Rd()&&K.g.userAgent.A.K("AppleWebKit")};K.g.userAgent.v.Qd=function(){return(K.g.userAgent.A.K("Chrome")||K.g.userAgent.A.K("CriOS"))&&!K.g.userAgent.v.Sd()};
K.g.userAgent.v.Lk=function(){return K.g.userAgent.A.K("Android")&&!(K.g.userAgent.v.zg()||K.g.userAgent.v.fk()||K.g.userAgent.v.Nd()||K.g.userAgent.v.Kg())};K.g.userAgent.v.Nd=K.g.userAgent.v.Rg;K.g.userAgent.v.uc=K.g.userAgent.v.Nk;K.g.userAgent.v.Ra=K.g.userAgent.v.Sd;K.g.userAgent.v.fk=K.g.userAgent.v.Mk;K.g.userAgent.v.Ur=K.g.userAgent.v.Sg;K.g.userAgent.v.Ar=K.g.userAgent.v.Rd;K.g.userAgent.v.Ir=K.g.userAgent.v.Ok;K.g.userAgent.v.zg=K.g.userAgent.v.Qd;K.g.userAgent.v.yr=K.g.userAgent.v.Lk;
K.g.userAgent.v.Kg=function(){return K.g.userAgent.A.K("Silk")};K.g.userAgent.v.Lb=function(){function b(b){b=K.j.find(b,e);return d[b]||""}var c=K.g.userAgent.A.sb();if(K.g.userAgent.v.uc())return K.g.userAgent.v.Jj(c);c=K.g.userAgent.A.Af(c);var d={};K.j.forEach(c,function(b){d[b[0]]=b[1]});var e=K.fb(K.object.bj,d);return K.g.userAgent.v.Nd()?b(["Version","Opera"]):K.g.userAgent.v.Ra()?b(["Edge"]):K.g.userAgent.v.zg()?b(["Chrome","CriOS"]):(c=c[2])&&c[1]||""};
K.g.userAgent.v.va=function(b){return 0<=K.f.Eb(K.g.userAgent.v.Lb(),b)};K.g.userAgent.v.Jj=function(b){var c=/rv: *([\d\.]*)/.exec(b);if(c&&c[1])return c[1];c="";var d=/MSIE +([\d\.]+)/.exec(b);if(d&&d[1])if(b=/Trident\/(\d.\d)/.exec(b),"7.0"==d[1])if(b&&b[1])switch(b[1]){case "4.0":c="8.0";break;case "5.0":c="9.0";break;case "6.0":c="10.0";break;case "7.0":c="11.0"}else c="7.0";else c=d[1];return c};K.g.userAgent.U={};K.g.userAgent.U.lk=function(){return K.g.userAgent.A.K("Presto")};K.g.userAgent.U.pk=function(){return K.g.userAgent.A.K("Trident")||K.g.userAgent.A.K("MSIE")};K.g.userAgent.U.Ra=function(){return K.g.userAgent.A.K("Edge")};K.g.userAgent.U.Mg=function(){return K.g.userAgent.A.Pk()&&!K.g.userAgent.U.Ra()};K.g.userAgent.U.gk=function(){return K.g.userAgent.A.K("Gecko")&&!K.g.userAgent.U.Mg()&&!K.g.userAgent.U.pk()&&!K.g.userAgent.U.Ra()};
K.g.userAgent.U.Lb=function(){var b=K.g.userAgent.A.sb();if(b){b=K.g.userAgent.A.Af(b);var c=K.g.userAgent.U.Hj(b);if(c)return"Gecko"==c[0]?K.g.userAgent.U.Rj(b):c[1];b=b[0];var d;if(b&&(d=b[2])&&(d=/Trident\/([^\s;]+)/.exec(d)))return d[1]}return""};K.g.userAgent.U.Hj=function(b){if(!K.g.userAgent.U.Ra())return b[1];for(var c=0;c<b.length;c++){var d=b[c];if("Edge"==d[0])return d}};K.g.userAgent.U.va=function(b){return 0<=K.f.Eb(K.g.userAgent.U.Lb(),b)};
K.g.userAgent.U.Rj=function(b){return(b=K.j.find(b,function(b){return"Firefox"==b[0]}))&&b[1]||""};K.async.qh=function(b){K.global.setTimeout(function(){throw b;},0)};K.async.pa=function(b,c,d){var e=b;c&&(e=K.bind(b,c));e=K.async.pa.Ah(e);K.ya(K.global.setImmediate)&&(d||K.async.pa.Kl())?K.global.setImmediate(e):(K.async.pa.kh||(K.async.pa.kh=K.async.pa.Nj()),K.async.pa.kh(e))};K.async.pa.Kl=function(){return K.global.Window&&K.global.Window.prototype&&!K.g.userAgent.v.Ra()&&K.global.Window.prototype.setImmediate==K.global.setImmediate?!1:!0};
K.async.pa.Nj=function(){var b=K.global.MessageChannel;"undefined"===typeof b&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!K.g.userAgent.U.lk()&&(b=function(){var b=document.createElement("IFRAME");b.style.display="none";b.src="";document.documentElement.appendChild(b);var c=b.contentWindow;b=c.document;b.open();b.write("");b.close();var d="callImmediate"+Math.random(),e="file:"==c.location.protocol?"*":c.location.protocol+"//"+c.location.host;b=K.bind(function(b){if(("*"==
e||b.origin==e)&&b.data==d)this.port1.onmessage()},this);c.addEventListener("message",b,!1);this.port1={};this.port2={postMessage:function(){c.postMessage(d,e)}}});if("undefined"!==typeof b&&!K.g.userAgent.v.uc()){var c=new b,d={},e=d;c.port1.onmessage=function(){if(K.R(d.next)){d=d.next;var b=d.lf;d.lf=null;b()}};return function(b){e.next={lf:b};e=e.next;c.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement(p)?function(b){var c=document.createElement(p);
c.onreadystatechange=function(){c.onreadystatechange=null;c.parentNode.removeChild(c);c=null;b();b=null};document.documentElement.appendChild(c)}:function(b){K.global.setTimeout(b,0)}};K.async.pa.Ah=K.J.$j;K.debug.Z.register(function(b){K.async.pa.Ah=b});K.async.Ea=function(){this.Qc=this.Ab=null};K.async.Ea.Vc=100;K.async.Ea.Kb=new K.async.Zb(function(){return new K.async.ad},function(b){b.reset()},K.async.Ea.Vc);K.async.Ea.prototype.add=function(b,c){var d=K.async.Ea.Kb.get();d.set(b,c);this.Qc?this.Qc.next=d:this.Ab=d;this.Qc=d};K.async.Ea.prototype.remove=function(){var b=null;this.Ab&&(b=this.Ab,this.Ab=this.Ab.next,this.Ab||(this.Qc=null),b.next=null);return b};K.async.ad=function(){this.next=this.scope=this.od=null};
K.async.ad.prototype.set=function(b,c){this.od=b;this.scope=c;this.next=null};K.async.ad.prototype.reset=function(){this.next=this.scope=this.od=null};K.async.M=function(b,c){K.async.M.Hc||K.async.M.bk();K.async.M.Pc||(K.async.M.Hc(),K.async.M.Pc=!0);K.async.M.ie.add(b,c)};K.async.M.bk=function(){if(-1!=String(K.global.Promise).indexOf("[native code]")){var b=K.global.Promise.resolve(void 0);K.async.M.Hc=function(){b.then(K.async.M.Cc)}}else K.async.M.Hc=function(){K.async.pa(K.async.M.Cc)}};K.async.M.Jq=function(b){K.async.M.Hc=function(){K.async.pa(K.async.M.Cc);b&&b(K.async.M.Cc)}};K.async.M.Pc=!1;K.async.M.ie=new K.async.Ea;
K.ea&&(K.async.M.Rs=function(){K.async.M.Pc=!1;K.async.M.ie=new K.async.Ea});K.async.M.Cc=function(){for(var b;b=K.async.M.ie.remove();){try{b.od.call(b.scope)}catch(c){K.async.qh(c)}K.async.Ea.Kb.put(b)}K.async.M.Pc=!1};K.a.m={};K.a.m.Cp=F();K.a.m.up=F();K.a.m.zp=F();K.a.m.yp=F();K.a.m.vp=F();K.a.m.wp=F();K.a.m.xp=F();K.a.m.Ap=F();K.a.m.Bp=F();K.a.m.sq=function(b){return K.ha(b)?b.constructor.displayName||b.constructor.name||Object.prototype.toString.call(b):void 0===b?"undefined":null===b?"null":typeof b};K.a.m.qc=function(b){return(b=b&&b.ownerDocument)&&(b.defaultView||b.parentWindow)||K.global};K.g.userAgent.platform={};K.g.userAgent.platform.yg=function(){return K.g.userAgent.A.K("Android")};K.g.userAgent.platform.Hg=function(){return K.g.userAgent.A.K("iPod")};K.g.userAgent.platform.Gg=function(){return K.g.userAgent.A.K("iPhone")&&!K.g.userAgent.A.K("iPod")&&!K.g.userAgent.A.K("iPad")};K.g.userAgent.platform.Fg=function(){return K.g.userAgent.A.K("iPad")};K.g.userAgent.platform.Eg=function(){return K.g.userAgent.platform.Gg()||K.g.userAgent.platform.Fg()||K.g.userAgent.platform.Hg()};
K.g.userAgent.platform.Ig=function(){return K.g.userAgent.A.K("Macintosh")};K.g.userAgent.platform.ik=function(){return K.g.userAgent.A.K("Linux")};K.g.userAgent.platform.Og=function(){return K.g.userAgent.A.K("Windows")};K.g.userAgent.platform.Ag=function(){return K.g.userAgent.A.K("CrOS")};
K.g.userAgent.platform.Lb=function(){var b=K.g.userAgent.A.sb(),c="";K.g.userAgent.platform.Og()?(c=/Windows (?:NT|Phone) ([0-9.]+)/,c=(b=c.exec(b))?b[1]:"0.0"):K.g.userAgent.platform.Eg()?(c=/(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/,c=(b=c.exec(b))&&b[1].replace(/_/g,".")):K.g.userAgent.platform.Ig()?(c=/Mac OS X ([0-9_.]+)/,c=(b=c.exec(b))?b[1].replace(/_/g,"."):"10"):K.g.userAgent.platform.yg()?(c=/Android\s+([^\);]+)(\)|;)/,c=(b=c.exec(b))&&b[1]):K.g.userAgent.platform.Ag()&&(c=/(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/,
c=(b=c.exec(b))&&b[1]);return c||""};K.g.userAgent.platform.va=function(b){return 0<=K.f.Eb(K.g.userAgent.platform.Lb(),b)};K.Ha={};K.Ha.object=function(b,c){return c};K.Ha.ce=function(b){K.Ha.ce[" "](b);return b};K.Ha.ce[" "]=K.eb;K.Ha.Pp=function(b,c){try{return K.Ha.ce(b[c]),!0}catch(d){}return!1};K.Ha.cache=function(b,c,d,e){e=e?e(c):c;return Object.prototype.hasOwnProperty.call(b,e)?b[e]:b[e]=d(c)};K.userAgent={};K.userAgent.oe=!1;K.userAgent.me=!1;K.userAgent.ne=!1;K.userAgent.te=!1;K.userAgent.Uc=!1;K.userAgent.re=!1;K.userAgent.Fh=!1;K.userAgent.Bb=K.userAgent.oe||K.userAgent.me||K.userAgent.ne||K.userAgent.Uc||K.userAgent.te||K.userAgent.re;K.userAgent.Qj=function(){return K.g.userAgent.A.sb()};K.userAgent.Yf=function(){return K.global.navigator||null};K.userAgent.Ne=K.userAgent.Bb?K.userAgent.re:K.g.userAgent.v.Nd();K.userAgent.Y=K.userAgent.Bb?K.userAgent.oe:K.g.userAgent.v.uc();
K.userAgent.Ce=K.userAgent.Bb?K.userAgent.me:K.g.userAgent.U.Ra();K.userAgent.Um=K.userAgent.Ce||K.userAgent.Y;K.userAgent.Yc=K.userAgent.Bb?K.userAgent.ne:K.g.userAgent.U.gk();K.userAgent.Cb=K.userAgent.Bb?K.userAgent.te||K.userAgent.Uc:K.g.userAgent.U.Mg();K.userAgent.kk=function(){return K.userAgent.Cb&&K.g.userAgent.A.K("Mobile")};K.userAgent.Yn=K.userAgent.Uc||K.userAgent.kk();K.userAgent.vo=K.userAgent.Cb;K.userAgent.nj=function(){var b=K.userAgent.Yf();return b&&b.platform||""};
K.userAgent.mo=K.userAgent.nj();K.userAgent.qe=!1;K.userAgent.ue=!1;K.userAgent.pe=!1;K.userAgent.ve=!1;K.userAgent.le=!1;K.userAgent.Sc=!1;K.userAgent.Rc=!1;K.userAgent.Tc=!1;K.userAgent.Da=K.userAgent.qe||K.userAgent.ue||K.userAgent.pe||K.userAgent.ve||K.userAgent.le||K.userAgent.Sc||K.userAgent.Rc||K.userAgent.Tc;K.userAgent.Rn=K.userAgent.Da?K.userAgent.qe:K.g.userAgent.platform.Ig();K.userAgent.ep=K.userAgent.Da?K.userAgent.ue:K.g.userAgent.platform.Og();
K.userAgent.hk=function(){return K.g.userAgent.platform.ik()||K.g.userAgent.platform.Ag()};K.userAgent.Qn=K.userAgent.Da?K.userAgent.pe:K.userAgent.hk();K.userAgent.tk=function(){var b=K.userAgent.Yf();return!!b&&K.f.contains(b.appVersion||"","X11")};K.userAgent.fp=K.userAgent.Da?K.userAgent.ve:K.userAgent.tk();K.userAgent.am=K.userAgent.Da?K.userAgent.le:K.g.userAgent.platform.yg();K.userAgent.Fn=K.userAgent.Da?K.userAgent.Sc:K.g.userAgent.platform.Gg();
K.userAgent.En=K.userAgent.Da?K.userAgent.Rc:K.g.userAgent.platform.Fg();K.userAgent.Gn=K.userAgent.Da?K.userAgent.Tc:K.g.userAgent.platform.Hg();K.userAgent.Dn=K.userAgent.Da?K.userAgent.Sc||K.userAgent.Rc||K.userAgent.Tc:K.g.userAgent.platform.Eg();K.userAgent.oj=function(){var b="",c=K.userAgent.Sj();c&&(b=c?c[1]:"");return K.userAgent.Y&&(c=K.userAgent.Of(),null!=c&&c>parseFloat(b))?String(c):b};
K.userAgent.Sj=function(){var b=K.userAgent.Qj();if(K.userAgent.Yc)return/rv\:([^\);]+)(\)|;)/.exec(b);if(K.userAgent.Ce)return/Edge\/([\d\.]+)/.exec(b);if(K.userAgent.Y)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(b);if(K.userAgent.Cb)return/WebKit\/(\S+)/.exec(b);if(K.userAgent.Ne)return/(?:Version)[ \/]?(\S+)/.exec(b)};K.userAgent.Of=function(){var b=K.global.document;return b?b.documentMode:void 0};K.userAgent.VERSION=K.userAgent.oj();K.userAgent.compare=function(b,c){return K.f.Eb(b,c)};
K.userAgent.rk={};K.userAgent.va=function(b){return K.userAgent.Fh||K.Ha.cache(K.userAgent.rk,b,function(){return 0<=K.f.Eb(K.userAgent.VERSION,b)})};K.userAgent.Zr=K.userAgent.va;K.userAgent.Pb=function(b){return Number(K.userAgent.Wh)>=b};K.userAgent.Cr=K.userAgent.Pb;var L;var M=K.global.document,aa=K.userAgent.Of();L=M&&K.userAgent.Y?aa||("CSS1Compat"==M.compatMode?parseInt(K.userAgent.VERSION,10):5):void 0;K.userAgent.Wh=L;K.a.ib={Lh:!K.userAgent.Y||K.userAgent.Pb(9),Mh:!K.userAgent.Yc&&!K.userAgent.Y||K.userAgent.Y&&K.userAgent.Pb(9)||K.userAgent.Yc&&K.userAgent.va("1.9.1"),xe:K.userAgent.Y&&!K.userAgent.va("9"),Nh:K.userAgent.Y||K.userAgent.Ne||K.userAgent.Cb,ci:K.userAgent.Y,Mn:K.userAgent.Y&&!K.userAgent.Pb(9)};K.a.Mc={};K.a.Mc.Hi={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0};K.a.Mc.sk=function(b){return!0===K.a.Mc.Hi[b]};K.b.V=function(){this.yc="";this.ni=K.b.V.ca};K.b.V.prototype.ua=!0;K.b.V.ca={};K.b.V.mc=function(b){b=K.f.I.u(b);return 0===b.length?K.b.V.EMPTY:K.b.V.hd(b)};K.b.V.prototype.ga=G("yc");K.ea&&(K.b.V.prototype.toString=function(){return"SafeScript{"+this.yc+"}"});K.b.V.u=function(b){if(b instanceof K.b.V&&b.constructor===K.b.V&&b.ni===K.b.V.ca)return b.yc;K.m.ma("expected object of type SafeScript, got '"+b+k+K.aa(b));return"type_error:SafeScript"};K.b.V.hd=function(b){return(new K.b.V).bb(b)};
K.b.V.prototype.bb=function(b){this.yc=b;return this};K.b.V.EMPTY=K.b.V.hd("");K.sa={};K.sa.url={};K.sa.url.dj=function(b){return K.sa.url.lg().createObjectURL(b)};K.sa.url.Ts=function(b){K.sa.url.lg().revokeObjectURL(b)};K.sa.url.lg=function(){var b=K.sa.url.Ef();if(null!=b)return b;throw Error("This browser doesn't seem to support blob URLs");};K.sa.url.Ef=function(){return K.R(K.global.URL)&&K.R(K.global.URL.createObjectURL)?K.global.URL:K.R(K.global.webkitURL)&&K.R(K.global.webkitURL.createObjectURL)?K.global.webkitURL:K.R(K.global.createObjectURL)?K.global:null};
K.sa.url.Lp=function(){return null!=K.sa.url.Ef()};K.b.o=function(){this.Ga="";this.ri=K.b.o.ca};K.b.o.Ka="about:invalid#zClosurez";K.b.o.prototype.ua=!0;K.b.o.prototype.ga=G("Ga");K.b.o.prototype.Dd=!0;K.b.o.prototype.$a=function(){return K.h.i.O.Ta};K.ea&&(K.b.o.prototype.toString=function(){return"SafeUrl{"+this.Ga+"}"});K.b.o.u=function(b){if(b instanceof K.b.o&&b.constructor===K.b.o&&b.ri===K.b.o.ca)return b.Ga;K.m.ma("expected object of type SafeUrl, got '"+b+k+K.aa(b));return"type_error:SafeUrl"};K.b.o.mc=function(b){return K.b.o.Fa(K.f.I.u(b))};
K.b.Re=/^(?:audio\/(?:3gpp|3gpp2|aac|midi|mp4|mpeg|ogg|x-m4a|x-wav|webm)|image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|text\/csv|video\/(?:mpeg|mp4|ogg|webm))$/i;K.b.o.Mq=function(b){b=K.b.Re.test(b.type)?K.sa.url.dj(b):K.b.o.Ka;return K.b.o.Fa(b)};K.b.Rh=/^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;K.b.o.Oq=function(b){var c=b.match(K.b.Rh);c=c&&K.b.Re.test(c[1]);return K.b.o.Fa(c?b:K.b.o.Ka)};K.b.o.Qq=function(b){K.f.Zi(b)||(b=K.b.o.Ka);return K.b.o.Fa(b)};K.b.o.Rq=function(b){return K.b.o.Fa(K.b.C.u(b))};
K.b.Se=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;K.b.o.Gc=function(b){if(b instanceof K.b.o)return b;b=b.ua?b.ga():String(b);K.b.Se.test(b)||(b=K.b.o.Ka);return K.b.o.Fa(b)};K.b.o.Vb=function(b){if(b instanceof K.b.o)return b;b=b.ua?b.ga():String(b);K.b.Se.test(b)||(b=K.b.o.Ka);return K.b.o.Fa(b)};K.b.o.ca={};K.b.o.Fa=function(b){var c=new K.b.o;c.Ga=b;return c};K.b.o.Wl=K.b.o.Fa("about:blank");K.b.B=function(){this.Ac="";this.pi=K.b.B.ca};K.b.B.prototype.ua=!0;K.b.B.ca={};K.b.B.mc=function(b){b=K.f.I.u(b);return 0===b.length?K.b.B.EMPTY:K.b.B.Fb(b)};K.b.B.Vp=F();K.b.B.prototype.ga=G("Ac");K.ea&&(K.b.B.prototype.toString=function(){return"SafeStyle{"+this.Ac+"}"});K.b.B.u=function(b){if(b instanceof K.b.B&&b.constructor===K.b.B&&b.pi===K.b.B.ca)return b.Ac;K.m.ma("expected object of type SafeStyle, got '"+b+k+K.aa(b));return"type_error:SafeStyle"};K.b.B.Fb=function(b){return(new K.b.B).bb(b)};
K.b.B.prototype.bb=function(b){this.Ac=b;return this};K.b.B.EMPTY=K.b.B.Fb("");K.b.B.Ka="zClosurez";K.b.B.create=function(b){var c="",d;for(d in b){if(!/^[-_a-zA-Z0-9]+$/.test(d))throw Error("Name allows only [-_a-zA-Z0-9], got: "+d);var e=b[d];null!=e&&(e=K.isArray(e)?K.j.map(e,K.b.B.gh).join(" "):K.b.B.gh(e),c+=d+":"+e+";")}return c?K.b.B.Fb(c):K.b.B.EMPTY};
K.b.B.gh=function(b){return b instanceof K.b.o?'url("'+K.b.o.u(b).replace(/</g,"%3c").replace(/[\\"]/g,"\\$&")+'")':b instanceof K.f.I?K.f.I.u(b):K.b.B.il(String(b))};K.b.B.il=function(b){var c=b.replace(K.b.o.ai,"$1").replace(K.b.o.Xe,"url");return K.b.B.Ei.test(c)?K.b.B.Vj(b)?K.b.B.jl(b):(K.m.ma("String value requires balanced quotes, got: "+b),K.b.B.Ka):(K.m.ma("String value allows only "+K.b.B.$e+" and simple functions, got: "+b),K.b.B.Ka)};
K.b.B.Vj=function(b){for(var c=!0,d=!0,e=0;e<b.length;e++){var f=b.charAt(e);"'"==f&&d?c=!c:'"'==f&&c&&(d=!d)}return c&&d};K.b.B.$e="[-,.\"'%_!# a-zA-Z0-9]";K.b.B.Ei=new RegExp("^"+K.b.B.$e+"+$");K.b.o.Xe=/\b(url\([ \t\n]*)('[ -&(-\[\]-~]*'|"[ !#-\[\]-~]*"|[!#-&*-\[\]-~]*)([ \t\n]*\))/g;K.b.o.ai=/\b(hsl|hsla|rgb|rgba|(rotate|scale|translate)(X|Y|Z|3d)?)\([-0-9a-z.%, ]+\)/g;
K.b.B.jl=function(b){return b.replace(K.b.o.Xe,function(b,d,e,f){var c="";e=e.replace(/^(['"])(.*)\1$/,function(b,d,e){c=d;return e});b=K.b.o.Gc(e).ga();return d+c+b+c+f})};K.b.B.concat=function(b){function c(b){K.isArray(b)?K.j.forEach(b,c):d+=K.b.B.u(b)}var d="";K.j.forEach(arguments,c);return d?K.b.B.Fb(d):K.b.B.EMPTY};K.b.N=function(){this.zc="";this.oi=K.b.N.ca};K.b.N.prototype.ua=!0;K.b.N.ca={};
K.b.N.kq=function(b,c){if(K.f.contains(b,"<"))throw Error("Selector does not allow '<', got: "+b);var d=b.replace(/('|")((?!\1)[^\r\n\f\\]|\\[\s\S])*\1/g,"");if(!/^[-_a-zA-Z0-9#.:* ,>+~[\]()=^$|]+$/.test(d))throw Error("Selector allows only [-_a-zA-Z0-9#.:* ,>+~[\\]()=^$|] and strings, got: "+b);if(!K.b.N.Uj(d))throw Error("() and [] in selector must be balanced, got: "+b);c instanceof K.b.B||(c=K.b.B.create(c));b=b+"{"+K.b.B.u(c)+"}";return K.b.N.Gb(b)};
K.b.N.Uj=function(b){for(var c={"(":")","[":"]"},d=[],e=0;e<b.length;e++){var f=b[e];if(c[f])d.push(c[f]);else if(K.object.contains(c,f)&&d.pop()!=f)return!1}return 0==d.length};K.b.N.concat=function(b){function c(b){K.isArray(b)?K.j.forEach(b,c):d+=K.b.N.u(b)}var d="";K.j.forEach(arguments,c);return K.b.N.Gb(d)};K.b.N.mc=function(b){b=K.f.I.u(b);return 0===b.length?K.b.N.EMPTY:K.b.N.Gb(b)};K.b.N.prototype.ga=G("zc");K.ea&&(K.b.N.prototype.toString=function(){return"SafeStyleSheet{"+this.zc+"}"});
K.b.N.u=function(b){if(b instanceof K.b.N&&b.constructor===K.b.N&&b.oi===K.b.N.ca)return b.zc;K.m.ma("expected object of type SafeStyleSheet, got '"+b+k+K.aa(b));return"type_error:SafeStyleSheet"};K.b.N.Gb=function(b){return(new K.b.N).bb(b)};K.b.N.prototype.bb=function(b){this.zc=b;return this};K.b.N.EMPTY=K.b.N.Gb("");K.b.l=function(){this.Ga="";this.mi=K.b.l.ca;this.kc=null};K.b.l.prototype.Dd=!0;K.b.l.prototype.$a=G("kc");K.b.l.prototype.ua=!0;K.b.l.prototype.ga=G("Ga");K.ea&&(K.b.l.prototype.toString=function(){return"SafeHtml{"+this.Ga+"}"});K.b.l.u=function(b){if(b instanceof K.b.l&&b.constructor===K.b.l&&b.mi===K.b.l.ca)return b.Ga;K.m.ma("expected object of type SafeHtml, got '"+b+k+K.aa(b));return"type_error:SafeHtml"};
K.b.l.ta=function(b){if(b instanceof K.b.l)return b;var c=null;b.Dd&&(c=b.$a());return K.b.l.ra(K.f.ta(b.ua?b.ga():String(b)),c)};K.b.l.pr=function(b){if(b instanceof K.b.l)return b;b=K.b.l.ta(b);return K.b.l.ra(K.f.Yg(K.b.l.u(b)),b.$a())};K.b.l.qr=function(b){if(b instanceof K.b.l)return b;b=K.b.l.ta(b);return K.b.l.ra(K.f.Ol(K.b.l.u(b)),b.$a())};K.b.l.from=K.b.l.ta;K.b.l.Ze=/^[a-zA-Z0-9-]+$/;K.b.l.Ci={action:!0,cite:!0,data:!0,formaction:!0,href:!0,manifest:!0,poster:!0,src:!0};
K.b.l.ii={APPLET:!0,BASE:!0,EMBED:!0,IFRAME:!0,LINK:!0,MATH:!0,META:!0,OBJECT:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};K.b.l.create=function(b,c,d){K.b.l.Ml(String(b));return K.b.l.Ya(String(b),c,d)};K.b.l.Ml=function(b){if(!K.b.l.Ze.test(b))throw Error("Invalid tag name <"+b+">.");if(b.toUpperCase()in K.b.l.ii)throw Error("Tag name <"+b+"> is not allowed for SafeHtml.");};
K.b.l.hq=function(b,c,d,e){b&&K.b.C.u(b);var f={};f.src=b||null;f.srcdoc=c&&K.b.l.u(c);b=K.b.l.hc(f,{sandbox:""},d);return K.b.l.Ya("iframe",b,e)};K.b.l.lq=function(b,c,d,e){if(!K.b.l.Wi())throw Error("The browser does not support sandboxed iframes.");var f={};f.src=b?K.b.o.u(K.b.o.Gc(b)):null;f.srcdoc=c||null;f.sandbox="";b=K.b.l.hc(f,{},d);return K.b.l.Ya("iframe",b,e)};K.b.l.Wi=function(){return K.global.HTMLIFrameElement&&"sandbox"in K.global.HTMLIFrameElement.prototype};
K.b.l.nq=function(b,c){K.b.C.u(b);b=K.b.l.hc({src:b},{},c);return K.b.l.Ya("script",b)};K.b.l.mq=function(b,c){for(var d in c){var e=d.toLowerCase();if("language"==e||"src"==e||"text"==e||"type"==e)throw Error('Cannot set "'+e+'" attribute');}d="";b=K.j.concat(b);for(e=0;e<b.length;e++)d+=K.b.V.u(b[e]);b=K.b.l.ra(d,K.h.i.O.qa);return K.b.l.Ya("script",c,b)};
K.b.l.oq=function(b,c){c=K.b.l.hc({type:"text/css"},{},c);var d="";b=K.j.concat(b);for(var e=0;e<b.length;e++)d+=K.b.N.u(b[e]);b=K.b.l.ra(d,K.h.i.O.qa);return K.b.l.Ya("style",c,b)};K.b.l.jq=function(b,c){b=K.b.o.u(K.b.o.Gc(b));(K.g.userAgent.v.uc()||K.g.userAgent.v.Ra())&&K.f.contains(b,";")&&(b="'"+b.replace(/'/g,"%27")+"'");return K.b.l.Ya("meta",{"http-equiv":"refresh",content:(c||0)+"; url="+b})};
K.b.l.Cj=function(b,c,d){if(d instanceof K.f.I)d=K.f.I.u(d);else if("style"==c.toLowerCase())d=K.b.l.Oj(d);else{if(/^on/i.test(c))throw Error('Attribute "'+c+'" requires goog.string.Const value, "'+d+'" given.');if(c.toLowerCase()in K.b.l.Ci)if(d instanceof K.b.C)d=K.b.C.u(d);else if(d instanceof K.b.o)d=K.b.o.u(d);else if(K.L(d))d=K.b.o.Gc(d).ga();else throw Error('Attribute "'+c+'" on tag "'+b+'" requires goog.html.SafeUrl, goog.string.Const, or string, value "'+d+'" given.');}d.ua&&(d=d.ga());
return c+'="'+K.f.ta(String(d))+'"'};K.b.l.Oj=function(b){if(!K.ha(b))throw Error('The "style" attribute requires goog.html.SafeStyle or map of style properties, '+typeof b+" given: "+b);b instanceof K.b.B||(b=K.b.B.create(b));return K.b.B.u(b)};K.b.l.qq=function(b,c,d,e){c=K.b.l.create(c,d,e);c.kc=b;return c};
K.b.l.concat=function(b){function c(b){K.isArray(b)?K.j.forEach(b,c):(b=K.b.l.ta(b),e+=K.b.l.u(b),b=b.$a(),d==K.h.i.O.qa?d=b:b!=K.h.i.O.qa&&d!=b&&(d=null))}var d=K.h.i.O.qa,e="";K.j.forEach(arguments,c);return K.b.l.ra(e,d)};K.b.l.cq=function(b,c){var d=K.b.l.concat(K.j.slice(arguments,1));d.kc=b;return d};K.b.l.ca={};K.b.l.ra=function(b,c){return(new K.b.l).bb(b,c)};K.b.l.prototype.bb=function(b,c){this.Ga=b;this.kc=c;return this};
K.b.l.Ya=function(b,c,d){var e=null;var f="<"+b+K.b.l.vl(b,c);K.cb(d)?K.isArray(d)||(d=[d]):d=[];K.a.Mc.sk(b.toLowerCase())?f+=">":(e=K.b.l.concat(d),f+=">"+K.b.l.u(e)+"</"+b+">",e=e.$a());(b=c&&c.dir)&&(e=/^(ltr|rtl|auto)$/i.test(b)?K.h.i.O.qa:null);return K.b.l.ra(f,e)};K.b.l.vl=function(b,c){var d="";if(c)for(var e in c){if(!K.b.l.Ze.test(e))throw Error('Invalid attribute name "'+e+'".');var f=c[e];K.cb(f)&&(d+=" "+K.b.l.Cj(b,e,f))}return d};
K.b.l.hc=function(b,c,d){var e={},f;for(f in b)e[f]=b[f];for(f in c)e[f]=c[f];for(f in d){var g=f.toLowerCase();if(g in b)throw Error('Cannot override "'+g+'" attribute, got "'+f+'" with value "'+d[f]+'"');g in c&&delete e[g];e[f]=d[f]}return e};K.b.l.Qm=K.b.l.ra("<!DOCTYPE html>",K.h.i.O.qa);K.b.l.EMPTY=K.b.l.ra("",K.h.i.O.qa);K.b.l.we=K.b.l.ra("<br>",K.h.i.O.qa);K.a.S={};K.a.S.In={Zl:"afterbegin",$l:"afterend",om:"beforebegin",pm:"beforeend"};K.a.S.sr=function(b,c,d){b.insertAdjacentHTML(c,K.b.l.u(d))};K.a.S.ui={MATH:!0,SCRIPT:!0,STYLE:!0,SVG:!0,TEMPLATE:!0};K.a.S.lh=function(b,c){if(K.m.ja&&K.a.S.ui[b.tagName.toUpperCase()])throw Error("goog.dom.safe.setInnerHtml cannot be used to set content of "+b.tagName+".");b.innerHTML=K.b.l.u(c)};K.a.S.ot=function(b,c){b.outerHTML=K.b.l.u(c)};K.a.S.qt=function(b,c){b.style.cssText=K.b.B.u(c)};K.a.S.wq=function(b,c){b.write(K.b.l.u(c))};
K.a.S.at=function(b,c){c=c instanceof K.b.o?c:K.b.o.Vb(c);b.href=K.b.o.u(c)};K.a.S.kt=function(b,c){c=c instanceof K.b.o?c:K.b.o.Vb(c);b.src=K.b.o.u(c)};K.a.S.et=function(b,c){b.src=K.b.C.u(c)};K.a.S.gt=function(b,c){b.src=K.b.C.u(c)};K.a.S.it=function(b,c){b.src=K.b.C.u(c)};K.a.S.jt=function(b,c){b.srcdoc=K.b.l.u(c)};K.a.S.lt=function(b,c,d){b.rel=d;K.f.kf(d,"stylesheet")?b.href=K.b.C.u(c):b.href=c instanceof K.b.C?K.b.C.u(c):c instanceof K.b.o?K.b.o.u(c):K.b.o.Vb(c).ga()};
K.a.S.nt=function(b,c){b.data=K.b.C.u(c)};K.a.S.ol=function(b,c){b.src=K.b.C.u(c)};K.a.S.pt=function(b,c){b.text=K.b.V.u(c)};K.a.S.mt=function(b,c){c=c instanceof K.b.o?c:K.b.o.Vb(c);b.href=K.b.o.u(c)};K.a.S.zs=function(b,c,d,e,f){b=b instanceof K.b.o?b:K.b.o.Vb(b);return(c||window).open(K.b.o.u(b),d?K.f.I.u(d):"",e,f)};K.b.hb={};K.b.hb.fl=function(b,c){return K.b.l.ra(c,null)};K.b.hb.Xs=function(b,c){return K.b.V.hd(c)};K.b.hb.Ys=function(b,c){return K.b.B.Fb(c)};K.b.hb.Zs=function(b,c){return K.b.N.Gb(c)};K.b.hb.$s=function(b,c){return K.b.o.Fa(c)};K.b.hb.Ot=function(b,c){return K.b.C.Hb(c)};K.s={};K.s.Fs=function(b){return Math.floor(Math.random()*b)};K.s.Qt=function(b,c){return b+Math.random()*(c-b)};K.s.Wp=function(b,c,d){return Math.min(Math.max(b,c),d)};K.s.Vg=function(b,c){b%=c;return 0>b*c?b+c:b};K.s.bs=function(b,c,d){return b+d*(c-b)};K.s.ps=function(b,c,d){return Math.abs(b-c)<=(d||1E-6)};K.s.fe=function(b){return K.s.Vg(b,360)};K.s.At=function(b){return K.s.Vg(b,2*Math.PI)};K.s.uh=function(b){return b*Math.PI/180};K.s.zl=function(b){return 180*b/Math.PI};
K.s.mp=function(b,c){return c*Math.cos(K.s.uh(b))};K.s.np=function(b,c){return c*Math.sin(K.s.uh(b))};K.s.angle=function(b,c,d,e){return K.s.fe(K.s.zl(Math.atan2(e-c,d-b)))};K.s.lp=function(b,c){b=K.s.fe(c)-K.s.fe(b);180<b?b-=360:-180>=b&&(b=360+b);return b};K.s.sign=function(b){return 0<b?1:0>b?-1:b};
K.s.gs=function(b,c,d,e){d=d||function(b,c){return b==c};e=e||function(c){return b[c]};for(var f=b.length,g=c.length,h=[],l=0;l<f+1;l++)h[l]=[],h[l][0]=0;for(var m=0;m<g+1;m++)h[0][m]=0;for(l=1;l<=f;l++)for(m=1;m<=g;m++)d(b[l-1],c[m-1])?h[l][m]=h[l-1][m-1]+1:h[l][m]=Math.max(h[l-1][m],h[l][m-1]);var q=[];l=f;for(m=g;0<l&&0<m;)d(b[l-1],c[m-1])?(q.unshift(e(l-1,m-1)),l--,m--):h[l-1][m]>h[l][m-1]?l--:m--;return q};K.s.ge=function(b){return K.j.reduce(arguments,function(b,d){return b+d},0)};
K.s.Pi=function(b){return K.s.ge.apply(null,arguments)/arguments.length};K.s.hl=function(b){var c=arguments.length;if(2>c)return 0;var d=K.s.Pi.apply(null,arguments);return K.s.ge.apply(null,K.j.map(arguments,function(b){return Math.pow(b-d,2)}))/(c-1)};K.s.Bt=function(b){return Math.sqrt(K.s.hl.apply(null,arguments))};K.s.Hr=function(b){return isFinite(b)&&0==b%1};K.s.Fr=function(b){return isFinite(b)};K.s.Mr=function(b){return 0==b&&0>1/b};
K.s.fs=function(b){if(0<b){var c=Math.round(Math.log(b)*Math.LOG10E);return c-(parseFloat("1e"+c)>b?1:0)}return 0==b?-Infinity:NaN};K.s.Vs=function(b,c){return Math.floor(b+(c||2E-15))};K.s.Us=function(b,c){return Math.ceil(b-(c||2E-15))};K.s.W=function(b,c){this.x=K.R(b)?b:0;this.y=K.R(c)?c:0};K.s.W.prototype.clone=function(){return new K.s.W(this.x,this.y)};K.ea&&(K.s.W.prototype.toString=function(){return"("+this.x+", "+this.y+")"});K.s.W.prototype.Ib=function(b){return b instanceof K.s.W&&K.s.W.Ib(this,b)};K.s.W.Ib=function(b,c){return b==c?!0:b&&c?b.x==c.x&&b.y==c.y:!1};K.s.W.vq=function(b,c){var d=b.x-c.x;b=b.y-c.y;return Math.sqrt(d*d+b*b)};K.s.W.hs=function(b){return Math.sqrt(b.x*b.x+b.y*b.y)};
K.s.W.azimuth=function(b){return K.s.angle(0,0,b.x,b.y)};K.s.W.yt=function(b,c){var d=b.x-c.x;b=b.y-c.y;return d*d+b*b};K.s.W.uq=function(b,c){return new K.s.W(b.x-c.x,b.y-c.y)};K.s.W.ge=function(b,c){return new K.s.W(b.x+c.x,b.y+c.y)};I=K.s.W.prototype;I.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};I.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};I.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};
I.translate=function(b,c){b instanceof K.s.W?(this.x+=b.x,this.y+=b.y):(this.x+=Number(b),K.Rb(c)&&(this.y+=c));return this};I.scale=function(b,c){c=K.Rb(c)?c:b;this.x*=b;this.y*=c;return this};K.s.nb=function(b,c){this.width=b;this.height=c};K.s.nb.Ib=function(b,c){return b==c?!0:b&&c?b.width==c.width&&b.height==c.height:!1};K.s.nb.prototype.clone=function(){return new K.s.nb(this.width,this.height)};K.ea&&(K.s.nb.prototype.toString=function(){return"("+this.width+" x "+this.height+")"});I=K.s.nb.prototype;I.Li=function(){return this.width*this.height};I.aspectRatio=function(){return this.width/this.height};I.Qb=function(){return!this.Li()};
I.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};I.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};I.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};I.scale=function(b,c){c=K.Rb(c)?c:b;this.width*=b;this.height*=c;return this};K.a.Hh=!1;K.a.se=!1;K.a.Qh=K.a.Hh||K.a.se;K.a.td=function(b){return b?new K.a.lb(K.a.Qa(b)):K.a.mj||(K.a.mj=new K.a.lb)};K.a.Dj=function(){return document};K.a.ud=function(b){return K.a.xd(document,b)};K.a.xd=function(b,c){return K.L(c)?b.getElementById(c):c};K.a.Lj=function(b){return K.a.ig(document,b)};K.a.ig=function(b,c){return K.a.xd(b,c)};K.a.Bh=K.a.ud;K.a.getElementsByTagName=function(b,c){return(c||document).getElementsByTagName(String(b))};
K.a.yd=function(b,c,d){return K.a.nc(document,b,c,d)};K.a.Gj=function(b,c,d){return K.a.wd(document,b,c,d)};K.a.Rf=function(b,c){var d=c||document;return K.a.cd(d)?d.querySelectorAll("."+b):K.a.nc(document,"*",b,c)};K.a.vd=function(b,c){var d=c||document;return(d.getElementsByClassName?d.getElementsByClassName(b)[0]:K.a.wd(document,"*",b,c))||null};K.a.hg=function(b,c){return K.a.vd(b,c)};K.a.cd=function(b){return!(!b.querySelectorAll||!b.querySelector)};
K.a.nc=function(b,c,d,e){b=e||b;c=c&&"*"!=c?String(c).toUpperCase():"";if(K.a.cd(b)&&(c||d))return b.querySelectorAll(c+(d?"."+d:""));if(d&&b.getElementsByClassName){b=b.getElementsByClassName(d);if(c){e={};for(var f=0,g=0,h;h=b[g];g++)c==h.nodeName&&(e[f++]=h);e.length=f;return e}return b}b=b.getElementsByTagName(c||"*");if(d){e={};for(g=f=0;h=b[g];g++)c=h.className,typeof c.split==u&&K.j.contains(c.split(/\s+/),d)&&(e[f++]=h);e.length=f;return e}return b};
K.a.wd=function(b,c,d,e){var f=e||b,g=c&&"*"!=c?String(c).toUpperCase():"";return K.a.cd(f)&&(g||d)?f.querySelector(g+(d?"."+d:"")):K.a.nc(b,c,d,e)[0]||null};K.a.Ch=K.a.yd;K.a.Jc=function(b,c){K.object.forEach(c,function(c,e){c&&c.ua&&(c=c.ga());"style"==e?b.style.cssText=c:"class"==e?b.className=c:"for"==e?b.htmlFor=c:K.a.Be.hasOwnProperty(e)?b.setAttribute(K.a.Be[e],c):K.f.startsWith(e,"aria-")||K.f.startsWith(e,"data-")?b.setAttribute(e,c):b[e]=c})};
K.a.Be={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};K.a.mg=function(b){return K.a.ng(b||window)};K.a.ng=function(b){b=b.document;b=K.a.Ob(b)?b.documentElement:b.body;return new K.s.nb(b.clientWidth,b.clientHeight)};K.a.Ej=function(){return K.a.rd(window)};K.a.Xq=function(b){return K.a.rd(b)};
K.a.rd=function(b){var c=b.document,d=0;if(c){d=c.body;var e=c.documentElement;if(!e||!d)return 0;b=K.a.ng(b).height;if(K.a.Ob(c)&&e.scrollHeight)d=e.scrollHeight!=b?e.scrollHeight:e.offsetHeight;else{c=e.scrollHeight;var f=e.offsetHeight;e.clientHeight!=f&&(c=d.scrollHeight,f=d.offsetHeight);d=c>b?c>f?c:f:c<f?c:f}}return d};K.a.dr=function(b){return K.a.td((b||K.global||window).document).Pf()};K.a.Pf=function(){return K.a.Qf(document)};
K.a.Qf=function(b){var c=K.a.sd(b);b=K.a.qc(b);return K.userAgent.Y&&K.userAgent.va("10")&&b.pageYOffset!=c.scrollTop?new K.s.W(c.scrollLeft,c.scrollTop):new K.s.W(b.pageXOffset||c.scrollLeft,b.pageYOffset||c.scrollTop)};K.a.Fj=function(){return K.a.sd(document)};K.a.sd=function(b){return b.scrollingElement?b.scrollingElement:!K.userAgent.Cb&&K.a.Ob(b)?b.documentElement:b.body||b.documentElement};K.a.tb=function(b){return b?K.a.qc(b):window};K.a.qc=function(b){return b.parentWindow||b.defaultView};
K.a.fd=function(b,c,d){return K.a.sf(document,arguments)};K.a.sf=function(b,c){var d=String(c[0]),e=c[1];if(!K.a.ib.Lh&&e&&(e.name||e.type)){d=["<",d];e.name&&d.push(' name="',K.f.ta(e.name),'"');if(e.type){d.push(' type="',K.f.ta(e.type),'"');var f={};K.object.extend(f,e);delete f.type;e=f}d.push(">");d=d.join("")}d=b.createElement(d);e&&(K.L(e)?d.className=e:K.isArray(e)?d.className=e.join(" "):K.a.Jc(d,e));2<c.length&&K.a.bf(b,d,c,2);return d};
K.a.bf=function(b,c,d,e){function f(d){d&&c.appendChild(K.L(d)?b.createTextNode(d):d)}for(;e<d.length;e++){var g=d[e];K.Nb(g)&&!K.a.Ld(g)?K.j.forEach(K.a.Md(g)?K.j.th(g):g,f):f(g)}};K.a.Dh=K.a.fd;K.a.createElement=function(b){return K.a.Oa(document,b)};K.a.Oa=function(b,c){return b.createElement(String(c))};K.a.createTextNode=function(b){return document.createTextNode(String(b))};K.a.hj=function(b,c,d){return K.a.tf(document,b,c,!!d)};
K.a.tf=function(b,c,d,e){for(var f=K.a.Oa(b,"TABLE"),g=f.appendChild(K.a.Oa(b,"TBODY")),h=0;h<c;h++){for(var l=K.a.Oa(b,"TR"),m=0;m<d;m++){var q=K.a.Oa(b,"TD");e&&K.a.ae(q,K.f.Ye.Ke);l.appendChild(q)}g.appendChild(l)}return f};K.a.eq=function(b){var c=K.j.map(arguments,K.f.I.u);c=K.b.hb.fl(K.f.I.from("Constant HTML string, that gets turned into a Node later, so it will be automatically balanced."),c.join(""));return K.a.eh(c)};K.a.eh=function(b){return K.a.fh(document,b)};
K.a.fh=function(b,c){var d=K.a.Oa(b,"DIV");K.a.ib.ci?(K.a.S.lh(d,K.b.l.concat(K.b.l.we,c)),d.removeChild(d.firstChild)):K.a.S.lh(d,c);return K.a.$i(b,d)};K.a.$i=function(b,c){if(1==c.childNodes.length)return c.removeChild(c.firstChild);for(b=b.createDocumentFragment();c.firstChild;)b.appendChild(c.firstChild);return b};K.a.dk=function(){return K.a.Ob(document)};K.a.Ob=function(b){return K.a.Qh?K.a.se:"CSS1Compat"==b.compatMode};K.a.canHaveChildren=function(b){if(b.nodeType!=K.a.fa.Ia)return!1;switch(b.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "COMMAND":case "EMBED":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "KEYGEN":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case p:case "SOURCE":case "STYLE":case "TRACK":case "WBR":return!1}return!0};
K.a.appendChild=function(b,c){b.appendChild(c)};K.a.append=function(b,c){K.a.bf(K.a.Qa(b),b,arguments,1)};K.a.Zd=function(b){for(var c;c=b.firstChild;)b.removeChild(c)};K.a.vg=function(b,c){c.parentNode&&c.parentNode.insertBefore(b,c)};K.a.ug=function(b,c){c.parentNode&&c.parentNode.insertBefore(b,c.nextSibling)};K.a.tg=function(b,c,d){b.insertBefore(c,b.childNodes[d]||null)};K.a.removeNode=function(b){return b&&b.parentNode?b.parentNode.removeChild(b):null};
K.a.dh=function(b,c){var d=c.parentNode;d&&d.replaceChild(b,c)};K.a.Ff=function(b){var c,d=b.parentNode;if(d&&d.nodeType!=K.a.fa.Vh){if(b.removeNode)return b.removeNode(!1);for(;c=b.firstChild;)d.insertBefore(c,b);return K.a.removeNode(b)}};K.a.Nf=function(b){return K.a.ib.Mh&&void 0!=b.children?b.children:K.j.filter(b.childNodes,function(b){return b.nodeType==K.a.fa.Ia})};K.a.Sf=function(b){return K.R(b.firstElementChild)?b.firstElementChild:K.a.oc(b.firstChild,!0)};
K.a.Wf=function(b){return K.R(b.lastElementChild)?b.lastElementChild:K.a.oc(b.lastChild,!1)};K.a.Zf=function(b){return K.R(b.nextElementSibling)?b.nextElementSibling:K.a.oc(b.nextSibling,!0)};K.a.fg=function(b){return K.R(b.previousElementSibling)?b.previousElementSibling:K.a.oc(b.previousSibling,!1)};K.a.oc=function(b,c){for(;b&&b.nodeType!=K.a.fa.Ia;)b=c?b.nextSibling:b.previousSibling;return b};
K.a.$f=function(b){if(!b)return null;if(b.firstChild)return b.firstChild;for(;b&&!b.nextSibling;)b=b.parentNode;return b?b.nextSibling:null};K.a.gg=function(b){if(!b)return null;if(!b.previousSibling)return b.parentNode;for(b=b.previousSibling;b&&b.lastChild;)b=b.lastChild;return b};K.a.Ld=function(b){return K.ha(b)&&0<b.nodeType};K.a.Hd=function(b){return K.ha(b)&&b.nodeType==K.a.fa.Ia};K.a.Ng=function(b){return K.ha(b)&&b.window==b};
K.a.eg=function(b){var c;if(K.a.ib.Nh&&!(K.userAgent.Y&&K.userAgent.va("9")&&!K.userAgent.va("10")&&K.global.SVGElement&&b instanceof K.global.SVGElement)&&(c=b.parentElement))return c;c=b.parentNode;return K.a.Hd(c)?c:null};K.a.contains=function(b,c){if(!b||!c)return!1;if(b.contains&&c.nodeType==K.a.fa.Ia)return b==c||b.contains(c);if("undefined"!=typeof b.compareDocumentPosition)return b==c||!!(b.compareDocumentPosition(c)&16);for(;c&&b!=c;)c=c.parentNode;return c==b};
K.a.mf=function(b,c){if(b==c)return 0;if(b.compareDocumentPosition)return b.compareDocumentPosition(c)&2?1:-1;if(K.userAgent.Y&&!K.userAgent.Pb(9)){if(b.nodeType==K.a.fa.Xc)return-1;if(c.nodeType==K.a.fa.Xc)return 1}if("sourceIndex"in b||b.parentNode&&"sourceIndex"in b.parentNode){var d=b.nodeType==K.a.fa.Ia,e=c.nodeType==K.a.fa.Ia;if(d&&e)return b.sourceIndex-c.sourceIndex;var f=b.parentNode,g=c.parentNode;return f==g?K.a.pf(b,c):!d&&K.a.contains(f,c)?-1*K.a.nf(b,c):!e&&K.a.contains(g,b)?K.a.nf(c,
b):(d?b.sourceIndex:f.sourceIndex)-(e?c.sourceIndex:g.sourceIndex)}e=K.a.Qa(b);d=e.createRange();d.selectNode(b);d.collapse(!0);b=e.createRange();b.selectNode(c);b.collapse(!0);return d.compareBoundaryPoints(K.global.Range.START_TO_END,b)};K.a.nf=function(b,c){var d=b.parentNode;if(d==c)return-1;for(;c.parentNode!=d;)c=c.parentNode;return K.a.pf(c,b)};K.a.pf=function(b,c){for(;c=c.previousSibling;)if(c==b)return-1;return 1};
K.a.Bf=function(b){var c,d=arguments.length;if(!d)return null;if(1==d)return arguments[0];var e=[],f=Infinity;for(c=0;c<d;c++){for(var g=[],h=arguments[c];h;)g.unshift(h),h=h.parentNode;e.push(g);f=Math.min(f,g.length)}g=null;for(c=0;c<f;c++){h=e[0][c];for(var l=1;l<d;l++)if(h!=e[l][c])return g;g=h}return g};K.a.Qa=function(b){return b.nodeType==K.a.fa.Xc?b:b.ownerDocument||b.document};K.a.Tf=function(b){return b.contentDocument||b.contentWindow.document};
K.a.Uf=function(b){try{return b.contentWindow||(b.contentDocument?K.a.tb(b.contentDocument):null)}catch(c){}return null};K.a.ae=function(b,c){if("textContent"in b)b.textContent=c;else if(b.nodeType==K.a.fa.cc)b.data=String(c);else if(b.firstChild&&b.firstChild.nodeType==K.a.fa.cc){for(;b.lastChild!=b.firstChild;)b.removeChild(b.lastChild);b.firstChild.data=String(c)}else{K.a.Zd(b);var d=K.a.Qa(b);b.appendChild(d.createTextNode(String(c)))}};
K.a.dg=function(b){if("outerHTML"in b)return b.outerHTML;var c=K.a.Qa(b);c=K.a.Oa(c,"DIV");c.appendChild(b.cloneNode(!0));return c.innerHTML};K.a.Cf=function(b,c){var d=[];return K.a.nd(b,c,d,!0)?d[0]:void 0};K.a.Df=function(b,c){var d=[];K.a.nd(b,c,d,!1);return d};K.a.nd=function(b,c,d,e){if(null!=b)for(b=b.firstChild;b;){if(c(b)&&(d.push(b),e)||K.a.nd(b,c,d,e))return!0;b=b.nextSibling}return!1};K.a.Ue={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1};K.a.ac={IMG:" ",BR:"\n"};
K.a.Jd=function(b){return K.a.pg(b)&&K.a.Lg(b)};K.a.jh=function(b,c){c?b.tabIndex=0:(b.tabIndex=-1,b.removeAttribute("tabIndex"))};K.a.Cg=function(b){var c;return(c=K.a.Qk(b)?!b.disabled&&(!K.a.pg(b)||K.a.Lg(b)):K.a.Jd(b))&&K.userAgent.Y?K.a.Wj(b):c};K.a.pg=function(b){return K.userAgent.Y&&!K.userAgent.va("9")?(b=b.getAttributeNode("tabindex"),K.cb(b)&&b.specified):b.hasAttribute("tabindex")};K.a.Lg=function(b){b=b.tabIndex;return K.Rb(b)&&0<=b&&32768>b};
K.a.Qk=function(b){return"A"==b.tagName||"INPUT"==b.tagName||"TEXTAREA"==b.tagName||"SELECT"==b.tagName||"BUTTON"==b.tagName};K.a.Wj=function(b){b=!K.ya(b.getBoundingClientRect)||K.userAgent.Y&&null==b.parentElement?{height:b.offsetHeight,width:b.offsetWidth}:b.getBoundingClientRect();return K.cb(b)&&0<b.height&&0<b.width};
K.a.pc=function(b){if(K.a.ib.xe&&null!==b&&"innerText"in b)b=K.f.Yi(b.innerText);else{var c=[];K.a.Ad(b,c,!0);b=c.join("")}b=b.replace(/ \xAD /g," ").replace(/\xAD/g,"");b=b.replace(/\u200B/g,"");K.a.ib.xe||(b=b.replace(/ +/g," "));" "!=b&&(b=b.replace(/^\s*/,""));return b};K.a.gr=function(b){var c=[];K.a.Ad(b,c,!1);return c.join("")};
K.a.Ad=function(b,c,d){if(!(b.nodeName in K.a.Ue))if(b.nodeType==K.a.fa.cc)d?c.push(String(b.nodeValue).replace(/(\r\n|\r|\n)/g,"")):c.push(b.nodeValue);else if(b.nodeName in K.a.ac)c.push(K.a.ac[b.nodeName]);else for(b=b.firstChild;b;)K.a.Ad(b,c,d),b=b.nextSibling};K.a.bg=function(b){return K.a.pc(b).length};K.a.cg=function(b,c){c=c||K.a.Qa(b).body;for(var d=[];b&&b!=c;){for(var e=b;e=e.previousSibling;)d.unshift(K.a.pc(e));b=b.parentNode}return K.f.trimLeft(d.join("")).replace(/ +/g," ").length};
K.a.ag=function(b,c,d){b=[b];for(var e=0,f=null;0<b.length&&e<c;)if(f=b.pop(),!(f.nodeName in K.a.Ue))if(f.nodeType==K.a.fa.cc){var g=f.nodeValue.replace(/(\r\n|\r|\n)/g,"").replace(/ +/g," ");e+=g.length}else if(f.nodeName in K.a.ac)e+=K.a.ac[f.nodeName].length;else for(g=f.childNodes.length-1;0<=g;g--)b.push(f.childNodes[g]);K.ha(d)&&(d.Is=f?f.nodeValue.length+c-e-1:0,d.node=f);return f};
K.a.Md=function(b){if(b&&typeof b.length==x){if(K.ha(b))return typeof b.item==u||typeof b.item==B;if(K.ya(b))return typeof b.item==u}return!1};K.a.qd=function(b,c,d,e){if(!c&&!d)return null;var f=c?String(c).toUpperCase():null;return K.a.pd(b,function(b){return(!f||b.nodeName==f)&&(!d||K.L(b.className)&&K.j.contains(b.className.split(/\s+/),d))},!0,e)};K.a.Kf=function(b,c,d){return K.a.qd(b,null,c,d)};
K.a.pd=function(b,c,d,e){b&&!d&&(b=b.parentNode);for(d=0;b&&(null==e||d<=e);){if(c(b))return b;b=b.parentNode;d++}return null};K.a.Jf=function(b){try{return b&&b.activeElement}catch(c){}return null};K.a.er=function(){var b=K.a.tb();return K.R(b.devicePixelRatio)?b.devicePixelRatio:b.matchMedia?K.a.wc(3)||K.a.wc(2)||K.a.wc(1.5)||K.a.wc(1)||.75:1};
K.a.wc=function(b){return K.a.tb().matchMedia("(min-resolution: "+b+"dppx),(min--moz-device-pixel-ratio: "+b+"),(min-resolution: "+96*b+"dpi)").matches?b:0};K.a.Mf=function(b){return b.getContext("2d")};K.a.lb=function(b){this.X=b||K.global.document||document};I=K.a.lb.prototype;I.td=K.a.td;I.Dj=G("X");I.ud=function(b){return K.a.xd(this.X,b)};I.Lj=function(b){return K.a.ig(this.X,b)};I.Bh=K.a.lb.prototype.ud;I.getElementsByTagName=function(b,c){return(c||this.X).getElementsByTagName(String(b))};
I.yd=function(b,c,d){return K.a.nc(this.X,b,c,d)};I.Gj=function(b,c,d){return K.a.wd(this.X,b,c,d)};I.Rf=function(b,c){return K.a.Rf(b,c||this.X)};I.vd=function(b,c){return K.a.vd(b,c||this.X)};I.hg=function(b,c){return K.a.hg(b,c||this.X)};I.Ch=K.a.lb.prototype.yd;I.Jc=K.a.Jc;I.mg=function(b){return K.a.mg(b||this.tb())};I.Ej=function(){return K.a.rd(this.tb())};I.fd=function(b,c,d){return K.a.sf(this.X,arguments)};I.Dh=K.a.lb.prototype.fd;I.createElement=function(b){return K.a.Oa(this.X,b)};
I.createTextNode=function(b){return this.X.createTextNode(String(b))};I.hj=function(b,c,d){return K.a.tf(this.X,b,c,!!d)};I.eh=function(b){return K.a.fh(this.X,b)};I.dk=function(){return K.a.Ob(this.X)};I.tb=function(){return K.a.qc(this.X)};I.Fj=function(){return K.a.sd(this.X)};I.Pf=function(){return K.a.Qf(this.X)};I.Jf=function(b){return K.a.Jf(b||this.X)};I.appendChild=K.a.appendChild;I.append=K.a.append;I.canHaveChildren=K.a.canHaveChildren;I.Zd=K.a.Zd;I.vg=K.a.vg;I.ug=K.a.ug;I.tg=K.a.tg;
I.removeNode=K.a.removeNode;I.dh=K.a.dh;I.Ff=K.a.Ff;I.Nf=K.a.Nf;I.Sf=K.a.Sf;I.Wf=K.a.Wf;I.Zf=K.a.Zf;I.fg=K.a.fg;I.$f=K.a.$f;I.gg=K.a.gg;I.Ld=K.a.Ld;I.Hd=K.a.Hd;I.Ng=K.a.Ng;I.eg=K.a.eg;I.contains=K.a.contains;I.mf=K.a.mf;I.Bf=K.a.Bf;I.Qa=K.a.Qa;I.Tf=K.a.Tf;I.Uf=K.a.Uf;I.ae=K.a.ae;I.dg=K.a.dg;I.Cf=K.a.Cf;I.Df=K.a.Df;I.Jd=K.a.Jd;I.jh=K.a.jh;I.Cg=K.a.Cg;I.pc=K.a.pc;I.bg=K.a.bg;I.cg=K.a.cg;I.ag=K.a.ag;I.Md=K.a.Md;I.qd=K.a.qd;I.Kf=K.a.Kf;I.pd=K.a.pd;I.Mf=K.a.Mf;K.bh={};K.bh.to=F();K.Thenable=F();K.Thenable.prototype.then=F();K.Thenable.He="$goog_Thenable";K.Thenable.af=function(b){b.prototype.then=b.prototype.then;b.prototype[K.Thenable.He]=!0};K.Thenable.Dg=function(b){if(!b)return!1;try{return!!b[K.Thenable.He]}catch(c){return!1}};K.Promise=function(b,c){this.$=K.Promise.P.wa;this.ia=void 0;this.ob=this.Na=this.da=null;this.ld=!1;0<K.Promise.Wa?this.Oc=0:0==K.Promise.Wa&&(this.rc=!1);K.Promise.Aa&&(this.ee=[],N(this,Error("created")),this.vf=0);if(b!=K.eb)try{var d=this;b.call(c,function(b){O(d,K.Promise.P.Ja,b)},function(b){if(K.ea&&!(b instanceof K.Promise.kb))try{if(b instanceof Error)throw b;throw Error("Promise rejected.");}catch(f){}O(d,K.Promise.P.ka,b)})}catch(e){O(this,K.Promise.P.ka,e)}};K.Promise.Aa=!1;
K.Promise.Wa=0;K.Promise.P={wa:0,Jh:1,Ja:2,ka:3};K.Promise.ze=function(){this.next=this.context=this.wb=this.Tb=this.Xa=null;this.dc=!1};K.Promise.ze.prototype.reset=function(){this.context=this.wb=this.Tb=this.Xa=null;this.dc=!1};K.Promise.Vc=100;K.Promise.Kb=new K.async.Zb(function(){return new K.Promise.ze},function(b){b.reset()},K.Promise.Vc);K.Promise.Lf=function(b,c,d){var e=K.Promise.Kb.get();e.Tb=b;e.wb=c;e.context=d;return e};K.Promise.Yk=function(b){K.Promise.Kb.put(b)};
K.Promise.resolve=function(b){if(b instanceof K.Promise)return b;var c=new K.Promise(K.eb);O(c,K.Promise.P.Ja,b);return c};K.Promise.reject=function(b){return new K.Promise(function(c,d){d(b)})};K.Promise.Ec=function(b,c,d){K.Promise.Ug(b,c,d,null)||K.async.M(K.fb(c,b))};K.Promise.race=function(b){return new K.Promise(function(c,d){b.length||c(void 0);for(var e=0,f;e<b.length;e++)f=b[e],K.Promise.Ec(f,c,d)})};
K.Promise.all=function(b){return new K.Promise(function(c,d){var e=b.length,f=[];if(e)for(var g=function(b,d){e--;f[b]=d;0==e&&c(f)},h=function(b){d(b)},l=0,m;l<b.length;l++)m=b[l],K.Promise.Ec(m,K.fb(g,l),h);else c(f)})};K.Promise.jp=function(b){return new K.Promise(function(c){var d=b.length,e=[];if(d)for(var f=function(b,f,g){d--;e[b]=f?{Bj:!0,value:g}:{Bj:!1,reason:g};0==d&&c(e)},g=0,h;g<b.length;g++)h=b[g],K.Promise.Ec(h,K.fb(f,g,!0),K.fb(f,g,!1));else c(e)})};
K.Promise.Iq=function(b){return new K.Promise(function(c,d){var e=b.length,f=[];if(e)for(var g=function(b){c(b)},h=function(b,c){e--;f[b]=c;0==e&&d(f)},l=0,m;l<b.length;l++)m=b[l],K.Promise.Ec(m,g,K.fb(h,l));else c(void 0)})};K.Promise.Wt=function(){var b,c,d=new K.Promise(function(d,f){b=d;c=f});return new K.Promise.li(d,b,c)};K.Promise.prototype.then=function(b,c,d){K.Promise.Aa&&N(this,Error("then"));return ba(this,K.ya(b)?b:null,K.ya(c)?c:null,d)};K.Thenable.af(K.Promise);
K.Promise.prototype.cancel=function(b){this.$==K.Promise.P.wa&&K.async.M(function(){var c=new K.Promise.kb(b);P(this,c)},this)};function P(b,c){if(b.$==K.Promise.P.wa)if(b.da){var d=b.da;if(d.Na){for(var e=0,f=null,g=null,h=d.Na;h&&(h.dc||(e++,h.Xa==b&&(f=h),!(f&&1<e)));h=h.next)f||(g=h);f&&(d.$==K.Promise.P.wa&&1==e?P(d,c):(g?(e=g,e.next==d.ob&&(d.ob=e),e.next=e.next.next):Q(d),R(d,f,K.Promise.P.ka,c)))}b.da=null}else O(b,K.Promise.P.ka,c)}
function S(b,c){b.Na||b.$!=K.Promise.P.Ja&&b.$!=K.Promise.P.ka||T(b);b.ob?b.ob.next=c:b.Na=c;b.ob=c}function ba(b,c,d,e){var f=K.Promise.Lf(null,null,null);f.Xa=new K.Promise(function(b,h){f.Tb=c?function(d){try{var f=c.call(e,d);b(f)}catch(q){h(q)}}:b;f.wb=d?function(c){try{var f=d.call(e,c);!K.R(f)&&c instanceof K.Promise.kb?h(c):b(f)}catch(q){h(q)}}:h});f.Xa.da=b;S(b,f);return f.Xa}K.Promise.prototype.Dl=function(b){this.$=K.Promise.P.wa;O(this,K.Promise.P.Ja,b)};
K.Promise.prototype.El=function(b){this.$=K.Promise.P.wa;O(this,K.Promise.P.ka,b)};function O(b,c,d){b.$==K.Promise.P.wa&&(b===d&&(c=K.Promise.P.ka,d=new TypeError("Promise cannot resolve to itself")),b.$=K.Promise.P.Jh,K.Promise.Ug(d,b.Dl,b.El,b)||(b.ia=d,b.$=c,b.da=null,T(b),c!=K.Promise.P.ka||d instanceof K.Promise.kb||K.Promise.Ii(b,d)))}
K.Promise.Ug=function(b,c,d,e){if(b instanceof K.Promise)return K.Promise.Aa&&N(b,Error("then")),S(b,K.Promise.Lf(c||K.eb,d||null,e)),!0;if(K.Thenable.Dg(b))return b.then(c,d,e),!0;if(K.ha(b))try{var f=b.then;if(K.ya(f))return K.Promise.Bl(b,f,c,d,e),!0}catch(g){return d.call(e,g),!0}return!1};K.Promise.Bl=function(b,c,d,e,f){function g(b){l||(l=!0,e.call(f,b))}function h(b){l||(l=!0,d.call(f,b))}var l=!1;try{c.call(b,h,g)}catch(m){g(m)}};function T(b){b.ld||(b.ld=!0,K.async.M(b.vj,b))}
function Q(b){var c=null;b.Na&&(c=b.Na,b.Na=c.next,c.next=null);b.Na||(b.ob=null);return c}K.Promise.prototype.vj=function(){for(var b;b=Q(this);)K.Promise.Aa&&this.vf++,R(this,b,this.$,this.ia);this.ld=!1};
function R(b,c,d,e){if(d==K.Promise.P.ka&&c.wb&&!c.dc)if(0<K.Promise.Wa)for(;b&&b.Oc;b=b.da)K.global.clearTimeout(b.Oc),b.Oc=0;else if(0==K.Promise.Wa)for(;b&&b.rc;b=b.da)b.rc=!1;if(c.Xa)c.Xa.da=null,K.Promise.xg(c,d,e);else try{c.dc?c.Tb.call(c.context):K.Promise.xg(c,d,e)}catch(f){K.Promise.sc.call(null,f)}K.Promise.Yk(c)}K.Promise.xg=function(b,c,d){c==K.Promise.P.Ja?b.Tb.call(b.context,d):b.wb&&b.wb.call(b.context,d)};
function N(b,c){if(K.Promise.Aa&&K.L(c.stack)){var d=c.stack.split("\n",4)[3];c=c.message;c+=Array(11-c.length).join(" ");b.ee.push(c+d)}}function U(b,c){if(K.Promise.Aa&&c&&K.L(c.stack)&&b.ee.length){for(var d=["Promise trace:"],e=b;e;e=e.da){for(var f=b.vf;0<=f;f--)d.push(e.ee[f]);d.push("Value: ["+(e.$==K.Promise.P.ka?"REJECTED":"FULFILLED")+"] <"+String(e.ia)+">")}c.stack+="\n\n"+d.join("\n")}}
K.Promise.Ii=function(b,c){0<K.Promise.Wa?b.Oc=K.global.setTimeout(function(){U(b,c);K.Promise.sc.call(null,c)},K.Promise.Wa):0==K.Promise.Wa&&(b.rc=!0,K.async.M(function(){b.rc&&(U(b,c),K.Promise.sc.call(null,c))}))};K.Promise.sc=K.async.qh;K.Promise.st=function(b){K.Promise.sc=b};K.Promise.kb=function(b){K.debug.Error.call(this,b)};K.ab(K.Promise.kb,K.debug.Error);K.Promise.kb.prototype.name="cancel";K.Promise.li=function(b,c,d){this.bh=b;this.resolve=c;this.reject=d};/*
Portions of this code are from MochiKit, received by
The Closure Authors under the MIT license. All other code is Copyright
2005-2009 The Closure Authors. All Rights Reserved.
*/
K.async.w=function(b,c){this.Ic=[];this.ah=b;this.wf=c||null;this.ub=this.qb=!1;this.ia=void 0;this.be=this.Ti=this.bd=!1;this.Nc=0;this.da=null;this.ec=0;K.async.w.Aa&&(this.ed=null,Error.captureStackTrace&&(b={stack:""},Error.captureStackTrace(b,K.async.w),typeof b.stack==B&&(this.ed=b.stack.replace(/^[^\n]*\n/,""))))};K.async.w.vi=!1;K.async.w.Aa=!1;I=K.async.w.prototype;
I.cancel=function(b){if(this.qb)this.ia instanceof K.async.w&&this.ia.cancel();else{if(this.da){var c=this.da;delete this.da;b?c.cancel(b):(c.ec--,0>=c.ec&&c.cancel())}this.ah?this.ah.call(this.wf,this):this.be=!0;this.qb||this.Za(new K.async.w.jb(this))}};I.rf=function(b,c){this.bd=!1;V(this,b,c)};function V(b,c,d){b.qb=!0;b.ia=d;b.ub=!c;W(b)}function X(b){if(b.qb){if(!b.be)throw new K.async.w.Wb(b);b.be=!1}}I.Db=function(b){X(this);V(this,!0,b)};I.Za=function(b){X(this);da(this,b);V(this,!1,b)};
function da(b,c){K.async.w.Aa&&b.ed&&K.ha(c)&&c.stack&&/^[^\n]+(\n [^\n]+)+/.test(c.stack)&&(c.stack=c.stack+"\nDEFERRED OPERATION:\n"+b.ed)}function Y(b,c,d){return Z(b,c,null,d)}function ea(b,c){Z(b,null,c,void 0)}function Z(b,c,d,e){b.Ic.push([c,d,e]);b.qb&&W(b);return b}I.then=function(b,c,d){var e,f,g=new K.Promise(function(b,c){e=b;f=c});Z(this,e,function(b){b instanceof K.async.w.jb?g.cancel():f(b)});return g.then(b,c,d)};K.Thenable.af(K.async.w);
K.async.w.prototype.Vi=function(){var b=new K.async.w;Z(this,b.Db,b.Za,b);b.da=this;this.ec++;return b};function fa(b){return K.j.some(b.Ic,function(b){return K.ya(b[1])})}
function W(b){b.Nc&&b.qb&&fa(b)&&(K.async.w.Il(b.Nc),b.Nc=0);b.da&&(b.da.ec--,delete b.da);for(var c=b.ia,d=!1,e=!1;b.Ic.length&&!b.bd;){var f=b.Ic.shift(),g=f[0],h=f[1];f=f[2];if(g=b.ub?h:g)try{var l=g.call(f||b.wf,c);K.R(l)&&(b.ub=b.ub&&(l==c||l instanceof Error),b.ia=c=l);if(K.Thenable.Dg(c)||typeof K.global.Promise===u&&c instanceof K.global.Promise)e=!0,b.bd=!0}catch(m){c=m,b.ub=!0,da(b,c),fa(b)||(d=!0)}}b.ia=c;e?(e=K.bind(b.rf,b,!0),l=K.bind(b.rf,b,!1),c instanceof K.async.w?(Z(c,e,l),c.Ti=
!0):c.then(e,l)):K.async.w.vi&&c instanceof Error&&!(c instanceof K.async.w.jb)&&(d=b.ub=!0);d&&(b.Nc=K.async.w.kl(c))}K.async.w.oh=function(b){var c=new K.async.w;c.Db(b);return c};K.async.w.Pq=function(b){var c=new K.async.w;c.Db();Y(c,function(){return b});return c};K.async.w.ma=function(b){var c=new K.async.w;c.Za(b);return c};K.async.w.Qp=function(){var b=new K.async.w;b.cancel();return b};K.async.w.Vt=function(b,c,d){return b instanceof K.async.w?Y(b.Vi(),c,d):Y(K.async.w.oh(b),c,d)};
K.async.w.Wb=function(b){K.debug.Error.call(this);this.pb=b};K.ab(K.async.w.Wb,K.debug.Error);K.async.w.Wb.prototype.message="Deferred has already fired";K.async.w.Wb.prototype.name="AlreadyCalledError";K.async.w.jb=function(b){K.debug.Error.call(this);this.pb=b};K.ab(K.async.w.jb,K.debug.Error);K.async.w.jb.prototype.message="Deferred was canceled";K.async.w.jb.prototype.name="CanceledError";K.async.w.Fe=function(b){this.Mb=K.global.setTimeout(K.bind(this.ph,this),0);this.tj=b};
K.async.w.Fe.prototype.ph=function(){delete K.async.w.Jb[this.Mb];throw this.tj;};K.async.w.Jb={};K.async.w.kl=function(b){b=new K.async.w.Fe(b);K.async.w.Jb[b.Mb]=b;return b.Mb};K.async.w.Il=function(b){var c=K.async.w.Jb[b];c&&(K.global.clearTimeout(c.Mb),delete K.async.w.Jb[b])};K.async.w.Dp=function(){var b=K.async.w.Jb,c;for(c in b){var d=b[c];K.global.clearTimeout(d.Mb);d.ph()}};K.D={};K.D.F={};K.D.F.Zc="closure_verification";K.D.F.Th=5E3;K.D.F.$d=[];K.D.F.gl=function(b,c){function d(){var e=b.shift();e=K.D.F.Fc(e,c);b.length&&Z(e,d,d,void 0);return e}if(!b.length)return K.async.w.oh(null);var e=K.D.F.$d.length;K.j.extend(K.D.F.$d,b);if(e)return K.D.F.hh;b=K.D.F.$d;K.D.F.hh=d();return K.D.F.hh};
K.D.F.Fc=function(b,c){var d=c||{};c=d.document||document;var e=K.b.C.u(b),f=K.a.createElement(p),g={ih:f,sh:void 0},h=new K.async.w(K.D.F.Xi,g),l=null,m=K.cb(d.timeout)?d.timeout:K.D.F.Th;0<m&&(l=window.setTimeout(function(){K.D.F.gc(f,!0);h.Za(new K.D.F.Error(K.D.F.Yb.TIMEOUT,"Timeout reached for loading script "+e))},m),g.sh=l);f.onload=f.onreadystatechange=function(){f.readyState&&"loaded"!=f.readyState&&f.readyState!=t||(K.D.F.gc(f,d.Xp||!1,l),h.Db(null))};f.onerror=function(){K.D.F.gc(f,!0,
l);h.Za(new K.D.F.Error(K.D.F.Yb.ei,"Error while loading script "+e))};g=d.attributes||{};K.object.extend(g,{type:C,charset:"UTF-8"});K.a.Jc(f,g);K.a.S.ol(f,b);K.D.F.Mj(c).appendChild(f);return h};
K.D.F.Ws=function(b,c,d){K.global[K.D.F.Zc]||(K.global[K.D.F.Zc]={});var e=K.global[K.D.F.Zc],f=K.b.C.u(b);if(K.R(e[c]))return K.async.w.ma(new K.D.F.Error(K.D.F.Yb.Gi,"Verification object "+c+" already defined."));b=K.D.F.Fc(b,d);var g=new K.async.w(K.bind(b.cancel,b));Y(b,function(){var b=e[c];K.R(b)?(g.Db(b),delete e[c]):g.Za(new K.D.F.Error(K.D.F.Yb.Fi,"Script "+f+" loaded, but verification object "+c+" was not defined."))});ea(b,function(b){K.R(e[c])&&delete e[c];g.Za(b)});return g};
K.D.F.Mj=function(b){var c=K.a.getElementsByTagName("HEAD",b);return!c||K.j.Qb(c)?b.documentElement:c[0]};K.D.F.Xi=function(){if(this&&this.ih){var b=this.ih;b&&b.tagName==p&&K.D.F.gc(b,!0,this.sh)}};K.D.F.gc=function(b,c,d){K.cb(d)&&K.global.clearTimeout(d);b.onload=K.eb;b.onerror=K.eb;b.onreadystatechange=K.eb;c&&window.setTimeout(function(){K.a.removeNode(b)},0)};K.D.F.Yb={ei:0,TIMEOUT:1,Fi:2,Gi:3};
K.D.F.Error=function(b,c){var d="Jsloader error (code #"+b+")";c&&(d+=": "+c);K.debug.Error.call(this,d);this.code=b};K.ab(K.D.F.Error,K.debug.Error);var google={G:{}};google.G.H={};google.G.H.Ba={};google.G.H.Ba.rh=3E4;google.G.H.Ba.js=function(b,c){return{format:b,Mi:c}};google.G.H.Ba.Pj=function(b){return K.b.C.format(b.format,b.Mi)};google.G.H.Ba.load=function(b,c){b=K.b.C.format(b,c);var d=K.D.F.Fc(b,{timeout:google.G.H.Ba.rh,attributes:{async:!1,defer:!1}});return new Promise(function(b){Y(d,b)})};
google.G.H.Ba.cs=function(b){b=K.j.map(b,google.G.H.Ba.Pj);if(K.j.Qb(b))return Promise.resolve();var c={timeout:google.G.H.Ba.rh,attributes:{async:!1,defer:!1}},d=[];!K.userAgent.Y||K.userAgent.va(11)?K.j.forEach(b,function(b){d.push(K.D.F.Fc(b,c))}):d.push(K.D.F.gl(b,c));return Promise.all(K.j.map(d,function(b){return new Promise(function(c){return Y(b,c)})}))};google.G.H.T={};if(K.rb(v))throw Error("Google Chart loader.js can only be loaded once.");google.G.H.T.Nl={41:z,42:z,43:z,44:z,1:"1.0","1.0":"current","1.1":"upcoming",current:"45.2",upcoming:"46"};google.G.H.T.Kk=function(b){var c=b,d=b.match(/^testing-/);d&&(c=c.replace(/^testing-/,""));b=c;do{var e=google.G.H.T.Nl[c];e&&(c=e)}while(e);d=(d?"testing-":"")+c;return{version:c==z?b:d,Dk:d}};google.G.H.T.yh=null;
google.G.H.T.Bk=function(b){var c=google.G.H.T.Kk(b),d=K.f.I.from("https://www.gstatic.com/charts/%{version}/loader.js");return google.G.H.Ba.load(d,{version:c.Dk}).then(function(){var d=K.rb("google.charts.loader.VersionSpecific.load")||K.rb("google.charts.loader.publicLoad")||K.rb("google.charts.versionSpecific.load");if(!d)throw Error("Bad version: "+b);google.G.H.T.yh=function(b){b=d(c.version,b);if(null==b||null==b.then){var e=K.rb("google.charts.loader.publicSetOnLoadCallback")||K.rb("google.charts.versionSpecific.setOnLoadCallback");
b=new Promise(function(b){e(b)});b.then=e}return b}})};google.G.H.T.Pd=null;google.G.H.T.jc=null;google.G.H.T.yk=function(b,c){google.G.H.T.Pd||(google.G.H.T.Pd=google.G.H.T.Bk(b));return google.G.H.T.jc=google.G.H.T.Pd.then(function(){return google.G.H.T.yh(c)})};google.G.H.T.nl=function(b){if(!google.G.H.T.jc)throw Error("Must call google.charts.load before google.charts.setOnLoadCallback");return b?google.G.H.T.jc.then(b):google.G.H.T.jc};
google.G.load=function(b){for(var c=[],d=0;d<arguments.length;++d)c[d-0]=arguments[d];d=0;"visualization"===c[d]&&d++;var e="current";K.L(c[d])&&(e=c[d],d++);var f={};K.ha(c[d])&&(f=c[d]);return google.G.H.T.yk(e,f)};K.zf(v,google.G.load);google.G.ml=google.G.H.T.nl;K.zf("google.charts.setOnLoadCallback",google.G.ml);}).call(this);

View File

@@ -0,0 +1,409 @@
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.load('current', {'packages':['line']});
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
if ($("#column-chart1").length > 0) {
var a = google.visualization.arrayToDataTable([
["Year", "Sales", "Expenses", "Profit"],
["2014", 1e3, 400, 250],
["2015", 1170, 460, 300],
["2016", 660, 1120, 400],
["2017", 1030, 540, 450]
]),
b = {
chart: {
title: "Company Performance",
subtitle: "Sales, Expenses, and Profit: 2014-2017"
},
bars: "vertical",
vAxis: {
format: "decimal"
},
height: 400,
width:'100%',
colors: [vihoAdminConfig.primary, vihoAdminConfig.primary, "#e2c636"]
},
c = new google.charts.Bar(document.getElementById("column-chart1"));
c.draw(a, google.charts.Bar.convertOptions(b))
}
if ($("#column-chart2").length > 0) {
var a = google.visualization.arrayToDataTable([
["Year", "Sales", "Expenses", "Profit"],
["2014", 1e3, 400, 250],
["2015", 1170, 460, 300],
["2016", 660, 1120, 400],
["2017", 1030, 540, 450]
]),
b = {
chart: {
title: "Company Performance",
subtitle: "Sales, Expenses, and Profit: 2014-2017"
},
bars: "horizontal",
vAxis: {
format: "decimal"
},
height: 400,
width:'100%',
colors: [vihoAdminConfig.primary, vihoAdminConfig.primary, "#e2c636"]
},
c = new google.charts.Bar(document.getElementById("column-chart2"));
c.draw(a, google.charts.Bar.convertOptions(b))
}
if ($("#pie-chart1").length > 0) {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 5],
['Eat', 10],
['Commute', 15],
['Watch TV', 20],
['Sleep', 25]
]);
var options = {
title: 'My Daily Activities',
width:'100%',
height: 300,
colors: [vihoAdminConfig.primary, vihoAdminConfig.primary, "#e2c636", "#222222", "#717171"]
};
var chart = new google.visualization.PieChart(document.getElementById('pie-chart1'));
chart.draw(data, options);
}
if ($("#pie-chart2").length > 0) {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 5],
['Eat', 10],
['Commute', 15],
['Watch TV', 20],
['Sleep', 25]
]);
var options = {
title: 'My Daily Activities',
is3D: true,
width:'100%',
height: 300,
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#e2c636", "#222222", "#717171"]
};
var chart = new google.visualization.PieChart(document.getElementById('pie-chart2'));
chart.draw(data, options);
}
if ($("#pie-chart3").length > 0) {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 2],
['Eat', 2],
['Commute', 11],
['Watch TV', 2],
['Sleep', 7]
]);
var options = {
title: 'My Daily Activities',
pieHole: 0.4,
width:'100%',
height: 300,
colors: [vihoAdminConfig.secondary, vihoAdminConfig.primary, "#222222", "#717171", "#e2c636"]
};
var chart = new google.visualization.PieChart(document.getElementById('pie-chart3'));
chart.draw(data, options);
}
if ($("#pie-chart4").length > 0) {
var data = google.visualization.arrayToDataTable([
['Language', 'Speakers (in millions)'],
['Assamese', 13],
['Bengali', 83],
['Bodo', 1.4],
['Dogri', 2.3],
['Gujarati', 46],
['Hindi', 300],
['Kannada', 38],
['Kashmiri', 5.5],
['Konkani', 5],
['Maithili', 20],
['Malayalam', 33],
['Manipuri', 1.5],
['Marathi', 72],
['Nepali', 2.9],
['Oriya', 33],
['Punjabi', 29],
['Sanskrit', 0.01],
['Santhali', 6.5],
['Sindhi', 2.5],
['Tamil', 61],
['Telugu', 74],
['Urdu', 52]
]);
var options = {
title: 'Indian Language Use',
legend: 'none',
width:'100%',
height: 400,
pieSliceText: 'label',
slices: { 4: {offset: 0.2},
12: {offset: 0.3},
14: {offset: 0.4},
15: {offset: 0.5},
},
// colors: ["#ab8ce4", "#26c6da"]
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222", "#717171", "#e2c636", "#d22d3d","#e6edef", vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222", "#717171", "#e2c636","#d22d3d", vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222", "#717171", "#e2c636", "#d22d3d", vihoAdminConfig.primary,vihoAdminConfig.secondary, "#222222"]
};
var chart = new google.visualization.PieChart(document.getElementById('pie-chart4'));
chart.draw(data, options);
}
if ($("#line-chart").length > 0) {
var data = new google.visualization.DataTable();
data.addColumn('number', 'month');
data.addColumn('number', 'Guardians of the Galaxy');
data.addColumn('number', 'The Avengers');
data.addColumn('number', 'Transformers: Age of Extinction');
data.addRows([
[1, 37.8, 80.8, 41.8],
[2, 30.9, 10.5, 32.4],
[3, 40.4, 57, 25.7],
[4, 11.7, 18.8, 10.5],
[5, 20, 17.6, 10.4],
[6, 8.8, 13.6, 7.7],
[7, 7.6, 12.3, 9.6],
[8, 12.3, 29.2, 10.6],
[9, 16.9, 42.9, 14.8],
[10, 12.8, 30.9, 11.6],
[11, 5.3, 7.9, 4.7],
[12, 6.6, 8.4, 5.2],
]);
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222"],
height: 500,
width:'100%',
};
var chart = new google.charts.Line(document.getElementById('line-chart'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
if ($("#combo-chart").length > 0) {
var data = google.visualization.arrayToDataTable([
['Month', 'Bolivia', 'Ecuador', 'Madagascar', 'Papua', 'Rwanda', 'Average'],
['2004/05', 165, 938, 522, 998, 450, 614.6],
['2005/06', 135, 1120, 599, 1268, 288, 682],
['2006/07', 157, 1167, 587, 807, 397, 623],
['2007/08', 139, 1110, 615, 968, 215, 609.4],
['2008/09', 136, 691, 629, 1026, 366, 569.6]
]);
var options = {
title : 'Monthly Coffee Production by Country',
vAxis: {title: 'Cups'},
hAxis: {title: 'Month'},
seriesType: 'bars',
series: {5: {type: 'line'}},
height: 500,
width:'100%',
colors: [vihoAdminConfig.secondary, vihoAdminConfig.primary, "#222222", "#717171", "#e2c636"]
};
var chart = new google.visualization.ComboChart(document.getElementById('combo-chart'));
chart.draw(data, options);
}
if ($("#area-chart1").length > 0) {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses'],
['2013', 1000, 400],
['2014', 1170, 460],
['2015', 660, 1120],
['2016', 1030, 540]
]);
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: '#333'}},
vAxis: {minValue: 0},
width:'100%',
height: 400,
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary]
};
var chart = new google.visualization.AreaChart(document.getElementById('area-chart1'));
chart.draw(data, options);
}
if ($("#area-chart2").length > 0) {
var data = google.visualization.arrayToDataTable([
['Year', 'Cars', 'Trucks' , 'Drones' , 'Segways'],
['2013', 100, 400, 2000, 400],
['2014', 500, 700, 530, 800],
['2015', 2000, 1000, 620, 120],
['2016', 120, 201, 2501, 540]
]);
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: '#333'}},
vAxis: {minValue: 0},
width:'100%',
height: 400,
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222", "#717171"]
};
var chart = new google.visualization.AreaChart(document.getElementById('area-chart2'));
chart.draw(data, options);
}
if ($("#area-chart-dashboard-default").length > 0) {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Day');
data.addColumn('number', 'Guardians of the Galaxy');
data.addColumn('number', 'The Avengers');
data.addColumn('number', 'Transformers: Extinction');
data.addRows([
[1, 37.8, 80.8, 41.8],
[2, 30.9, 10.5, 32.4],
[3, 40.4, 57, 25.7],
[4, 11.7, 18.8, 10.5],
[5, 20, 17.6, 10.4],
[6, 8.8, 13.6, 7.7],
[7, 7.6, 12.3, 9.6],
[8, 12.3, 29.2, 10.6],
[9, 16.9, 42.9, 14.8],
[10, 12.8, 30.9, 11.6],
[11, 5.3, 7.9, 4.7],
[12, 6.6, 8.4, 5.2],
[13, 4.8, 6.3, 3.6],
[14, 4.2, 6.2, 3.4]
]);
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
colors: [vihoAdminConfig.primary, vihoAdminConfig.secondary , "#222222"],
width:'100%',
legend: {position: 'top'},
};
var chart = new google.charts.Line(document.getElementById('area-chart-dashboard-default'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
if ($("#bar-chart2").length > 0) {
var a = google.visualization.arrayToDataTable([
["Element", "Density", {
role: "style"
}],
["Copper", 10, vihoAdminConfig.primary],
["Silver", 12, vihoAdminConfig.secondary],
["Gold", 14, "#222222"],
["Platinum", 16, "color: #717171"]
]),
d = new google.visualization.DataView(a);
d.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2]);
var b = {
title: "Density of Precious Metals, in g/cm^3",
width:'100%',
height: 400,
bar: {
groupWidth: "95%"
},
legend: {
position: "none"
}
},
c = new google.visualization.BarChart(document.getElementById("bar-chart2"));
c.draw(d, b)
}
}
// Gantt chart
google.charts.load('current', {'packages':['gantt']});
google.charts.setOnLoadCallback(drawChart);
function daysToMilliseconds(days) {
return days * 24 * 60 * 60 * 1000;
}
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task ID');
data.addColumn('string', 'Task Name');
data.addColumn('string', 'Resource');
data.addColumn('date', 'Start Date');
data.addColumn('date', 'End Date');
data.addColumn('number', 'Duration');
data.addColumn('number', 'Percent Complete');
data.addColumn('string', 'Dependencies');
data.addRows([
['Research', 'Find sources', null,
new Date(2015, 0, 1), new Date(2015, 0, 5), null, 100, null],
['Write', 'Write paper', 'write',
null, new Date(2015, 0, 9), daysToMilliseconds(3), 25, 'Research,Outline'],
['Cite', 'Create bibliography', 'write',
null, new Date(2015, 0, 7), daysToMilliseconds(1), 20, 'Research'],
['Complete', 'Hand in paper', 'complete',
null, new Date(2015, 0, 10), daysToMilliseconds(1), 0, 'Cite,Write'],
['Outline', 'Outline paper', 'write',
null, new Date(2015, 0, 6), daysToMilliseconds(1), 100, 'Research']
]);
var options = {
height: 275,
gantt: {
criticalPathEnabled: false, // Critical path arrows will be the same as other arrows.
arrow: {
angle: 100,
width: 5,
color: vihoAdminConfig.secondary,
radius: 0
},
palette: [
{
"color": vihoAdminConfig.primary,
"dark": vihoAdminConfig.primary,
"light": "#222222"
}
]
}
};
var chart = new google.visualization.Gantt(document.getElementById('gantt_chart'));
chart.draw(data, options);
}
// word tree
google.charts.load('current1', {packages:['wordtree']});
google.charts.setOnLoadCallback(drawChart1);
function drawChart1() {
var data = google.visualization.arrayToDataTable(
[ ['Phrases'],
['cats are better than dogs'],
['cats eat kibble'],
['cats are better than hamsters'],
['cats are awesome'],
['cats are people too'],
['cats eat mice'],
['cats meowing'],
['cats in the cradle'],
['cats eat mice'],
['cats in the cradle lyrics'],
['cats eat kibble'],
['cats for adoption'],
['cats are family'],
['cats eat mice'],
['cats are better than kittens'],
['cats are evil'],
['cats are weird'],
['cats eat mice']
]
);
var options = {
wordtree: {
format: 'implicit',
word: 'cats'
}
};
var chart = new google.visualization.WordTree(document.getElementById('wordtree_basic'));
chart.draw(data, options);
}

View File

@@ -0,0 +1,98 @@
(function($) {
"use strict";
$(".knob").knob({
change : function (value) {
//console.log("change : " + value);
},
release : function (value) {
//console.log(this.$.attr('value'));
console.log("release : " + value);
},
cancel : function () {
console.log("cancel : ", this);
},
/*format : function (value) {
return value + '%';
},*/
draw : function () {
// "tron" case
if(this.$.data('skin') == 'tron') {
this.cursorExt = 0.3;
var a = this.arc(this.cv) // Arc
, pa // Previous arc
, r = 1;
this.g.lineWidth = this.lineWidth;
if (this.o.displayPrevious) {
pa = this.arc(this.v);
this.g.beginPath();
this.g.strokeStyle = this.pColor;
this.g.arc(this.xy, this.xy, this.radius - this.lineWidth, pa.s, pa.e, pa.d);
this.g.stroke();
}
this.g.beginPath();
this.g.strokeStyle = r ? this.o.fgColor : this.fgColor ;
this.g.arc(this.xy, this.xy, this.radius - this.lineWidth, a.s, a.e, a.d);
this.g.stroke();
this.g.lineWidth = 2;
this.g.beginPath();
this.g.strokeStyle = this.o.fgColor;
this.g.arc( this.xy, this.xy, this.radius - this.lineWidth + 1 + this.lineWidth * 2 / 3, 0, 2 * Math.PI, false);
this.g.stroke();
return false;
}
}
});
// Example of infinite knob, iPod click wheel
var v, up=0,down=0,i=0
,$idir = $("div.idir")
,$ival = $("div.ival")
,incr = function() { i++; $idir.show().html("+").fadeOut(); $ival.html(i); }
,decr = function() { i--; $idir.show().html("-").fadeOut(); $ival.html(i); };
$("input.infinite").knob(
{
min : 0
, max : 20
, stopper : false
, change : function () {
if(v > this.cv){
if(up){
decr();
up=0;
}else{up=1;down=0;}
} else {
if(v < this.cv){
if(down){
incr();
down=0;
}else{down=1;up=0;}
}
}
v = this.cv;
}
});
})(jQuery);
function clock() {
var $s = $(".second"),
$m = $(".minute"),
$h = $(".hour");
d = new Date(),
s = d.getSeconds(),
m = d.getMinutes(),
h = d.getHours();
$s.val(s).trigger("change");
$m.val(m).trigger("change");
$h.val(h).trigger("change");
setTimeout("clock()", 1000);
}
clock();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,385 @@
"use strict";
var morris_chart = {
init: function() {
Morris.Area({
element: 'graph123',
behaveLikeLine: true,
data: [{
x: '2011 Q1',
y: 3,
z: 3
},
{
x: '2011 Q2',
y: 2,
z: 1
},
{
x: '2011 Q3',
y: 2,
z: 4
},
{
x: '2011 Q4',
y: 3,
z: 3
}
],
xkey: 'x',
ykeys: ['y', 'z'],
labels: ['Y', 'Z'],
lineColors: [vihoAdminConfig.secondary, vihoAdminConfig.primary],
}), Morris.Line({
element: "morris-line-chart",
data: [{
y: "2011",
a: 100,
b: 90
},
{
y: "2012",
a: 75,
b: 65
},
{
y: "2013",
a: 50,
b: 40
},
{
y: "2014",
a: 75,
b: 65
},
{
y: "2015",
a: 50,
b: 40
},
{
y: "2016",
a: 75,
b: 65
},
{
y: "2017",
a: 100,
b: 90
}],
xkey: "y",
ykeys: ["a", "b"],
lineColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary],
labels: ["Series A", "Series B"]
}), Morris.Bar({
element: "morris-simple-bar-chart",
data: [{
x: "2011 Q1",
y: 3,
z: 2,
a: 3
},
{
x: "2011 Q2",
y: 2,
z: 3,
a: 1
},
{
x: "2011 Q3",
y: 5,
z: 2,
a: 4
},
{
x: "2011 Q4",
y: 2,
z: 4,
a: 3
}],
xkey: "x",
ykeys: ["y", "z", "a"],
barColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary ,"#222222"],
labels: ["Y", "Z", "A"]
}), Morris.Bar({
element: "bar-line-chart-morris",
data: [{
x: "2011 Q1",
y: 0
},
{
x: "2011 Q2",
y: 1
},
{
x: "2011 Q3",
y: 2
},
{
x: "2011 Q4",
y: 3
},
{
x: "2012 Q1",
y: 4
},
{
x: "2012 Q2",
y: 5
},
{
x: "2012 Q3",
y: 6
},
{
x: "2012 Q4",
y: 7
},
{
x: "2013 Q1",
y: 8
}],
xkey: "x",
ykeys: ["y"],
labels: ["Y"],
barColors: [vihoAdminConfig.primary]
}), $(function() {
var b = [{
period: "2012-10-01",
licensed: 5000,
sorned: 4750
},
{
period: "2012-09-30",
licensed: 4500,
sorned: 4250
},
{
period: "2012-09-29",
licensed: 4000,
sorned: 3750
},
{
period: "2012-09-20",
licensed: 3500,
sorned: 3250
},
{
period: "2012-09-19",
licensed: 3000,
sorned: 2750
},
{
period: "2012-09-18",
licensed: 2500,
sorned: 2250
}
];
Morris.Bar({
element: 'x-lable-morris-chart',
data: b,
barColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary],
xkey: "period",
ykeys: ["licensed", "sorned"],
labels: ["Licensed", "SORN"],
xLabelAngle: 60
})
}), $(function() {
for (var c = [], d = 0; d <= 360; d += 10) c.push({
x: d,
y: 1.5 + 1.5 * Math.sin(Math.PI * d / 180).toFixed(4)
});
window.m = Morris.Line({
element: 'decimal-morris-chart',
data: c,
xkey: "x",
ykeys: ["y"],
labels: ["sin(x)"],
parseTime: !1,
lineColors: [vihoAdminConfig.primary],
hoverCallback: function(a, b, c, d) {
return c.replace("sin(x)", "1.5 + 1.5 sin(" + d.x + ")")
},
xLabelMargin: 10,
integerYLabels: !0
})
}), $(function() {
var b = [{
period: "2012-10-30",
licensed: 2000,
sorned: 2000
},
{
period: "2012-09-30",
licensed: 3000,
sorned: 1000
},
{
period: "2012-09-29",
licensed: 2000,
sorned: 2000
},
{
period: "2012-09-20",
licensed: 4000,
sorned: 0
},
{
period: "2012-09-19",
licensed: 3000,
sorned: 1000
},
{
period: "2012-09-18",
licensed: 4000,
sorned: 0
},
{
period: "2012-09-17",
licensed: 3171,
sorned: 660
},
{
period: "2012-09-16",
licensed: 3171,
sorned: 676
},
{
period: "2012-09-15",
licensed: 3201,
sorned: 656
},
{
period: "2012-09-10",
licensed: 3215,
sorned: 622
}];
Morris.Line({
element: 'x-Labels-Diagonally-morris-chart',
data: b,
xkey: "period",
lineColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary],
ykeys: ["licensed", "sorned"],
labels: ["Licensed", "SORN"],
xLabelAngle: 60
})
}), $(function() {
Morris.Donut({
element: 'donut-color-chart-morris',
data: [{
value: 70,
label: "foo"
},
{
value: 15,
label: "bar"
},
{
value: 10,
label: "baz"
},
{
value: 5,
label: "A really really long label"
}],
backgroundColor: "rgba(36, 105, 92, 0.5)",
labelColor: vihoAdminConfig.primary,
colors: ["rgba(36, 105, 92, 1)", "rgba(186, 137, 93, 1)" ,"rgba(9,9, 9, 1)" ,"rgba(113, 113, 113, 1)" ,"rgba(230, 237, 239, 1)", "rgba(210, 45, 61, 1)" ,"rgba(36, 105, 92, 1)"],
formatter: function(a) {
return a + "%"
}
});
}),
$(function() {
var e = 0,
f = function(a) {
for (var b = [], c = 0; c <= 360; c += 10) {
var d = (a + c) % 360;
b.push({
x: c,
y: Math.sin(Math.PI * d / 180).toFixed(4),
z: Math.cos(Math.PI * d / 180).toFixed(4)
})
}
return b
},
g = Morris.Line({
element:'updating-data-morris-chart',
data: f(0),
xkey: "x",
ykeys: ["y", "z"],
labels: ["sin()", "cos()"],
parseTime: !1,
ymin: -1,
ymax: 1,
hideHover: !0,
lineColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary],
}),
h = function() {
e++, g.setData(f(5 * e)), $(".reloadStatus").text(e + " reloads")
};
setInterval(h, 100)
}), $(function() {
Morris.Bar({
element: 'stacked-bar-chart',
data: [{
x: "2011 Q1",
a: 3,
y: 3,
z: 2
},
{
x: "2011 Q2",
a: 1,
y: 2,
z: null
},
{
x: "2011 Q3",
a: 4,
y: 0,
z: 2
},
{
x: "2011 Q4",
a: 1,
y: 2,
z: null
},
{
x: "2011 Q5",
a: 4,
y: 0,
z: 2
},
{
x: "2011 Q6",
a: 3,
y: 3,
z: 2
},
{
x: "2011 Q4",
a: 4,
y: 0,
z: 2
},
{
x: "2011 Q7",
a: 3,
y: 3,
z: 2
}],
xkey: "x",
ykeys: ["y", "z", "a"],
labels: ["A", "Y", "Z"],
barColors: [vihoAdminConfig.primary, vihoAdminConfig.secondary ,"#222222" ,"#717171" ,"#e2c636", "#d22d3d" ,"#e6edef"],
stacked: !0
});
});
}
};
(function($) {
"use strict";
morris_chart.init()
})(jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
var updatingChart = $(".updating-chart").peity("line")
setInterval(function() {
var random = Math.round(Math.random() * 10)
var values = updatingChart.text().split(",")
values.shift()
values.push(random)
updatingChart
.text(values.join(","))
.change()
}, 1000)
$(".line").peity("line")
$(".bar").peity("bar")
$('.donut').peity('donut')
$(".data-attributes span").peity("donut")
$("span.pie").peity("pie")
$(".bar-colours-1").peity("bar", {
fill: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222"],
width: '100',
height: '82'
})
$(".bar-colours-2").peity("bar", {
fill: function(value) {
return value > 0 ? vihoAdminConfig.primary : vihoAdminConfig.secondary
},
width: '100',
height: '82'
})
$(".bar-colours-3").peity("bar", {
fill: function(_, i, all) {
var g = parseInt((i / all.length) * 36)
return "rgb(36, " + g + ", 0)"
},
width: '100',
height: '82'
})
$(".pie-colours-1").peity("pie", {
fill: [vihoAdminConfig.primary, vihoAdminConfig.secondary, "#222222", "#717171"],
width: '100',
height: '82'
})

View File

@@ -0,0 +1,383 @@
// Peity jQuery plugin version 3.2.1
// (c) 2016 Ben Pickles
//
// http://benpickles.github.io/peity
//
// Released under MIT license.
(function($, document, Math, undefined) {
var peity = $.fn.peity = function(type, options) {
if (svgSupported) {
this.each(function() {
var $this = $(this)
var chart = $this.data('_peity')
if (chart) {
if (type) chart.type = type
$.extend(chart.opts, options)
} else {
chart = new Peity(
$this,
type,
$.extend({},
peity.defaults[type],
$this.data('peity'),
options)
)
$this
.change(function() { chart.draw() })
.data('_peity', chart)
}
chart.draw()
});
}
return this;
};
var Peity = function($el, type, opts) {
this.$el = $el
this.type = type
this.opts = opts
}
var PeityPrototype = Peity.prototype
var svgElement = PeityPrototype.svgElement = function(tag, attrs) {
return $(
document.createElementNS('http://www.w3.org/2000/svg', tag)
).attr(attrs)
}
// https://gist.github.com/madrobby/3201472
var svgSupported = 'createElementNS' in document && svgElement('svg', {})[0].createSVGRect
PeityPrototype.draw = function() {
var opts = this.opts
peity.graphers[this.type].call(this, opts)
if (opts.after) opts.after.call(this, opts)
}
PeityPrototype.fill = function() {
var fill = this.opts.fill
return $.isFunction(fill)
? fill
: function(_, i) { return fill[i % fill.length] }
}
PeityPrototype.prepare = function(width, height) {
if (!this.$svg) {
this.$el.hide().after(
this.$svg = svgElement('svg', {
"class": "peity"
})
)
}
return this.$svg
.empty()
.data('peity', this)
.attr({
height: height,
width: width
})
}
PeityPrototype.values = function() {
return $.map(this.$el.text().split(this.opts.delimiter), function(value) {
return parseFloat(value)
})
}
peity.defaults = {}
peity.graphers = {}
peity.register = function(type, defaults, grapher) {
this.defaults[type] = defaults
this.graphers[type] = grapher
}
peity.register(
'pie',
{
fill: ['#24695c', '#ba895d', '#222222'],
radius: 8
},
function(opts) {
if (!opts.delimiter) {
var delimiter = this.$el.text().match(/[^0-9\.]/)
opts.delimiter = delimiter ? delimiter[0] : ","
}
var values = $.map(this.values(), function(n) {
return n > 0 ? n : 0
})
if (opts.delimiter == "/") {
var v1 = values[0]
var v2 = values[1]
values = [v1, Math.max(0, v2 - v1)]
}
var i = 0
var length = values.length
var sum = 0
for (; i < length; i++) {
sum += values[i]
}
if (!sum) {
length = 2
sum = 1
values = [0, 1]
}
var diameter = opts.radius * 2
var $svg = this.prepare(
opts.width || diameter,
opts.height || diameter
)
var width = $svg.width()
, height = $svg.height()
, cx = width / 2
, cy = height / 2
var radius = Math.min(cx, cy)
, innerRadius = opts.innerRadius
if (this.type == 'donut' && !innerRadius) {
innerRadius = radius * 0.5
}
var pi = Math.PI
var fill = this.fill()
var scale = this.scale = function(value, radius) {
var radians = value / sum * pi * 2 - pi / 2
return [
radius * Math.cos(radians) + cx,
radius * Math.sin(radians) + cy
]
}
var cumulative = 0
for (i = 0; i < length; i++) {
var value = values[i]
, portion = value / sum
, $node
if (portion == 0) continue
if (portion == 1) {
if (innerRadius) {
var x2 = cx - 0.01
, y1 = cy - radius
, y2 = cy - innerRadius
$node = svgElement('path', {
d: [
'M', cx, y1,
'A', radius, radius, 0, 1, 1, x2, y1,
'L', x2, y2,
'A', innerRadius, innerRadius, 0, 1, 0, cx, y2
].join(' ')
})
} else {
$node = svgElement('circle', {
cx: cx,
cy: cy,
r: radius
})
}
} else {
var cumulativePlusValue = cumulative + value
var d = ['M'].concat(
scale(cumulative, radius),
'A', radius, radius, 0, portion > 0.5 ? 1 : 0, 1,
scale(cumulativePlusValue, radius),
'L'
)
if (innerRadius) {
d = d.concat(
scale(cumulativePlusValue, innerRadius),
'A', innerRadius, innerRadius, 0, portion > 0.5 ? 1 : 0, 0,
scale(cumulative, innerRadius)
)
} else {
d.push(cx, cy)
}
cumulative += value
$node = svgElement('path', {
d: d.join(" ")
})
}
$node.attr('fill', fill.call(this, value, i, values))
$svg.append($node)
}
}
)
peity.register(
'donut',
$.extend(true, {}, peity.defaults.pie),
function(opts) {
peity.graphers.pie.call(this, opts)
}
)
peity.register(
"line",
{
delimiter: ",",
fill: "#24695c",
height: 16,
min: 0,
stroke: "#ba895d",
strokeWidth: 1,
width: 32
},
function(opts) {
var values = this.values()
if (values.length == 1) values.push(values[0])
var max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))
, min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))
var $svg = this.prepare(opts.width, opts.height)
, strokeWidth = opts.strokeWidth
, width = $svg.width()
, height = $svg.height() - strokeWidth
, diff = max - min
var xScale = this.x = function(input) {
return input * (width / (values.length - 1))
}
var yScale = this.y = function(input) {
var y = height
if (diff) {
y -= ((input - min) / diff) * height
}
return y + strokeWidth / 2
}
var zero = yScale(Math.max(min, 0))
, coords = [0, zero]
for (var i = 0; i < values.length; i++) {
coords.push(
xScale(i),
yScale(values[i])
)
}
coords.push(width, zero)
if (opts.fill) {
$svg.append(
svgElement('polygon', {
fill: opts.fill,
points: coords.join(' ')
})
)
}
if (strokeWidth) {
$svg.append(
svgElement('polyline', {
fill: 'none',
points: coords.slice(2, coords.length - 2).join(' '),
stroke: opts.stroke,
'stroke-width': strokeWidth,
'stroke-linecap': 'square'
})
)
}
}
);
peity.register(
'bar',
{
delimiter: ",",
fill: ["#4D89F9"],
height: 16,
min: 0,
padding: 0.1,
width: 32
},
function(opts) {
var values = this.values()
, max = Math.max.apply(Math, opts.max == undefined ? values : values.concat(opts.max))
, min = Math.min.apply(Math, opts.min == undefined ? values : values.concat(opts.min))
var $svg = this.prepare(opts.width, opts.height)
, width = $svg.width()
, height = $svg.height()
, diff = max - min
, padding = opts.padding
, fill = this.fill()
var xScale = this.x = function(input) {
return input * width / values.length
}
var yScale = this.y = function(input) {
return height - (
diff
? ((input - min) / diff) * height
: 1
)
}
for (var i = 0; i < values.length; i++) {
var x = xScale(i + padding)
, w = xScale(i + 1 - padding) - x
, value = values[i]
, valueY = yScale(value)
, y1 = valueY
, y2 = valueY
, h
if (!diff) {
h = 1
} else if (value < 0) {
y1 = yScale(Math.min(max, 0))
} else {
y2 = yScale(Math.max(min, 0))
}
h = y2 - y1
if (h == 0) {
h = 1
if (max > 0 && diff) y1--
}
$svg.append(
svgElement('rect', {
fill: fill.call(this, value, i, values),
x: x,
y: y1,
width: w,
height: h
})
)
}
}
);
})(jQuery, document, Math);

View File

@@ -0,0 +1,145 @@
(function($) {
"use strict";
setTimeout(function(){
$("#line-chart-sparkline").sparkline([5, 10, 20, 14, 17, 21, 20, 10, 4, 13,0, 10, 30, 40, 10, 15, 20], {
type: 'line',
width: '100%',
height: '100%',
tooltipClassname: 'chart-sparkline',
lineColor: vihoAdminConfig.primary,
fillColor: 'rgba(36, 105, 92, 0.40)',
highlightLineColor: vihoAdminConfig.primary,
highlightSpotColor: vihoAdminConfig.primary,
targetColor: vihoAdminConfig.primary,
performanceColor: vihoAdminConfig.primary,
boxFillColor: vihoAdminConfig.primary,
medianColor: vihoAdminConfig.primary,
minSpotColor: vihoAdminConfig.primary
});
});
var mrefreshinterval = 500;
var lastmousex = -1;
var lastmousey = -1;
var lastmousetime;
var mousetravel = 0;
var mpoints = [];
var mpoints_max = 30;
$('body').mousemove(function(e) {
var mousex = e.pageX;
var mousey = e.pageY;
if (lastmousex > -1)
mousetravel += Math.max(Math.abs(mousex - lastmousex), Math.abs(mousey - lastmousey));
lastmousex = mousex;
lastmousey = mousey;
});
var mdraw = function() {
var md = new Date();
var timenow = md.getTime();
if (lastmousetime && lastmousetime != timenow) {
var pps = Math.round(mousetravel / (timenow - lastmousetime) * 1000);
mpoints.push(pps);
if (mpoints.length > mpoints_max)
mpoints.splice(0, 1);
mousetravel = 0;
var mouse_wid = $('#mouse-speed-chart-sparkline').parent('.card-block').parent().width();
var a = mpoints - mouse_wid;
$('#mouse-speed-chart-sparkline').sparkline(mpoints, {
width: '100%',
height: '100%',
tooltipClassname: 'chart-sparkline',
lineColor: vihoAdminConfig.primary,
fillColor: 'rgba(36, 105, 92, 0.40)',
highlightLineColor: vihoAdminConfig.primary,
highlightSpotColor: vihoAdminConfig.primary,
targetColor: vihoAdminConfig.primary,
performanceColor: vihoAdminConfig.primary,
boxFillColor: vihoAdminConfig.primary,
medianColor: vihoAdminConfig.primary,
minSpotColor: vihoAdminConfig.primary
});
}
lastmousetime = timenow;
mtimer = setTimeout(mdraw, mrefreshinterval);
}
var mtimer = setTimeout(mdraw, mrefreshinterval);
$.sparkline_display_visible();
$("#custom-line-chart").sparkline([5, 30, 27, 35, 30, 50, 70], {
type: 'line',
width: '100%',
height: '100%',
tooltipClassname: 'chart-sparkline',
chartRangeMax: '50',
lineColor: vihoAdminConfig.primary,
fillColor: 'rgba(36, 105, 92, 0.40)',
highlightLineColor: 'rgba(101, 90, 243, 0.40)',
highlightSpotColor: 'rgba(101, 90, 243, 0.8)'
});
$("#custom-line-chart").sparkline([0, 5, 10, 7, 25, 20, 30], {
type: 'line',
width: '100%',
height: '100%',
composite: '!0',
tooltipClassname: 'chart-sparkline',
chartRangeMax: '40',
lineColor: vihoAdminConfig.secondary,
fillColor: 'rgba(186, 137, 93, 0.30)',
highlightLineColor: 'rgba(186, 137, 93, 0.30)',
highlightSpotColor: 'rgba(186, 137, 93, 0.8)'
});
})(jQuery);
var sparkline_chart = {
init: function() {
setTimeout(function(){
$("#simple-line-chart-sparkline").sparkline([5, 10, 20, 14, 17, 21, 20, 10, 4, 13,0, 10, 30, 40, 10, 15, 20], {
type: 'line',
width: '100%',
height: '100%',
tooltipClassname: 'chart-sparkline',
lineColor: vihoAdminConfig.primary,
fillColor: 'transparent',
highlightLineColor: vihoAdminConfig.primary,
highlightSpotColor: vihoAdminConfig.primary,
targetColor: vihoAdminConfig.primary,
performanceColor: vihoAdminConfig.primary,
boxFillColor: vihoAdminConfig.primary,
medianColor: vihoAdminConfig.primary,
minSpotColor: vihoAdminConfig.primary
});
}), $("#bar-chart-sparkline").sparkline([5, 2, 2, 4, 9, 5, 7, 5, 2, 2, 6], {
type: 'bar',
barWidth: '60',
height: '100%',
tooltipClassname: 'chart-sparkline',
barColor: vihoAdminConfig.primary
}), $("#pie-sparkline-chart").sparkline([1.5, 1, 1, 0.5], {
type: 'pie',
width: '100%',
height: '100%',
sliceColors: ['#717171','#222222',vihoAdminConfig.secondary, vihoAdminConfig.primary],
tooltipClassname: 'chart-sparkline'
}),$("#linechart-defaultdashboard").sparkline([5, 30, 27, 35, 30, 50, 70], {
type: 'line',
width: '100%',
height: '100%',
tooltipClassname: 'chart-sparkline',
chartRangeMax: '50',
lineColor: vihoAdminConfig.secondary,
fillColor: 'rgba(186, 137, 93 ,0.50)'
}), $("#linechart-defaultdashboard").sparkline([0, 5, 10, 7, 25, 20, 30], {
type: 'line',
width: '100%',
height: '100%',
composite: '!0',
tooltipClassname: 'chart-sparkline',
chartRangeMax: '40',
lineColor: '#e2c636',
fillColor: 'rgba(226, 198, 54, 0.50)'
});
}
};
(function($) {
"use strict";
sparkline_chart.init()
})(jQuery);

File diff suppressed because it is too large Load Diff