diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
index a71cb2d..1a09682 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -404,7 +404,7 @@
             };
         }])
 
-    .directive("filedrop", function ($parse, $document) {
+    .directive("filedrop", ['$parse', '$document', function ($parse, $document) {
         return {
             restrict: "A",
             link: function (scope, element, attrs) {
@@ -440,7 +440,7 @@
                     });
             }
         };
-    })
+    }])
 
     .directive('applicationDetailsPanel',
         ['$rootScope', '$window', '$timeout', 'KeyService',
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index e74329b..b8eaca0 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -30,7 +30,16 @@
     <title>ONOS</title>
 
     <!-- Third party library code included here -->
-    <script src="dist/vendor.js"></script>
+    <script src="tp/angular.js"></script>
+    <script src="tp/angular-route.js"></script>
+    <script src="tp/angular-cookies.js"></script>
+
+    <script src="tp/d3.js"></script>
+    <script src="tp/topojson.v1.min.js"></script>
+
+    <script src="tp/Chart.min.js"></script>
+    <script src="tp/angular-chart.min.js"></script>
+    <script src="tp/lodash.min.js"></script>
 
     <!-- {INJECTED-USER-START} -->
     <!-- {INJECTED-USER-END} -->
diff --git a/web/gui/src/main/webapp/tp/Chart.js b/web/gui/src/main/webapp/tp/Chart.js
index 34f9728..24ffad0 100644
--- a/web/gui/src/main/webapp/tp/Chart.js
+++ b/web/gui/src/main/webapp/tp/Chart.js
@@ -1,10397 +1,12757 @@
 /*!
  * Chart.js
  * http://chartjs.org/
- * Version: 2.2.1
+ * Version: 2.6.0
  *
- * Copyright 2016 Nick Downie
+ * Copyright 2017 Nick Downie
  * Released under the MIT license
  * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
  */
 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
 
 },{}],2:[function(require,module,exports){
-/* MIT license */
-var colorNames = require(6);
-
-module.exports = {
-   getRgba: getRgba,
-   getHsla: getHsla,
-   getRgb: getRgb,
-   getHsl: getHsl,
-   getHwb: getHwb,
-   getAlpha: getAlpha,
-
-   hexString: hexString,
-   rgbString: rgbString,
-   rgbaString: rgbaString,
-   percentString: percentString,
-   percentaString: percentaString,
-   hslString: hslString,
-   hslaString: hslaString,
-   hwbString: hwbString,
-   keyword: keyword
-}
-
-function getRgba(string) {
-   if (!string) {
-      return;
-   }
-   var abbr =  /^#([a-fA-F0-9]{3})$/,
-       hex =  /^#([a-fA-F0-9]{6})$/,
-       rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
-       per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
-       keyword = /(\w+)/;
-
-   var rgb = [0, 0, 0],
-       a = 1,
-       match = string.match(abbr);
-   if (match) {
-      match = match[1];
-      for (var i = 0; i < rgb.length; i++) {
-         rgb[i] = parseInt(match[i] + match[i], 16);
-      }
-   }
-   else if (match = string.match(hex)) {
-      match = match[1];
-      for (var i = 0; i < rgb.length; i++) {
-         rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
-      }
-   }
-   else if (match = string.match(rgba)) {
-      for (var i = 0; i < rgb.length; i++) {
-         rgb[i] = parseInt(match[i + 1]);
-      }
-      a = parseFloat(match[4]);
-   }
-   else if (match = string.match(per)) {
-      for (var i = 0; i < rgb.length; i++) {
-         rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
-      }
-      a = parseFloat(match[4]);
-   }
-   else if (match = string.match(keyword)) {
-      if (match[1] == "transparent") {
-         return [0, 0, 0, 0];
-      }
-      rgb = colorNames[match[1]];
-      if (!rgb) {
-         return;
-      }
-   }
-
-   for (var i = 0; i < rgb.length; i++) {
-      rgb[i] = scale(rgb[i], 0, 255);
-   }
-   if (!a && a != 0) {
-      a = 1;
-   }
-   else {
-      a = scale(a, 0, 1);
-   }
-   rgb[3] = a;
-   return rgb;
-}
-
-function getHsla(string) {
-   if (!string) {
-      return;
-   }
-   var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
-   var match = string.match(hsl);
-   if (match) {
-      var alpha = parseFloat(match[4]);
-      var h = scale(parseInt(match[1]), 0, 360),
-          s = scale(parseFloat(match[2]), 0, 100),
-          l = scale(parseFloat(match[3]), 0, 100),
-          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
-      return [h, s, l, a];
-   }
-}
-
-function getHwb(string) {
-   if (!string) {
-      return;
-   }
-   var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
-   var match = string.match(hwb);
-   if (match) {
-    var alpha = parseFloat(match[4]);
-      var h = scale(parseInt(match[1]), 0, 360),
-          w = scale(parseFloat(match[2]), 0, 100),
-          b = scale(parseFloat(match[3]), 0, 100),
-          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
-      return [h, w, b, a];
-   }
-}
-
-function getRgb(string) {
-   var rgba = getRgba(string);
-   return rgba && rgba.slice(0, 3);
-}
-
-function getHsl(string) {
-  var hsla = getHsla(string);
-  return hsla && hsla.slice(0, 3);
-}
-
-function getAlpha(string) {
-   var vals = getRgba(string);
-   if (vals) {
-      return vals[3];
-   }
-   else if (vals = getHsla(string)) {
-      return vals[3];
-   }
-   else if (vals = getHwb(string)) {
-      return vals[3];
-   }
-}
-
-// generators
-function hexString(rgb) {
-   return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])
-              + hexDouble(rgb[2]);
-}
-
-function rgbString(rgba, alpha) {
-   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
-      return rgbaString(rgba, alpha);
-   }
-   return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
-}
-
-function rgbaString(rgba, alpha) {
-   if (alpha === undefined) {
-      alpha = (rgba[3] !== undefined ? rgba[3] : 1);
-   }
-   return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
-           + ", " + alpha + ")";
-}
-
-function percentString(rgba, alpha) {
-   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
-      return percentaString(rgba, alpha);
-   }
-   var r = Math.round(rgba[0]/255 * 100),
-       g = Math.round(rgba[1]/255 * 100),
-       b = Math.round(rgba[2]/255 * 100);
-
-   return "rgb(" + r + "%, " + g + "%, " + b + "%)";
-}
-
-function percentaString(rgba, alpha) {
-   var r = Math.round(rgba[0]/255 * 100),
-       g = Math.round(rgba[1]/255 * 100),
-       b = Math.round(rgba[2]/255 * 100);
-   return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
-}
-
-function hslString(hsla, alpha) {
-   if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
-      return hslaString(hsla, alpha);
-   }
-   return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
-}
-
-function hslaString(hsla, alpha) {
-   if (alpha === undefined) {
-      alpha = (hsla[3] !== undefined ? hsla[3] : 1);
-   }
-   return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
-           + alpha + ")";
-}
-
-// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
-// (hwb have alpha optional & 1 is default value)
-function hwbString(hwb, alpha) {
-   if (alpha === undefined) {
-      alpha = (hwb[3] !== undefined ? hwb[3] : 1);
-   }
-   return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
-           + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
-}
-
-function keyword(rgb) {
-  return reverseNames[rgb.slice(0, 3)];
-}
-
-// helpers
-function scale(num, min, max) {
-   return Math.min(Math.max(min, num), max);
-}
-
-function hexDouble(num) {
-  var str = num.toString(16).toUpperCase();
-  return (str.length < 2) ? "0" + str : str;
-}
-
-
-//create a list of reverse color names
-var reverseNames = {};
-for (var name in colorNames) {
-   reverseNames[colorNames[name]] = name;
-}
+    /* MIT license */
+    var colorNames = require(6);
+
+    module.exports = {
+        getRgba: getRgba,
+        getHsla: getHsla,
+        getRgb: getRgb,
+        getHsl: getHsl,
+        getHwb: getHwb,
+        getAlpha: getAlpha,
+
+        hexString: hexString,
+        rgbString: rgbString,
+        rgbaString: rgbaString,
+        percentString: percentString,
+        percentaString: percentaString,
+        hslString: hslString,
+        hslaString: hslaString,
+        hwbString: hwbString,
+        keyword: keyword
+    }
+
+    function getRgba(string) {
+        if (!string) {
+            return;
+        }
+        var abbr =  /^#([a-fA-F0-9]{3})$/,
+            hex =  /^#([a-fA-F0-9]{6})$/,
+            rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
+            per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,
+            keyword = /(\w+)/;
+
+        var rgb = [0, 0, 0],
+            a = 1,
+            match = string.match(abbr);
+        if (match) {
+            match = match[1];
+            for (var i = 0; i < rgb.length; i++) {
+                rgb[i] = parseInt(match[i] + match[i], 16);
+            }
+        }
+        else if (match = string.match(hex)) {
+            match = match[1];
+            for (var i = 0; i < rgb.length; i++) {
+                rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
+            }
+        }
+        else if (match = string.match(rgba)) {
+            for (var i = 0; i < rgb.length; i++) {
+                rgb[i] = parseInt(match[i + 1]);
+            }
+            a = parseFloat(match[4]);
+        }
+        else if (match = string.match(per)) {
+            for (var i = 0; i < rgb.length; i++) {
+                rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
+            }
+            a = parseFloat(match[4]);
+        }
+        else if (match = string.match(keyword)) {
+            if (match[1] == "transparent") {
+                return [0, 0, 0, 0];
+            }
+            rgb = colorNames[match[1]];
+            if (!rgb) {
+                return;
+            }
+        }
+
+        for (var i = 0; i < rgb.length; i++) {
+            rgb[i] = scale(rgb[i], 0, 255);
+        }
+        if (!a && a != 0) {
+            a = 1;
+        }
+        else {
+            a = scale(a, 0, 1);
+        }
+        rgb[3] = a;
+        return rgb;
+    }
+
+    function getHsla(string) {
+        if (!string) {
+            return;
+        }
+        var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
+        var match = string.match(hsl);
+        if (match) {
+            var alpha = parseFloat(match[4]);
+            var h = scale(parseInt(match[1]), 0, 360),
+                s = scale(parseFloat(match[2]), 0, 100),
+                l = scale(parseFloat(match[3]), 0, 100),
+                a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
+            return [h, s, l, a];
+        }
+    }
+
+    function getHwb(string) {
+        if (!string) {
+            return;
+        }
+        var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
+        var match = string.match(hwb);
+        if (match) {
+            var alpha = parseFloat(match[4]);
+            var h = scale(parseInt(match[1]), 0, 360),
+                w = scale(parseFloat(match[2]), 0, 100),
+                b = scale(parseFloat(match[3]), 0, 100),
+                a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
+            return [h, w, b, a];
+        }
+    }
+
+    function getRgb(string) {
+        var rgba = getRgba(string);
+        return rgba && rgba.slice(0, 3);
+    }
+
+    function getHsl(string) {
+        var hsla = getHsla(string);
+        return hsla && hsla.slice(0, 3);
+    }
+
+    function getAlpha(string) {
+        var vals = getRgba(string);
+        if (vals) {
+            return vals[3];
+        }
+        else if (vals = getHsla(string)) {
+            return vals[3];
+        }
+        else if (vals = getHwb(string)) {
+            return vals[3];
+        }
+    }
+
+// generators
+    function hexString(rgb) {
+        return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])
+            + hexDouble(rgb[2]);
+    }
+
+    function rgbString(rgba, alpha) {
+        if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
+            return rgbaString(rgba, alpha);
+        }
+        return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
+    }
+
+    function rgbaString(rgba, alpha) {
+        if (alpha === undefined) {
+            alpha = (rgba[3] !== undefined ? rgba[3] : 1);
+        }
+        return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
+            + ", " + alpha + ")";
+    }
+
+    function percentString(rgba, alpha) {
+        if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
+            return percentaString(rgba, alpha);
+        }
+        var r = Math.round(rgba[0]/255 * 100),
+            g = Math.round(rgba[1]/255 * 100),
+            b = Math.round(rgba[2]/255 * 100);
+
+        return "rgb(" + r + "%, " + g + "%, " + b + "%)";
+    }
+
+    function percentaString(rgba, alpha) {
+        var r = Math.round(rgba[0]/255 * 100),
+            g = Math.round(rgba[1]/255 * 100),
+            b = Math.round(rgba[2]/255 * 100);
+        return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
+    }
+
+    function hslString(hsla, alpha) {
+        if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
+            return hslaString(hsla, alpha);
+        }
+        return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
+    }
+
+    function hslaString(hsla, alpha) {
+        if (alpha === undefined) {
+            alpha = (hsla[3] !== undefined ? hsla[3] : 1);
+        }
+        return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
+            + alpha + ")";
+    }
+
+// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
+// (hwb have alpha optional & 1 is default value)
+    function hwbString(hwb, alpha) {
+        if (alpha === undefined) {
+            alpha = (hwb[3] !== undefined ? hwb[3] : 1);
+        }
+        return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
+            + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
+    }
+
+    function keyword(rgb) {
+        return reverseNames[rgb.slice(0, 3)];
+    }
+
+// helpers
+    function scale(num, min, max) {
+        return Math.min(Math.max(min, num), max);
+    }
+
+    function hexDouble(num) {
+        var str = num.toString(16).toUpperCase();
+        return (str.length < 2) ? "0" + str : str;
+    }
+
+
+//create a list of reverse color names
+    var reverseNames = {};
+    for (var name in colorNames) {
+        reverseNames[colorNames[name]] = name;
+    }
 
 },{"6":6}],3:[function(require,module,exports){
-/* MIT license */
-var convert = require(5);
-var string = require(2);
-
-var Color = function (obj) {
-	if (obj instanceof Color) {
-		return obj;
-	}
-	if (!(this instanceof Color)) {
-		return new Color(obj);
-	}
-
-	this.values = {
-		rgb: [0, 0, 0],
-		hsl: [0, 0, 0],
-		hsv: [0, 0, 0],
-		hwb: [0, 0, 0],
-		cmyk: [0, 0, 0, 0],
-		alpha: 1
-	};
-
-	// parse Color() argument
-	var vals;
-	if (typeof obj === 'string') {
-		vals = string.getRgba(obj);
-		if (vals) {
-			this.setValues('rgb', vals);
-		} else if (vals = string.getHsla(obj)) {
-			this.setValues('hsl', vals);
-		} else if (vals = string.getHwb(obj)) {
-			this.setValues('hwb', vals);
-		} else {
-			throw new Error('Unable to parse color from string "' + obj + '"');
-		}
-	} else if (typeof obj === 'object') {
-		vals = obj;
-		if (vals.r !== undefined || vals.red !== undefined) {
-			this.setValues('rgb', vals);
-		} else if (vals.l !== undefined || vals.lightness !== undefined) {
-			this.setValues('hsl', vals);
-		} else if (vals.v !== undefined || vals.value !== undefined) {
-			this.setValues('hsv', vals);
-		} else if (vals.w !== undefined || vals.whiteness !== undefined) {
-			this.setValues('hwb', vals);
-		} else if (vals.c !== undefined || vals.cyan !== undefined) {
-			this.setValues('cmyk', vals);
-		} else {
-			throw new Error('Unable to parse color from object ' + JSON.stringify(obj));
-		}
-	}
-};
-
-Color.prototype = {
-	rgb: function () {
-		return this.setSpace('rgb', arguments);
-	},
-	hsl: function () {
-		return this.setSpace('hsl', arguments);
-	},
-	hsv: function () {
-		return this.setSpace('hsv', arguments);
-	},
-	hwb: function () {
-		return this.setSpace('hwb', arguments);
-	},
-	cmyk: function () {
-		return this.setSpace('cmyk', arguments);
-	},
-
-	rgbArray: function () {
-		return this.values.rgb;
-	},
-	hslArray: function () {
-		return this.values.hsl;
-	},
-	hsvArray: function () {
-		return this.values.hsv;
-	},
-	hwbArray: function () {
-		var values = this.values;
-		if (values.alpha !== 1) {
-			return values.hwb.concat([values.alpha]);
-		}
-		return values.hwb;
-	},
-	cmykArray: function () {
-		return this.values.cmyk;
-	},
-	rgbaArray: function () {
-		var values = this.values;
-		return values.rgb.concat([values.alpha]);
-	},
-	hslaArray: function () {
-		var values = this.values;
-		return values.hsl.concat([values.alpha]);
-	},
-	alpha: function (val) {
-		if (val === undefined) {
-			return this.values.alpha;
-		}
-		this.setValues('alpha', val);
-		return this;
-	},
-
-	red: function (val) {
-		return this.setChannel('rgb', 0, val);
-	},
-	green: function (val) {
-		return this.setChannel('rgb', 1, val);
-	},
-	blue: function (val) {
-		return this.setChannel('rgb', 2, val);
-	},
-	hue: function (val) {
-		if (val) {
-			val %= 360;
-			val = val < 0 ? 360 + val : val;
-		}
-		return this.setChannel('hsl', 0, val);
-	},
-	saturation: function (val) {
-		return this.setChannel('hsl', 1, val);
-	},
-	lightness: function (val) {
-		return this.setChannel('hsl', 2, val);
-	},
-	saturationv: function (val) {
-		return this.setChannel('hsv', 1, val);
-	},
-	whiteness: function (val) {
-		return this.setChannel('hwb', 1, val);
-	},
-	blackness: function (val) {
-		return this.setChannel('hwb', 2, val);
-	},
-	value: function (val) {
-		return this.setChannel('hsv', 2, val);
-	},
-	cyan: function (val) {
-		return this.setChannel('cmyk', 0, val);
-	},
-	magenta: function (val) {
-		return this.setChannel('cmyk', 1, val);
-	},
-	yellow: function (val) {
-		return this.setChannel('cmyk', 2, val);
-	},
-	black: function (val) {
-		return this.setChannel('cmyk', 3, val);
-	},
-
-	hexString: function () {
-		return string.hexString(this.values.rgb);
-	},
-	rgbString: function () {
-		return string.rgbString(this.values.rgb, this.values.alpha);
-	},
-	rgbaString: function () {
-		return string.rgbaString(this.values.rgb, this.values.alpha);
-	},
-	percentString: function () {
-		return string.percentString(this.values.rgb, this.values.alpha);
-	},
-	hslString: function () {
-		return string.hslString(this.values.hsl, this.values.alpha);
-	},
-	hslaString: function () {
-		return string.hslaString(this.values.hsl, this.values.alpha);
-	},
-	hwbString: function () {
-		return string.hwbString(this.values.hwb, this.values.alpha);
-	},
-	keyword: function () {
-		return string.keyword(this.values.rgb, this.values.alpha);
-	},
-
-	rgbNumber: function () {
-		var rgb = this.values.rgb;
-		return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
-	},
-
-	luminosity: function () {
-		// http://www.w3.org/TR/WCAG20/#relativeluminancedef
-		var rgb = this.values.rgb;
-		var lum = [];
-		for (var i = 0; i < rgb.length; i++) {
-			var chan = rgb[i] / 255;
-			lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
-		}
-		return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
-	},
-
-	contrast: function (color2) {
-		// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
-		var lum1 = this.luminosity();
-		var lum2 = color2.luminosity();
-		if (lum1 > lum2) {
-			return (lum1 + 0.05) / (lum2 + 0.05);
-		}
-		return (lum2 + 0.05) / (lum1 + 0.05);
-	},
-
-	level: function (color2) {
-		var contrastRatio = this.contrast(color2);
-		if (contrastRatio >= 7.1) {
-			return 'AAA';
-		}
-
-		return (contrastRatio >= 4.5) ? 'AA' : '';
-	},
-
-	dark: function () {
-		// YIQ equation from http://24ways.org/2010/calculating-color-contrast
-		var rgb = this.values.rgb;
-		var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
-		return yiq < 128;
-	},
-
-	light: function () {
-		return !this.dark();
-	},
-
-	negate: function () {
-		var rgb = [];
-		for (var i = 0; i < 3; i++) {
-			rgb[i] = 255 - this.values.rgb[i];
-		}
-		this.setValues('rgb', rgb);
-		return this;
-	},
-
-	lighten: function (ratio) {
-		var hsl = this.values.hsl;
-		hsl[2] += hsl[2] * ratio;
-		this.setValues('hsl', hsl);
-		return this;
-	},
-
-	darken: function (ratio) {
-		var hsl = this.values.hsl;
-		hsl[2] -= hsl[2] * ratio;
-		this.setValues('hsl', hsl);
-		return this;
-	},
-
-	saturate: function (ratio) {
-		var hsl = this.values.hsl;
-		hsl[1] += hsl[1] * ratio;
-		this.setValues('hsl', hsl);
-		return this;
-	},
-
-	desaturate: function (ratio) {
-		var hsl = this.values.hsl;
-		hsl[1] -= hsl[1] * ratio;
-		this.setValues('hsl', hsl);
-		return this;
-	},
-
-	whiten: function (ratio) {
-		var hwb = this.values.hwb;
-		hwb[1] += hwb[1] * ratio;
-		this.setValues('hwb', hwb);
-		return this;
-	},
-
-	blacken: function (ratio) {
-		var hwb = this.values.hwb;
-		hwb[2] += hwb[2] * ratio;
-		this.setValues('hwb', hwb);
-		return this;
-	},
-
-	greyscale: function () {
-		var rgb = this.values.rgb;
-		// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
-		var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
-		this.setValues('rgb', [val, val, val]);
-		return this;
-	},
-
-	clearer: function (ratio) {
-		var alpha = this.values.alpha;
-		this.setValues('alpha', alpha - (alpha * ratio));
-		return this;
-	},
-
-	opaquer: function (ratio) {
-		var alpha = this.values.alpha;
-		this.setValues('alpha', alpha + (alpha * ratio));
-		return this;
-	},
-
-	rotate: function (degrees) {
-		var hsl = this.values.hsl;
-		var hue = (hsl[0] + degrees) % 360;
-		hsl[0] = hue < 0 ? 360 + hue : hue;
-		this.setValues('hsl', hsl);
-		return this;
-	},
-
-	/**
-	 * Ported from sass implementation in C
-	 * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
-	 */
-	mix: function (mixinColor, weight) {
-		var color1 = this;
-		var color2 = mixinColor;
-		var p = weight === undefined ? 0.5 : weight;
-
-		var w = 2 * p - 1;
-		var a = color1.alpha() - color2.alpha();
-
-		var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
-		var w2 = 1 - w1;
-
-		return this
-			.rgb(
-				w1 * color1.red() + w2 * color2.red(),
-				w1 * color1.green() + w2 * color2.green(),
-				w1 * color1.blue() + w2 * color2.blue()
-			)
-			.alpha(color1.alpha() * p + color2.alpha() * (1 - p));
-	},
-
-	toJSON: function () {
-		return this.rgb();
-	},
-
-	clone: function () {
-		// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
-		// making the final build way to big to embed in Chart.js. So let's do it manually,
-		// assuming that values to clone are 1 dimension arrays containing only numbers,
-		// except 'alpha' which is a number.
-		var result = new Color();
-		var source = this.values;
-		var target = result.values;
-		var value, type;
-
-		for (var prop in source) {
-			if (source.hasOwnProperty(prop)) {
-				value = source[prop];
-				type = ({}).toString.call(value);
-				if (type === '[object Array]') {
-					target[prop] = value.slice(0);
-				} else if (type === '[object Number]') {
-					target[prop] = value;
-				} else {
-					console.error('unexpected color value:', value);
-				}
-			}
-		}
-
-		return result;
-	}
-};
-
-Color.prototype.spaces = {
-	rgb: ['red', 'green', 'blue'],
-	hsl: ['hue', 'saturation', 'lightness'],
-	hsv: ['hue', 'saturation', 'value'],
-	hwb: ['hue', 'whiteness', 'blackness'],
-	cmyk: ['cyan', 'magenta', 'yellow', 'black']
-};
-
-Color.prototype.maxes = {
-	rgb: [255, 255, 255],
-	hsl: [360, 100, 100],
-	hsv: [360, 100, 100],
-	hwb: [360, 100, 100],
-	cmyk: [100, 100, 100, 100]
-};
-
-Color.prototype.getValues = function (space) {
-	var values = this.values;
-	var vals = {};
-
-	for (var i = 0; i < space.length; i++) {
-		vals[space.charAt(i)] = values[space][i];
-	}
-
-	if (values.alpha !== 1) {
-		vals.a = values.alpha;
-	}
-
-	// {r: 255, g: 255, b: 255, a: 0.4}
-	return vals;
-};
-
-Color.prototype.setValues = function (space, vals) {
-	var values = this.values;
-	var spaces = this.spaces;
-	var maxes = this.maxes;
-	var alpha = 1;
-	var i;
-
-	if (space === 'alpha') {
-		alpha = vals;
-	} else if (vals.length) {
-		// [10, 10, 10]
-		values[space] = vals.slice(0, space.length);
-		alpha = vals[space.length];
-	} else if (vals[space.charAt(0)] !== undefined) {
-		// {r: 10, g: 10, b: 10}
-		for (i = 0; i < space.length; i++) {
-			values[space][i] = vals[space.charAt(i)];
-		}
-
-		alpha = vals.a;
-	} else if (vals[spaces[space][0]] !== undefined) {
-		// {red: 10, green: 10, blue: 10}
-		var chans = spaces[space];
-
-		for (i = 0; i < space.length; i++) {
-			values[space][i] = vals[chans[i]];
-		}
-
-		alpha = vals.alpha;
-	}
-
-	values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
-
-	if (space === 'alpha') {
-		return false;
-	}
-
-	var capped;
-
-	// cap values of the space prior converting all values
-	for (i = 0; i < space.length; i++) {
-		capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
-		values[space][i] = Math.round(capped);
-	}
-
-	// convert to all the other color spaces
-	for (var sname in spaces) {
-		if (sname !== space) {
-			values[sname] = convert[space][sname](values[space]);
-		}
-	}
-
-	return true;
-};
-
-Color.prototype.setSpace = function (space, args) {
-	var vals = args[0];
-
-	if (vals === undefined) {
-		// color.rgb()
-		return this.getValues(space);
-	}
-
-	// color.rgb(10, 10, 10)
-	if (typeof vals === 'number') {
-		vals = Array.prototype.slice.call(args);
-	}
-
-	this.setValues(space, vals);
-	return this;
-};
-
-Color.prototype.setChannel = function (space, index, val) {
-	var svalues = this.values[space];
-	if (val === undefined) {
-		// color.red()
-		return svalues[index];
-	} else if (val === svalues[index]) {
-		// color.red(color.red())
-		return this;
-	}
-
-	// color.red(100)
-	svalues[index] = val;
-	this.setValues(space, svalues);
-
-	return this;
-};
-
-if (typeof window !== 'undefined') {
-	window.Color = Color;
-}
-
-module.exports = Color;
+    /* MIT license */
+    var convert = require(5);
+    var string = require(2);
+
+    var Color = function (obj) {
+        if (obj instanceof Color) {
+            return obj;
+        }
+        if (!(this instanceof Color)) {
+            return new Color(obj);
+        }
+
+        this.valid = false;
+        this.values = {
+            rgb: [0, 0, 0],
+            hsl: [0, 0, 0],
+            hsv: [0, 0, 0],
+            hwb: [0, 0, 0],
+            cmyk: [0, 0, 0, 0],
+            alpha: 1
+        };
+
+        // parse Color() argument
+        var vals;
+        if (typeof obj === 'string') {
+            vals = string.getRgba(obj);
+            if (vals) {
+                this.setValues('rgb', vals);
+            } else if (vals = string.getHsla(obj)) {
+                this.setValues('hsl', vals);
+            } else if (vals = string.getHwb(obj)) {
+                this.setValues('hwb', vals);
+            }
+        } else if (typeof obj === 'object') {
+            vals = obj;
+            if (vals.r !== undefined || vals.red !== undefined) {
+                this.setValues('rgb', vals);
+            } else if (vals.l !== undefined || vals.lightness !== undefined) {
+                this.setValues('hsl', vals);
+            } else if (vals.v !== undefined || vals.value !== undefined) {
+                this.setValues('hsv', vals);
+            } else if (vals.w !== undefined || vals.whiteness !== undefined) {
+                this.setValues('hwb', vals);
+            } else if (vals.c !== undefined || vals.cyan !== undefined) {
+                this.setValues('cmyk', vals);
+            }
+        }
+    };
+
+    Color.prototype = {
+        isValid: function () {
+            return this.valid;
+        },
+        rgb: function () {
+            return this.setSpace('rgb', arguments);
+        },
+        hsl: function () {
+            return this.setSpace('hsl', arguments);
+        },
+        hsv: function () {
+            return this.setSpace('hsv', arguments);
+        },
+        hwb: function () {
+            return this.setSpace('hwb', arguments);
+        },
+        cmyk: function () {
+            return this.setSpace('cmyk', arguments);
+        },
+
+        rgbArray: function () {
+            return this.values.rgb;
+        },
+        hslArray: function () {
+            return this.values.hsl;
+        },
+        hsvArray: function () {
+            return this.values.hsv;
+        },
+        hwbArray: function () {
+            var values = this.values;
+            if (values.alpha !== 1) {
+                return values.hwb.concat([values.alpha]);
+            }
+            return values.hwb;
+        },
+        cmykArray: function () {
+            return this.values.cmyk;
+        },
+        rgbaArray: function () {
+            var values = this.values;
+            return values.rgb.concat([values.alpha]);
+        },
+        hslaArray: function () {
+            var values = this.values;
+            return values.hsl.concat([values.alpha]);
+        },
+        alpha: function (val) {
+            if (val === undefined) {
+                return this.values.alpha;
+            }
+            this.setValues('alpha', val);
+            return this;
+        },
+
+        red: function (val) {
+            return this.setChannel('rgb', 0, val);
+        },
+        green: function (val) {
+            return this.setChannel('rgb', 1, val);
+        },
+        blue: function (val) {
+            return this.setChannel('rgb', 2, val);
+        },
+        hue: function (val) {
+            if (val) {
+                val %= 360;
+                val = val < 0 ? 360 + val : val;
+            }
+            return this.setChannel('hsl', 0, val);
+        },
+        saturation: function (val) {
+            return this.setChannel('hsl', 1, val);
+        },
+        lightness: function (val) {
+            return this.setChannel('hsl', 2, val);
+        },
+        saturationv: function (val) {
+            return this.setChannel('hsv', 1, val);
+        },
+        whiteness: function (val) {
+            return this.setChannel('hwb', 1, val);
+        },
+        blackness: function (val) {
+            return this.setChannel('hwb', 2, val);
+        },
+        value: function (val) {
+            return this.setChannel('hsv', 2, val);
+        },
+        cyan: function (val) {
+            return this.setChannel('cmyk', 0, val);
+        },
+        magenta: function (val) {
+            return this.setChannel('cmyk', 1, val);
+        },
+        yellow: function (val) {
+            return this.setChannel('cmyk', 2, val);
+        },
+        black: function (val) {
+            return this.setChannel('cmyk', 3, val);
+        },
+
+        hexString: function () {
+            return string.hexString(this.values.rgb);
+        },
+        rgbString: function () {
+            return string.rgbString(this.values.rgb, this.values.alpha);
+        },
+        rgbaString: function () {
+            return string.rgbaString(this.values.rgb, this.values.alpha);
+        },
+        percentString: function () {
+            return string.percentString(this.values.rgb, this.values.alpha);
+        },
+        hslString: function () {
+            return string.hslString(this.values.hsl, this.values.alpha);
+        },
+        hslaString: function () {
+            return string.hslaString(this.values.hsl, this.values.alpha);
+        },
+        hwbString: function () {
+            return string.hwbString(this.values.hwb, this.values.alpha);
+        },
+        keyword: function () {
+            return string.keyword(this.values.rgb, this.values.alpha);
+        },
+
+        rgbNumber: function () {
+            var rgb = this.values.rgb;
+            return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
+        },
+
+        luminosity: function () {
+            // http://www.w3.org/TR/WCAG20/#relativeluminancedef
+            var rgb = this.values.rgb;
+            var lum = [];
+            for (var i = 0; i < rgb.length; i++) {
+                var chan = rgb[i] / 255;
+                lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
+            }
+            return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
+        },
+
+        contrast: function (color2) {
+            // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
+            var lum1 = this.luminosity();
+            var lum2 = color2.luminosity();
+            if (lum1 > lum2) {
+                return (lum1 + 0.05) / (lum2 + 0.05);
+            }
+            return (lum2 + 0.05) / (lum1 + 0.05);
+        },
+
+        level: function (color2) {
+            var contrastRatio = this.contrast(color2);
+            if (contrastRatio >= 7.1) {
+                return 'AAA';
+            }
+
+            return (contrastRatio >= 4.5) ? 'AA' : '';
+        },
+
+        dark: function () {
+            // YIQ equation from http://24ways.org/2010/calculating-color-contrast
+            var rgb = this.values.rgb;
+            var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
+            return yiq < 128;
+        },
+
+        light: function () {
+            return !this.dark();
+        },
+
+        negate: function () {
+            var rgb = [];
+            for (var i = 0; i < 3; i++) {
+                rgb[i] = 255 - this.values.rgb[i];
+            }
+            this.setValues('rgb', rgb);
+            return this;
+        },
+
+        lighten: function (ratio) {
+            var hsl = this.values.hsl;
+            hsl[2] += hsl[2] * ratio;
+            this.setValues('hsl', hsl);
+            return this;
+        },
+
+        darken: function (ratio) {
+            var hsl = this.values.hsl;
+            hsl[2] -= hsl[2] * ratio;
+            this.setValues('hsl', hsl);
+            return this;
+        },
+
+        saturate: function (ratio) {
+            var hsl = this.values.hsl;
+            hsl[1] += hsl[1] * ratio;
+            this.setValues('hsl', hsl);
+            return this;
+        },
+
+        desaturate: function (ratio) {
+            var hsl = this.values.hsl;
+            hsl[1] -= hsl[1] * ratio;
+            this.setValues('hsl', hsl);
+            return this;
+        },
+
+        whiten: function (ratio) {
+            var hwb = this.values.hwb;
+            hwb[1] += hwb[1] * ratio;
+            this.setValues('hwb', hwb);
+            return this;
+        },
+
+        blacken: function (ratio) {
+            var hwb = this.values.hwb;
+            hwb[2] += hwb[2] * ratio;
+            this.setValues('hwb', hwb);
+            return this;
+        },
+
+        greyscale: function () {
+            var rgb = this.values.rgb;
+            // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
+            var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
+            this.setValues('rgb', [val, val, val]);
+            return this;
+        },
+
+        clearer: function (ratio) {
+            var alpha = this.values.alpha;
+            this.setValues('alpha', alpha - (alpha * ratio));
+            return this;
+        },
+
+        opaquer: function (ratio) {
+            var alpha = this.values.alpha;
+            this.setValues('alpha', alpha + (alpha * ratio));
+            return this;
+        },
+
+        rotate: function (degrees) {
+            var hsl = this.values.hsl;
+            var hue = (hsl[0] + degrees) % 360;
+            hsl[0] = hue < 0 ? 360 + hue : hue;
+            this.setValues('hsl', hsl);
+            return this;
+        },
+
+        /**
+         * Ported from sass implementation in C
+         * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
+         */
+        mix: function (mixinColor, weight) {
+            var color1 = this;
+            var color2 = mixinColor;
+            var p = weight === undefined ? 0.5 : weight;
+
+            var w = 2 * p - 1;
+            var a = color1.alpha() - color2.alpha();
+
+            var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+            var w2 = 1 - w1;
+
+            return this
+                .rgb(
+                    w1 * color1.red() + w2 * color2.red(),
+                    w1 * color1.green() + w2 * color2.green(),
+                    w1 * color1.blue() + w2 * color2.blue()
+                )
+                .alpha(color1.alpha() * p + color2.alpha() * (1 - p));
+        },
+
+        toJSON: function () {
+            return this.rgb();
+        },
+
+        clone: function () {
+            // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
+            // making the final build way to big to embed in Chart.js. So let's do it manually,
+            // assuming that values to clone are 1 dimension arrays containing only numbers,
+            // except 'alpha' which is a number.
+            var result = new Color();
+            var source = this.values;
+            var target = result.values;
+            var value, type;
+
+            for (var prop in source) {
+                if (source.hasOwnProperty(prop)) {
+                    value = source[prop];
+                    type = ({}).toString.call(value);
+                    if (type === '[object Array]') {
+                        target[prop] = value.slice(0);
+                    } else if (type === '[object Number]') {
+                        target[prop] = value;
+                    } else {
+                        console.error('unexpected color value:', value);
+                    }
+                }
+            }
+
+            return result;
+        }
+    };
+
+    Color.prototype.spaces = {
+        rgb: ['red', 'green', 'blue'],
+        hsl: ['hue', 'saturation', 'lightness'],
+        hsv: ['hue', 'saturation', 'value'],
+        hwb: ['hue', 'whiteness', 'blackness'],
+        cmyk: ['cyan', 'magenta', 'yellow', 'black']
+    };
+
+    Color.prototype.maxes = {
+        rgb: [255, 255, 255],
+        hsl: [360, 100, 100],
+        hsv: [360, 100, 100],
+        hwb: [360, 100, 100],
+        cmyk: [100, 100, 100, 100]
+    };
+
+    Color.prototype.getValues = function (space) {
+        var values = this.values;
+        var vals = {};
+
+        for (var i = 0; i < space.length; i++) {
+            vals[space.charAt(i)] = values[space][i];
+        }
+
+        if (values.alpha !== 1) {
+            vals.a = values.alpha;
+        }
+
+        // {r: 255, g: 255, b: 255, a: 0.4}
+        return vals;
+    };
+
+    Color.prototype.setValues = function (space, vals) {
+        var values = this.values;
+        var spaces = this.spaces;
+        var maxes = this.maxes;
+        var alpha = 1;
+        var i;
+
+        this.valid = true;
+
+        if (space === 'alpha') {
+            alpha = vals;
+        } else if (vals.length) {
+            // [10, 10, 10]
+            values[space] = vals.slice(0, space.length);
+            alpha = vals[space.length];
+        } else if (vals[space.charAt(0)] !== undefined) {
+            // {r: 10, g: 10, b: 10}
+            for (i = 0; i < space.length; i++) {
+                values[space][i] = vals[space.charAt(i)];
+            }
+
+            alpha = vals.a;
+        } else if (vals[spaces[space][0]] !== undefined) {
+            // {red: 10, green: 10, blue: 10}
+            var chans = spaces[space];
+
+            for (i = 0; i < space.length; i++) {
+                values[space][i] = vals[chans[i]];
+            }
+
+            alpha = vals.alpha;
+        }
+
+        values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
+
+        if (space === 'alpha') {
+            return false;
+        }
+
+        var capped;
+
+        // cap values of the space prior converting all values
+        for (i = 0; i < space.length; i++) {
+            capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
+            values[space][i] = Math.round(capped);
+        }
+
+        // convert to all the other color spaces
+        for (var sname in spaces) {
+            if (sname !== space) {
+                values[sname] = convert[space][sname](values[space]);
+            }
+        }
+
+        return true;
+    };
+
+    Color.prototype.setSpace = function (space, args) {
+        var vals = args[0];
+
+        if (vals === undefined) {
+            // color.rgb()
+            return this.getValues(space);
+        }
+
+        // color.rgb(10, 10, 10)
+        if (typeof vals === 'number') {
+            vals = Array.prototype.slice.call(args);
+        }
+
+        this.setValues(space, vals);
+        return this;
+    };
+
+    Color.prototype.setChannel = function (space, index, val) {
+        var svalues = this.values[space];
+        if (val === undefined) {
+            // color.red()
+            return svalues[index];
+        } else if (val === svalues[index]) {
+            // color.red(color.red())
+            return this;
+        }
+
+        // color.red(100)
+        svalues[index] = val;
+        this.setValues(space, svalues);
+
+        return this;
+    };
+
+    if (typeof window !== 'undefined') {
+        window.Color = Color;
+    }
+
+    module.exports = Color;
 
 },{"2":2,"5":5}],4:[function(require,module,exports){
-/* MIT license */
+    /* MIT license */
 
-module.exports = {
-  rgb2hsl: rgb2hsl,
-  rgb2hsv: rgb2hsv,
-  rgb2hwb: rgb2hwb,
-  rgb2cmyk: rgb2cmyk,
-  rgb2keyword: rgb2keyword,
-  rgb2xyz: rgb2xyz,
-  rgb2lab: rgb2lab,
-  rgb2lch: rgb2lch,
+    module.exports = {
+        rgb2hsl: rgb2hsl,
+        rgb2hsv: rgb2hsv,
+        rgb2hwb: rgb2hwb,
+        rgb2cmyk: rgb2cmyk,
+        rgb2keyword: rgb2keyword,
+        rgb2xyz: rgb2xyz,
+        rgb2lab: rgb2lab,
+        rgb2lch: rgb2lch,
 
-  hsl2rgb: hsl2rgb,
-  hsl2hsv: hsl2hsv,
-  hsl2hwb: hsl2hwb,
-  hsl2cmyk: hsl2cmyk,
-  hsl2keyword: hsl2keyword,
+        hsl2rgb: hsl2rgb,
+        hsl2hsv: hsl2hsv,
+        hsl2hwb: hsl2hwb,
+        hsl2cmyk: hsl2cmyk,
+        hsl2keyword: hsl2keyword,
 
-  hsv2rgb: hsv2rgb,
-  hsv2hsl: hsv2hsl,
-  hsv2hwb: hsv2hwb,
-  hsv2cmyk: hsv2cmyk,
-  hsv2keyword: hsv2keyword,
+        hsv2rgb: hsv2rgb,
+        hsv2hsl: hsv2hsl,
+        hsv2hwb: hsv2hwb,
+        hsv2cmyk: hsv2cmyk,
+        hsv2keyword: hsv2keyword,
 
-  hwb2rgb: hwb2rgb,
-  hwb2hsl: hwb2hsl,
-  hwb2hsv: hwb2hsv,
-  hwb2cmyk: hwb2cmyk,
-  hwb2keyword: hwb2keyword,
+        hwb2rgb: hwb2rgb,
+        hwb2hsl: hwb2hsl,
+        hwb2hsv: hwb2hsv,
+        hwb2cmyk: hwb2cmyk,
+        hwb2keyword: hwb2keyword,
 
-  cmyk2rgb: cmyk2rgb,
-  cmyk2hsl: cmyk2hsl,
-  cmyk2hsv: cmyk2hsv,
-  cmyk2hwb: cmyk2hwb,
-  cmyk2keyword: cmyk2keyword,
+        cmyk2rgb: cmyk2rgb,
+        cmyk2hsl: cmyk2hsl,
+        cmyk2hsv: cmyk2hsv,
+        cmyk2hwb: cmyk2hwb,
+        cmyk2keyword: cmyk2keyword,
 
-  keyword2rgb: keyword2rgb,
-  keyword2hsl: keyword2hsl,
-  keyword2hsv: keyword2hsv,
-  keyword2hwb: keyword2hwb,
-  keyword2cmyk: keyword2cmyk,
-  keyword2lab: keyword2lab,
-  keyword2xyz: keyword2xyz,
+        keyword2rgb: keyword2rgb,
+        keyword2hsl: keyword2hsl,
+        keyword2hsv: keyword2hsv,
+        keyword2hwb: keyword2hwb,
+        keyword2cmyk: keyword2cmyk,
+        keyword2lab: keyword2lab,
+        keyword2xyz: keyword2xyz,
 
-  xyz2rgb: xyz2rgb,
-  xyz2lab: xyz2lab,
-  xyz2lch: xyz2lch,
+        xyz2rgb: xyz2rgb,
+        xyz2lab: xyz2lab,
+        xyz2lch: xyz2lch,
 
-  lab2xyz: lab2xyz,
-  lab2rgb: lab2rgb,
-  lab2lch: lab2lch,
+        lab2xyz: lab2xyz,
+        lab2rgb: lab2rgb,
+        lab2lch: lab2lch,
 
-  lch2lab: lch2lab,
-  lch2xyz: lch2xyz,
-  lch2rgb: lch2rgb
-}
+        lch2lab: lch2lab,
+        lch2xyz: lch2xyz,
+        lch2rgb: lch2rgb
+    }
 
 
-function rgb2hsl(rgb) {
-  var r = rgb[0]/255,
-      g = rgb[1]/255,
-      b = rgb[2]/255,
-      min = Math.min(r, g, b),
-      max = Math.max(r, g, b),
-      delta = max - min,
-      h, s, l;
+    function rgb2hsl(rgb) {
+        var r = rgb[0]/255,
+            g = rgb[1]/255,
+            b = rgb[2]/255,
+            min = Math.min(r, g, b),
+            max = Math.max(r, g, b),
+            delta = max - min,
+            h, s, l;
 
-  if (max == min)
-    h = 0;
-  else if (r == max)
-    h = (g - b) / delta;
-  else if (g == max)
-    h = 2 + (b - r) / delta;
-  else if (b == max)
-    h = 4 + (r - g)/ delta;
+        if (max == min)
+            h = 0;
+        else if (r == max)
+            h = (g - b) / delta;
+        else if (g == max)
+            h = 2 + (b - r) / delta;
+        else if (b == max)
+            h = 4 + (r - g)/ delta;
 
-  h = Math.min(h * 60, 360);
+        h = Math.min(h * 60, 360);
 
-  if (h < 0)
-    h += 360;
+        if (h < 0)
+            h += 360;
 
-  l = (min + max) / 2;
+        l = (min + max) / 2;
 
-  if (max == min)
-    s = 0;
-  else if (l <= 0.5)
-    s = delta / (max + min);
-  else
-    s = delta / (2 - max - min);
+        if (max == min)
+            s = 0;
+        else if (l <= 0.5)
+            s = delta / (max + min);
+        else
+            s = delta / (2 - max - min);
 
-  return [h, s * 100, l * 100];
-}
+        return [h, s * 100, l * 100];
+    }
 
-function rgb2hsv(rgb) {
-  var r = rgb[0],
-      g = rgb[1],
-      b = rgb[2],
-      min = Math.min(r, g, b),
-      max = Math.max(r, g, b),
-      delta = max - min,
-      h, s, v;
+    function rgb2hsv(rgb) {
+        var r = rgb[0],
+            g = rgb[1],
+            b = rgb[2],
+            min = Math.min(r, g, b),
+            max = Math.max(r, g, b),
+            delta = max - min,
+            h, s, v;
 
-  if (max == 0)
-    s = 0;
-  else
-    s = (delta/max * 1000)/10;
+        if (max == 0)
+            s = 0;
+        else
+            s = (delta/max * 1000)/10;
 
-  if (max == min)
-    h = 0;
-  else if (r == max)
-    h = (g - b) / delta;
-  else if (g == max)
-    h = 2 + (b - r) / delta;
-  else if (b == max)
-    h = 4 + (r - g) / delta;
+        if (max == min)
+            h = 0;
+        else if (r == max)
+            h = (g - b) / delta;
+        else if (g == max)
+            h = 2 + (b - r) / delta;
+        else if (b == max)
+            h = 4 + (r - g) / delta;
 
-  h = Math.min(h * 60, 360);
+        h = Math.min(h * 60, 360);
 
-  if (h < 0)
-    h += 360;
+        if (h < 0)
+            h += 360;
 
-  v = ((max / 255) * 1000) / 10;
+        v = ((max / 255) * 1000) / 10;
 
-  return [h, s, v];
-}
+        return [h, s, v];
+    }
 
-function rgb2hwb(rgb) {
-  var r = rgb[0],
-      g = rgb[1],
-      b = rgb[2],
-      h = rgb2hsl(rgb)[0],
-      w = 1/255 * Math.min(r, Math.min(g, b)),
-      b = 1 - 1/255 * Math.max(r, Math.max(g, b));
+    function rgb2hwb(rgb) {
+        var r = rgb[0],
+            g = rgb[1],
+            b = rgb[2],
+            h = rgb2hsl(rgb)[0],
+            w = 1/255 * Math.min(r, Math.min(g, b)),
+            b = 1 - 1/255 * Math.max(r, Math.max(g, b));
 
-  return [h, w * 100, b * 100];
-}
+        return [h, w * 100, b * 100];
+    }
 
-function rgb2cmyk(rgb) {
-  var r = rgb[0] / 255,
-      g = rgb[1] / 255,
-      b = rgb[2] / 255,
-      c, m, y, k;
+    function rgb2cmyk(rgb) {
+        var r = rgb[0] / 255,
+            g = rgb[1] / 255,
+            b = rgb[2] / 255,
+            c, m, y, k;
 
-  k = Math.min(1 - r, 1 - g, 1 - b);
-  c = (1 - r - k) / (1 - k) || 0;
-  m = (1 - g - k) / (1 - k) || 0;
-  y = (1 - b - k) / (1 - k) || 0;
-  return [c * 100, m * 100, y * 100, k * 100];
-}
+        k = Math.min(1 - r, 1 - g, 1 - b);
+        c = (1 - r - k) / (1 - k) || 0;
+        m = (1 - g - k) / (1 - k) || 0;
+        y = (1 - b - k) / (1 - k) || 0;
+        return [c * 100, m * 100, y * 100, k * 100];
+    }
 
-function rgb2keyword(rgb) {
-  return reverseKeywords[JSON.stringify(rgb)];
-}
+    function rgb2keyword(rgb) {
+        return reverseKeywords[JSON.stringify(rgb)];
+    }
 
-function rgb2xyz(rgb) {
-  var r = rgb[0] / 255,
-      g = rgb[1] / 255,
-      b = rgb[2] / 255;
+    function rgb2xyz(rgb) {
+        var r = rgb[0] / 255,
+            g = rgb[1] / 255,
+            b = rgb[2] / 255;
 
-  // assume sRGB
-  r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
-  g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
-  b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+        // assume sRGB
+        r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+        g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+        b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
 
-  var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
-  var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
-  var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+        var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+        var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+        var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
 
-  return [x * 100, y *100, z * 100];
-}
+        return [x * 100, y *100, z * 100];
+    }
 
-function rgb2lab(rgb) {
-  var xyz = rgb2xyz(rgb),
-        x = xyz[0],
-        y = xyz[1],
-        z = xyz[2],
-        l, a, b;
+    function rgb2lab(rgb) {
+        var xyz = rgb2xyz(rgb),
+            x = xyz[0],
+            y = xyz[1],
+            z = xyz[2],
+            l, a, b;
 
-  x /= 95.047;
-  y /= 100;
-  z /= 108.883;
+        x /= 95.047;
+        y /= 100;
+        z /= 108.883;
 
-  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
-  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
-  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+        x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+        y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+        z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
 
-  l = (116 * y) - 16;
-  a = 500 * (x - y);
-  b = 200 * (y - z);
+        l = (116 * y) - 16;
+        a = 500 * (x - y);
+        b = 200 * (y - z);
 
-  return [l, a, b];
-}
+        return [l, a, b];
+    }
 
-function rgb2lch(args) {
-  return lab2lch(rgb2lab(args));
-}
+    function rgb2lch(args) {
+        return lab2lch(rgb2lab(args));
+    }
 
-function hsl2rgb(hsl) {
-  var h = hsl[0] / 360,
-      s = hsl[1] / 100,
-      l = hsl[2] / 100,
-      t1, t2, t3, rgb, val;
+    function hsl2rgb(hsl) {
+        var h = hsl[0] / 360,
+            s = hsl[1] / 100,
+            l = hsl[2] / 100,
+            t1, t2, t3, rgb, val;
 
-  if (s == 0) {
-    val = l * 255;
-    return [val, val, val];
-  }
+        if (s == 0) {
+            val = l * 255;
+            return [val, val, val];
+        }
 
-  if (l < 0.5)
-    t2 = l * (1 + s);
-  else
-    t2 = l + s - l * s;
-  t1 = 2 * l - t2;
+        if (l < 0.5)
+            t2 = l * (1 + s);
+        else
+            t2 = l + s - l * s;
+        t1 = 2 * l - t2;
 
-  rgb = [0, 0, 0];
-  for (var i = 0; i < 3; i++) {
-    t3 = h + 1 / 3 * - (i - 1);
-    t3 < 0 && t3++;
-    t3 > 1 && t3--;
+        rgb = [0, 0, 0];
+        for (var i = 0; i < 3; i++) {
+            t3 = h + 1 / 3 * - (i - 1);
+            t3 < 0 && t3++;
+            t3 > 1 && t3--;
 
-    if (6 * t3 < 1)
-      val = t1 + (t2 - t1) * 6 * t3;
-    else if (2 * t3 < 1)
-      val = t2;
-    else if (3 * t3 < 2)
-      val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
-    else
-      val = t1;
+            if (6 * t3 < 1)
+                val = t1 + (t2 - t1) * 6 * t3;
+            else if (2 * t3 < 1)
+                val = t2;
+            else if (3 * t3 < 2)
+                val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+            else
+                val = t1;
 
-    rgb[i] = val * 255;
-  }
+            rgb[i] = val * 255;
+        }
 
-  return rgb;
-}
+        return rgb;
+    }
 
-function hsl2hsv(hsl) {
-  var h = hsl[0],
-      s = hsl[1] / 100,
-      l = hsl[2] / 100,
-      sv, v;
+    function hsl2hsv(hsl) {
+        var h = hsl[0],
+            s = hsl[1] / 100,
+            l = hsl[2] / 100,
+            sv, v;
 
-  if(l === 0) {
-      // no need to do calc on black
-      // also avoids divide by 0 error
-      return [0, 0, 0];
-  }
+        if(l === 0) {
+            // no need to do calc on black
+            // also avoids divide by 0 error
+            return [0, 0, 0];
+        }
 
-  l *= 2;
-  s *= (l <= 1) ? l : 2 - l;
-  v = (l + s) / 2;
-  sv = (2 * s) / (l + s);
-  return [h, sv * 100, v * 100];
-}
+        l *= 2;
+        s *= (l <= 1) ? l : 2 - l;
+        v = (l + s) / 2;
+        sv = (2 * s) / (l + s);
+        return [h, sv * 100, v * 100];
+    }
 
-function hsl2hwb(args) {
-  return rgb2hwb(hsl2rgb(args));
-}
+    function hsl2hwb(args) {
+        return rgb2hwb(hsl2rgb(args));
+    }
 
-function hsl2cmyk(args) {
-  return rgb2cmyk(hsl2rgb(args));
-}
+    function hsl2cmyk(args) {
+        return rgb2cmyk(hsl2rgb(args));
+    }
 
-function hsl2keyword(args) {
-  return rgb2keyword(hsl2rgb(args));
-}
+    function hsl2keyword(args) {
+        return rgb2keyword(hsl2rgb(args));
+    }
 
 
-function hsv2rgb(hsv) {
-  var h = hsv[0] / 60,
-      s = hsv[1] / 100,
-      v = hsv[2] / 100,
-      hi = Math.floor(h) % 6;
+    function hsv2rgb(hsv) {
+        var h = hsv[0] / 60,
+            s = hsv[1] / 100,
+            v = hsv[2] / 100,
+            hi = Math.floor(h) % 6;
 
-  var f = h - Math.floor(h),
-      p = 255 * v * (1 - s),
-      q = 255 * v * (1 - (s * f)),
-      t = 255 * v * (1 - (s * (1 - f))),
-      v = 255 * v;
+        var f = h - Math.floor(h),
+            p = 255 * v * (1 - s),
+            q = 255 * v * (1 - (s * f)),
+            t = 255 * v * (1 - (s * (1 - f))),
+            v = 255 * v;
 
-  switch(hi) {
-    case 0:
-      return [v, t, p];
-    case 1:
-      return [q, v, p];
-    case 2:
-      return [p, v, t];
-    case 3:
-      return [p, q, v];
-    case 4:
-      return [t, p, v];
-    case 5:
-      return [v, p, q];
-  }
-}
+        switch(hi) {
+            case 0:
+                return [v, t, p];
+            case 1:
+                return [q, v, p];
+            case 2:
+                return [p, v, t];
+            case 3:
+                return [p, q, v];
+            case 4:
+                return [t, p, v];
+            case 5:
+                return [v, p, q];
+        }
+    }
 
-function hsv2hsl(hsv) {
-  var h = hsv[0],
-      s = hsv[1] / 100,
-      v = hsv[2] / 100,
-      sl, l;
+    function hsv2hsl(hsv) {
+        var h = hsv[0],
+            s = hsv[1] / 100,
+            v = hsv[2] / 100,
+            sl, l;
 
-  l = (2 - s) * v;
-  sl = s * v;
-  sl /= (l <= 1) ? l : 2 - l;
-  sl = sl || 0;
-  l /= 2;
-  return [h, sl * 100, l * 100];
-}
+        l = (2 - s) * v;
+        sl = s * v;
+        sl /= (l <= 1) ? l : 2 - l;
+        sl = sl || 0;
+        l /= 2;
+        return [h, sl * 100, l * 100];
+    }
 
-function hsv2hwb(args) {
-  return rgb2hwb(hsv2rgb(args))
-}
+    function hsv2hwb(args) {
+        return rgb2hwb(hsv2rgb(args))
+    }
 
-function hsv2cmyk(args) {
-  return rgb2cmyk(hsv2rgb(args));
-}
+    function hsv2cmyk(args) {
+        return rgb2cmyk(hsv2rgb(args));
+    }
 
-function hsv2keyword(args) {
-  return rgb2keyword(hsv2rgb(args));
-}
+    function hsv2keyword(args) {
+        return rgb2keyword(hsv2rgb(args));
+    }
 
 // http://dev.w3.org/csswg/css-color/#hwb-to-rgb
-function hwb2rgb(hwb) {
-  var h = hwb[0] / 360,
-      wh = hwb[1] / 100,
-      bl = hwb[2] / 100,
-      ratio = wh + bl,
-      i, v, f, n;
+    function hwb2rgb(hwb) {
+        var h = hwb[0] / 360,
+            wh = hwb[1] / 100,
+            bl = hwb[2] / 100,
+            ratio = wh + bl,
+            i, v, f, n;
 
-  // wh + bl cant be > 1
-  if (ratio > 1) {
-    wh /= ratio;
-    bl /= ratio;
-  }
+        // wh + bl cant be > 1
+        if (ratio > 1) {
+            wh /= ratio;
+            bl /= ratio;
+        }
 
-  i = Math.floor(6 * h);
-  v = 1 - bl;
-  f = 6 * h - i;
-  if ((i & 0x01) != 0) {
-    f = 1 - f;
-  }
-  n = wh + f * (v - wh);  // linear interpolation
+        i = Math.floor(6 * h);
+        v = 1 - bl;
+        f = 6 * h - i;
+        if ((i & 0x01) != 0) {
+            f = 1 - f;
+        }
+        n = wh + f * (v - wh);  // linear interpolation
 
-  switch (i) {
-    default:
-    case 6:
-    case 0: r = v; g = n; b = wh; break;
-    case 1: r = n; g = v; b = wh; break;
-    case 2: r = wh; g = v; b = n; break;
-    case 3: r = wh; g = n; b = v; break;
-    case 4: r = n; g = wh; b = v; break;
-    case 5: r = v; g = wh; b = n; break;
-  }
+        switch (i) {
+            default:
+            case 6:
+            case 0: r = v; g = n; b = wh; break;
+            case 1: r = n; g = v; b = wh; break;
+            case 2: r = wh; g = v; b = n; break;
+            case 3: r = wh; g = n; b = v; break;
+            case 4: r = n; g = wh; b = v; break;
+            case 5: r = v; g = wh; b = n; break;
+        }
 
-  return [r * 255, g * 255, b * 255];
-}
+        return [r * 255, g * 255, b * 255];
+    }
 
-function hwb2hsl(args) {
-  return rgb2hsl(hwb2rgb(args));
-}
+    function hwb2hsl(args) {
+        return rgb2hsl(hwb2rgb(args));
+    }
 
-function hwb2hsv(args) {
-  return rgb2hsv(hwb2rgb(args));
-}
+    function hwb2hsv(args) {
+        return rgb2hsv(hwb2rgb(args));
+    }
 
-function hwb2cmyk(args) {
-  return rgb2cmyk(hwb2rgb(args));
-}
+    function hwb2cmyk(args) {
+        return rgb2cmyk(hwb2rgb(args));
+    }
 
-function hwb2keyword(args) {
-  return rgb2keyword(hwb2rgb(args));
-}
+    function hwb2keyword(args) {
+        return rgb2keyword(hwb2rgb(args));
+    }
 
-function cmyk2rgb(cmyk) {
-  var c = cmyk[0] / 100,
-      m = cmyk[1] / 100,
-      y = cmyk[2] / 100,
-      k = cmyk[3] / 100,
-      r, g, b;
+    function cmyk2rgb(cmyk) {
+        var c = cmyk[0] / 100,
+            m = cmyk[1] / 100,
+            y = cmyk[2] / 100,
+            k = cmyk[3] / 100,
+            r, g, b;
 
-  r = 1 - Math.min(1, c * (1 - k) + k);
-  g = 1 - Math.min(1, m * (1 - k) + k);
-  b = 1 - Math.min(1, y * (1 - k) + k);
-  return [r * 255, g * 255, b * 255];
-}
+        r = 1 - Math.min(1, c * (1 - k) + k);
+        g = 1 - Math.min(1, m * (1 - k) + k);
+        b = 1 - Math.min(1, y * (1 - k) + k);
+        return [r * 255, g * 255, b * 255];
+    }
 
-function cmyk2hsl(args) {
-  return rgb2hsl(cmyk2rgb(args));
-}
+    function cmyk2hsl(args) {
+        return rgb2hsl(cmyk2rgb(args));
+    }
 
-function cmyk2hsv(args) {
-  return rgb2hsv(cmyk2rgb(args));
-}
+    function cmyk2hsv(args) {
+        return rgb2hsv(cmyk2rgb(args));
+    }
 
-function cmyk2hwb(args) {
-  return rgb2hwb(cmyk2rgb(args));
-}
+    function cmyk2hwb(args) {
+        return rgb2hwb(cmyk2rgb(args));
+    }
 
-function cmyk2keyword(args) {
-  return rgb2keyword(cmyk2rgb(args));
-}
+    function cmyk2keyword(args) {
+        return rgb2keyword(cmyk2rgb(args));
+    }
 
 
-function xyz2rgb(xyz) {
-  var x = xyz[0] / 100,
-      y = xyz[1] / 100,
-      z = xyz[2] / 100,
-      r, g, b;
+    function xyz2rgb(xyz) {
+        var x = xyz[0] / 100,
+            y = xyz[1] / 100,
+            z = xyz[2] / 100,
+            r, g, b;
 
-  r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
-  g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
-  b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+        r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+        g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+        b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
 
-  // assume sRGB
-  r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
-    : r = (r * 12.92);
+        // assume sRGB
+        r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+            : r = (r * 12.92);
 
-  g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
-    : g = (g * 12.92);
+        g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+            : g = (g * 12.92);
 
-  b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
-    : b = (b * 12.92);
+        b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+            : b = (b * 12.92);
 
-  r = Math.min(Math.max(0, r), 1);
-  g = Math.min(Math.max(0, g), 1);
-  b = Math.min(Math.max(0, b), 1);
+        r = Math.min(Math.max(0, r), 1);
+        g = Math.min(Math.max(0, g), 1);
+        b = Math.min(Math.max(0, b), 1);
 
-  return [r * 255, g * 255, b * 255];
-}
+        return [r * 255, g * 255, b * 255];
+    }
 
-function xyz2lab(xyz) {
-  var x = xyz[0],
-      y = xyz[1],
-      z = xyz[2],
-      l, a, b;
+    function xyz2lab(xyz) {
+        var x = xyz[0],
+            y = xyz[1],
+            z = xyz[2],
+            l, a, b;
 
-  x /= 95.047;
-  y /= 100;
-  z /= 108.883;
+        x /= 95.047;
+        y /= 100;
+        z /= 108.883;
 
-  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
-  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
-  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
+        x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
+        y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
+        z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
 
-  l = (116 * y) - 16;
-  a = 500 * (x - y);
-  b = 200 * (y - z);
+        l = (116 * y) - 16;
+        a = 500 * (x - y);
+        b = 200 * (y - z);
 
-  return [l, a, b];
-}
+        return [l, a, b];
+    }
 
-function xyz2lch(args) {
-  return lab2lch(xyz2lab(args));
-}
+    function xyz2lch(args) {
+        return lab2lch(xyz2lab(args));
+    }
 
-function lab2xyz(lab) {
-  var l = lab[0],
-      a = lab[1],
-      b = lab[2],
-      x, y, z, y2;
+    function lab2xyz(lab) {
+        var l = lab[0],
+            a = lab[1],
+            b = lab[2],
+            x, y, z, y2;
 
-  if (l <= 8) {
-    y = (l * 100) / 903.3;
-    y2 = (7.787 * (y / 100)) + (16 / 116);
-  } else {
-    y = 100 * Math.pow((l + 16) / 116, 3);
-    y2 = Math.pow(y / 100, 1/3);
-  }
+        if (l <= 8) {
+            y = (l * 100) / 903.3;
+            y2 = (7.787 * (y / 100)) + (16 / 116);
+        } else {
+            y = 100 * Math.pow((l + 16) / 116, 3);
+            y2 = Math.pow(y / 100, 1/3);
+        }
 
-  x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
+        x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
 
-  z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
+        z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
 
-  return [x, y, z];
-}
+        return [x, y, z];
+    }
 
-function lab2lch(lab) {
-  var l = lab[0],
-      a = lab[1],
-      b = lab[2],
-      hr, h, c;
+    function lab2lch(lab) {
+        var l = lab[0],
+            a = lab[1],
+            b = lab[2],
+            hr, h, c;
 
-  hr = Math.atan2(b, a);
-  h = hr * 360 / 2 / Math.PI;
-  if (h < 0) {
-    h += 360;
-  }
-  c = Math.sqrt(a * a + b * b);
-  return [l, c, h];
-}
+        hr = Math.atan2(b, a);
+        h = hr * 360 / 2 / Math.PI;
+        if (h < 0) {
+            h += 360;
+        }
+        c = Math.sqrt(a * a + b * b);
+        return [l, c, h];
+    }
 
-function lab2rgb(args) {
-  return xyz2rgb(lab2xyz(args));
-}
+    function lab2rgb(args) {
+        return xyz2rgb(lab2xyz(args));
+    }
 
-function lch2lab(lch) {
-  var l = lch[0],
-      c = lch[1],
-      h = lch[2],
-      a, b, hr;
+    function lch2lab(lch) {
+        var l = lch[0],
+            c = lch[1],
+            h = lch[2],
+            a, b, hr;
 
-  hr = h / 360 * 2 * Math.PI;
-  a = c * Math.cos(hr);
-  b = c * Math.sin(hr);
-  return [l, a, b];
-}
+        hr = h / 360 * 2 * Math.PI;
+        a = c * Math.cos(hr);
+        b = c * Math.sin(hr);
+        return [l, a, b];
+    }
 
-function lch2xyz(args) {
-  return lab2xyz(lch2lab(args));
-}
+    function lch2xyz(args) {
+        return lab2xyz(lch2lab(args));
+    }
 
-function lch2rgb(args) {
-  return lab2rgb(lch2lab(args));
-}
+    function lch2rgb(args) {
+        return lab2rgb(lch2lab(args));
+    }
 
-function keyword2rgb(keyword) {
-  return cssKeywords[keyword];
-}
+    function keyword2rgb(keyword) {
+        return cssKeywords[keyword];
+    }
 
-function keyword2hsl(args) {
-  return rgb2hsl(keyword2rgb(args));
-}
+    function keyword2hsl(args) {
+        return rgb2hsl(keyword2rgb(args));
+    }
 
-function keyword2hsv(args) {
-  return rgb2hsv(keyword2rgb(args));
-}
+    function keyword2hsv(args) {
+        return rgb2hsv(keyword2rgb(args));
+    }
 
-function keyword2hwb(args) {
-  return rgb2hwb(keyword2rgb(args));
-}
+    function keyword2hwb(args) {
+        return rgb2hwb(keyword2rgb(args));
+    }
 
-function keyword2cmyk(args) {
-  return rgb2cmyk(keyword2rgb(args));
-}
+    function keyword2cmyk(args) {
+        return rgb2cmyk(keyword2rgb(args));
+    }
 
-function keyword2lab(args) {
-  return rgb2lab(keyword2rgb(args));
-}
+    function keyword2lab(args) {
+        return rgb2lab(keyword2rgb(args));
+    }
 
-function keyword2xyz(args) {
-  return rgb2xyz(keyword2rgb(args));
-}
+    function keyword2xyz(args) {
+        return rgb2xyz(keyword2rgb(args));
+    }
 
-var cssKeywords = {
-  aliceblue:  [240,248,255],
-  antiquewhite: [250,235,215],
-  aqua: [0,255,255],
-  aquamarine: [127,255,212],
-  azure:  [240,255,255],
-  beige:  [245,245,220],
-  bisque: [255,228,196],
-  black:  [0,0,0],
-  blanchedalmond: [255,235,205],
-  blue: [0,0,255],
-  blueviolet: [138,43,226],
-  brown:  [165,42,42],
-  burlywood:  [222,184,135],
-  cadetblue:  [95,158,160],
-  chartreuse: [127,255,0],
-  chocolate:  [210,105,30],
-  coral:  [255,127,80],
-  cornflowerblue: [100,149,237],
-  cornsilk: [255,248,220],
-  crimson:  [220,20,60],
-  cyan: [0,255,255],
-  darkblue: [0,0,139],
-  darkcyan: [0,139,139],
-  darkgoldenrod:  [184,134,11],
-  darkgray: [169,169,169],
-  darkgreen:  [0,100,0],
-  darkgrey: [169,169,169],
-  darkkhaki:  [189,183,107],
-  darkmagenta:  [139,0,139],
-  darkolivegreen: [85,107,47],
-  darkorange: [255,140,0],
-  darkorchid: [153,50,204],
-  darkred:  [139,0,0],
-  darksalmon: [233,150,122],
-  darkseagreen: [143,188,143],
-  darkslateblue:  [72,61,139],
-  darkslategray:  [47,79,79],
-  darkslategrey:  [47,79,79],
-  darkturquoise:  [0,206,209],
-  darkviolet: [148,0,211],
-  deeppink: [255,20,147],
-  deepskyblue:  [0,191,255],
-  dimgray:  [105,105,105],
-  dimgrey:  [105,105,105],
-  dodgerblue: [30,144,255],
-  firebrick:  [178,34,34],
-  floralwhite:  [255,250,240],
-  forestgreen:  [34,139,34],
-  fuchsia:  [255,0,255],
-  gainsboro:  [220,220,220],
-  ghostwhite: [248,248,255],
-  gold: [255,215,0],
-  goldenrod:  [218,165,32],
-  gray: [128,128,128],
-  green:  [0,128,0],
-  greenyellow:  [173,255,47],
-  grey: [128,128,128],
-  honeydew: [240,255,240],
-  hotpink:  [255,105,180],
-  indianred:  [205,92,92],
-  indigo: [75,0,130],
-  ivory:  [255,255,240],
-  khaki:  [240,230,140],
-  lavender: [230,230,250],
-  lavenderblush:  [255,240,245],
-  lawngreen:  [124,252,0],
-  lemonchiffon: [255,250,205],
-  lightblue:  [173,216,230],
-  lightcoral: [240,128,128],
-  lightcyan:  [224,255,255],
-  lightgoldenrodyellow: [250,250,210],
-  lightgray:  [211,211,211],
-  lightgreen: [144,238,144],
-  lightgrey:  [211,211,211],
-  lightpink:  [255,182,193],
-  lightsalmon:  [255,160,122],
-  lightseagreen:  [32,178,170],
-  lightskyblue: [135,206,250],
-  lightslategray: [119,136,153],
-  lightslategrey: [119,136,153],
-  lightsteelblue: [176,196,222],
-  lightyellow:  [255,255,224],
-  lime: [0,255,0],
-  limegreen:  [50,205,50],
-  linen:  [250,240,230],
-  magenta:  [255,0,255],
-  maroon: [128,0,0],
-  mediumaquamarine: [102,205,170],
-  mediumblue: [0,0,205],
-  mediumorchid: [186,85,211],
-  mediumpurple: [147,112,219],
-  mediumseagreen: [60,179,113],
-  mediumslateblue:  [123,104,238],
-  mediumspringgreen:  [0,250,154],
-  mediumturquoise:  [72,209,204],
-  mediumvioletred:  [199,21,133],
-  midnightblue: [25,25,112],
-  mintcream:  [245,255,250],
-  mistyrose:  [255,228,225],
-  moccasin: [255,228,181],
-  navajowhite:  [255,222,173],
-  navy: [0,0,128],
-  oldlace:  [253,245,230],
-  olive:  [128,128,0],
-  olivedrab:  [107,142,35],
-  orange: [255,165,0],
-  orangered:  [255,69,0],
-  orchid: [218,112,214],
-  palegoldenrod:  [238,232,170],
-  palegreen:  [152,251,152],
-  paleturquoise:  [175,238,238],
-  palevioletred:  [219,112,147],
-  papayawhip: [255,239,213],
-  peachpuff:  [255,218,185],
-  peru: [205,133,63],
-  pink: [255,192,203],
-  plum: [221,160,221],
-  powderblue: [176,224,230],
-  purple: [128,0,128],
-  rebeccapurple: [102, 51, 153],
-  red:  [255,0,0],
-  rosybrown:  [188,143,143],
-  royalblue:  [65,105,225],
-  saddlebrown:  [139,69,19],
-  salmon: [250,128,114],
-  sandybrown: [244,164,96],
-  seagreen: [46,139,87],
-  seashell: [255,245,238],
-  sienna: [160,82,45],
-  silver: [192,192,192],
-  skyblue:  [135,206,235],
-  slateblue:  [106,90,205],
-  slategray:  [112,128,144],
-  slategrey:  [112,128,144],
-  snow: [255,250,250],
-  springgreen:  [0,255,127],
-  steelblue:  [70,130,180],
-  tan:  [210,180,140],
-  teal: [0,128,128],
-  thistle:  [216,191,216],
-  tomato: [255,99,71],
-  turquoise:  [64,224,208],
-  violet: [238,130,238],
-  wheat:  [245,222,179],
-  white:  [255,255,255],
-  whitesmoke: [245,245,245],
-  yellow: [255,255,0],
-  yellowgreen:  [154,205,50]
-};
+    var cssKeywords = {
+        aliceblue:  [240,248,255],
+        antiquewhite: [250,235,215],
+        aqua: [0,255,255],
+        aquamarine: [127,255,212],
+        azure:  [240,255,255],
+        beige:  [245,245,220],
+        bisque: [255,228,196],
+        black:  [0,0,0],
+        blanchedalmond: [255,235,205],
+        blue: [0,0,255],
+        blueviolet: [138,43,226],
+        brown:  [165,42,42],
+        burlywood:  [222,184,135],
+        cadetblue:  [95,158,160],
+        chartreuse: [127,255,0],
+        chocolate:  [210,105,30],
+        coral:  [255,127,80],
+        cornflowerblue: [100,149,237],
+        cornsilk: [255,248,220],
+        crimson:  [220,20,60],
+        cyan: [0,255,255],
+        darkblue: [0,0,139],
+        darkcyan: [0,139,139],
+        darkgoldenrod:  [184,134,11],
+        darkgray: [169,169,169],
+        darkgreen:  [0,100,0],
+        darkgrey: [169,169,169],
+        darkkhaki:  [189,183,107],
+        darkmagenta:  [139,0,139],
+        darkolivegreen: [85,107,47],
+        darkorange: [255,140,0],
+        darkorchid: [153,50,204],
+        darkred:  [139,0,0],
+        darksalmon: [233,150,122],
+        darkseagreen: [143,188,143],
+        darkslateblue:  [72,61,139],
+        darkslategray:  [47,79,79],
+        darkslategrey:  [47,79,79],
+        darkturquoise:  [0,206,209],
+        darkviolet: [148,0,211],
+        deeppink: [255,20,147],
+        deepskyblue:  [0,191,255],
+        dimgray:  [105,105,105],
+        dimgrey:  [105,105,105],
+        dodgerblue: [30,144,255],
+        firebrick:  [178,34,34],
+        floralwhite:  [255,250,240],
+        forestgreen:  [34,139,34],
+        fuchsia:  [255,0,255],
+        gainsboro:  [220,220,220],
+        ghostwhite: [248,248,255],
+        gold: [255,215,0],
+        goldenrod:  [218,165,32],
+        gray: [128,128,128],
+        green:  [0,128,0],
+        greenyellow:  [173,255,47],
+        grey: [128,128,128],
+        honeydew: [240,255,240],
+        hotpink:  [255,105,180],
+        indianred:  [205,92,92],
+        indigo: [75,0,130],
+        ivory:  [255,255,240],
+        khaki:  [240,230,140],
+        lavender: [230,230,250],
+        lavenderblush:  [255,240,245],
+        lawngreen:  [124,252,0],
+        lemonchiffon: [255,250,205],
+        lightblue:  [173,216,230],
+        lightcoral: [240,128,128],
+        lightcyan:  [224,255,255],
+        lightgoldenrodyellow: [250,250,210],
+        lightgray:  [211,211,211],
+        lightgreen: [144,238,144],
+        lightgrey:  [211,211,211],
+        lightpink:  [255,182,193],
+        lightsalmon:  [255,160,122],
+        lightseagreen:  [32,178,170],
+        lightskyblue: [135,206,250],
+        lightslategray: [119,136,153],
+        lightslategrey: [119,136,153],
+        lightsteelblue: [176,196,222],
+        lightyellow:  [255,255,224],
+        lime: [0,255,0],
+        limegreen:  [50,205,50],
+        linen:  [250,240,230],
+        magenta:  [255,0,255],
+        maroon: [128,0,0],
+        mediumaquamarine: [102,205,170],
+        mediumblue: [0,0,205],
+        mediumorchid: [186,85,211],
+        mediumpurple: [147,112,219],
+        mediumseagreen: [60,179,113],
+        mediumslateblue:  [123,104,238],
+        mediumspringgreen:  [0,250,154],
+        mediumturquoise:  [72,209,204],
+        mediumvioletred:  [199,21,133],
+        midnightblue: [25,25,112],
+        mintcream:  [245,255,250],
+        mistyrose:  [255,228,225],
+        moccasin: [255,228,181],
+        navajowhite:  [255,222,173],
+        navy: [0,0,128],
+        oldlace:  [253,245,230],
+        olive:  [128,128,0],
+        olivedrab:  [107,142,35],
+        orange: [255,165,0],
+        orangered:  [255,69,0],
+        orchid: [218,112,214],
+        palegoldenrod:  [238,232,170],
+        palegreen:  [152,251,152],
+        paleturquoise:  [175,238,238],
+        palevioletred:  [219,112,147],
+        papayawhip: [255,239,213],
+        peachpuff:  [255,218,185],
+        peru: [205,133,63],
+        pink: [255,192,203],
+        plum: [221,160,221],
+        powderblue: [176,224,230],
+        purple: [128,0,128],
+        rebeccapurple: [102, 51, 153],
+        red:  [255,0,0],
+        rosybrown:  [188,143,143],
+        royalblue:  [65,105,225],
+        saddlebrown:  [139,69,19],
+        salmon: [250,128,114],
+        sandybrown: [244,164,96],
+        seagreen: [46,139,87],
+        seashell: [255,245,238],
+        sienna: [160,82,45],
+        silver: [192,192,192],
+        skyblue:  [135,206,235],
+        slateblue:  [106,90,205],
+        slategray:  [112,128,144],
+        slategrey:  [112,128,144],
+        snow: [255,250,250],
+        springgreen:  [0,255,127],
+        steelblue:  [70,130,180],
+        tan:  [210,180,140],
+        teal: [0,128,128],
+        thistle:  [216,191,216],
+        tomato: [255,99,71],
+        turquoise:  [64,224,208],
+        violet: [238,130,238],
+        wheat:  [245,222,179],
+        white:  [255,255,255],
+        whitesmoke: [245,245,245],
+        yellow: [255,255,0],
+        yellowgreen:  [154,205,50]
+    };
 
-var reverseKeywords = {};
-for (var key in cssKeywords) {
-  reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
-}
+    var reverseKeywords = {};
+    for (var key in cssKeywords) {
+        reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
+    }
 
 },{}],5:[function(require,module,exports){
-var conversions = require(4);
+    var conversions = require(4);
 
-var convert = function() {
-   return new Converter();
-}
-
-for (var func in conversions) {
-  // export Raw versions
-  convert[func + "Raw"] =  (function(func) {
-    // accept array or plain args
-    return function(arg) {
-      if (typeof arg == "number")
-        arg = Array.prototype.slice.call(arguments);
-      return conversions[func](arg);
+    var convert = function() {
+        return new Converter();
     }
-  })(func);
 
-  var pair = /(\w+)2(\w+)/.exec(func),
-      from = pair[1],
-      to = pair[2];
+    for (var func in conversions) {
+        // export Raw versions
+        convert[func + "Raw"] =  (function(func) {
+            // accept array or plain args
+            return function(arg) {
+                if (typeof arg == "number")
+                    arg = Array.prototype.slice.call(arguments);
+                return conversions[func](arg);
+            }
+        })(func);
 
-  // export rgb2hsl and ["rgb"]["hsl"]
-  convert[from] = convert[from] || {};
+        var pair = /(\w+)2(\w+)/.exec(func),
+            from = pair[1],
+            to = pair[2];
 
-  convert[from][to] = convert[func] = (function(func) { 
-    return function(arg) {
-      if (typeof arg == "number")
-        arg = Array.prototype.slice.call(arguments);
-      
-      var val = conversions[func](arg);
-      if (typeof val == "string" || val === undefined)
-        return val; // keyword
+        // export rgb2hsl and ["rgb"]["hsl"]
+        convert[from] = convert[from] || {};
 
-      for (var i = 0; i < val.length; i++)
-        val[i] = Math.round(val[i]);
-      return val;
+        convert[from][to] = convert[func] = (function(func) {
+            return function(arg) {
+                if (typeof arg == "number")
+                    arg = Array.prototype.slice.call(arguments);
+
+                var val = conversions[func](arg);
+                if (typeof val == "string" || val === undefined)
+                    return val; // keyword
+
+                for (var i = 0; i < val.length; i++)
+                    val[i] = Math.round(val[i]);
+                return val;
+            }
+        })(func);
     }
-  })(func);
-}
 
 
-/* Converter does lazy conversion and caching */
-var Converter = function() {
-   this.convs = {};
-};
+    /* Converter does lazy conversion and caching */
+    var Converter = function() {
+        this.convs = {};
+    };
 
-/* Either get the values for a space or
-  set the values for a space, depending on args */
-Converter.prototype.routeSpace = function(space, args) {
-   var values = args[0];
-   if (values === undefined) {
-      // color.rgb()
-      return this.getValues(space);
-   }
-   // color.rgb(10, 10, 10)
-   if (typeof values == "number") {
-      values = Array.prototype.slice.call(args);        
-   }
+    /* Either get the values for a space or
+     set the values for a space, depending on args */
+    Converter.prototype.routeSpace = function(space, args) {
+        var values = args[0];
+        if (values === undefined) {
+            // color.rgb()
+            return this.getValues(space);
+        }
+        // color.rgb(10, 10, 10)
+        if (typeof values == "number") {
+            values = Array.prototype.slice.call(args);
+        }
 
-   return this.setValues(space, values);
-};
-  
-/* Set the values for a space, invalidating cache */
-Converter.prototype.setValues = function(space, values) {
-   this.space = space;
-   this.convs = {};
-   this.convs[space] = values;
-   return this;
-};
+        return this.setValues(space, values);
+    };
 
-/* Get the values for a space. If there's already
-  a conversion for the space, fetch it, otherwise
-  compute it */
-Converter.prototype.getValues = function(space) {
-   var vals = this.convs[space];
-   if (!vals) {
-      var fspace = this.space,
-          from = this.convs[fspace];
-      vals = convert[fspace][space](from);
+    /* Set the values for a space, invalidating cache */
+    Converter.prototype.setValues = function(space, values) {
+        this.space = space;
+        this.convs = {};
+        this.convs[space] = values;
+        return this;
+    };
 
-      this.convs[space] = vals;
-   }
-  return vals;
-};
+    /* Get the values for a space. If there's already
+     a conversion for the space, fetch it, otherwise
+     compute it */
+    Converter.prototype.getValues = function(space) {
+        var vals = this.convs[space];
+        if (!vals) {
+            var fspace = this.space,
+                from = this.convs[fspace];
+            vals = convert[fspace][space](from);
 
-["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
-   Converter.prototype[space] = function(vals) {
-      return this.routeSpace(space, arguments);
-   }
-});
+            this.convs[space] = vals;
+        }
+        return vals;
+    };
 
-module.exports = convert;
+    ["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
+        Converter.prototype[space] = function(vals) {
+            return this.routeSpace(space, arguments);
+        }
+    });
+
+    module.exports = convert;
 },{"4":4}],6:[function(require,module,exports){
-module.exports = {
-	"aliceblue": [240, 248, 255],
-	"antiquewhite": [250, 235, 215],
-	"aqua": [0, 255, 255],
-	"aquamarine": [127, 255, 212],
-	"azure": [240, 255, 255],
-	"beige": [245, 245, 220],
-	"bisque": [255, 228, 196],
-	"black": [0, 0, 0],
-	"blanchedalmond": [255, 235, 205],
-	"blue": [0, 0, 255],
-	"blueviolet": [138, 43, 226],
-	"brown": [165, 42, 42],
-	"burlywood": [222, 184, 135],
-	"cadetblue": [95, 158, 160],
-	"chartreuse": [127, 255, 0],
-	"chocolate": [210, 105, 30],
-	"coral": [255, 127, 80],
-	"cornflowerblue": [100, 149, 237],
-	"cornsilk": [255, 248, 220],
-	"crimson": [220, 20, 60],
-	"cyan": [0, 255, 255],
-	"darkblue": [0, 0, 139],
-	"darkcyan": [0, 139, 139],
-	"darkgoldenrod": [184, 134, 11],
-	"darkgray": [169, 169, 169],
-	"darkgreen": [0, 100, 0],
-	"darkgrey": [169, 169, 169],
-	"darkkhaki": [189, 183, 107],
-	"darkmagenta": [139, 0, 139],
-	"darkolivegreen": [85, 107, 47],
-	"darkorange": [255, 140, 0],
-	"darkorchid": [153, 50, 204],
-	"darkred": [139, 0, 0],
-	"darksalmon": [233, 150, 122],
-	"darkseagreen": [143, 188, 143],
-	"darkslateblue": [72, 61, 139],
-	"darkslategray": [47, 79, 79],
-	"darkslategrey": [47, 79, 79],
-	"darkturquoise": [0, 206, 209],
-	"darkviolet": [148, 0, 211],
-	"deeppink": [255, 20, 147],
-	"deepskyblue": [0, 191, 255],
-	"dimgray": [105, 105, 105],
-	"dimgrey": [105, 105, 105],
-	"dodgerblue": [30, 144, 255],
-	"firebrick": [178, 34, 34],
-	"floralwhite": [255, 250, 240],
-	"forestgreen": [34, 139, 34],
-	"fuchsia": [255, 0, 255],
-	"gainsboro": [220, 220, 220],
-	"ghostwhite": [248, 248, 255],
-	"gold": [255, 215, 0],
-	"goldenrod": [218, 165, 32],
-	"gray": [128, 128, 128],
-	"green": [0, 128, 0],
-	"greenyellow": [173, 255, 47],
-	"grey": [128, 128, 128],
-	"honeydew": [240, 255, 240],
-	"hotpink": [255, 105, 180],
-	"indianred": [205, 92, 92],
-	"indigo": [75, 0, 130],
-	"ivory": [255, 255, 240],
-	"khaki": [240, 230, 140],
-	"lavender": [230, 230, 250],
-	"lavenderblush": [255, 240, 245],
-	"lawngreen": [124, 252, 0],
-	"lemonchiffon": [255, 250, 205],
-	"lightblue": [173, 216, 230],
-	"lightcoral": [240, 128, 128],
-	"lightcyan": [224, 255, 255],
-	"lightgoldenrodyellow": [250, 250, 210],
-	"lightgray": [211, 211, 211],
-	"lightgreen": [144, 238, 144],
-	"lightgrey": [211, 211, 211],
-	"lightpink": [255, 182, 193],
-	"lightsalmon": [255, 160, 122],
-	"lightseagreen": [32, 178, 170],
-	"lightskyblue": [135, 206, 250],
-	"lightslategray": [119, 136, 153],
-	"lightslategrey": [119, 136, 153],
-	"lightsteelblue": [176, 196, 222],
-	"lightyellow": [255, 255, 224],
-	"lime": [0, 255, 0],
-	"limegreen": [50, 205, 50],
-	"linen": [250, 240, 230],
-	"magenta": [255, 0, 255],
-	"maroon": [128, 0, 0],
-	"mediumaquamarine": [102, 205, 170],
-	"mediumblue": [0, 0, 205],
-	"mediumorchid": [186, 85, 211],
-	"mediumpurple": [147, 112, 219],
-	"mediumseagreen": [60, 179, 113],
-	"mediumslateblue": [123, 104, 238],
-	"mediumspringgreen": [0, 250, 154],
-	"mediumturquoise": [72, 209, 204],
-	"mediumvioletred": [199, 21, 133],
-	"midnightblue": [25, 25, 112],
-	"mintcream": [245, 255, 250],
-	"mistyrose": [255, 228, 225],
-	"moccasin": [255, 228, 181],
-	"navajowhite": [255, 222, 173],
-	"navy": [0, 0, 128],
-	"oldlace": [253, 245, 230],
-	"olive": [128, 128, 0],
-	"olivedrab": [107, 142, 35],
-	"orange": [255, 165, 0],
-	"orangered": [255, 69, 0],
-	"orchid": [218, 112, 214],
-	"palegoldenrod": [238, 232, 170],
-	"palegreen": [152, 251, 152],
-	"paleturquoise": [175, 238, 238],
-	"palevioletred": [219, 112, 147],
-	"papayawhip": [255, 239, 213],
-	"peachpuff": [255, 218, 185],
-	"peru": [205, 133, 63],
-	"pink": [255, 192, 203],
-	"plum": [221, 160, 221],
-	"powderblue": [176, 224, 230],
-	"purple": [128, 0, 128],
-	"rebeccapurple": [102, 51, 153],
-	"red": [255, 0, 0],
-	"rosybrown": [188, 143, 143],
-	"royalblue": [65, 105, 225],
-	"saddlebrown": [139, 69, 19],
-	"salmon": [250, 128, 114],
-	"sandybrown": [244, 164, 96],
-	"seagreen": [46, 139, 87],
-	"seashell": [255, 245, 238],
-	"sienna": [160, 82, 45],
-	"silver": [192, 192, 192],
-	"skyblue": [135, 206, 235],
-	"slateblue": [106, 90, 205],
-	"slategray": [112, 128, 144],
-	"slategrey": [112, 128, 144],
-	"snow": [255, 250, 250],
-	"springgreen": [0, 255, 127],
-	"steelblue": [70, 130, 180],
-	"tan": [210, 180, 140],
-	"teal": [0, 128, 128],
-	"thistle": [216, 191, 216],
-	"tomato": [255, 99, 71],
-	"turquoise": [64, 224, 208],
-	"violet": [238, 130, 238],
-	"wheat": [245, 222, 179],
-	"white": [255, 255, 255],
-	"whitesmoke": [245, 245, 245],
-	"yellow": [255, 255, 0],
-	"yellowgreen": [154, 205, 50]
-};
+    module.exports = {
+        "aliceblue": [240, 248, 255],
+        "antiquewhite": [250, 235, 215],
+        "aqua": [0, 255, 255],
+        "aquamarine": [127, 255, 212],
+        "azure": [240, 255, 255],
+        "beige": [245, 245, 220],
+        "bisque": [255, 228, 196],
+        "black": [0, 0, 0],
+        "blanchedalmond": [255, 235, 205],
+        "blue": [0, 0, 255],
+        "blueviolet": [138, 43, 226],
+        "brown": [165, 42, 42],
+        "burlywood": [222, 184, 135],
+        "cadetblue": [95, 158, 160],
+        "chartreuse": [127, 255, 0],
+        "chocolate": [210, 105, 30],
+        "coral": [255, 127, 80],
+        "cornflowerblue": [100, 149, 237],
+        "cornsilk": [255, 248, 220],
+        "crimson": [220, 20, 60],
+        "cyan": [0, 255, 255],
+        "darkblue": [0, 0, 139],
+        "darkcyan": [0, 139, 139],
+        "darkgoldenrod": [184, 134, 11],
+        "darkgray": [169, 169, 169],
+        "darkgreen": [0, 100, 0],
+        "darkgrey": [169, 169, 169],
+        "darkkhaki": [189, 183, 107],
+        "darkmagenta": [139, 0, 139],
+        "darkolivegreen": [85, 107, 47],
+        "darkorange": [255, 140, 0],
+        "darkorchid": [153, 50, 204],
+        "darkred": [139, 0, 0],
+        "darksalmon": [233, 150, 122],
+        "darkseagreen": [143, 188, 143],
+        "darkslateblue": [72, 61, 139],
+        "darkslategray": [47, 79, 79],
+        "darkslategrey": [47, 79, 79],
+        "darkturquoise": [0, 206, 209],
+        "darkviolet": [148, 0, 211],
+        "deeppink": [255, 20, 147],
+        "deepskyblue": [0, 191, 255],
+        "dimgray": [105, 105, 105],
+        "dimgrey": [105, 105, 105],
+        "dodgerblue": [30, 144, 255],
+        "firebrick": [178, 34, 34],
+        "floralwhite": [255, 250, 240],
+        "forestgreen": [34, 139, 34],
+        "fuchsia": [255, 0, 255],
+        "gainsboro": [220, 220, 220],
+        "ghostwhite": [248, 248, 255],
+        "gold": [255, 215, 0],
+        "goldenrod": [218, 165, 32],
+        "gray": [128, 128, 128],
+        "green": [0, 128, 0],
+        "greenyellow": [173, 255, 47],
+        "grey": [128, 128, 128],
+        "honeydew": [240, 255, 240],
+        "hotpink": [255, 105, 180],
+        "indianred": [205, 92, 92],
+        "indigo": [75, 0, 130],
+        "ivory": [255, 255, 240],
+        "khaki": [240, 230, 140],
+        "lavender": [230, 230, 250],
+        "lavenderblush": [255, 240, 245],
+        "lawngreen": [124, 252, 0],
+        "lemonchiffon": [255, 250, 205],
+        "lightblue": [173, 216, 230],
+        "lightcoral": [240, 128, 128],
+        "lightcyan": [224, 255, 255],
+        "lightgoldenrodyellow": [250, 250, 210],
+        "lightgray": [211, 211, 211],
+        "lightgreen": [144, 238, 144],
+        "lightgrey": [211, 211, 211],
+        "lightpink": [255, 182, 193],
+        "lightsalmon": [255, 160, 122],
+        "lightseagreen": [32, 178, 170],
+        "lightskyblue": [135, 206, 250],
+        "lightslategray": [119, 136, 153],
+        "lightslategrey": [119, 136, 153],
+        "lightsteelblue": [176, 196, 222],
+        "lightyellow": [255, 255, 224],
+        "lime": [0, 255, 0],
+        "limegreen": [50, 205, 50],
+        "linen": [250, 240, 230],
+        "magenta": [255, 0, 255],
+        "maroon": [128, 0, 0],
+        "mediumaquamarine": [102, 205, 170],
+        "mediumblue": [0, 0, 205],
+        "mediumorchid": [186, 85, 211],
+        "mediumpurple": [147, 112, 219],
+        "mediumseagreen": [60, 179, 113],
+        "mediumslateblue": [123, 104, 238],
+        "mediumspringgreen": [0, 250, 154],
+        "mediumturquoise": [72, 209, 204],
+        "mediumvioletred": [199, 21, 133],
+        "midnightblue": [25, 25, 112],
+        "mintcream": [245, 255, 250],
+        "mistyrose": [255, 228, 225],
+        "moccasin": [255, 228, 181],
+        "navajowhite": [255, 222, 173],
+        "navy": [0, 0, 128],
+        "oldlace": [253, 245, 230],
+        "olive": [128, 128, 0],
+        "olivedrab": [107, 142, 35],
+        "orange": [255, 165, 0],
+        "orangered": [255, 69, 0],
+        "orchid": [218, 112, 214],
+        "palegoldenrod": [238, 232, 170],
+        "palegreen": [152, 251, 152],
+        "paleturquoise": [175, 238, 238],
+        "palevioletred": [219, 112, 147],
+        "papayawhip": [255, 239, 213],
+        "peachpuff": [255, 218, 185],
+        "peru": [205, 133, 63],
+        "pink": [255, 192, 203],
+        "plum": [221, 160, 221],
+        "powderblue": [176, 224, 230],
+        "purple": [128, 0, 128],
+        "rebeccapurple": [102, 51, 153],
+        "red": [255, 0, 0],
+        "rosybrown": [188, 143, 143],
+        "royalblue": [65, 105, 225],
+        "saddlebrown": [139, 69, 19],
+        "salmon": [250, 128, 114],
+        "sandybrown": [244, 164, 96],
+        "seagreen": [46, 139, 87],
+        "seashell": [255, 245, 238],
+        "sienna": [160, 82, 45],
+        "silver": [192, 192, 192],
+        "skyblue": [135, 206, 235],
+        "slateblue": [106, 90, 205],
+        "slategray": [112, 128, 144],
+        "slategrey": [112, 128, 144],
+        "snow": [255, 250, 250],
+        "springgreen": [0, 255, 127],
+        "steelblue": [70, 130, 180],
+        "tan": [210, 180, 140],
+        "teal": [0, 128, 128],
+        "thistle": [216, 191, 216],
+        "tomato": [255, 99, 71],
+        "turquoise": [64, 224, 208],
+        "violet": [238, 130, 238],
+        "wheat": [245, 222, 179],
+        "white": [255, 255, 255],
+        "whitesmoke": [245, 245, 245],
+        "yellow": [255, 255, 0],
+        "yellowgreen": [154, 205, 50]
+    };
 },{}],7:[function(require,module,exports){
-/**
- * @namespace Chart
- */
-var Chart = require(27)();
+    /**
+     * @namespace Chart
+     */
+    var Chart = require(28)();
 
-require(26)(Chart);
-require(22)(Chart);
-require(25)(Chart);
-require(21)(Chart);
-require(23)(Chart);
-require(24)(Chart);
-require(28)(Chart);
-require(32)(Chart);
-require(30)(Chart);
-require(31)(Chart);
-require(33)(Chart);
-require(29)(Chart);
-require(34)(Chart);
+    require(26)(Chart);
+    require(40)(Chart);
+    require(22)(Chart);
+    require(25)(Chart);
+    require(30)(Chart);
+    require(21)(Chart);
+    require(23)(Chart);
+    require(24)(Chart);
+    require(29)(Chart);
+    require(32)(Chart);
+    require(33)(Chart);
+    require(31)(Chart);
+    require(27)(Chart);
+    require(34)(Chart);
 
-require(35)(Chart);
-require(36)(Chart);
-require(37)(Chart);
-require(38)(Chart);
+    require(35)(Chart);
+    require(36)(Chart);
+    require(37)(Chart);
+    require(38)(Chart);
 
-require(41)(Chart);
-require(39)(Chart);
-require(40)(Chart);
-require(42)(Chart);
-require(43)(Chart);
-require(44)(Chart);
+    require(46)(Chart);
+    require(44)(Chart);
+    require(45)(Chart);
+    require(47)(Chart);
+    require(48)(Chart);
+    require(49)(Chart);
 
 // Controllers must be loaded after elements
 // See Chart.core.datasetController.dataElementType
-require(15)(Chart);
-require(16)(Chart);
-require(17)(Chart);
-require(18)(Chart);
-require(19)(Chart);
-require(20)(Chart);
+    require(15)(Chart);
+    require(16)(Chart);
+    require(17)(Chart);
+    require(18)(Chart);
+    require(19)(Chart);
+    require(20)(Chart);
 
-require(8)(Chart);
-require(9)(Chart);
-require(10)(Chart);
-require(11)(Chart);
-require(12)(Chart);
-require(13)(Chart);
-require(14)(Chart);
+    require(8)(Chart);
+    require(9)(Chart);
+    require(10)(Chart);
+    require(11)(Chart);
+    require(12)(Chart);
+    require(13)(Chart);
+    require(14)(Chart);
 
-window.Chart = module.exports = Chart;
+// Loading built-it plugins
+    var plugins = [];
 
-},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"8":8,"9":9}],8:[function(require,module,exports){
-"use strict";
+    plugins.push(
+        require(41)(Chart),
+        require(42)(Chart),
+        require(43)(Chart)
+    );
 
-module.exports = function(Chart) {
+    Chart.plugins.register(plugins);
 
-	Chart.Bar = function(context, config) {
-		config.type = 'bar';
+    module.exports = Chart;
+    if (typeof window !== 'undefined') {
+        window.Chart = Chart;
+    }
 
-		return new Chart(context, config);
-	};
+},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"40":40,"41":41,"42":42,"43":43,"44":44,"45":45,"46":46,"47":47,"48":48,"49":49,"8":8,"9":9}],8:[function(require,module,exports){
+    'use strict';
 
-};
+    module.exports = function(Chart) {
+
+        Chart.Bar = function(context, config) {
+            config.type = 'bar';
+
+            return new Chart(context, config);
+        };
+
+    };
+
 },{}],9:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Bubble = function(context, config) {
-		config.type = 'bubble';
-		return new Chart(context, config);
-	};
+        Chart.Bubble = function(context, config) {
+            config.type = 'bubble';
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],10:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Doughnut = function(context, config) {
-		config.type = 'doughnut';
+        Chart.Doughnut = function(context, config) {
+            config.type = 'doughnut';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],11:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.Line = function(context, config) {
-		config.type = 'line';
+        Chart.Line = function(context, config) {
+            config.type = 'line';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],12:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	Chart.PolarArea = function(context, config) {
-		config.type = 'polarArea';
+        Chart.PolarArea = function(context, config) {
+            config.type = 'polarArea';
 
-		return new Chart(context, config);
-	};
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],13:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
-	
-	Chart.Radar = function(context, config) {
-		config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options);
-		config.type = 'radar';
+    module.exports = function(Chart) {
 
-		return new Chart(context, config);
-	};
+        Chart.Radar = function(context, config) {
+            config.type = 'radar';
 
-};
+            return new Chart(context, config);
+        };
+
+    };
 
 },{}],14:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var defaultConfig = {
-		hover: {
-			mode: 'single'
-		},
+        var defaultConfig = {
+            hover: {
+                mode: 'single'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "linear", // scatter should not use a category axis
-				position: "bottom",
-				id: "x-axis-1" // need an ID so datasets can reference the scale
-			}],
-			yAxes: [{
-				type: "linear",
-				position: "left",
-				id: "y-axis-1"
-			}]
-		},
+            scales: {
+                xAxes: [{
+                    type: 'linear', // scatter should not use a category axis
+                    position: 'bottom',
+                    id: 'x-axis-1' // need an ID so datasets can reference the scale
+                }],
+                yAxes: [{
+                    type: 'linear',
+                    position: 'left',
+                    id: 'y-axis-1'
+                }]
+            },
 
-		tooltips: {
-			callbacks: {
-				title: function() {
-					// Title doesn't make sense for scatter since we format the data as a point
-					return '';
-				},
-				label: function(tooltipItem) {
-					return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
-				}
-			}
-		}
-	};
+            tooltips: {
+                callbacks: {
+                    title: function() {
+                        // Title doesn't make sense for scatter since we format the data as a point
+                        return '';
+                    },
+                    label: function(tooltipItem) {
+                        return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
+                    }
+                }
+            }
+        };
 
-	// Register the default config for this type
-	Chart.defaults.scatter = defaultConfig;
+        // Register the default config for this type
+        Chart.defaults.scatter = defaultConfig;
 
-	// Scatter charts use line controllers
-	Chart.controllers.scatter = Chart.controllers.line;
+        // Scatter charts use line controllers
+        Chart.controllers.scatter = Chart.controllers.line;
 
-	Chart.Scatter = function(context, config) {
-		config.type = 'scatter';
-		return new Chart(context, config);
-	};
+        Chart.Scatter = function(context, config) {
+            config.type = 'scatter';
+            return new Chart(context, config);
+        };
 
-};
+    };
+
 },{}],15:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.bar = {
-		hover: {
-			mode: "label"
-		},
+        Chart.defaults.bar = {
+            hover: {
+                mode: 'label'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "category",
+            scales: {
+                xAxes: [{
+                    type: 'category',
 
-				// Specific to Bar Controller
-				categoryPercentage: 0.8,
-				barPercentage: 0.9,
+                    // Specific to Bar Controller
+                    categoryPercentage: 0.8,
+                    barPercentage: 0.9,
 
-				// grid line settings
-				gridLines: {
-					offsetGridLines: true
-				}
-			}],
-			yAxes: [{
-				type: "linear"
-			}]
-		}
-	};
+                    // grid line settings
+                    gridLines: {
+                        offsetGridLines: true
+                    }
+                }],
+                yAxes: [{
+                    type: 'linear'
+                }]
+            }
+        };
 
-	Chart.controllers.bar = Chart.DatasetController.extend({
+        Chart.controllers.bar = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Rectangle,
+            dataElementType: Chart.elements.Rectangle,
 
-		initialize: function(chart, datasetIndex) {
-			Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
+            initialize: function() {
+                var me = this;
+                var meta;
 
-			// Use this to indicate that this is a bar dataset.
-			this.getMeta().bar = true;
-		},
+                Chart.DatasetController.prototype.initialize.apply(me, arguments);
 
-		// Get the number of datasets that display bars. We use this to correctly calculate the bar width
-		getBarCount: function() {
-			var me = this;
-			var barCount = 0;
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				var meta = me.chart.getDatasetMeta(datasetIndex);
-				if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {
-					++barCount;
-				}
-			}, me);
-			return barCount;
-		},
+                meta = me.getMeta();
+                meta.stack = me.getDataset().stack;
+                meta.bar = true;
+            },
 
-		update: function(reset) {
-			var me = this;
-			helpers.each(me.getMeta().data, function(rectangle, index) {
-				me.updateElement(rectangle, index, reset);
-			}, me);
-		},
+            update: function(reset) {
+                var me = this;
+                var elements = me.getMeta().data;
+                var i, ilen;
 
-		updateElement: function(rectangle, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var scaleBase = yScale.getBasePixel();
-			var rectangleElementOptions = me.chart.options.elements.rectangle;
-			var custom = rectangle.custom || {};
-			var dataset = me.getDataset();
+                me._ruler = me.getRuler();
 
-			helpers.extend(rectangle, {
-				// Utility
-				_xScale: xScale,
-				_yScale: yScale,
-				_datasetIndex: me.index,
-				_index: index,
+                for (i = 0, ilen = elements.length; i < ilen; ++i) {
+                    me.updateElement(elements[i], i, reset);
+                }
+            },
 
-				// Desired view properties
-				_model: {
-					x: me.calculateBarX(index, me.index),
-					y: reset ? scaleBase : me.calculateBarY(index, me.index),
+            updateElement: function(rectangle, index, reset) {
+                var me = this;
+                var chart = me.chart;
+                var meta = me.getMeta();
+                var dataset = me.getDataset();
+                var custom = rectangle.custom || {};
+                var rectangleOptions = chart.options.elements.rectangle;
 
-					// Tooltip
-					label: me.chart.data.labels[index],
-					datasetLabel: dataset.label,
+                rectangle._xScale = me.getScaleForId(meta.xAxisID);
+                rectangle._yScale = me.getScaleForId(meta.yAxisID);
+                rectangle._datasetIndex = me.index;
+                rectangle._index = index;
 
-					// Appearance
-					base: reset ? scaleBase : me.calculateBarBase(me.index, index),
-					width: me.calculateBarWidth(index),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
-					borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
-					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
-				}
-			});
-			rectangle.pivot();
-		},
+                rectangle._model = {
+                    datasetLabel: dataset.label,
+                    label: chart.data.labels[index],
+                    borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,
+                    backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),
+                    borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),
+                    borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)
+                };
 
-		calculateBarBase: function(datasetIndex, index) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var base = 0;
+                me.updateElementGeometry(rectangle, index, reset);
 
-			if (yScale.options.stacked) {
-				var chart = me.chart;
-				var datasets = chart.data.datasets;
-				var value = Number(datasets[datasetIndex].data[index]);
+                rectangle.pivot();
+            },
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var currentDs = datasets[i];
-					var currentDsMeta = chart.getDatasetMeta(i);
-					if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
-						var currentVal = Number(currentDs.data[index]);
-						base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
-					}
-				}
+            /**
+             * @private
+             */
+            updateElementGeometry: function(rectangle, index, reset) {
+                var me = this;
+                var model = rectangle._model;
+                var vscale = me.getValueScale();
+                var base = vscale.getBasePixel();
+                var horizontal = vscale.isHorizontal();
+                var ruler = me._ruler || me.getRuler();
+                var vpixels = me.calculateBarValuePixels(me.index, index);
+                var ipixels = me.calculateBarIndexPixels(me.index, index, ruler);
 
-				return yScale.getPixelForValue(base);
-			}
+                model.horizontal = horizontal;
+                model.base = reset? base : vpixels.base;
+                model.x = horizontal? reset? base : vpixels.head : ipixels.center;
+                model.y = horizontal? ipixels.center : reset? base : vpixels.head;
+                model.height = horizontal? ipixels.size : undefined;
+                model.width = horizontal? undefined : ipixels.size;
+            },
 
-			return yScale.getBasePixel();
-		},
+            /**
+             * @private
+             */
+            getValueScaleId: function() {
+                return this.getMeta().yAxisID;
+            },
 
-		getRuler: function(index) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var datasetCount = me.getBarCount();
+            /**
+             * @private
+             */
+            getIndexScaleId: function() {
+                return this.getMeta().xAxisID;
+            },
 
-			var tickWidth;
+            /**
+             * @private
+             */
+            getValueScale: function() {
+                return this.getScaleForId(this.getValueScaleId());
+            },
 
-			if (xScale.options.type === 'category') {
-				tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);
-			} else {
-				// Average width
-				tickWidth = xScale.width / xScale.ticks.length;
-			}
-			var categoryWidth = tickWidth * xScale.options.categoryPercentage;
-			var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
-			var fullBarWidth = categoryWidth / datasetCount;
+            /**
+             * @private
+             */
+            getIndexScale: function() {
+                return this.getScaleForId(this.getIndexScaleId());
+            },
 
-			if (xScale.ticks.length !== me.chart.data.labels.length) {
-			    var perc = xScale.ticks.length / me.chart.data.labels.length;
-			    fullBarWidth = fullBarWidth * perc;
-			}
+            /**
+             * Returns the effective number of stacks based on groups and bar visibility.
+             * @private
+             */
+            getStackCount: function(last) {
+                var me = this;
+                var chart = me.chart;
+                var scale = me.getIndexScale();
+                var stacked = scale.options.stacked;
+                var ilen = last === undefined? chart.data.datasets.length : last + 1;
+                var stacks = [];
+                var i, meta;
 
-			var barWidth = fullBarWidth * xScale.options.barPercentage;
-			var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
+                for (i = 0; i < ilen; ++i) {
+                    meta = chart.getDatasetMeta(i);
+                    if (meta.bar && chart.isDatasetVisible(i) &&
+                        (stacked === false ||
+                        (stacked === true && stacks.indexOf(meta.stack) === -1) ||
+                        (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
+                        stacks.push(meta.stack);
+                    }
+                }
 
-			return {
-				datasetCount: datasetCount,
-				tickWidth: tickWidth,
-				categoryWidth: categoryWidth,
-				categorySpacing: categorySpacing,
-				fullBarWidth: fullBarWidth,
-				barWidth: barWidth,
-				barSpacing: barSpacing
-			};
-		},
+                return stacks.length;
+            },
 
-		calculateBarWidth: function(index) {
-			var xScale = this.getScaleForId(this.getMeta().xAxisID);
-			if (xScale.options.barThickness) {
-				return xScale.options.barThickness;
-			}
-			var ruler = this.getRuler(index);
-			return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
-		},
+            /**
+             * Returns the stack index for the given dataset based on groups and bar visibility.
+             * @private
+             */
+            getStackIndex: function(datasetIndex) {
+                return this.getStackCount(datasetIndex) - 1;
+            },
 
-		// Get bar index from the given dataset index accounting for the fact that not all bars are visible
-		getBarIndex: function(datasetIndex) {
-			var barIndex = 0;
-			var meta, j;
+            /**
+             * @private
+             */
+            getRuler: function() {
+                var me = this;
+                var scale = me.getIndexScale();
+                var options = scale.options;
+                var stackCount = me.getStackCount();
+                var fullSize = scale.isHorizontal()? scale.width : scale.height;
+                var tickSize = fullSize / scale.ticks.length;
+                var categorySize = tickSize * options.categoryPercentage;
+                var fullBarSize = categorySize / stackCount;
+                var barSize = fullBarSize * options.barPercentage;
 
-			for (j = 0; j < datasetIndex; ++j) {
-				meta = this.chart.getDatasetMeta(j);
-				if (meta.bar && this.chart.isDatasetVisible(j)) {
-					++barIndex;
-				}
-			}
+                barSize = Math.min(
+                    helpers.getValueOrDefault(options.barThickness, barSize),
+                    helpers.getValueOrDefault(options.maxBarThickness, Infinity));
 
-			return barIndex;
-		},
+                return {
+                    stackCount: stackCount,
+                    tickSize: tickSize,
+                    categorySize: categorySize,
+                    categorySpacing: tickSize - categorySize,
+                    fullBarSize: fullBarSize,
+                    barSize: barSize,
+                    barSpacing: fullBarSize - barSize,
+                    scale: scale
+                };
+            },
 
-		calculateBarX: function(index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var barIndex = me.getBarIndex(datasetIndex);
+            /**
+             * Note: pixel values are not clamped to the scale area.
+             * @private
+             */
+            calculateBarValuePixels: function(datasetIndex, index) {
+                var me = this;
+                var chart = me.chart;
+                var meta = me.getMeta();
+                var scale = me.getValueScale();
+                var datasets = chart.data.datasets;
+                var value = Number(datasets[datasetIndex].data[index]);
+                var stacked = scale.options.stacked;
+                var stack = meta.stack;
+                var start = 0;
+                var i, imeta, ivalue, base, head, size;
 
-			var ruler = me.getRuler(index);
-			var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
-			leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;
+                if (stacked || (stacked === undefined && stack !== undefined)) {
+                    for (i = 0; i < datasetIndex; ++i) {
+                        imeta = chart.getDatasetMeta(i);
 
-			if (xScale.options.stacked) {
-				return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
-			}
+                        if (imeta.bar &&
+                            imeta.stack === stack &&
+                            imeta.controller.getValueScaleId() === scale.id &&
+                            chart.isDatasetVisible(i)) {
 
-			return leftTick +
-				(ruler.barWidth / 2) +
-				ruler.categorySpacing +
-				(ruler.barWidth * barIndex) +
-				(ruler.barSpacing / 2) +
-				(ruler.barSpacing * barIndex);
-		},
+                            ivalue = Number(datasets[i].data[index]);
+                            if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
+                                start += ivalue;
+                            }
+                        }
+                    }
+                }
 
-		calculateBarY: function(index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var value = Number(me.getDataset().data[index]);
+                base = scale.getPixelForValue(start);
+                head = scale.getPixelForValue(start + value);
+                size = (head - base) / 2;
 
-			if (yScale.options.stacked) {
+                return {
+                    size: size,
+                    base: base,
+                    head: head,
+                    center: head + size / 2
+                };
+            },
 
-				var sumPos = 0,
-					sumNeg = 0;
+            /**
+             * @private
+             */
+            calculateBarIndexPixels: function(datasetIndex, index, ruler) {
+                var me = this;
+                var scale = ruler.scale;
+                var isCombo = me.chart.isCombo;
+                var stackIndex = me.getStackIndex(datasetIndex);
+                var base = scale.getPixelForValue(null, index, datasetIndex, isCombo);
+                var size = ruler.barSize;
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var ds = me.chart.data.datasets[i];
-					var dsMeta = me.chart.getDatasetMeta(i);
-					if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {
-						var stackedVal = Number(ds.data[index]);
-						if (stackedVal < 0) {
-							sumNeg += stackedVal || 0;
-						} else {
-							sumPos += stackedVal || 0;
-						}
-					}
-				}
+                base -= isCombo? ruler.tickSize / 2 : 0;
+                base += ruler.fullBarSize * stackIndex;
+                base += ruler.categorySpacing / 2;
+                base += ruler.barSpacing / 2;
 
-				if (value < 0) {
-					return yScale.getPixelForValue(sumNeg + value);
-				} else {
-					return yScale.getPixelForValue(sumPos + value);
-				}
-			}
-
-			return yScale.getPixelForValue(value);
-		},
-
-		draw: function(ease) {
-			var me = this;
-			var easingDecimal = ease || 1;
-			helpers.each(me.getMeta().data, function(rectangle, index) {
-				var d = me.getDataset().data[index];
-				if (d !== null && d !== undefined && !isNaN(d)) {
-					rectangle.transition(easingDecimal).draw();
-				}
-			}, me);
-		},
-
-		setHoverStyle: function(rectangle) {
-			var dataset = this.chart.data.datasets[rectangle._datasetIndex];
-			var index = rectangle._index;
-
-			var custom = rectangle.custom || {};
-			var model = rectangle._model;
-			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
-		},
-
-		removeHoverStyle: function(rectangle) {
-			var dataset = this.chart.data.datasets[rectangle._datasetIndex];
-			var index = rectangle._index;
-			var custom = rectangle.custom || {};
-			var model = rectangle._model;
-			var rectangleElementOptions = this.chart.options.elements.rectangle;
-
-			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
-			model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
-			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
-		}
-
-	});
-
-
-	// including horizontalBar in the bar file, instead of a file of its own
-	// it extends bar (like pie extends doughnut)
-	Chart.defaults.horizontalBar = {
-		hover: {
-			mode: "label"
-		},
-
-		scales: {
-			xAxes: [{
-				type: "linear",
-				position: "bottom"
-			}],
-			yAxes: [{
-				position: "left",
-				type: "category",
-
-				// Specific to Horizontal Bar Controller
-				categoryPercentage: 0.8,
-				barPercentage: 0.9,
-
-				// grid line settings
-				gridLines: {
-					offsetGridLines: true
-				}
-			}]
-		},
-		elements: {
-			rectangle: {
-				borderSkipped: 'left'
-			}
-		},
-		tooltips: {
-			callbacks: {
-				title: function(tooltipItems, data) {
-					// Pick first xLabel for now
-					var title = '';
-
-					if (tooltipItems.length > 0) {
-						if (tooltipItems[0].yLabel) {
-							title = tooltipItems[0].yLabel;
-						} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {
-							title = data.labels[tooltipItems[0].index];
-						}
-					}
-
-					return title;
-				},
-				label: function(tooltipItem, data) {
-					var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-				return datasetLabel + ': ' + tooltipItem.xLabel;
-				}
-			}
-		}
-	};
-
-	Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
-		updateElement: function(rectangle, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var scaleBase = xScale.getBasePixel();
-			var custom = rectangle.custom || {};
-			var dataset = me.getDataset();
-			var rectangleElementOptions = me.chart.options.elements.rectangle;
-
-			helpers.extend(rectangle, {
-				// Utility
-				_xScale: xScale,
-				_yScale: yScale,
-				_datasetIndex: me.index,
-				_index: index,
-
-				// Desired view properties
-				_model: {
-					x: reset ? scaleBase : me.calculateBarX(index, me.index),
-					y: me.calculateBarY(index, me.index),
-
-					// Tooltip
-					label: me.chart.data.labels[index],
-					datasetLabel: dataset.label,
-
-					// Appearance
-					base: reset ? scaleBase : me.calculateBarBase(me.index, index),
-					height: me.calculateBarHeight(index),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
-					borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
-					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
-				},
-
-				draw: function () {
-					var ctx = this._chart.ctx;
-					var vm = this._view;
-
-					var halfHeight = vm.height / 2,
-						topY = vm.y - halfHeight,
-						bottomY = vm.y + halfHeight,
-						right = vm.base - (vm.base - vm.x),
-						halfStroke = vm.borderWidth / 2;
-
-					// 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 (vm.borderWidth) {
-						topY += halfStroke;
-						bottomY -= halfStroke;
-						right += halfStroke;
-					}
-
-					ctx.beginPath();
-
-					ctx.fillStyle = vm.backgroundColor;
-					ctx.strokeStyle = vm.borderColor;
-					ctx.lineWidth = vm.borderWidth;
-
-					// Corner points, from bottom-left to bottom-right clockwise
-					// | 1 2 |
-					// | 0 3 |
-					var corners = [
-						[vm.base, bottomY],
-						[vm.base, topY],
-						[right, topY],
-						[right, bottomY]
-					];
-
-					// Find first (starting) corner with fallback to 'bottom'
-					var borders = ['bottom', 'left', 'top', 'right'];
-					var startCorner = borders.indexOf(vm.borderSkipped, 0);
-					if (startCorner === -1)
-						startCorner = 0;
-
-					function cornerAt(index) {
-						return corners[(startCorner + index) % 4];
-					}
-
-					// Draw rectangle from 'startCorner'
-					ctx.moveTo.apply(ctx, cornerAt(0));
-					for (var i = 1; i < 4; i++)
-						ctx.lineTo.apply(ctx, cornerAt(i));
-
-					ctx.fill();
-					if (vm.borderWidth) {
-						ctx.stroke();
-					}
-				},
-
-				inRange: function (mouseX, mouseY) {
-					var vm = this._view;
-					var inRange = false;
-
-					if (vm) {
-						if (vm.x < vm.base) {
-							inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);
-						} else {
-							inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);
-						}
-					}
-
-					return inRange;
-				}
-			});
-
-			rectangle.pivot();
-		},
-
-		calculateBarBase: function (datasetIndex, index) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var base = 0;
-
-			if (xScale.options.stacked) {
-				var chart = me.chart;
-				var datasets = chart.data.datasets;
-				var value = Number(datasets[datasetIndex].data[index]);
-
-				for (var i = 0; i < datasetIndex; i++) {
-					var currentDs = datasets[i];
-					var currentDsMeta = chart.getDatasetMeta(i);
-					if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i)) {
-						var currentVal = Number(currentDs.data[index]);
-						base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
-					}
-				}
-
-				return xScale.getPixelForValue(base);
-			}
+                return {
+                    size: size,
+                    base: base,
+                    head: base + size,
+                    center: base + size / 2
+                };
+            },
 
-			return xScale.getBasePixel();
-		},
+            draw: function() {
+                var me = this;
+                var chart = me.chart;
+                var elements = me.getMeta().data;
+                var dataset = me.getDataset();
+                var ilen = elements.length;
+                var i = 0;
+                var d;
 
-		getRuler: function (index) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var datasetCount = me.getBarCount();
+                helpers.canvas.clipArea(chart.ctx, chart.chartArea);
 
-			var tickHeight;
-			if (yScale.options.type === 'category') {
-				tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index);
-			} else {
-				// Average width
-				tickHeight = yScale.width / yScale.ticks.length;
-			}
-			var categoryHeight = tickHeight * yScale.options.categoryPercentage;
-			var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;
-			var fullBarHeight = categoryHeight / datasetCount;
+                for (; i<ilen; ++i) {
+                    d = dataset.data[i];
+                    if (d !== null && d !== undefined && !isNaN(d)) {
+                        elements[i].draw();
+                    }
+                }
 
-			if (yScale.ticks.length !== me.chart.data.labels.length) {
-				var perc = yScale.ticks.length / me.chart.data.labels.length;
-				fullBarHeight = fullBarHeight * perc;
-			}
+                helpers.canvas.unclipArea(chart.ctx);
+            },
 
-			var barHeight = fullBarHeight * yScale.options.barPercentage;
-			var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);
+            setHoverStyle: function(rectangle) {
+                var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+                var index = rectangle._index;
+                var custom = rectangle.custom || {};
+                var model = rectangle._model;
 
-			return {
-				datasetCount: datasetCount,
-				tickHeight: tickHeight,
-				categoryHeight: categoryHeight,
-				categorySpacing: categorySpacing,
-				fullBarHeight: fullBarHeight,
-				barHeight: barHeight,
-				barSpacing: barSpacing,
-			};
-		},
+                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+            },
 
-		calculateBarHeight: function (index) {
-			var me = this;
-			var yScale = me.getScaleForId(me.getMeta().yAxisID);
-			if (yScale.options.barThickness) {
-				return yScale.options.barThickness;
-			}
-			var ruler = me.getRuler(index);
-			return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
-		},
+            removeHoverStyle: function(rectangle) {
+                var dataset = this.chart.data.datasets[rectangle._datasetIndex];
+                var index = rectangle._index;
+                var custom = rectangle.custom || {};
+                var model = rectangle._model;
+                var rectangleElementOptions = this.chart.options.elements.rectangle;
 
-		calculateBarX: function (index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var value = Number(me.getDataset().data[index]);
+                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
+                model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
+                model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
+            }
+        });
 
-			if (xScale.options.stacked) {
 
-				var sumPos = 0,
-					sumNeg = 0;
+        // including horizontalBar in the bar file, instead of a file of its own
+        // it extends bar (like pie extends doughnut)
+        Chart.defaults.horizontalBar = {
+            hover: {
+                mode: 'label'
+            },
 
-				for (var i = 0; i < datasetIndex; i++) {
-					var ds = me.chart.data.datasets[i];
-					var dsMeta = me.chart.getDatasetMeta(i);
-					if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {
-						var stackedVal = Number(ds.data[index]);
-						if (stackedVal < 0) {
-							sumNeg += stackedVal || 0;
-						} else {
-							sumPos += stackedVal || 0;
-						}
-					}
-				}
+            scales: {
+                xAxes: [{
+                    type: 'linear',
+                    position: 'bottom'
+                }],
+                yAxes: [{
+                    position: 'left',
+                    type: 'category',
 
-				if (value < 0) {
-					return xScale.getPixelForValue(sumNeg + value);
-				} else {
-					return xScale.getPixelForValue(sumPos + value);
-				}
-			}
+                    // Specific to Horizontal Bar Controller
+                    categoryPercentage: 0.8,
+                    barPercentage: 0.9,
 
-			return xScale.getPixelForValue(value);
-		},
+                    // grid line settings
+                    gridLines: {
+                        offsetGridLines: true
+                    }
+                }]
+            },
+            elements: {
+                rectangle: {
+                    borderSkipped: 'left'
+                }
+            },
+            tooltips: {
+                callbacks: {
+                    title: function(tooltipItems, data) {
+                        // Pick first xLabel for now
+                        var title = '';
 
-		calculateBarY: function (index, datasetIndex) {
-			var me = this;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var barIndex = me.getBarIndex(datasetIndex);
+                        if (tooltipItems.length > 0) {
+                            if (tooltipItems[0].yLabel) {
+                                title = tooltipItems[0].yLabel;
+                            } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {
+                                title = data.labels[tooltipItems[0].index];
+                            }
+                        }
 
-			var ruler = me.getRuler(index);
-			var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
-			topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;
+                        return title;
+                    },
+                    label: function(tooltipItem, data) {
+                        var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
+                        return datasetLabel + ': ' + tooltipItem.xLabel;
+                    }
+                }
+            }
+        };
 
-			if (yScale.options.stacked) {
-				return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;
-			}
+        Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
+            /**
+             * @private
+             */
+            getValueScaleId: function() {
+                return this.getMeta().xAxisID;
+            },
 
-			return topTick +
-				(ruler.barHeight / 2) +
-				ruler.categorySpacing +
-				(ruler.barHeight * barIndex) +
-				(ruler.barSpacing / 2) +
-				(ruler.barSpacing * barIndex);
-		}
-	});
-};
+            /**
+             * @private
+             */
+            getIndexScaleId: function() {
+                return this.getMeta().yAxisID;
+            }
+        });
+    };
 
 },{}],16:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.bubble = {
-		hover: {
-			mode: "single"
-		},
+        Chart.defaults.bubble = {
+            hover: {
+                mode: 'single'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "linear", // bubble should probably use a linear scale by default
-				position: "bottom",
-				id: "x-axis-0" // need an ID so datasets can reference the scale
-			}],
-			yAxes: [{
-				type: "linear",
-				position: "left",
-				id: "y-axis-0"
-			}]
-		},
+            scales: {
+                xAxes: [{
+                    type: 'linear', // bubble should probably use a linear scale by default
+                    position: 'bottom',
+                    id: 'x-axis-0' // need an ID so datasets can reference the scale
+                }],
+                yAxes: [{
+                    type: 'linear',
+                    position: 'left',
+                    id: 'y-axis-0'
+                }]
+            },
 
-		tooltips: {
-			callbacks: {
-				title: function() {
-					// Title doesn't make sense for scatter since we format the data as a point
-					return '';
-				},
-				label: function(tooltipItem, data) {
-					var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-					var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
-					return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';
-				}
-			}
-		}
-	};
+            tooltips: {
+                callbacks: {
+                    title: function() {
+                        // Title doesn't make sense for scatter since we format the data as a point
+                        return '';
+                    },
+                    label: function(tooltipItem, data) {
+                        var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
+                        var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
+                        return datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';
+                    }
+                }
+            }
+        };
 
-	Chart.controllers.bubble = Chart.DatasetController.extend({
+        Chart.controllers.bubble = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		update: function(reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var points = meta.data;
+            update: function(reset) {
+                var me = this;
+                var meta = me.getMeta();
+                var points = meta.data;
 
-			// Update Points
-			helpers.each(points, function(point, index) {
-				me.updateElement(point, index, reset);
-			});
-		},
+                // Update Points
+                helpers.each(points, function(point, index) {
+                    me.updateElement(point, index, reset);
+                });
+            },
 
-		updateElement: function(point, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var yScale = me.getScaleForId(meta.yAxisID);
+            updateElement: function(point, index, reset) {
+                var me = this;
+                var meta = me.getMeta();
+                var xScale = me.getScaleForId(meta.xAxisID);
+                var yScale = me.getScaleForId(meta.yAxisID);
 
-			var custom = point.custom || {};
-			var dataset = me.getDataset();
-			var data = dataset.data[index];
-			var pointElementOptions = me.chart.options.elements.point;
-			var dsIndex = me.index;
+                var custom = point.custom || {};
+                var dataset = me.getDataset();
+                var data = dataset.data[index];
+                var pointElementOptions = me.chart.options.elements.point;
+                var dsIndex = me.index;
 
-			helpers.extend(point, {
-				// Utility
-				_xScale: xScale,
-				_yScale: yScale,
-				_datasetIndex: dsIndex,
-				_index: index,
+                helpers.extend(point, {
+                    // Utility
+                    _xScale: xScale,
+                    _yScale: yScale,
+                    _datasetIndex: dsIndex,
+                    _index: index,
 
-				// Desired view properties
-				_model: {
-					x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),
-					y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),
-					// Appearance
-					radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),
+                    // Desired view properties
+                    _model: {
+                        x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),
+                        y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),
+                        // Appearance
+                        radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),
 
-					// Tooltip
-					hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
-				}
-			});
+                        // Tooltip
+                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
+                    }
+                });
 
-			// Trick to reset the styles of the point
-			Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);
+                // Trick to reset the styles of the point
+                Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);
 
-			var model = point._model;
-			model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));
+                var model = point._model;
+                model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));
 
-			point.pivot();
-		},
+                point.pivot();
+            },
 
-		getRadius: function(value) {
-			return value.r || this.chart.options.elements.point.radius;
-		},
+            getRadius: function(value) {
+                return value.r || this.chart.options.elements.point.radius;
+            },
 
-		setHoverStyle: function(point) {
-			var me = this;
-			Chart.DatasetController.prototype.setHoverStyle.call(me, point);
+            setHoverStyle: function(point) {
+                var me = this;
+                Chart.DatasetController.prototype.setHoverStyle.call(me, point);
 
-			// Radius
-			var dataset = me.chart.data.datasets[point._datasetIndex];
-			var index = point._index;
-			var custom = point.custom || {};
-			var model = point._model;
-			model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);
-		},
+                // Radius
+                var dataset = me.chart.data.datasets[point._datasetIndex];
+                var index = point._index;
+                var custom = point.custom || {};
+                var model = point._model;
+                model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);
+            },
 
-		removeHoverStyle: function(point) {
-			var me = this;
-			Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);
+            removeHoverStyle: function(point) {
+                var me = this;
+                Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);
 
-			var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];
-			var custom = point.custom || {};
-			var model = point._model;
+                var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];
+                var custom = point.custom || {};
+                var model = point._model;
 
-			model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);
-		}
-	});
-};
+                model.radius = custom.radius ? custom.radius : me.getRadius(dataVal);
+            }
+        });
+    };
 
 },{}],17:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers,
-		defaults = Chart.defaults;
+        var helpers = Chart.helpers,
+            defaults = Chart.defaults;
 
-	defaults.doughnut = {
-		animation: {
-			//Boolean - Whether we animate the rotation of the Doughnut
-			animateRotate: true,
-			//Boolean - Whether we animate scaling the Doughnut from the centre
-			animateScale: false
-		},
-		aspectRatio: 1,
-		hover: {
-			mode: 'single'
-		},
-		legendCallback: function(chart) {
-			var text = [];
-			text.push('<ul class="' + chart.id + '-legend">');
+        defaults.doughnut = {
+            animation: {
+                // Boolean - Whether we animate the rotation of the Doughnut
+                animateRotate: true,
+                // Boolean - Whether we animate scaling the Doughnut from the centre
+                animateScale: false
+            },
+            aspectRatio: 1,
+            hover: {
+                mode: 'single'
+            },
+            legendCallback: function(chart) {
+                var text = [];
+                text.push('<ul class="' + chart.id + '-legend">');
 
-			var data = chart.data;
-			var datasets = data.datasets;
-			var labels = data.labels;
+                var data = chart.data;
+                var datasets = data.datasets;
+                var labels = data.labels;
 
-			if (datasets.length) {
-				for (var i = 0; i < datasets[0].data.length; ++i) {
-					text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
-					if (labels[i]) {
-						text.push(labels[i]);
-					}
-					text.push('</li>');
-				}
-			}
+                if (datasets.length) {
+                    for (var i = 0; i < datasets[0].data.length; ++i) {
+                        text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
+                        if (labels[i]) {
+                            text.push(labels[i]);
+                        }
+                        text.push('</li>');
+                    }
+                }
 
-			text.push('</ul>');
-			return text.join("");
-		},
-		legend: {
-			labels: {
-				generateLabels: function(chart) {
-					var data = chart.data;
-					if (data.labels.length && data.datasets.length) {
-						return data.labels.map(function(label, i) {
-							var meta = chart.getDatasetMeta(0);
-							var ds = data.datasets[0];
-							var arc = meta.data[i];
-							var custom = arc && arc.custom || {};
-							var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-							var arcOpts = chart.options.elements.arc;
-							var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
-							var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
-							var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+                text.push('</ul>');
+                return text.join('');
+            },
+            legend: {
+                labels: {
+                    generateLabels: function(chart) {
+                        var data = chart.data;
+                        if (data.labels.length && data.datasets.length) {
+                            return data.labels.map(function(label, i) {
+                                var meta = chart.getDatasetMeta(0);
+                                var ds = data.datasets[0];
+                                var arc = meta.data[i];
+                                var custom = arc && arc.custom || {};
+                                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
+                                var arcOpts = chart.options.elements.arc;
+                                var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+                                var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+                                var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
 
-							return {
-								text: label,
-								fillStyle: fill,
-								strokeStyle: stroke,
-								lineWidth: bw,
-								hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+                                return {
+                                    text: label,
+                                    fillStyle: fill,
+                                    strokeStyle: stroke,
+                                    lineWidth: bw,
+                                    hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
 
-								// Extra data used for toggling the correct item
-								index: i
-							};
-						});
-					} else {
-						return [];
-					}
-				}
-			},
+                                    // Extra data used for toggling the correct item
+                                    index: i
+                                };
+                            });
+                        }
+                        return [];
+                    }
+                },
 
-			onClick: function(e, legendItem) {
-				var index = legendItem.index;
-				var chart = this.chart;
-				var i, ilen, meta;
+                onClick: function(e, legendItem) {
+                    var index = legendItem.index;
+                    var chart = this.chart;
+                    var i, ilen, meta;
 
-				for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-					meta = chart.getDatasetMeta(i);
-					meta.data[index].hidden = !meta.data[index].hidden;
-				}
+                    for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+                        meta = chart.getDatasetMeta(i);
+                        // toggle visibility of index if exists
+                        if (meta.data[index]) {
+                            meta.data[index].hidden = !meta.data[index].hidden;
+                        }
+                    }
 
-				chart.update();
-			}
-		},
+                    chart.update();
+                }
+            },
 
-		//The percentage of the chart that we cut out of the middle.
-		cutoutPercentage: 50,
+            // The percentage of the chart that we cut out of the middle.
+            cutoutPercentage: 50,
 
-		//The rotation of the chart, where the first data arc begins.
-		rotation: Math.PI * -0.5,
+            // The rotation of the chart, where the first data arc begins.
+            rotation: Math.PI * -0.5,
 
-		//The total circumference of the chart.
-		circumference: Math.PI * 2.0,
+            // The total circumference of the chart.
+            circumference: Math.PI * 2.0,
 
-		// Need to override these to give a nice default
-		tooltips: {
-			callbacks: {
-				title: function() {
-					return '';
-				},
-				label: function(tooltipItem, data) {
-					return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
-				}
-			}
-		}
-	};
+            // Need to override these to give a nice default
+            tooltips: {
+                callbacks: {
+                    title: function() {
+                        return '';
+                    },
+                    label: function(tooltipItem, data) {
+                        var dataLabel = data.labels[tooltipItem.index];
+                        var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
 
-	defaults.pie = helpers.clone(defaults.doughnut);
-	helpers.extend(defaults.pie, {
-		cutoutPercentage: 0
-	});
+                        if (helpers.isArray(dataLabel)) {
+                            // show value on first line of multiline label
+                            // need to clone because we are changing the value
+                            dataLabel = dataLabel.slice();
+                            dataLabel[0] += value;
+                        } else {
+                            dataLabel += value;
+                        }
 
-
-	Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
-
-		dataElementType: Chart.elements.Arc,
-
-		linkScales: helpers.noop,
-
-		// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
-		getRingIndex: function(datasetIndex) {
-			var ringIndex = 0;
-
-			for (var j = 0; j < datasetIndex; ++j) {
-				if (this.chart.isDatasetVisible(j)) {
-					++ringIndex;
-				}
-			}
-
-			return ringIndex;
-		},
-
-		update: function(reset) {
-			var me = this;
-			var chart = me.chart,
-				chartArea = chart.chartArea,
-				opts = chart.options,
-				arcOpts = opts.elements.arc,
-				availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,
-				availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,
-				minSize = Math.min(availableWidth, availableHeight),
-				offset = {
-					x: 0,
-					y: 0
-				},
-				meta = me.getMeta(),
-				cutoutPercentage = opts.cutoutPercentage,
-				circumference = opts.circumference;
-
-			// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
-			if (circumference < Math.PI * 2.0) {
-				var startAngle = opts.rotation % (Math.PI * 2.0);
-				startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
-				var endAngle = startAngle + circumference;
-				var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
-				var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
-				var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
-				var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
-				var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
-				var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
-				var cutout = cutoutPercentage / 100.0;
-				var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};
-				var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};
-				var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
-				minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
-				offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
-			}
-            chart.borderWidth = me.getMaxBorderWidth(meta.data);
-
-			chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
-			chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0);
-			chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
-			chart.offsetX = offset.x * chart.outerRadius;
-			chart.offsetY = offset.y * chart.outerRadius;
-
-			meta.total = me.calculateTotal();
-
-			me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
-			me.innerRadius = me.outerRadius - chart.radiusLength;
-
-			helpers.each(meta.data, function(arc, index) {
-				me.updateElement(arc, index, reset);
-			});
-		},
-
-		updateElement: function(arc, index, reset) {
-			var me = this;
-			var chart = me.chart,
-				chartArea = chart.chartArea,
-				opts = chart.options,
-				animationOpts = opts.animation,
-				centerX = (chartArea.left + chartArea.right) / 2,
-				centerY = (chartArea.top + chartArea.bottom) / 2,
-				startAngle = opts.rotation, // non reset case handled later
-				endAngle = opts.rotation, // non reset case handled later
-				dataset = me.getDataset(),
-				circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),
-				innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,
-				outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,
-				valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-
-			helpers.extend(arc, {
-				// Utility
-				_datasetIndex: me.index,
-				_index: index,
-
-				// Desired view properties
-				_model: {
-					x: centerX + chart.offsetX,
-					y: centerY + chart.offsetY,
-					startAngle: startAngle,
-					endAngle: endAngle,
-					circumference: circumference,
-					outerRadius: outerRadius,
-					innerRadius: innerRadius,
-					label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
-				}
-			});
-
-			var model = arc._model;
-			// Resets the visual styles
-			this.removeHoverStyle(arc);
-
-			// Set correct angles if not resetting
-			if (!reset || !animationOpts.animateRotate) {
-				if (index === 0) {
-					model.startAngle = opts.rotation;
-				} else {
-					model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
-				}
-
-				model.endAngle = model.startAngle + model.circumference;
-			}
-
-			arc.pivot();
-		},
-
-		removeHoverStyle: function(arc) {
-			Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
-		},
-
-		calculateTotal: function() {
-			var dataset = this.getDataset();
-			var meta = this.getMeta();
-			var total = 0;
-			var value;
-
-			helpers.each(meta.data, function(element, index) {
-				value = dataset.data[index];
-				if (!isNaN(value) && !element.hidden) {
-					total += Math.abs(value);
-				}
-			});
-
-			/*if (total === 0) {
-				total = NaN;
-			}*/
-
-			return total;
-		},
-
-		calculateCircumference: function(value) {
-			var total = this.getMeta().total;
-			if (total > 0 && !isNaN(value)) {
-				return (Math.PI * 2.0) * (value / total);
-			} else {
-				return 0;
-			}
-		},
-		
-		//gets the max border or hover width to properly scale pie charts
-        getMaxBorderWidth: function (elements) {
-            var max = 0,
-				index = this.index,
-				length = elements.length,
-				borderWidth,
-				hoverWidth;
-
-            for (var i = 0; i < length; i++) {
-               	borderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;
-                hoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
-				
-                max = borderWidth > max ? borderWidth : max;
-                max = hoverWidth > max ? hoverWidth : max;
+                        return dataLabel;
+                    }
+                }
             }
-            return max;
-        }
-	});
-};
+        };
+
+        defaults.pie = helpers.clone(defaults.doughnut);
+        helpers.extend(defaults.pie, {
+            cutoutPercentage: 0
+        });
+
+
+        Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
+
+            dataElementType: Chart.elements.Arc,
+
+            linkScales: helpers.noop,
+
+            // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
+            getRingIndex: function(datasetIndex) {
+                var ringIndex = 0;
+
+                for (var j = 0; j < datasetIndex; ++j) {
+                    if (this.chart.isDatasetVisible(j)) {
+                        ++ringIndex;
+                    }
+                }
+
+                return ringIndex;
+            },
+
+            update: function(reset) {
+                var me = this;
+                var chart = me.chart,
+                    chartArea = chart.chartArea,
+                    opts = chart.options,
+                    arcOpts = opts.elements.arc,
+                    availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,
+                    availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,
+                    minSize = Math.min(availableWidth, availableHeight),
+                    offset = {
+                        x: 0,
+                        y: 0
+                    },
+                    meta = me.getMeta(),
+                    cutoutPercentage = opts.cutoutPercentage,
+                    circumference = opts.circumference;
+
+                // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
+                if (circumference < Math.PI * 2.0) {
+                    var startAngle = opts.rotation % (Math.PI * 2.0);
+                    startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
+                    var endAngle = startAngle + circumference;
+                    var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
+                    var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
+                    var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
+                    var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
+                    var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
+                    var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
+                    var cutout = cutoutPercentage / 100.0;
+                    var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};
+                    var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};
+                    var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
+                    minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
+                    offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
+                }
+
+                chart.borderWidth = me.getMaxBorderWidth(meta.data);
+                chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
+                chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
+                chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+                chart.offsetX = offset.x * chart.outerRadius;
+                chart.offsetY = offset.y * chart.outerRadius;
+
+                meta.total = me.calculateTotal();
+
+                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
+                me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
+
+                helpers.each(meta.data, function(arc, index) {
+                    me.updateElement(arc, index, reset);
+                });
+            },
+
+            updateElement: function(arc, index, reset) {
+                var me = this;
+                var chart = me.chart,
+                    chartArea = chart.chartArea,
+                    opts = chart.options,
+                    animationOpts = opts.animation,
+                    centerX = (chartArea.left + chartArea.right) / 2,
+                    centerY = (chartArea.top + chartArea.bottom) / 2,
+                    startAngle = opts.rotation, // non reset case handled later
+                    endAngle = opts.rotation, // non reset case handled later
+                    dataset = me.getDataset(),
+                    circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),
+                    innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,
+                    outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,
+                    valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
+
+                helpers.extend(arc, {
+                    // Utility
+                    _datasetIndex: me.index,
+                    _index: index,
+
+                    // Desired view properties
+                    _model: {
+                        x: centerX + chart.offsetX,
+                        y: centerY + chart.offsetY,
+                        startAngle: startAngle,
+                        endAngle: endAngle,
+                        circumference: circumference,
+                        outerRadius: outerRadius,
+                        innerRadius: innerRadius,
+                        label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
+                    }
+                });
+
+                var model = arc._model;
+                // Resets the visual styles
+                this.removeHoverStyle(arc);
+
+                // Set correct angles if not resetting
+                if (!reset || !animationOpts.animateRotate) {
+                    if (index === 0) {
+                        model.startAngle = opts.rotation;
+                    } else {
+                        model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
+                    }
+
+                    model.endAngle = model.startAngle + model.circumference;
+                }
+
+                arc.pivot();
+            },
+
+            removeHoverStyle: function(arc) {
+                Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+            },
+
+            calculateTotal: function() {
+                var dataset = this.getDataset();
+                var meta = this.getMeta();
+                var total = 0;
+                var value;
+
+                helpers.each(meta.data, function(element, index) {
+                    value = dataset.data[index];
+                    if (!isNaN(value) && !element.hidden) {
+                        total += Math.abs(value);
+                    }
+                });
+
+                /* if (total === 0) {
+                 total = NaN;
+                 }*/
+
+                return total;
+            },
+
+            calculateCircumference: function(value) {
+                var total = this.getMeta().total;
+                if (total > 0 && !isNaN(value)) {
+                    return (Math.PI * 2.0) * (value / total);
+                }
+                return 0;
+            },
+
+            // gets the max border or hover width to properly scale pie charts
+            getMaxBorderWidth: function(elements) {
+                var max = 0,
+                    index = this.index,
+                    length = elements.length,
+                    borderWidth,
+                    hoverWidth;
+
+                for (var i = 0; i < length; i++) {
+                    borderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;
+                    hoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
+
+                    max = borderWidth > max ? borderWidth : max;
+                    max = hoverWidth > max ? hoverWidth : max;
+                }
+                return max;
+            }
+        });
+    };
 
 },{}],18:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.line = {
-		showLines: true,
-		spanGaps: false,
+        Chart.defaults.line = {
+            showLines: true,
+            spanGaps: false,
 
-		hover: {
-			mode: "label"
-		},
+            hover: {
+                mode: 'label'
+            },
 
-		scales: {
-			xAxes: [{
-				type: "category",
-				id: 'x-axis-0'
-			}],
-			yAxes: [{
-				type: "linear",
-				id: 'y-axis-0'
-			}]
-		}
-	};
+            scales: {
+                xAxes: [{
+                    type: 'category',
+                    id: 'x-axis-0'
+                }],
+                yAxes: [{
+                    type: 'linear',
+                    id: 'y-axis-0'
+                }]
+            }
+        };
 
-	function lineEnabled(dataset, options) {
-		return helpers.getValueOrDefault(dataset.showLine, options.showLines);
-	}
+        function lineEnabled(dataset, options) {
+            return helpers.getValueOrDefault(dataset.showLine, options.showLines);
+        }
 
-	Chart.controllers.line = Chart.DatasetController.extend({
+        Chart.controllers.line = Chart.DatasetController.extend({
 
-		datasetElementType: Chart.elements.Line,
+            datasetElementType: Chart.elements.Line,
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		addElementAndReset: function(index) {
-			var me = this;
-			var options = me.chart.options;
-			var meta = me.getMeta();
+            update: function(reset) {
+                var me = this;
+                var meta = me.getMeta();
+                var line = meta.dataset;
+                var points = meta.data || [];
+                var options = me.chart.options;
+                var lineElementOptions = options.elements.line;
+                var scale = me.getScaleForId(meta.yAxisID);
+                var i, ilen, custom;
+                var dataset = me.getDataset();
+                var showLine = lineEnabled(dataset, options);
 
-			Chart.DatasetController.prototype.addElementAndReset.call(me, index);
+                // Update Line
+                if (showLine) {
+                    custom = line.custom || {};
 
-			// Make sure bezier control points are updated
-			if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {
-				me.updateBezierControlPoints();
-			}
-		},
+                    // Compatibility: If the properties are defined with only the old name, use those values
+                    if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+                        dataset.lineTension = dataset.tension;
+                    }
 
-		update: function(reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var line = meta.dataset;
-			var points = meta.data || [];
-			var options = me.chart.options;
-			var lineElementOptions = options.elements.line;
-			var scale = me.getScaleForId(meta.yAxisID);
-			var i, ilen, custom;
-			var dataset = me.getDataset();
-			var showLine = lineEnabled(dataset, options);
+                    // Utility
+                    line._scale = scale;
+                    line._datasetIndex = me.index;
+                    // Data
+                    line._children = points;
+                    // Model
+                    line._model = {
+                        // Appearance
+                        // The default behavior of lines is to break at null values, according
+                        // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
+                        // This option gives lines the ability to span gaps
+                        spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
+                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
+                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+                        borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+                        borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+                        borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+                        borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+                        borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+                        borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+                        fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+                        steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
+                        cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
+                    };
 
-			// Update Line
-			if (showLine) {
-				custom = line.custom || {};
+                    line.pivot();
+                }
 
-				// Compatibility: If the properties are defined with only the old name, use those values
-				if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
-					dataset.lineTension = dataset.tension;
-				}
+                // Update Points
+                for (i=0, ilen=points.length; i<ilen; ++i) {
+                    me.updateElement(points[i], i, reset);
+                }
 
-				// Utility
-				line._scale = scale;
-				line._datasetIndex = me.index;
-				// Data
-				line._children = points;
-				// Model
-				line._model = {
-					// Appearance
-					// The default behavior of lines is to break at null values, according
-					// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
-					// This option gives linse the ability to span gaps
-					spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
-					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
-					borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
-					borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
-					borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
-					borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
-					borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
-					fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
-					steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
-					// Scale
-					scaleTop: scale.top,
-					scaleBottom: scale.bottom,
-					scaleZero: scale.getBasePixel()
-				};
+                if (showLine && line._model.tension !== 0) {
+                    me.updateBezierControlPoints();
+                }
 
-				line.pivot();
-			}
+                // Now pivot the point for animation
+                for (i=0, ilen=points.length; i<ilen; ++i) {
+                    points[i].pivot();
+                }
+            },
 
-			// Update Points
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				me.updateElement(points[i], i, reset);
-			}
+            getPointBackgroundColor: function(point, index) {
+                var backgroundColor = this.chart.options.elements.point.backgroundColor;
+                var dataset = this.getDataset();
+                var custom = point.custom || {};
 
-			if (showLine && line._model.tension !== 0) {
-				me.updateBezierControlPoints();
-			}
+                if (custom.backgroundColor) {
+                    backgroundColor = custom.backgroundColor;
+                } else if (dataset.pointBackgroundColor) {
+                    backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
+                } else if (dataset.backgroundColor) {
+                    backgroundColor = dataset.backgroundColor;
+                }
 
-			// Now pivot the point for animation
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].pivot();
-			}
-		},
+                return backgroundColor;
+            },
 
-		getPointBackgroundColor: function(point, index) {
-			var backgroundColor = this.chart.options.elements.point.backgroundColor;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            getPointBorderColor: function(point, index) {
+                var borderColor = this.chart.options.elements.point.borderColor;
+                var dataset = this.getDataset();
+                var custom = point.custom || {};
 
-			if (custom.backgroundColor) {
-				backgroundColor = custom.backgroundColor;
-			} else if (dataset.pointBackgroundColor) {
-				backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
-			} else if (dataset.backgroundColor) {
-				backgroundColor = dataset.backgroundColor;
-			}
+                if (custom.borderColor) {
+                    borderColor = custom.borderColor;
+                } else if (dataset.pointBorderColor) {
+                    borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
+                } else if (dataset.borderColor) {
+                    borderColor = dataset.borderColor;
+                }
 
-			return backgroundColor;
-		},
+                return borderColor;
+            },
 
-		getPointBorderColor: function(point, index) {
-			var borderColor = this.chart.options.elements.point.borderColor;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            getPointBorderWidth: function(point, index) {
+                var borderWidth = this.chart.options.elements.point.borderWidth;
+                var dataset = this.getDataset();
+                var custom = point.custom || {};
 
-			if (custom.borderColor) {
-				borderColor = custom.borderColor;
-			} else if (dataset.pointBorderColor) {
-				borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
-			} else if (dataset.borderColor) {
-				borderColor = dataset.borderColor;
-			}
+                if (!isNaN(custom.borderWidth)) {
+                    borderWidth = custom.borderWidth;
+                } else if (!isNaN(dataset.pointBorderWidth)) {
+                    borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
+                } else if (!isNaN(dataset.borderWidth)) {
+                    borderWidth = dataset.borderWidth;
+                }
 
-			return borderColor;
-		},
+                return borderWidth;
+            },
 
-		getPointBorderWidth: function(point, index) {
-			var borderWidth = this.chart.options.elements.point.borderWidth;
-			var dataset = this.getDataset();
-			var custom = point.custom || {};
+            updateElement: function(point, index, reset) {
+                var me = this;
+                var meta = me.getMeta();
+                var custom = point.custom || {};
+                var dataset = me.getDataset();
+                var datasetIndex = me.index;
+                var value = dataset.data[index];
+                var yScale = me.getScaleForId(meta.yAxisID);
+                var xScale = me.getScaleForId(meta.xAxisID);
+                var pointOptions = me.chart.options.elements.point;
+                var x, y;
+                var labels = me.chart.data.labels || [];
+                var includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;
 
-			if (custom.borderWidth) {
-				borderWidth = custom.borderWidth;
-			} else if (dataset.pointBorderWidth) {
-				borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
-			} else if (dataset.borderWidth) {
-				borderWidth = dataset.borderWidth;
-			}
+                // Compatibility: If the properties are defined with only the old name, use those values
+                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+                    dataset.pointRadius = dataset.radius;
+                }
+                if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+                    dataset.pointHitRadius = dataset.hitRadius;
+                }
 
-			return borderWidth;
-		},
+                x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
+                y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
 
-		updateElement: function(point, index, reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var custom = point.custom || {};
-			var dataset = me.getDataset();
-			var datasetIndex = me.index;
-			var value = dataset.data[index];
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var xScale = me.getScaleForId(meta.xAxisID);
-			var pointOptions = me.chart.options.elements.point;
-			var x, y;
+                // Utility
+                point._xScale = xScale;
+                point._yScale = yScale;
+                point._datasetIndex = datasetIndex;
+                point._index = index;
 
-			// Compatibility: If the properties are defined with only the old name, use those values
-			if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
-				dataset.pointRadius = dataset.radius;
-			}
-			if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
-				dataset.pointHitRadius = dataset.hitRadius;
-			}
+                // Desired view properties
+                point._model = {
+                    x: x,
+                    y: y,
+                    skip: custom.skip || isNaN(x) || isNaN(y),
+                    // Appearance
+                    radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
+                    pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
+                    backgroundColor: me.getPointBackgroundColor(point, index),
+                    borderColor: me.getPointBorderColor(point, index),
+                    borderWidth: me.getPointBorderWidth(point, index),
+                    tension: meta.dataset._model ? meta.dataset._model.tension : 0,
+                    steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
+                    // Tooltip
+                    hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
+                };
+            },
 
-			x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, me.chart.isCombo);
-			y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
+            calculatePointY: function(value, index, datasetIndex) {
+                var me = this;
+                var chart = me.chart;
+                var meta = me.getMeta();
+                var yScale = me.getScaleForId(meta.yAxisID);
+                var sumPos = 0;
+                var sumNeg = 0;
+                var i, ds, dsMeta;
 
-			// Utility
-			point._xScale = xScale;
-			point._yScale = yScale;
-			point._datasetIndex = datasetIndex;
-			point._index = index;
+                if (yScale.options.stacked) {
+                    for (i = 0; i < datasetIndex; i++) {
+                        ds = chart.data.datasets[i];
+                        dsMeta = chart.getDatasetMeta(i);
+                        if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
+                            var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
+                            if (stackedRightValue < 0) {
+                                sumNeg += stackedRightValue || 0;
+                            } else {
+                                sumPos += stackedRightValue || 0;
+                            }
+                        }
+                    }
 
-			// Desired view properties
-			point._model = {
-				x: x,
-				y: y,
-				skip: custom.skip || isNaN(x) || isNaN(y),
-				// Appearance
-				radius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
-				pointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
-				backgroundColor: me.getPointBackgroundColor(point, index),
-				borderColor: me.getPointBorderColor(point, index),
-				borderWidth: me.getPointBorderWidth(point, index),
-				tension: meta.dataset._model ? meta.dataset._model.tension : 0,
-				steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
-				// Tooltip
-				hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
-			};
-		},
+                    var rightValue = Number(yScale.getRightValue(value));
+                    if (rightValue < 0) {
+                        return yScale.getPixelForValue(sumNeg + rightValue);
+                    }
+                    return yScale.getPixelForValue(sumPos + rightValue);
+                }
 
-		calculatePointY: function(value, index, datasetIndex) {
-			var me = this;
-			var chart = me.chart;
-			var meta = me.getMeta();
-			var yScale = me.getScaleForId(meta.yAxisID);
-			var sumPos = 0;
-			var sumNeg = 0;
-			var i, ds, dsMeta;
+                return yScale.getPixelForValue(value);
+            },
 
-			if (yScale.options.stacked) {
-				for (i = 0; i < datasetIndex; i++) {
-					ds = chart.data.datasets[i];
-					dsMeta = chart.getDatasetMeta(i);
-					if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
-						var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
-						if (stackedRightValue < 0) {
-							sumNeg += stackedRightValue || 0;
-						} else {
-							sumPos += stackedRightValue || 0;
-						}
-					}
-				}
+            updateBezierControlPoints: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var area = me.chart.chartArea;
+                var points = (meta.data || []);
+                var i, ilen, point, model, controlPoints;
 
-				var rightValue = Number(yScale.getRightValue(value));
-				if (rightValue < 0) {
-					return yScale.getPixelForValue(sumNeg + rightValue);
-				} else {
-					return yScale.getPixelForValue(sumPos + rightValue);
-				}
-			}
+                // Only consider points that are drawn in case the spanGaps option is used
+                if (meta.dataset._model.spanGaps) {
+                    points = points.filter(function(pt) {
+                        return !pt._model.skip;
+                    });
+                }
 
-			return yScale.getPixelForValue(value);
-		},
+                function capControlPoint(pt, min, max) {
+                    return Math.max(Math.min(pt, max), min);
+                }
 
-		updateBezierControlPoints: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var area = me.chart.chartArea;
+                if (meta.dataset._model.cubicInterpolationMode === 'monotone') {
+                    helpers.splineCurveMonotone(points);
+                } else {
+                    for (i = 0, ilen = points.length; i < ilen; ++i) {
+                        point = points[i];
+                        model = point._model;
+                        controlPoints = helpers.splineCurve(
+                            helpers.previousItem(points, i)._model,
+                            model,
+                            helpers.nextItem(points, i)._model,
+                            meta.dataset._model.tension
+                        );
+                        model.controlPointPreviousX = controlPoints.previous.x;
+                        model.controlPointPreviousY = controlPoints.previous.y;
+                        model.controlPointNextX = controlPoints.next.x;
+                        model.controlPointNextY = controlPoints.next.y;
+                    }
+                }
 
-			// only consider points that are drawn in case the spanGaps option is ued
-			var points = (meta.data || []).filter(function(pt) { return !pt._model.skip; });
-			var i, ilen, point, model, controlPoints;
+                if (me.chart.options.elements.line.capBezierPoints) {
+                    for (i = 0, ilen = points.length; i < ilen; ++i) {
+                        model = points[i]._model;
+                        model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
+                        model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
+                        model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
+                        model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
+                    }
+                }
+            },
 
-			var needToCap = me.chart.options.elements.line.capBezierPoints;
-			function capIfNecessary(pt, min, max) {
-				return needToCap ? Math.max(Math.min(pt, max), min) : pt;
-			}
+            draw: function() {
+                var me = this;
+                var chart = me.chart;
+                var meta = me.getMeta();
+                var points = meta.data || [];
+                var area = chart.chartArea;
+                var ilen = points.length;
+                var i = 0;
 
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				point = points[i];
-				model = point._model;
-				controlPoints = helpers.splineCurve(
-					helpers.previousItem(points, i)._model,
-					model,
-					helpers.nextItem(points, i)._model,
-					meta.dataset._model.tension
-				);
+                Chart.canvasHelpers.clipArea(chart.ctx, area);
 
-				model.controlPointPreviousX = capIfNecessary(controlPoints.previous.x, area.left, area.right);
-				model.controlPointPreviousY = capIfNecessary(controlPoints.previous.y, area.top, area.bottom);
-				model.controlPointNextX = capIfNecessary(controlPoints.next.x, area.left, area.right);
-				model.controlPointNextY = capIfNecessary(controlPoints.next.y, area.top, area.bottom);
-			}
-		},
+                if (lineEnabled(me.getDataset(), chart.options)) {
+                    meta.dataset.draw();
+                }
 
-		draw: function(ease) {
-			var me = this;
-			var meta = me.getMeta();
-			var points = meta.data || [];
-			var easingDecimal = ease || 1;
-			var i, ilen;
+                Chart.canvasHelpers.unclipArea(chart.ctx);
 
-			// Transition Point Locations
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].transition(easingDecimal);
-			}
+                // Draw the points
+                for (; i<ilen; ++i) {
+                    points[i].draw(area);
+                }
+            },
 
-			// Transition and Draw the line
-			if (lineEnabled(me.getDataset(), me.chart.options)) {
-				meta.dataset.transition(easingDecimal).draw();
-			}
+            setHoverStyle: function(point) {
+                // Point
+                var dataset = this.chart.data.datasets[point._datasetIndex];
+                var index = point._index;
+                var custom = point.custom || {};
+                var model = point._model;
 
-			// Draw the points
-			for (i=0, ilen=points.length; i<ilen; ++i) {
-				points[i].draw();
-			}
-		},
+                model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+                model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+                model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+                model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+            },
 
-		setHoverStyle: function(point) {
-			// Point
-			var dataset = this.chart.data.datasets[point._datasetIndex];
-			var index = point._index;
-			var custom = point.custom || {};
-			var model = point._model;
+            removeHoverStyle: function(point) {
+                var me = this;
+                var dataset = me.chart.data.datasets[point._datasetIndex];
+                var index = point._index;
+                var custom = point.custom || {};
+                var model = point._model;
 
-			model.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
-			model.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-			model.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-			model.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
-		},
+                // Compatibility: If the properties are defined with only the old name, use those values
+                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+                    dataset.pointRadius = dataset.radius;
+                }
 
-		removeHoverStyle: function(point) {
-			var me = this;
-			var dataset = me.chart.data.datasets[point._datasetIndex];
-			var index = point._index;
-			var custom = point.custom || {};
-			var model = point._model;
-
-			// Compatibility: If the properties are defined with only the old name, use those values
-			if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
-				dataset.pointRadius = dataset.radius;
-			}
-
-			model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
-			model.backgroundColor = me.getPointBackgroundColor(point, index);
-			model.borderColor = me.getPointBorderColor(point, index);
-			model.borderWidth = me.getPointBorderWidth(point, index);
-		}
-	});
-};
+                model.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
+                model.backgroundColor = me.getPointBackgroundColor(point, index);
+                model.borderColor = me.getPointBorderColor(point, index);
+                model.borderWidth = me.getPointBorderWidth(point, index);
+            }
+        });
+    };
 
 },{}],19:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.polarArea = {
+        Chart.defaults.polarArea = {
 
-		scale: {
-			type: "radialLinear",
-			lineArc: true, // so that lines are circular
-			ticks: {
-				beginAtZero: true
-			}
-		},
+            scale: {
+                type: 'radialLinear',
+                angleLines: {
+                    display: false
+                },
+                gridLines: {
+                    circular: true
+                },
+                pointLabels: {
+                    display: false
+                },
+                ticks: {
+                    beginAtZero: true
+                }
+            },
 
-		//Boolean - Whether to animate the rotation of the chart
-		animation: {
-			animateRotate: true,
-			animateScale: true
-		},
+            // Boolean - Whether to animate the rotation of the chart
+            animation: {
+                animateRotate: true,
+                animateScale: true
+            },
 
-		startAngle: -0.5 * Math.PI,
-		aspectRatio: 1,
-		legendCallback: function(chart) {
-			var text = [];
-			text.push('<ul class="' + chart.id + '-legend">');
+            startAngle: -0.5 * Math.PI,
+            aspectRatio: 1,
+            legendCallback: function(chart) {
+                var text = [];
+                text.push('<ul class="' + chart.id + '-legend">');
 
-			var data = chart.data;
-			var datasets = data.datasets;
-			var labels = data.labels;
+                var data = chart.data;
+                var datasets = data.datasets;
+                var labels = data.labels;
 
-			if (datasets.length) {
-				for (var i = 0; i < datasets[0].data.length; ++i) {
-					text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '">');
-					if (labels[i]) {
-						text.push(labels[i]);
-					}
-					text.push('</span></li>');
-				}
-			}
+                if (datasets.length) {
+                    for (var i = 0; i < datasets[0].data.length; ++i) {
+                        text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
+                        if (labels[i]) {
+                            text.push(labels[i]);
+                        }
+                        text.push('</li>');
+                    }
+                }
 
-			text.push('</ul>');
-			return text.join("");
-		},
-		legend: {
-			labels: {
-				generateLabels: function(chart) {
-					var data = chart.data;
-					if (data.labels.length && data.datasets.length) {
-						return data.labels.map(function(label, i) {
-							var meta = chart.getDatasetMeta(0);
-							var ds = data.datasets[0];
-							var arc = meta.data[i];
-							var custom = arc.custom || {};
-							var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-							var arcOpts = chart.options.elements.arc;
-							var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
-							var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
-							var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
+                text.push('</ul>');
+                return text.join('');
+            },
+            legend: {
+                labels: {
+                    generateLabels: function(chart) {
+                        var data = chart.data;
+                        if (data.labels.length && data.datasets.length) {
+                            return data.labels.map(function(label, i) {
+                                var meta = chart.getDatasetMeta(0);
+                                var ds = data.datasets[0];
+                                var arc = meta.data[i];
+                                var custom = arc.custom || {};
+                                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
+                                var arcOpts = chart.options.elements.arc;
+                                var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
+                                var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
+                                var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
 
-							return {
-								text: label,
-								fillStyle: fill,
-								strokeStyle: stroke,
-								lineWidth: bw,
-								hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
+                                return {
+                                    text: label,
+                                    fillStyle: fill,
+                                    strokeStyle: stroke,
+                                    lineWidth: bw,
+                                    hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
 
-								// Extra data used for toggling the correct item
-								index: i
-							};
-						});
-					} else {
-						return [];
-					}
-				}
-			},
+                                    // Extra data used for toggling the correct item
+                                    index: i
+                                };
+                            });
+                        }
+                        return [];
+                    }
+                },
 
-			onClick: function(e, legendItem) {
-				var index = legendItem.index;
-				var chart = this.chart;
-				var i, ilen, meta;
+                onClick: function(e, legendItem) {
+                    var index = legendItem.index;
+                    var chart = this.chart;
+                    var i, ilen, meta;
 
-				for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-					meta = chart.getDatasetMeta(i);
-					meta.data[index].hidden = !meta.data[index].hidden;
-				}
+                    for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
+                        meta = chart.getDatasetMeta(i);
+                        meta.data[index].hidden = !meta.data[index].hidden;
+                    }
 
-				chart.update();
-			}
-		},
+                    chart.update();
+                }
+            },
 
-		// Need to override these to give a nice default
-		tooltips: {
-			callbacks: {
-				title: function() {
-					return '';
-				},
-				label: function(tooltipItem, data) {
-					return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;
-				}
-			}
-		}
-	};
+            // Need to override these to give a nice default
+            tooltips: {
+                callbacks: {
+                    title: function() {
+                        return '';
+                    },
+                    label: function(tooltipItem, data) {
+                        return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;
+                    }
+                }
+            }
+        };
 
-	Chart.controllers.polarArea = Chart.DatasetController.extend({
+        Chart.controllers.polarArea = Chart.DatasetController.extend({
 
-		dataElementType: Chart.elements.Arc,
+            dataElementType: Chart.elements.Arc,
 
-		linkScales: helpers.noop,
+            linkScales: helpers.noop,
 
-		update: function(reset) {
-			var me = this;
-			var chart = me.chart;
-			var chartArea = chart.chartArea;
-			var meta = me.getMeta();
-			var opts = chart.options;
-			var arcOpts = opts.elements.arc;
-			var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
-			chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
-			chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
-			chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
+            update: function(reset) {
+                var me = this;
+                var chart = me.chart;
+                var chartArea = chart.chartArea;
+                var meta = me.getMeta();
+                var opts = chart.options;
+                var arcOpts = opts.elements.arc;
+                var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
+                chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
+                chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
+                chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
 
-			me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
-			me.innerRadius = me.outerRadius - chart.radiusLength;
+                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
+                me.innerRadius = me.outerRadius - chart.radiusLength;
 
-			meta.count = me.countVisibleElements();
+                meta.count = me.countVisibleElements();
 
-			helpers.each(meta.data, function(arc, index) {
-				me.updateElement(arc, index, reset);
-			});
-		},
+                helpers.each(meta.data, function(arc, index) {
+                    me.updateElement(arc, index, reset);
+                });
+            },
 
-		updateElement: function(arc, index, reset) {
-			var me = this;
-			var chart = me.chart;
-			var dataset = me.getDataset();
-			var opts = chart.options;
-			var animationOpts = opts.animation;
-			var scale = chart.scale;
-			var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
-			var labels = chart.data.labels;
+            updateElement: function(arc, index, reset) {
+                var me = this;
+                var chart = me.chart;
+                var dataset = me.getDataset();
+                var opts = chart.options;
+                var animationOpts = opts.animation;
+                var scale = chart.scale;
+                var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
+                var labels = chart.data.labels;
 
-			var circumference = me.calculateCircumference(dataset.data[index]);
-			var centerX = scale.xCenter;
-			var centerY = scale.yCenter;
+                var circumference = me.calculateCircumference(dataset.data[index]);
+                var centerX = scale.xCenter;
+                var centerY = scale.yCenter;
 
-			// If there is NaN data before us, we need to calculate the starting angle correctly.
-			// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
-			var visibleCount = 0;
-			var meta = me.getMeta();
-			for (var i = 0; i < index; ++i) {
-				if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
-					++visibleCount;
-				}
-			}
+                // If there is NaN data before us, we need to calculate the starting angle correctly.
+                // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
+                var visibleCount = 0;
+                var meta = me.getMeta();
+                for (var i = 0; i < index; ++i) {
+                    if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
+                        ++visibleCount;
+                    }
+                }
 
-			//var negHalfPI = -0.5 * Math.PI;
-			var datasetStartAngle = opts.startAngle;
-			var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
-			var startAngle = datasetStartAngle + (circumference * visibleCount);
-			var endAngle = startAngle + (arc.hidden ? 0 : circumference);
+                // var negHalfPI = -0.5 * Math.PI;
+                var datasetStartAngle = opts.startAngle;
+                var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+                var startAngle = datasetStartAngle + (circumference * visibleCount);
+                var endAngle = startAngle + (arc.hidden ? 0 : circumference);
 
-			var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+                var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
 
-			helpers.extend(arc, {
-				// Utility
-				_datasetIndex: me.index,
-				_index: index,
-				_scale: scale,
+                helpers.extend(arc, {
+                    // Utility
+                    _datasetIndex: me.index,
+                    _index: index,
+                    _scale: scale,
 
-				// Desired view properties
-				_model: {
-					x: centerX,
-					y: centerY,
-					innerRadius: 0,
-					outerRadius: reset ? resetRadius : distance,
-					startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
-					endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
-					label: getValueAtIndexOrDefault(labels, index, labels[index])
-				}
-			});
+                    // Desired view properties
+                    _model: {
+                        x: centerX,
+                        y: centerY,
+                        innerRadius: 0,
+                        outerRadius: reset ? resetRadius : distance,
+                        startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
+                        endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
+                        label: getValueAtIndexOrDefault(labels, index, labels[index])
+                    }
+                });
 
-			// Apply border and fill style
-			me.removeHoverStyle(arc);
+                // Apply border and fill style
+                me.removeHoverStyle(arc);
 
-			arc.pivot();
-		},
+                arc.pivot();
+            },
 
-		removeHoverStyle: function(arc) {
-			Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
-		},
+            removeHoverStyle: function(arc) {
+                Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
+            },
 
-		countVisibleElements: function() {
-			var dataset = this.getDataset();
-			var meta = this.getMeta();
-			var count = 0;
+            countVisibleElements: function() {
+                var dataset = this.getDataset();
+                var meta = this.getMeta();
+                var count = 0;
 
-			helpers.each(meta.data, function(element, index) {
-				if (!isNaN(dataset.data[index]) && !element.hidden) {
-					count++;
-				}
-			});
+                helpers.each(meta.data, function(element, index) {
+                    if (!isNaN(dataset.data[index]) && !element.hidden) {
+                        count++;
+                    }
+                });
 
-			return count;
-		},
+                return count;
+            },
 
-		calculateCircumference: function(value) {
-			var count = this.getMeta().count;
-			if (count > 0 && !isNaN(value)) {
-				return (2 * Math.PI) / count;
-			} else {
-				return 0;
-			}
-		}
-	});
-};
+            calculateCircumference: function(value) {
+                var count = this.getMeta().count;
+                if (count > 0 && !isNaN(value)) {
+                    return (2 * Math.PI) / count;
+                }
+                return 0;
+            }
+        });
+    };
 
 },{}],20:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.radar = {
-		scale: {
-			type: "radialLinear"
-		},
-		elements: {
-			line: {
-				tension: 0 // no bezier in radar
-			}
-		}
-	};
+        Chart.defaults.radar = {
+            aspectRatio: 1,
+            scale: {
+                type: 'radialLinear'
+            },
+            elements: {
+                line: {
+                    tension: 0 // no bezier in radar
+                }
+            }
+        };
 
-	Chart.controllers.radar = Chart.DatasetController.extend({
+        Chart.controllers.radar = Chart.DatasetController.extend({
 
-		datasetElementType: Chart.elements.Line,
+            datasetElementType: Chart.elements.Line,
 
-		dataElementType: Chart.elements.Point,
+            dataElementType: Chart.elements.Point,
 
-		linkScales: helpers.noop,
+            linkScales: helpers.noop,
 
-		addElementAndReset: function(index) {
-			Chart.DatasetController.prototype.addElementAndReset.call(this, index);
+            update: function(reset) {
+                var me = this;
+                var meta = me.getMeta();
+                var line = meta.dataset;
+                var points = meta.data;
+                var custom = line.custom || {};
+                var dataset = me.getDataset();
+                var lineElementOptions = me.chart.options.elements.line;
+                var scale = me.chart.scale;
 
-			// Make sure bezier control points are updated
-			this.updateBezierControlPoints();
-		},
+                // Compatibility: If the properties are defined with only the old name, use those values
+                if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
+                    dataset.lineTension = dataset.tension;
+                }
 
-		update: function(reset) {
-			var me = this;
-			var meta = me.getMeta();
-			var line = meta.dataset;
-			var points = meta.data;
-			var custom = line.custom || {};
-			var dataset = me.getDataset();
-			var lineElementOptions = me.chart.options.elements.line;
-			var scale = me.chart.scale;
+                helpers.extend(meta.dataset, {
+                    // Utility
+                    _datasetIndex: me.index,
+                    _scale: scale,
+                    // Data
+                    _children: points,
+                    _loop: true,
+                    // Model
+                    _model: {
+                        // Appearance
+                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
+                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
+                        borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
+                        borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
+                        fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
+                        borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
+                        borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
+                        borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
+                        borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+                    }
+                });
 
-			// Compatibility: If the properties are defined with only the old name, use those values
-			if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
-				dataset.lineTension = dataset.tension;
-			}
+                meta.dataset.pivot();
 
-			helpers.extend(meta.dataset, {
-				// Utility
-				_datasetIndex: me.index,
-				// Data
-				_children: points,
-				_loop: true,
-				// Model
-				_model: {
-					// Appearance
-					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
-					borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
-					fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
-					borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
-					borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
-					borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
-					borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
+                // Update Points
+                helpers.each(points, function(point, index) {
+                    me.updateElement(point, index, reset);
+                }, me);
 
-					// Scale
-					scaleTop: scale.top,
-					scaleBottom: scale.bottom,
-					scaleZero: scale.getBasePosition()
-				}
-			});
+                // Update bezier control points
+                me.updateBezierControlPoints();
+            },
+            updateElement: function(point, index, reset) {
+                var me = this;
+                var custom = point.custom || {};
+                var dataset = me.getDataset();
+                var scale = me.chart.scale;
+                var pointElementOptions = me.chart.options.elements.point;
+                var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
 
-			meta.dataset.pivot();
+                // Compatibility: If the properties are defined with only the old name, use those values
+                if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
+                    dataset.pointRadius = dataset.radius;
+                }
+                if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
+                    dataset.pointHitRadius = dataset.hitRadius;
+                }
 
-			// Update Points
-			helpers.each(points, function(point, index) {
-				me.updateElement(point, index, reset);
-			}, me);
+                helpers.extend(point, {
+                    // Utility
+                    _datasetIndex: me.index,
+                    _index: index,
+                    _scale: scale,
 
+                    // Desired view properties
+                    _model: {
+                        x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
+                        y: reset ? scale.yCenter : pointPosition.y,
 
-			// Update bezier control points
-			me.updateBezierControlPoints();
-		},
-		updateElement: function(point, index, reset) {
-			var me = this;
-			var custom = point.custom || {};
-			var dataset = me.getDataset();
-			var scale = me.chart.scale;
-			var pointElementOptions = me.chart.options.elements.point;
-			var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
+                        // Appearance
+                        tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),
+                        radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
+                        backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
+                        borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
+                        borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
+                        pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
 
-			helpers.extend(point, {
-				// Utility
-				_datasetIndex: me.index,
-				_index: index,
-				_scale: scale,
+                        // Tooltip
+                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
+                    }
+                });
 
-				// Desired view properties
-				_model: {
-					x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
-					y: reset ? scale.yCenter : pointPosition.y,
+                point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
+            },
+            updateBezierControlPoints: function() {
+                var chartArea = this.chart.chartArea;
+                var meta = this.getMeta();
 
-					// Appearance
-					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, me.chart.options.elements.line.tension),
-					radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
-					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
-					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
-					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
-					pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
+                helpers.each(meta.data, function(point, index) {
+                    var model = point._model;
+                    var controlPoints = helpers.splineCurve(
+                        helpers.previousItem(meta.data, index, true)._model,
+                        model,
+                        helpers.nextItem(meta.data, index, true)._model,
+                        model.tension
+                    );
 
-					// Tooltip
-					hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
-				}
-			});
+                    // Prevent the bezier going outside of the bounds of the graph
+                    model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
+                    model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
 
-			point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
-		},
-		updateBezierControlPoints: function() {
-			var chartArea = this.chart.chartArea;
-			var meta = this.getMeta();
+                    model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
+                    model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
 
-			helpers.each(meta.data, function(point, index) {
-				var model = point._model;
-				var controlPoints = helpers.splineCurve(
-					helpers.previousItem(meta.data, index, true)._model,
-					model,
-					helpers.nextItem(meta.data, index, true)._model,
-					model.tension
-				);
+                    // Now pivot the point for animation
+                    point.pivot();
+                });
+            },
 
-				// Prevent the bezier going outside of the bounds of the graph
-				model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
-				model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
+            setHoverStyle: function(point) {
+                // Point
+                var dataset = this.chart.data.datasets[point._datasetIndex];
+                var custom = point.custom || {};
+                var index = point._index;
+                var model = point._model;
 
-				model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
-				model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
+                model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
+                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
+                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
+                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
+            },
 
-				// Now pivot the point for animation
-				point.pivot();
-			});
-		},
+            removeHoverStyle: function(point) {
+                var dataset = this.chart.data.datasets[point._datasetIndex];
+                var custom = point.custom || {};
+                var index = point._index;
+                var model = point._model;
+                var pointElementOptions = this.chart.options.elements.point;
 
-		draw: function(ease) {
-			var meta = this.getMeta();
-			var easingDecimal = ease || 1;
-
-			// Transition Point Locations
-			helpers.each(meta.data, function(point) {
-				point.transition(easingDecimal);
-			});
-
-			// Transition and Draw the line
-			meta.dataset.transition(easingDecimal).draw();
-
-			// Draw the points
-			helpers.each(meta.data, function(point) {
-				point.draw();
-			});
-		},
-
-		setHoverStyle: function(point) {
-			// Point
-			var dataset = this.chart.data.datasets[point._datasetIndex];
-			var custom = point.custom || {};
-			var index = point._index;
-			var model = point._model;
-
-			model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
-			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
-			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
-			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
-		},
-
-		removeHoverStyle: function(point) {
-			var dataset = this.chart.data.datasets[point._datasetIndex];
-			var custom = point.custom || {};
-			var index = point._index;
-			var model = point._model;
-			var pointElementOptions = this.chart.options.elements.point;
-
-			model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius);
-			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
-			model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
-			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
-		}
-	});
-};
+                model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);
+                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
+                model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
+                model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
+            }
+        });
+    };
 
 },{}],21:[function(require,module,exports){
-/*global window: false */
-"use strict";
+    /* global window: false */
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.animation = {
-		duration: 1000,
-		easing: "easeOutQuart",
-		onProgress: helpers.noop,
-		onComplete: helpers.noop
-	};
+        Chart.defaults.global.animation = {
+            duration: 1000,
+            easing: 'easeOutQuart',
+            onProgress: helpers.noop,
+            onComplete: helpers.noop
+        };
 
-	Chart.Animation = Chart.Element.extend({
-		currentStep: null, // the current animation step
-		numSteps: 60, // default number of steps
-		easing: "", // the easing to use for this animation
-		render: null, // render function used by the animation service
+        Chart.Animation = Chart.Element.extend({
+            chart: null, // the animation associated chart instance
+            currentStep: 0, // the current animation step
+            numSteps: 60, // default number of steps
+            easing: '', // the easing to use for this animation
+            render: null, // render function used by the animation service
 
-		onAnimationProgress: null, // user specified callback to fire on each step of the animation
-		onAnimationComplete: null // user specified callback to fire when the animation finishes
-	});
+            onAnimationProgress: null, // user specified callback to fire on each step of the animation
+            onAnimationComplete: null, // user specified callback to fire when the animation finishes
+        });
 
-	Chart.animationService = {
-		frameDuration: 17,
-		animations: [],
-		dropFrames: 0,
-		request: null,
-		addAnimation: function(chartInstance, animationObject, duration, lazy) {
-			var me = this;
+        Chart.animationService = {
+            frameDuration: 17,
+            animations: [],
+            dropFrames: 0,
+            request: null,
 
-			if (!lazy) {
-				chartInstance.animating = true;
-			}
+            /**
+             * @param {Chart} chart - The chart to animate.
+             * @param {Chart.Animation} animation - The animation that we will animate.
+             * @param {Number} duration - The animation duration in ms.
+             * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
+             */
+            addAnimation: function(chart, animation, duration, lazy) {
+                var animations = this.animations;
+                var i, ilen;
 
-			for (var index = 0; index < me.animations.length; ++index) {
-				if (me.animations[index].chartInstance === chartInstance) {
-					// replacing an in progress animation
-					me.animations[index].animationObject = animationObject;
-					return;
-				}
-			}
+                animation.chart = chart;
 
-			me.animations.push({
-				chartInstance: chartInstance,
-				animationObject: animationObject
-			});
+                if (!lazy) {
+                    chart.animating = true;
+                }
 
-			// If there are no animations queued, manually kickstart a digest, for lack of a better word
-			if (me.animations.length === 1) {
-				me.requestAnimationFrame();
-			}
-		},
-		// Cancel the animation for a given chart instance
-		cancelAnimation: function(chartInstance) {
-			var index = helpers.findIndex(this.animations, function(animationWrapper) {
-				return animationWrapper.chartInstance === chartInstance;
-			});
+                for (i=0, ilen=animations.length; i < ilen; ++i) {
+                    if (animations[i].chart === chart) {
+                        animations[i] = animation;
+                        return;
+                    }
+                }
 
-			if (index !== -1) {
-				this.animations.splice(index, 1);
-				chartInstance.animating = false;
-			}
-		},
-		requestAnimationFrame: function() {
-			var me = this;
-			if (me.request === null) {
-				// Skip animation frame requests until the active one is executed.
-				// This can happen when processing mouse events, e.g. 'mousemove'
-				// and 'mouseout' events will trigger multiple renders.
-				me.request = helpers.requestAnimFrame.call(window, function() {
-					me.request = null;
-					me.startDigest();
-				});
-			}
-		},
-		startDigest: function() {
-			var me = this;
+                animations.push(animation);
 
-			var startTime = Date.now();
-			var framesToDrop = 0;
+                // If there are no animations queued, manually kickstart a digest, for lack of a better word
+                if (animations.length === 1) {
+                    this.requestAnimationFrame();
+                }
+            },
 
-			if (me.dropFrames > 1) {
-				framesToDrop = Math.floor(me.dropFrames);
-				me.dropFrames = me.dropFrames % 1;
-			}
+            cancelAnimation: function(chart) {
+                var index = helpers.findIndex(this.animations, function(animation) {
+                    return animation.chart === chart;
+                });
 
-			var i = 0;
-			while (i < me.animations.length) {
-				if (me.animations[i].animationObject.currentStep === null) {
-					me.animations[i].animationObject.currentStep = 0;
-				}
+                if (index !== -1) {
+                    this.animations.splice(index, 1);
+                    chart.animating = false;
+                }
+            },
 
-				me.animations[i].animationObject.currentStep += 1 + framesToDrop;
+            requestAnimationFrame: function() {
+                var me = this;
+                if (me.request === null) {
+                    // Skip animation frame requests until the active one is executed.
+                    // This can happen when processing mouse events, e.g. 'mousemove'
+                    // and 'mouseout' events will trigger multiple renders.
+                    me.request = helpers.requestAnimFrame.call(window, function() {
+                        me.request = null;
+                        me.startDigest();
+                    });
+                }
+            },
 
-				if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) {
-					me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps;
-				}
+            /**
+             * @private
+             */
+            startDigest: function() {
+                var me = this;
+                var startTime = Date.now();
+                var framesToDrop = 0;
 
-				me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject);
-				if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) {
-					me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]);
-				}
+                if (me.dropFrames > 1) {
+                    framesToDrop = Math.floor(me.dropFrames);
+                    me.dropFrames = me.dropFrames % 1;
+                }
 
-				if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) {
-					if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) {
-						me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]);
-					}
+                me.advance(1 + framesToDrop);
 
-					// executed the last frame. Remove the animation.
-					me.animations[i].chartInstance.animating = false;
+                var endTime = Date.now();
 
-					me.animations.splice(i, 1);
-				} else {
-					++i;
-				}
-			}
+                me.dropFrames += (endTime - startTime) / me.frameDuration;
 
-			var endTime = Date.now();
-			var dropFrames = (endTime - startTime) / me.frameDuration;
+                // Do we have more stuff to animate?
+                if (me.animations.length > 0) {
+                    me.requestAnimationFrame();
+                }
+            },
 
-			me.dropFrames += dropFrames;
+            /**
+             * @private
+             */
+            advance: function(count) {
+                var animations = this.animations;
+                var animation, chart;
+                var i = 0;
 
-			// Do we have more stuff to animate?
-			if (me.animations.length > 0) {
-				me.requestAnimationFrame();
-			}
-		}
-	};
-};
+                while (i < animations.length) {
+                    animation = animations[i];
+                    chart = animation.chart;
+
+                    animation.currentStep = (animation.currentStep || 0) + count;
+                    animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
+
+                    helpers.callback(animation.render, [chart, animation], chart);
+                    helpers.callback(animation.onAnimationProgress, [animation], chart);
+
+                    if (animation.currentStep >= animation.numSteps) {
+                        helpers.callback(animation.onAnimationComplete, [animation], chart);
+                        chart.animating = false;
+                        animations.splice(i, 1);
+                    } else {
+                        ++i;
+                    }
+                }
+            }
+        };
+
+        /**
+         * Provided for backward compatibility, use Chart.Animation instead
+         * @prop Chart.Animation#animationObject
+         * @deprecated since version 2.6.0
+         * @todo remove at version 3
+         */
+        Object.defineProperty(Chart.Animation.prototype, 'animationObject', {
+            get: function() {
+                return this;
+            }
+        });
+
+        /**
+         * Provided for backward compatibility, use Chart.Animation#chart instead
+         * @prop Chart.Animation#chartInstance
+         * @deprecated since version 2.6.0
+         * @todo remove at version 3
+         */
+        Object.defineProperty(Chart.Animation.prototype, 'chartInstance', {
+            get: function() {
+                return this.chart;
+            },
+            set: function(value) {
+                this.chart = value;
+            }
+        });
+
+    };
+
 },{}],22:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
-	// Global Chart canvas helpers object for drawing items to canvas
-	var helpers = Chart.canvasHelpers = {};
+    module.exports = function(Chart) {
+        // Global Chart canvas helpers object for drawing items to canvas
+        var helpers = Chart.canvasHelpers = {};
 
-	helpers.drawPoint = function(ctx, pointStyle, radius, x, y) {
-		var type, edgeLength, xOffset, yOffset, height, size;
+        helpers.drawPoint = function(ctx, pointStyle, radius, x, y) {
+            var type, edgeLength, xOffset, yOffset, height, size;
 
-		if (typeof pointStyle === 'object') {
-			type = pointStyle.toString();
-			if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
-				ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);
-				return;
-			}
-		}
+            if (typeof pointStyle === 'object') {
+                type = pointStyle.toString();
+                if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
+                    ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);
+                    return;
+                }
+            }
 
-		if (isNaN(radius) || radius <= 0) {
-			return;
-		}
+            if (isNaN(radius) || radius <= 0) {
+                return;
+            }
 
-		switch (pointStyle) {
-		// Default includes circle
-		default:
-			ctx.beginPath();
-			ctx.arc(x, y, radius, 0, Math.PI * 2);
-			ctx.closePath();
-			ctx.fill();
-			break;
-		case 'triangle':
-			ctx.beginPath();
-			edgeLength = 3 * radius / Math.sqrt(3);
-			height = edgeLength * Math.sqrt(3) / 2;
-			ctx.moveTo(x - edgeLength / 2, y + height / 3);
-			ctx.lineTo(x + edgeLength / 2, y + height / 3);
-			ctx.lineTo(x, y - 2 * height / 3);
-			ctx.closePath();
-			ctx.fill();
-			break;
-		case 'rect':
-			size = 1 / Math.SQRT2 * radius;
-			ctx.beginPath();
-			ctx.fillRect(x - size, y - size, 2 * size,  2 * size);
-			ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
-			break;
-		case 'rectRot':
-			size = 1 / Math.SQRT2 * radius;
-			ctx.beginPath();
-			ctx.moveTo(x - size, y);
-			ctx.lineTo(x, y + size);
-			ctx.lineTo(x + size, y);
-			ctx.lineTo(x, y - size);
-			ctx.closePath();
-			ctx.fill();
-			break;
-		case 'cross':
-			ctx.beginPath();
-			ctx.moveTo(x, y + radius);
-			ctx.lineTo(x, y - radius);
-			ctx.moveTo(x - radius, y);
-			ctx.lineTo(x + radius, y);
-			ctx.closePath();
-			break;
-		case 'crossRot':
-			ctx.beginPath();
-			xOffset = Math.cos(Math.PI / 4) * radius;
-			yOffset = Math.sin(Math.PI / 4) * radius;
-			ctx.moveTo(x - xOffset, y - yOffset);
-			ctx.lineTo(x + xOffset, y + yOffset);
-			ctx.moveTo(x - xOffset, y + yOffset);
-			ctx.lineTo(x + xOffset, y - yOffset);
-			ctx.closePath();
-			break;
-		case 'star':
-			ctx.beginPath();
-			ctx.moveTo(x, y + radius);
-			ctx.lineTo(x, y - radius);
-			ctx.moveTo(x - radius, y);
-			ctx.lineTo(x + radius, y);
-			xOffset = Math.cos(Math.PI / 4) * radius;
-			yOffset = Math.sin(Math.PI / 4) * radius;
-			ctx.moveTo(x - xOffset, y - yOffset);
-			ctx.lineTo(x + xOffset, y + yOffset);
-			ctx.moveTo(x - xOffset, y + yOffset);
-			ctx.lineTo(x + xOffset, y - yOffset);
-			ctx.closePath();
-			break;
-		case 'line':
-			ctx.beginPath();
-			ctx.moveTo(x - radius, y);
-			ctx.lineTo(x + radius, y);
-			ctx.closePath();
-			break;
-		case 'dash':
-			ctx.beginPath();
-			ctx.moveTo(x, y);
-			ctx.lineTo(x + radius, y);
-			ctx.closePath();
-			break;
-		}
+            switch (pointStyle) {
+                // Default includes circle
+                default:
+                    ctx.beginPath();
+                    ctx.arc(x, y, radius, 0, Math.PI * 2);
+                    ctx.closePath();
+                    ctx.fill();
+                    break;
+                case 'triangle':
+                    ctx.beginPath();
+                    edgeLength = 3 * radius / Math.sqrt(3);
+                    height = edgeLength * Math.sqrt(3) / 2;
+                    ctx.moveTo(x - edgeLength / 2, y + height / 3);
+                    ctx.lineTo(x + edgeLength / 2, y + height / 3);
+                    ctx.lineTo(x, y - 2 * height / 3);
+                    ctx.closePath();
+                    ctx.fill();
+                    break;
+                case 'rect':
+                    size = 1 / Math.SQRT2 * radius;
+                    ctx.beginPath();
+                    ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
+                    ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
+                    break;
+                case 'rectRounded':
+                    var offset = radius / Math.SQRT2;
+                    var leftX = x - offset;
+                    var topY = y - offset;
+                    var sideSize = Math.SQRT2 * radius;
+                    Chart.helpers.drawRoundedRectangle(ctx, leftX, topY, sideSize, sideSize, radius / 2);
+                    ctx.fill();
+                    break;
+                case 'rectRot':
+                    size = 1 / Math.SQRT2 * radius;
+                    ctx.beginPath();
+                    ctx.moveTo(x - size, y);
+                    ctx.lineTo(x, y + size);
+                    ctx.lineTo(x + size, y);
+                    ctx.lineTo(x, y - size);
+                    ctx.closePath();
+                    ctx.fill();
+                    break;
+                case 'cross':
+                    ctx.beginPath();
+                    ctx.moveTo(x, y + radius);
+                    ctx.lineTo(x, y - radius);
+                    ctx.moveTo(x - radius, y);
+                    ctx.lineTo(x + radius, y);
+                    ctx.closePath();
+                    break;
+                case 'crossRot':
+                    ctx.beginPath();
+                    xOffset = Math.cos(Math.PI / 4) * radius;
+                    yOffset = Math.sin(Math.PI / 4) * radius;
+                    ctx.moveTo(x - xOffset, y - yOffset);
+                    ctx.lineTo(x + xOffset, y + yOffset);
+                    ctx.moveTo(x - xOffset, y + yOffset);
+                    ctx.lineTo(x + xOffset, y - yOffset);
+                    ctx.closePath();
+                    break;
+                case 'star':
+                    ctx.beginPath();
+                    ctx.moveTo(x, y + radius);
+                    ctx.lineTo(x, y - radius);
+                    ctx.moveTo(x - radius, y);
+                    ctx.lineTo(x + radius, y);
+                    xOffset = Math.cos(Math.PI / 4) * radius;
+                    yOffset = Math.sin(Math.PI / 4) * radius;
+                    ctx.moveTo(x - xOffset, y - yOffset);
+                    ctx.lineTo(x + xOffset, y + yOffset);
+                    ctx.moveTo(x - xOffset, y + yOffset);
+                    ctx.lineTo(x + xOffset, y - yOffset);
+                    ctx.closePath();
+                    break;
+                case 'line':
+                    ctx.beginPath();
+                    ctx.moveTo(x - radius, y);
+                    ctx.lineTo(x + radius, y);
+                    ctx.closePath();
+                    break;
+                case 'dash':
+                    ctx.beginPath();
+                    ctx.moveTo(x, y);
+                    ctx.lineTo(x + radius, y);
+                    ctx.closePath();
+                    break;
+            }
 
-		ctx.stroke();
-	};
-};
+            ctx.stroke();
+        };
+
+        helpers.clipArea = function(ctx, clipArea) {
+            ctx.save();
+            ctx.beginPath();
+            ctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);
+            ctx.clip();
+        };
+
+        helpers.unclipArea = function(ctx) {
+            ctx.restore();
+        };
+
+        helpers.lineTo = function(ctx, previous, target, flip) {
+            if (target.steppedLine) {
+                if (target.steppedLine === 'after') {
+                    ctx.lineTo(previous.x, target.y);
+                } else {
+                    ctx.lineTo(target.x, previous.y);
+                }
+                ctx.lineTo(target.x, target.y);
+                return;
+            }
+
+            if (!target.tension) {
+                ctx.lineTo(target.x, target.y);
+                return;
+            }
+
+            ctx.bezierCurveTo(
+                flip? previous.controlPointPreviousX : previous.controlPointNextX,
+                flip? previous.controlPointPreviousY : previous.controlPointNextY,
+                flip? target.controlPointNextX : target.controlPointPreviousX,
+                flip? target.controlPointNextY : target.controlPointPreviousY,
+                target.x,
+                target.y);
+        };
+
+        Chart.helpers.canvas = helpers;
+    };
+
 },{}],23:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	//Create a dictionary of chart types, to allow for extension of existing types
-	Chart.types = {};
+        var helpers = Chart.helpers;
+        var plugins = Chart.plugins;
+        var platform = Chart.platform;
 
-	//Store a reference to each instance - allowing us to globally resize chart instances on window resize.
-	//Destroy method on the chart will remove the instance of the chart from this reference.
-	Chart.instances = {};
+        // Create a dictionary of chart types, to allow for extension of existing types
+        Chart.types = {};
 
-	// Controllers available for dataset visualization eg. bar, line, slice, etc.
-	Chart.controllers = {};
+        // Store a reference to each instance - allowing us to globally resize chart instances on window resize.
+        // Destroy method on the chart will remove the instance of the chart from this reference.
+        Chart.instances = {};
 
-	/**
-	 * @class Chart.Controller
-	 * The main controller of a chart.
-	 */
-	Chart.Controller = function(instance) {
+        // Controllers available for dataset visualization eg. bar, line, slice, etc.
+        Chart.controllers = {};
 
-		this.chart = instance;
-		this.config = instance.config;
-		this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});
-		this.id = helpers.uid();
+        /**
+         * Initializes the given config with global and chart default values.
+         */
+        function initConfig(config) {
+            config = config || {};
 
-		Object.defineProperty(this, 'data', {
-			get: function() {
-				return this.config.data;
-			}
-		});
+            // Do NOT use configMerge() for the data object because this method merges arrays
+            // and so would change references to labels and datasets, preventing data updates.
+            var data = config.data = config.data || {};
+            data.datasets = data.datasets || [];
+            data.labels = data.labels || [];
 
-		//Add the chart instance to the global namespace
-		Chart.instances[this.id] = this;
+            config.options = helpers.configMerge(
+                Chart.defaults.global,
+                Chart.defaults[config.type],
+                config.options || {});
 
-		if (this.options.responsive) {
-			// Silent resize before chart draws
-			this.resize(true);
-		}
+            return config;
+        }
 
-		this.initialize();
+        /**
+         * Updates the config of the chart
+         * @param chart {Chart} chart to update the options for
+         */
+        function updateConfig(chart) {
+            var newOptions = chart.options;
 
-		return this;
-	};
+            // Update Scale(s) with options
+            if (newOptions.scale) {
+                chart.scale.options = newOptions.scale;
+            } else if (newOptions.scales) {
+                newOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {
+                    chart.scales[scaleOptions.id].options = scaleOptions;
+                });
+            }
 
-	helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {
+            // Tooltip
+            chart.tooltip._options = newOptions.tooltips;
+        }
 
-		initialize: function() {
-			var me = this;
-			// Before init plugin notification
-			Chart.plugins.notify('beforeInit', [me]);
+        function positionIsHorizontal(position) {
+            return position === 'top' || position === 'bottom';
+        }
 
-			me.bindEvents();
+        helpers.extend(Chart.prototype, /** @lends Chart */ {
+            /**
+             * @private
+             */
+            construct: function(item, config) {
+                var me = this;
 
-			// Make sure controllers are built first so that each dataset is bound to an axis before the scales
-			// are built
-			me.ensureScalesHaveIDs();
-			me.buildOrUpdateControllers();
-			me.buildScales();
-			me.updateLayout();
-			me.resetElements();
-			me.initToolTip();
-			me.update();
+                config = initConfig(config);
 
-			// After init plugin notification
-			Chart.plugins.notify('afterInit', [me]);
+                var context = platform.acquireContext(item, config);
+                var canvas = context && context.canvas;
+                var height = canvas && canvas.height;
+                var width = canvas && canvas.width;
 
-			return me;
-		},
+                me.id = helpers.uid();
+                me.ctx = context;
+                me.canvas = canvas;
+                me.config = config;
+                me.width = width;
+                me.height = height;
+                me.aspectRatio = height? width / height : null;
+                me.options = config.options;
+                me._bufferedRender = false;
 
-		clear: function() {
-			helpers.clear(this.chart);
-			return this;
-		},
+                /**
+                 * Provided for backward compatibility, Chart and Chart.Controller have been merged,
+                 * the "instance" still need to be defined since it might be called from plugins.
+                 * @prop Chart#chart
+                 * @deprecated since version 2.6.0
+                 * @todo remove at version 3
+                 * @private
+                 */
+                me.chart = me;
+                me.controller = me;  // chart.chart.controller #inception
 
-		stop: function() {
-			// Stops any current animation loop occuring
-			Chart.animationService.cancelAnimation(this);
-			return this;
-		},
+                // Add the chart instance to the global namespace
+                Chart.instances[me.id] = me;
 
-		resize: function resize(silent) {
-			var me = this;
-			var chart = me.chart;
-			var canvas = chart.canvas;
-			var newWidth = helpers.getMaximumWidth(canvas);
-			var aspectRatio = chart.aspectRatio;
-			var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);
+                // Define alias to the config data: `chart.data === chart.config.data`
+                Object.defineProperty(me, 'data', {
+                    get: function() {
+                        return me.config.data;
+                    },
+                    set: function(value) {
+                        me.config.data = value;
+                    }
+                });
 
-			var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;
+                if (!context || !canvas) {
+                    // The given item is not a compatible context2d element, let's return before finalizing
+                    // the chart initialization but after setting basic chart / controller properties that
+                    // can help to figure out that the chart is not valid (e.g chart.canvas !== null);
+                    // https://github.com/chartjs/Chart.js/issues/2807
+                    console.error("Failed to create chart: can't acquire context from the given item");
+                    return;
+                }
 
-			if (!sizeChanged) {
-				return me;
-			}
+                me.initialize();
+                me.update();
+            },
 
-			canvas.width = chart.width = newWidth;
-			canvas.height = chart.height = newHeight;
+            /**
+             * @private
+             */
+            initialize: function() {
+                var me = this;
 
-			helpers.retinaScale(chart);
+                // Before init plugin notification
+                plugins.notify(me, 'beforeInit');
 
-			// Notify any plugins about the resize
-			var newSize = { width: newWidth, height: newHeight };
-			Chart.plugins.notify('resize', [me, newSize]);
+                helpers.retinaScale(me);
 
-			// Notify of resize
-			if (me.options.onResize) {
-				me.options.onResize(me, newSize);
-			}
+                me.bindEvents();
 
-			if (!silent) {
-				me.stop();
-				me.update(me.options.responsiveAnimationDuration);
-			}
+                if (me.options.responsive) {
+                    // Initial resize before chart draws (must be silent to preserve initial animations).
+                    me.resize(true);
+                }
 
-			return me;
-		},
+                // Make sure scales have IDs and are built before we build any controllers.
+                me.ensureScalesHaveIDs();
+                me.buildScales();
+                me.initToolTip();
 
-		ensureScalesHaveIDs: function() {
-			var options = this.options;
-			var scalesOptions = options.scales || {};
-			var scaleOptions = options.scale;
+                // After init plugin notification
+                plugins.notify(me, 'afterInit');
 
-			helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
-				xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
-			});
+                return me;
+            },
 
-			helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
-				yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
-			});
+            clear: function() {
+                helpers.clear(this);
+                return this;
+            },
 
-			if (scaleOptions) {
-				scaleOptions.id = scaleOptions.id || 'scale';
-			}
-		},
+            stop: function() {
+                // Stops any current animation loop occurring
+                Chart.animationService.cancelAnimation(this);
+                return this;
+            },
 
-		/**
-		 * Builds a map of scale ID to scale object for future lookup.
-		 */
-		buildScales: function() {
-			var me = this;
-			var options = me.options;
-			var scales = me.scales = {};
-			var items = [];
+            resize: function(silent) {
+                var me = this;
+                var options = me.options;
+                var canvas = me.canvas;
+                var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
 
-			if (options.scales) {
-				items = items.concat(
-					(options.scales.xAxes || []).map(function(xAxisOptions) {
-						return { options: xAxisOptions, dtype: 'category' }; }),
-					(options.scales.yAxes || []).map(function(yAxisOptions) {
-						return { options: yAxisOptions, dtype: 'linear' }; }));
-			}
+                // the canvas render width and height will be casted to integers so make sure that
+                // the canvas display style uses the same integer values to avoid blurring effect.
+                var newWidth = Math.floor(helpers.getMaximumWidth(canvas));
+                var newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));
 
-			if (options.scale) {
-				items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });
-			}
+                if (me.width === newWidth && me.height === newHeight) {
+                    return;
+                }
 
-			helpers.each(items, function(item) {
-				var scaleOptions = item.options;
-				var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);
-				var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
-				if (!scaleClass) {
-					return;
-				}
+                canvas.width = me.width = newWidth;
+                canvas.height = me.height = newHeight;
+                canvas.style.width = newWidth + 'px';
+                canvas.style.height = newHeight + 'px';
 
-				var scale = new scaleClass({
-					id: scaleOptions.id,
-					options: scaleOptions,
-					ctx: me.chart.ctx,
-					chart: me
-				});
+                helpers.retinaScale(me);
 
-				scales[scale.id] = scale;
+                if (!silent) {
+                    // Notify any plugins about the resize
+                    var newSize = {width: newWidth, height: newHeight};
+                    plugins.notify(me, 'resize', [newSize]);
 
-				// TODO(SB): I think we should be able to remove this custom case (options.scale)
-				// and consider it as a regular scale part of the "scales"" map only! This would
-				// make the logic easier and remove some useless? custom code.
-				if (item.isDefault) {
-					me.scale = scale;
-				}
-			});
+                    // Notify of resize
+                    if (me.options.onResize) {
+                        me.options.onResize(me, newSize);
+                    }
 
-			Chart.scaleService.addScalesToLayout(this);
-		},
+                    me.stop();
+                    me.update(me.options.responsiveAnimationDuration);
+                }
+            },
 
-		updateLayout: function() {
-			Chart.layoutService.update(this, this.chart.width, this.chart.height);
-		},
+            ensureScalesHaveIDs: function() {
+                var options = this.options;
+                var scalesOptions = options.scales || {};
+                var scaleOptions = options.scale;
 
-		buildOrUpdateControllers: function() {
-			var me = this;
-			var types = [];
-			var newControllers = [];
+                helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
+                    xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
+                });
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				var meta = me.getDatasetMeta(datasetIndex);
-				if (!meta.type) {
-					meta.type = dataset.type || me.config.type;
-				}
+                helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
+                    yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
+                });
 
-				types.push(meta.type);
+                if (scaleOptions) {
+                    scaleOptions.id = scaleOptions.id || 'scale';
+                }
+            },
 
-				if (meta.controller) {
-					meta.controller.updateIndex(datasetIndex);
-				} else {
-					meta.controller = new Chart.controllers[meta.type](me, datasetIndex);
-					newControllers.push(meta.controller);
-				}
-			}, me);
+            /**
+             * Builds a map of scale ID to scale object for future lookup.
+             */
+            buildScales: function() {
+                var me = this;
+                var options = me.options;
+                var scales = me.scales = {};
+                var items = [];
 
-			if (types.length > 1) {
-				for (var i = 1; i < types.length; i++) {
-					if (types[i] !== types[i - 1]) {
-						me.isCombo = true;
-						break;
-					}
-				}
-			}
+                if (options.scales) {
+                    items = items.concat(
+                        (options.scales.xAxes || []).map(function(xAxisOptions) {
+                            return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};
+                        }),
+                        (options.scales.yAxes || []).map(function(yAxisOptions) {
+                            return {options: yAxisOptions, dtype: 'linear', dposition: 'left'};
+                        })
+                    );
+                }
 
-			return newControllers;
-		},
+                if (options.scale) {
+                    items.push({
+                        options: options.scale,
+                        dtype: 'radialLinear',
+                        isDefault: true,
+                        dposition: 'chartArea'
+                    });
+                }
 
-		resetElements: function() {
-			var me = this;
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				me.getDatasetMeta(datasetIndex).controller.reset();
-			}, me);
-		},
+                helpers.each(items, function(item) {
+                    var scaleOptions = item.options;
+                    var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);
+                    var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
+                    if (!scaleClass) {
+                        return;
+                    }
 
-		update: function update(animationDuration, lazy) {
-			var me = this;
-			Chart.plugins.notify('beforeUpdate', [me]);
+                    if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
+                        scaleOptions.position = item.dposition;
+                    }
 
-			// In case the entire data object changed
-			me.tooltip._data = me.data;
+                    var scale = new scaleClass({
+                        id: scaleOptions.id,
+                        options: scaleOptions,
+                        ctx: me.ctx,
+                        chart: me
+                    });
 
-			// Make sure dataset controllers are updated and new controllers are reset
-			var newControllers = me.buildOrUpdateControllers();
+                    scales[scale.id] = scale;
 
-			// Make sure all dataset controllers have correct meta data counts
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
-			}, me);
+                    // TODO(SB): I think we should be able to remove this custom case (options.scale)
+                    // and consider it as a regular scale part of the "scales"" map only! This would
+                    // make the logic easier and remove some useless? custom code.
+                    if (item.isDefault) {
+                        me.scale = scale;
+                    }
+                });
 
-			Chart.layoutService.update(me, me.chart.width, me.chart.height);
+                Chart.scaleService.addScalesToLayout(this);
+            },
 
-			// Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages
-			Chart.plugins.notify('afterScaleUpdate', [me]);
+            buildOrUpdateControllers: function() {
+                var me = this;
+                var types = [];
+                var newControllers = [];
 
-			// Can only reset the new controllers after the scales have been updated
-			helpers.each(newControllers, function(controller) {
-				controller.reset();
-			});
+                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+                    var meta = me.getDatasetMeta(datasetIndex);
+                    if (!meta.type) {
+                        meta.type = dataset.type || me.config.type;
+                    }
 
-			me.updateDatasets();
+                    types.push(meta.type);
 
-			// Do this before render so that any plugins that need final scale updates can use it
-			Chart.plugins.notify('afterUpdate', [me]);
+                    if (meta.controller) {
+                        meta.controller.updateIndex(datasetIndex);
+                    } else {
+                        var ControllerClass = Chart.controllers[meta.type];
+                        if (ControllerClass === undefined) {
+                            throw new Error('"' + meta.type + '" is not a chart type.');
+                        }
 
-			me.render(animationDuration, lazy);
-		},
+                        meta.controller = new ControllerClass(me, datasetIndex);
+                        newControllers.push(meta.controller);
+                    }
+                }, me);
 
-		/**
-		 * @method beforeDatasetsUpdate
-		 * @description Called before all datasets are updated. If a plugin returns false,
-		 * the datasets update will be cancelled until another chart update is triggered.
-		 * @param {Object} instance the chart instance being updated.
-		 * @returns {Boolean} false to cancel the datasets update.
-		 * @memberof Chart.PluginBase
-		 * @since version 2.1.5
-		 * @instance
-		 */
+                if (types.length > 1) {
+                    for (var i = 1; i < types.length; i++) {
+                        if (types[i] !== types[i - 1]) {
+                            me.isCombo = true;
+                            break;
+                        }
+                    }
+                }
 
-		/**
-		 * @method afterDatasetsUpdate
-		 * @description Called after all datasets have been updated. Note that this
-		 * extension will not be called if the datasets update has been cancelled.
-		 * @param {Object} instance the chart instance being updated.
-		 * @memberof Chart.PluginBase
-		 * @since version 2.1.5
-		 * @instance
-		 */
+                return newControllers;
+            },
+
+            /**
+             * Reset the elements of all datasets
+             * @private
+             */
+            resetElements: function() {
+                var me = this;
+                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+                    me.getDatasetMeta(datasetIndex).controller.reset();
+                }, me);
+            },
+
+            /**
+             * Resets the chart back to it's state before the initial animation
+             */
+            reset: function() {
+                this.resetElements();
+                this.tooltip.initialize();
+            },
+
+            update: function(animationDuration, lazy) {
+                var me = this;
+
+                updateConfig(me);
+
+                if (plugins.notify(me, 'beforeUpdate') === false) {
+                    return;
+                }
+
+                // In case the entire data object changed
+                me.tooltip._data = me.data;
+
+                // Make sure dataset controllers are updated and new controllers are reset
+                var newControllers = me.buildOrUpdateControllers();
+
+                // Make sure all dataset controllers have correct meta data counts
+                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
+                    me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
+                }, me);
+
+                me.updateLayout();
+
+                // Can only reset the new controllers after the scales have been updated
+                helpers.each(newControllers, function(controller) {
+                    controller.reset();
+                });
+
+                me.updateDatasets();
+
+                // Do this before render so that any plugins that need final scale updates can use it
+                plugins.notify(me, 'afterUpdate');
+
+                if (me._bufferedRender) {
+                    me._bufferedRequest = {
+                        lazy: lazy,
+                        duration: animationDuration
+                    };
+                } else {
+                    me.render(animationDuration, lazy);
+                }
+            },
+
+            /**
+             * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`
+             * hook, in which case, plugins will not be called on `afterLayout`.
+             * @private
+             */
+            updateLayout: function() {
+                var me = this;
+
+                if (plugins.notify(me, 'beforeLayout') === false) {
+                    return;
+                }
+
+                Chart.layoutService.update(this, this.width, this.height);
+
+                /**
+                 * Provided for backward compatibility, use `afterLayout` instead.
+                 * @method IPlugin#afterScaleUpdate
+                 * @deprecated since version 2.5.0
+                 * @todo remove at version 3
+                 * @private
+                 */
+                plugins.notify(me, 'afterScaleUpdate');
+                plugins.notify(me, 'afterLayout');
+            },
+
+            /**
+             * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`
+             * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.
+             * @private
+             */
+            updateDatasets: function() {
+                var me = this;
+
+                if (plugins.notify(me, 'beforeDatasetsUpdate') === false) {
+                    return;
+                }
+
+                for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+                    me.updateDataset(i);
+                }
+
+                plugins.notify(me, 'afterDatasetsUpdate');
+            },
+
+            /**
+             * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`
+             * hook, in which case, plugins will not be called on `afterDatasetUpdate`.
+             * @private
+             */
+            updateDataset: function(index) {
+                var me = this;
+                var meta = me.getDatasetMeta(index);
+                var args = {
+                    meta: meta,
+                    index: index
+                };
+
+                if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {
+                    return;
+                }
+
+                meta.controller.update();
+
+                plugins.notify(me, 'afterDatasetUpdate', [args]);
+            },
+
+            render: function(duration, lazy) {
+                var me = this;
+
+                if (plugins.notify(me, 'beforeRender') === false) {
+                    return;
+                }
+
+                var animationOptions = me.options.animation;
+                var onComplete = function(animation) {
+                    plugins.notify(me, 'afterRender');
+                    helpers.callback(animationOptions && animationOptions.onComplete, [animation], me);
+                };
+
+                if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
+                    var animation = new Chart.Animation({
+                        numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps
+                        easing: animationOptions.easing,
+
+                        render: function(chart, animationObject) {
+                            var easingFunction = helpers.easingEffects[animationObject.easing];
+                            var currentStep = animationObject.currentStep;
+                            var stepDecimal = currentStep / animationObject.numSteps;
+
+                            chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);
+                        },
+
+                        onAnimationProgress: animationOptions.onProgress,
+                        onAnimationComplete: onComplete
+                    });
+
+                    Chart.animationService.addAnimation(me, animation, duration, lazy);
+                } else {
+                    me.draw();
+
+                    // See https://github.com/chartjs/Chart.js/issues/3781
+                    onComplete(new Chart.Animation({numSteps: 0, chart: me}));
+                }
+
+                return me;
+            },
+
+            draw: function(easingValue) {
+                var me = this;
+
+                me.clear();
+
+                if (easingValue === undefined || easingValue === null) {
+                    easingValue = 1;
+                }
 
-		/**
-		 * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate
-		 * extension, in which case no datasets will be updated and the afterDatasetsUpdate
-		 * notification will be skipped.
-		 * @protected
-		 * @instance
-		 */
-		updateDatasets: function() {
-			var me = this;
-			var i, ilen;
+                me.transition(easingValue);
 
-			if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) {
-				for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
-					me.getDatasetMeta(i).controller.update();
-				}
+                if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
+                    return;
+                }
 
-				Chart.plugins.notify('afterDatasetsUpdate', [ me ]);
-			}
-		},
+                // Draw all the scales
+                helpers.each(me.boxes, function(box) {
+                    box.draw(me.chartArea);
+                }, me);
 
-		render: function render(duration, lazy) {
-			var me = this;
-			Chart.plugins.notify('beforeRender', [me]);
+                if (me.scale) {
+                    me.scale.draw();
+                }
 
-			var animationOptions = me.options.animation;
-			if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
-				var animation = new Chart.Animation();
-				animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps
-				animation.easing = animationOptions.easing;
+                me.drawDatasets(easingValue);
 
-				// render function
-				animation.render = function(chartInstance, animationObject) {
-					var easingFunction = helpers.easingEffects[animationObject.easing];
-					var stepDecimal = animationObject.currentStep / animationObject.numSteps;
-					var easeDecimal = easingFunction(stepDecimal);
+                // Finally draw the tooltip
+                me.tooltip.draw();
 
-					chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
-				};
+                plugins.notify(me, 'afterDraw', [easingValue]);
+            },
 
-				// user events
-				animation.onAnimationProgress = animationOptions.onProgress;
-				animation.onAnimationComplete = animationOptions.onComplete;
+            /**
+             * @private
+             */
+            transition: function(easingValue) {
+                var me = this;
 
-				Chart.animationService.addAnimation(me, animation, duration, lazy);
-			} else {
-				me.draw();
-				if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) {
-					animationOptions.onComplete.call(me);
-				}
-			}
-			return me;
-		},
+                for (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {
+                    if (me.isDatasetVisible(i)) {
+                        me.getDatasetMeta(i).controller.transition(easingValue);
+                    }
+                }
 
-		draw: function(ease) {
-			var me = this;
-			var easingDecimal = ease || 1;
-			me.clear();
+                me.tooltip.transition(easingValue);
+            },
 
-			Chart.plugins.notify('beforeDraw', [me, easingDecimal]);
+            /**
+             * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
+             * hook, in which case, plugins will not be called on `afterDatasetsDraw`.
+             * @private
+             */
+            drawDatasets: function(easingValue) {
+                var me = this;
 
-			// Draw all the scales
-			helpers.each(me.boxes, function(box) {
-				box.draw(me.chartArea);
-			}, me);
-			if (me.scale) {
-				me.scale.draw();
-			}
+                if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
+                    return;
+                }
 
-			Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]);
+                // Draw datasets reversed to support proper line stacking
+                for (var i=(me.data.datasets || []).length - 1; i >= 0; --i) {
+                    if (me.isDatasetVisible(i)) {
+                        me.drawDataset(i, easingValue);
+                    }
+                }
 
-			// Draw each dataset via its respective controller (reversed to support proper line stacking)
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					me.getDatasetMeta(datasetIndex).controller.draw(ease);
-				}
-			}, me, true);
+                plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
+            },
 
-			Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]);
+            /**
+             * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`
+             * hook, in which case, plugins will not be called on `afterDatasetDraw`.
+             * @private
+             */
+            drawDataset: function(index, easingValue) {
+                var me = this;
+                var meta = me.getDatasetMeta(index);
+                var args = {
+                    meta: meta,
+                    index: index,
+                    easingValue: easingValue
+                };
 
-			// Finally draw the tooltip
-			me.tooltip.transition(easingDecimal).draw();
+                if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
+                    return;
+                }
 
-			Chart.plugins.notify('afterDraw', [me, easingDecimal]);
-		},
+                meta.controller.draw(easingValue);
 
-		// Get the single element that was clicked on
-		// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
-		getElementAtEvent: function(e) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+                plugins.notify(me, 'afterDatasetDraw', [args]);
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex);
-					helpers.each(meta.data, function(element) {
-						if (element.inRange(eventPosition.x, eventPosition.y)) {
-							elementsArray.push(element);
-							return elementsArray;
-						}
-					});
-				}
-			});
+            // Get the single element that was clicked on
+            // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
+            getElementAtEvent: function(e) {
+                return Chart.Interaction.modes.single(this, e);
+            },
 
-			return elementsArray.slice(0, 1);
-		},
+            getElementsAtEvent: function(e) {
+                return Chart.Interaction.modes.label(this, e, {intersect: true});
+            },
 
-		getElementsAtEvent: function(e) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+            getElementsAtXAxis: function(e) {
+                return Chart.Interaction.modes['x-axis'](this, e, {intersect: true});
+            },
 
-			var found = (function() {
-				if (me.data.datasets) {
-					for (var i = 0; i < me.data.datasets.length; i++) {
-						var meta = me.getDatasetMeta(i);
-						if (me.isDatasetVisible(i)) {
-							for (var j = 0; j < meta.data.length; j++) {
-								if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {
-									return meta.data[j];
-								}
-							}
-						}
-					}
-				}
-			}).call(me);
+            getElementsAtEventForMode: function(e, mode, options) {
+                var method = Chart.Interaction.modes[mode];
+                if (typeof method === 'function') {
+                    return method(this, e, options);
+                }
 
-			if (!found) {
-				return elementsArray;
-			}
+                return [];
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex),
-						element = meta.data[found._index];
-					if(element && !element._view.skip){
-						elementsArray.push(element);
-					}
-				}
-			}, me);
+            getDatasetAtEvent: function(e) {
+                return Chart.Interaction.modes.dataset(this, e, {intersect: true});
+            },
 
-			return elementsArray;
-		},
+            getDatasetMeta: function(datasetIndex) {
+                var me = this;
+                var dataset = me.data.datasets[datasetIndex];
+                if (!dataset._meta) {
+                    dataset._meta = {};
+                }
 
-		getElementsAtXAxis: function(e) {
-			var me = this;
-			var eventPosition = helpers.getRelativePosition(e, me.chart);
-			var elementsArray = [];
+                var meta = dataset._meta[me.id];
+                if (!meta) {
+                    meta = dataset._meta[me.id] = {
+                        type: null,
+                        data: [],
+                        dataset: null,
+                        controller: null,
+                        hidden: null,			// See isDatasetVisible() comment
+                        xAxisID: null,
+                        yAxisID: null
+                    };
+                }
 
-			var found = (function() {
-				if (me.data.datasets) {
-					for (var i = 0; i < me.data.datasets.length; i++) {
-						var meta = me.getDatasetMeta(i);
-						if (me.isDatasetVisible(i)) {
-							for (var j = 0; j < meta.data.length; j++) {
-								if (meta.data[j].inLabelRange(eventPosition.x, eventPosition.y)) {
-									return meta.data[j];
-								}
-							}
-						}
-					}
-				}
-			}).call(me);
+                return meta;
+            },
 
-			if (!found) {
-				return elementsArray;
-			}
+            getVisibleDatasetCount: function() {
+                var count = 0;
+                for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
+                    if (this.isDatasetVisible(i)) {
+                        count++;
+                    }
+                }
+                return count;
+            },
 
-			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
-				if (me.isDatasetVisible(datasetIndex)) {
-					var meta = me.getDatasetMeta(datasetIndex);
-					var index = helpers.findIndex(meta.data, function (it) {
-						return found._model.x === it._model.x;
-					});
-					if(index !== -1 && !meta.data[index]._view.skip) {
-						elementsArray.push(meta.data[index]);
-					}
-				}
-			}, me);
+            isDatasetVisible: function(datasetIndex) {
+                var meta = this.getDatasetMeta(datasetIndex);
 
-			return elementsArray;
-		},		
+                // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
+                // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
+                return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
+            },
 
-		getElementsAtEventForMode: function(e, mode) {
-			var me = this;
-			switch (mode) {
-			case 'single':
-				return me.getElementAtEvent(e);
-			case 'label':
-				return me.getElementsAtEvent(e);
-			case 'dataset':
-				return me.getDatasetAtEvent(e);
-            case 'x-axis':
-                return me.getElementsAtXAxis(e);
-			default:
-				return e;
-			}
-		},
+            generateLegend: function() {
+                return this.options.legendCallback(this);
+            },
 
-		getDatasetAtEvent: function(e) {
-			var elementsArray = this.getElementAtEvent(e);
+            destroy: function() {
+                var me = this;
+                var canvas = me.canvas;
+                var meta, i, ilen;
 
-			if (elementsArray.length > 0) {
-				elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;
-			}
+                me.stop();
 
-			return elementsArray;
-		},
+                // dataset controllers need to cleanup associated data
+                for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
+                    meta = me.getDatasetMeta(i);
+                    if (meta.controller) {
+                        meta.controller.destroy();
+                        meta.controller = null;
+                    }
+                }
 
-		getDatasetMeta: function(datasetIndex) {
-			var me = this;
-			var dataset = me.data.datasets[datasetIndex];
-			if (!dataset._meta) {
-				dataset._meta = {};
-			}
+                if (canvas) {
+                    me.unbindEvents();
+                    helpers.clear(me);
+                    platform.releaseContext(me.ctx);
+                    me.canvas = null;
+                    me.ctx = null;
+                }
 
-			var meta = dataset._meta[me.id];
-			if (!meta) {
-				meta = dataset._meta[me.id] = {
-				type: null,
-				data: [],
-				dataset: null,
-				controller: null,
-				hidden: null,			// See isDatasetVisible() comment
-				xAxisID: null,
-				yAxisID: null
-			};
-			}
+                plugins.notify(me, 'destroy');
 
-			return meta;
-		},
+                delete Chart.instances[me.id];
+            },
 
-		getVisibleDatasetCount: function() {
-			var count = 0;
-			for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
-				 if (this.isDatasetVisible(i)) {
-					count++;
-				}
-			}
-			return count;
-		},
+            toBase64Image: function() {
+                return this.canvas.toDataURL.apply(this.canvas, arguments);
+            },
 
-		isDatasetVisible: function(datasetIndex) {
-			var meta = this.getDatasetMeta(datasetIndex);
+            initToolTip: function() {
+                var me = this;
+                me.tooltip = new Chart.Tooltip({
+                    _chart: me,
+                    _chartInstance: me,            // deprecated, backward compatibility
+                    _data: me.data,
+                    _options: me.options.tooltips
+                }, me);
+                me.tooltip.initialize();
+            },
 
-			// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
-			// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
-			return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
-		},
+            /**
+             * @private
+             */
+            bindEvents: function() {
+                var me = this;
+                var listeners = me._listeners = {};
+                var listener = function() {
+                    me.eventHandler.apply(me, arguments);
+                };
 
-		generateLegend: function() {
-			return this.options.legendCallback(this);
-		},
+                helpers.each(me.options.events, function(type) {
+                    platform.addEventListener(me, type, listener);
+                    listeners[type] = listener;
+                });
 
-		destroy: function() {
-			var me = this;
-			me.stop();
-			me.clear();
-			helpers.unbindEvents(me, me.events);
-			helpers.removeResizeListener(me.chart.canvas.parentNode);
+                // Responsiveness is currently based on the use of an iframe, however this method causes
+                // performance issues and could be troublesome when used with ad blockers. So make sure
+                // that the user is still able to create a chart without iframe when responsive is false.
+                // See https://github.com/chartjs/Chart.js/issues/2210
+                if (me.options.responsive) {
+                    listener = function() {
+                        me.resize();
+                    };
 
-			// Reset canvas height/width attributes
-			var canvas = me.chart.canvas;
-			canvas.width = me.chart.width;
-			canvas.height = me.chart.height;
+                    platform.addEventListener(me, 'resize', listener);
+                    listeners.resize = listener;
+                }
+            },
 
-			// if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here
-			if (me.chart.originalDevicePixelRatio !== undefined) {
-				me.chart.ctx.scale(1 / me.chart.originalDevicePixelRatio, 1 / me.chart.originalDevicePixelRatio);
-			}
+            /**
+             * @private
+             */
+            unbindEvents: function() {
+                var me = this;
+                var listeners = me._listeners;
+                if (!listeners) {
+                    return;
+                }
 
-			// Reset to the old style since it may have been changed by the device pixel ratio changes
-			canvas.style.width = me.chart.originalCanvasStyleWidth;
-			canvas.style.height = me.chart.originalCanvasStyleHeight;
+                delete me._listeners;
+                helpers.each(listeners, function(listener, type) {
+                    platform.removeEventListener(me, type, listener);
+                });
+            },
 
-			Chart.plugins.notify('destroy', [me]);
+            updateHoverStyle: function(elements, mode, enabled) {
+                var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
+                var element, i, ilen;
 
-			delete Chart.instances[me.id];
-		},
+                for (i=0, ilen=elements.length; i<ilen; ++i) {
+                    element = elements[i];
+                    if (element) {
+                        this.getDatasetMeta(element._datasetIndex).controller[method](element);
+                    }
+                }
+            },
 
-		toBase64Image: function() {
-			return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
-		},
+            /**
+             * @private
+             */
+            eventHandler: function(e) {
+                var me = this;
+                var tooltip = me.tooltip;
 
-		initToolTip: function() {
-			var me = this;
-			me.tooltip = new Chart.Tooltip({
-				_chart: me.chart,
-				_chartInstance: me,
-				_data: me.data,
-				_options: me.options.tooltips
-			}, me);
-		},
+                if (plugins.notify(me, 'beforeEvent', [e]) === false) {
+                    return;
+                }
 
-		bindEvents: function() {
-			var me = this;
-			helpers.bindEvents(me, me.options.events, function(evt) {
-				me.eventHandler(evt);
-			});
-		},
+                // Buffer any update calls so that renders do not occur
+                me._bufferedRender = true;
+                me._bufferedRequest = null;
 
-		updateHoverStyle: function(elements, mode, enabled) {
-			var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
-			var element, i, ilen;
+                var changed = me.handleEvent(e);
+                changed |= tooltip && tooltip.handleEvent(e);
 
-			switch (mode) {
-			case 'single':
-				elements = [ elements[0] ];
-				break;
-			case 'label':
-			case 'dataset':
-            case 'x-axis':
-				// elements = elements;
-				break;
-			default:
-				// unsupported mode
-				return;
-			}
+                plugins.notify(me, 'afterEvent', [e]);
 
-			for (i=0, ilen=elements.length; i<ilen; ++i) {
-				element = elements[i];
-				if (element) {
-					this.getDatasetMeta(element._datasetIndex).controller[method](element);
-				}
-			}
-		},
+                var bufferedRequest = me._bufferedRequest;
+                if (bufferedRequest) {
+                    // If we have an update that was triggered, we need to do a normal render
+                    me.render(bufferedRequest.duration, bufferedRequest.lazy);
+                } else if (changed && !me.animating) {
+                    // If entering, leaving, or changing elements, animate the change via pivot
+                    me.stop();
 
-		eventHandler: function eventHandler(e) {
-			var me = this;
-			var tooltip = me.tooltip;
-			var options = me.options || {};
-			var hoverOptions = options.hover;
-			var tooltipsOptions = options.tooltips;
+                    // We only need to render at this point. Updating will cause scales to be
+                    // recomputed generating flicker & using more memory than necessary.
+                    me.render(me.options.hover.animationDuration, true);
+                }
 
-			me.lastActive = me.lastActive || [];
-			me.lastTooltipActive = me.lastTooltipActive || [];
+                me._bufferedRender = false;
+                me._bufferedRequest = null;
 
-			// Find Active Elements for hover and tooltips
-			if (e.type === 'mouseout') {
-				me.active = [];
-				me.tooltipActive = [];
-			} else {
-				me.active = me.getElementsAtEventForMode(e, hoverOptions.mode);
-				me.tooltipActive =  me.getElementsAtEventForMode(e, tooltipsOptions.mode);
-			}
+                return me;
+            },
 
-			// On Hover hook
-			if (hoverOptions.onHover) {
-				hoverOptions.onHover.call(me, me.active);
-			}
+            /**
+             * Handle an event
+             * @private
+             * @param {IEvent} event the event to handle
+             * @return {Boolean} true if the chart needs to re-render
+             */
+            handleEvent: function(e) {
+                var me = this;
+                var options = me.options || {};
+                var hoverOptions = options.hover;
+                var changed = false;
 
-			if (e.type === 'mouseup' || e.type === 'click') {
-				if (options.onClick) {
-					options.onClick.call(me, e, me.active);
-				}
-				if (me.legend && me.legend.handleEvent) {
-					me.legend.handleEvent(e);
-				}
-			}
+                me.lastActive = me.lastActive || [];
 
-			// Remove styling for last active (even if it may still be active)
-			if (me.lastActive.length) {
-				me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
-			}
+                // Find Active Elements for hover and tooltips
+                if (e.type === 'mouseout') {
+                    me.active = [];
+                } else {
+                    me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
+                }
 
-			// Built in hover styling
-			if (me.active.length && hoverOptions.mode) {
-				me.updateHoverStyle(me.active, hoverOptions.mode, true);
-			}
+                // On Hover hook
+                if (hoverOptions.onHover) {
+                    // Need to call with native event here to not break backwards compatibility
+                    hoverOptions.onHover.call(me, e.native, me.active);
+                }
 
-			// Built in Tooltips
-			if (tooltipsOptions.enabled || tooltipsOptions.custom) {
-				tooltip.initialize();
-				tooltip._active = me.tooltipActive;
-				tooltip.update(true);
-			}
+                if (e.type === 'mouseup' || e.type === 'click') {
+                    if (options.onClick) {
+                        // Use e.native here for backwards compatibility
+                        options.onClick.call(me, e.native, me.active);
+                    }
+                }
 
-			// Hover animations
-			tooltip.pivot();
+                // Remove styling for last active (even if it may still be active)
+                if (me.lastActive.length) {
+                    me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
+                }
 
-			if (!me.animating) {
-				// If entering, leaving, or changing elements, animate the change via pivot
-				if (!helpers.arrayEquals(me.active, me.lastActive) ||
-					!helpers.arrayEquals(me.tooltipActive, me.lastTooltipActive)) {
+                // Built in hover styling
+                if (me.active.length && hoverOptions.mode) {
+                    me.updateHoverStyle(me.active, hoverOptions.mode, true);
+                }
 
-					me.stop();
+                changed = !helpers.arrayEquals(me.active, me.lastActive);
 
-					if (tooltipsOptions.enabled || tooltipsOptions.custom) {
-						tooltip.update(true);
-					}
+                // Remember Last Actives
+                me.lastActive = me.active;
 
-					// We only need to render at this point. Updating will cause scales to be
-					// recomputed generating flicker & using more memory than necessary.
-					me.render(hoverOptions.animationDuration, true);
-				}
-			}
+                return changed;
+            }
+        });
 
-			// Remember Last Actives
-			me.lastActive = me.active;
-			me.lastTooltipActive = me.tooltipActive;
-			return me;
-		}
-	});
-};
+        /**
+         * Provided for backward compatibility, use Chart instead.
+         * @class Chart.Controller
+         * @deprecated since version 2.6.0
+         * @todo remove at version 3
+         * @private
+         */
+        Chart.Controller = Chart;
+    };
 
 },{}],24:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var noop = helpers.noop;
+        var helpers = Chart.helpers;
 
-	// Base class for all dataset controllers (line, bar, etc)
-	Chart.DatasetController = function(chart, datasetIndex) {
-		this.initialize.call(this, chart, datasetIndex);
-	};
+        var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
 
-	helpers.extend(Chart.DatasetController.prototype, {
+        /**
+         * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
+         * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
+         * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
+         */
+        function listenArrayEvents(array, listener) {
+            if (array._chartjs) {
+                array._chartjs.listeners.push(listener);
+                return;
+            }
 
-		/**
-		 * Element type used to generate a meta dataset (e.g. Chart.element.Line).
-		 * @type {Chart.core.element}
-		 */
-		datasetElementType: null,
+            Object.defineProperty(array, '_chartjs', {
+                configurable: true,
+                enumerable: false,
+                value: {
+                    listeners: [listener]
+                }
+            });
 
-		/**
-		 * Element type used to generate a meta data (e.g. Chart.element.Point).
-		 * @type {Chart.core.element}
-		 */
-		dataElementType: null,
+            arrayEvents.forEach(function(key) {
+                var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
+                var base = array[key];
 
-		initialize: function(chart, datasetIndex) {
-			var me = this;
-			me.chart = chart;
-			me.index = datasetIndex;
-			me.linkScales();
-			me.addElements();
-		},
+                Object.defineProperty(array, key, {
+                    configurable: true,
+                    enumerable: false,
+                    value: function() {
+                        var args = Array.prototype.slice.call(arguments);
+                        var res = base.apply(this, args);
 
-		updateIndex: function(datasetIndex) {
-			this.index = datasetIndex;
-		},
+                        helpers.each(array._chartjs.listeners, function(object) {
+                            if (typeof object[method] === 'function') {
+                                object[method].apply(object, args);
+                            }
+                        });
 
-		linkScales: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var dataset = me.getDataset();
+                        return res;
+                    }
+                });
+            });
+        }
 
-			if (meta.xAxisID === null) {
-				meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
-			}
-			if (meta.yAxisID === null) {
-				meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
-			}
-		},
+        /**
+         * Removes the given array event listener and cleanup extra attached properties (such as
+         * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
+         */
+        function unlistenArrayEvents(array, listener) {
+            var stub = array._chartjs;
+            if (!stub) {
+                return;
+            }
 
-		getDataset: function() {
-			return this.chart.data.datasets[this.index];
-		},
+            var listeners = stub.listeners;
+            var index = listeners.indexOf(listener);
+            if (index !== -1) {
+                listeners.splice(index, 1);
+            }
 
-		getMeta: function() {
-			return this.chart.getDatasetMeta(this.index);
-		},
+            if (listeners.length > 0) {
+                return;
+            }
 
-		getScaleForId: function(scaleID) {
-			return this.chart.scales[scaleID];
-		},
+            arrayEvents.forEach(function(key) {
+                delete array[key];
+            });
 
-		reset: function() {
-			this.update(true);
-		},
+            delete array._chartjs;
+        }
 
-		createMetaDataset: function() {
-			var me = this;
-			var type = me.datasetElementType;
-			return type && new type({
-				_chart: me.chart.chart,
-				_datasetIndex: me.index
-			});
-		},
+        // Base class for all dataset controllers (line, bar, etc)
+        Chart.DatasetController = function(chart, datasetIndex) {
+            this.initialize(chart, datasetIndex);
+        };
 
-		createMetaData: function(index) {
-			var me = this;
-			var type = me.dataElementType;
-			return type && new type({
-				_chart: me.chart.chart,
-				_datasetIndex: me.index,
-				_index: index
-			});
-		},
+        helpers.extend(Chart.DatasetController.prototype, {
 
-		addElements: function() {
-			var me = this;
-			var meta = me.getMeta();
-			var data = me.getDataset().data || [];
-			var metaData = meta.data;
-			var i, ilen;
+            /**
+             * Element type used to generate a meta dataset (e.g. Chart.element.Line).
+             * @type {Chart.core.element}
+             */
+            datasetElementType: null,
 
-			for (i=0, ilen=data.length; i<ilen; ++i) {
-				metaData[i] = metaData[i] || me.createMetaData(meta, i);
-			}
+            /**
+             * Element type used to generate a meta data (e.g. Chart.element.Point).
+             * @type {Chart.core.element}
+             */
+            dataElementType: null,
 
-			meta.dataset = meta.dataset || me.createMetaDataset();
-		},
+            initialize: function(chart, datasetIndex) {
+                var me = this;
+                me.chart = chart;
+                me.index = datasetIndex;
+                me.linkScales();
+                me.addElements();
+            },
 
-		addElementAndReset: function(index) {
-			var me = this;
-			var element = me.createMetaData(index);
-			me.getMeta().data.splice(index, 0, element);
-			me.updateElement(element, index, true);
-		},
+            updateIndex: function(datasetIndex) {
+                this.index = datasetIndex;
+            },
 
-		buildOrUpdateElements: function() {
-			// Handle the number of data points changing
-			var meta = this.getMeta(),
-				md = meta.data,
-				numData = this.getDataset().data.length,
-				numMetaData = md.length;
+            linkScales: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var dataset = me.getDataset();
 
-			// Make sure that we handle number of datapoints changing
-			if (numData < numMetaData) {
-				// Remove excess bars for data points that have been removed
-				md.splice(numData, numMetaData - numData);
-			} else if (numData > numMetaData) {
-				// Add new elements
-				for (var index = numMetaData; index < numData; ++index) {
-					this.addElementAndReset(index);
-				}
-			}
-		},
+                if (meta.xAxisID === null) {
+                    meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
+                }
+                if (meta.yAxisID === null) {
+                    meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
+                }
+            },
 
-		update: noop,
+            getDataset: function() {
+                return this.chart.data.datasets[this.index];
+            },
 
-		draw: function(ease) {
-			var easingDecimal = ease || 1;
-			helpers.each(this.getMeta().data, function(element) {
-				element.transition(easingDecimal).draw();
-			});
-		},
+            getMeta: function() {
+                return this.chart.getDatasetMeta(this.index);
+            },
 
-		removeHoverStyle: function(element, elementOpts) {
-			var dataset = this.chart.data.datasets[element._datasetIndex],
-				index = element._index,
-				custom = element.custom || {},
-				valueOrDefault = helpers.getValueAtIndexOrDefault,
-				model = element._model;
+            getScaleForId: function(scaleID) {
+                return this.chart.scales[scaleID];
+            },
 
-			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
-			model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
-			model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
-		},
+            reset: function() {
+                this.update(true);
+            },
 
-		setHoverStyle: function(element) {
-			var dataset = this.chart.data.datasets[element._datasetIndex],
-				index = element._index,
-				custom = element.custom || {},
-				valueOrDefault = helpers.getValueAtIndexOrDefault,
-				getHoverColor = helpers.getHoverColor,
-				model = element._model;
+            /**
+             * @private
+             */
+            destroy: function() {
+                if (this._data) {
+                    unlistenArrayEvents(this._data, this);
+                }
+            },
 
-			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
-			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
-			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
-		}
-		
-    });
-	
+            createMetaDataset: function() {
+                var me = this;
+                var type = me.datasetElementType;
+                return type && new type({
+                        _chart: me.chart,
+                        _datasetIndex: me.index
+                    });
+            },
 
-	Chart.DatasetController.extend = helpers.inherits;
-};
+            createMetaData: function(index) {
+                var me = this;
+                var type = me.dataElementType;
+                return type && new type({
+                        _chart: me.chart,
+                        _datasetIndex: me.index,
+                        _index: index
+                    });
+            },
+
+            addElements: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var data = me.getDataset().data || [];
+                var metaData = meta.data;
+                var i, ilen;
+
+                for (i=0, ilen=data.length; i<ilen; ++i) {
+                    metaData[i] = metaData[i] || me.createMetaData(i);
+                }
+
+                meta.dataset = meta.dataset || me.createMetaDataset();
+            },
+
+            addElementAndReset: function(index) {
+                var element = this.createMetaData(index);
+                this.getMeta().data.splice(index, 0, element);
+                this.updateElement(element, index, true);
+            },
+
+            buildOrUpdateElements: function() {
+                var me = this;
+                var dataset = me.getDataset();
+                var data = dataset.data || (dataset.data = []);
+
+                // In order to correctly handle data addition/deletion animation (an thus simulate
+                // real-time charts), we need to monitor these data modifications and synchronize
+                // the internal meta data accordingly.
+                if (me._data !== data) {
+                    if (me._data) {
+                        // This case happens when the user replaced the data array instance.
+                        unlistenArrayEvents(me._data, me);
+                    }
+
+                    listenArrayEvents(data, me);
+                    me._data = data;
+                }
+
+                // Re-sync meta data in case the user replaced the data array or if we missed
+                // any updates and so make sure that we handle number of datapoints changing.
+                me.resyncElements();
+            },
+
+            update: helpers.noop,
+
+            transition: function(easingValue) {
+                var meta = this.getMeta();
+                var elements = meta.data || [];
+                var ilen = elements.length;
+                var i = 0;
+
+                for (; i<ilen; ++i) {
+                    elements[i].transition(easingValue);
+                }
+
+                if (meta.dataset) {
+                    meta.dataset.transition(easingValue);
+                }
+            },
+
+            draw: function() {
+                var meta = this.getMeta();
+                var elements = meta.data || [];
+                var ilen = elements.length;
+                var i = 0;
+
+                if (meta.dataset) {
+                    meta.dataset.draw();
+                }
+
+                for (; i<ilen; ++i) {
+                    elements[i].draw();
+                }
+            },
+
+            removeHoverStyle: function(element, elementOpts) {
+                var dataset = this.chart.data.datasets[element._datasetIndex],
+                    index = element._index,
+                    custom = element.custom || {},
+                    valueOrDefault = helpers.getValueAtIndexOrDefault,
+                    model = element._model;
+
+                model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
+                model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
+                model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
+            },
+
+            setHoverStyle: function(element) {
+                var dataset = this.chart.data.datasets[element._datasetIndex],
+                    index = element._index,
+                    custom = element.custom || {},
+                    valueOrDefault = helpers.getValueAtIndexOrDefault,
+                    getHoverColor = helpers.getHoverColor,
+                    model = element._model;
+
+                model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
+                model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
+                model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
+            },
+
+            /**
+             * @private
+             */
+            resyncElements: function() {
+                var me = this;
+                var meta = me.getMeta();
+                var data = me.getDataset().data;
+                var numMeta = meta.data.length;
+                var numData = data.length;
+
+                if (numData < numMeta) {
+                    meta.data.splice(numData, numMeta - numData);
+                } else if (numData > numMeta) {
+                    me.insertElements(numMeta, numData - numMeta);
+                }
+            },
+
+            /**
+             * @private
+             */
+            insertElements: function(start, count) {
+                for (var i=0; i<count; ++i) {
+                    this.addElementAndReset(start + i);
+                }
+            },
+
+            /**
+             * @private
+             */
+            onDataPush: function() {
+                this.insertElements(this.getDataset().data.length-1, arguments.length);
+            },
+
+            /**
+             * @private
+             */
+            onDataPop: function() {
+                this.getMeta().data.pop();
+            },
+
+            /**
+             * @private
+             */
+            onDataShift: function() {
+                this.getMeta().data.shift();
+            },
+
+            /**
+             * @private
+             */
+            onDataSplice: function(start, count) {
+                this.getMeta().data.splice(start, count);
+                this.insertElements(start, arguments.length - 2);
+            },
+
+            /**
+             * @private
+             */
+            onDataUnshift: function() {
+                this.insertElements(0, arguments.length);
+            }
+        });
+
+        Chart.DatasetController.extend = helpers.inherits;
+    };
+
 },{}],25:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    var color = require(3);
 
-  var helpers = Chart.helpers;
+    module.exports = function(Chart) {
 
-  Chart.elements = {};
+        var helpers = Chart.helpers;
 
-  Chart.Element = function(configuration) {
-    helpers.extend(this, configuration);
-    this.initialize.apply(this, arguments);
-  };
+        function interpolate(start, view, model, ease) {
+            var keys = Object.keys(model);
+            var i, ilen, key, actual, origin, target, type, c0, c1;
 
-  helpers.extend(Chart.Element.prototype, {
+            for (i=0, ilen=keys.length; i<ilen; ++i) {
+                key = keys[i];
 
-    initialize: function() {
-      this.hidden = false;
-    },
+                target = model[key];
 
-    pivot: function() {
-      var me = this;
-      if (!me._view) {
-        me._view = helpers.clone(me._model);
-      }
-      me._start = helpers.clone(me._view);
-      return me;
-    },
+                // if a value is added to the model after pivot() has been called, the view
+                // doesn't contain it, so let's initialize the view to the target value.
+                if (!view.hasOwnProperty(key)) {
+                    view[key] = target;
+                }
 
-    transition: function(ease) {
-      var me = this;
-      
-      if (!me._view) {
-        me._view = helpers.clone(me._model);
-      }
+                actual = view[key];
 
-      // No animation -> No Transition
-      if (ease === 1) {
-        me._view = me._model;
-        me._start = null;
-        return me;
-      }
+                if (actual === target || key[0] === '_') {
+                    continue;
+                }
 
-      if (!me._start) {
-        me.pivot();
-      }
+                if (!start.hasOwnProperty(key)) {
+                    start[key] = actual;
+                }
 
-      helpers.each(me._model, function(value, key) {
+                origin = start[key];
 
-        if (key[0] === '_') {
-          // Only non-underscored properties
+                type = typeof(target);
+
+                if (type === typeof(origin)) {
+                    if (type === 'string') {
+                        c0 = color(origin);
+                        if (c0.valid) {
+                            c1 = color(target);
+                            if (c1.valid) {
+                                view[key] = c1.mix(c0, ease).rgbString();
+                                continue;
+                            }
+                        }
+                    } else if (type === 'number' && isFinite(origin) && isFinite(target)) {
+                        view[key] = origin + (target - origin) * ease;
+                        continue;
+                    }
+                }
+
+                view[key] = target;
+            }
         }
 
-        // Init if doesn't exist
-        else if (!me._view.hasOwnProperty(key)) {
-          if (typeof value === 'number' && !isNaN(me._view[key])) {
-            me._view[key] = value * ease;
-          } else {
-            me._view[key] = value;
-          }
+        Chart.elements = {};
+
+        Chart.Element = function(configuration) {
+            helpers.extend(this, configuration);
+            this.initialize.apply(this, arguments);
+        };
+
+        helpers.extend(Chart.Element.prototype, {
+
+            initialize: function() {
+                this.hidden = false;
+            },
+
+            pivot: function() {
+                var me = this;
+                if (!me._view) {
+                    me._view = helpers.clone(me._model);
+                }
+                me._start = {};
+                return me;
+            },
+
+            transition: function(ease) {
+                var me = this;
+                var model = me._model;
+                var start = me._start;
+                var view = me._view;
+
+                // No animation -> No Transition
+                if (!model || ease === 1) {
+                    me._view = model;
+                    me._start = null;
+                    return me;
+                }
+
+                if (!view) {
+                    view = me._view = {};
+                }
+
+                if (!start) {
+                    start = me._start = {};
+                }
+
+                interpolate(start, view, model, ease);
+
+                return me;
+            },
+
+            tooltipPosition: function() {
+                return {
+                    x: this._model.x,
+                    y: this._model.y
+                };
+            },
+
+            hasValue: function() {
+                return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
+            }
+        });
+
+        Chart.Element.extend = helpers.inherits;
+    };
+
+},{"3":3}],26:[function(require,module,exports){
+    /* global window: false */
+    /* global document: false */
+    'use strict';
+
+    var color = require(3);
+
+    module.exports = function(Chart) {
+        // Global Chart helpers object for utility methods and classes
+        var helpers = Chart.helpers = {};
+
+        // -- Basic js utility methods
+        helpers.each = function(loopable, callback, self, reverse) {
+            // Check to see if null or undefined firstly.
+            var i, len;
+            if (helpers.isArray(loopable)) {
+                len = loopable.length;
+                if (reverse) {
+                    for (i = len - 1; i >= 0; i--) {
+                        callback.call(self, loopable[i], i);
+                    }
+                } else {
+                    for (i = 0; i < len; i++) {
+                        callback.call(self, loopable[i], i);
+                    }
+                }
+            } else if (typeof loopable === 'object') {
+                var keys = Object.keys(loopable);
+                len = keys.length;
+                for (i = 0; i < len; i++) {
+                    callback.call(self, loopable[keys[i]], keys[i]);
+                }
+            }
+        };
+        helpers.clone = function(obj) {
+            var objClone = {};
+            helpers.each(obj, function(value, key) {
+                if (helpers.isArray(value)) {
+                    objClone[key] = value.slice(0);
+                } else if (typeof value === 'object' && value !== null) {
+                    objClone[key] = helpers.clone(value);
+                } else {
+                    objClone[key] = value;
+                }
+            });
+            return objClone;
+        };
+        helpers.extend = function(base) {
+            var setFn = function(value, key) {
+                base[key] = value;
+            };
+            for (var i = 1, ilen = arguments.length; i < ilen; i++) {
+                helpers.each(arguments[i], setFn);
+            }
+            return base;
+        };
+        // Need a special merge function to chart configs since they are now grouped
+        helpers.configMerge = function(_base) {
+            var base = helpers.clone(_base);
+            helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
+                helpers.each(extension, function(value, key) {
+                    var baseHasProperty = base.hasOwnProperty(key);
+                    var baseVal = baseHasProperty ? base[key] : {};
+
+                    if (key === 'scales') {
+                        // Scale config merging is complex. Add our own function here for that
+                        base[key] = helpers.scaleMerge(baseVal, value);
+                    } else if (key === 'scale') {
+                        // Used in polar area & radar charts since there is only one scale
+                        base[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);
+                    } else if (baseHasProperty
+                        && typeof baseVal === 'object'
+                        && !helpers.isArray(baseVal)
+                        && baseVal !== null
+                        && typeof value === 'object'
+                        && !helpers.isArray(value)) {
+                        // If we are overwriting an object with an object, do a merge of the properties.
+                        base[key] = helpers.configMerge(baseVal, value);
+                    } else {
+                        // can just overwrite the value in this case
+                        base[key] = value;
+                    }
+                });
+            });
+
+            return base;
+        };
+        helpers.scaleMerge = function(_base, extension) {
+            var base = helpers.clone(_base);
+
+            helpers.each(extension, function(value, key) {
+                if (key === 'xAxes' || key === 'yAxes') {
+                    // These properties are arrays of items
+                    if (base.hasOwnProperty(key)) {
+                        helpers.each(value, function(valueObj, index) {
+                            var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
+                            var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);
+                            if (index >= base[key].length || !base[key][index].type) {
+                                base[key].push(helpers.configMerge(axisDefaults, valueObj));
+                            } else if (valueObj.type && valueObj.type !== base[key][index].type) {
+                                // Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults
+                                base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);
+                            } else {
+                                // Type is the same
+                                base[key][index] = helpers.configMerge(base[key][index], valueObj);
+                            }
+                        });
+                    } else {
+                        base[key] = [];
+                        helpers.each(value, function(valueObj) {
+                            var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
+                            base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));
+                        });
+                    }
+                } else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {
+                    // If we are overwriting an object with an object, do a merge of the properties.
+                    base[key] = helpers.configMerge(base[key], value);
+
+                } else {
+                    // can just overwrite the value in this case
+                    base[key] = value;
+                }
+            });
+
+            return base;
+        };
+        helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
+            if (value === undefined || value === null) {
+                return defaultValue;
+            }
+
+            if (helpers.isArray(value)) {
+                return index < value.length ? value[index] : defaultValue;
+            }
+
+            return value;
+        };
+        helpers.getValueOrDefault = function(value, defaultValue) {
+            return value === undefined ? defaultValue : value;
+        };
+        helpers.indexOf = Array.prototype.indexOf?
+            function(array, item) {
+                return array.indexOf(item);
+            }:
+            function(array, item) {
+                for (var i = 0, ilen = array.length; i < ilen; ++i) {
+                    if (array[i] === item) {
+                        return i;
+                    }
+                }
+                return -1;
+            };
+        helpers.where = function(collection, filterCallback) {
+            if (helpers.isArray(collection) && Array.prototype.filter) {
+                return collection.filter(filterCallback);
+            }
+            var filtered = [];
+
+            helpers.each(collection, function(item) {
+                if (filterCallback(item)) {
+                    filtered.push(item);
+                }
+            });
+
+            return filtered;
+        };
+        helpers.findIndex = Array.prototype.findIndex?
+            function(array, callback, scope) {
+                return array.findIndex(callback, scope);
+            } :
+            function(array, callback, scope) {
+                scope = scope === undefined? array : scope;
+                for (var i = 0, ilen = array.length; i < ilen; ++i) {
+                    if (callback.call(scope, array[i], i, array)) {
+                        return i;
+                    }
+                }
+                return -1;
+            };
+        helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
+            // Default to start of the array
+            if (startIndex === undefined || startIndex === null) {
+                startIndex = -1;
+            }
+            for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
+                var currentItem = arrayToSearch[i];
+                if (filterCallback(currentItem)) {
+                    return currentItem;
+                }
+            }
+        };
+        helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
+            // Default to end of the array
+            if (startIndex === undefined || startIndex === null) {
+                startIndex = arrayToSearch.length;
+            }
+            for (var i = startIndex - 1; i >= 0; i--) {
+                var currentItem = arrayToSearch[i];
+                if (filterCallback(currentItem)) {
+                    return currentItem;
+                }
+            }
+        };
+        helpers.inherits = function(extensions) {
+            // Basic javascript inheritance based on the model created in Backbone.js
+            var me = this;
+            var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
+                return me.apply(this, arguments);
+            };
+
+            var Surrogate = function() {
+                this.constructor = ChartElement;
+            };
+            Surrogate.prototype = me.prototype;
+            ChartElement.prototype = new Surrogate();
+
+            ChartElement.extend = helpers.inherits;
+
+            if (extensions) {
+                helpers.extend(ChartElement.prototype, extensions);
+            }
+
+            ChartElement.__super__ = me.prototype;
+
+            return ChartElement;
+        };
+        helpers.noop = function() {};
+        helpers.uid = (function() {
+            var id = 0;
+            return function() {
+                return id++;
+            };
+        }());
+        // -- Math methods
+        helpers.isNumber = function(n) {
+            return !isNaN(parseFloat(n)) && isFinite(n);
+        };
+        helpers.almostEquals = function(x, y, epsilon) {
+            return Math.abs(x - y) < epsilon;
+        };
+        helpers.almostWhole = function(x, epsilon) {
+            var rounded = Math.round(x);
+            return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
+        };
+        helpers.max = function(array) {
+            return array.reduce(function(max, value) {
+                if (!isNaN(value)) {
+                    return Math.max(max, value);
+                }
+                return max;
+            }, Number.NEGATIVE_INFINITY);
+        };
+        helpers.min = function(array) {
+            return array.reduce(function(min, value) {
+                if (!isNaN(value)) {
+                    return Math.min(min, value);
+                }
+                return min;
+            }, Number.POSITIVE_INFINITY);
+        };
+        helpers.sign = Math.sign?
+            function(x) {
+                return Math.sign(x);
+            } :
+            function(x) {
+                x = +x; // convert to a number
+                if (x === 0 || isNaN(x)) {
+                    return x;
+                }
+                return x > 0 ? 1 : -1;
+            };
+        helpers.log10 = Math.log10?
+            function(x) {
+                return Math.log10(x);
+            } :
+            function(x) {
+                return Math.log(x) / Math.LN10;
+            };
+        helpers.toRadians = function(degrees) {
+            return degrees * (Math.PI / 180);
+        };
+        helpers.toDegrees = function(radians) {
+            return radians * (180 / Math.PI);
+        };
+        // Gets the angle from vertical upright to the point about a centre.
+        helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
+            var distanceFromXCenter = anglePoint.x - centrePoint.x,
+                distanceFromYCenter = anglePoint.y - centrePoint.y,
+                radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
+
+            var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
+
+            if (angle < (-0.5 * Math.PI)) {
+                angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
+            }
+
+            return {
+                angle: angle,
+                distance: radialDistanceFromCenter
+            };
+        };
+        helpers.distanceBetweenPoints = function(pt1, pt2) {
+            return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
+        };
+        helpers.aliasPixel = function(pixelWidth) {
+            return (pixelWidth % 2 === 0) ? 0 : 0.5;
+        };
+        helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
+            // Props to Rob Spencer at scaled innovation for his post on splining between points
+            // http://scaledinnovation.com/analytics/splines/aboutSplines.html
+
+            // This function must also respect "skipped" points
+
+            var previous = firstPoint.skip ? middlePoint : firstPoint,
+                current = middlePoint,
+                next = afterPoint.skip ? middlePoint : afterPoint;
+
+            var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
+            var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
+
+            var s01 = d01 / (d01 + d12);
+            var s12 = d12 / (d01 + d12);
+
+            // If all points are the same, s01 & s02 will be inf
+            s01 = isNaN(s01) ? 0 : s01;
+            s12 = isNaN(s12) ? 0 : s12;
+
+            var fa = t * s01; // scaling factor for triangle Ta
+            var fb = t * s12;
+
+            return {
+                previous: {
+                    x: current.x - fa * (next.x - previous.x),
+                    y: current.y - fa * (next.y - previous.y)
+                },
+                next: {
+                    x: current.x + fb * (next.x - previous.x),
+                    y: current.y + fb * (next.y - previous.y)
+                }
+            };
+        };
+        helpers.EPSILON = Number.EPSILON || 1e-14;
+        helpers.splineCurveMonotone = function(points) {
+            // This function calculates Bézier control points in a similar way than |splineCurve|,
+            // but preserves monotonicity of the provided data and ensures no local extremums are added
+            // between the dataset discrete points due to the interpolation.
+            // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
+
+            var pointsWithTangents = (points || []).map(function(point) {
+                return {
+                    model: point._model,
+                    deltaK: 0,
+                    mK: 0
+                };
+            });
+
+            // Calculate slopes (deltaK) and initialize tangents (mK)
+            var pointsLen = pointsWithTangents.length;
+            var i, pointBefore, pointCurrent, pointAfter;
+            for (i = 0; i < pointsLen; ++i) {
+                pointCurrent = pointsWithTangents[i];
+                if (pointCurrent.model.skip) {
+                    continue;
+                }
+
+                pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+                pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+                if (pointAfter && !pointAfter.model.skip) {
+                    var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);
+
+                    // In the case of two points that appear at the same x pixel, slopeDeltaX is 0
+                    pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;
+                }
+
+                if (!pointBefore || pointBefore.model.skip) {
+                    pointCurrent.mK = pointCurrent.deltaK;
+                } else if (!pointAfter || pointAfter.model.skip) {
+                    pointCurrent.mK = pointBefore.deltaK;
+                } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {
+                    pointCurrent.mK = 0;
+                } else {
+                    pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
+                }
+            }
+
+            // Adjust tangents to ensure monotonic properties
+            var alphaK, betaK, tauK, squaredMagnitude;
+            for (i = 0; i < pointsLen - 1; ++i) {
+                pointCurrent = pointsWithTangents[i];
+                pointAfter = pointsWithTangents[i + 1];
+                if (pointCurrent.model.skip || pointAfter.model.skip) {
+                    continue;
+                }
+
+                if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {
+                    pointCurrent.mK = pointAfter.mK = 0;
+                    continue;
+                }
+
+                alphaK = pointCurrent.mK / pointCurrent.deltaK;
+                betaK = pointAfter.mK / pointCurrent.deltaK;
+                squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
+                if (squaredMagnitude <= 9) {
+                    continue;
+                }
+
+                tauK = 3 / Math.sqrt(squaredMagnitude);
+                pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
+                pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
+            }
+
+            // Compute control points
+            var deltaX;
+            for (i = 0; i < pointsLen; ++i) {
+                pointCurrent = pointsWithTangents[i];
+                if (pointCurrent.model.skip) {
+                    continue;
+                }
+
+                pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
+                pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
+                if (pointBefore && !pointBefore.model.skip) {
+                    deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
+                    pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
+                    pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
+                }
+                if (pointAfter && !pointAfter.model.skip) {
+                    deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
+                    pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
+                    pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
+                }
+            }
+        };
+        helpers.nextItem = function(collection, index, loop) {
+            if (loop) {
+                return index >= collection.length - 1 ? collection[0] : collection[index + 1];
+            }
+            return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
+        };
+        helpers.previousItem = function(collection, index, loop) {
+            if (loop) {
+                return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
+            }
+            return index <= 0 ? collection[0] : collection[index - 1];
+        };
+        // Implementation of the nice number algorithm used in determining where axis labels will go
+        helpers.niceNum = function(range, round) {
+            var exponent = Math.floor(helpers.log10(range));
+            var fraction = range / Math.pow(10, exponent);
+            var niceFraction;
+
+            if (round) {
+                if (fraction < 1.5) {
+                    niceFraction = 1;
+                } else if (fraction < 3) {
+                    niceFraction = 2;
+                } else if (fraction < 7) {
+                    niceFraction = 5;
+                } else {
+                    niceFraction = 10;
+                }
+            } else if (fraction <= 1.0) {
+                niceFraction = 1;
+            } else if (fraction <= 2) {
+                niceFraction = 2;
+            } else if (fraction <= 5) {
+                niceFraction = 5;
+            } else {
+                niceFraction = 10;
+            }
+
+            return niceFraction * Math.pow(10, exponent);
+        };
+        // Easing functions adapted from Robert Penner's easing equations
+        // http://www.robertpenner.com/easing/
+        var easingEffects = helpers.easingEffects = {
+            linear: function(t) {
+                return t;
+            },
+            easeInQuad: function(t) {
+                return t * t;
+            },
+            easeOutQuad: function(t) {
+                return -1 * t * (t - 2);
+            },
+            easeInOutQuad: function(t) {
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * t * t;
+                }
+                return -1 / 2 * ((--t) * (t - 2) - 1);
+            },
+            easeInCubic: function(t) {
+                return t * t * t;
+            },
+            easeOutCubic: function(t) {
+                return 1 * ((t = t / 1 - 1) * t * t + 1);
+            },
+            easeInOutCubic: function(t) {
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * t * t * t;
+                }
+                return 1 / 2 * ((t -= 2) * t * t + 2);
+            },
+            easeInQuart: function(t) {
+                return t * t * t * t;
+            },
+            easeOutQuart: function(t) {
+                return -1 * ((t = t / 1 - 1) * t * t * t - 1);
+            },
+            easeInOutQuart: function(t) {
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * t * t * t * t;
+                }
+                return -1 / 2 * ((t -= 2) * t * t * t - 2);
+            },
+            easeInQuint: function(t) {
+                return 1 * (t /= 1) * t * t * t * t;
+            },
+            easeOutQuint: function(t) {
+                return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
+            },
+            easeInOutQuint: function(t) {
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * t * t * t * t * t;
+                }
+                return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
+            },
+            easeInSine: function(t) {
+                return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
+            },
+            easeOutSine: function(t) {
+                return 1 * Math.sin(t / 1 * (Math.PI / 2));
+            },
+            easeInOutSine: function(t) {
+                return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
+            },
+            easeInExpo: function(t) {
+                return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
+            },
+            easeOutExpo: function(t) {
+                return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
+            },
+            easeInOutExpo: function(t) {
+                if (t === 0) {
+                    return 0;
+                }
+                if (t === 1) {
+                    return 1;
+                }
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * Math.pow(2, 10 * (t - 1));
+                }
+                return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
+            },
+            easeInCirc: function(t) {
+                if (t >= 1) {
+                    return t;
+                }
+                return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
+            },
+            easeOutCirc: function(t) {
+                return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
+            },
+            easeInOutCirc: function(t) {
+                if ((t /= 1 / 2) < 1) {
+                    return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
+                }
+                return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
+            },
+            easeInElastic: function(t) {
+                var s = 1.70158;
+                var p = 0;
+                var a = 1;
+                if (t === 0) {
+                    return 0;
+                }
+                if ((t /= 1) === 1) {
+                    return 1;
+                }
+                if (!p) {
+                    p = 1 * 0.3;
+                }
+                if (a < Math.abs(1)) {
+                    a = 1;
+                    s = p / 4;
+                } else {
+                    s = p / (2 * Math.PI) * Math.asin(1 / a);
+                }
+                return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
+            },
+            easeOutElastic: function(t) {
+                var s = 1.70158;
+                var p = 0;
+                var a = 1;
+                if (t === 0) {
+                    return 0;
+                }
+                if ((t /= 1) === 1) {
+                    return 1;
+                }
+                if (!p) {
+                    p = 1 * 0.3;
+                }
+                if (a < Math.abs(1)) {
+                    a = 1;
+                    s = p / 4;
+                } else {
+                    s = p / (2 * Math.PI) * Math.asin(1 / a);
+                }
+                return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
+            },
+            easeInOutElastic: function(t) {
+                var s = 1.70158;
+                var p = 0;
+                var a = 1;
+                if (t === 0) {
+                    return 0;
+                }
+                if ((t /= 1 / 2) === 2) {
+                    return 1;
+                }
+                if (!p) {
+                    p = 1 * (0.3 * 1.5);
+                }
+                if (a < Math.abs(1)) {
+                    a = 1;
+                    s = p / 4;
+                } else {
+                    s = p / (2 * Math.PI) * Math.asin(1 / a);
+                }
+                if (t < 1) {
+                    return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
+                }
+                return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
+            },
+            easeInBack: function(t) {
+                var s = 1.70158;
+                return 1 * (t /= 1) * t * ((s + 1) * t - s);
+            },
+            easeOutBack: function(t) {
+                var s = 1.70158;
+                return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
+            },
+            easeInOutBack: function(t) {
+                var s = 1.70158;
+                if ((t /= 1 / 2) < 1) {
+                    return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
+                }
+                return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
+            },
+            easeInBounce: function(t) {
+                return 1 - easingEffects.easeOutBounce(1 - t);
+            },
+            easeOutBounce: function(t) {
+                if ((t /= 1) < (1 / 2.75)) {
+                    return 1 * (7.5625 * t * t);
+                } else if (t < (2 / 2.75)) {
+                    return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
+                } else if (t < (2.5 / 2.75)) {
+                    return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
+                }
+                return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
+            },
+            easeInOutBounce: function(t) {
+                if (t < 1 / 2) {
+                    return easingEffects.easeInBounce(t * 2) * 0.5;
+                }
+                return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
+            }
+        };
+        // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
+        helpers.requestAnimFrame = (function() {
+            if (typeof window === 'undefined') {
+                return function(callback) {
+                    callback();
+                };
+            }
+            return window.requestAnimationFrame ||
+                window.webkitRequestAnimationFrame ||
+                window.mozRequestAnimationFrame ||
+                window.oRequestAnimationFrame ||
+                window.msRequestAnimationFrame ||
+                function(callback) {
+                    return window.setTimeout(callback, 1000 / 60);
+                };
+        }());
+        // -- DOM methods
+        helpers.getRelativePosition = function(evt, chart) {
+            var mouseX, mouseY;
+            var e = evt.originalEvent || evt,
+                canvas = evt.currentTarget || evt.srcElement,
+                boundingRect = canvas.getBoundingClientRect();
+
+            var touches = e.touches;
+            if (touches && touches.length > 0) {
+                mouseX = touches[0].clientX;
+                mouseY = touches[0].clientY;
+
+            } else {
+                mouseX = e.clientX;
+                mouseY = e.clientY;
+            }
+
+            // Scale mouse coordinates into canvas coordinates
+            // by following the pattern laid out by 'jerryj' in the comments of
+            // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
+            var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
+            var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
+            var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
+            var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
+            var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
+            var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
+
+            // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
+            // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
+            mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
+            mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
+
+            return {
+                x: mouseX,
+                y: mouseY
+            };
+
+        };
+        helpers.addEvent = function(node, eventType, method) {
+            if (node.addEventListener) {
+                node.addEventListener(eventType, method);
+            } else if (node.attachEvent) {
+                node.attachEvent('on' + eventType, method);
+            } else {
+                node['on' + eventType] = method;
+            }
+        };
+        helpers.removeEvent = function(node, eventType, handler) {
+            if (node.removeEventListener) {
+                node.removeEventListener(eventType, handler, false);
+            } else if (node.detachEvent) {
+                node.detachEvent('on' + eventType, handler);
+            } else {
+                node['on' + eventType] = helpers.noop;
+            }
+        };
+
+        // Private helper function to convert max-width/max-height values that may be percentages into a number
+        function parseMaxStyle(styleValue, node, parentProperty) {
+            var valueInPixels;
+            if (typeof(styleValue) === 'string') {
+                valueInPixels = parseInt(styleValue, 10);
+
+                if (styleValue.indexOf('%') !== -1) {
+                    // percentage * size in dimension
+                    valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
+                }
+            } else {
+                valueInPixels = styleValue;
+            }
+
+            return valueInPixels;
         }
 
-        // No unnecessary computations
-        else if (value === me._view[key]) {
-          // It's the same! Woohoo!
+        /**
+         * Returns if the given value contains an effective constraint.
+         * @private
+         */
+        function isConstrainedValue(value) {
+            return value !== undefined && value !== null && value !== 'none';
         }
 
-        // Color transitions if possible
-        else if (typeof value === 'string') {
-          try {
-            var color = helpers.color(me._model[key]).mix(helpers.color(me._start[key]), ease);
-            me._view[key] = color.rgbString();
-          } catch (err) {
-            me._view[key] = value;
-          }
+        // Private helper to get a constraint dimension
+        // @param domNode : the node to check the constraint on
+        // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
+        // @param percentageProperty : property of parent to use when calculating width as a percentage
+        // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
+        function getConstraintDimension(domNode, maxStyle, percentageProperty) {
+            var view = document.defaultView;
+            var parentNode = domNode.parentNode;
+            var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
+            var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
+            var hasCNode = isConstrainedValue(constrainedNode);
+            var hasCContainer = isConstrainedValue(constrainedContainer);
+            var infinity = Number.POSITIVE_INFINITY;
+
+            if (hasCNode || hasCContainer) {
+                return Math.min(
+                    hasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
+                    hasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
+            }
+
+            return 'none';
         }
-        // Number transitions
-        else if (typeof value === 'number') {
-          var startVal = me._start[key] !== undefined && isNaN(me._start[key]) === false ? me._start[key] : 0;
-          me._view[key] = ((me._model[key] - startVal) * ease) + startVal;
-        }
-        // Everything else
-        else {
-          me._view[key] = value;
-        }
-      }, me);
+        // returns Number or undefined if no constraint
+        helpers.getConstraintWidth = function(domNode) {
+            return getConstraintDimension(domNode, 'max-width', 'clientWidth');
+        };
+        // returns Number or undefined if no constraint
+        helpers.getConstraintHeight = function(domNode) {
+            return getConstraintDimension(domNode, 'max-height', 'clientHeight');
+        };
+        helpers.getMaximumWidth = function(domNode) {
+            var container = domNode.parentNode;
+            var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);
+            var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);
+            var w = container.clientWidth - paddingLeft - paddingRight;
+            var cw = helpers.getConstraintWidth(domNode);
+            return isNaN(cw)? w : Math.min(w, cw);
+        };
+        helpers.getMaximumHeight = function(domNode) {
+            var container = domNode.parentNode;
+            var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);
+            var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);
+            var h = container.clientHeight - paddingTop - paddingBottom;
+            var ch = helpers.getConstraintHeight(domNode);
+            return isNaN(ch)? h : Math.min(h, ch);
+        };
+        helpers.getStyle = function(el, property) {
+            return el.currentStyle ?
+                el.currentStyle[property] :
+                document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
+        };
+        helpers.retinaScale = function(chart) {
+            var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
+            if (pixelRatio === 1) {
+                return;
+            }
 
-      return me;
-    },
+            var canvas = chart.canvas;
+            var height = chart.height;
+            var width = chart.width;
 
-    tooltipPosition: function() {
-      return {
-        x: this._model.x,
-        y: this._model.y
-      };
-    },
+            canvas.height = height * pixelRatio;
+            canvas.width = width * pixelRatio;
+            chart.ctx.scale(pixelRatio, pixelRatio);
 
-    hasValue: function() {
-      return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
-    }
-  });
+            // If no style has been set on the canvas, the render size is used as display size,
+            // making the chart visually bigger, so let's enforce it to the "correct" values.
+            // See https://github.com/chartjs/Chart.js/issues/3575
+            canvas.style.height = height + 'px';
+            canvas.style.width = width + 'px';
+        };
+        // -- Canvas methods
+        helpers.clear = function(chart) {
+            chart.ctx.clearRect(0, 0, chart.width, chart.height);
+        };
+        helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
+            return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
+        };
+        helpers.longestText = function(ctx, font, arrayOfThings, cache) {
+            cache = cache || {};
+            var data = cache.data = cache.data || {};
+            var gc = cache.garbageCollect = cache.garbageCollect || [];
 
-  Chart.Element.extend = helpers.inherits;
+            if (cache.font !== font) {
+                data = cache.data = {};
+                gc = cache.garbageCollect = [];
+                cache.font = font;
+            }
 
-};
+            ctx.font = font;
+            var longest = 0;
+            helpers.each(arrayOfThings, function(thing) {
+                // Undefined strings and arrays should not be measured
+                if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
+                    longest = helpers.measureText(ctx, data, gc, longest, thing);
+                } else if (helpers.isArray(thing)) {
+                    // if it is an array lets measure each element
+                    // to do maybe simplify this function a bit so we can do this more recursively?
+                    helpers.each(thing, function(nestedThing) {
+                        // Undefined strings and arrays should not be measured
+                        if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
+                            longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
+                        }
+                    });
+                }
+            });
 
-},{}],26:[function(require,module,exports){
-/*global window: false */
-/*global document: false */
-"use strict";
+            var gcLen = gc.length / 2;
+            if (gcLen > arrayOfThings.length) {
+                for (var i = 0; i < gcLen; i++) {
+                    delete data[gc[i]];
+                }
+                gc.splice(0, gcLen);
+            }
+            return longest;
+        };
+        helpers.measureText = function(ctx, data, gc, longest, string) {
+            var textWidth = data[string];
+            if (!textWidth) {
+                textWidth = data[string] = ctx.measureText(string).width;
+                gc.push(string);
+            }
+            if (textWidth > longest) {
+                longest = textWidth;
+            }
+            return longest;
+        };
+        helpers.numberOfLabelLines = function(arrayOfThings) {
+            var numberOfLines = 1;
+            helpers.each(arrayOfThings, function(thing) {
+                if (helpers.isArray(thing)) {
+                    if (thing.length > numberOfLines) {
+                        numberOfLines = thing.length;
+                    }
+                }
+            });
+            return numberOfLines;
+        };
+        helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {
+            ctx.beginPath();
+            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.closePath();
+        };
 
-var color = require(3);
+        helpers.color = !color?
+            function(value) {
+                console.error('Color.js not found!');
+                return value;
+            } :
+            function(value) {
+                /* global CanvasGradient */
+                if (value instanceof CanvasGradient) {
+                    value = Chart.defaults.global.defaultColor;
+                }
 
-module.exports = function(Chart) {
-	//Global Chart helpers object for utility methods and classes
-	var helpers = Chart.helpers = {};
+                return color(value);
+            };
 
-	//-- Basic js utility methods
-	helpers.each = function(loopable, callback, self, reverse) {
-		// Check to see if null or undefined firstly.
-		var i, len;
-		if (helpers.isArray(loopable)) {
-			len = loopable.length;
-			if (reverse) {
-				for (i = len - 1; i >= 0; i--) {
-					callback.call(self, loopable[i], i);
-				}
-			} else {
-				for (i = 0; i < len; i++) {
-					callback.call(self, loopable[i], i);
-				}
-			}
-		} else if (typeof loopable === 'object') {
-			var keys = Object.keys(loopable);
-			len = keys.length;
-			for (i = 0; i < len; i++) {
-				callback.call(self, loopable[keys[i]], keys[i]);
-			}
-		}
-	};
-	helpers.clone = function(obj) {
-		var objClone = {};
-		helpers.each(obj, function(value, key) {
-			if (helpers.isArray(value)) {
-				objClone[key] = value.slice(0);
-			} else if (typeof value === 'object' && value !== null) {
-				objClone[key] = helpers.clone(value);
-			} else {
-				objClone[key] = value;
-			}
-		});
-		return objClone;
-	};
-	helpers.extend = function(base) {
-		var setFn = function(value, key) { base[key] = value; };
-		for (var i = 1, ilen = arguments.length; i < ilen; i++) {
-			helpers.each(arguments[i], setFn);
-		}
-		return base;
-	};
-	// Need a special merge function to chart configs since they are now grouped
-	helpers.configMerge = function(_base) {
-		var base = helpers.clone(_base);
-		helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
-			helpers.each(extension, function(value, key) {
-				if (key === 'scales') {
-					// Scale config merging is complex. Add out own function here for that
-					base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value);
+        helpers.isArray = Array.isArray?
+            function(obj) {
+                return Array.isArray(obj);
+            } :
+            function(obj) {
+                return Object.prototype.toString.call(obj) === '[object Array]';
+            };
+        // ! @see http://stackoverflow.com/a/14853974
+        helpers.arrayEquals = function(a0, a1) {
+            var i, ilen, v0, v1;
 
-				} else if (key === 'scale') {
-					// Used in polar area & radar charts since there is only one scale
-					base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value);
-				} else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
-					// In this case we have an array of objects replacing another array. Rather than doing a strict replace,
-					// merge. This allows easy scale option merging
-					var baseArray = base[key];
+            if (!a0 || !a1 || a0.length !== a1.length) {
+                return false;
+            }
 
-					helpers.each(value, function(valueObj, index) {
+            for (i = 0, ilen=a0.length; i < ilen; ++i) {
+                v0 = a0[i];
+                v1 = a1[i];
 
-						if (index < baseArray.length) {
-							if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) {
-								// Two objects are coming together. Do a merge of them.
-								baseArray[index] = helpers.configMerge(baseArray[index], valueObj);
-							} else {
-								// Just overwrite in this case since there is nothing to merge
-								baseArray[index] = valueObj;
-							}
-						} else {
-							baseArray.push(valueObj); // nothing to merge
-						}
-					});
+                if (v0 instanceof Array && v1 instanceof Array) {
+                    if (!helpers.arrayEquals(v0, v1)) {
+                        return false;
+                    }
+                } else if (v0 !== v1) {
+                    // NOTE: two different object instances will never be equal: {x:20} != {x:20}
+                    return false;
+                }
+            }
 
-				} else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {
-					// If we are overwriting an object with an object, do a merge of the properties.
-					base[key] = helpers.configMerge(base[key], value);
+            return true;
+        };
+        helpers.callback = function(fn, args, thisArg) {
+            if (fn && typeof fn.call === 'function') {
+                fn.apply(thisArg, args);
+            }
+        };
+        helpers.getHoverColor = function(colorValue) {
+            /* global CanvasPattern */
+            return (colorValue instanceof CanvasPattern) ?
+                colorValue :
+                helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();
+        };
 
-				} else {
-					// can just overwrite the value in this case
-					base[key] = value;
-				}
-			});
-		});
-
-		return base;
-	};
-	helpers.scaleMerge = function(_base, extension) {
-		var base = helpers.clone(_base);
-
-		helpers.each(extension, function(value, key) {
-			if (key === 'xAxes' || key === 'yAxes') {
-				// These properties are arrays of items
-				if (base.hasOwnProperty(key)) {
-					helpers.each(value, function(valueObj, index) {
-						var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
-						var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);
-						if (index >= base[key].length || !base[key][index].type) {
-							base[key].push(helpers.configMerge(axisDefaults, valueObj));
-						} else if (valueObj.type && valueObj.type !== base[key][index].type) {
-							// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults
-							base[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);
-						} else {
-							// Type is the same
-							base[key][index] = helpers.configMerge(base[key][index], valueObj);
-						}
-					});
-				} else {
-					base[key] = [];
-					helpers.each(value, function(valueObj) {
-						var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
-						base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));
-					});
-				}
-			} else if (base.hasOwnProperty(key) && typeof base[key] === "object" && base[key] !== null && typeof value === "object") {
-				// If we are overwriting an object with an object, do a merge of the properties.
-				base[key] = helpers.configMerge(base[key], value);
-
-			} else {
-				// can just overwrite the value in this case
-				base[key] = value;
-			}
-		});
-
-		return base;
-	};
-	helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
-		if (value === undefined || value === null) {
-			return defaultValue;
-		}
-
-		if (helpers.isArray(value)) {
-			return index < value.length ? value[index] : defaultValue;
-		}
-
-		return value;
-	};
-	helpers.getValueOrDefault = function(value, defaultValue) {
-		return value === undefined ? defaultValue : value;
-	};
-	helpers.indexOf = Array.prototype.indexOf?
-		function(array, item) { return array.indexOf(item); } :
-		function(array, item) {
-			for (var i = 0, ilen = array.length; i < ilen; ++i) {
-				if (array[i] === item) {
-					return i;
-				}
-			}
-			return -1;
-		};
-	helpers.where = function(collection, filterCallback) {
-		if (helpers.isArray(collection) && Array.prototype.filter) {
-			return collection.filter(filterCallback);
-		} else {
-			var filtered = [];
-
-			helpers.each(collection, function(item) {
-				if (filterCallback(item)) {
-					filtered.push(item);
-				}
-			});
-
-			return filtered;
-		}
-	};
-	helpers.findIndex = Array.prototype.findIndex?
-		function(array, callback, scope) { return array.findIndex(callback, scope); } :
-		function(array, callback, scope) {
-			scope = scope === undefined? array : scope;
-			for (var i = 0, ilen = array.length; i < ilen; ++i) {
-				if (callback.call(scope, array[i], i, array)) {
-					return i;
-				}
-			}
-			return -1;
-		};
-	helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
-		// Default to start of the array
-		if (startIndex === undefined || startIndex === null) {
-			startIndex = -1;
-		}
-		for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
-			var currentItem = arrayToSearch[i];
-			if (filterCallback(currentItem)) {
-				return currentItem;
-			}
-		}
-	};
-	helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
-		// Default to end of the array
-		if (startIndex === undefined || startIndex === null) {
-			startIndex = arrayToSearch.length;
-		}
-		for (var i = startIndex - 1; i >= 0; i--) {
-			var currentItem = arrayToSearch[i];
-			if (filterCallback(currentItem)) {
-				return currentItem;
-			}
-		}
-	};
-	helpers.inherits = function(extensions) {
-		//Basic javascript inheritance based on the model created in Backbone.js
-		var parent = this;
-		var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {
-			return parent.apply(this, arguments);
-		};
-
-		var Surrogate = function() {
-			this.constructor = ChartElement;
-		};
-		Surrogate.prototype = parent.prototype;
-		ChartElement.prototype = new Surrogate();
-
-		ChartElement.extend = helpers.inherits;
-
-		if (extensions) {
-			helpers.extend(ChartElement.prototype, extensions);
-		}
-
-		ChartElement.__super__ = parent.prototype;
-
-		return ChartElement;
-	};
-	helpers.noop = function() {};
-	helpers.uid = (function() {
-		var id = 0;
-		return function() {
-			return id++;
-		};
-	})();
-	//-- Math methods
-	helpers.isNumber = function(n) {
-		return !isNaN(parseFloat(n)) && isFinite(n);
-	};
-	helpers.almostEquals = function(x, y, epsilon) {
-		return Math.abs(x - y) < epsilon;
-	};
-	helpers.max = function(array) {
-		return array.reduce(function(max, value) {
-			if (!isNaN(value)) {
-				return Math.max(max, value);
-			} else {
-				return max;
-			}
-		}, Number.NEGATIVE_INFINITY);
-	};
-	helpers.min = function(array) {
-		return array.reduce(function(min, value) {
-			if (!isNaN(value)) {
-				return Math.min(min, value);
-			} else {
-				return min;
-			}
-		}, Number.POSITIVE_INFINITY);
-	};
-	helpers.sign = Math.sign?
-		function(x) { return Math.sign(x); } :
-		function(x) {
-			x = +x; // convert to a number
-			if (x === 0 || isNaN(x)) {
-				return x;
-			}
-			return x > 0 ? 1 : -1;
-		};
-	helpers.log10 = Math.log10?
-		function(x) { return Math.log10(x); } :
-		function(x) {
-			return Math.log(x) / Math.LN10;
-		};
-	helpers.toRadians = function(degrees) {
-		return degrees * (Math.PI / 180);
-	};
-	helpers.toDegrees = function(radians) {
-		return radians * (180 / Math.PI);
-	};
-	// Gets the angle from vertical upright to the point about a centre.
-	helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
-		var distanceFromXCenter = anglePoint.x - centrePoint.x,
-			distanceFromYCenter = anglePoint.y - centrePoint.y,
-			radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
-
-		var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
-
-		if (angle < (-0.5 * Math.PI)) {
-			angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
-		}
-
-		return {
-			angle: angle,
-			distance: radialDistanceFromCenter
-		};
-	};
-	helpers.aliasPixel = function(pixelWidth) {
-		return (pixelWidth % 2 === 0) ? 0 : 0.5;
-	};
-	helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
-		//Props to Rob Spencer at scaled innovation for his post on splining between points
-		//http://scaledinnovation.com/analytics/splines/aboutSplines.html
-
-		// This function must also respect "skipped" points
-
-		var previous = firstPoint.skip ? middlePoint : firstPoint,
-			current = middlePoint,
-			next = afterPoint.skip ? middlePoint : afterPoint;
-
-		var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
-		var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
-
-		var s01 = d01 / (d01 + d12);
-		var s12 = d12 / (d01 + d12);
-
-		// If all points are the same, s01 & s02 will be inf
-		s01 = isNaN(s01) ? 0 : s01;
-		s12 = isNaN(s12) ? 0 : s12;
-
-		var fa = t * s01; // scaling factor for triangle Ta
-		var fb = t * s12;
-
-		return {
-			previous: {
-				x: current.x - fa * (next.x - previous.x),
-				y: current.y - fa * (next.y - previous.y)
-			},
-			next: {
-				x: current.x + fb * (next.x - previous.x),
-				y: current.y + fb * (next.y - previous.y)
-			}
-		};
-	};
-	helpers.nextItem = function(collection, index, loop) {
-		if (loop) {
-			return index >= collection.length - 1 ? collection[0] : collection[index + 1];
-		}
-
-		return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
-	};
-	helpers.previousItem = function(collection, index, loop) {
-		if (loop) {
-			return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
-		}
-		return index <= 0 ? collection[0] : collection[index - 1];
-	};
-	// Implementation of the nice number algorithm used in determining where axis labels will go
-	helpers.niceNum = function(range, round) {
-		var exponent = Math.floor(helpers.log10(range));
-		var fraction = range / Math.pow(10, exponent);
-		var niceFraction;
-
-		if (round) {
-			if (fraction < 1.5) {
-				niceFraction = 1;
-			} else if (fraction < 3) {
-				niceFraction = 2;
-			} else if (fraction < 7) {
-				niceFraction = 5;
-			} else {
-				niceFraction = 10;
-			}
-		} else {
-			if (fraction <= 1.0) {
-				niceFraction = 1;
-			} else if (fraction <= 2) {
-				niceFraction = 2;
-			} else if (fraction <= 5) {
-				niceFraction = 5;
-			} else {
-				niceFraction = 10;
-			}
-		}
-
-		return niceFraction * Math.pow(10, exponent);
-	};
-	//Easing functions adapted from Robert Penner's easing equations
-	//http://www.robertpenner.com/easing/
-	var easingEffects = helpers.easingEffects = {
-		linear: function(t) {
-			return t;
-		},
-		easeInQuad: function(t) {
-			return t * t;
-		},
-		easeOutQuad: function(t) {
-			return -1 * t * (t - 2);
-		},
-		easeInOutQuad: function(t) {
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * t * t;
-			}
-			return -1 / 2 * ((--t) * (t - 2) - 1);
-		},
-		easeInCubic: function(t) {
-			return t * t * t;
-		},
-		easeOutCubic: function(t) {
-			return 1 * ((t = t / 1 - 1) * t * t + 1);
-		},
-		easeInOutCubic: function(t) {
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * t * t * t;
-			}
-			return 1 / 2 * ((t -= 2) * t * t + 2);
-		},
-		easeInQuart: function(t) {
-			return t * t * t * t;
-		},
-		easeOutQuart: function(t) {
-			return -1 * ((t = t / 1 - 1) * t * t * t - 1);
-		},
-		easeInOutQuart: function(t) {
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * t * t * t * t;
-			}
-			return -1 / 2 * ((t -= 2) * t * t * t - 2);
-		},
-		easeInQuint: function(t) {
-			return 1 * (t /= 1) * t * t * t * t;
-		},
-		easeOutQuint: function(t) {
-			return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
-		},
-		easeInOutQuint: function(t) {
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * t * t * t * t * t;
-			}
-			return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
-		},
-		easeInSine: function(t) {
-			return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
-		},
-		easeOutSine: function(t) {
-			return 1 * Math.sin(t / 1 * (Math.PI / 2));
-		},
-		easeInOutSine: function(t) {
-			return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
-		},
-		easeInExpo: function(t) {
-			return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
-		},
-		easeOutExpo: function(t) {
-			return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
-		},
-		easeInOutExpo: function(t) {
-			if (t === 0) {
-				return 0;
-			}
-			if (t === 1) {
-				return 1;
-			}
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * Math.pow(2, 10 * (t - 1));
-			}
-			return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
-		},
-		easeInCirc: function(t) {
-			if (t >= 1) {
-				return t;
-			}
-			return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
-		},
-		easeOutCirc: function(t) {
-			return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
-		},
-		easeInOutCirc: function(t) {
-			if ((t /= 1 / 2) < 1) {
-				return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
-			}
-			return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
-		},
-		easeInElastic: function(t) {
-			var s = 1.70158;
-			var p = 0;
-			var a = 1;
-			if (t === 0) {
-				return 0;
-			}
-			if ((t /= 1) === 1) {
-				return 1;
-			}
-			if (!p) {
-				p = 1 * 0.3;
-			}
-			if (a < Math.abs(1)) {
-				a = 1;
-				s = p / 4;
-			} else {
-				s = p / (2 * Math.PI) * Math.asin(1 / a);
-			}
-			return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
-		},
-		easeOutElastic: function(t) {
-			var s = 1.70158;
-			var p = 0;
-			var a = 1;
-			if (t === 0) {
-				return 0;
-			}
-			if ((t /= 1) === 1) {
-				return 1;
-			}
-			if (!p) {
-				p = 1 * 0.3;
-			}
-			if (a < Math.abs(1)) {
-				a = 1;
-				s = p / 4;
-			} else {
-				s = p / (2 * Math.PI) * Math.asin(1 / a);
-			}
-			return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
-		},
-		easeInOutElastic: function(t) {
-			var s = 1.70158;
-			var p = 0;
-			var a = 1;
-			if (t === 0) {
-				return 0;
-			}
-			if ((t /= 1 / 2) === 2) {
-				return 1;
-			}
-			if (!p) {
-				p = 1 * (0.3 * 1.5);
-			}
-			if (a < Math.abs(1)) {
-				a = 1;
-				s = p / 4;
-			} else {
-				s = p / (2 * Math.PI) * Math.asin(1 / a);
-			}
-			if (t < 1) {
-				return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
-			}
-			return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
-		},
-		easeInBack: function(t) {
-			var s = 1.70158;
-			return 1 * (t /= 1) * t * ((s + 1) * t - s);
-		},
-		easeOutBack: function(t) {
-			var s = 1.70158;
-			return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
-		},
-		easeInOutBack: function(t) {
-			var s = 1.70158;
-			if ((t /= 1 / 2) < 1) {
-				return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
-			}
-			return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
-		},
-		easeInBounce: function(t) {
-			return 1 - easingEffects.easeOutBounce(1 - t);
-		},
-		easeOutBounce: function(t) {
-			if ((t /= 1) < (1 / 2.75)) {
-				return 1 * (7.5625 * t * t);
-			} else if (t < (2 / 2.75)) {
-				return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
-			} else if (t < (2.5 / 2.75)) {
-				return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
-			} else {
-				return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
-			}
-		},
-		easeInOutBounce: function(t) {
-			if (t < 1 / 2) {
-				return easingEffects.easeInBounce(t * 2) * 0.5;
-			}
-			return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
-		}
-	};
-	//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
-	helpers.requestAnimFrame = (function() {
-		return window.requestAnimationFrame ||
-			window.webkitRequestAnimationFrame ||
-			window.mozRequestAnimationFrame ||
-			window.oRequestAnimationFrame ||
-			window.msRequestAnimationFrame ||
-			function(callback) {
-				return window.setTimeout(callback, 1000 / 60);
-			};
-	})();
-	helpers.cancelAnimFrame = (function() {
-		return window.cancelAnimationFrame ||
-			window.webkitCancelAnimationFrame ||
-			window.mozCancelAnimationFrame ||
-			window.oCancelAnimationFrame ||
-			window.msCancelAnimationFrame ||
-			function(callback) {
-				return window.clearTimeout(callback, 1000 / 60);
-			};
-	})();
-	//-- DOM methods
-	helpers.getRelativePosition = function(evt, chart) {
-		var mouseX, mouseY;
-		var e = evt.originalEvent || evt,
-			canvas = evt.currentTarget || evt.srcElement,
-			boundingRect = canvas.getBoundingClientRect();
-
-		var touches = e.touches;
-		if (touches && touches.length > 0) {
-			mouseX = touches[0].clientX;
-			mouseY = touches[0].clientY;
-
-		} else {
-			mouseX = e.clientX;
-			mouseY = e.clientY;
-		}
-
-		// Scale mouse coordinates into canvas coordinates
-		// by following the pattern laid out by 'jerryj' in the comments of
-		// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
-		var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
-		var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
-		var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
-		var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
-		var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
-		var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
-
-		// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
-		// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
-		mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
-		mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
-
-		return {
-			x: mouseX,
-			y: mouseY
-		};
-
-	};
-	helpers.addEvent = function(node, eventType, method) {
-		if (node.addEventListener) {
-			node.addEventListener(eventType, method);
-		} else if (node.attachEvent) {
-			node.attachEvent("on" + eventType, method);
-		} else {
-			node["on" + eventType] = method;
-		}
-	};
-	helpers.removeEvent = function(node, eventType, handler) {
-		if (node.removeEventListener) {
-			node.removeEventListener(eventType, handler, false);
-		} else if (node.detachEvent) {
-			node.detachEvent("on" + eventType, handler);
-		} else {
-			node["on" + eventType] = helpers.noop;
-		}
-	};
-	helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {
-		// Create the events object if it's not already present
-		var events = chartInstance.events = chartInstance.events || {};
-
-		helpers.each(arrayOfEvents, function(eventName) {
-			events[eventName] = function() {
-				handler.apply(chartInstance, arguments);
-			};
-			helpers.addEvent(chartInstance.chart.canvas, eventName, events[eventName]);
-		});
-	};
-	helpers.unbindEvents = function(chartInstance, arrayOfEvents) {
-		var canvas = chartInstance.chart.canvas;
-		helpers.each(arrayOfEvents, function(handler, eventName) {
-			helpers.removeEvent(canvas, eventName, handler);
-		});
-	};
-
-	// Private helper function to convert max-width/max-height values that may be percentages into a number
-	function parseMaxStyle(styleValue, node, parentProperty) {
-		var valueInPixels;
-		if (typeof(styleValue) === 'string') {
-			valueInPixels = parseInt(styleValue, 10);
-
-			if (styleValue.indexOf('%') != -1) {
-				// percentage * size in dimension
-				valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
-			}
-		} else {
-			valueInPixels = styleValue;
-		}
-
-		return valueInPixels;
-	}
-
-	/**
-	 * Returns if the given value contains an effective constraint.
-	 * @private
-	 */
-	function isConstrainedValue(value) {
-		return value !== undefined &&  value !== null && value !== 'none';
-	}
-
-	// Private helper to get a constraint dimension
-	// @param domNode : the node to check the constraint on
-	// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
-	// @param percentageProperty : property of parent to use when calculating width as a percentage
-	// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
-	function getConstraintDimension(domNode, maxStyle, percentageProperty) {
-		var view = document.defaultView;
-		var parentNode = domNode.parentNode;
-		var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
-		var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
-		var hasCNode = isConstrainedValue(constrainedNode);
-		var hasCContainer = isConstrainedValue(constrainedContainer);
-		var infinity = Number.POSITIVE_INFINITY;
-
-		if (hasCNode || hasCContainer) {
-			return Math.min(
-				hasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
-				hasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
-		}
-
-		return 'none';
-	}
-	// returns Number or undefined if no constraint
-	helpers.getConstraintWidth = function(domNode) {
-		return getConstraintDimension(domNode, 'max-width', 'clientWidth');
-	};
-	// returns Number or undefined if no constraint
-	helpers.getConstraintHeight = function(domNode) {
-		return getConstraintDimension(domNode, 'max-height', 'clientHeight');
-	};
-	helpers.getMaximumWidth = function(domNode) {
-		var container = domNode.parentNode;
-		var padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right'));
-		var w = container.clientWidth - padding;
-		var cw = helpers.getConstraintWidth(domNode);
-		return isNaN(cw)? w : Math.min(w, cw);
-	};
-	helpers.getMaximumHeight = function(domNode) {
-		var container = domNode.parentNode;
-		var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom'));
-		var h = container.clientHeight - padding;
-		var ch = helpers.getConstraintHeight(domNode);
-		return isNaN(ch)? h : Math.min(h, ch);
-	};
-	helpers.getStyle = function(el, property) {
-		return el.currentStyle ?
-			el.currentStyle[property] :
-			document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
-	};
-	helpers.retinaScale = function(chart) {
-		var ctx = chart.ctx;
-		var canvas = chart.canvas;
-		var width = canvas.width;
-		var height = canvas.height;
-		var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
-
-		if (pixelRatio !== 1) {
-			canvas.height = height * pixelRatio;
-			canvas.width = width * pixelRatio;
-			ctx.scale(pixelRatio, pixelRatio);
-
-			// Store the device pixel ratio so that we can go backwards in `destroy`.
-			// The devicePixelRatio changes with zoom, so there are no guarantees that it is the same
-			// when destroy is called
-			chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;
-		}
-
-		canvas.style.width = width + 'px';
-		canvas.style.height = height + 'px';
-	};
-	//-- Canvas methods
-	helpers.clear = function(chart) {
-		chart.ctx.clearRect(0, 0, chart.width, chart.height);
-	};
-	helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
-		return fontStyle + " " + pixelSize + "px " + fontFamily;
-	};
-	helpers.longestText = function(ctx, font, arrayOfThings, cache) {
-		cache = cache || {};
-		var data = cache.data = cache.data || {};
-		var gc = cache.garbageCollect = cache.garbageCollect || [];
-
-		if (cache.font !== font) {
-			data = cache.data = {};
-			gc = cache.garbageCollect = [];
-			cache.font = font;
-		}
-
-		ctx.font = font;
-		var longest = 0;
-		helpers.each(arrayOfThings, function(thing) {
-			// Undefined strings and arrays should not be measured
-			if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
-				longest = helpers.measureText(ctx, data, gc, longest, thing);
-			} else if (helpers.isArray(thing)) {
-				// if it is an array lets measure each element
-				// to do maybe simplify this function a bit so we can do this more recursively?
-				helpers.each(thing, function(nestedThing) {
-					// Undefined strings and arrays should not be measured
-					if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
-						longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
-					}
-				});
-			}
-		});
-
-		var gcLen = gc.length / 2;
-		if (gcLen > arrayOfThings.length) {
-			for (var i = 0; i < gcLen; i++) {
-				delete data[gc[i]];
-			}
-			gc.splice(0, gcLen);
-		}
-		return longest;
-	};
-	helpers.measureText = function (ctx, data, gc, longest, string) {
-		var textWidth = data[string];
-		if (!textWidth) {
-			textWidth = data[string] = ctx.measureText(string).width;
-			gc.push(string);
-		}
-		if (textWidth > longest) {
-			longest = textWidth;
-		}
-		return longest;
-	};
-	helpers.numberOfLabelLines = function(arrayOfThings) {
-		var numberOfLines = 1;
-		helpers.each(arrayOfThings, function(thing) {
-			if (helpers.isArray(thing)) {
-				if (thing.length > numberOfLines) {
-					numberOfLines = thing.length;
-				}
-			}
-		});
-		return numberOfLines;
-	};
-	helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {
-		ctx.beginPath();
-		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.closePath();
-	};
-	helpers.color = function(c) {
-		if (!color) {
-			console.log('Color.js not found!');
-			return c;
-		}
-
-		/* global CanvasGradient */
-		if (c instanceof CanvasGradient) {
-			return color(Chart.defaults.global.defaultColor);
-		}
-
-		return color(c);
-	};
-	helpers.addResizeListener = function(node, callback) {
-		// Hide an iframe before the node
-		var hiddenIframe = document.createElement('iframe');
-		var hiddenIframeClass = 'chartjs-hidden-iframe';
-
-		if (hiddenIframe.classlist) {
-			// can use classlist
-			hiddenIframe.classlist.add(hiddenIframeClass);
-		} else {
-			hiddenIframe.setAttribute('class', hiddenIframeClass);
-		}
-
-		// Set the style
-		var style = hiddenIframe.style;
-		style.width = '100%';
-		style.display = 'block';
-		style.border = 0;
-		style.height = 0;
-		style.margin = 0;
-		style.position = 'absolute';
-		style.left = 0;
-		style.right = 0;
-		style.top = 0;
-		style.bottom = 0;
-
-		// Insert the iframe so that contentWindow is available
-		node.insertBefore(hiddenIframe, node.firstChild);
-
-		(hiddenIframe.contentWindow || hiddenIframe).onresize = function() {
-			if (callback) {
-				callback();
-			}
-		};
-	};
-	helpers.removeResizeListener = function(node) {
-		var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
-
-		// Remove the resize detect iframe
-		if (hiddenIframe) {
-			hiddenIframe.parentNode.removeChild(hiddenIframe);
-		}
-	};
-	helpers.isArray = Array.isArray?
-		function(obj) { return Array.isArray(obj); } :
-		function(obj) {
-			return Object.prototype.toString.call(obj) === '[object Array]';
-		};
-	//! @see http://stackoverflow.com/a/14853974
-	helpers.arrayEquals = function(a0, a1) {
-		var i, ilen, v0, v1;
-
-		if (!a0 || !a1 || a0.length != a1.length) {
-			return false;
-		}
-
-		for (i = 0, ilen=a0.length; i < ilen; ++i) {
-			v0 = a0[i];
-			v1 = a1[i];
-
-			if (v0 instanceof Array && v1 instanceof Array) {
-				if (!helpers.arrayEquals(v0, v1)) {
-					return false;
-				}
-			} else if (v0 != v1) {
-				// NOTE: two different object instances will never be equal: {x:20} != {x:20}
-				return false;
-			}
-		}
-
-		return true;
-	};
-	helpers.callCallback = function(fn, args, _tArg) {
-		if (fn && typeof fn.call === 'function') {
-			fn.apply(_tArg, args);
-		}
-	};
-	helpers.getHoverColor = function(color) {
-		/* global CanvasPattern */
-		return (color instanceof CanvasPattern) ?
-			color :
-			helpers.color(color).saturate(0.5).darken(0.1).rgbString();
-	};
-};
+        /**
+         * Provided for backward compatibility, use Chart.helpers#callback instead.
+         * @function Chart.helpers#callCallback
+         * @deprecated since version 2.6.0
+         * @todo remove at version 3
+         */
+        helpers.callCallback = helpers.callback;
+    };
 
 },{"3":3}],27:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function() {
+    module.exports = function(Chart) {
+        var helpers = Chart.helpers;
 
-	//Occupy the global variable of Chart, and create a simple base class
-	var Chart = function(context, config) {
-		var me = this;
-		var helpers = Chart.helpers;
-		me.config = config || { 
-			data: {
-				datasets: []
-			}
-		};
+        /**
+         * Helper function to get relative position for an event
+         * @param {Event|IEvent} event - The event to get the position for
+         * @param {Chart} chart - The chart
+         * @returns {Point} the event position
+         */
+        function getRelativePosition(e, chart) {
+            if (e.native) {
+                return {
+                    x: e.x,
+                    y: e.y
+                };
+            }
 
-		// Support a jQuery'd canvas element
-		if (context.length && context[0].getContext) {
-			context = context[0];
-		}
+            return helpers.getRelativePosition(e, chart);
+        }
 
-		// Support a canvas domnode
-		if (context.getContext) {
-			context = context.getContext("2d");
-		}
+        /**
+         * Helper function to traverse all of the visible elements in the chart
+         * @param chart {chart} the chart
+         * @param handler {Function} the callback to execute for each visible item
+         */
+        function parseVisibleItems(chart, handler) {
+            var datasets = chart.data.datasets;
+            var meta, i, j, ilen, jlen;
 
-		me.ctx = context;
-		me.canvas = context.canvas;
+            for (i = 0, ilen = datasets.length; i < ilen; ++i) {
+                if (!chart.isDatasetVisible(i)) {
+                    continue;
+                }
 
-		context.canvas.style.display = context.canvas.style.display || 'block';
+                meta = chart.getDatasetMeta(i);
+                for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
+                    var element = meta.data[j];
+                    if (!element._view.skip) {
+                        handler(element);
+                    }
+                }
+            }
+        }
 
-		// Figure out what the size of the chart will be.
-		// If the canvas has a specified width and height, we use those else
-		// we look to see if the canvas node has a CSS width and height.
-		// If there is still no height, fill the parent container
-		me.width = context.canvas.width || parseInt(helpers.getStyle(context.canvas, 'width'), 10) || helpers.getMaximumWidth(context.canvas);
-		me.height = context.canvas.height || parseInt(helpers.getStyle(context.canvas, 'height'), 10) || helpers.getMaximumHeight(context.canvas);
+        /**
+         * Helper function to get the items that intersect the event position
+         * @param items {ChartElement[]} elements to filter
+         * @param position {Point} the point to be nearest to
+         * @return {ChartElement[]} the nearest items
+         */
+        function getIntersectItems(chart, position) {
+            var elements = [];
 
-		me.aspectRatio = me.width / me.height;
+            parseVisibleItems(chart, function(element) {
+                if (element.inRange(position.x, position.y)) {
+                    elements.push(element);
+                }
+            });
 
-		if (isNaN(me.aspectRatio) || isFinite(me.aspectRatio) === false) {
-			// If the canvas has no size, try and figure out what the aspect ratio will be.
-			// Some charts prefer square canvases (pie, radar, etc). If that is specified, use that
-			// else use the canvas default ratio of 2
-			me.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
-		}
+            return elements;
+        }
 
-		// Store the original style of the element so we can set it back
-		me.originalCanvasStyleWidth = context.canvas.style.width;
-		me.originalCanvasStyleHeight = context.canvas.style.height;
+        /**
+         * Helper function to get the items nearest to the event position considering all visible items in teh chart
+         * @param chart {Chart} the chart to look at elements from
+         * @param position {Point} the point to be nearest to
+         * @param intersect {Boolean} if true, only consider items that intersect the position
+         * @param distanceMetric {Function} Optional function to provide the distance between
+         * @return {ChartElement[]} the nearest items
+         */
+        function getNearestItems(chart, position, intersect, distanceMetric) {
+            var minDistance = Number.POSITIVE_INFINITY;
+            var nearestItems = [];
 
-		// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
-		helpers.retinaScale(me);
-		me.controller = new Chart.Controller(me);
+            if (!distanceMetric) {
+                distanceMetric = helpers.distanceBetweenPoints;
+            }
 
-		// Always bind this so that if the responsive state changes we still work
-		helpers.addResizeListener(context.canvas.parentNode, function() {
-			if (me.controller && me.controller.config.options.responsive) {
-				me.controller.resize();
-			}
-		});
+            parseVisibleItems(chart, function(element) {
+                if (intersect && !element.inRange(position.x, position.y)) {
+                    return;
+                }
 
-		return me.controller ? me.controller : me;
+                var center = element.getCenterPoint();
+                var distance = distanceMetric(position, center);
 
-	};
+                if (distance < minDistance) {
+                    nearestItems = [element];
+                    minDistance = distance;
+                } else if (distance === minDistance) {
+                    // Can have multiple items at the same distance in which case we sort by size
+                    nearestItems.push(element);
+                }
+            });
 
-	//Globally expose the defaults to allow for user updating/changing
-	Chart.defaults = {
-		global: {
-			responsive: true,
-			responsiveAnimationDuration: 0,
-			maintainAspectRatio: true,
-			events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"],
-			hover: {
-				onHover: null,
-				mode: 'single',
-				animationDuration: 400
-			},
-			onClick: null,
-			defaultColor: 'rgba(0,0,0,0.1)',
-			defaultFontColor: '#666',
-			defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
-			defaultFontSize: 12,
-			defaultFontStyle: 'normal',
-			showLines: true,
+            return nearestItems;
+        }
 
-			// Element defaults defined in element extensions
-			elements: {},
+        function indexMode(chart, e, options) {
+            var position = getRelativePosition(e, chart);
+            var distanceMetric = function(pt1, pt2) {
+                return Math.abs(pt1.x - pt2.x);
+            };
+            var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
+            var elements = [];
 
-			// Legend callback string
-			legendCallback: function(chart) {
-				var text = [];
-				text.push('<ul class="' + chart.id + '-legend">');
-				for (var i = 0; i < chart.data.datasets.length; i++) {
-					text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');
-					if (chart.data.datasets[i].label) {
-						text.push(chart.data.datasets[i].label);
-					}
-					text.push('</li>');
-				}
-				text.push('</ul>');
+            if (!items.length) {
+                return [];
+            }
 
-				return text.join("");
-			}
-		}
-	};
+            chart.data.datasets.forEach(function(dataset, datasetIndex) {
+                if (chart.isDatasetVisible(datasetIndex)) {
+                    var meta = chart.getDatasetMeta(datasetIndex),
+                        element = meta.data[items[0]._index];
 
-	Chart.Chart = Chart;
+                    // don't count items that are skipped (null data)
+                    if (element && !element._view.skip) {
+                        elements.push(element);
+                    }
+                }
+            });
 
-	return Chart;
+            return elements;
+        }
 
-};
+        /**
+         * @interface IInteractionOptions
+         */
+        /**
+         * If true, only consider items that intersect the point
+         * @name IInterfaceOptions#boolean
+         * @type Boolean
+         */
+
+        /**
+         * Contains interaction related functions
+         * @namespace Chart.Interaction
+         */
+        Chart.Interaction = {
+            // Helper function for different modes
+            modes: {
+                single: function(chart, e) {
+                    var position = getRelativePosition(e, chart);
+                    var elements = [];
+
+                    parseVisibleItems(chart, function(element) {
+                        if (element.inRange(position.x, position.y)) {
+                            elements.push(element);
+                            return elements;
+                        }
+                    });
+
+                    return elements.slice(0, 1);
+                },
+
+                /**
+                 * @function Chart.Interaction.modes.label
+                 * @deprecated since version 2.4.0
+                 * @todo remove at version 3
+                 * @private
+                 */
+                label: indexMode,
+
+                /**
+                 * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
+                 * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
+                 * @function Chart.Interaction.modes.index
+                 * @since v2.4.0
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @param options {IInteractionOptions} options to use during interaction
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                index: indexMode,
+
+                /**
+                 * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
+                 * If the options.intersect is false, we find the nearest item and return the items in that dataset
+                 * @function Chart.Interaction.modes.dataset
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @param options {IInteractionOptions} options to use during interaction
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                dataset: function(chart, e, options) {
+                    var position = getRelativePosition(e, chart);
+                    var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);
+
+                    if (items.length > 0) {
+                        items = chart.getDatasetMeta(items[0]._datasetIndex).data;
+                    }
+
+                    return items;
+                },
+
+                /**
+                 * @function Chart.Interaction.modes.x-axis
+                 * @deprecated since version 2.4.0. Use index mode and intersect == true
+                 * @todo remove at version 3
+                 * @private
+                 */
+                'x-axis': function(chart, e) {
+                    return indexMode(chart, e, true);
+                },
+
+                /**
+                 * Point mode returns all elements that hit test based on the event position
+                 * of the event
+                 * @function Chart.Interaction.modes.intersect
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                point: function(chart, e) {
+                    var position = getRelativePosition(e, chart);
+                    return getIntersectItems(chart, position);
+                },
+
+                /**
+                 * nearest mode returns the element closest to the point
+                 * @function Chart.Interaction.modes.intersect
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @param options {IInteractionOptions} options to use
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                nearest: function(chart, e, options) {
+                    var position = getRelativePosition(e, chart);
+                    var nearestItems = getNearestItems(chart, position, options.intersect);
+
+                    // We have multiple items at the same distance from the event. Now sort by smallest
+                    if (nearestItems.length > 1) {
+                        nearestItems.sort(function(a, b) {
+                            var sizeA = a.getArea();
+                            var sizeB = b.getArea();
+                            var ret = sizeA - sizeB;
+
+                            if (ret === 0) {
+                                // if equal sort by dataset index
+                                ret = a._datasetIndex - b._datasetIndex;
+                            }
+
+                            return ret;
+                        });
+                    }
+
+                    // Return only 1 item
+                    return nearestItems.slice(0, 1);
+                },
+
+                /**
+                 * x mode returns the elements that hit-test at the current x coordinate
+                 * @function Chart.Interaction.modes.x
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @param options {IInteractionOptions} options to use
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                x: function(chart, e, options) {
+                    var position = getRelativePosition(e, chart);
+                    var items = [];
+                    var intersectsItem = false;
+
+                    parseVisibleItems(chart, function(element) {
+                        if (element.inXRange(position.x)) {
+                            items.push(element);
+                        }
+
+                        if (element.inRange(position.x, position.y)) {
+                            intersectsItem = true;
+                        }
+                    });
+
+                    // If we want to trigger on an intersect and we don't have any items
+                    // that intersect the position, return nothing
+                    if (options.intersect && !intersectsItem) {
+                        items = [];
+                    }
+                    return items;
+                },
+
+                /**
+                 * y mode returns the elements that hit-test at the current y coordinate
+                 * @function Chart.Interaction.modes.y
+                 * @param chart {chart} the chart we are returning items from
+                 * @param e {Event} the event we are find things at
+                 * @param options {IInteractionOptions} options to use
+                 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
+                 */
+                y: function(chart, e, options) {
+                    var position = getRelativePosition(e, chart);
+                    var items = [];
+                    var intersectsItem = false;
+
+                    parseVisibleItems(chart, function(element) {
+                        if (element.inYRange(position.y)) {
+                            items.push(element);
+                        }
+
+                        if (element.inRange(position.x, position.y)) {
+                            intersectsItem = true;
+                        }
+                    });
+
+                    // If we want to trigger on an intersect and we don't have any items
+                    // that intersect the position, return nothing
+                    if (options.intersect && !intersectsItem) {
+                        items = [];
+                    }
+                    return items;
+                }
+            }
+        };
+    };
 
 },{}],28:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function() {
 
-	var helpers = Chart.helpers;
+        // Occupy the global variable of Chart, and create a simple base class
+        var Chart = function(item, config) {
+            this.construct(item, config);
+            return this;
+        };
 
-	// The layout service is very self explanatory.  It's responsible for the layout within a chart.
-	// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
-	// It is this service's responsibility of carrying out that layout.
-	Chart.layoutService = {
-		defaults: {},
+        // Globally expose the defaults to allow for user updating/changing
+        Chart.defaults = {
+            global: {
+                responsive: true,
+                responsiveAnimationDuration: 0,
+                maintainAspectRatio: true,
+                events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
+                hover: {
+                    onHover: null,
+                    mode: 'nearest',
+                    intersect: true,
+                    animationDuration: 400
+                },
+                onClick: null,
+                defaultColor: 'rgba(0,0,0,0.1)',
+                defaultFontColor: '#666',
+                defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
+                defaultFontSize: 12,
+                defaultFontStyle: 'normal',
+                showLines: true,
 
-		// Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.
-		addBox: function(chartInstance, box) {
-			if (!chartInstance.boxes) {
-				chartInstance.boxes = [];
-			}
-			chartInstance.boxes.push(box);
-		},
+                // Element defaults defined in element extensions
+                elements: {},
 
-		removeBox: function(chartInstance, box) {
-			if (!chartInstance.boxes) {
-				return;
-			}
-			chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);
-		},
+                // Legend callback string
+                legendCallback: function(chart) {
+                    var text = [];
+                    text.push('<ul class="' + chart.id + '-legend">');
+                    for (var i = 0; i < chart.data.datasets.length; i++) {
+                        text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');
+                        if (chart.data.datasets[i].label) {
+                            text.push(chart.data.datasets[i].label);
+                        }
+                        text.push('</li>');
+                    }
+                    text.push('</ul>');
 
-		// The most important function
-		update: function(chartInstance, width, height) {
+                    return text.join('');
+                }
+            }
+        };
 
-			if (!chartInstance) {
-				return;
-			}
+        Chart.Chart = Chart;
 
-			var xPadding = 0;
-			var yPadding = 0;
-
-			var leftBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "left";
-			});
-			var rightBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "right";
-			});
-			var topBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "top";
-			});
-			var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "bottom";
-			});
-
-			// Boxes that overlay the chartarea such as the radialLinear scale
-			var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {
-				return box.options.position === "chartArea";
-			});
-
-			// Ensure that full width boxes are at the very top / bottom
-			topBoxes.sort(function(a, b) {
-				return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);
-			});
-			bottomBoxes.sort(function(a, b) {
-				return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);
-			});
-
-			// Essentially we now have any number of boxes on each of the 4 sides.
-			// Our canvas looks like the following.
-			// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
-			// B1 is the bottom axis
-			// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
-			// These locations are single-box locations only, when trying to register a chartArea location that is already taken,
-			// an error will be thrown.
-			//
-			// |----------------------------------------------------|
-			// |                  T1 (Full Width)                   |
-			// |----------------------------------------------------|
-			// |    |    |                 T2                  |    |
-			// |    |----|-------------------------------------|----|
-			// |    |    | C1 |                           | C2 |    |
-			// |    |    |----|                           |----|    |
-			// |    |    |                                     |    |
-			// | L1 | L2 |           ChartArea (C0)            | R1 |
-			// |    |    |                                     |    |
-			// |    |    |----|                           |----|    |
-			// |    |    | C3 |                           | C4 |    |
-			// |    |----|-------------------------------------|----|
-			// |    |    |                 B1                  |    |
-			// |----------------------------------------------------|
-			// |                  B2 (Full Width)                   |
-			// |----------------------------------------------------|
-			//
-			// What we do to find the best sizing, we do the following
-			// 1. Determine the minimum size of the chart area.
-			// 2. Split the remaining width equally between each vertical axis
-			// 3. Split the remaining height equally between each horizontal axis
-			// 4. Give each layout the maximum size it can be. The layout will return it's minimum size
-			// 5. Adjust the sizes of each axis based on it's minimum reported size.
-			// 6. Refit each axis
-			// 7. Position each axis in the final location
-			// 8. Tell the chart the final location of the chart area
-			// 9. Tell any axes that overlay the chart area the positions of the chart area
-
-			// Step 1
-			var chartWidth = width - (2 * xPadding);
-			var chartHeight = height - (2 * yPadding);
-			var chartAreaWidth = chartWidth / 2; // min 50%
-			var chartAreaHeight = chartHeight / 2; // min 50%
-
-			// Step 2
-			var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
-
-			// Step 3
-			var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
-
-			// Step 4
-			var maxChartAreaWidth = chartWidth;
-			var maxChartAreaHeight = chartHeight;
-			var minBoxSizes = [];
-
-			helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
-
-			function getMinimumBoxSize(box) {
-				var minSize;
-				var isHorizontal = box.isHorizontal();
-
-				if (isHorizontal) {
-					minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
-					maxChartAreaHeight -= minSize.height;
-				} else {
-					minSize = box.update(verticalBoxWidth, chartAreaHeight);
-					maxChartAreaWidth -= minSize.width;
-				}
-
-				minBoxSizes.push({
-					horizontal: isHorizontal,
-					minSize: minSize,
-					box: box
-				});
-			}
-
-			// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
-			// be if the axes are drawn at their minimum sizes.
-
-			// Steps 5 & 6
-			var totalLeftBoxesWidth = xPadding;
-			var totalRightBoxesWidth = xPadding;
-			var totalTopBoxesHeight = yPadding;
-			var totalBottomBoxesHeight = yPadding;
-
-			// Update, and calculate the left and right margins for the horizontal boxes
-			helpers.each(leftBoxes.concat(rightBoxes), fitBox);
-
-			helpers.each(leftBoxes, function(box) {
-				totalLeftBoxesWidth += box.width;
-			});
-
-			helpers.each(rightBoxes, function(box) {
-				totalRightBoxesWidth += box.width;
-			});
-
-			// Set the Left and Right margins for the horizontal boxes
-			helpers.each(topBoxes.concat(bottomBoxes), fitBox);
-
-			// Function to fit a box
-			function fitBox(box) {
-				var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
-					return minBoxSize.box === box;
-				});
-
-				if (minBoxSize) {
-					if (box.isHorizontal()) {
-						var scaleMargin = {
-							left: totalLeftBoxesWidth,
-							right: totalRightBoxesWidth,
-							top: 0,
-							bottom: 0
-						};
-
-						// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
-						// on the margin. Sometimes they need to increase in size slightly
-						box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
-					} else {
-						box.update(minBoxSize.minSize.width, maxChartAreaHeight);
-					}
-				}
-			}
-
-			// Figure out how much margin is on the top and bottom of the vertical boxes
-			helpers.each(topBoxes, function(box) {
-				totalTopBoxesHeight += box.height;
-			});
-
-			helpers.each(bottomBoxes, function(box) {
-				totalBottomBoxesHeight += box.height;
-			});
-
-			// Let the left layout know the final margin
-			helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
-
-			function finalFitVerticalBox(box) {
-				var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
-					return minBoxSize.box === box;
-				});
-
-				var scaleMargin = {
-					left: 0,
-					right: 0,
-					top: totalTopBoxesHeight,
-					bottom: totalBottomBoxesHeight
-				};
-
-				if (minBoxSize) {
-					box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
-				}
-			}
-
-			// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
-			totalLeftBoxesWidth = xPadding;
-			totalRightBoxesWidth = xPadding;
-			totalTopBoxesHeight = yPadding;
-			totalBottomBoxesHeight = yPadding;
-
-			helpers.each(leftBoxes, function(box) {
-				totalLeftBoxesWidth += box.width;
-			});
-
-			helpers.each(rightBoxes, function(box) {
-				totalRightBoxesWidth += box.width;
-			});
-
-			helpers.each(topBoxes, function(box) {
-				totalTopBoxesHeight += box.height;
-			});
-			helpers.each(bottomBoxes, function(box) {
-				totalBottomBoxesHeight += box.height;
-			});
-
-			// Figure out if our chart area changed. This would occur if the dataset layout label rotation
-			// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
-			// without calling `fit` again
-			var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
-			var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
-
-			if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
-				helpers.each(leftBoxes, function(box) {
-					box.height = newMaxChartAreaHeight;
-				});
-
-				helpers.each(rightBoxes, function(box) {
-					box.height = newMaxChartAreaHeight;
-				});
-
-				helpers.each(topBoxes, function(box) {
-					if (!box.options.fullWidth) {
-						box.width = newMaxChartAreaWidth;
-					}
-				});
-
-				helpers.each(bottomBoxes, function(box) {
-					if (!box.options.fullWidth) {
-						box.width = newMaxChartAreaWidth;
-					}
-				});
-
-				maxChartAreaHeight = newMaxChartAreaHeight;
-				maxChartAreaWidth = newMaxChartAreaWidth;
-			}
-
-			// Step 7 - Position the boxes
-			var left = xPadding;
-			var top = yPadding;
-
-			helpers.each(leftBoxes.concat(topBoxes), placeBox);
-
-			// Account for chart width and height
-			left += maxChartAreaWidth;
-			top += maxChartAreaHeight;
-
-			helpers.each(rightBoxes, placeBox);
-			helpers.each(bottomBoxes, placeBox);
-
-			function placeBox(box) {
-				if (box.isHorizontal()) {
-					box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
-					box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;
-					box.top = top;
-					box.bottom = top + box.height;
-
-					// Move to next point
-					top = box.bottom;
-
-				} else {
-
-					box.left = left;
-					box.right = left + box.width;
-					box.top = totalTopBoxesHeight;
-					box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
-
-					// Move to next point
-					left = box.right;
-				}
-			}
-
-			// Step 8
-			chartInstance.chartArea = {
-				left: totalLeftBoxesWidth,
-				top: totalTopBoxesHeight,
-				right: totalLeftBoxesWidth + maxChartAreaWidth,
-				bottom: totalTopBoxesHeight + maxChartAreaHeight
-			};
-
-			// Step 9
-			helpers.each(chartAreaBoxes, function(box) {
-				box.left = chartInstance.chartArea.left;
-				box.top = chartInstance.chartArea.top;
-				box.right = chartInstance.chartArea.right;
-				box.bottom = chartInstance.chartArea.bottom;
-
-				box.update(maxChartAreaWidth, maxChartAreaHeight);
-			});
-		}
-	};
-};
+        return Chart;
+    };
 
 },{}],29:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var noop = helpers.noop;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.legend = {
+        function filterByPosition(array, position) {
+            return helpers.where(array, function(v) {
+                return v.position === position;
+            });
+        }
 
-		display: true,
-		position: 'top',
-		fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
-		reverse: false,
+        function sortByWeight(array, reverse) {
+            array.forEach(function(v, i) {
+                v._tmpIndex_ = i;
+                return v;
+            });
+            array.sort(function(a, b) {
+                var v0 = reverse ? b : a;
+                var v1 = reverse ? a : b;
+                return v0.weight === v1.weight ?
+                    v0._tmpIndex_ - v1._tmpIndex_ :
+                    v0.weight - v1.weight;
+            });
+            array.forEach(function(v) {
+                delete v._tmpIndex_;
+            });
+        }
 
-		// a callback that will handle
-		onClick: function(e, legendItem) {
-			var index = legendItem.datasetIndex;
-			var ci = this.chart;
-			var meta = ci.getDatasetMeta(index);
+        /**
+         * @interface ILayoutItem
+         * @prop {String} position - The position of the item in the chart layout. Possible values are
+         * 'left', 'top', 'right', 'bottom', and 'chartArea'
+         * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area
+         * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
+         * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
+         * @prop {Function} update - Takes two parameters: width and height. Returns size of item
+         * @prop {Function} getPadding -  Returns an object with padding on the edges
+         * @prop {Number} width - Width of item. Must be valid after update()
+         * @prop {Number} height - Height of item. Must be valid after update()
+         * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update
+         * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update
+         * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update
+         * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
+         */
 
-			// See controller.isDatasetVisible comment
-			meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
+        // The layout service is very self explanatory.  It's responsible for the layout within a chart.
+        // Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
+        // It is this service's responsibility of carrying out that layout.
+        Chart.layoutService = {
+            defaults: {},
 
-			// We hid a dataset ... rerender the chart
-			ci.update();
-		},
+            /**
+             * Register a box to a chart.
+             * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
+             * @param {Chart} chart - the chart to use
+             * @param {ILayoutItem} item - the item to add to be layed out
+             */
+            addBox: function(chart, item) {
+                if (!chart.boxes) {
+                    chart.boxes = [];
+                }
 
-		labels: {
-			boxWidth: 40,
-			padding: 10,
-			// Generates labels shown in the legend
-			// Valid properties to return:
-			// text : text to display
-			// fillStyle : fill of coloured box
-			// strokeStyle: stroke of coloured box
-			// hidden : if this legend item refers to a hidden item
-			// lineCap : cap style for line
-			// lineDash
-			// lineDashOffset :
-			// lineJoin :
-			// lineWidth :
-			generateLabels: function(chart) {
-				var data = chart.data;
-				return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
-					return {
-						text: dataset.label,
-						fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
-						hidden: !chart.isDatasetVisible(i),
-						lineCap: dataset.borderCapStyle,
-						lineDash: dataset.borderDash,
-						lineDashOffset: dataset.borderDashOffset,
-						lineJoin: dataset.borderJoinStyle,
-						lineWidth: dataset.borderWidth,
-						strokeStyle: dataset.borderColor,
-						pointStyle: dataset.pointStyle,
+                // initialize item with default values
+                item.fullWidth = item.fullWidth || false;
+                item.position = item.position || 'top';
+                item.weight = item.weight || 0;
 
-						// Below is extra data used for toggling the datasets
-						datasetIndex: i
-					};
-				}, this) : [];
-			}
-		}
-	};
+                chart.boxes.push(item);
+            },
 
-	Chart.Legend = Chart.Element.extend({
+            /**
+             * Remove a layoutItem from a chart
+             * @param {Chart} chart - the chart to remove the box from
+             * @param {Object} layoutItem - the item to remove from the layout
+             */
+            removeBox: function(chart, layoutItem) {
+                var index = chart.boxes? chart.boxes.indexOf(layoutItem) : -1;
+                if (index !== -1) {
+                    chart.boxes.splice(index, 1);
+                }
+            },
 
-		initialize: function(config) {
-			helpers.extend(this, config);
+            /**
+             * Sets (or updates) options on the given `item`.
+             * @param {Chart} chart - the chart in which the item lives (or will be added to)
+             * @param {Object} item - the item to configure with the given options
+             * @param {Object} options - the new item options.
+             */
+            configure: function(chart, item, options) {
+                var props = ['fullWidth', 'position', 'weight'];
+                var ilen = props.length;
+                var i = 0;
+                var prop;
 
-			// Contains hit boxes for each dataset (in dataset order)
-			this.legendHitBoxes = [];
+                for (; i<ilen; ++i) {
+                    prop = props[i];
+                    if (options.hasOwnProperty(prop)) {
+                        item[prop] = options[prop];
+                    }
+                }
+            },
 
-			// Are we in doughnut mode which has a different data type
-			this.doughnutMode = false;
-		},
+            /**
+             * Fits boxes of the given chart into the given size by having each box measure itself
+             * then running a fitting algorithm
+             * @param {Chart} chart - the chart
+             * @param {Number} width - the width to fit into
+             * @param {Number} height - the height to fit into
+             */
+            update: function(chart, width, height) {
+                if (!chart) {
+                    return;
+                }
 
-		// These methods are ordered by lifecyle. Utilities then follow.
-		// Any function defined here is inherited by all legend types.
-		// Any function can be extended by the legend type
+                var layoutOptions = chart.options.layout;
+                var padding = layoutOptions ? layoutOptions.padding : null;
 
-		beforeUpdate: noop,
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+                var leftPadding = 0;
+                var rightPadding = 0;
+                var topPadding = 0;
+                var bottomPadding = 0;
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+                if (!isNaN(padding)) {
+                    // options.layout.padding is a number. assign to all
+                    leftPadding = padding;
+                    rightPadding = padding;
+                    topPadding = padding;
+                    bottomPadding = padding;
+                } else {
+                    leftPadding = padding.left || 0;
+                    rightPadding = padding.right || 0;
+                    topPadding = padding.top || 0;
+                    bottomPadding = padding.bottom || 0;
+                }
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = margins;
+                var leftBoxes = filterByPosition(chart.boxes, 'left');
+                var rightBoxes = filterByPosition(chart.boxes, 'right');
+                var topBoxes = filterByPosition(chart.boxes, 'top');
+                var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
+                var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
-			// Labels
-			me.beforeBuildLabels();
-			me.buildLabels();
-			me.afterBuildLabels();
+                // Sort boxes by weight. A higher weight is further away from the chart area
+                sortByWeight(leftBoxes, true);
+                sortByWeight(rightBoxes, false);
+                sortByWeight(topBoxes, true);
+                sortByWeight(bottomBoxes, false);
 
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                // Essentially we now have any number of boxes on each of the 4 sides.
+                // Our canvas looks like the following.
+                // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
+                // B1 is the bottom axis
+                // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
+                // These locations are single-box locations only, when trying to register a chartArea location that is already taken,
+                // an error will be thrown.
+                //
+                // |----------------------------------------------------|
+                // |                  T1 (Full Width)                   |
+                // |----------------------------------------------------|
+                // |    |    |                 T2                  |    |
+                // |    |----|-------------------------------------|----|
+                // |    |    | C1 |                           | C2 |    |
+                // |    |    |----|                           |----|    |
+                // |    |    |                                     |    |
+                // | L1 | L2 |           ChartArea (C0)            | R1 |
+                // |    |    |                                     |    |
+                // |    |    |----|                           |----|    |
+                // |    |    | C3 |                           | C4 |    |
+                // |    |----|-------------------------------------|----|
+                // |    |    |                 B1                  |    |
+                // |----------------------------------------------------|
+                // |                  B2 (Full Width)                   |
+                // |----------------------------------------------------|
+                //
+                // What we do to find the best sizing, we do the following
+                // 1. Determine the minimum size of the chart area.
+                // 2. Split the remaining width equally between each vertical axis
+                // 3. Split the remaining height equally between each horizontal axis
+                // 4. Give each layout the maximum size it can be. The layout will return it's minimum size
+                // 5. Adjust the sizes of each axis based on it's minimum reported size.
+                // 6. Refit each axis
+                // 7. Position each axis in the final location
+                // 8. Tell the chart the final location of the chart area
+                // 9. Tell any axes that overlay the chart area the positions of the chart area
 
-			return me.minSize;
-		},
-		afterUpdate: noop,
+                // Step 1
+                var chartWidth = width - leftPadding - rightPadding;
+                var chartHeight = height - topPadding - bottomPadding;
+                var chartAreaWidth = chartWidth / 2; // min 50%
+                var chartAreaHeight = chartHeight / 2; // min 50%
 
-		//
+                // Step 2
+                var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
 
-		beforeSetDimensions: noop,
-		setDimensions: function() {
-			var me = this;
-			// Set the unconstrained dimension before label rotation
-			if (me.isHorizontal()) {
-				// Reset position before calculating rotation
-				me.width = me.maxWidth;
-				me.left = 0;
-				me.right = me.width;
-			} else {
-				me.height = me.maxHeight;
+                // Step 3
+                var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+                // Step 4
+                var maxChartAreaWidth = chartWidth;
+                var maxChartAreaHeight = chartHeight;
+                var minBoxSizes = [];
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
+                function getMinimumBoxSize(box) {
+                    var minSize;
+                    var isHorizontal = box.isHorizontal();
 
-			// Reset minSize
-			me.minSize = {
-				width: 0,
-				height: 0
-			};
-		},
-		afterSetDimensions: noop,
+                    if (isHorizontal) {
+                        minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
+                        maxChartAreaHeight -= minSize.height;
+                    } else {
+                        minSize = box.update(verticalBoxWidth, chartAreaHeight);
+                        maxChartAreaWidth -= minSize.width;
+                    }
 
-		//
+                    minBoxSizes.push({
+                        horizontal: isHorizontal,
+                        minSize: minSize,
+                        box: box,
+                    });
+                }
 
-		beforeBuildLabels: noop,
-		buildLabels: function() {
-			var me = this;
-			me.legendItems = me.options.labels.generateLabels.call(me, me.chart);
-			if(me.options.reverse){
-				me.legendItems.reverse();
-			}
-		},
-		afterBuildLabels: noop,
+                helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
 
-		//
+                // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
+                var maxHorizontalLeftPadding = 0;
+                var maxHorizontalRightPadding = 0;
+                var maxVerticalTopPadding = 0;
+                var maxVerticalBottomPadding = 0;
 
-		beforeFit: noop,
-		fit: function() {
-			var me = this;
-			var opts = me.options;
-			var labelOpts = opts.labels;
-			var display = opts.display;
+                helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
+                    if (horizontalBox.getPadding) {
+                        var boxPadding = horizontalBox.getPadding();
+                        maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
+                        maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
+                    }
+                });
 
-			var ctx = me.ctx;
+                helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {
+                    if (verticalBox.getPadding) {
+                        var boxPadding = verticalBox.getPadding();
+                        maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);
+                        maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);
+                    }
+                });
 
-			var globalDefault = Chart.defaults.global,
-				itemOrDefault = helpers.getValueOrDefault,
-				fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
-				fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
-				fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
-				labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+                // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
+                // be if the axes are drawn at their minimum sizes.
+                // Steps 5 & 6
+                var totalLeftBoxesWidth = leftPadding;
+                var totalRightBoxesWidth = rightPadding;
+                var totalTopBoxesHeight = topPadding;
+                var totalBottomBoxesHeight = bottomPadding;
 
-			// Reset hit boxes
-			var hitboxes = me.legendHitBoxes = [];
+                // Function to fit a box
+                function fitBox(box) {
+                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
+                        return minBox.box === box;
+                    });
 
-			var minSize = me.minSize;
-			var isHorizontal = me.isHorizontal();
+                    if (minBoxSize) {
+                        if (box.isHorizontal()) {
+                            var scaleMargin = {
+                                left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
+                                right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
+                                top: 0,
+                                bottom: 0
+                            };
 
-			if (isHorizontal) {
-				minSize.width = me.maxWidth; // fill all the width
-				minSize.height = display ? 10 : 0;
-			} else {
-				minSize.width = display ? 10 : 0;
-				minSize.height = me.maxHeight; // fill all the height
-			}
-
-			// Increase sizes here
-			if (display) {
-				ctx.font = labelFont;
-
-				if (isHorizontal) {
-					// Labels
-
-					// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
-					var lineWidths = me.lineWidths = [0];
-					var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
-
-					ctx.textAlign = "left";
-					ctx.textBaseline = 'top';
-
-					helpers.each(me.legendItems, function(legendItem, i) {
-						var boxWidth = labelOpts.usePointStyle ?
-							fontSize * Math.sqrt(2) :
-							labelOpts.boxWidth;
-
-						var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
-						if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
-							totalHeight += fontSize + (labelOpts.padding);
-							lineWidths[lineWidths.length] = me.left;
-						}
-
-						// Store the hitbox width and height here. Final position will be updated in `draw`
-						hitboxes[i] = {
-							left: 0,
-							top: 0,
-							width: width,
-							height: fontSize
-						};
-
-						lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
-					});
-
-					minSize.height += totalHeight;
-
-				} else {
-					var vPadding = labelOpts.padding;
-					var columnWidths = me.columnWidths = [];
-					var totalWidth = labelOpts.padding;
-					var currentColWidth = 0;
-					var currentColHeight = 0;
-					var itemHeight = fontSize + vPadding;
-
-					helpers.each(me.legendItems, function(legendItem, i) {
-						// If usePointStyle is set, multiple boxWidth by 2 since it represents
-						// the radius and not truly the width
-						var boxWidth = labelOpts.usePointStyle ? 2 * labelOpts.boxWidth : labelOpts.boxWidth;
+                            // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
+                            // on the margin. Sometimes they need to increase in size slightly
+                            box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
+                        } else {
+                            box.update(minBoxSize.minSize.width, maxChartAreaHeight);
+                        }
+                    }
+                }
 
-						var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+                // Update, and calculate the left and right margins for the horizontal boxes
+                helpers.each(leftBoxes.concat(rightBoxes), fitBox);
 
-						// If too tall, go to new column
-						if (currentColHeight + itemHeight > minSize.height) {
-							totalWidth += currentColWidth + labelOpts.padding;
-							columnWidths.push(currentColWidth); // previous column width
+                helpers.each(leftBoxes, function(box) {
+                    totalLeftBoxesWidth += box.width;
+                });
 
-							currentColWidth = 0;
-							currentColHeight = 0;
-						}
+                helpers.each(rightBoxes, function(box) {
+                    totalRightBoxesWidth += box.width;
+                });
 
-						// Get max width
-						currentColWidth = Math.max(currentColWidth, itemWidth);
-						currentColHeight += itemHeight;
+                // Set the Left and Right margins for the horizontal boxes
+                helpers.each(topBoxes.concat(bottomBoxes), fitBox);
 
-						// Store the hitbox width and height here. Final position will be updated in `draw`
-						hitboxes[i] = {
-							left: 0,
-							top: 0,
-							width: itemWidth,
-							height: fontSize
-						};
-					});
+                // Figure out how much margin is on the top and bottom of the vertical boxes
+                helpers.each(topBoxes, function(box) {
+                    totalTopBoxesHeight += box.height;
+                });
 
-					totalWidth += currentColWidth;
-					columnWidths.push(currentColWidth);
-					minSize.width += totalWidth;
-				}
-			}
+                helpers.each(bottomBoxes, function(box) {
+                    totalBottomBoxesHeight += box.height;
+                });
 
-			me.width = minSize.width;
-			me.height = minSize.height;
-		},
-		afterFit: noop,
+                function finalFitVerticalBox(box) {
+                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
+                        return minSize.box === box;
+                    });
 
-		// Shared Methods
-		isHorizontal: function() {
-			return this.options.position === "top" || this.options.position === "bottom";
-		},
+                    var scaleMargin = {
+                        left: 0,
+                        right: 0,
+                        top: totalTopBoxesHeight,
+                        bottom: totalBottomBoxesHeight
+                    };
 
-		// Actualy draw the legend on the canvas
-		draw: function() {
-			var me = this;
-			var opts = me.options;
-			var labelOpts = opts.labels;
-			var globalDefault = Chart.defaults.global,
-				lineDefault = globalDefault.elements.line,
-				legendWidth = me.width,
-				lineWidths = me.lineWidths;
+                    if (minBoxSize) {
+                        box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
+                    }
+                }
 
-			if (opts.display) {
-				var ctx = me.ctx,
-					cursor,
-					itemOrDefault = helpers.getValueOrDefault,
-					fontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),
-					fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
-					fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
-					fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
-					labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+                // Let the left layout know the final margin
+                helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
 
-				// Canvas setup
-				ctx.textAlign = "left";
-				ctx.textBaseline = 'top';
-				ctx.lineWidth = 0.5;
-				ctx.strokeStyle = fontColor; // for strikethrough effect
-				ctx.fillStyle = fontColor; // render in correct colour
-				ctx.font = labelFont;
+                // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
+                totalLeftBoxesWidth = leftPadding;
+                totalRightBoxesWidth = rightPadding;
+                totalTopBoxesHeight = topPadding;
+                totalBottomBoxesHeight = bottomPadding;
 
-				var boxWidth = labelOpts.boxWidth,
-					hitboxes = me.legendHitBoxes;
+                helpers.each(leftBoxes, function(box) {
+                    totalLeftBoxesWidth += box.width;
+                });
 
-				// current position
-				var drawLegendBox = function(x, y, legendItem) {
-					if (isNaN(boxWidth) || boxWidth <= 0) {
-						return;
-					}
+                helpers.each(rightBoxes, function(box) {
+                    totalRightBoxesWidth += box.width;
+                });
 
-					// Set the ctx for the box
-					ctx.save();
+                helpers.each(topBoxes, function(box) {
+                    totalTopBoxesHeight += box.height;
+                });
+                helpers.each(bottomBoxes, function(box) {
+                    totalBottomBoxesHeight += box.height;
+                });
 
-					ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
-					ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
-					ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
-					ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
-					ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
-					ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
+                // We may be adding some padding to account for rotated x axis labels
+                var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
+                totalLeftBoxesWidth += leftPaddingAddition;
+                totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
 
-					if (ctx.setLineDash) {
-						// IE 9 and 10 do not support line dash
-						ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
-					}
+                var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
+                totalTopBoxesHeight += topPaddingAddition;
+                totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
 
-					if (opts.labels && opts.labels.usePointStyle) {
-						// Recalulate x and y for drawPoint() because its expecting
-						// x and y to be center of figure (instead of top left)
-						var radius = fontSize * Math.SQRT2 / 2;
-						var offSet = radius / Math.SQRT2;
-						var centerX = x + offSet;
-						var centerY = y + offSet;
+                // Figure out if our chart area changed. This would occur if the dataset layout label rotation
+                // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
+                // without calling `fit` again
+                var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
+                var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
 
-						// Draw pointStyle as legend symbol
-						Chart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
-					}
-					else {
-						// Draw box as legend symbol
-						ctx.strokeRect(x, y, boxWidth, fontSize);
-						ctx.fillRect(x, y, boxWidth, fontSize);
-					}
+                if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
+                    helpers.each(leftBoxes, function(box) {
+                        box.height = newMaxChartAreaHeight;
+                    });
 
-					ctx.restore();
-				};
-				var fillText = function(x, y, legendItem, textWidth) {
-					ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+                    helpers.each(rightBoxes, function(box) {
+                        box.height = newMaxChartAreaHeight;
+                    });
 
-					if (legendItem.hidden) {
-						// Strikethrough the text if hidden
-						ctx.beginPath();
-						ctx.lineWidth = 2;
-						ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
-						ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
-						ctx.stroke();
-					}
-				};
+                    helpers.each(topBoxes, function(box) {
+                        if (!box.fullWidth) {
+                            box.width = newMaxChartAreaWidth;
+                        }
+                    });
 
-				// Horizontal
-				var isHorizontal = me.isHorizontal();
-				if (isHorizontal) {
-					cursor = {
-						x: me.left + ((legendWidth - lineWidths[0]) / 2),
-						y: me.top + labelOpts.padding,
-						line: 0
-					};
-				} else {
-					cursor = {
-						x: me.left + labelOpts.padding,
-						y: me.top + labelOpts.padding,
-						line: 0
-					};
-				}
+                    helpers.each(bottomBoxes, function(box) {
+                        if (!box.fullWidth) {
+                            box.width = newMaxChartAreaWidth;
+                        }
+                    });
 
-				var itemHeight = fontSize + labelOpts.padding;
-				helpers.each(me.legendItems, function(legendItem, i) {
-					var textWidth = ctx.measureText(legendItem.text).width,
-						width = labelOpts.usePointStyle ?
-							fontSize + (fontSize / 2) + textWidth :
-							boxWidth + (fontSize / 2) + textWidth,
-						x = cursor.x,
-						y = cursor.y;
+                    maxChartAreaHeight = newMaxChartAreaHeight;
+                    maxChartAreaWidth = newMaxChartAreaWidth;
+                }
 
-					if (isHorizontal) {
-						if (x + width >= legendWidth) {
-							y = cursor.y += itemHeight;
-							cursor.line++;
-							x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
-						}
-					} else {
-						if (y + itemHeight > me.bottom) {
-							x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
-							y = cursor.y = me.top;
-							cursor.line++;
-						}
-					}
+                // Step 7 - Position the boxes
+                var left = leftPadding + leftPaddingAddition;
+                var top = topPadding + topPaddingAddition;
 
-					drawLegendBox(x, y, legendItem);
+                function placeBox(box) {
+                    if (box.isHorizontal()) {
+                        box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;
+                        box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
+                        box.top = top;
+                        box.bottom = top + box.height;
 
-					hitboxes[i].left = x;
-					hitboxes[i].top = y;
+                        // Move to next point
+                        top = box.bottom;
 
-					// Fill the actual label
-					fillText(x, y, legendItem, textWidth);
+                    } else {
 
-					if (isHorizontal) {
-						cursor.x += width + (labelOpts.padding);
-					} else {
-						cursor.y += itemHeight;
-					}
+                        box.left = left;
+                        box.right = left + box.width;
+                        box.top = totalTopBoxesHeight;
+                        box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
 
-				});
-			}
-		},
+                        // Move to next point
+                        left = box.right;
+                    }
+                }
 
-		// Handle an event
-		handleEvent: function(e) {
-			var me = this;
-			var position = helpers.getRelativePosition(e, me.chart.chart),
-				x = position.x,
-				y = position.y,
-				opts = me.options;
+                helpers.each(leftBoxes.concat(topBoxes), placeBox);
 
-			if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
-				// See if we are touching one of the dataset boxes
-				var lh = me.legendHitBoxes;
-				for (var i = 0; i < lh.length; ++i) {
-					var hitBox = lh[i];
+                // Account for chart width and height
+                left += maxChartAreaWidth;
+                top += maxChartAreaHeight;
 
-					if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
-						// Touching an element
-						if (opts.onClick) {
-							opts.onClick.call(me, e, me.legendItems[i]);
-						}
-						break;
-					}
-				}
-			}
-		}
-	});
+                helpers.each(rightBoxes, placeBox);
+                helpers.each(bottomBoxes, placeBox);
 
-	// Register the legend plugin
-	Chart.plugins.register({
-		beforeInit: function(chartInstance) {
-			var opts = chartInstance.options;
-			var legendOpts = opts.legend;
+                // Step 8
+                chart.chartArea = {
+                    left: totalLeftBoxesWidth,
+                    top: totalTopBoxesHeight,
+                    right: totalLeftBoxesWidth + maxChartAreaWidth,
+                    bottom: totalTopBoxesHeight + maxChartAreaHeight
+                };
 
-			if (legendOpts) {
-				chartInstance.legend = new Chart.Legend({
-					ctx: chartInstance.chart.ctx,
-					options: legendOpts,
-					chart: chartInstance
-				});
+                // Step 9
+                helpers.each(chartAreaBoxes, function(box) {
+                    box.left = chart.chartArea.left;
+                    box.top = chart.chartArea.top;
+                    box.right = chart.chartArea.right;
+                    box.bottom = chart.chartArea.bottom;
 
-				Chart.layoutService.addBox(chartInstance, chartInstance.legend);
-			}
-		}
-	});
-};
+                    box.update(maxChartAreaWidth, maxChartAreaHeight);
+                });
+            }
+        };
+    };
 
 },{}],30:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var noop = Chart.helpers.noop;
+        var helpers = Chart.helpers;
 
-	/**
-	 * The plugin service singleton
-	 * @namespace Chart.plugins
-	 * @since 2.1.0
-	 */
-	Chart.plugins = {
-		_plugins: [],
+        Chart.defaults.global.plugins = {};
 
-		/**
-		 * Registers the given plugin(s) if not already registered.
-		 * @param {Array|Object} plugins plugin instance(s).
-		 */
-		register: function(plugins) {
-			var p = this._plugins;
-			([]).concat(plugins).forEach(function(plugin) {
-				if (p.indexOf(plugin) === -1) {
-					p.push(plugin);
-				}
-			});
-		},
+        /**
+         * The plugin service singleton
+         * @namespace Chart.plugins
+         * @since 2.1.0
+         */
+        Chart.plugins = {
+            /**
+             * Globally registered plugins.
+             * @private
+             */
+            _plugins: [],
 
-		/**
-		 * Unregisters the given plugin(s) only if registered.
-		 * @param {Array|Object} plugins plugin instance(s).
-		 */
-		unregister: function(plugins) {
-			var p = this._plugins;
-			([]).concat(plugins).forEach(function(plugin) {
-				var idx = p.indexOf(plugin);
-				if (idx !== -1) {
-					p.splice(idx, 1);
-				}
-			});
-		},
+            /**
+             * This identifier is used to invalidate the descriptors cache attached to each chart
+             * when a global plugin is registered or unregistered. In this case, the cache ID is
+             * incremented and descriptors are regenerated during following API calls.
+             * @private
+             */
+            _cacheId: 0,
 
-		/**
-		 * Remove all registered p^lugins.
-		 * @since 2.1.5
-		 */
-		clear: function() {
-			this._plugins = [];
-		},
+            /**
+             * Registers the given plugin(s) if not already registered.
+             * @param {Array|Object} plugins plugin instance(s).
+             */
+            register: function(plugins) {
+                var p = this._plugins;
+                ([]).concat(plugins).forEach(function(plugin) {
+                    if (p.indexOf(plugin) === -1) {
+                        p.push(plugin);
+                    }
+                });
 
-		/**
-		 * Returns the number of registered plugins?
-		 * @returns {Number}
-		 * @since 2.1.5
-		 */
-		count: function() {
-			return this._plugins.length;
-		},
+                this._cacheId++;
+            },
 
-		/**
-		 * Returns all registered plugin intances.
-		 * @returns {Array} array of plugin objects.
-		 * @since 2.1.5
-		 */
-		getAll: function() {
-			return this._plugins;
-		},
+            /**
+             * Unregisters the given plugin(s) only if registered.
+             * @param {Array|Object} plugins plugin instance(s).
+             */
+            unregister: function(plugins) {
+                var p = this._plugins;
+                ([]).concat(plugins).forEach(function(plugin) {
+                    var idx = p.indexOf(plugin);
+                    if (idx !== -1) {
+                        p.splice(idx, 1);
+                    }
+                });
 
-		/**
-		 * Calls registered plugins on the specified extension, with the given args. This
-		 * method immediately returns as soon as a plugin explicitly returns false. The
-		 * returned value can be used, for instance, to interrupt the current action.
-		 * @param {String} extension the name of the plugin method to call (e.g. 'beforeUpdate').
-		 * @param {Array} [args] extra arguments to apply to the extension call.
-		 * @returns {Boolean} false if any of the plugins return false, else returns true.
-		 */
-		notify: function(extension, args) {
-			var plugins = this._plugins;
-			var ilen = plugins.length;
-			var i, plugin;
+                this._cacheId++;
+            },
 
-			for (i=0; i<ilen; ++i) {
-				plugin = plugins[i];
-				if (typeof plugin[extension] === 'function') {
-					if (plugin[extension].apply(plugin, args || []) === false) {
-						return false;
-					}
-				}
-			}
+            /**
+             * Remove all registered plugins.
+             * @since 2.1.5
+             */
+            clear: function() {
+                this._plugins = [];
+                this._cacheId++;
+            },
 
-			return true;
-		}
-	};
+            /**
+             * Returns the number of registered plugins?
+             * @returns {Number}
+             * @since 2.1.5
+             */
+            count: function() {
+                return this._plugins.length;
+            },
 
-	/**
-	 * Plugin extension methods.
-	 * @interface Chart.PluginBase
-	 * @since 2.1.0
-	 */
-	Chart.PluginBase = Chart.Element.extend({
-		// Called at start of chart init
-		beforeInit: noop,
+            /**
+             * Returns all registered plugin instances.
+             * @returns {Array} array of plugin objects.
+             * @since 2.1.5
+             */
+            getAll: function() {
+                return this._plugins;
+            },
 
-		// Called at end of chart init
-		afterInit: noop,
+            /**
+             * Calls enabled plugins for `chart` on the specified hook and with the given args.
+             * This method immediately returns as soon as a plugin explicitly returns false. The
+             * returned value can be used, for instance, to interrupt the current action.
+             * @param {Object} chart - The chart instance for which plugins should be called.
+             * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').
+             * @param {Array} [args] - Extra arguments to apply to the hook call.
+             * @returns {Boolean} false if any of the plugins return false, else returns true.
+             */
+            notify: function(chart, hook, args) {
+                var descriptors = this.descriptors(chart);
+                var ilen = descriptors.length;
+                var i, descriptor, plugin, params, method;
 
-		// Called at start of update
-		beforeUpdate: noop,
+                for (i=0; i<ilen; ++i) {
+                    descriptor = descriptors[i];
+                    plugin = descriptor.plugin;
+                    method = plugin[hook];
+                    if (typeof method === 'function') {
+                        params = [chart].concat(args || []);
+                        params.push(descriptor.options);
+                        if (method.apply(plugin, params) === false) {
+                            return false;
+                        }
+                    }
+                }
 
-		// Called at end of update
-		afterUpdate: noop,
+                return true;
+            },
 
-		// Called at start of draw
-		beforeDraw: noop,
+            /**
+             * Returns descriptors of enabled plugins for the given chart.
+             * @returns {Array} [{ plugin, options }]
+             * @private
+             */
+            descriptors: function(chart) {
+                var cache = chart._plugins || (chart._plugins = {});
+                if (cache.id === this._cacheId) {
+                    return cache.descriptors;
+                }
 
-		// Called at end of draw
-		afterDraw: noop,
+                var plugins = [];
+                var descriptors = [];
+                var config = (chart && chart.config) || {};
+                var defaults = Chart.defaults.global.plugins;
+                var options = (config.options && config.options.plugins) || {};
 
-		// Called during destroy
-		destroy: noop
-	});
+                this._plugins.concat(config.plugins || []).forEach(function(plugin) {
+                    var idx = plugins.indexOf(plugin);
+                    if (idx !== -1) {
+                        return;
+                    }
 
-	/**
-	 * Provided for backward compatibility, use Chart.plugins instead
-	 * @namespace Chart.pluginService
-	 * @deprecated since version 2.1.5
-	 * @todo remove me at version 3
-	 */
-	Chart.pluginService = Chart.plugins;
-};
+                    var id = plugin.id;
+                    var opts = options[id];
+                    if (opts === false) {
+                        return;
+                    }
+
+                    if (opts === true) {
+                        opts = helpers.clone(defaults[id]);
+                    }
+
+                    plugins.push(plugin);
+                    descriptors.push({
+                        plugin: plugin,
+                        options: opts || {}
+                    });
+                });
+
+                cache.descriptors = descriptors;
+                cache.id = this._cacheId;
+                return descriptors;
+            }
+        };
+
+        /**
+         * Plugin extension hooks.
+         * @interface IPlugin
+         * @since 2.1.0
+         */
+        /**
+         * @method IPlugin#beforeInit
+         * @desc Called before initializing `chart`.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#afterInit
+         * @desc Called after `chart` has been initialized and before the first update.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeUpdate
+         * @desc Called before updating `chart`. If any plugin returns `false`, the update
+         * is cancelled (and thus subsequent render(s)) until another `update` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart update.
+         */
+        /**
+         * @method IPlugin#afterUpdate
+         * @desc Called after `chart` has been updated and before rendering. Note that this
+         * hook will not be called if the chart update has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeDatasetsUpdate
+         * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
+         * the datasets update is cancelled until another `update` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} false to cancel the datasets update.
+         * @since version 2.1.5
+         */
+        /**
+         * @method IPlugin#afterDatasetsUpdate
+         * @desc Called after the `chart` datasets have been updated. Note that this hook
+         * will not be called if the datasets update has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         * @since version 2.1.5
+         */
+        /**
+         * @method IPlugin#beforeDatasetUpdate
+         * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin
+         * returns `false`, the datasets update is cancelled until another `update` is triggered.
+         * @param {Chart} chart - The chart instance.
+         * @param {Object} args - The call arguments.
+         * @param {Object} args.index - The dataset index.
+         * @param {Number} args.meta - The dataset metadata.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart datasets drawing.
+         */
+        /**
+         * @method IPlugin#afterDatasetUpdate
+         * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note
+         * that this hook will not be called if the datasets update has been previously cancelled.
+         * @param {Chart} chart - The chart instance.
+         * @param {Object} args - The call arguments.
+         * @param {Object} args.index - The dataset index.
+         * @param {Number} args.meta - The dataset metadata.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeLayout
+         * @desc Called before laying out `chart`. If any plugin returns `false`,
+         * the layout update is cancelled until another `update` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart layout.
+         */
+        /**
+         * @method IPlugin#afterLayout
+         * @desc Called after the `chart` has been layed out. Note that this hook will not
+         * be called if the layout update has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeRender
+         * @desc Called before rendering `chart`. If any plugin returns `false`,
+         * the rendering is cancelled until another `render` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart rendering.
+         */
+        /**
+         * @method IPlugin#afterRender
+         * @desc Called after the `chart` has been fully rendered (and animation completed). Note
+         * that this hook will not be called if the rendering has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeDraw
+         * @desc Called before drawing `chart` at every animation frame specified by the given
+         * easing value. If any plugin returns `false`, the frame drawing is cancelled until
+         * another `render` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart drawing.
+         */
+        /**
+         * @method IPlugin#afterDraw
+         * @desc Called after the `chart` has been drawn for the specific easing value. Note
+         * that this hook will not be called if the drawing has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeDatasetsDraw
+         * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,
+         * the datasets drawing is cancelled until another `render` is triggered.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart datasets drawing.
+         */
+        /**
+         * @method IPlugin#afterDatasetsDraw
+         * @desc Called after the `chart` datasets have been drawn. Note that this hook
+         * will not be called if the datasets drawing has been previously cancelled.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeDatasetDraw
+         * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets
+         * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing
+         * is cancelled until another `render` is triggered.
+         * @param {Chart} chart - The chart instance.
+         * @param {Object} args - The call arguments.
+         * @param {Object} args.index - The dataset index.
+         * @param {Number} args.meta - The dataset metadata.
+         * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         * @returns {Boolean} `false` to cancel the chart datasets drawing.
+         */
+        /**
+         * @method IPlugin#afterDatasetDraw
+         * @desc Called after the `chart` datasets at the given `args.index` have been drawn
+         * (datasets are drawn in the reverse order). Note that this hook will not be called
+         * if the datasets drawing has been previously cancelled.
+         * @param {Chart} chart - The chart instance.
+         * @param {Object} args - The call arguments.
+         * @param {Object} args.index - The dataset index.
+         * @param {Number} args.meta - The dataset metadata.
+         * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#beforeEvent
+         * @desc Called before processing the specified `event`. If any plugin returns `false`,
+         * the event will be discarded.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {IEvent} event - The event object.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#afterEvent
+         * @desc Called after the `event` has been consumed. Note that this hook
+         * will not be called if the `event` has been previously discarded.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {IEvent} event - The event object.
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#resize
+         * @desc Called after the chart as been resized.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Number} size - The new canvas display size (eq. canvas.style width & height).
+         * @param {Object} options - The plugin options.
+         */
+        /**
+         * @method IPlugin#destroy
+         * @desc Called after the chart as been destroyed.
+         * @param {Chart.Controller} chart - The chart instance.
+         * @param {Object} options - The plugin options.
+         */
+
+        /**
+         * Provided for backward compatibility, use Chart.plugins instead
+         * @namespace Chart.pluginService
+         * @deprecated since version 2.1.5
+         * @todo remove at version 3
+         * @private
+         */
+        Chart.pluginService = Chart.plugins;
+
+        /**
+         * Provided for backward compatibility, inheriting from Chart.PlugingBase has no
+         * effect, instead simply create/register plugins via plain JavaScript objects.
+         * @interface Chart.PluginBase
+         * @deprecated since version 2.5.0
+         * @todo remove at version 3
+         * @private
+         */
+        Chart.PluginBase = Chart.Element.extend({});
+    };
 
 },{}],31:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.scale = {
-		display: true,
-		position: "left",
+        Chart.defaults.scale = {
+            display: true,
+            position: 'left',
 
-		// grid line settings
-		gridLines: {
-			display: true,
-			color: "rgba(0, 0, 0, 0.1)",
-			lineWidth: 1,
-			drawBorder: true,
-			drawOnChartArea: true,
-			drawTicks: true,
-			tickMarkLength: 10,
-			zeroLineWidth: 1,
-			zeroLineColor: "rgba(0,0,0,0.25)",
-			offsetGridLines: false
-		},
+            // grid line settings
+            gridLines: {
+                display: true,
+                color: 'rgba(0, 0, 0, 0.1)',
+                lineWidth: 1,
+                drawBorder: true,
+                drawOnChartArea: true,
+                drawTicks: true,
+                tickMarkLength: 10,
+                zeroLineWidth: 1,
+                zeroLineColor: 'rgba(0,0,0,0.25)',
+                zeroLineBorderDash: [],
+                zeroLineBorderDashOffset: 0.0,
+                offsetGridLines: false,
+                borderDash: [],
+                borderDashOffset: 0.0
+            },
 
-		// scale label
-		scaleLabel: {
-			// actual label
-			labelString: '',
+            // scale label
+            scaleLabel: {
+                // actual label
+                labelString: '',
 
-			// display property
-			display: false
-		},
+                // display property
+                display: false
+            },
 
-		// label settings
-		ticks: {
-			beginAtZero: false,
-			minRotation: 0,
-			maxRotation: 50,
-			mirror: false,
-			padding: 10,
-			reverse: false,
-			display: true,
-			autoSkip: true,
-			autoSkipPadding: 0,
-			labelOffset: 0,
-			// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
-			callback: function(value) {
-				return helpers.isArray(value) ? value : '' + value;
-			}
-		}
-	};
+            // label settings
+            ticks: {
+                beginAtZero: false,
+                minRotation: 0,
+                maxRotation: 50,
+                mirror: false,
+                padding: 0,
+                reverse: false,
+                display: true,
+                autoSkip: true,
+                autoSkipPadding: 0,
+                labelOffset: 0,
+                // We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
+                callback: Chart.Ticks.formatters.values
+            }
+        };
 
-	Chart.Scale = Chart.Element.extend({
+        function computeTextSize(context, tick, font) {
+            return helpers.isArray(tick) ?
+                helpers.longestText(context, font, tick) :
+                context.measureText(tick).width;
+        }
 
-		// These methods are ordered by lifecyle. Utilities then follow.
-		// Any function defined here is inherited by all scale types.
-		// Any function can be extended by the scale type
+        function parseFontOptions(options) {
+            var getValueOrDefault = helpers.getValueOrDefault;
+            var globalDefaults = Chart.defaults.global;
+            var size = getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
+            var style = getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
+            var family = getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
 
-		beforeUpdate: function() {
-			helpers.callCallback(this.options.beforeUpdate, [this]);
-		},
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+            return {
+                size: size,
+                style: style,
+                family: family,
+                font: helpers.fontString(size, style, family)
+            };
+        }
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+        Chart.Scale = Chart.Element.extend({
+            /**
+             * Get the padding needed for the scale
+             * @method getPadding
+             * @private
+             * @returns {Padding} the necessary padding
+             */
+            getPadding: function() {
+                var me = this;
+                return {
+                    left: me.paddingLeft || 0,
+                    top: me.paddingTop || 0,
+                    right: me.paddingRight || 0,
+                    bottom: me.paddingBottom || 0
+                };
+            },
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = helpers.extend({
-				left: 0,
-				right: 0,
-				top: 0,
-				bottom: 0
-			}, margins);
+            // These methods are ordered by lifecyle. Utilities then follow.
+            // Any function defined here is inherited by all scale types.
+            // Any function can be extended by the scale type
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
+            beforeUpdate: function() {
+                helpers.callback(this.options.beforeUpdate, [this]);
+            },
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			// Data min/max
-			me.beforeDataLimits();
-			me.determineDataLimits();
-			me.afterDataLimits();
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-			// Ticks
-			me.beforeBuildTicks();
-			me.buildTicks();
-			me.afterBuildTicks();
+                // Absorb the master measurements
+                me.maxWidth = maxWidth;
+                me.maxHeight = maxHeight;
+                me.margins = helpers.extend({
+                    left: 0,
+                    right: 0,
+                    top: 0,
+                    bottom: 0
+                }, margins);
+                me.longestTextCache = me.longestTextCache || {};
 
-			me.beforeTickToLabelConversion();
-			me.convertTicksToLabels();
-			me.afterTickToLabelConversion();
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
 
-			// Tick Rotation
-			me.beforeCalculateTickRotation();
-			me.calculateTickRotation();
-			me.afterCalculateTickRotation();
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                // Data min/max
+                me.beforeDataLimits();
+                me.determineDataLimits();
+                me.afterDataLimits();
 
-			return me.minSize;
+                // Ticks
+                me.beforeBuildTicks();
+                me.buildTicks();
+                me.afterBuildTicks();
 
-		},
-		afterUpdate: function() {
-			helpers.callCallback(this.options.afterUpdate, [this]);
-		},
+                me.beforeTickToLabelConversion();
+                me.convertTicksToLabels();
+                me.afterTickToLabelConversion();
 
-		//
+                // Tick Rotation
+                me.beforeCalculateTickRotation();
+                me.calculateTickRotation();
+                me.afterCalculateTickRotation();
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-		beforeSetDimensions: function() {
-			helpers.callCallback(this.options.beforeSetDimensions, [this]);
-		},
-		setDimensions: function() {
-			var me = this;
-			// Set the unconstrained dimension before label rotation
-			if (me.isHorizontal()) {
-				// Reset position before calculating rotation
-				me.width = me.maxWidth;
-				me.left = 0;
-				me.right = me.width;
-			} else {
-				me.height = me.maxHeight;
+                return me.minSize;
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+            },
+            afterUpdate: function() {
+                helpers.callback(this.options.afterUpdate, [this]);
+            },
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
-		},
-		afterSetDimensions: function() {
-			helpers.callCallback(this.options.afterSetDimensions, [this]);
-		},
+            //
 
-		// Data limits
-		beforeDataLimits: function() {
-			helpers.callCallback(this.options.beforeDataLimits, [this]);
-		},
-		determineDataLimits: helpers.noop,
-		afterDataLimits: function() {
-			helpers.callCallback(this.options.afterDataLimits, [this]);
-		},
+            beforeSetDimensions: function() {
+                helpers.callback(this.options.beforeSetDimensions, [this]);
+            },
+            setDimensions: function() {
+                var me = this;
+                // Set the unconstrained dimension before label rotation
+                if (me.isHorizontal()) {
+                    // Reset position before calculating rotation
+                    me.width = me.maxWidth;
+                    me.left = 0;
+                    me.right = me.width;
+                } else {
+                    me.height = me.maxHeight;
 
-		//
-		beforeBuildTicks: function() {
-			helpers.callCallback(this.options.beforeBuildTicks, [this]);
-		},
-		buildTicks: helpers.noop,
-		afterBuildTicks: function() {
-			helpers.callCallback(this.options.afterBuildTicks, [this]);
-		},
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-		beforeTickToLabelConversion: function() {
-			helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			// Convert ticks to strings
-			me.ticks = me.ticks.map(function(numericalTick, index, ticks) {
-					if (me.options.ticks.userCallback) {
-						return me.options.ticks.userCallback(numericalTick, index, ticks);
-					}
-					return me.options.ticks.callback(numericalTick, index, ticks);
-				},
-				me);
-		},
-		afterTickToLabelConversion: function() {
-			helpers.callCallback(this.options.afterTickToLabelConversion, [this]);
-		},
+                // Reset padding
+                me.paddingLeft = 0;
+                me.paddingTop = 0;
+                me.paddingRight = 0;
+                me.paddingBottom = 0;
+            },
+            afterSetDimensions: function() {
+                helpers.callback(this.options.afterSetDimensions, [this]);
+            },
 
-		//
+            // Data limits
+            beforeDataLimits: function() {
+                helpers.callback(this.options.beforeDataLimits, [this]);
+            },
+            determineDataLimits: helpers.noop,
+            afterDataLimits: function() {
+                helpers.callback(this.options.afterDataLimits, [this]);
+            },
 
-		beforeCalculateTickRotation: function() {
-			helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);
-		},
-		calculateTickRotation: function() {
-			var me = this;
-			var context = me.ctx;
-			var globalDefaults = Chart.defaults.global;
-			var optionTicks = me.options.ticks;
+            //
+            beforeBuildTicks: function() {
+                helpers.callback(this.options.beforeBuildTicks, [this]);
+            },
+            buildTicks: helpers.noop,
+            afterBuildTicks: function() {
+                helpers.callback(this.options.afterBuildTicks, [this]);
+            },
 
-			//Get the width of each grid by calculating the difference
-			//between x offsets between 0 and 1.
-			var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			context.font = tickLabelFont;
+            beforeTickToLabelConversion: function() {
+                helpers.callback(this.options.beforeTickToLabelConversion, [this]);
+            },
+            convertTicksToLabels: function() {
+                var me = this;
+                // Convert ticks to strings
+                var tickOpts = me.options.ticks;
+                me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);
+            },
+            afterTickToLabelConversion: function() {
+                helpers.callback(this.options.afterTickToLabelConversion, [this]);
+            },
 
-			var firstWidth = context.measureText(me.ticks[0]).width;
-			var lastWidth = context.measureText(me.ticks[me.ticks.length - 1]).width;
-			var firstRotated;
+            //
 
-			me.labelRotation = optionTicks.minRotation || 0;
-			me.paddingRight = 0;
-			me.paddingLeft = 0;
+            beforeCalculateTickRotation: function() {
+                helpers.callback(this.options.beforeCalculateTickRotation, [this]);
+            },
+            calculateTickRotation: function() {
+                var me = this;
+                var context = me.ctx;
+                var tickOpts = me.options.ticks;
 
-			if (me.options.display) {
-				if (me.isHorizontal()) {
-					me.paddingRight = lastWidth / 2 + 3;
-					me.paddingLeft = firstWidth / 2 + 3;
+                // Get the width of each grid by calculating the difference
+                // between x offsets between 0 and 1.
+                var tickFont = parseFontOptions(tickOpts);
+                context.font = tickFont.font;
 
-					if (!me.longestTextCache) {
-						me.longestTextCache = {};
-					}
-					var originalLabelWidth = helpers.longestText(context, tickLabelFont, me.ticks, me.longestTextCache);
-					var labelWidth = originalLabelWidth;
-					var cosRotation;
-					var sinRotation;
+                var labelRotation = tickOpts.minRotation || 0;
 
-					// Allow 3 pixels x2 padding either side for label readability
-					// only the index matters for a dataset scale, but we want a consistent interface between scales
-					var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
+                if (me.options.display && me.isHorizontal()) {
+                    var originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);
+                    var labelWidth = originalLabelWidth;
+                    var cosRotation;
+                    var sinRotation;
 
-					//Max label rotation can be set or default to 90 - also act as a loop counter
-					while (labelWidth > tickWidth && me.labelRotation < optionTicks.maxRotation) {
-						cosRotation = Math.cos(helpers.toRadians(me.labelRotation));
-						sinRotation = Math.sin(helpers.toRadians(me.labelRotation));
+                    // Allow 3 pixels x2 padding either side for label readability
+                    var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
 
-						firstRotated = cosRotation * firstWidth;
+                    // Max label rotation can be set or default to 90 - also act as a loop counter
+                    while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {
+                        var angleRadians = helpers.toRadians(labelRotation);
+                        cosRotation = Math.cos(angleRadians);
+                        sinRotation = Math.sin(angleRadians);
 
-						// We're right aligning the text now.
-						if (firstRotated + tickFontSize / 2 > me.yLabelWidth) {
-							me.paddingLeft = firstRotated + tickFontSize / 2;
-						}
+                        if (sinRotation * originalLabelWidth > me.maxHeight) {
+                            // go back one step
+                            labelRotation--;
+                            break;
+                        }
 
-						me.paddingRight = tickFontSize / 2;
+                        labelRotation++;
+                        labelWidth = cosRotation * originalLabelWidth;
+                    }
+                }
 
-						if (sinRotation * originalLabelWidth > me.maxHeight) {
-							// go back one step
-							me.labelRotation--;
-							break;
-						}
+                me.labelRotation = labelRotation;
+            },
+            afterCalculateTickRotation: function() {
+                helpers.callback(this.options.afterCalculateTickRotation, [this]);
+            },
 
-						me.labelRotation++;
-						labelWidth = cosRotation * originalLabelWidth;
-					}
-				}
-			}
+            //
 
-			if (me.margins) {
-				me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
-				me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
-			}
-		},
-		afterCalculateTickRotation: function() {
-			helpers.callCallback(this.options.afterCalculateTickRotation, [this]);
-		},
+            beforeFit: function() {
+                helpers.callback(this.options.beforeFit, [this]);
+            },
+            fit: function() {
+                var me = this;
+                // Reset
+                var minSize = me.minSize = {
+                    width: 0,
+                    height: 0
+                };
 
-		//
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+                var scaleLabelOpts = opts.scaleLabel;
+                var gridLineOpts = opts.gridLines;
+                var display = opts.display;
+                var isHorizontal = me.isHorizontal();
 
-		beforeFit: function() {
-			helpers.callCallback(this.options.beforeFit, [this]);
-		},
-		fit: function() {
-			var me = this;
-			// Reset
-			var minSize = me.minSize = {
-				width: 0,
-				height: 0
-			};
+                var tickFont = parseFontOptions(tickOpts);
+                var scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;
+                var tickMarkLength = opts.gridLines.tickMarkLength;
 
-			var opts = me.options;
-			var globalDefaults = Chart.defaults.global;
-			var tickOpts = opts.ticks;
-			var scaleLabelOpts = opts.scaleLabel;
-			var display = opts.display;
-			var isHorizontal = me.isHorizontal();
+                // Width
+                if (isHorizontal) {
+                    // subtract the margins to line up with the chartArea if we are a full width scale
+                    minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
+                } else {
+                    minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+                }
 
-			var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+                // height
+                if (isHorizontal) {
+                    minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
+                } else {
+                    minSize.height = me.maxHeight; // fill all the height
+                }
 
-			var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize);
+                // Are we showing a title for the scale?
+                if (scaleLabelOpts.display && display) {
+                    if (isHorizontal) {
+                        minSize.height += scaleLabelFontSize;
+                    } else {
+                        minSize.width += scaleLabelFontSize;
+                    }
+                }
 
-			var tickMarkLength = opts.gridLines.tickMarkLength;
+                // Don't bother fitting the ticks if we are not showing them
+                if (tickOpts.display && display) {
+                    var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, me.ticks, me.longestTextCache);
+                    var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);
+                    var lineSpace = tickFont.size * 0.5;
 
-			// Width
-			if (isHorizontal) {
-				// subtract the margins to line up with the chartArea if we are a full width scale
-				minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
-			} else {
-				minSize.width = display ? tickMarkLength : 0;
-			}
+                    if (isHorizontal) {
+                        // A horizontal axis is more constrained by the height.
+                        me.longestLabelWidth = largestTextWidth;
 
-			// height
-			if (isHorizontal) {
-				minSize.height = display ? tickMarkLength : 0;
-			} else {
-				minSize.height = me.maxHeight; // fill all the height
-			}
+                        var angleRadians = helpers.toRadians(me.labelRotation);
+                        var cosRotation = Math.cos(angleRadians);
+                        var sinRotation = Math.sin(angleRadians);
 
-			// Are we showing a title for the scale?
-			if (scaleLabelOpts.display && display) {
-				if (isHorizontal) {
-					minSize.height += (scaleLabelFontSize * 1.5);
-				} else {
-					minSize.width += (scaleLabelFontSize * 1.5);
-				}
-			}
+                        // TODO - improve this calculation
+                        var labelHeight = (sinRotation * largestTextWidth)
+                            + (tickFont.size * tallestLabelHeightInLines)
+                            + (lineSpace * tallestLabelHeightInLines);
 
-			if (tickOpts.display && display) {
-				// Don't bother fitting the ticks if we are not showing them
-				if (!me.longestTextCache) {
-					me.longestTextCache = {};
-				}
+                        minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
+                        me.ctx.font = tickFont.font;
 
-				var largestTextWidth = helpers.longestText(me.ctx, tickLabelFont, me.ticks, me.longestTextCache);
-				var tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);
-				var lineSpace = tickFontSize * 0.5;
+                        var firstTick = me.ticks[0];
+                        var firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);
 
-				if (isHorizontal) {
-					// A horizontal axis is more constrained by the height.
-					me.longestLabelWidth = largestTextWidth;
+                        var lastTick = me.ticks[me.ticks.length - 1];
+                        var lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);
 
-					// TODO - improve this calculation
-					var labelHeight = (Math.sin(helpers.toRadians(me.labelRotation)) * me.longestLabelWidth) + (tickFontSize * tallestLabelHeightInLines) + (lineSpace * tallestLabelHeightInLines);
+                        // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated
+                        // by the font height
+                        if (me.labelRotation !== 0) {
+                            me.paddingLeft = opts.position === 'bottom'? (cosRotation * firstLabelWidth) + 3: (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges
+                            me.paddingRight = opts.position === 'bottom'? (cosRotation * lineSpace) + 3: (cosRotation * lastLabelWidth) + 3;
+                        } else {
+                            me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
+                            me.paddingRight = lastLabelWidth / 2 + 3;
+                        }
+                    } else {
+                        // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
+                        // Account for padding
 
-					minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
-					me.ctx.font = tickLabelFont;
+                        if (tickOpts.mirror) {
+                            largestTextWidth = 0;
+                        } else {
+                            largestTextWidth += me.options.ticks.padding;
+                        }
+                        minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);
+                        me.paddingTop = tickFont.size / 2;
+                        me.paddingBottom = tickFont.size / 2;
+                    }
+                }
 
-					var firstLabelWidth = me.ctx.measureText(me.ticks[0]).width;
-					var lastLabelWidth = me.ctx.measureText(me.ticks[me.ticks.length - 1]).width;
+                me.handleMargins();
 
-					// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated
-					// by the font height
-					var cosRotation = Math.cos(helpers.toRadians(me.labelRotation));
-					var sinRotation = Math.sin(helpers.toRadians(me.labelRotation));
-					me.paddingLeft = me.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
-					me.paddingRight = me.labelRotation !== 0 ? (sinRotation * (tickFontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated
-				} else {
-					// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
-					var maxLabelWidth = me.maxWidth - minSize.width;
+                me.width = minSize.width;
+                me.height = minSize.height;
+            },
 
-					// Account for padding
-					var mirror = tickOpts.mirror;
-					if (!mirror) {
-						largestTextWidth += me.options.ticks.padding;
-					} else {
-						// If mirrored text is on the inside so don't expand
-						largestTextWidth = 0;
-					}
+            /**
+             * Handle margins and padding interactions
+             * @private
+             */
+            handleMargins: function() {
+                var me = this;
+                if (me.margins) {
+                    me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
+                    me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
+                    me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
+                    me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
+                }
+            },
 
-					if (largestTextWidth < maxLabelWidth) {
-						// We don't need all the room
-						minSize.width += largestTextWidth;
-					} else {
-						// Expand to max size
-						minSize.width = me.maxWidth;
-					}
+            afterFit: function() {
+                helpers.callback(this.options.afterFit, [this]);
+            },
 
-					me.paddingTop = tickFontSize / 2;
-					me.paddingBottom = tickFontSize / 2;
-				}
-			}
-
-			if (me.margins) {
-				me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
-				me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
-				me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
-				me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
-			}
+            // Shared Methods
+            isHorizontal: function() {
+                return this.options.position === 'top' || this.options.position === 'bottom';
+            },
+            isFullWidth: function() {
+                return (this.options.fullWidth);
+            },
 
-			me.width = minSize.width;
-			me.height = minSize.height;
+            // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
+            getRightValue: function(rawValue) {
+                // Null and undefined values first
+                if (rawValue === null || typeof(rawValue) === 'undefined') {
+                    return NaN;
+                }
+                // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
+                if (typeof(rawValue) === 'number' && !isFinite(rawValue)) {
+                    return NaN;
+                }
+                // If it is in fact an object, dive in one more level
+                if (typeof(rawValue) === 'object') {
+                    if ((rawValue instanceof Date) || (rawValue.isValid)) {
+                        return rawValue;
+                    }
+                    return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
+                }
 
-		},
-		afterFit: function() {
-			helpers.callCallback(this.options.afterFit, [this]);
-		},
+                // Value is good, return it
+                return rawValue;
+            },
 
-		// Shared Methods
-		isHorizontal: function() {
-			return this.options.position === "top" || this.options.position === "bottom";
-		},
-		isFullWidth: function() {
-			return (this.options.fullWidth);
-		},
+            // Used to get the value to display in the tooltip for the data at the given index
+            // function getLabelForIndex(index, datasetIndex)
+            getLabelForIndex: helpers.noop,
 
-		// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
-		getRightValue: function(rawValue) {
-			// Null and undefined values first
-			if (rawValue === null || typeof(rawValue) === 'undefined') {
-				return NaN;
-			}
-			// isNaN(object) returns true, so make sure NaN is checking for a number
-			if (typeof(rawValue) === 'number' && isNaN(rawValue)) {
-				return NaN;
-			}
-			// If it is in fact an object, dive in one more level
-			if (typeof(rawValue) === "object") {
-				if ((rawValue instanceof Date) || (rawValue.isValid)) {
-					return rawValue;
-				} else {
-					return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
-				}
-			}
+            // Used to get data value locations.  Value can either be an index or a numerical value
+            getPixelForValue: helpers.noop,
 
-			// Value is good, return it
-			return rawValue;
-		},
+            // Used to get the data value from a given pixel. This is the inverse of getPixelForValue
+            getValueForPixel: helpers.noop,
 
-		// Used to get the value to display in the tooltip for the data at the given index
-		// function getLabelForIndex(index, datasetIndex)
-		getLabelForIndex: helpers.noop,
+            // Used for tick location, should
+            getPixelForTick: function(index, includeOffset) {
+                var me = this;
+                if (me.isHorizontal()) {
+                    var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+                    var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
+                    var pixel = (tickWidth * index) + me.paddingLeft;
 
-		// Used to get data value locations.  Value can either be an index or a numerical value
-		getPixelForValue: helpers.noop,
+                    if (includeOffset) {
+                        pixel += tickWidth / 2;
+                    }
 
-		// Used to get the data value from a given pixel. This is the inverse of getPixelForValue
-		getValueForPixel: helpers.noop,
+                    var finalVal = me.left + Math.round(pixel);
+                    finalVal += me.isFullWidth() ? me.margins.left : 0;
+                    return finalVal;
+                }
+                var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
+                return me.top + (index * (innerHeight / (me.ticks.length - 1)));
+            },
 
-		// Used for tick location, should
-		getPixelForTick: function(index, includeOffset) {
-			var me = this;
-			if (me.isHorizontal()) {
-				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-				var tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-				var pixel = (tickWidth * index) + me.paddingLeft;
+            // Utility for getting the pixel location of a percentage of scale
+            getPixelForDecimal: function(decimal /* , includeOffset*/) {
+                var me = this;
+                if (me.isHorizontal()) {
+                    var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
+                    var valueOffset = (innerWidth * decimal) + me.paddingLeft;
 
-				if (includeOffset) {
-					pixel += tickWidth / 2;
-				}
+                    var finalVal = me.left + Math.round(valueOffset);
+                    finalVal += me.isFullWidth() ? me.margins.left : 0;
+                    return finalVal;
+                }
+                return me.top + (decimal * me.height);
+            },
 
-				var finalVal = me.left + Math.round(pixel);
-				finalVal += me.isFullWidth() ? me.margins.left : 0;
-				return finalVal;
-			} else {
-				var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-				return me.top + (index * (innerHeight / (me.ticks.length - 1)));
-			}
-		},
+            getBasePixel: function() {
+                return this.getPixelForValue(this.getBaseValue());
+            },
 
-		// Utility for getting the pixel location of a percentage of scale
-		getPixelForDecimal: function(decimal /*, includeOffset*/ ) {
-			var me = this;
-			if (me.isHorizontal()) {
-				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-				var valueOffset = (innerWidth * decimal) + me.paddingLeft;
+            getBaseValue: function() {
+                var me = this;
+                var min = me.min;
+                var max = me.max;
 
-				var finalVal = me.left + Math.round(valueOffset);
-				finalVal += me.isFullWidth() ? me.margins.left : 0;
-				return finalVal;
-			} else {
-				return me.top + (decimal * me.height);
-			}
-		},
+                return me.beginAtZero ? 0:
+                    min < 0 && max < 0? max :
+                        min > 0 && max > 0? min :
+                            0;
+            },
 
-		getBasePixel: function() {
-			var me = this;
-			var min = me.min;
-			var max = me.max;
+            // Actually draw the scale on the canvas
+            // @param {rectangle} chartArea : the area of the chart to draw full grid lines on
+            draw: function(chartArea) {
+                var me = this;
+                var options = me.options;
+                if (!options.display) {
+                    return;
+                }
 
-			return me.getPixelForValue(
-				me.beginAtZero? 0:
-				min < 0 && max < 0? max :
-				min > 0 && max > 0? min :
-				0);
-		},
+                var context = me.ctx;
+                var globalDefaults = Chart.defaults.global;
+                var optionTicks = options.ticks;
+                var gridLines = options.gridLines;
+                var scaleLabel = options.scaleLabel;
 
-		// Actualy draw the scale on the canvas
-		// @param {rectangle} chartArea : the area of the chart to draw full grid lines on
-		draw: function(chartArea) {
-			var me = this;
-			var options = me.options;
-			if (!options.display) {
-				return;
-			}
+                var isRotated = me.labelRotation !== 0;
+                var skipRatio;
+                var useAutoskipper = optionTicks.autoSkip;
+                var isHorizontal = me.isHorizontal();
 
-			var context = me.ctx;
-			var globalDefaults = Chart.defaults.global;
-			var optionTicks = options.ticks;
-			var gridLines = options.gridLines;
-			var scaleLabel = options.scaleLabel;
+                // figure out the maximum number of gridlines to show
+                var maxTicks;
+                if (optionTicks.maxTicksLimit) {
+                    maxTicks = optionTicks.maxTicksLimit;
+                }
 
-			var isRotated = me.labelRotation !== 0;
-			var skipRatio;
-			var useAutoskipper = optionTicks.autoSkip;
-			var isHorizontal = me.isHorizontal();
+                var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
+                var tickFont = parseFontOptions(optionTicks);
 
-			// figure out the maximum number of gridlines to show
-			var maxTicks;
-			if (optionTicks.maxTicksLimit) {
-				maxTicks = optionTicks.maxTicksLimit;
-			}
+                var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
 
-			var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
-			var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			var tl = gridLines.tickMarkLength;
+                var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
+                var scaleLabelFont = parseFontOptions(scaleLabel);
 
-			var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
-			var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);
-			var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);
-			var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);
-			var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);
+                var labelRotationRadians = helpers.toRadians(me.labelRotation);
+                var cosRotation = Math.cos(labelRotationRadians);
+                var longestRotatedLabel = me.longestLabelWidth * cosRotation;
 
-			var labelRotationRadians = helpers.toRadians(me.labelRotation);
-			var cosRotation = Math.cos(labelRotationRadians);
-			var longestRotatedLabel = me.longestLabelWidth * cosRotation;
+                // Make sure we draw text in the correct color and font
+                context.fillStyle = tickFontColor;
 
-			// Make sure we draw text in the correct color and font
-			context.fillStyle = tickFontColor;
+                var itemsToDraw = [];
 
-			var itemsToDraw = [];
+                if (isHorizontal) {
+                    skipRatio = false;
 
-			if (isHorizontal) {
-				skipRatio = false;
+                    if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {
+                        skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));
+                    }
 
-				// Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation
-				// See #2584
-				if (isRotated) {
-					longestRotatedLabel /= 2;
-				}
+                    // if they defined a max number of optionTicks,
+                    // increase skipRatio until that number is met
+                    if (maxTicks && me.ticks.length > maxTicks) {
+                        while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {
+                            if (!skipRatio) {
+                                skipRatio = 1;
+                            }
+                            skipRatio += 1;
+                        }
+                    }
 
-				if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {
-					skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));
-				}
+                    if (!useAutoskipper) {
+                        skipRatio = false;
+                    }
+                }
 
-				// if they defined a max number of optionTicks,
-				// increase skipRatio until that number is met
-				if (maxTicks && me.ticks.length > maxTicks) {
-					while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {
-						if (!skipRatio) {
-							skipRatio = 1;
-						}
-						skipRatio += 1;
-					}
-				}
 
-				if (!useAutoskipper) {
-					skipRatio = false;
-				}
-			}
+                var xTickStart = options.position === 'right' ? me.left : me.right - tl;
+                var xTickEnd = options.position === 'right' ? me.left + tl : me.right;
+                var yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;
+                var yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;
 
+                helpers.each(me.ticks, function(label, index) {
+                    // If the callback returned a null or undefined value, do not draw this line
+                    if (label === undefined || label === null) {
+                        return;
+                    }
 
-			var xTickStart = options.position === "right" ? me.left : me.right - tl;
-			var xTickEnd = options.position === "right" ? me.left + tl : me.right;
-			var yTickStart = options.position === "bottom" ? me.top : me.bottom - tl;
-			var yTickEnd = options.position === "bottom" ? me.top + tl : me.bottom;
+                    var isLastTick = me.ticks.length === index + 1;
 
-			helpers.each(me.ticks, function(label, index) {
-				// If the callback returned a null or undefined value, do not draw this line
-				if (label === undefined || label === null) {
-					return;
-				}
+                    // Since we always show the last tick,we need may need to hide the last shown one before
+                    var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);
+                    if (shouldSkip && !isLastTick || (label === undefined || label === null)) {
+                        return;
+                    }
 
-				var isLastTick = me.ticks.length === index + 1;
+                    var lineWidth, lineColor, borderDash, borderDashOffset;
+                    if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {
+                        // Draw the first index specially
+                        lineWidth = gridLines.zeroLineWidth;
+                        lineColor = gridLines.zeroLineColor;
+                        borderDash = gridLines.zeroLineBorderDash;
+                        borderDashOffset = gridLines.zeroLineBorderDashOffset;
+                    } else {
+                        lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);
+                        lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);
+                        borderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
+                        borderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
+                    }
 
-				// Since we always show the last tick,we need may need to hide the last shown one before
-				var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);
-				if (shouldSkip && !isLastTick || (label === undefined || label === null)) {
-					return;
-				}
+                    // Common properties
+                    var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
+                    var textAlign = 'middle';
+                    var textBaseline = 'middle';
 
-				var lineWidth, lineColor;
-				if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {
-					// Draw the first index specially
-					lineWidth = gridLines.zeroLineWidth;
-					lineColor = gridLines.zeroLineColor;
-				} else  {
-					lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);
-					lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);
-				}
+                    if (isHorizontal) {
 
-				// Common properties
-				var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
-				var textAlign, textBaseline = 'middle';
+                        if (options.position === 'bottom') {
+                            // bottom
+                            textBaseline = !isRotated? 'top':'middle';
+                            textAlign = !isRotated? 'center': 'right';
+                            labelY = me.top + tl;
+                        } else {
+                            // top
+                            textBaseline = !isRotated? 'bottom':'middle';
+                            textAlign = !isRotated? 'center': 'left';
+                            labelY = me.bottom - tl;
+                        }
 
-				if (isHorizontal) {
-					if (!isRotated) {
-						textBaseline = options.position === 'top' ? 'bottom' : 'top';
-					}
+                        var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines
+                        labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
 
-					textAlign = isRotated ? 'right' : 'center';
+                        tx1 = tx2 = x1 = x2 = xLineValue;
+                        ty1 = yTickStart;
+                        ty2 = yTickEnd;
+                        y1 = chartArea.top;
+                        y2 = chartArea.bottom;
+                    } else {
+                        var isLeft = options.position === 'left';
+                        var tickPadding = optionTicks.padding;
+                        var labelXOffset;
 
-					var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines
-					labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
-					labelY = (isRotated) ? me.top + 12 : options.position === 'top' ? me.bottom - tl : me.top + tl;
+                        if (optionTicks.mirror) {
+                            textAlign = isLeft ? 'left' : 'right';
+                            labelXOffset = tickPadding;
+                        } else {
+                            textAlign = isLeft ? 'right' : 'left';
+                            labelXOffset = tl + tickPadding;
+                        }
 
-					tx1 = tx2 = x1 = x2 = xLineValue;
-					ty1 = yTickStart;
-					ty2 = yTickEnd;
-					y1 = chartArea.top;
-					y2 = chartArea.bottom;
-				} else {
-					if (options.position === 'left') {
-						if (optionTicks.mirror) {
-							labelX = me.right + optionTicks.padding;
-							textAlign = 'left';
-						} else {
-							labelX = me.right - optionTicks.padding;
-							textAlign = 'right';
-						}
-					} else {
-						// right side
-						if (optionTicks.mirror) {
-							labelX = me.left - optionTicks.padding;
-							textAlign = 'right';
-						} else {
-							labelX = me.left + optionTicks.padding;
-							textAlign = 'left';
-						}
-					}
+                        labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;
 
-					var yLineValue = me.getPixelForTick(index); // xvalues for grid lines
-					yLineValue += helpers.aliasPixel(lineWidth);
-					labelY = me.getPixelForTick(index, gridLines.offsetGridLines);
+                        var yLineValue = me.getPixelForTick(index); // xvalues for grid lines
+                        yLineValue += helpers.aliasPixel(lineWidth);
+                        labelY = me.getPixelForTick(index, gridLines.offsetGridLines);
 
-					tx1 = xTickStart;
-					tx2 = xTickEnd;
-					x1 = chartArea.left;
-					x2 = chartArea.right;
-					ty1 = ty2 = y1 = y2 = yLineValue;
-				}
+                        tx1 = xTickStart;
+                        tx2 = xTickEnd;
+                        x1 = chartArea.left;
+                        x2 = chartArea.right;
+                        ty1 = ty2 = y1 = y2 = yLineValue;
+                    }
 
-				itemsToDraw.push({
-					tx1: tx1,
-					ty1: ty1,
-					tx2: tx2,
-					ty2: ty2,
-					x1: x1,
-					y1: y1,
-					x2: x2,
-					y2: y2,
-					labelX: labelX,
-					labelY: labelY,
-					glWidth: lineWidth,
-					glColor: lineColor,
-					rotation: -1 * labelRotationRadians,
-					label: label,
-					textBaseline: textBaseline,
-					textAlign: textAlign
-				});
-			});
+                    itemsToDraw.push({
+                        tx1: tx1,
+                        ty1: ty1,
+                        tx2: tx2,
+                        ty2: ty2,
+                        x1: x1,
+                        y1: y1,
+                        x2: x2,
+                        y2: y2,
+                        labelX: labelX,
+                        labelY: labelY,
+                        glWidth: lineWidth,
+                        glColor: lineColor,
+                        glBorderDash: borderDash,
+                        glBorderDashOffset: borderDashOffset,
+                        rotation: -1 * labelRotationRadians,
+                        label: label,
+                        textBaseline: textBaseline,
+                        textAlign: textAlign
+                    });
+                });
 
-			// Draw all of the tick labels, tick marks, and grid lines at the correct places
-			helpers.each(itemsToDraw, function(itemToDraw) {
-				if (gridLines.display) {
-					context.lineWidth = itemToDraw.glWidth;
-					context.strokeStyle = itemToDraw.glColor;
+                // Draw all of the tick labels, tick marks, and grid lines at the correct places
+                helpers.each(itemsToDraw, function(itemToDraw) {
+                    if (gridLines.display) {
+                        context.save();
+                        context.lineWidth = itemToDraw.glWidth;
+                        context.strokeStyle = itemToDraw.glColor;
+                        if (context.setLineDash) {
+                            context.setLineDash(itemToDraw.glBorderDash);
+                            context.lineDashOffset = itemToDraw.glBorderDashOffset;
+                        }
 
-					context.beginPath();
+                        context.beginPath();
 
-					if (gridLines.drawTicks) {
-						context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
-						context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
-					}
+                        if (gridLines.drawTicks) {
+                            context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
+                            context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
+                        }
 
-					if (gridLines.drawOnChartArea) {
-						context.moveTo(itemToDraw.x1, itemToDraw.y1);
-						context.lineTo(itemToDraw.x2, itemToDraw.y2);
-					}
+                        if (gridLines.drawOnChartArea) {
+                            context.moveTo(itemToDraw.x1, itemToDraw.y1);
+                            context.lineTo(itemToDraw.x2, itemToDraw.y2);
+                        }
 
-					context.stroke();
-				}
+                        context.stroke();
+                        context.restore();
+                    }
 
-				if (optionTicks.display) {
-					context.save();
-					context.translate(itemToDraw.labelX, itemToDraw.labelY);
-					context.rotate(itemToDraw.rotation);
-					context.font = tickLabelFont;
-					context.textBaseline = itemToDraw.textBaseline;
-					context.textAlign = itemToDraw.textAlign;
+                    if (optionTicks.display) {
+                        context.save();
+                        context.translate(itemToDraw.labelX, itemToDraw.labelY);
+                        context.rotate(itemToDraw.rotation);
+                        context.font = tickFont.font;
+                        context.textBaseline = itemToDraw.textBaseline;
+                        context.textAlign = itemToDraw.textAlign;
 
-					var label = itemToDraw.label;
-					if (helpers.isArray(label)) {
-						for (var i = 0, y = 0; i < label.length; ++i) {
-							// We just make sure the multiline element is a string here..
-							context.fillText('' + label[i], 0, y);
-							// apply same lineSpacing as calculated @ L#320
-							y += (tickFontSize * 1.5);
-						}
-					} else {
-						context.fillText(label, 0, 0);
-					}
-					context.restore();
-				}
-			});
+                        var label = itemToDraw.label;
+                        if (helpers.isArray(label)) {
+                            for (var i = 0, y = 0; i < label.length; ++i) {
+                                // We just make sure the multiline element is a string here..
+                                context.fillText('' + label[i], 0, y);
+                                // apply same lineSpacing as calculated @ L#320
+                                y += (tickFont.size * 1.5);
+                            }
+                        } else {
+                            context.fillText(label, 0, 0);
+                        }
+                        context.restore();
+                    }
+                });
 
-			if (scaleLabel.display) {
-				// Draw the scale label
-				var scaleLabelX;
-				var scaleLabelY;
-				var rotation = 0;
+                if (scaleLabel.display) {
+                    // Draw the scale label
+                    var scaleLabelX;
+                    var scaleLabelY;
+                    var rotation = 0;
 
-				if (isHorizontal) {
-					scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
-					scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFontSize / 2) : me.top + (scaleLabelFontSize / 2);
-				} else {
-					var isLeft = options.position === 'left';
-					scaleLabelX = isLeft ? me.left + (scaleLabelFontSize / 2) : me.right - (scaleLabelFontSize / 2);
-					scaleLabelY = me.top + ((me.bottom - me.top) / 2);
-					rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
-				}
+                    if (isHorizontal) {
+                        scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
+                        scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFont.size / 2) : me.top + (scaleLabelFont.size / 2);
+                    } else {
+                        var isLeft = options.position === 'left';
+                        scaleLabelX = isLeft ? me.left + (scaleLabelFont.size / 2) : me.right - (scaleLabelFont.size / 2);
+                        scaleLabelY = me.top + ((me.bottom - me.top) / 2);
+                        rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
+                    }
 
-				context.save();
-				context.translate(scaleLabelX, scaleLabelY);
-				context.rotate(rotation);
-				context.textAlign = 'center';
-				context.textBaseline = 'middle';
-				context.fillStyle = scaleLabelFontColor; // render in correct colour
-				context.font = scaleLabelFont;
-				context.fillText(scaleLabel.labelString, 0, 0);
-				context.restore();
-			}
+                    context.save();
+                    context.translate(scaleLabelX, scaleLabelY);
+                    context.rotate(rotation);
+                    context.textAlign = 'center';
+                    context.textBaseline = 'middle';
+                    context.fillStyle = scaleLabelFontColor; // render in correct colour
+                    context.font = scaleLabelFont.font;
+                    context.fillText(scaleLabel.labelString, 0, 0);
+                    context.restore();
+                }
 
-			if (gridLines.drawBorder) {
-				// Draw the line at the edge of the axis
-				context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);
-				context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);
-				var x1 = me.left,
-					x2 = me.right,
-					y1 = me.top,
-					y2 = me.bottom;
+                if (gridLines.drawBorder) {
+                    // Draw the line at the edge of the axis
+                    context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);
+                    context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);
+                    var x1 = me.left,
+                        x2 = me.right,
+                        y1 = me.top,
+                        y2 = me.bottom;
 
-				var aliasPixel = helpers.aliasPixel(context.lineWidth);
-				if (isHorizontal) {
-					y1 = y2 = options.position === 'top' ? me.bottom : me.top;
-					y1 += aliasPixel;
-					y2 += aliasPixel;
-				} else {
-					x1 = x2 = options.position === 'left' ? me.right : me.left;
-					x1 += aliasPixel;
-					x2 += aliasPixel;
-				}
+                    var aliasPixel = helpers.aliasPixel(context.lineWidth);
+                    if (isHorizontal) {
+                        y1 = y2 = options.position === 'top' ? me.bottom : me.top;
+                        y1 += aliasPixel;
+                        y2 += aliasPixel;
+                    } else {
+                        x1 = x2 = options.position === 'left' ? me.right : me.left;
+                        x1 += aliasPixel;
+                        x2 += aliasPixel;
+                    }
 
-				context.beginPath();
-				context.moveTo(x1, y1);
-				context.lineTo(x2, y2);
-				context.stroke();
-			}
-		}
-	});
-};
+                    context.beginPath();
+                    context.moveTo(x1, y1);
+                    context.lineTo(x2, y2);
+                    context.stroke();
+                }
+            }
+        });
+    };
 
 },{}],32:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.scaleService = {
-		// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
-		// use the new chart options to grab the correct scale
-		constructors: {},
-		// Use a registration function so that we can move to an ES6 map when we no longer need to support
-		// old browsers
+        Chart.scaleService = {
+            // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
+            // use the new chart options to grab the correct scale
+            constructors: {},
+            // Use a registration function so that we can move to an ES6 map when we no longer need to support
+            // old browsers
 
-		// Scale config defaults
-		defaults: {},
-		registerScaleType: function(type, scaleConstructor, defaults) {
-			this.constructors[type] = scaleConstructor;
-			this.defaults[type] = helpers.clone(defaults);
-		},
-		getScaleConstructor: function(type) {
-			return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
-		},
-		getScaleDefaults: function(type) {
-			// Return the scale defaults merged with the global settings so that we always use the latest ones
-			return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};
-		},
-		updateScaleDefaults: function(type, additions) {
-			var defaults = this.defaults;
-			if (defaults.hasOwnProperty(type)) {
-				defaults[type] = helpers.extend(defaults[type], additions);
-			}
-		},
-		addScalesToLayout: function(chartInstance) {
-			// Adds each scale to the chart.boxes array to be sized accordingly
-			helpers.each(chartInstance.scales, function(scale) {
-				Chart.layoutService.addBox(chartInstance, scale);
-			});
-		}
-	};
-};
+            // Scale config defaults
+            defaults: {},
+            registerScaleType: function(type, scaleConstructor, defaults) {
+                this.constructors[type] = scaleConstructor;
+                this.defaults[type] = helpers.clone(defaults);
+            },
+            getScaleConstructor: function(type) {
+                return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
+            },
+            getScaleDefaults: function(type) {
+                // Return the scale defaults merged with the global settings so that we always use the latest ones
+                return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};
+            },
+            updateScaleDefaults: function(type, additions) {
+                var defaults = this.defaults;
+                if (defaults.hasOwnProperty(type)) {
+                    defaults[type] = helpers.extend(defaults[type], additions);
+                }
+            },
+            addScalesToLayout: function(chart) {
+                // Adds each scale to the chart.boxes array to be sized accordingly
+                helpers.each(chart.scales, function(scale) {
+                    // Set ILayoutItem parameters for backwards compatibility
+                    scale.fullWidth = scale.options.fullWidth;
+                    scale.position = scale.options.position;
+                    scale.weight = scale.options.weight;
+                    Chart.layoutService.addBox(chart, scale);
+                });
+            }
+        };
+    };
+
 },{}],33:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.title = {
-		display: false,
-		position: 'top',
-		fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
+        /**
+         * Namespace to hold static tick generation functions
+         * @namespace Chart.Ticks
+         */
+        Chart.Ticks = {
+            /**
+             * Namespace to hold generators for different types of ticks
+             * @namespace Chart.Ticks.generators
+             */
+            generators: {
+                /**
+                 * Interface for the options provided to the numeric tick generator
+                 * @interface INumericTickGenerationOptions
+                 */
+                /**
+                 * The maximum number of ticks to display
+                 * @name INumericTickGenerationOptions#maxTicks
+                 * @type Number
+                 */
+                /**
+                 * The distance between each tick.
+                 * @name INumericTickGenerationOptions#stepSize
+                 * @type Number
+                 * @optional
+                 */
+                /**
+                 * Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum
+                 * @name INumericTickGenerationOptions#min
+                 * @type Number
+                 * @optional
+                 */
+                /**
+                 * The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum
+                 * @name INumericTickGenerationOptions#max
+                 * @type Number
+                 * @optional
+                 */
 
-		fontStyle: 'bold',
-		padding: 10,
+                /**
+                 * Generate a set of linear ticks
+                 * @method Chart.Ticks.generators.linear
+                 * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
+                 * @param dataRange {IRange} the range of the data
+                 * @returns {Array<Number>} array of tick values
+                 */
+                linear: function(generationOptions, dataRange) {
+                    var ticks = [];
+                    // To get a "nice" value for the tick spacing, we will use the appropriately named
+                    // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
+                    // for details.
 
-		// actual title
-		text: ''
-	};
+                    var spacing;
+                    if (generationOptions.stepSize && generationOptions.stepSize > 0) {
+                        spacing = generationOptions.stepSize;
+                    } else {
+                        var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
+                        spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
+                    }
+                    var niceMin = Math.floor(dataRange.min / spacing) * spacing;
+                    var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
 
-	var noop = helpers.noop;
-	Chart.Title = Chart.Element.extend({
+                    // If min, max and stepSize is set and they make an evenly spaced scale use it.
+                    if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
+                        // If very close to our whole number, use it.
+                        if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {
+                            niceMin = generationOptions.min;
+                            niceMax = generationOptions.max;
+                        }
+                    }
 
-		initialize: function(config) {
-			var me = this;
-			helpers.extend(me, config);
-			me.options = helpers.configMerge(Chart.defaults.global.title, config.options);
+                    var numSpaces = (niceMax - niceMin) / spacing;
+                    // If very close to our rounded value, use it.
+                    if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
+                        numSpaces = Math.round(numSpaces);
+                    } else {
+                        numSpaces = Math.ceil(numSpaces);
+                    }
 
-			// Contains hit boxes for each dataset (in dataset order)
-			me.legendHitBoxes = [];
-		},
+                    // Put the values into the ticks array
+                    ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
+                    for (var j = 1; j < numSpaces; ++j) {
+                        ticks.push(niceMin + (j * spacing));
+                    }
+                    ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
 
-		// These methods are ordered by lifecyle. Utilities then follow.
+                    return ticks;
+                },
 
-		beforeUpdate: function () {
-			var chartOpts = this.chart.options;
-			if (chartOpts && chartOpts.title) {
-				this.options = helpers.configMerge(Chart.defaults.global.title, chartOpts.title);
-			}
-		},
-		update: function(maxWidth, maxHeight, margins) {
-			var me = this;
+                /**
+                 * Generate a set of logarithmic ticks
+                 * @method Chart.Ticks.generators.logarithmic
+                 * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
+                 * @param dataRange {IRange} the range of the data
+                 * @returns {Array<Number>} array of tick values
+                 */
+                logarithmic: function(generationOptions, dataRange) {
+                    var ticks = [];
+                    var getValueOrDefault = helpers.getValueOrDefault;
 
-			// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
-			me.beforeUpdate();
+                    // Figure out what the max number of ticks we can support it is based on the size of
+                    // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+                    // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+                    // the graph
+                    var tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
 
-			// Absorb the master measurements
-			me.maxWidth = maxWidth;
-			me.maxHeight = maxHeight;
-			me.margins = margins;
+                    var endExp = Math.floor(helpers.log10(dataRange.max));
+                    var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
+                    var exp;
+                    var significand;
 
-			// Dimensions
-			me.beforeSetDimensions();
-			me.setDimensions();
-			me.afterSetDimensions();
-			// Labels
-			me.beforeBuildLabels();
-			me.buildLabels();
-			me.afterBuildLabels();
+                    if (tickVal === 0) {
+                        exp = Math.floor(helpers.log10(dataRange.minNotZero));
+                        significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
 
-			// Fit
-			me.beforeFit();
-			me.fit();
-			me.afterFit();
-			//
-			me.afterUpdate();
+                        ticks.push(tickVal);
+                        tickVal = significand * Math.pow(10, exp);
+                    } else {
+                        exp = Math.floor(helpers.log10(tickVal));
+                        significand = Math.floor(tickVal / Math.pow(10, exp));
+                    }
 
-			return me.minSize;
+                    do {
+                        ticks.push(tickVal);
 
-		},
-		afterUpdate: noop,
+                        ++significand;
+                        if (significand === 10) {
+                            significand = 1;
+                            ++exp;
+                        }
 
-		//
+                        tickVal = significand * Math.pow(10, exp);
+                    } while (exp < endExp || (exp === endExp && significand < endSignificand));
 
-		beforeSetDimensions: noop,
-		setDimensions: function() {
-			var me = this;
-			// Set the unconstrained dimension before label rotation
-			if (me.isHorizontal()) {
-				// Reset position before calculating rotation
-				me.width = me.maxWidth;
-				me.left = 0;
-				me.right = me.width;
-			} else {
-				me.height = me.maxHeight;
+                    var lastTick = getValueOrDefault(generationOptions.max, tickVal);
+                    ticks.push(lastTick);
 
-				// Reset position before calculating rotation
-				me.top = 0;
-				me.bottom = me.height;
-			}
+                    return ticks;
+                }
+            },
 
-			// Reset padding
-			me.paddingLeft = 0;
-			me.paddingTop = 0;
-			me.paddingRight = 0;
-			me.paddingBottom = 0;
+            /**
+             * Namespace to hold formatters for different types of ticks
+             * @namespace Chart.Ticks.formatters
+             */
+            formatters: {
+                /**
+                 * Formatter for value labels
+                 * @method Chart.Ticks.formatters.values
+                 * @param value the value to display
+                 * @return {String|Array} the label to display
+                 */
+                values: function(value) {
+                    return helpers.isArray(value) ? value : '' + value;
+                },
 
-			// Reset minSize
-			me.minSize = {
-				width: 0,
-				height: 0
-			};
-		},
-		afterSetDimensions: noop,
+                /**
+                 * Formatter for linear numeric ticks
+                 * @method Chart.Ticks.formatters.linear
+                 * @param tickValue {Number} the value to be formatted
+                 * @param index {Number} the position of the tickValue parameter in the ticks array
+                 * @param ticks {Array<Number>} the list of ticks being converted
+                 * @return {String} string representation of the tickValue parameter
+                 */
+                linear: function(tickValue, index, ticks) {
+                    // If we have lots of ticks, don't use the ones
+                    var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
 
-		//
+                    // If we have a number like 2.5 as the delta, figure out how many decimal places we need
+                    if (Math.abs(delta) > 1) {
+                        if (tickValue !== Math.floor(tickValue)) {
+                            // not an integer
+                            delta = tickValue - Math.floor(tickValue);
+                        }
+                    }
 
-		beforeBuildLabels: noop,
-		buildLabels: noop,
-		afterBuildLabels: noop,
+                    var logDelta = helpers.log10(Math.abs(delta));
+                    var tickString = '';
 
-		//
+                    if (tickValue !== 0) {
+                        var numDecimal = -1 * Math.floor(logDelta);
+                        numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
+                        tickString = tickValue.toFixed(numDecimal);
+                    } else {
+                        tickString = '0'; // never show decimal places for 0
+                    }
 
-		beforeFit: noop,
-		fit: function() {
-			var me = this,
-				valueOrDefault = helpers.getValueOrDefault,
-				opts = me.options,
-				globalDefaults = Chart.defaults.global,
-				display = opts.display,
-				fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
-				minSize = me.minSize;
+                    return tickString;
+                },
 
-			if (me.isHorizontal()) {
-				minSize.width = me.maxWidth; // fill all the width
-				minSize.height = display ? fontSize + (opts.padding * 2) : 0;
-			} else {
-				minSize.width = display ? fontSize + (opts.padding * 2) : 0;
-				minSize.height = me.maxHeight; // fill all the height
-			}
+                logarithmic: function(tickValue, index, ticks) {
+                    var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
 
-			me.width = minSize.width;
-			me.height = minSize.height;
-
-		},
-		afterFit: noop,
-
-		// Shared Methods
-		isHorizontal: function() {
-			var pos = this.options.position;
-			return pos === "top" || pos === "bottom";
-		},
-
-		// Actualy draw the title block on the canvas
-		draw: function() {
-			var me = this,
-				ctx = me.ctx,
-				valueOrDefault = helpers.getValueOrDefault,
-				opts = me.options,
-				globalDefaults = Chart.defaults.global;
-
-			if (opts.display) {
-				var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
-					fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),
-					fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),
-					titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),
-					rotation = 0,
-					titleX,
-					titleY,
-					top = me.top,
-					left = me.left,
-					bottom = me.bottom,
-					right = me.right;
-
-				ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
-				ctx.font = titleFont;
-
-				// Horizontal
-				if (me.isHorizontal()) {
-					titleX = left + ((right - left) / 2); // midpoint of the width
-					titleY = top + ((bottom - top) / 2); // midpoint of the height
-				} else {
-					titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);
-					titleY = top + ((bottom - top) / 2);
-					rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
-				}
-
-				ctx.save();
-				ctx.translate(titleX, titleY);
-				ctx.rotate(rotation);
-				ctx.textAlign = 'center';
-				ctx.textBaseline = 'middle';
-				ctx.fillText(opts.text, 0, 0);
-				ctx.restore();
-			}
-		}
-	});
-
-	// Register the title plugin
-	Chart.plugins.register({
-		beforeInit: function(chartInstance) {
-			var opts = chartInstance.options;
-			var titleOpts = opts.title;
-
-			if (titleOpts) {
-				chartInstance.titleBlock = new Chart.Title({
-					ctx: chartInstance.chart.ctx,
-					options: titleOpts,
-					chart: chartInstance
-				});
-
-				Chart.layoutService.addBox(chartInstance, chartInstance.titleBlock);
-			}
-		}
-	});
-};
+                    if (tickValue === 0) {
+                        return '0';
+                    } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
+                        return tickValue.toExponential();
+                    }
+                    return '';
+                }
+            }
+        };
+    };
 
 },{}],34:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
 
-	Chart.defaults.global.tooltips = {
-		enabled: true,
-		custom: null,
-		mode: 'single',
-		backgroundColor: "rgba(0,0,0,0.8)",
-		titleFontStyle: "bold",
-		titleSpacing: 2,
-		titleMarginBottom: 6,
-		titleFontColor: "#fff",
-		titleAlign: "left",
-		bodySpacing: 2,
-		bodyFontColor: "#fff",
-		bodyAlign: "left",
-		footerFontStyle: "bold",
-		footerSpacing: 2,
-		footerMarginTop: 6,
-		footerFontColor: "#fff",
-		footerAlign: "left",
-		yPadding: 6,
-		xPadding: 6,
-		yAlign : 'center',
-		xAlign : 'center',
-		caretSize: 5,
-		cornerRadius: 6,
-		multiKeyBackground: '#fff',
-		callbacks: {
-			// Args are: (tooltipItems, data)
-			beforeTitle: helpers.noop,
-			title: function(tooltipItems, data) {
-				// Pick first xLabel for now
-				var title = '';
-				var labels = data.labels;
-				var labelCount = labels ? labels.length : 0;
+        /**
+         * Helper method to merge the opacity into a color
+         */
+        function mergeOpacity(colorString, opacity) {
+            var color = helpers.color(colorString);
+            return color.alpha(opacity * color.alpha()).rgbaString();
+        }
 
-				if (tooltipItems.length > 0) {
-					var item = tooltipItems[0];
+        Chart.defaults.global.tooltips = {
+            enabled: true,
+            custom: null,
+            mode: 'nearest',
+            position: 'average',
+            intersect: true,
+            backgroundColor: 'rgba(0,0,0,0.8)',
+            titleFontStyle: 'bold',
+            titleSpacing: 2,
+            titleMarginBottom: 6,
+            titleFontColor: '#fff',
+            titleAlign: 'left',
+            bodySpacing: 2,
+            bodyFontColor: '#fff',
+            bodyAlign: 'left',
+            footerFontStyle: 'bold',
+            footerSpacing: 2,
+            footerMarginTop: 6,
+            footerFontColor: '#fff',
+            footerAlign: 'left',
+            yPadding: 6,
+            xPadding: 6,
+            caretPadding: 2,
+            caretSize: 5,
+            cornerRadius: 6,
+            multiKeyBackground: '#fff',
+            displayColors: true,
+            borderColor: 'rgba(0,0,0,0)',
+            borderWidth: 0,
+            callbacks: {
+                // Args are: (tooltipItems, data)
+                beforeTitle: helpers.noop,
+                title: function(tooltipItems, data) {
+                    // Pick first xLabel for now
+                    var title = '';
+                    var labels = data.labels;
+                    var labelCount = labels ? labels.length : 0;
 
-					if (item.xLabel) {
-						title = item.xLabel;
-					} else if (labelCount > 0 && item.index < labelCount) {
-						title = labels[item.index];
-					}
-				}
+                    if (tooltipItems.length > 0) {
+                        var item = tooltipItems[0];
 
-				return title;
-			},
-			afterTitle: helpers.noop,
+                        if (item.xLabel) {
+                            title = item.xLabel;
+                        } else if (labelCount > 0 && item.index < labelCount) {
+                            title = labels[item.index];
+                        }
+                    }
 
-			// Args are: (tooltipItems, data)
-			beforeBody: helpers.noop,
+                    return title;
+                },
+                afterTitle: helpers.noop,
 
-			// Args are: (tooltipItem, data)
-			beforeLabel: helpers.noop,
-			label: function(tooltipItem, data) {
-				var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
-				return datasetLabel + ': ' + tooltipItem.yLabel;
-			},
-			labelColor: function(tooltipItem, chartInstance) {
-				var meta = chartInstance.getDatasetMeta(tooltipItem.datasetIndex);
-				var activeElement = meta.data[tooltipItem.index];
-				var view = activeElement._view;
-				return {
-					borderColor: view.borderColor,
-					backgroundColor: view.backgroundColor
-				};
-			},
-			afterLabel: helpers.noop,
+                // Args are: (tooltipItems, data)
+                beforeBody: helpers.noop,
 
-			// Args are: (tooltipItems, data)
-			afterBody: helpers.noop,
+                // Args are: (tooltipItem, data)
+                beforeLabel: helpers.noop,
+                label: function(tooltipItem, data) {
+                    var label = data.datasets[tooltipItem.datasetIndex].label || '';
 
-			// Args are: (tooltipItems, data)
-			beforeFooter: helpers.noop,
-			footer: helpers.noop,
-			afterFooter: helpers.noop
-		}
-	};
+                    if (label) {
+                        label += ': ';
+                    }
+                    label += tooltipItem.yLabel;
+                    return label;
+                },
+                labelColor: function(tooltipItem, chart) {
+                    var meta = chart.getDatasetMeta(tooltipItem.datasetIndex);
+                    var activeElement = meta.data[tooltipItem.index];
+                    var view = activeElement._view;
+                    return {
+                        borderColor: view.borderColor,
+                        backgroundColor: view.backgroundColor
+                    };
+                },
+                afterLabel: helpers.noop,
 
-	// Helper to push or concat based on if the 2nd parameter is an array or not
-	function pushOrConcat(base, toPush) {
-		if (toPush) {
-			if (helpers.isArray(toPush)) {
-				//base = base.concat(toPush);
-				Array.prototype.push.apply(base, toPush);
-			} else {
-				base.push(toPush);
-			}
-		}
+                // Args are: (tooltipItems, data)
+                afterBody: helpers.noop,
 
-		return base;
-	}
+                // Args are: (tooltipItems, data)
+                beforeFooter: helpers.noop,
+                footer: helpers.noop,
+                afterFooter: helpers.noop
+            }
+        };
 
-	function getAveragePosition(elements) {
-		if (!elements.length) {
-			return false;
-		}
+        // Helper to push or concat based on if the 2nd parameter is an array or not
+        function pushOrConcat(base, toPush) {
+            if (toPush) {
+                if (helpers.isArray(toPush)) {
+                    // base = base.concat(toPush);
+                    Array.prototype.push.apply(base, toPush);
+                } else {
+                    base.push(toPush);
+                }
+            }
 
-		var i, len;
-		var xPositions = [];
-		var yPositions = [];
+            return base;
+        }
 
-		for (i = 0, len = elements.length; i < len; ++i) {
-			var el = elements[i];
-			if (el && el.hasValue()){
-				var pos = el.tooltipPosition();
-				xPositions.push(pos.x);
-				yPositions.push(pos.y);
-			}
-		}
+        // Private helper to create a tooltip item model
+        // @param element : the chart element (point, arc, bar) to create the tooltip item for
+        // @return : new tooltip item
+        function createTooltipItem(element) {
+            var xScale = element._xScale;
+            var yScale = element._yScale || element._scale; // handle radar || polarArea charts
+            var index = element._index,
+                datasetIndex = element._datasetIndex;
 
-		var x = 0,
-			y = 0;
-		for (i = 0; i < xPositions.length; ++i) {
-			if (xPositions[ i ]) {
-				x += xPositions[i];
-				y += yPositions[i];
-			}
-		}
+            return {
+                xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
+                yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
+                index: index,
+                datasetIndex: datasetIndex,
+                x: element._model.x,
+                y: element._model.y
+            };
+        }
 
-		return {
-			x: Math.round(x / xPositions.length),
-			y: Math.round(y / xPositions.length)
-		};
-	}
+        /**
+         * Helper to get the reset model for the tooltip
+         * @param tooltipOpts {Object} the tooltip options
+         */
+        function getBaseModel(tooltipOpts) {
+            var globalDefaults = Chart.defaults.global;
+            var getValueOrDefault = helpers.getValueOrDefault;
 
-	// Private helper to create a tooltip iteam model
-	// @param element : the chart element (point, arc, bar) to create the tooltip item for
-	// @return : new tooltip item
-	function createTooltipItem(element) {
-		var xScale = element._xScale;
-		var yScale = element._yScale || element._scale; // handle radar || polarArea charts
-		var index = element._index,
-			datasetIndex = element._datasetIndex;
+            return {
+                // Positioning
+                xPadding: tooltipOpts.xPadding,
+                yPadding: tooltipOpts.yPadding,
+                xAlign: tooltipOpts.xAlign,
+                yAlign: tooltipOpts.yAlign,
 
-		return {
-			xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
-			yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
-			index: index,
-			datasetIndex: datasetIndex
-		};
-	}
+                // Body
+                bodyFontColor: tooltipOpts.bodyFontColor,
+                _bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
+                _bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
+                _bodyAlign: tooltipOpts.bodyAlign,
+                bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
+                bodySpacing: tooltipOpts.bodySpacing,
 
-	Chart.Tooltip = Chart.Element.extend({
-		initialize: function() {
-			var me = this;
-			var globalDefaults = Chart.defaults.global;
-			var tooltipOpts = me._options;
-			var getValueOrDefault = helpers.getValueOrDefault;
+                // Title
+                titleFontColor: tooltipOpts.titleFontColor,
+                _titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
+                _titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
+                titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
+                _titleAlign: tooltipOpts.titleAlign,
+                titleSpacing: tooltipOpts.titleSpacing,
+                titleMarginBottom: tooltipOpts.titleMarginBottom,
 
-			helpers.extend(me, {
-				_model: {
-					// Positioning
-					xPadding: tooltipOpts.xPadding,
-					yPadding: tooltipOpts.yPadding,
-					xAlign : tooltipOpts.xAlign,
-					yAlign : tooltipOpts.yAlign,
+                // Footer
+                footerFontColor: tooltipOpts.footerFontColor,
+                _footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
+                _footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
+                footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
+                _footerAlign: tooltipOpts.footerAlign,
+                footerSpacing: tooltipOpts.footerSpacing,
+                footerMarginTop: tooltipOpts.footerMarginTop,
 
-					// Body
-					bodyFontColor: tooltipOpts.bodyFontColor,
-					_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
-					_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
-					_bodyAlign: tooltipOpts.bodyAlign,
-					bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
-					bodySpacing: tooltipOpts.bodySpacing,
+                // Appearance
+                caretSize: tooltipOpts.caretSize,
+                cornerRadius: tooltipOpts.cornerRadius,
+                backgroundColor: tooltipOpts.backgroundColor,
+                opacity: 0,
+                legendColorBackground: tooltipOpts.multiKeyBackground,
+                displayColors: tooltipOpts.displayColors,
+                borderColor: tooltipOpts.borderColor,
+                borderWidth: tooltipOpts.borderWidth
+            };
+        }
 
-					// Title
-					titleFontColor: tooltipOpts.titleFontColor,
-					_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
-					_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
-					titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
-					_titleAlign: tooltipOpts.titleAlign,
-					titleSpacing: tooltipOpts.titleSpacing,
-					titleMarginBottom: tooltipOpts.titleMarginBottom,
+        /**
+         * Get the size of the tooltip
+         */
+        function getTooltipSize(tooltip, model) {
+            var ctx = tooltip._chart.ctx;
 
-					// Footer
-					footerFontColor: tooltipOpts.footerFontColor,
-					_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
-					_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
-					footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
-					_footerAlign: tooltipOpts.footerAlign,
-					footerSpacing: tooltipOpts.footerSpacing,
-					footerMarginTop: tooltipOpts.footerMarginTop,
+            var height = model.yPadding * 2; // Tooltip Padding
+            var width = 0;
 
-					// Appearance
-					caretSize: tooltipOpts.caretSize,
-					cornerRadius: tooltipOpts.cornerRadius,
-					backgroundColor: tooltipOpts.backgroundColor,
-					opacity: 0,
-					legendColorBackground: tooltipOpts.multiKeyBackground
-				}
-			});
-		},
+            // Count of all lines in the body
+            var body = model.body;
+            var combinedBodyLength = body.reduce(function(count, bodyItem) {
+                return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
+            }, 0);
+            combinedBodyLength += model.beforeBody.length + model.afterBody.length;
 
-		// Get the title
-		// Args are: (tooltipItem, data)
-		getTitle: function() {
-			var me = this;
-			var opts = me._options;
-			var callbacks = opts.callbacks;
+            var titleLineCount = model.title.length;
+            var footerLineCount = model.footer.length;
+            var titleFontSize = model.titleFontSize,
+                bodyFontSize = model.bodyFontSize,
+                footerFontSize = model.footerFontSize;
 
-			var beforeTitle = callbacks.beforeTitle.apply(me, arguments),
-				title = callbacks.title.apply(me, arguments),
-				afterTitle = callbacks.afterTitle.apply(me, arguments);
+            height += titleLineCount * titleFontSize; // Title Lines
+            height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
+            height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
+            height += combinedBodyLength * bodyFontSize; // Body Lines
+            height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
+            height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
+            height += footerLineCount * (footerFontSize); // Footer Lines
+            height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
 
-			var lines = [];
-			lines = pushOrConcat(lines, beforeTitle);
-			lines = pushOrConcat(lines, title);
-			lines = pushOrConcat(lines, afterTitle);
+            // Title width
+            var widthPadding = 0;
+            var maxLineWidth = function(line) {
+                width = Math.max(width, ctx.measureText(line).width + widthPadding);
+            };
 
-			return lines;
-		},
+            ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
+            helpers.each(model.title, maxLineWidth);
 
-		// Args are: (tooltipItem, data)
-		getBeforeBody: function() {
-			var lines = this._options.callbacks.beforeBody.apply(this, arguments);
-			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-		},
+            // Body width
+            ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
+            helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
 
-		// Args are: (tooltipItem, data)
-		getBody: function(tooltipItems, data) {
-			var me = this;
-			var callbacks = me._options.callbacks;
-			var bodyItems = [];
+            // Body lines may include some extra width due to the color box
+            widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
+            helpers.each(body, function(bodyItem) {
+                helpers.each(bodyItem.before, maxLineWidth);
+                helpers.each(bodyItem.lines, maxLineWidth);
+                helpers.each(bodyItem.after, maxLineWidth);
+            });
 
-			helpers.each(tooltipItems, function(tooltipItem) {
-				var bodyItem = {
-					before: [],
-					lines: [],
-					after: []
-				};
-				pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
-				pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
-				pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
+            // Reset back to 0
+            widthPadding = 0;
 
-				bodyItems.push(bodyItem);
-			});
+            // Footer width
+            ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
+            helpers.each(model.footer, maxLineWidth);
 
-			return bodyItems;
-		},
+            // Add padding
+            width += 2 * model.xPadding;
 
-		// Args are: (tooltipItem, data)
-		getAfterBody: function() {
-			var lines = this._options.callbacks.afterBody.apply(this, arguments);
-			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
-		},
+            return {
+                width: width,
+                height: height
+            };
+        }
 
-		// Get the footer and beforeFooter and afterFooter lines
-		// Args are: (tooltipItem, data)
-		getFooter: function() {
-			var me = this;
-			var callbacks = me._options.callbacks;
+        /**
+         * Helper to get the alignment of a tooltip given the size
+         */
+        function determineAlignment(tooltip, size) {
+            var model = tooltip._model;
+            var chart = tooltip._chart;
+            var chartArea = tooltip._chart.chartArea;
+            var xAlign = 'center';
+            var yAlign = 'center';
 
-			var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
-			var footer = callbacks.footer.apply(me, arguments);
-			var afterFooter = callbacks.afterFooter.apply(me, arguments);
+            if (model.y < size.height) {
+                yAlign = 'top';
+            } else if (model.y > (chart.height - size.height)) {
+                yAlign = 'bottom';
+            }
 
-			var lines = [];
-			lines = pushOrConcat(lines, beforeFooter);
-			lines = pushOrConcat(lines, footer);
-			lines = pushOrConcat(lines, afterFooter);
+            var lf, rf; // functions to determine left, right alignment
+            var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
+            var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
+            var midX = (chartArea.left + chartArea.right) / 2;
+            var midY = (chartArea.top + chartArea.bottom) / 2;
 
-			return lines;
-		},
+            if (yAlign === 'center') {
+                lf = function(x) {
+                    return x <= midX;
+                };
+                rf = function(x) {
+                    return x > midX;
+                };
+            } else {
+                lf = function(x) {
+                    return x <= (size.width / 2);
+                };
+                rf = function(x) {
+                    return x >= (chart.width - (size.width / 2));
+                };
+            }
 
-		update: function(changed) {
-			var me = this;
-			var opts = me._options;
-			var model = me._model;
-			var active = me._active;
+            olf = function(x) {
+                return x + size.width > chart.width;
+            };
+            orf = function(x) {
+                return x - size.width < 0;
+            };
+            yf = function(y) {
+                return y <= midY ? 'top' : 'bottom';
+            };
 
-			var data = me._data;
-			var chartInstance = me._chartInstance;
+            if (lf(model.x)) {
+                xAlign = 'left';
 
-			var i, len;
+                // Is tooltip too wide and goes over the right side of the chart.?
+                if (olf(model.x)) {
+                    xAlign = 'center';
+                    yAlign = yf(model.y);
+                }
+            } else if (rf(model.x)) {
+                xAlign = 'right';
 
-			if (active.length) {
-				model.opacity = 1;
+                // Is tooltip too wide and goes outside left edge of canvas?
+                if (orf(model.x)) {
+                    xAlign = 'center';
+                    yAlign = yf(model.y);
+                }
+            }
 
-				var labelColors = [],
-					tooltipPosition = getAveragePosition(active);
+            var opts = tooltip._options;
+            return {
+                xAlign: opts.xAlign ? opts.xAlign : xAlign,
+                yAlign: opts.yAlign ? opts.yAlign : yAlign
+            };
+        }
 
-				var tooltipItems = [];
-				for (i = 0, len = active.length; i < len; ++i) {
-					tooltipItems.push(createTooltipItem(active[i]));
-				}
+        /**
+         * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
+         */
+        function getBackgroundPoint(vm, size, alignment) {
+            // Background Position
+            var x = vm.x;
+            var y = vm.y;
+
+            var caretSize = vm.caretSize,
+                caretPadding = vm.caretPadding,
+                cornerRadius = vm.cornerRadius,
+                xAlign = alignment.xAlign,
+                yAlign = alignment.yAlign,
+                paddingAndSize = caretSize + caretPadding,
+                radiusAndPadding = cornerRadius + caretPadding;
+
+            if (xAlign === 'right') {
+                x -= size.width;
+            } else if (xAlign === 'center') {
+                x -= (size.width / 2);
+            }
+
+            if (yAlign === 'top') {
+                y += paddingAndSize;
+            } else if (yAlign === 'bottom') {
+                y -= size.height + paddingAndSize;
+            } else {
+                y -= (size.height / 2);
+            }
+
+            if (yAlign === 'center') {
+                if (xAlign === 'left') {
+                    x += paddingAndSize;
+                } else if (xAlign === 'right') {
+                    x -= paddingAndSize;
+                }
+            } else if (xAlign === 'left') {
+                x -= radiusAndPadding;
+            } else if (xAlign === 'right') {
+                x += radiusAndPadding;
+            }
+
+            return {
+                x: x,
+                y: y
+            };
+        }
+
+        Chart.Tooltip = Chart.Element.extend({
+            initialize: function() {
+                this._model = getBaseModel(this._options);
+            },
+
+            // Get the title
+            // Args are: (tooltipItem, data)
+            getTitle: function() {
+                var me = this;
+                var opts = me._options;
+                var callbacks = opts.callbacks;
+
+                var beforeTitle = callbacks.beforeTitle.apply(me, arguments),
+                    title = callbacks.title.apply(me, arguments),
+                    afterTitle = callbacks.afterTitle.apply(me, arguments);
+
+                var lines = [];
+                lines = pushOrConcat(lines, beforeTitle);
+                lines = pushOrConcat(lines, title);
+                lines = pushOrConcat(lines, afterTitle);
+
+                return lines;
+            },
+
+            // Args are: (tooltipItem, data)
+            getBeforeBody: function() {
+                var lines = this._options.callbacks.beforeBody.apply(this, arguments);
+                return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+            },
+
+            // Args are: (tooltipItem, data)
+            getBody: function(tooltipItems, data) {
+                var me = this;
+                var callbacks = me._options.callbacks;
+                var bodyItems = [];
+
+                helpers.each(tooltipItems, function(tooltipItem) {
+                    var bodyItem = {
+                        before: [],
+                        lines: [],
+                        after: []
+                    };
+                    pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
+                    pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
+                    pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
+
+                    bodyItems.push(bodyItem);
+                });
+
+                return bodyItems;
+            },
+
+            // Args are: (tooltipItem, data)
+            getAfterBody: function() {
+                var lines = this._options.callbacks.afterBody.apply(this, arguments);
+                return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
+            },
+
+            // Get the footer and beforeFooter and afterFooter lines
+            // Args are: (tooltipItem, data)
+            getFooter: function() {
+                var me = this;
+                var callbacks = me._options.callbacks;
+
+                var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
+                var footer = callbacks.footer.apply(me, arguments);
+                var afterFooter = callbacks.afterFooter.apply(me, arguments);
+
+                var lines = [];
+                lines = pushOrConcat(lines, beforeFooter);
+                lines = pushOrConcat(lines, footer);
+                lines = pushOrConcat(lines, afterFooter);
+
+                return lines;
+            },
+
+            update: function(changed) {
+                var me = this;
+                var opts = me._options;
+
+                // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
+                // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
+                // which breaks any animations.
+                var existingModel = me._model;
+                var model = me._model = getBaseModel(opts);
+                var active = me._active;
+
+                var data = me._data;
+
+                // In the case where active.length === 0 we need to keep these at existing values for good animations
+                var alignment = {
+                    xAlign: existingModel.xAlign,
+                    yAlign: existingModel.yAlign
+                };
+                var backgroundPoint = {
+                    x: existingModel.x,
+                    y: existingModel.y
+                };
+                var tooltipSize = {
+                    width: existingModel.width,
+                    height: existingModel.height
+                };
+                var tooltipPosition = {
+                    x: existingModel.caretX,
+                    y: existingModel.caretY
+                };
+
+                var i, len;
+
+                if (active.length) {
+                    model.opacity = 1;
+
+                    var labelColors = [];
+                    tooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);
+
+                    var tooltipItems = [];
+                    for (i = 0, len = active.length; i < len; ++i) {
+                        tooltipItems.push(createTooltipItem(active[i]));
+                    }
+
+                    // If the user provided a filter function, use it to modify the tooltip items
+                    if (opts.filter) {
+                        tooltipItems = tooltipItems.filter(function(a) {
+                            return opts.filter(a, data);
+                        });
+                    }
+
+                    // If the user provided a sorting function, use it to modify the tooltip items
+                    if (opts.itemSort) {
+                        tooltipItems = tooltipItems.sort(function(a, b) {
+                            return opts.itemSort(a, b, data);
+                        });
+                    }
+
+                    // Determine colors for boxes
+                    helpers.each(tooltipItems, function(tooltipItem) {
+                        labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));
+                    });
+
+                    // Build the Text Lines
+                    model.title = me.getTitle(tooltipItems, data);
+                    model.beforeBody = me.getBeforeBody(tooltipItems, data);
+                    model.body = me.getBody(tooltipItems, data);
+                    model.afterBody = me.getAfterBody(tooltipItems, data);
+                    model.footer = me.getFooter(tooltipItems, data);
 
-				// If the user provided a sorting function, use it to modify the tooltip items
-				if (opts.itemSort) {
-					tooltipItems = tooltipItems.sort(opts.itemSort);
-				}
+                    // Initial positioning and colors
+                    model.x = Math.round(tooltipPosition.x);
+                    model.y = Math.round(tooltipPosition.y);
+                    model.caretPadding = opts.caretPadding;
+                    model.labelColors = labelColors;
 
-				// If there is more than one item, show color items
-				if (active.length > 1) {
-					helpers.each(tooltipItems, function(tooltipItem) {
-						labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));
-					});
-				}
+                    // data points
+                    model.dataPoints = tooltipItems;
 
-				// Build the Text Lines
-				helpers.extend(model, {
-					title: me.getTitle(tooltipItems, data),
-					beforeBody: me.getBeforeBody(tooltipItems, data),
-					body: me.getBody(tooltipItems, data),
-					afterBody: me.getAfterBody(tooltipItems, data),
-					footer: me.getFooter(tooltipItems, data),
-					x: Math.round(tooltipPosition.x),
-					y: Math.round(tooltipPosition.y),
-					caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
-					labelColors: labelColors
-				});
+                    // We need to determine alignment of the tooltip
+                    tooltipSize = getTooltipSize(this, model);
+                    alignment = determineAlignment(this, tooltipSize);
+                    // Final Size and Position
+                    backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);
+                } else {
+                    model.opacity = 0;
+                }
 
-				// We need to determine alignment of
-				var tooltipSize = me.getTooltipSize(model);
-				me.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
+                model.xAlign = alignment.xAlign;
+                model.yAlign = alignment.yAlign;
+                model.x = backgroundPoint.x;
+                model.y = backgroundPoint.y;
+                model.width = tooltipSize.width;
+                model.height = tooltipSize.height;
 
-				helpers.extend(model, me.getBackgroundPoint(model, tooltipSize));
-			} else {
-				me._model.opacity = 0;
-			}
+                // Point where the caret on the tooltip points to
+                model.caretX = tooltipPosition.x;
+                model.caretY = tooltipPosition.y;
 
-			if (changed && opts.custom) {
-				opts.custom.call(me, model);
-			}
+                me._model = model;
 
-			return me;
-		},
-		getTooltipSize: function(vm) {
-			var ctx = this._chart.ctx;
+                if (changed && opts.custom) {
+                    opts.custom.call(me, model);
+                }
 
-			var size = {
-				height: vm.yPadding * 2, // Tooltip Padding
-				width: 0
-			};
+                return me;
+            },
+            drawCaret: function(tooltipPoint, size) {
+                var ctx = this._chart.ctx;
+                var vm = this._view;
+                var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
 
-			// Count of all lines in the body
-			var body = vm.body;
-			var combinedBodyLength = body.reduce(function(count, bodyItem) {
-				return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
-			}, 0);
-			combinedBodyLength += vm.beforeBody.length + vm.afterBody.length;
+                ctx.lineTo(caretPosition.x1, caretPosition.y1);
+                ctx.lineTo(caretPosition.x2, caretPosition.y2);
+                ctx.lineTo(caretPosition.x3, caretPosition.y3);
+            },
+            getCaretPosition: function(tooltipPoint, size, vm) {
+                var x1, x2, x3;
+                var y1, y2, y3;
+                var caretSize = vm.caretSize;
+                var cornerRadius = vm.cornerRadius;
+                var xAlign = vm.xAlign,
+                    yAlign = vm.yAlign;
+                var ptX = tooltipPoint.x,
+                    ptY = tooltipPoint.y;
+                var width = size.width,
+                    height = size.height;
 
-			var titleLineCount = vm.title.length;
-			var footerLineCount = vm.footer.length;
-			var titleFontSize = vm.titleFontSize,
-				bodyFontSize = vm.bodyFontSize,
-				footerFontSize = vm.footerFontSize;
+                if (yAlign === 'center') {
+                    y2 = ptY + (height / 2);
 
-			size.height += titleLineCount * titleFontSize; // Title Lines
-			size.height += (titleLineCount - 1) * vm.titleSpacing; // Title Line Spacing
-			size.height += titleLineCount ? vm.titleMarginBottom : 0; // Title's bottom Margin
-			size.height += combinedBodyLength * bodyFontSize; // Body Lines
-			size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
-			size.height += footerLineCount ? vm.footerMarginTop : 0; // Footer Margin
-			size.height += footerLineCount * (footerFontSize); // Footer Lines
-			size.height += footerLineCount ? (footerLineCount - 1) * vm.footerSpacing : 0; // Footer Line Spacing
+                    if (xAlign === 'left') {
+                        x1 = ptX;
+                        x2 = x1 - caretSize;
+                        x3 = x1;
 
-			// Title width
-			var widthPadding = 0;
-			var maxLineWidth = function(line) {
-				size.width = Math.max(size.width, ctx.measureText(line).width + widthPadding);
-			};
+                        y1 = y2 + caretSize;
+                        y3 = y2 - caretSize;
+                    } else {
+                        x1 = ptX + width;
+                        x2 = x1 + caretSize;
+                        x3 = x1;
 
-			ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
-			helpers.each(vm.title, maxLineWidth);
+                        y1 = y2 - caretSize;
+                        y3 = y2 + caretSize;
+                    }
+                } else {
+                    if (xAlign === 'left') {
+                        x2 = ptX + cornerRadius + (caretSize);
+                        x1 = x2 - caretSize;
+                        x3 = x2 + caretSize;
+                    } else if (xAlign === 'right') {
+                        x2 = ptX + width - cornerRadius - caretSize;
+                        x1 = x2 - caretSize;
+                        x3 = x2 + caretSize;
+                    } else {
+                        x2 = ptX + (width / 2);
+                        x1 = x2 - caretSize;
+                        x3 = x2 + caretSize;
+                    }
+                    if (yAlign === 'top') {
+                        y1 = ptY;
+                        y2 = y1 - caretSize;
+                        y3 = y1;
+                    } else {
+                        y1 = ptY + height;
+                        y2 = y1 + caretSize;
+                        y3 = y1;
+                        // invert drawing order
+                        var tmp = x3;
+                        x3 = x1;
+                        x1 = tmp;
+                    }
+                }
+                return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
+            },
+            drawTitle: function(pt, vm, ctx, opacity) {
+                var title = vm.title;
 
-			// Body width
-			ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
-			helpers.each(vm.beforeBody.concat(vm.afterBody), maxLineWidth);
+                if (title.length) {
+                    ctx.textAlign = vm._titleAlign;
+                    ctx.textBaseline = 'top';
 
-			// Body lines may include some extra width due to the color box
-			widthPadding = body.length > 1 ? (bodyFontSize + 2) : 0;
-			helpers.each(body, function(bodyItem) {
-				helpers.each(bodyItem.before, maxLineWidth);
-				helpers.each(bodyItem.lines, maxLineWidth);
-				helpers.each(bodyItem.after, maxLineWidth);
-			});
+                    var titleFontSize = vm.titleFontSize,
+                        titleSpacing = vm.titleSpacing;
 
-			// Reset back to 0
-			widthPadding = 0;
+                    ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
+                    ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
 
-			// Footer width
-			ctx.font = helpers.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
-			helpers.each(vm.footer, maxLineWidth);
+                    var i, len;
+                    for (i = 0, len = title.length; i < len; ++i) {
+                        ctx.fillText(title[i], pt.x, pt.y);
+                        pt.y += titleFontSize + titleSpacing; // Line Height and spacing
 
-			// Add padding
-			size.width += 2 * vm.xPadding;
+                        if (i + 1 === title.length) {
+                            pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
+                        }
+                    }
+                }
+            },
+            drawBody: function(pt, vm, ctx, opacity) {
+                var bodyFontSize = vm.bodyFontSize;
+                var bodySpacing = vm.bodySpacing;
+                var body = vm.body;
 
-			return size;
-		},
-		determineAlignment: function(size) {
-			var me = this;
-			var model = me._model;
-			var chart = me._chart;
-			var chartArea = me._chartInstance.chartArea;
+                ctx.textAlign = vm._bodyAlign;
+                ctx.textBaseline = 'top';
 
-			if (model.y < size.height) {
-				model.yAlign = 'top';
-			} else if (model.y > (chart.height - size.height)) {
-				model.yAlign = 'bottom';
-			}
+                var textColor = mergeOpacity(vm.bodyFontColor, opacity);
+                ctx.fillStyle = textColor;
+                ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
 
-			var lf, rf; // functions to determine left, right alignment
-			var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
-			var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
-			var midX = (chartArea.left + chartArea.right) / 2;
-			var midY = (chartArea.top + chartArea.bottom) / 2;
+                // Before Body
+                var xLinePadding = 0;
+                var fillLineOfText = function(line) {
+                    ctx.fillText(line, pt.x + xLinePadding, pt.y);
+                    pt.y += bodyFontSize + bodySpacing;
+                };
 
-			if (model.yAlign === 'center') {
-				lf = function(x) {
-					return x <= midX;
-				};
-				rf = function(x) {
-					return x > midX;
-				};
-			} else {
-				lf = function(x) {
-					return x <= (size.width / 2);
-				};
-				rf = function(x) {
-					return x >= (chart.width - (size.width / 2));
-				};
-			}
+                // Before body lines
+                helpers.each(vm.beforeBody, fillLineOfText);
 
-			olf = function(x) {
-				return x + size.width > chart.width;
-			};
-			orf = function(x) {
-				return x - size.width < 0;
-			};
-			yf = function(y) {
-				return y <= midY ? 'top' : 'bottom';
-			};
+                var drawColorBoxes = vm.displayColors;
+                xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
 
-			if (lf(model.x)) {
-				model.xAlign = 'left';
+                // Draw body lines now
+                helpers.each(body, function(bodyItem, i) {
+                    helpers.each(bodyItem.before, fillLineOfText);
 
-				// Is tooltip too wide and goes over the right side of the chart.?
-				if (olf(model.x)) {
-					model.xAlign = 'center';
-					model.yAlign = yf(model.y);
-				}
-			} else if (rf(model.x)) {
-				model.xAlign = 'right';
+                    helpers.each(bodyItem.lines, function(line) {
+                        // Draw Legend-like boxes if needed
+                        if (drawColorBoxes) {
+                            // Fill a white rect so that colours merge nicely if the opacity is < 1
+                            ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
+                            ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
 
-				// Is tooltip too wide and goes outside left edge of canvas?
-				if (orf(model.x)) {
-					model.xAlign = 'center';
-					model.yAlign = yf(model.y);
-				}
-			}
-		},
-		getBackgroundPoint: function(vm, size) {
-			// Background Position
-			var pt = {
-				x: vm.x,
-				y: vm.y
-			};
+                            // Border
+                            ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
+                            ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
 
-			var caretSize = vm.caretSize,
-				caretPadding = vm.caretPadding,
-				cornerRadius = vm.cornerRadius,
-				xAlign = vm.xAlign,
-				yAlign = vm.yAlign,
-				paddingAndSize = caretSize + caretPadding,
-				radiusAndPadding = cornerRadius + caretPadding;
+                            // Inner square
+                            ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
+                            ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
 
-			if (xAlign === 'right') {
-				pt.x -= size.width;
-			} else if (xAlign === 'center') {
-				pt.x -= (size.width / 2);
-			}
+                            ctx.fillStyle = textColor;
+                        }
 
-			if (yAlign === 'top') {
-				pt.y += paddingAndSize;
-			} else if (yAlign === 'bottom') {
-				pt.y -= size.height + paddingAndSize;
-			} else {
-				pt.y -= (size.height / 2);
-			}
+                        fillLineOfText(line);
+                    });
 
-			if (yAlign === 'center') {
-				if (xAlign === 'left') {
-					pt.x += paddingAndSize;
-				} else if (xAlign === 'right') {
-					pt.x -= paddingAndSize;
-				}
-			} else {
-				if (xAlign === 'left') {
-					pt.x -= radiusAndPadding;
-				} else if (xAlign === 'right') {
-					pt.x += radiusAndPadding;
-				}
-			}
+                    helpers.each(bodyItem.after, fillLineOfText);
+                });
 
-			return pt;
-		},
-		drawCaret: function(tooltipPoint, size, opacity) {
-			var vm = this._view;
-			var ctx = this._chart.ctx;
-			var x1, x2, x3;
-			var y1, y2, y3;
-			var caretSize = vm.caretSize;
-			var cornerRadius = vm.cornerRadius;
-			var xAlign = vm.xAlign,
-				yAlign = vm.yAlign;
-			var ptX = tooltipPoint.x,
-				ptY = tooltipPoint.y;
-			var width = size.width,
-				height = size.height;
+                // Reset back to 0 for after body
+                xLinePadding = 0;
 
-			if (yAlign === 'center') {
-				// Left or right side
-				if (xAlign === 'left') {
-					x1 = ptX;
-					x2 = x1 - caretSize;
-					x3 = x1;
-				} else {
-					x1 = ptX + width;
-					x2 = x1 + caretSize;
-					x3 = x1;
-				}
+                // After body lines
+                helpers.each(vm.afterBody, fillLineOfText);
+                pt.y -= bodySpacing; // Remove last body spacing
+            },
+            drawFooter: function(pt, vm, ctx, opacity) {
+                var footer = vm.footer;
 
-				y2 = ptY + (height / 2);
-				y1 = y2 - caretSize;
-				y3 = y2 + caretSize;
-			} else {
-				if (xAlign === 'left') {
-					x1 = ptX + cornerRadius;
-					x2 = x1 + caretSize;
-					x3 = x2 + caretSize;
-				} else if (xAlign === 'right') {
-					x1 = ptX + width - cornerRadius;
-					x2 = x1 - caretSize;
-					x3 = x2 - caretSize;
-				} else {
-					x2 = ptX + (width / 2);
-					x1 = x2 - caretSize;
-					x3 = x2 + caretSize;
-				}
+                if (footer.length) {
+                    pt.y += vm.footerMarginTop;
 
-				if (yAlign === 'top') {
-					y1 = ptY;
-					y2 = y1 - caretSize;
-					y3 = y1;
-				} else {
-					y1 = ptY + height;
-					y2 = y1 + caretSize;
-					y3 = y1;
-				}
-			}
+                    ctx.textAlign = vm._footerAlign;
+                    ctx.textBaseline = 'top';
 
-			var bgColor = helpers.color(vm.backgroundColor);
-			ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
-			ctx.beginPath();
-			ctx.moveTo(x1, y1);
-			ctx.lineTo(x2, y2);
-			ctx.lineTo(x3, y3);
-			ctx.closePath();
-			ctx.fill();
-		},
-		drawTitle: function(pt, vm, ctx, opacity) {
-			var title = vm.title;
+                    ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
+                    ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
 
-			if (title.length) {
-				ctx.textAlign = vm._titleAlign;
-				ctx.textBaseline = "top";
+                    helpers.each(footer, function(line) {
+                        ctx.fillText(line, pt.x, pt.y);
+                        pt.y += vm.footerFontSize + vm.footerSpacing;
+                    });
+                }
+            },
+            drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
+                ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
+                ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
+                ctx.lineWidth = vm.borderWidth;
+                var xAlign = vm.xAlign;
+                var yAlign = vm.yAlign;
+                var x = pt.x;
+                var y = pt.y;
+                var width = tooltipSize.width;
+                var height = tooltipSize.height;
+                var radius = vm.cornerRadius;
 
-				var titleFontSize = vm.titleFontSize,
-					titleSpacing = vm.titleSpacing;
+                ctx.beginPath();
+                ctx.moveTo(x + radius, y);
+                if (yAlign === 'top') {
+                    this.drawCaret(pt, tooltipSize);
+                }
+                ctx.lineTo(x + width - radius, y);
+                ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
+                if (yAlign === 'center' && xAlign === 'right') {
+                    this.drawCaret(pt, tooltipSize);
+                }
+                ctx.lineTo(x + width, y + height - radius);
+                ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+                if (yAlign === 'bottom') {
+                    this.drawCaret(pt, tooltipSize);
+                }
+                ctx.lineTo(x + radius, y + height);
+                ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
+                if (yAlign === 'center' && xAlign === 'left') {
+                    this.drawCaret(pt, tooltipSize);
+                }
+                ctx.lineTo(x, y + radius);
+                ctx.quadraticCurveTo(x, y, x + radius, y);
+                ctx.closePath();
 
-				var titleFontColor = helpers.color(vm.titleFontColor);
-				ctx.fillStyle = titleFontColor.alpha(opacity * titleFontColor.alpha()).rgbString();
-				ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
+                ctx.fill();
 
-				var i, len;
-				for (i = 0, len = title.length; i < len; ++i) {
-					ctx.fillText(title[i], pt.x, pt.y);
-					pt.y += titleFontSize + titleSpacing; // Line Height and spacing
+                if (vm.borderWidth > 0) {
+                    ctx.stroke();
+                }
+            },
+            draw: function() {
+                var ctx = this._chart.ctx;
+                var vm = this._view;
 
-					if (i + 1 === title.length) {
-						pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
-					}
-				}
-			}
-		},
-		drawBody: function(pt, vm, ctx, opacity) {
-			var bodyFontSize = vm.bodyFontSize;
-			var bodySpacing = vm.bodySpacing;
-			var body = vm.body;
+                if (vm.opacity === 0) {
+                    return;
+                }
 
-			ctx.textAlign = vm._bodyAlign;
-			ctx.textBaseline = "top";
+                var tooltipSize = {
+                    width: vm.width,
+                    height: vm.height
+                };
+                var pt = {
+                    x: vm.x,
+                    y: vm.y
+                };
 
-			var bodyFontColor = helpers.color(vm.bodyFontColor);
-			var textColor = bodyFontColor.alpha(opacity * bodyFontColor.alpha()).rgbString();
-			ctx.fillStyle = textColor;
-			ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
+                // IE11/Edge does not like very small opacities, so snap to 0
+                var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
 
-			// Before Body
-			var xLinePadding = 0;
-			var fillLineOfText = function(line) {
-				ctx.fillText(line, pt.x + xLinePadding, pt.y);
-				pt.y += bodyFontSize + bodySpacing;
-			};
+                // Truthy/falsey value for empty tooltip
+                var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
 
-			// Before body lines
-			helpers.each(vm.beforeBody, fillLineOfText);
+                if (this._options.enabled && hasTooltipContent) {
+                    // Draw Background
+                    this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
 
-			var drawColorBoxes = body.length > 1;
-			xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
+                    // Draw Title, Body, and Footer
+                    pt.x += vm.xPadding;
+                    pt.y += vm.yPadding;
 
-			// Draw body lines now
-			helpers.each(body, function(bodyItem, i) {
-				helpers.each(bodyItem.before, fillLineOfText);
+                    // Titles
+                    this.drawTitle(pt, vm, ctx, opacity);
 
-				helpers.each(bodyItem.lines, function(line) {
-					// Draw Legend-like boxes if needed
-					if (drawColorBoxes) {
-						// Fill a white rect so that colours merge nicely if the opacity is < 1
-						ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
-						ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+                    // Body
+                    this.drawBody(pt, vm, ctx, opacity);
 
-						// Border
-						ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
-						ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
+                    // Footer
+                    this.drawFooter(pt, vm, ctx, opacity);
+                }
+            },
 
-						// Inner square
-						ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
-						ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
+            /**
+             * Handle an event
+             * @private
+             * @param {IEvent} event - The event to handle
+             * @returns {Boolean} true if the tooltip changed
+             */
+            handleEvent: function(e) {
+                var me = this;
+                var options = me._options;
+                var changed = false;
 
-						ctx.fillStyle = textColor;
-					}
+                me._lastActive = me._lastActive || [];
 
-					fillLineOfText(line);
-				});
+                // Find Active Elements for tooltips
+                if (e.type === 'mouseout') {
+                    me._active = [];
+                } else {
+                    me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
+                }
 
-				helpers.each(bodyItem.after, fillLineOfText);
-			});
+                // Remember Last Actives
+                changed = !helpers.arrayEquals(me._active, me._lastActive);
 
-			// Reset back to 0 for after body
-			xLinePadding = 0;
+                // If tooltip didn't change, do not handle the target event
+                if (!changed) {
+                    return false;
+                }
 
-			// After body lines
-			helpers.each(vm.afterBody, fillLineOfText);
-			pt.y -= bodySpacing; // Remove last body spacing
-		},
-		drawFooter: function(pt, vm, ctx, opacity) {
-			var footer = vm.footer;
+                me._lastActive = me._active;
 
-			if (footer.length) {
-				pt.y += vm.footerMarginTop;
+                if (options.enabled || options.custom) {
+                    me._eventPosition = {
+                        x: e.x,
+                        y: e.y
+                    };
 
-				ctx.textAlign = vm._footerAlign;
-				ctx.textBaseline = "top";
+                    var model = me._model;
+                    me.update(true);
+                    me.pivot();
 
-				var footerFontColor = helpers.color(vm.footerFontColor);
-				ctx.fillStyle = footerFontColor.alpha(opacity * footerFontColor.alpha()).rgbString();
-				ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
+                    // See if our tooltip position changed
+                    changed |= (model.x !== me._model.x) || (model.y !== me._model.y);
+                }
 
-				helpers.each(footer, function(line) {
-					ctx.fillText(line, pt.x, pt.y);
-					pt.y += vm.footerFontSize + vm.footerSpacing;
-				});
-			}
-		},
-		draw: function() {
-			var ctx = this._chart.ctx;
-			var vm = this._view;
+                return changed;
+            }
+        });
 
-			if (vm.opacity === 0) {
-				return;
-			}
+        /**
+         * @namespace Chart.Tooltip.positioners
+         */
+        Chart.Tooltip.positioners = {
+            /**
+             * Average mode places the tooltip at the average position of the elements shown
+             * @function Chart.Tooltip.positioners.average
+             * @param elements {ChartElement[]} the elements being displayed in the tooltip
+             * @returns {Point} tooltip position
+             */
+            average: function(elements) {
+                if (!elements.length) {
+                    return false;
+                }
 
-			var tooltipSize = this.getTooltipSize(vm);
-			var pt = {
-				x: vm.x,
-				y: vm.y
-			};
+                var i, len;
+                var x = 0;
+                var y = 0;
+                var count = 0;
 
-			// IE11/Edge does not like very small opacities, so snap to 0
-			var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
+                for (i = 0, len = elements.length; i < len; ++i) {
+                    var el = elements[i];
+                    if (el && el.hasValue()) {
+                        var pos = el.tooltipPosition();
+                        x += pos.x;
+                        y += pos.y;
+                        ++count;
+                    }
+                }
 
-			if (this._options.enabled) {
-				// Draw Background
-				var bgColor = helpers.color(vm.backgroundColor);
-				ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
-				helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
-				ctx.fill();
+                return {
+                    x: Math.round(x / count),
+                    y: Math.round(y / count)
+                };
+            },
 
-				// Draw Caret
-				this.drawCaret(pt, tooltipSize, opacity);
+            /**
+             * Gets the tooltip position nearest of the item nearest to the event position
+             * @function Chart.Tooltip.positioners.nearest
+             * @param elements {Chart.Element[]} the tooltip elements
+             * @param eventPosition {Point} the position of the event in canvas coordinates
+             * @returns {Point} the tooltip position
+             */
+            nearest: function(elements, eventPosition) {
+                var x = eventPosition.x;
+                var y = eventPosition.y;
 
-				// Draw Title, Body, and Footer
-				pt.x += vm.xPadding;
-				pt.y += vm.yPadding;
+                var nearestElement;
+                var minDistance = Number.POSITIVE_INFINITY;
+                var i, len;
+                for (i = 0, len = elements.length; i < len; ++i) {
+                    var el = elements[i];
+                    if (el && el.hasValue()) {
+                        var center = el.getCenterPoint();
+                        var d = helpers.distanceBetweenPoints(eventPosition, center);
 
-				// Titles
-				this.drawTitle(pt, vm, ctx, opacity);
+                        if (d < minDistance) {
+                            minDistance = d;
+                            nearestElement = el;
+                        }
+                    }
+                }
 
-				// Body
-				this.drawBody(pt, vm, ctx, opacity);
+                if (nearestElement) {
+                    var tp = nearestElement.tooltipPosition();
+                    x = tp.x;
+                    y = tp.y;
+                }
 
-				// Footer
-				this.drawFooter(pt, vm, ctx, opacity);
-			}
-		}
-	});
-};
+                return {
+                    x: x,
+                    y: y
+                };
+            }
+        };
+    };
 
 },{}],35:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-  var helpers = Chart.helpers,
-    globalOpts = Chart.defaults.global;
+        var helpers = Chart.helpers,
+            globalOpts = Chart.defaults.global;
 
-  globalOpts.elements.arc = {
-    backgroundColor: globalOpts.defaultColor,
-    borderColor: "#fff",
-    borderWidth: 2
-  };
+        globalOpts.elements.arc = {
+            backgroundColor: globalOpts.defaultColor,
+            borderColor: '#fff',
+            borderWidth: 2
+        };
 
-  Chart.elements.Arc = Chart.Element.extend({
-    inLabelRange: function(mouseX) {
-      var vm = this._view;
+        Chart.elements.Arc = Chart.Element.extend({
+            inLabelRange: function(mouseX) {
+                var vm = this._view;
 
-      if (vm) {
-        return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
-      } else {
-        return false;
-      }
-    },
-    inRange: function(chartX, chartY) {
-      var vm = this._view;
+                if (vm) {
+                    return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
+                }
+                return false;
+            },
+            inRange: function(chartX, chartY) {
+                var vm = this._view;
 
-      if (vm) {
-        var pointRelativePosition = helpers.getAngleFromPoint(vm, {
-            x: chartX,
-            y: chartY
-          }),
-          angle = pointRelativePosition.angle,
-          distance = pointRelativePosition.distance;
+                if (vm) {
+                    var pointRelativePosition = helpers.getAngleFromPoint(vm, {
+                            x: chartX,
+                            y: chartY
+                        }),
+                        angle = pointRelativePosition.angle,
+                        distance = pointRelativePosition.distance;
 
-        //Sanitise angle range
-        var startAngle = vm.startAngle;
-        var endAngle = vm.endAngle;
-        while (endAngle < startAngle) {
-          endAngle += 2.0 * Math.PI;
-        }
-        while (angle > endAngle) {
-          angle -= 2.0 * Math.PI;
-        }
-        while (angle < startAngle) {
-          angle += 2.0 * Math.PI;
-        }
+                    // Sanitise angle range
+                    var startAngle = vm.startAngle;
+                    var endAngle = vm.endAngle;
+                    while (endAngle < startAngle) {
+                        endAngle += 2.0 * Math.PI;
+                    }
+                    while (angle > endAngle) {
+                        angle -= 2.0 * Math.PI;
+                    }
+                    while (angle < startAngle) {
+                        angle += 2.0 * Math.PI;
+                    }
 
-        //Check if within the range of the open/close angle
-        var betweenAngles = (angle >= startAngle && angle <= endAngle),
-          withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
+                    // Check if within the range of the open/close angle
+                    var betweenAngles = (angle >= startAngle && angle <= endAngle),
+                        withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
 
-        return (betweenAngles && withinRadius);
-      } else {
-        return false;
-      }
-    },
-    tooltipPosition: function() {
-      var vm = this._view;
+                    return (betweenAngles && withinRadius);
+                }
+                return false;
+            },
+            getCenterPoint: function() {
+                var vm = this._view;
+                var halfAngle = (vm.startAngle + vm.endAngle) / 2;
+                var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
+                return {
+                    x: vm.x + Math.cos(halfAngle) * halfRadius,
+                    y: vm.y + Math.sin(halfAngle) * halfRadius
+                };
+            },
+            getArea: function() {
+                var vm = this._view;
+                return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
+            },
+            tooltipPosition: function() {
+                var vm = this._view;
 
-      var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),
-        rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
-      return {
-        x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
-        y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
-      };
-    },
-    draw: function() {
+                var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),
+                    rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
+                return {
+                    x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
+                    y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
+                };
+            },
+            draw: function() {
 
-      var ctx = this._chart.ctx,
-        vm = this._view,
-        sA = vm.startAngle,
-        eA = vm.endAngle;
+                var ctx = this._chart.ctx,
+                    vm = this._view,
+                    sA = vm.startAngle,
+                    eA = vm.endAngle;
 
-      ctx.beginPath();
+                ctx.beginPath();
 
-      ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
-      ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
+                ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
+                ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
 
-      ctx.closePath();
-      ctx.strokeStyle = vm.borderColor;
-      ctx.lineWidth = vm.borderWidth;
+                ctx.closePath();
+                ctx.strokeStyle = vm.borderColor;
+                ctx.lineWidth = vm.borderWidth;
 
-      ctx.fillStyle = vm.backgroundColor;
+                ctx.fillStyle = vm.backgroundColor;
 
-      ctx.fill();
-      ctx.lineJoin = 'bevel';
+                ctx.fill();
+                ctx.lineJoin = 'bevel';
 
-      if (vm.borderWidth) {
-        ctx.stroke();
-      }
-    }
-  });
-};
+                if (vm.borderWidth) {
+                    ctx.stroke();
+                }
+            }
+        });
+    };
 
 },{}],36:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var globalDefaults = Chart.defaults.global;
+        var helpers = Chart.helpers;
+        var globalDefaults = Chart.defaults.global;
 
-	Chart.defaults.global.elements.line = {
-		tension: 0.4,
-		backgroundColor: globalDefaults.defaultColor,
-		borderWidth: 3,
-		borderColor: globalDefaults.defaultColor,
-		borderCapStyle: 'butt',
-		borderDash: [],
-		borderDashOffset: 0.0,
-		borderJoinStyle: 'miter',
-		capBezierPoints: true,
-		fill: true // do we fill in the area between the line and its base axis
-	};
+        Chart.defaults.global.elements.line = {
+            tension: 0.4,
+            backgroundColor: globalDefaults.defaultColor,
+            borderWidth: 3,
+            borderColor: globalDefaults.defaultColor,
+            borderCapStyle: 'butt',
+            borderDash: [],
+            borderDashOffset: 0.0,
+            borderJoinStyle: 'miter',
+            capBezierPoints: true,
+            fill: true, // do we fill in the area between the line and its base axis
+        };
 
-	Chart.elements.Line = Chart.Element.extend({
-		draw: function() {
-			var me = this;
-			var vm = me._view;
-			var spanGaps = vm.spanGaps;
-			var scaleZero = vm.scaleZero;
-			var loop = me._loop;
+        Chart.elements.Line = Chart.Element.extend({
+            draw: function() {
+                var me = this;
+                var vm = me._view;
+                var ctx = me._chart.ctx;
+                var spanGaps = vm.spanGaps;
+                var points = me._children.slice(); // clone array
+                var globalOptionLineElements = globalDefaults.elements.line;
+                var lastDrawnIndex = -1;
+                var index, current, previous, currentVM;
 
-			var ctx = me._chart.ctx;
-			ctx.save();
+                // If we are looping, adding the first point again
+                if (me._loop && points.length) {
+                    points.push(points[0]);
+                }
 
-			// Helper function to draw a line to a point
-			function lineToPoint(previousPoint, point) {
-				var vm = point._view;
-				if (point._view.steppedLine === true) {
-					ctx.lineTo(point._view.x, previousPoint._view.y);
-					ctx.lineTo(point._view.x, point._view.y);				
-				} else if (point._view.tension === 0) {
-					ctx.lineTo(vm.x, vm.y);
-				} else {
-					ctx.bezierCurveTo(
-						previousPoint._view.controlPointNextX,
-						previousPoint._view.controlPointNextY,
-						vm.controlPointPreviousX,
-						vm.controlPointPreviousY,
-						vm.x,
-						vm.y
-					);
-				}
-			}
+                ctx.save();
 
-			var points = me._children.slice(); // clone array
-			var lastDrawnIndex = -1;
+                // Stroke Line Options
+                ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
 
-			// If we are looping, adding the first point again
-			if (loop && points.length) {
-				points.push(points[0]);
-			}
+                // IE 9 and 10 do not support line dash
+                if (ctx.setLineDash) {
+                    ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
+                }
 
-			var index, current, previous, currentVM;
+                ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
+                ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
+                ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
+                ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
 
-			// Fill Line
-			if (points.length && vm.fill) {
-				ctx.beginPath();
+                // Stroke Line
+                ctx.beginPath();
+                lastDrawnIndex = -1;
 
-				for (index = 0; index < points.length; ++index) {
-					current = points[index];
-					previous = helpers.previousItem(points, index);
-					currentVM = current._view;
+                for (index = 0; index < points.length; ++index) {
+                    current = points[index];
+                    previous = helpers.previousItem(points, index);
+                    currentVM = current._view;
 
-					// First point moves to it's starting position no matter what
-					if (index === 0) {
-						if (loop) {
-							ctx.moveTo(scaleZero.x, scaleZero.y);
-						} else {
-							ctx.moveTo(currentVM.x, scaleZero);
-						}
+                    // First point moves to it's starting position no matter what
+                    if (index === 0) {
+                        if (!currentVM.skip) {
+                            ctx.moveTo(currentVM.x, currentVM.y);
+                            lastDrawnIndex = index;
+                        }
+                    } else {
+                        previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
 
-						if (!currentVM.skip) {
-							lastDrawnIndex = index;
-							ctx.lineTo(currentVM.x, currentVM.y);
-						}
-					} else {
-						previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
+                        if (!currentVM.skip) {
+                            if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
+                                // There was a gap and this is the first point after the gap
+                                ctx.moveTo(currentVM.x, currentVM.y);
+                            } else {
+                                // Line to next point
+                                helpers.canvas.lineTo(ctx, previous._view, current._view);
+                            }
+                            lastDrawnIndex = index;
+                        }
+                    }
+                }
 
-						if (currentVM.skip) {
-							// Only do this if this is the first point that is skipped
-							if (!spanGaps && lastDrawnIndex === (index - 1)) {
-								if (loop) {
-									ctx.lineTo(scaleZero.x, scaleZero.y);
-								} else {
-									ctx.lineTo(previous._view.x, scaleZero);
-								}
-							}
-						} else {
-							if (lastDrawnIndex !== (index - 1)) {
-								// There was a gap and this is the first point after the gap. If we've never drawn a point, this is a special case. 
-								// If the first data point is NaN, then there is no real gap to skip
-								if (spanGaps && lastDrawnIndex !== -1) {
-									// We are spanning the gap, so simple draw a line to this point
-									lineToPoint(previous, current);
-								} else {
-									if (loop) {
-										ctx.lineTo(currentVM.x, currentVM.y);
-									} else {
-										ctx.lineTo(currentVM.x, scaleZero);
-										ctx.lineTo(currentVM.x, currentVM.y);
-									}
-								}
-							} else {
-								// Line to next point
-								lineToPoint(previous, current);
-							}
-							lastDrawnIndex = index;
-						}
-					}
-				}
+                ctx.stroke();
+                ctx.restore();
+            }
+        });
+    };
 
-				if (!loop) {
-					ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
-				}
-
-				ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
-				ctx.closePath();
-				ctx.fill();
-			}
-
-			// Stroke Line Options
-			var globalOptionLineElements = globalDefaults.elements.line;
-			ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
-
-			// IE 9 and 10 do not support line dash
-			if (ctx.setLineDash) {
-				ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
-			}
-
-			ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
-			ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
-			ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
-			ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
-
-			// Stroke Line
-			ctx.beginPath();
-			lastDrawnIndex = -1;
-
-			for (index = 0; index < points.length; ++index) {
-				current = points[index];
-				previous = helpers.previousItem(points, index);
-				currentVM = current._view;
-
-				// First point moves to it's starting position no matter what
-				if (index === 0) {
-					if (currentVM.skip) {
-						
-					} else {
-						ctx.moveTo(currentVM.x, currentVM.y);
-						lastDrawnIndex = index;
-					}
-				} else {
-					previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
-
-					if (!currentVM.skip) {
-						if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
-							// There was a gap and this is the first point after the gap
-							ctx.moveTo(currentVM.x, currentVM.y);
-						} else {
-							// Line to next point
-							lineToPoint(previous, current);
-						}
-						lastDrawnIndex = index;
-					}
-				}
-			}
-
-			ctx.stroke();
-			ctx.restore();
-		}
-	});
-};
 },{}],37:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers,
-		globalOpts = Chart.defaults.global,
-		defaultColor = globalOpts.defaultColor;
+        var helpers = Chart.helpers,
+            globalOpts = Chart.defaults.global,
+            defaultColor = globalOpts.defaultColor;
 
-	globalOpts.elements.point = {
-		radius: 3,
-		pointStyle: 'circle',
-		backgroundColor: defaultColor,
-		borderWidth: 1,
-		borderColor: defaultColor,
-		// Hover
-		hitRadius: 1,
-		hoverRadius: 4,
-		hoverBorderWidth: 1
-	};
+        globalOpts.elements.point = {
+            radius: 3,
+            pointStyle: 'circle',
+            backgroundColor: defaultColor,
+            borderWidth: 1,
+            borderColor: defaultColor,
+            // Hover
+            hitRadius: 1,
+            hoverRadius: 4,
+            hoverBorderWidth: 1
+        };
 
-	Chart.elements.Point = Chart.Element.extend({
-		inRange: function(mouseX, mouseY) {
-			var vm = this._view;
-			return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
-		},
-		inLabelRange: function(mouseX) {
-			var vm = this._view;
-			return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
-		},
-		tooltipPosition: function() {
-			var vm = this._view;
-			return {
-				x: vm.x,
-				y: vm.y,
-				padding: vm.radius + vm.borderWidth
-			};
-		},
-		draw: function() {
-			var vm = this._view;
-			var ctx = this._chart.ctx;
-			var pointStyle = vm.pointStyle;
-			var radius = vm.radius;
-			var x = vm.x;
-			var y = vm.y;
+        function xRange(mouseX) {
+            var vm = this._view;
+            return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
+        }
 
-			if (vm.skip) {
-				return;
-			}
+        function yRange(mouseY) {
+            var vm = this._view;
+            return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
+        }
 
-			ctx.strokeStyle = vm.borderColor || defaultColor;
-			ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
-			ctx.fillStyle = vm.backgroundColor || defaultColor;
+        Chart.elements.Point = Chart.Element.extend({
+            inRange: function(mouseX, mouseY) {
+                var vm = this._view;
+                return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
+            },
 
-			Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
-		}
-	});
-};
+            inLabelRange: xRange,
+            inXRange: xRange,
+            inYRange: yRange,
+
+            getCenterPoint: function() {
+                var vm = this._view;
+                return {
+                    x: vm.x,
+                    y: vm.y
+                };
+            },
+            getArea: function() {
+                return Math.PI * Math.pow(this._view.radius, 2);
+            },
+            tooltipPosition: function() {
+                var vm = this._view;
+                return {
+                    x: vm.x,
+                    y: vm.y,
+                    padding: vm.radius + vm.borderWidth
+                };
+            },
+            draw: function(chartArea) {
+                var vm = this._view;
+                var model = this._model;
+                var ctx = this._chart.ctx;
+                var pointStyle = vm.pointStyle;
+                var radius = vm.radius;
+                var x = vm.x;
+                var y = vm.y;
+                var color = Chart.helpers.color;
+                var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
+                var ratio = 0;
+
+                if (vm.skip) {
+                    return;
+                }
+
+                ctx.strokeStyle = vm.borderColor || defaultColor;
+                ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
+                ctx.fillStyle = vm.backgroundColor || defaultColor;
+
+                // Cliping for Points.
+                // going out from inner charArea?
+                if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) {
+                    // Point fade out
+                    if (model.x < chartArea.left) {
+                        ratio = (x - model.x) / (chartArea.left - model.x);
+                    } else if (chartArea.right*errMargin < model.x) {
+                        ratio = (model.x - x) / (model.x - chartArea.right);
+                    } else if (model.y < chartArea.top) {
+                        ratio = (y - model.y) / (chartArea.top - model.y);
+                    } else if (chartArea.bottom*errMargin < model.y) {
+                        ratio = (model.y - y) / (model.y - chartArea.bottom);
+                    }
+                    ratio = Math.round(ratio*100) / 100;
+                    ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();
+                    ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
+                }
+
+                Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
+            }
+        });
+    };
 
 },{}],38:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var globalOpts = Chart.defaults.global;
+        var globalOpts = Chart.defaults.global;
 
-	globalOpts.elements.rectangle = {
-		backgroundColor: globalOpts.defaultColor,
-		borderWidth: 0,
-		borderColor: globalOpts.defaultColor,
-		borderSkipped: 'bottom'
-	};
+        globalOpts.elements.rectangle = {
+            backgroundColor: globalOpts.defaultColor,
+            borderWidth: 0,
+            borderColor: globalOpts.defaultColor,
+            borderSkipped: 'bottom'
+        };
 
-	Chart.elements.Rectangle = Chart.Element.extend({
-		draw: function() {
-			var ctx = this._chart.ctx;
-			var vm = this._view;
+        function isVertical(bar) {
+            return bar._view.width !== undefined;
+        }
 
-			var halfWidth = vm.width / 2,
-				leftX = vm.x - halfWidth,
-				rightX = vm.x + halfWidth,
-				top = vm.base - (vm.base - vm.y),
-				halfStroke = vm.borderWidth / 2;
+        /**
+         * Helper function to get the bounds of the bar regardless of the orientation
+         * @private
+         * @param bar {Chart.Element.Rectangle} the bar
+         * @return {Bounds} bounds of the bar
+         */
+        function getBarBounds(bar) {
+            var vm = bar._view;
+            var x1, x2, y1, y2;
 
-			// 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 (vm.borderWidth) {
-				leftX += halfStroke;
-				rightX -= halfStroke;
-				top += halfStroke;
-			}
+            if (isVertical(bar)) {
+                // vertical
+                var halfWidth = vm.width / 2;
+                x1 = vm.x - halfWidth;
+                x2 = vm.x + halfWidth;
+                y1 = Math.min(vm.y, vm.base);
+                y2 = Math.max(vm.y, vm.base);
+            } else {
+                // horizontal bar
+                var halfHeight = vm.height / 2;
+                x1 = Math.min(vm.x, vm.base);
+                x2 = Math.max(vm.x, vm.base);
+                y1 = vm.y - halfHeight;
+                y2 = vm.y + halfHeight;
+            }
 
-			ctx.beginPath();
-			ctx.fillStyle = vm.backgroundColor;
-			ctx.strokeStyle = vm.borderColor;
-			ctx.lineWidth = vm.borderWidth;
+            return {
+                left: x1,
+                top: y1,
+                right: x2,
+                bottom: y2
+            };
+        }
 
-			// Corner points, from bottom-left to bottom-right clockwise
-			// | 1 2 |
-			// | 0 3 |
-			var corners = [
-				[leftX, vm.base],
-				[leftX, top],
-				[rightX, top],
-				[rightX, vm.base]
-			];
+        Chart.elements.Rectangle = Chart.Element.extend({
+            draw: function() {
+                var ctx = this._chart.ctx;
+                var vm = this._view;
+                var left, right, top, bottom, signX, signY, borderSkipped;
+                var borderWidth = vm.borderWidth;
 
-			// Find first (starting) corner with fallback to 'bottom'
-			var borders = ['bottom', 'left', 'top', 'right'];
-			var startCorner = borders.indexOf(vm.borderSkipped, 0);
-			if (startCorner === -1)
-				startCorner = 0;
+                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';
+                }
 
-			function cornerAt(index) {
-				return corners[(startCorner + index) % 4];
-			}
+                // 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;
+                    }
+                }
 
-			// Draw rectangle from 'startCorner'
-			ctx.moveTo.apply(ctx, cornerAt(0));
-			for (var i = 1; i < 4; i++)
-				ctx.lineTo.apply(ctx, cornerAt(i));
+                ctx.beginPath();
+                ctx.fillStyle = vm.backgroundColor;
+                ctx.strokeStyle = vm.borderColor;
+                ctx.lineWidth = borderWidth;
 
-			ctx.fill();
-			if (vm.borderWidth) {
-				ctx.stroke();
-			}
-		},
-		height: function() {
-			var vm = this._view;
-			return vm.base - vm.y;
-		},
-		inRange: function(mouseX, mouseY) {
-			var vm = this._view;
-			return vm ?
-					(vm.y < vm.base ?
-						(mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base) :
-						(mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y)) :
-					false;
-		},
-		inLabelRange: function(mouseX) {
-			var vm = this._view;
-			return vm ? (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) : false;
-		},
-		tooltipPosition: function() {
-			var vm = this._view;
-			return {
-				x: vm.x,
-				y: vm.y
-			};
-		}
-	});
+                // 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);
+                    ctx.lineTo(corner[0], corner[1]);
+                }
+
+                ctx.fill();
+                if (borderWidth) {
+                    ctx.stroke();
+                }
+            },
+            height: function() {
+                var vm = this._view;
+                return vm.base - vm.y;
+            },
+            inRange: function(mouseX, mouseY) {
+                var inRange = false;
+
+                if (this._view) {
+                    var bounds = getBarBounds(this);
+                    inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;
+                }
+
+                return inRange;
+            },
+            inLabelRange: function(mouseX, mouseY) {
+                var me = this;
+                if (!me._view) {
+                    return false;
+                }
+
+                var inRange = false;
+                var bounds = getBarBounds(me);
+
+                if (isVertical(me)) {
+                    inRange = mouseX >= bounds.left && mouseX <= bounds.right;
+                } else {
+                    inRange = mouseY >= bounds.top && mouseY <= bounds.bottom;
+                }
+
+                return inRange;
+            },
+            inXRange: function(mouseX) {
+                var bounds = getBarBounds(this);
+                return mouseX >= bounds.left && mouseX <= bounds.right;
+            },
+            inYRange: function(mouseY) {
+                var bounds = getBarBounds(this);
+                return mouseY >= bounds.top && mouseY <= bounds.bottom;
+            },
+            getCenterPoint: function() {
+                var vm = this._view;
+                var x, y;
+                if (isVertical(this)) {
+                    x = vm.x;
+                    y = (vm.y + vm.base) / 2;
+                } else {
+                    x = (vm.x + vm.base) / 2;
+                    y = vm.y;
+                }
+
+                return {x: x, y: y};
+            },
+            getArea: function() {
+                var vm = this._view;
+                return vm.width * Math.abs(vm.y - vm.base);
+            },
+            tooltipPosition: function() {
+                var vm = this._view;
+                return {
+                    x: vm.x,
+                    y: vm.y
+                };
+            }
+        });
+
+    };
+
 },{}],39:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+// Chart.Platform implementation for targeting a web browser
+    module.exports = function(Chart) {
+        var helpers = Chart.helpers;
 
-	var helpers = Chart.helpers;
-	// Default config for a category scale
-	var defaultConfig = {
-		position: "bottom"
-	};
+        // DOM event types -> Chart.js event types.
+        // Note: only events with different types are mapped.
+        // https://developer.mozilla.org/en-US/docs/Web/Events
+        var eventTypeMap = {
+            // Touch events
+            touchstart: 'mousedown',
+            touchmove: 'mousemove',
+            touchend: 'mouseup',
 
-	var DatasetScale = Chart.Scale.extend({
-		/**
-		* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use tose
-		* else fall back to data.labels
-		* @private
-		*/
-		getLabels: function() {
-			var data = this.chart.data;
-			return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
-		},
-		// Implement this so that
-		determineDataLimits: function() {
-			var me = this;
-			var labels = me.getLabels(); 
-			me.minIndex = 0;
-			me.maxIndex = labels.length - 1;
-			var findIndex;
+            // Pointer events
+            pointerenter: 'mouseenter',
+            pointerdown: 'mousedown',
+            pointermove: 'mousemove',
+            pointerup: 'mouseup',
+            pointerleave: 'mouseout',
+            pointerout: 'mouseout'
+        };
 
-			if (me.options.ticks.min !== undefined) {
-				// user specified min value
-				findIndex = helpers.indexOf(labels, me.options.ticks.min);
-				me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
-			}
+        /**
+         * The "used" size is the final value of a dimension property after all calculations have
+         * been performed. This method uses the computed style of `element` but returns undefined
+         * if the computed style is not expressed in pixels. That can happen in some cases where
+         * `element` has a size relative to its parent and this last one is not yet displayed,
+         * for example because of `display: none` on a parent node.
+         * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
+         * @returns {Number} Size in pixels or undefined if unknown.
+         */
+        function readUsedSize(element, property) {
+            var value = helpers.getStyle(element, property);
+            var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
+            return matches? Number(matches[1]) : undefined;
+        }
 
-			if (me.options.ticks.max !== undefined) {
-				// user specified max value
-				findIndex = helpers.indexOf(labels, me.options.ticks.max);
-				me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
-			}
+        /**
+         * Initializes the canvas style and render size without modifying the canvas display size,
+         * since responsiveness is handled by the controller.resize() method. The config is used
+         * to determine the aspect ratio to apply in case no explicit height has been specified.
+         */
+        function initCanvas(canvas, config) {
+            var style = canvas.style;
 
-			me.min = labels[me.minIndex];
-			me.max = labels[me.maxIndex];
-		},
+            // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
+            // returns null or '' if no explicit value has been set to the canvas attribute.
+            var renderHeight = canvas.getAttribute('height');
+            var renderWidth = canvas.getAttribute('width');
 
-		buildTicks: function() {
-			var me = this;
-			var labels = me.getLabels();
-			// If we are viewing some subset of labels, slice the original array
-			me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
-		},
+            // Chart.js modifies some canvas values that we want to restore on destroy
+            canvas._chartjs = {
+                initial: {
+                    height: renderHeight,
+                    width: renderWidth,
+                    style: {
+                        display: style.display,
+                        height: style.height,
+                        width: style.width
+                    }
+                }
+            };
 
-		getLabelForIndex: function(index) {
-			return this.ticks[index];
-		},
+            // Force canvas to display as block to avoid extra space caused by inline
+            // elements, which would interfere with the responsive resize process.
+            // https://github.com/chartjs/Chart.js/issues/2538
+            style.display = style.display || 'block';
 
-		// Used to get data value locations.  Value can either be an index or a numerical value
-		getPixelForValue: function(value, index, datasetIndex, includeOffset) {
-			var me = this;
-			// 1 is added because we need the length but we have the indexes
-			var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
+            if (renderWidth === null || renderWidth === '') {
+                var displayWidth = readUsedSize(canvas, 'width');
+                if (displayWidth !== undefined) {
+                    canvas.width = displayWidth;
+                }
+            }
 
-			if (value !== undefined) {
-				var labels = me.getLabels();
-				var idx = labels.indexOf(value);
-				index = idx !== -1 ? idx : index;
-			}
+            if (renderHeight === null || renderHeight === '') {
+                if (canvas.style.height === '') {
+                    // If no explicit render height and style height, let's apply the aspect ratio,
+                    // which one can be specified by the user but also by charts as default option
+                    // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
+                    canvas.height = canvas.width / (config.options.aspectRatio || 2);
+                } else {
+                    var displayHeight = readUsedSize(canvas, 'height');
+                    if (displayWidth !== undefined) {
+                        canvas.height = displayHeight;
+                    }
+                }
+            }
 
-			if (me.isHorizontal()) {
-				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-				var valueWidth = innerWidth / offsetAmt;
-				var widthOffset = (valueWidth * (index - me.minIndex)) + me.paddingLeft;
+            return canvas;
+        }
 
-				if (me.options.gridLines.offsetGridLines && includeOffset) {
-					widthOffset += (valueWidth / 2);
-				}
+        function createEvent(type, chart, x, y, nativeEvent) {
+            return {
+                type: type,
+                chart: chart,
+                native: nativeEvent || null,
+                x: x !== undefined? x : null,
+                y: y !== undefined? y : null,
+            };
+        }
 
-				return me.left + Math.round(widthOffset);
-			} else {
-				var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-				var valueHeight = innerHeight / offsetAmt;
-				var heightOffset = (valueHeight * (index - me.minIndex)) + me.paddingTop;
+        function fromNativeEvent(event, chart) {
+            var type = eventTypeMap[event.type] || event.type;
+            var pos = helpers.getRelativePosition(event, chart);
+            return createEvent(type, chart, pos.x, pos.y, event);
+        }
 
-				if (me.options.gridLines.offsetGridLines && includeOffset) {
-					heightOffset += (valueHeight / 2);
-				}
+        function createResizer(handler) {
+            var iframe = document.createElement('iframe');
+            iframe.className = 'chartjs-hidden-iframe';
+            iframe.style.cssText =
+                'display:block;'+
+                'overflow:hidden;'+
+                'border:0;'+
+                'margin:0;'+
+                'top:0;'+
+                'left:0;'+
+                'bottom:0;'+
+                'right:0;'+
+                'height:100%;'+
+                'width:100%;'+
+                'position:absolute;'+
+                'pointer-events:none;'+
+                'z-index:-1;';
 
-				return me.top + Math.round(heightOffset);
-			}
-		},
-		getPixelForTick: function(index, includeOffset) {
-			return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var value;
-			var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-			var horz = me.isHorizontal();
-			var innerDimension = horz ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
-			var valueDimension = innerDimension / offsetAmt;
+            // Prevent the iframe to gain focus on tab.
+            // https://github.com/chartjs/Chart.js/issues/3090
+            iframe.tabIndex = -1;
 
-			pixel -= horz ? me.left : me.top;
+            // If the iframe is re-attached to the DOM, the resize listener is removed because the
+            // content is reloaded, so make sure to install the handler after the iframe is loaded.
+            // https://github.com/chartjs/Chart.js/issues/3521
+            helpers.addEvent(iframe, 'load', function() {
+                helpers.addEvent(iframe.contentWindow || iframe, 'resize', handler);
 
-			if (me.options.gridLines.offsetGridLines) {
-				pixel -= (valueDimension / 2);
-			}
-			pixel -= horz ? me.paddingLeft : me.paddingTop;
+                // The iframe size might have changed while loading, which can also
+                // happen if the size has been changed while detached from the DOM.
+                handler();
+            });
 
-			if (pixel <= 0) {
-				value = 0;
-			} else {
-				value = Math.round(pixel / valueDimension);
-			}
+            return iframe;
+        }
 
-			return value;
-		},
-		getBasePixel: function() {
-			return this.bottom;
-		}
-	});
+        function addResizeListener(node, listener, chart) {
+            var stub = node._chartjs = {
+                ticking: false
+            };
 
-	Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
+            // Throttle the callback notification until the next animation frame.
+            var notify = function() {
+                if (!stub.ticking) {
+                    stub.ticking = true;
+                    helpers.requestAnimFrame.call(window, function() {
+                        if (stub.resizer) {
+                            stub.ticking = false;
+                            return listener(createEvent('resize', chart));
+                        }
+                    });
+                }
+            };
 
-};
+            // Let's keep track of this added iframe and thus avoid DOM query when removing it.
+            stub.resizer = createResizer(notify);
+
+            node.insertBefore(stub.resizer, node.firstChild);
+        }
+
+        function removeResizeListener(node) {
+            if (!node || !node._chartjs) {
+                return;
+            }
+
+            var resizer = node._chartjs.resizer;
+            if (resizer) {
+                resizer.parentNode.removeChild(resizer);
+                node._chartjs.resizer = null;
+            }
+
+            delete node._chartjs;
+        }
+
+        return {
+            acquireContext: function(item, config) {
+                if (typeof item === 'string') {
+                    item = document.getElementById(item);
+                } else if (item.length) {
+                    // Support for array based queries (such as jQuery)
+                    item = item[0];
+                }
+
+                if (item && item.canvas) {
+                    // Support for any object associated to a canvas (including a context2d)
+                    item = item.canvas;
+                }
+
+                // To prevent canvas fingerprinting, some add-ons undefine the getContext
+                // method, for example: https://github.com/kkapsner/CanvasBlocker
+                // https://github.com/chartjs/Chart.js/issues/2807
+                var context = item && item.getContext && item.getContext('2d');
+
+                // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
+                // inside an iframe or when running in a protected environment. We could guess the
+                // types from their toString() value but let's keep things flexible and assume it's
+                // a sufficient condition if the item has a context2D which has item as `canvas`.
+                // https://github.com/chartjs/Chart.js/issues/3887
+                // https://github.com/chartjs/Chart.js/issues/4102
+                // https://github.com/chartjs/Chart.js/issues/4152
+                if (context && context.canvas === item) {
+                    initCanvas(item, config);
+                    return context;
+                }
+
+                return null;
+            },
+
+            releaseContext: function(context) {
+                var canvas = context.canvas;
+                if (!canvas._chartjs) {
+                    return;
+                }
+
+                var initial = canvas._chartjs.initial;
+                ['height', 'width'].forEach(function(prop) {
+                    var value = initial[prop];
+                    if (value === undefined || value === null) {
+                        canvas.removeAttribute(prop);
+                    } else {
+                        canvas.setAttribute(prop, value);
+                    }
+                });
+
+                helpers.each(initial.style || {}, function(value, key) {
+                    canvas.style[key] = value;
+                });
+
+                // The canvas render size might have been changed (and thus the state stack discarded),
+                // we can't use save() and restore() to restore the initial state. So make sure that at
+                // least the canvas context is reset to the default state by setting the canvas width.
+                // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
+                canvas.width = canvas.width;
+
+                delete canvas._chartjs;
+            },
+
+            addEventListener: function(chart, type, listener) {
+                var canvas = chart.canvas;
+                if (type === 'resize') {
+                    // Note: the resize event is not supported on all browsers.
+                    addResizeListener(canvas.parentNode, listener, chart);
+                    return;
+                }
+
+                var stub = listener._chartjs || (listener._chartjs = {});
+                var proxies = stub.proxies || (stub.proxies = {});
+                var proxy = proxies[chart.id + '_' + type] = function(event) {
+                    listener(fromNativeEvent(event, chart));
+                };
+
+                helpers.addEvent(canvas, type, proxy);
+            },
+
+            removeEventListener: function(chart, type, listener) {
+                var canvas = chart.canvas;
+                if (type === 'resize') {
+                    // Note: the resize event is not supported on all browsers.
+                    removeResizeListener(canvas.parentNode, listener);
+                    return;
+                }
+
+                var stub = listener._chartjs || {};
+                var proxies = stub.proxies || {};
+                var proxy = proxies[chart.id + '_' + type];
+                if (!proxy) {
+                    return;
+                }
+
+                helpers.removeEvent(canvas, type, proxy);
+            }
+        };
+    };
+
 },{}],40:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+// By default, select the browser (DOM) platform.
+// @TODO Make possible to select another platform at build time.
+    var implementation = require(39);
 
-	var helpers = Chart.helpers;
+    module.exports = function(Chart) {
+        /**
+         * @namespace Chart.platform
+         * @see https://chartjs.gitbooks.io/proposals/content/Platform.html
+         * @since 2.4.0
+         */
+        Chart.platform = {
+            /**
+             * Called at chart construction time, returns a context2d instance implementing
+             * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.
+             * @param {*} item - The native item from which to acquire context (platform specific)
+             * @param {Object} options - The chart options
+             * @returns {CanvasRenderingContext2D} context2d instance
+             */
+            acquireContext: function() {},
 
-	var defaultConfig = {
-		position: "left",
-		ticks: {
-			callback: function(tickValue, index, ticks) {
-				// If we have lots of ticks, don't use the ones
-				var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
+            /**
+             * Called at chart destruction time, releases any resources associated to the context
+             * previously returned by the acquireContext() method.
+             * @param {CanvasRenderingContext2D} context - The context2d instance
+             * @returns {Boolean} true if the method succeeded, else false
+             */
+            releaseContext: function() {},
 
-				// If we have a number like 2.5 as the delta, figure out how many decimal places we need
-				if (Math.abs(delta) > 1) {
-					if (tickValue !== Math.floor(tickValue)) {
-						// not an integer
-						delta = tickValue - Math.floor(tickValue);
-					}
-				}
+            /**
+             * Registers the specified listener on the given chart.
+             * @param {Chart} chart - Chart from which to listen for event
+             * @param {String} type - The ({@link IEvent}) type to listen for
+             * @param {Function} listener - Receives a notification (an object that implements
+             * the {@link IEvent} interface) when an event of the specified type occurs.
+             */
+            addEventListener: function() {},
 
-				var logDelta = helpers.log10(Math.abs(delta));
-				var tickString = '';
+            /**
+             * Removes the specified listener previously registered with addEventListener.
+             * @param {Chart} chart -Chart from which to remove the listener
+             * @param {String} type - The ({@link IEvent}) type to remove
+             * @param {Function} listener - The listener function to remove from the event target.
+             */
+            removeEventListener: function() {}
+        };
 
-				if (tickValue !== 0) {
-					var numDecimal = -1 * Math.floor(logDelta);
-					numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
-					tickString = tickValue.toFixed(numDecimal);
-				} else {
-					tickString = '0'; // never show decimal places for 0
-				}
+        /**
+         * @interface IPlatform
+         * Allows abstracting platform dependencies away from the chart
+         * @borrows Chart.platform.acquireContext as acquireContext
+         * @borrows Chart.platform.releaseContext as releaseContext
+         * @borrows Chart.platform.addEventListener as addEventListener
+         * @borrows Chart.platform.removeEventListener as removeEventListener
+         */
 
-				return tickString;
-			}
-		}
-	};
+        /**
+         * @interface IEvent
+         * @prop {String} type - The event type name, possible values are:
+         * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
+         * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'
+         * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')
+         * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)
+         * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
+         */
 
-	var LinearScale = Chart.LinearScaleBase.extend({
-		determineDataLimits: function() {
-			var me = this;
-			var opts = me.options;
-			var chart = me.chart;
-			var data = chart.data;
-			var datasets = data.datasets;
-			var isHorizontal = me.isHorizontal();
+        Chart.helpers.extend(Chart.platform, implementation(Chart));
+    };
 
-			function IDMatches(meta) {
-				return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
-			}
+},{"39":39}],41:[function(require,module,exports){
+    'use strict';
 
-			// First Calculate the range
-			me.min = null;
-			me.max = null;
+    module.exports = function(Chart) {
+        /**
+         * Plugin based on discussion from the following Chart.js issues:
+         * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569
+         * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897
+         */
+        Chart.defaults.global.plugins.filler = {
+            propagate: true
+        };
 
-			if (opts.stacked) {
-				var valuesPerType = {};
-				var hasPositiveValues = false;
-				var hasNegativeValues = false;
+        var defaults = Chart.defaults;
+        var helpers = Chart.helpers;
+        var mappers = {
+            dataset: function(source) {
+                var index = source.fill;
+                var chart = source.chart;
+                var meta = chart.getDatasetMeta(index);
+                var visible = meta && chart.isDatasetVisible(index);
+                var points = (visible && meta.dataset._children) || [];
 
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (valuesPerType[meta.type] === undefined) {
-						valuesPerType[meta.type] = {
-							positiveValues: [],
-							negativeValues: []
-						};
-					}
+                return !points.length? null : function(point, i) {
+                    return points[i]._view || null;
+                };
+            },
 
-					// Store these per type
-					var positiveValues = valuesPerType[meta.type].positiveValues;
-					var negativeValues = valuesPerType[meta.type].negativeValues;
+            boundary: function(source) {
+                var boundary = source.boundary;
+                var x = boundary? boundary.x : null;
+                var y = boundary? boundary.y : null;
 
-					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-						helpers.each(dataset.data, function(rawValue, index) {
-							var value = +me.getRightValue(rawValue);
-							if (isNaN(value) || meta.data[index].hidden) {
-								return;
-							}
+                return function(point) {
+                    return {
+                        x: x === null? point.x : x,
+                        y: y === null? point.y : y,
+                    };
+                };
+            }
+        };
 
-							positiveValues[index] = positiveValues[index] || 0;
-							negativeValues[index] = negativeValues[index] || 0;
+        // @todo if (fill[0] === '#')
+        function decodeFill(el, index, count) {
+            var model = el._model || {};
+            var fill = model.fill;
+            var target;
 
-							if (opts.relativePoints) {
-								positiveValues[index] = 100;
-							} else {
-								if (value < 0) {
-									hasNegativeValues = true;
-									negativeValues[index] += value;
-								} else {
-									hasPositiveValues = true;
-									positiveValues[index] += value;
-								}
-							}
-						});
-					}
-				});
+            if (fill === undefined) {
+                fill = !!model.backgroundColor;
+            }
 
-				helpers.each(valuesPerType, function(valuesForType) {
-					var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
-					var minVal = helpers.min(values);
-					var maxVal = helpers.max(values);
-					me.min = me.min === null ? minVal : Math.min(me.min, minVal);
-					me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
-				});
+            if (fill === false || fill === null) {
+                return false;
+            }
 
-			} else {
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-						helpers.each(dataset.data, function(rawValue, index) {
-							var value = +me.getRightValue(rawValue);
-							if (isNaN(value) || meta.data[index].hidden) {
-								return;
-							}
+            if (fill === true) {
+                return 'origin';
+            }
 
-							if (me.min === null) {
-								me.min = value;
-							} else if (value < me.min) {
-								me.min = value;
-							}
+            target = parseFloat(fill, 10);
+            if (isFinite(target) && Math.floor(target) === target) {
+                if (fill[0] === '-' || fill[0] === '+') {
+                    target = index + target;
+                }
 
-							if (me.max === null) {
-								me.max = value;
-							} else if (value > me.max) {
-								me.max = value;
-							}
-						});
-					}
-				});
-			}
+                if (target === index || target < 0 || target >= count) {
+                    return false;
+                }
 
-			// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
-			this.handleTickRangeOptions();
-		},
-		getTickLimit: function() {
-			var maxTicks;
-			var me = this;
-			var tickOpts = me.options.ticks;
+                return target;
+            }
 
-			if (me.isHorizontal()) {
-				maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
-			} else {
-				// The factor of 2 used to scale the font size has been experimentally determined.
-				var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);
-				maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
-			}
+            switch (fill) {
+                // compatibility
+                case 'bottom':
+                    return 'start';
+                case 'top':
+                    return 'end';
+                case 'zero':
+                    return 'origin';
+                // supported boundaries
+                case 'origin':
+                case 'start':
+                case 'end':
+                    return fill;
+                // invalid fill values
+                default:
+                    return false;
+            }
+        }
 
-			return maxTicks;
-		},
-		// Called after the ticks are built. We need
-		handleDirectionalChanges: function() {
-			if (!this.isHorizontal()) {
-				// We are in a vertical orientation. The top value is the highest. So reverse the array
-				this.ticks.reverse();
-			}
-		},
-		getLabelForIndex: function(index, datasetIndex) {
-			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-		},
-		// Utils
-		getPixelForValue: function(value) {
-			// This must be called after fit has been run so that
-			// this.left, this.top, this.right, and this.bottom have been defined
-			var me = this;
-			var paddingLeft = me.paddingLeft;
-			var paddingBottom = me.paddingBottom;
-			var start = me.start;
+        function computeBoundary(source) {
+            var model = source.el._model || {};
+            var scale = source.el._scale || {};
+            var fill = source.fill;
+            var target = null;
+            var horizontal;
 
-			var rightValue = +me.getRightValue(value);
-			var pixel;
-			var innerDimension;
-			var range = me.end - start;
+            if (isFinite(fill)) {
+                return null;
+            }
 
-			if (me.isHorizontal()) {
-				innerDimension = me.width - (paddingLeft + me.paddingRight);
-				pixel = me.left + (innerDimension / range * (rightValue - start));
-				return Math.round(pixel + paddingLeft);
-			} else {
-				innerDimension = me.height - (me.paddingTop + paddingBottom);
-				pixel = (me.bottom - paddingBottom) - (innerDimension / range * (rightValue - start));
-				return Math.round(pixel);
-			}
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var isHorizontal = me.isHorizontal();
-			var paddingLeft = me.paddingLeft;
-			var paddingBottom = me.paddingBottom;
-			var innerDimension = isHorizontal ? me.width - (paddingLeft + me.paddingRight) : me.height - (me.paddingTop + paddingBottom);
-			var offset = (isHorizontal ? pixel - me.left - paddingLeft : me.bottom - paddingBottom - pixel) / innerDimension;
-			return me.start + ((me.end - me.start) * offset);
-		},
-		getPixelForTick: function(index) {
-			return this.getPixelForValue(this.ticksAsNumbers[index]);
-		}
-	});
-	Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);
+            // Backward compatibility: until v3, we still need to support boundary values set on
+            // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and
+            // controllers might still use it (e.g. the Smith chart).
 
-};
-},{}],41:[function(require,module,exports){
-"use strict";
+            if (fill === 'start') {
+                target = model.scaleBottom === undefined? scale.bottom : model.scaleBottom;
+            } else if (fill === 'end') {
+                target = model.scaleTop === undefined? scale.top : model.scaleTop;
+            } else if (model.scaleZero !== undefined) {
+                target = model.scaleZero;
+            } else if (scale.getBasePosition) {
+                target = scale.getBasePosition();
+            } else if (scale.getBasePixel) {
+                target = scale.getBasePixel();
+            }
 
-module.exports = function(Chart) {
+            if (target !== undefined && target !== null) {
+                if (target.x !== undefined && target.y !== undefined) {
+                    return target;
+                }
 
-	var helpers = Chart.helpers,
-		noop = helpers.noop;
+                if (typeof target === 'number' && isFinite(target)) {
+                    horizontal = scale.isHorizontal();
+                    return {
+                        x: horizontal? target : null,
+                        y: horizontal? null : target
+                    };
+                }
+            }
 
-	Chart.LinearScaleBase = Chart.Scale.extend({
-		handleTickRangeOptions: function() {
-			var me = this;
-			var opts = me.options;
-			var tickOpts = opts.ticks;
+            return null;
+        }
 
-			// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
-			// do nothing since that would make the chart weird. If the user really wants a weird chart
-			// axis, they can manually override it
-			if (tickOpts.beginAtZero) {
-				var minSign = helpers.sign(me.min);
-				var maxSign = helpers.sign(me.max);
+        function resolveTarget(sources, index, propagate) {
+            var source = sources[index];
+            var fill = source.fill;
+            var visited = [index];
+            var target;
 
-				if (minSign < 0 && maxSign < 0) {
-					// move the top up to 0
-					me.max = 0;
-				} else if (minSign > 0 && maxSign > 0) {
-					// move the botttom down to 0
-					me.min = 0;
-				}
-			}
+            if (!propagate) {
+                return fill;
+            }
 
-			if (tickOpts.min !== undefined) {
-				me.min = tickOpts.min;
-			} else if (tickOpts.suggestedMin !== undefined) {
-				me.min = Math.min(me.min, tickOpts.suggestedMin);
-			}
+            while (fill !== false && visited.indexOf(fill) === -1) {
+                if (!isFinite(fill)) {
+                    return fill;
+                }
 
-			if (tickOpts.max !== undefined) {
-				me.max = tickOpts.max;
-			} else if (tickOpts.suggestedMax !== undefined) {
-				me.max = Math.max(me.max, tickOpts.suggestedMax);
-			}
+                target = sources[fill];
+                if (!target) {
+                    return false;
+                }
 
-			if (me.min === me.max) {
-				me.max++;
+                if (target.visible) {
+                    return fill;
+                }
 
-				if (!tickOpts.beginAtZero) {
-					me.min--;
-				}
-			}
-		},
-		getTickLimit: noop,
-		handleDirectionalChanges: noop,
+                visited.push(fill);
+                fill = target.fill;
+            }
 
-		buildTicks: function() {
-			var me = this;
-			var opts = me.options;
-			var ticks = me.ticks = [];
-			var tickOpts = opts.ticks;
-			var getValueOrDefault = helpers.getValueOrDefault;
+            return false;
+        }
 
-			// Figure out what the max number of ticks we can support it is based on the size of
-			// the axis area. For now, we say that the minimum tick spacing in pixels must be 50
-			// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
-			// the graph
+        function createMapper(source) {
+            var fill = source.fill;
+            var type = 'dataset';
 
-			var maxTicks = me.getTickLimit();
+            if (fill === false) {
+                return null;
+            }
 
-			// Make sure we always have at least 2 ticks
-			maxTicks = Math.max(2, maxTicks);
+            if (!isFinite(fill)) {
+                type = 'boundary';
+            }
 
-			// To get a "nice" value for the tick spacing, we will use the appropriately named
-			// "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
-			// for details.
+            return mappers[type](source);
+        }
 
-			var spacing;
-			var fixedStepSizeSet = (tickOpts.fixedStepSize && tickOpts.fixedStepSize > 0) || (tickOpts.stepSize && tickOpts.stepSize > 0);
-			if (fixedStepSizeSet) {
-				spacing = getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize);
-			} else {
-				var niceRange = helpers.niceNum(me.max - me.min, false);
-				spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
-			}
-			var niceMin = Math.floor(me.min / spacing) * spacing;
-			var niceMax = Math.ceil(me.max / spacing) * spacing;
-			var numSpaces = (niceMax - niceMin) / spacing;
+        function isDrawable(point) {
+            return point && !point.skip;
+        }
 
-			// If very close to our rounded value, use it.
-			if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
-				numSpaces = Math.round(numSpaces);
-			} else {
-				numSpaces = Math.ceil(numSpaces);
-			}
+        function drawArea(ctx, curve0, curve1, len0, len1) {
+            var i;
 
-			// Put the values into the ticks array
-			ticks.push(tickOpts.min !== undefined ? tickOpts.min : niceMin);
-			for (var j = 1; j < numSpaces; ++j) {
-				ticks.push(niceMin + (j * spacing));
-			}
-			ticks.push(tickOpts.max !== undefined ? tickOpts.max : niceMax);
+            if (!len0 || !len1) {
+                return;
+            }
 
-			me.handleDirectionalChanges();
+            // building first area curve (normal)
+            ctx.moveTo(curve0[0].x, curve0[0].y);
+            for (i=1; i<len0; ++i) {
+                helpers.canvas.lineTo(ctx, curve0[i-1], curve0[i]);
+            }
 
-			// At this point, we need to update our max and min given the tick values since we have expanded the
-			// range of the scale
-			me.max = helpers.max(ticks);
-			me.min = helpers.min(ticks);
+            // joining the two area curves
+            ctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);
 
-			if (tickOpts.reverse) {
-				ticks.reverse();
+            // building opposite area curve (reverse)
+            for (i=len1-1; i>0; --i) {
+                helpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);
+            }
+        }
 
-				me.start = me.max;
-				me.end = me.min;
-			} else {
-				me.start = me.min;
-				me.end = me.max;
-			}
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			me.ticksAsNumbers = me.ticks.slice();
-			me.zeroLineIndex = me.ticks.indexOf(0);
+        function doFill(ctx, points, mapper, view, color, loop) {
+            var count = points.length;
+            var span = view.spanGaps;
+            var curve0 = [];
+            var curve1 = [];
+            var len0 = 0;
+            var len1 = 0;
+            var i, ilen, index, p0, p1, d0, d1;
 
-			Chart.Scale.prototype.convertTicksToLabels.call(me);
-		},
-	});
-};
+            ctx.beginPath();
+
+            for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
+                index = i%count;
+                p0 = points[index]._view;
+                p1 = mapper(p0, index, view);
+                d0 = isDrawable(p0);
+                d1 = isDrawable(p1);
+
+                if (d0 && d1) {
+                    len0 = curve0.push(p0);
+                    len1 = curve1.push(p1);
+                } else if (len0 && len1) {
+                    if (!span) {
+                        drawArea(ctx, curve0, curve1, len0, len1);
+                        len0 = len1 = 0;
+                        curve0 = [];
+                        curve1 = [];
+                    } else {
+                        if (d0) {
+                            curve0.push(p0);
+                        }
+                        if (d1) {
+                            curve1.push(p1);
+                        }
+                    }
+                }
+            }
+
+            drawArea(ctx, curve0, curve1, len0, len1);
+
+            ctx.closePath();
+            ctx.fillStyle = color;
+            ctx.fill();
+        }
+
+        return {
+            id: 'filler',
+
+            afterDatasetsUpdate: function(chart, options) {
+                var count = (chart.data.datasets || []).length;
+                var propagate = options.propagate;
+                var sources = [];
+                var meta, i, el, source;
+
+                for (i = 0; i < count; ++i) {
+                    meta = chart.getDatasetMeta(i);
+                    el = meta.dataset;
+                    source = null;
+
+                    if (el && el._model && el instanceof Chart.elements.Line) {
+                        source = {
+                            visible: chart.isDatasetVisible(i),
+                            fill: decodeFill(el, i, count),
+                            chart: chart,
+                            el: el
+                        };
+                    }
+
+                    meta.$filler = source;
+                    sources.push(source);
+                }
+
+                for (i=0; i<count; ++i) {
+                    source = sources[i];
+                    if (!source) {
+                        continue;
+                    }
+
+                    source.fill = resolveTarget(sources, i, propagate);
+                    source.boundary = computeBoundary(source);
+                    source.mapper = createMapper(source);
+                }
+            },
+
+            beforeDatasetDraw: function(chart, args) {
+                var meta = args.meta.$filler;
+                if (!meta) {
+                    return;
+                }
+
+                var el = meta.el;
+                var view = el._view;
+                var points = el._children || [];
+                var mapper = meta.mapper;
+                var color = view.backgroundColor || defaults.global.defaultColor;
+
+                if (mapper && color && points.length) {
+                    doFill(chart.ctx, points, mapper, view, color, el._loop);
+                }
+            }
+        };
+    };
+
 },{}],42:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
+        var helpers = Chart.helpers;
+        var layout = Chart.layoutService;
+        var noop = helpers.noop;
 
-	var defaultConfig = {
-		position: "left",
+        Chart.defaults.global.legend = {
+            display: true,
+            position: 'top',
+            fullWidth: true,
+            reverse: false,
+            weight: 1000,
 
-		// label settings
-		ticks: {
-			callback: function(value, index, arr) {
-				var remain = value / (Math.pow(10, Math.floor(helpers.log10(value))));
+            // a callback that will handle
+            onClick: function(e, legendItem) {
+                var index = legendItem.datasetIndex;
+                var ci = this.chart;
+                var meta = ci.getDatasetMeta(index);
 
-				if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {
-					return value.toExponential();
-				} else {
-					return '';
-				}
-			}
-		}
-	};
+                // See controller.isDatasetVisible comment
+                meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
 
-	var LogarithmicScale = Chart.Scale.extend({
-		determineDataLimits: function() {
-			var me = this;
-			var opts = me.options;
-			var tickOpts = opts.ticks;
-			var chart = me.chart;
-			var data = chart.data;
-			var datasets = data.datasets;
-			var getValueOrDefault = helpers.getValueOrDefault;
-			var isHorizontal = me.isHorizontal();
-			function IDMatches(meta) {
-				return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
-			}
+                // We hid a dataset ... rerender the chart
+                ci.update();
+            },
 
-			// Calculate Range
-			me.min = null;
-			me.max = null;
+            onHover: null,
 
-			if (opts.stacked) {
-				var valuesPerType = {};
+            labels: {
+                boxWidth: 40,
+                padding: 10,
+                // Generates labels shown in the legend
+                // Valid properties to return:
+                // text : text to display
+                // fillStyle : fill of coloured box
+                // strokeStyle: stroke of coloured box
+                // hidden : if this legend item refers to a hidden item
+                // lineCap : cap style for line
+                // lineDash
+                // lineDashOffset :
+                // lineJoin :
+                // lineWidth :
+                generateLabels: function(chart) {
+                    var data = chart.data;
+                    return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
+                        return {
+                            text: dataset.label,
+                            fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
+                            hidden: !chart.isDatasetVisible(i),
+                            lineCap: dataset.borderCapStyle,
+                            lineDash: dataset.borderDash,
+                            lineDashOffset: dataset.borderDashOffset,
+                            lineJoin: dataset.borderJoinStyle,
+                            lineWidth: dataset.borderWidth,
+                            strokeStyle: dataset.borderColor,
+                            pointStyle: dataset.pointStyle,
 
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-						if (valuesPerType[meta.type] === undefined) {
-							valuesPerType[meta.type] = [];
-						}
+                            // Below is extra data used for toggling the datasets
+                            datasetIndex: i
+                        };
+                    }, this) : [];
+                }
+            }
+        };
 
-						helpers.each(dataset.data, function(rawValue, index) {
-							var values = valuesPerType[meta.type];
-							var value = +me.getRightValue(rawValue);
-							if (isNaN(value) || meta.data[index].hidden) {
-								return;
-							}
+        /**
+         * Helper function to get the box width based on the usePointStyle option
+         * @param labelopts {Object} the label options on the legend
+         * @param fontSize {Number} the label font size
+         * @return {Number} width of the color box area
+         */
+        function getBoxWidth(labelOpts, fontSize) {
+            return labelOpts.usePointStyle ?
+                fontSize * Math.SQRT2 :
+                labelOpts.boxWidth;
+        }
 
-							values[index] = values[index] || 0;
+        Chart.Legend = Chart.Element.extend({
 
-							if (opts.relativePoints) {
-								values[index] = 100;
-							} else {
-								// Don't need to split positive and negative since the log scale can't handle a 0 crossing
-								values[index] += value;
-							}
-						});
-					}
-				});
+            initialize: function(config) {
+                helpers.extend(this, config);
 
-				helpers.each(valuesPerType, function(valuesForType) {
-					var minVal = helpers.min(valuesForType);
-					var maxVal = helpers.max(valuesForType);
-					me.min = me.min === null ? minVal : Math.min(me.min, minVal);
-					me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
-				});
+                // Contains hit boxes for each dataset (in dataset order)
+                this.legendHitBoxes = [];
 
-			} else {
-				helpers.each(datasets, function(dataset, datasetIndex) {
-					var meta = chart.getDatasetMeta(datasetIndex);
-					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
-						helpers.each(dataset.data, function(rawValue, index) {
-							var value = +me.getRightValue(rawValue);
-							if (isNaN(value) || meta.data[index].hidden) {
-								return;
-							}
+                // Are we in doughnut mode which has a different data type
+                this.doughnutMode = false;
+            },
 
-							if (me.min === null) {
-								me.min = value;
-							} else if (value < me.min) {
-								me.min = value;
-							}
+            // These methods are ordered by lifecycle. Utilities then follow.
+            // Any function defined here is inherited by all legend types.
+            // Any function can be extended by the legend type
 
-							if (me.max === null) {
-								me.max = value;
-							} else if (value > me.max) {
-								me.max = value;
-							}
-						});
-					}
-				});
-			}
+            beforeUpdate: noop,
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			me.min = getValueOrDefault(tickOpts.min, me.min);
-			me.max = getValueOrDefault(tickOpts.max, me.max);
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-			if (me.min === me.max) {
-				if (me.min !== 0 && me.min !== null) {
-					me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
-					me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
-				} else {
-					me.min = 1;
-					me.max = 10;
-				}
-			}
-		},
-		buildTicks: function() {
-			var me = this;
-			var opts = me.options;
-			var tickOpts = opts.ticks;
-			var getValueOrDefault = helpers.getValueOrDefault;
+                // Absorb the master measurements
+                me.maxWidth = maxWidth;
+                me.maxHeight = maxHeight;
+                me.margins = margins;
 
-			// Reset the ticks array. Later on, we will draw a grid line at these positions
-			// The array simply contains the numerical value of the spots where ticks will be
-			var ticks = me.ticks = [];
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
+                // Labels
+                me.beforeBuildLabels();
+                me.buildLabels();
+                me.afterBuildLabels();
 
-			// Figure out what the max number of ticks we can support it is based on the size of
-			// the axis area. For now, we say that the minimum tick spacing in pixels must be 50
-			// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
-			// the graph
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-			var tickVal = getValueOrDefault(tickOpts.min, Math.pow(10, Math.floor(helpers.log10(me.min))));
+                return me.minSize;
+            },
+            afterUpdate: noop,
 
-			while (tickVal < me.max) {
-				ticks.push(tickVal);
+            //
 
-				var exp = Math.floor(helpers.log10(tickVal));
-				var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
+            beforeSetDimensions: noop,
+            setDimensions: function() {
+                var me = this;
+                // Set the unconstrained dimension before label rotation
+                if (me.isHorizontal()) {
+                    // Reset position before calculating rotation
+                    me.width = me.maxWidth;
+                    me.left = 0;
+                    me.right = me.width;
+                } else {
+                    me.height = me.maxHeight;
 
-				if (significand === 10) {
-					significand = 1;
-					++exp;
-				}
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-				tickVal = significand * Math.pow(10, exp);
-			}
+                // Reset padding
+                me.paddingLeft = 0;
+                me.paddingTop = 0;
+                me.paddingRight = 0;
+                me.paddingBottom = 0;
 
-			var lastTick = getValueOrDefault(tickOpts.max, tickVal);
-			ticks.push(lastTick);
+                // Reset minSize
+                me.minSize = {
+                    width: 0,
+                    height: 0
+                };
+            },
+            afterSetDimensions: noop,
 
-			if (!me.isHorizontal()) {
-				// We are in a vertical orientation. The top value is the highest. So reverse the array
-				ticks.reverse();
-			}
+            //
 
-			// At this point, we need to update our max and min given the tick values since we have expanded the
-			// range of the scale
-			me.max = helpers.max(ticks);
-			me.min = helpers.min(ticks);
+            beforeBuildLabels: noop,
+            buildLabels: function() {
+                var me = this;
+                var labelOpts = me.options.labels;
+                var legendItems = labelOpts.generateLabels.call(me, me.chart);
 
-			if (tickOpts.reverse) {
-				ticks.reverse();
+                if (labelOpts.filter) {
+                    legendItems = legendItems.filter(function(item) {
+                        return labelOpts.filter(item, me.chart.data);
+                    });
+                }
 
-				me.start = me.max;
-				me.end = me.min;
-			} else {
-				me.start = me.min;
-				me.end = me.max;
-			}
-		},
-		convertTicksToLabels: function() {
-			this.tickValues = this.ticks.slice();
+                if (me.options.reverse) {
+                    legendItems.reverse();
+                }
 
-			Chart.Scale.prototype.convertTicksToLabels.call(this);
-		},
-		// Get the correct tooltip label
-		getLabelForIndex: function(index, datasetIndex) {
-			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-		},
-		getPixelForTick: function(index) {
-			return this.getPixelForValue(this.tickValues[index]);
-		},
-		getPixelForValue: function(value) {
-			var me = this;
-			var innerDimension;
-			var pixel;
+                me.legendItems = legendItems;
+            },
+            afterBuildLabels: noop,
 
-			var start = me.start;
-			var newVal = +me.getRightValue(value);
-			var range = helpers.log10(me.end) - helpers.log10(start);
-			var paddingTop = me.paddingTop;
-			var paddingBottom = me.paddingBottom;
-			var paddingLeft = me.paddingLeft;
+            //
 
-			if (me.isHorizontal()) {
+            beforeFit: noop,
+            fit: function() {
+                var me = this;
+                var opts = me.options;
+                var labelOpts = opts.labels;
+                var display = opts.display;
 
-				if (newVal === 0) {
-					pixel = me.left + paddingLeft;
-				} else {
-					innerDimension = me.width - (paddingLeft + me.paddingRight);
-					pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-					pixel += paddingLeft;
-				}
-			} else {
-				// Bottom - top since pixels increase downard on a screen
-				if (newVal === 0) {
-					pixel = me.top + paddingTop;
-				} else {
-					innerDimension = me.height - (paddingTop + paddingBottom);
-					pixel = (me.bottom - paddingBottom) - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
-				}
-			}
+                var ctx = me.ctx;
 
-			return pixel;
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var range = helpers.log10(me.end) - helpers.log10(me.start);
-			var value, innerDimension;
+                var globalDefault = Chart.defaults.global,
+                    itemOrDefault = helpers.getValueOrDefault,
+                    fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
+                    fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
+                    fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
+                    labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
 
-			if (me.isHorizontal()) {
-				innerDimension = me.width - (me.paddingLeft + me.paddingRight);
-				value = me.start * Math.pow(10, (pixel - me.left - me.paddingLeft) * range / innerDimension);
-			} else {
-				innerDimension = me.height - (me.paddingTop + me.paddingBottom);
-				value = Math.pow(10, (me.bottom - me.paddingBottom - pixel) * range / innerDimension) / me.start;
-			}
+                // Reset hit boxes
+                var hitboxes = me.legendHitBoxes = [];
 
-			return value;
-		}
-	});
-	Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
+                var minSize = me.minSize;
+                var isHorizontal = me.isHorizontal();
 
-};
+                if (isHorizontal) {
+                    minSize.width = me.maxWidth; // fill all the width
+                    minSize.height = display ? 10 : 0;
+                } else {
+                    minSize.width = display ? 10 : 0;
+                    minSize.height = me.maxHeight; // fill all the height
+                }
+
+                // Increase sizes here
+                if (display) {
+                    ctx.font = labelFont;
+
+                    if (isHorizontal) {
+                        // Labels
+
+                        // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
+                        var lineWidths = me.lineWidths = [0];
+                        var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
+
+                        ctx.textAlign = 'left';
+                        ctx.textBaseline = 'top';
+
+                        helpers.each(me.legendItems, function(legendItem, i) {
+                            var boxWidth = getBoxWidth(labelOpts, fontSize);
+                            var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+                            if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
+                                totalHeight += fontSize + (labelOpts.padding);
+                                lineWidths[lineWidths.length] = me.left;
+                            }
+
+                            // Store the hitbox width and height here. Final position will be updated in `draw`
+                            hitboxes[i] = {
+                                left: 0,
+                                top: 0,
+                                width: width,
+                                height: fontSize
+                            };
+
+                            lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
+                        });
+
+                        minSize.height += totalHeight;
+
+                    } else {
+                        var vPadding = labelOpts.padding;
+                        var columnWidths = me.columnWidths = [];
+                        var totalWidth = labelOpts.padding;
+                        var currentColWidth = 0;
+                        var currentColHeight = 0;
+                        var itemHeight = fontSize + vPadding;
+
+                        helpers.each(me.legendItems, function(legendItem, i) {
+                            var boxWidth = getBoxWidth(labelOpts, fontSize);
+                            var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
+
+                            // If too tall, go to new column
+                            if (currentColHeight + itemHeight > minSize.height) {
+                                totalWidth += currentColWidth + labelOpts.padding;
+                                columnWidths.push(currentColWidth); // previous column width
+
+                                currentColWidth = 0;
+                                currentColHeight = 0;
+                            }
+
+                            // Get max width
+                            currentColWidth = Math.max(currentColWidth, itemWidth);
+                            currentColHeight += itemHeight;
+
+                            // Store the hitbox width and height here. Final position will be updated in `draw`
+                            hitboxes[i] = {
+                                left: 0,
+                                top: 0,
+                                width: itemWidth,
+                                height: fontSize
+                            };
+                        });
+
+                        totalWidth += currentColWidth;
+                        columnWidths.push(currentColWidth);
+                        minSize.width += totalWidth;
+                    }
+                }
+
+                me.width = minSize.width;
+                me.height = minSize.height;
+            },
+            afterFit: noop,
+
+            // Shared Methods
+            isHorizontal: function() {
+                return this.options.position === 'top' || this.options.position === 'bottom';
+            },
+
+            // Actually draw the legend on the canvas
+            draw: function() {
+                var me = this;
+                var opts = me.options;
+                var labelOpts = opts.labels;
+                var globalDefault = Chart.defaults.global,
+                    lineDefault = globalDefault.elements.line,
+                    legendWidth = me.width,
+                    lineWidths = me.lineWidths;
+
+                if (opts.display) {
+                    var ctx = me.ctx,
+                        cursor,
+                        itemOrDefault = helpers.getValueOrDefault,
+                        fontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),
+                        fontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),
+                        fontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),
+                        fontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),
+                        labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+                    // Canvas setup
+                    ctx.textAlign = 'left';
+                    ctx.textBaseline = 'top';
+                    ctx.lineWidth = 0.5;
+                    ctx.strokeStyle = fontColor; // for strikethrough effect
+                    ctx.fillStyle = fontColor; // render in correct colour
+                    ctx.font = labelFont;
+
+                    var boxWidth = getBoxWidth(labelOpts, fontSize),
+                        hitboxes = me.legendHitBoxes;
+
+                    // current position
+                    var drawLegendBox = function(x, y, legendItem) {
+                        if (isNaN(boxWidth) || boxWidth <= 0) {
+                            return;
+                        }
+
+                        // Set the ctx for the box
+                        ctx.save();
+
+                        ctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
+                        ctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
+                        ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
+                        ctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
+                        ctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
+                        ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
+                        var isLineWidthZero = (itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
+
+                        if (ctx.setLineDash) {
+                            // IE 9 and 10 do not support line dash
+                            ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
+                        }
+
+                        if (opts.labels && opts.labels.usePointStyle) {
+                            // Recalculate x and y for drawPoint() because its expecting
+                            // x and y to be center of figure (instead of top left)
+                            var radius = fontSize * Math.SQRT2 / 2;
+                            var offSet = radius / Math.SQRT2;
+                            var centerX = x + offSet;
+                            var centerY = y + offSet;
+
+                            // Draw pointStyle as legend symbol
+                            Chart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
+                        } else {
+                            // Draw box as legend symbol
+                            if (!isLineWidthZero) {
+                                ctx.strokeRect(x, y, boxWidth, fontSize);
+                            }
+                            ctx.fillRect(x, y, boxWidth, fontSize);
+                        }
+
+                        ctx.restore();
+                    };
+                    var fillText = function(x, y, legendItem, textWidth) {
+                        ctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);
+
+                        if (legendItem.hidden) {
+                            // Strikethrough the text if hidden
+                            ctx.beginPath();
+                            ctx.lineWidth = 2;
+                            ctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));
+                            ctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));
+                            ctx.stroke();
+                        }
+                    };
+
+                    // Horizontal
+                    var isHorizontal = me.isHorizontal();
+                    if (isHorizontal) {
+                        cursor = {
+                            x: me.left + ((legendWidth - lineWidths[0]) / 2),
+                            y: me.top + labelOpts.padding,
+                            line: 0
+                        };
+                    } else {
+                        cursor = {
+                            x: me.left + labelOpts.padding,
+                            y: me.top + labelOpts.padding,
+                            line: 0
+                        };
+                    }
+
+                    var itemHeight = fontSize + labelOpts.padding;
+                    helpers.each(me.legendItems, function(legendItem, i) {
+                        var textWidth = ctx.measureText(legendItem.text).width,
+                            width = boxWidth + (fontSize / 2) + textWidth,
+                            x = cursor.x,
+                            y = cursor.y;
+
+                        if (isHorizontal) {
+                            if (x + width >= legendWidth) {
+                                y = cursor.y += itemHeight;
+                                cursor.line++;
+                                x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
+                            }
+                        } else if (y + itemHeight > me.bottom) {
+                            x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
+                            y = cursor.y = me.top + labelOpts.padding;
+                            cursor.line++;
+                        }
+
+                        drawLegendBox(x, y, legendItem);
+
+                        hitboxes[i].left = x;
+                        hitboxes[i].top = y;
+
+                        // Fill the actual label
+                        fillText(x, y, legendItem, textWidth);
+
+                        if (isHorizontal) {
+                            cursor.x += width + (labelOpts.padding);
+                        } else {
+                            cursor.y += itemHeight;
+                        }
+
+                    });
+                }
+            },
+
+            /**
+             * Handle an event
+             * @private
+             * @param {IEvent} event - The event to handle
+             * @return {Boolean} true if a change occured
+             */
+            handleEvent: function(e) {
+                var me = this;
+                var opts = me.options;
+                var type = e.type === 'mouseup' ? 'click' : e.type;
+                var changed = false;
+
+                if (type === 'mousemove') {
+                    if (!opts.onHover) {
+                        return;
+                    }
+                } else if (type === 'click') {
+                    if (!opts.onClick) {
+                        return;
+                    }
+                } else {
+                    return;
+                }
+
+                // Chart event already has relative position in it
+                var x = e.x,
+                    y = e.y;
+
+                if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
+                    // See if we are touching one of the dataset boxes
+                    var lh = me.legendHitBoxes;
+                    for (var i = 0; i < lh.length; ++i) {
+                        var hitBox = lh[i];
+
+                        if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
+                            // Touching an element
+                            if (type === 'click') {
+                                // use e.native for backwards compatibility
+                                opts.onClick.call(me, e.native, me.legendItems[i]);
+                                changed = true;
+                                break;
+                            } else if (type === 'mousemove') {
+                                // use e.native for backwards compatibility
+                                opts.onHover.call(me, e.native, me.legendItems[i]);
+                                changed = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                return changed;
+            }
+        });
+
+        function createNewLegendAndAttach(chart, legendOpts) {
+            var legend = new Chart.Legend({
+                ctx: chart.ctx,
+                options: legendOpts,
+                chart: chart
+            });
+
+            layout.configure(chart, legend, legendOpts);
+            layout.addBox(chart, legend);
+            chart.legend = legend;
+        }
+
+        return {
+            id: 'legend',
+
+            beforeInit: function(chart) {
+                var legendOpts = chart.options.legend;
+
+                if (legendOpts) {
+                    createNewLegendAndAttach(chart, legendOpts);
+                }
+            },
+
+            beforeUpdate: function(chart) {
+                var legendOpts = chart.options.legend;
+                var legend = chart.legend;
+
+                if (legendOpts) {
+                    legendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);
+
+                    if (legend) {
+                        layout.configure(chart, legend, legendOpts);
+                        legend.options = legendOpts;
+                    } else {
+                        createNewLegendAndAttach(chart, legendOpts);
+                    }
+                } else if (legend) {
+                    layout.removeBox(chart, legend);
+                    delete chart.legend;
+                }
+            },
+
+            afterEvent: function(chart, e) {
+                var legend = chart.legend;
+                if (legend) {
+                    legend.handleEvent(e);
+                }
+            }
+        };
+    };
+
 },{}],43:[function(require,module,exports){
-"use strict";
+    'use strict';
 
-module.exports = function(Chart) {
+    module.exports = function(Chart) {
 
-	var helpers = Chart.helpers;
-	var globalDefaults = Chart.defaults.global;
+        var helpers = Chart.helpers;
+        var layout = Chart.layoutService;
+        var noop = helpers.noop;
 
-	var defaultConfig = {
-		display: true,
+        Chart.defaults.global.title = {
+            display: false,
+            position: 'top',
+            fullWidth: true,
+            weight: 2000,        // by default greater than legend (1000) to be above
+            fontStyle: 'bold',
+            padding: 10,
 
-		//Boolean - Whether to animate scaling the chart from the centre
-		animate: true,
-		lineArc: false,
-		position: "chartArea",
+            // actual title
+            text: ''
+        };
 
-		angleLines: {
-			display: true,
-			color: "rgba(0, 0, 0, 0.1)",
-			lineWidth: 1
-		},
+        Chart.Title = Chart.Element.extend({
+            initialize: function(config) {
+                var me = this;
+                helpers.extend(me, config);
 
-		// label settings
-		ticks: {
-			//Boolean - Show a backdrop to the scale label
-			showLabelBackdrop: true,
+                // Contains hit boxes for each dataset (in dataset order)
+                me.legendHitBoxes = [];
+            },
 
-			//String - The colour of the label backdrop
-			backdropColor: "rgba(255,255,255,0.75)",
+            // These methods are ordered by lifecycle. Utilities then follow.
 
-			//Number - The backdrop padding above & below the label in pixels
-			backdropPaddingY: 2,
+            beforeUpdate: noop,
+            update: function(maxWidth, maxHeight, margins) {
+                var me = this;
 
-			//Number - The backdrop padding to the side of the label in pixels
-			backdropPaddingX: 2
-		},
+                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
+                me.beforeUpdate();
 
-		pointLabels: {
-			//Number - Point label font size in pixels
-			fontSize: 10,
+                // Absorb the master measurements
+                me.maxWidth = maxWidth;
+                me.maxHeight = maxHeight;
+                me.margins = margins;
 
-			//Function - Used to convert point labels
-			callback: function(label) {
-				return label;
-			}
-		}
-	};
+                // Dimensions
+                me.beforeSetDimensions();
+                me.setDimensions();
+                me.afterSetDimensions();
+                // Labels
+                me.beforeBuildLabels();
+                me.buildLabels();
+                me.afterBuildLabels();
 
-	var LinearRadialScale = Chart.LinearScaleBase.extend({
-		getValueCount: function() {
-			return this.chart.data.labels.length;
-		},
-		setDimensions: function() {
-			var me = this;
-			var opts = me.options;
-			var tickOpts = opts.ticks;
-			// Set the unconstrained dimension before label rotation
-			me.width = me.maxWidth;
-			me.height = me.maxHeight;
-			me.xCenter = Math.round(me.width / 2);
-			me.yCenter = Math.round(me.height / 2);
+                // Fit
+                me.beforeFit();
+                me.fit();
+                me.afterFit();
+                //
+                me.afterUpdate();
 
-			var minSize = helpers.min([me.height, me.width]);
-			var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-			me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
-		},
-		determineDataLimits: function() {
-			var me = this;
-			var chart = me.chart;
-			me.min = null;
-			me.max = null;
+                return me.minSize;
 
+            },
+            afterUpdate: noop,
 
-			helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
-				if (chart.isDatasetVisible(datasetIndex)) {
-					var meta = chart.getDatasetMeta(datasetIndex);
+            //
 
-					helpers.each(dataset.data, function(rawValue, index) {
-						var value = +me.getRightValue(rawValue);
-						if (isNaN(value) || meta.data[index].hidden) {
-							return;
-						}
+            beforeSetDimensions: noop,
+            setDimensions: function() {
+                var me = this;
+                // Set the unconstrained dimension before label rotation
+                if (me.isHorizontal()) {
+                    // Reset position before calculating rotation
+                    me.width = me.maxWidth;
+                    me.left = 0;
+                    me.right = me.width;
+                } else {
+                    me.height = me.maxHeight;
 
-						if (me.min === null) {
-							me.min = value;
-						} else if (value < me.min) {
-							me.min = value;
-						}
+                    // Reset position before calculating rotation
+                    me.top = 0;
+                    me.bottom = me.height;
+                }
 
-						if (me.max === null) {
-							me.max = value;
-						} else if (value > me.max) {
-							me.max = value;
-						}
-					});
-				}
-			});
+                // Reset padding
+                me.paddingLeft = 0;
+                me.paddingTop = 0;
+                me.paddingRight = 0;
+                me.paddingBottom = 0;
 
-			// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
-			me.handleTickRangeOptions();
-		},
-		getTickLimit: function() {
-			var tickOpts = this.options.ticks;
-			var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-			return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
+                // Reset minSize
+                me.minSize = {
+                    width: 0,
+                    height: 0
+                };
+            },
+            afterSetDimensions: noop,
 
-			// Point labels
-			me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
-		},
-		getLabelForIndex: function(index, datasetIndex) {
-			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
-		},
-		fit: function() {
-			/*
-			 * Right, this is really confusing and there is a lot of maths going on here
-			 * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
-			 *
-			 * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
-			 *
-			 * Solution:
-			 *
-			 * We assume the radius of the polygon is half the size of the canvas at first
-			 * at each index we check if the text overlaps.
-			 *
-			 * Where it does, we store that angle and that index.
-			 *
-			 * After finding the largest index and angle we calculate how much we need to remove
-			 * from the shape radius to move the point inwards by that x.
-			 *
-			 * We average the left and right distances to get the maximum shape radius that can fit in the box
-			 * along with labels.
-			 *
-			 * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
-			 * on each side, removing that from the size, halving it and adding the left x protrusion width.
-			 *
-			 * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
-			 * and position it in the most space efficient manner
-			 *
-			 * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
-			 */
+            //
 
-			var pointLabels = this.options.pointLabels;
-			var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize);
-			var pointLabeFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle);
-			var pointLabeFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily);
-			var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
+            beforeBuildLabels: noop,
+            buildLabels: noop,
+            afterBuildLabels: noop,
 
-			// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
-			// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
-			var largestPossibleRadius = helpers.min([(this.height / 2 - pointLabelFontSize - 5), this.width / 2]),
-				pointPosition,
-				i,
-				textWidth,
-				halfTextWidth,
-				furthestRight = this.width,
-				furthestRightIndex,
-				furthestRightAngle,
-				furthestLeft = 0,
-				furthestLeftIndex,
-				furthestLeftAngle,
-				xProtrusionLeft,
-				xProtrusionRight,
-				radiusReductionRight,
-				radiusReductionLeft;
-			this.ctx.font = pointLabeFont;
+            //
 
-			for (i = 0; i < this.getValueCount(); i++) {
-				// 5px to space the text slightly out - similar to what we do in the draw function.
-				pointPosition = this.getPointPosition(i, largestPossibleRadius);
-				textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5;
+            beforeFit: noop,
+            fit: function() {
+                var me = this,
+                    valueOrDefault = helpers.getValueOrDefault,
+                    opts = me.options,
+                    globalDefaults = Chart.defaults.global,
+                    display = opts.display,
+                    fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
+                    minSize = me.minSize;
 
-				// Add quarter circle to make degree 0 mean top of circle
-				var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
-				var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
+                if (me.isHorizontal()) {
+                    minSize.width = me.maxWidth; // fill all the width
+                    minSize.height = display ? fontSize + (opts.padding * 2) : 0;
+                } else {
+                    minSize.width = display ? fontSize + (opts.padding * 2) : 0;
+                    minSize.height = me.maxHeight; // fill all the height
+                }
 
-				if (angle === 0 || angle === 180) {
-					// At angle 0 and 180, we're at exactly the top/bottom
-					// of the radar chart, so text will be aligned centrally, so we'll half it and compare
-					// w/left and right text sizes
-					halfTextWidth = textWidth / 2;
-					if (pointPosition.x + halfTextWidth > furthestRight) {
-						furthestRight = pointPosition.x + halfTextWidth;
-						furthestRightIndex = i;
-					}
-					if (pointPosition.x - halfTextWidth < furthestLeft) {
-						furthestLeft = pointPosition.x - halfTextWidth;
-						furthestLeftIndex = i;
-					}
-				} else if (angle < 180) {
-					// Less than half the values means we'll left align the text
-					if (pointPosition.x + textWidth > furthestRight) {
-						furthestRight = pointPosition.x + textWidth;
-						furthestRightIndex = i;
-					}
-				} else {
-					// More than half the values means we'll right align the text
-					if (pointPosition.x - textWidth < furthestLeft) {
-						furthestLeft = pointPosition.x - textWidth;
-						furthestLeftIndex = i;
-					}
-				}
-			}
+                me.width = minSize.width;
+                me.height = minSize.height;
 
-			xProtrusionLeft = furthestLeft;
-			xProtrusionRight = Math.ceil(furthestRight - this.width);
+            },
+            afterFit: noop,
 
-			furthestRightAngle = this.getIndexAngle(furthestRightIndex);
-			furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
+            // Shared Methods
+            isHorizontal: function() {
+                var pos = this.options.position;
+                return pos === 'top' || pos === 'bottom';
+            },
 
-			radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2);
-			radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2);
+            // Actually draw the title block on the canvas
+            draw: function() {
+                var me = this,
+                    ctx = me.ctx,
+                    valueOrDefault = helpers.getValueOrDefault,
+                    opts = me.options,
+                    globalDefaults = Chart.defaults.global;
 
-			// Ensure we actually need to reduce the size of the chart
-			radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
-			radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
+                if (opts.display) {
+                    var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),
+                        fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),
+                        fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),
+                        titleFont = helpers.fontString(fontSize, fontStyle, fontFamily),
+                        rotation = 0,
+                        titleX,
+                        titleY,
+                        top = me.top,
+                        left = me.left,
+                        bottom = me.bottom,
+                        right = me.right,
+                        maxWidth;
 
-			this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2);
-			this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
-		},
-		setCenterPoint: function(leftMovement, rightMovement) {
-			var me = this;
-			var maxRight = me.width - rightMovement - me.drawingArea,
-				maxLeft = leftMovement + me.drawingArea;
+                    ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
+                    ctx.font = titleFont;
 
-			me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
-			// Always vertically in the centre as the text height doesn't change
-			me.yCenter = Math.round((me.height / 2) + me.top);
-		},
+                    // Horizontal
+                    if (me.isHorizontal()) {
+                        titleX = left + ((right - left) / 2); // midpoint of the width
+                        titleY = top + ((bottom - top) / 2); // midpoint of the height
+                        maxWidth = right - left;
+                    } else {
+                        titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);
+                        titleY = top + ((bottom - top) / 2);
+                        maxWidth = bottom - top;
+                        rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
+                    }
 
-		getIndexAngle: function(index) {
-			var angleMultiplier = (Math.PI * 2) / this.getValueCount();
-			var startAngle = this.chart.options && this.chart.options.startAngle ?
-				this.chart.options.startAngle :
-				0;
+                    ctx.save();
+                    ctx.translate(titleX, titleY);
+                    ctx.rotate(rotation);
+                    ctx.textAlign = 'center';
+                    ctx.textBaseline = 'middle';
+                    ctx.fillText(opts.text, 0, 0, maxWidth);
+                    ctx.restore();
+                }
+            }
+        });
 
-			var startAngleRadians = startAngle * Math.PI * 2 / 360;
+        function createNewTitleBlockAndAttach(chart, titleOpts) {
+            var title = new Chart.Title({
+                ctx: chart.ctx,
+                options: titleOpts,
+                chart: chart
+            });
 
-			// Start from the top instead of right, so remove a quarter of the circle
-			return index * angleMultiplier - (Math.PI / 2) + startAngleRadians;
-		},
-		getDistanceFromCenterForValue: function(value) {
-			var me = this;
+            layout.configure(chart, title, titleOpts);
+            layout.addBox(chart, title);
+            chart.titleBlock = title;
+        }
 
-			if (value === null) {
-				return 0; // null always in center
-			}
+        return {
+            id: 'title',
 
-			// Take into account half font size + the yPadding of the top value
-			var scalingFactor = me.drawingArea / (me.max - me.min);
-			if (me.options.reverse) {
-				return (me.max - value) * scalingFactor;
-			} else {
-				return (value - me.min) * scalingFactor;
-			}
-		},
-		getPointPosition: function(index, distanceFromCenter) {
-			var me = this;
-			var thisAngle = me.getIndexAngle(index);
-			return {
-				x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
-				y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
-			};
-		},
-		getPointPositionForValue: function(index, value) {
-			return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
-		},
+            beforeInit: function(chart) {
+                var titleOpts = chart.options.title;
 
-		getBasePosition: function() {
-			var me = this;
-			var min = me.min;
-			var max = me.max;
+                if (titleOpts) {
+                    createNewTitleBlockAndAttach(chart, titleOpts);
+                }
+            },
 
-			return me.getPointPositionForValue(0,
-				me.beginAtZero? 0:
-				min < 0 && max < 0? max :
-				min > 0 && max > 0? min :
-				0);
-		},
+            beforeUpdate: function(chart) {
+                var titleOpts = chart.options.title;
+                var titleBlock = chart.titleBlock;
 
-		draw: function() {
-			var me = this;
-			var opts = me.options;
-			var gridLineOpts = opts.gridLines;
-			var tickOpts = opts.ticks;
-			var angleLineOpts = opts.angleLines;
-			var pointLabelOpts = opts.pointLabels;
-			var getValueOrDefault = helpers.getValueOrDefault;
+                if (titleOpts) {
+                    titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);
 
-			if (opts.display) {
-				var ctx = me.ctx;
-
-				// Tick Font
-				var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
-				var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
-				var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
-				var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-
-				helpers.each(me.ticks, function(label, index) {
-					// Don't draw a centre value (if it is minimum)
-					if (index > 0 || opts.reverse) {
-						var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
-						var yHeight = me.yCenter - yCenterOffset;
-
-						// Draw circular lines around the scale
-						if (gridLineOpts.display && index !== 0) {
-							ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);
-							ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
-
-							if (opts.lineArc) {
-								// Draw circular arcs between the points
-								ctx.beginPath();
-								ctx.arc(me.xCenter, me.yCenter, yCenterOffset, 0, Math.PI * 2);
-								ctx.closePath();
-								ctx.stroke();
-							} else {
-								// Draw straight lines connecting each index
-								ctx.beginPath();
-								for (var i = 0; i < me.getValueCount(); i++) {
-									var pointPosition = me.getPointPosition(i, yCenterOffset);
-									if (i === 0) {
-										ctx.moveTo(pointPosition.x, pointPosition.y);
-									} else {
-										ctx.lineTo(pointPosition.x, pointPosition.y);
-									}
-								}
-								ctx.closePath();
-								ctx.stroke();
-							}
-						}
-
-						if (tickOpts.display) {
-							var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
-							ctx.font = tickLabelFont;
-
-							if (tickOpts.showLabelBackdrop) {
-								var labelWidth = ctx.measureText(label).width;
-								ctx.fillStyle = tickOpts.backdropColor;
-								ctx.fillRect(
-									me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,
-									yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,
-									labelWidth + tickOpts.backdropPaddingX * 2,
-									tickFontSize + tickOpts.backdropPaddingY * 2
-								);
-							}
-
-							ctx.textAlign = 'center';
-							ctx.textBaseline = "middle";
-							ctx.fillStyle = tickFontColor;
-							ctx.fillText(label, me.xCenter, yHeight);
-						}
-					}
-				});
-
-				if (!opts.lineArc) {
-					ctx.lineWidth = angleLineOpts.lineWidth;
-					ctx.strokeStyle = angleLineOpts.color;
-
-					var outerDistance = me.getDistanceFromCenterForValue(opts.reverse ? me.min : me.max);
-
-					// Point Label Font
-					var pointLabelFontSize = getValueOrDefault(pointLabelOpts.fontSize, globalDefaults.defaultFontSize);
-					var pointLabeFontStyle = getValueOrDefault(pointLabelOpts.fontStyle, globalDefaults.defaultFontStyle);
-					var pointLabeFontFamily = getValueOrDefault(pointLabelOpts.fontFamily, globalDefaults.defaultFontFamily);
-					var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
-
-					for (var i = me.getValueCount() - 1; i >= 0; i--) {
-						if (angleLineOpts.display) {
-							var outerPosition = me.getPointPosition(i, outerDistance);
-							ctx.beginPath();
-							ctx.moveTo(me.xCenter, me.yCenter);
-							ctx.lineTo(outerPosition.x, outerPosition.y);
-							ctx.stroke();
-							ctx.closePath();
-						}
-						// Extra 3px out for some label spacing
-						var pointLabelPosition = me.getPointPosition(i, outerDistance + 5);
-
-						// Keep this in loop since we may support array properties here
-						var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);
-						ctx.font = pointLabeFont;
-						ctx.fillStyle = pointLabelFontColor;
-
-						var pointLabels = me.pointLabels;
-
-						// Add quarter circle to make degree 0 mean top of circle
-						var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
-						var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
-
-						if (angle === 0 || angle === 180) {
-							ctx.textAlign = 'center';
-						} else if (angle < 180) {
-							ctx.textAlign = 'left';
-						} else {
-							ctx.textAlign = 'right';
-						}
-
-						// Set the correct text baseline based on outer positioning
-						if (angle === 90 || angle === 270) {
-							ctx.textBaseline = 'middle';
-						} else if (angle > 270 || angle < 90) {
-							ctx.textBaseline = 'bottom';
-						} else {
-							ctx.textBaseline = 'top';
-						}
-
-						ctx.fillText(pointLabels[i] ? pointLabels[i] : '', pointLabelPosition.x, pointLabelPosition.y);
-					}
-				}
-			}
-		}
-	});
-	Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);
-
-};
+                    if (titleBlock) {
+                        layout.configure(chart, titleBlock, titleOpts);
+                        titleBlock.options = titleOpts;
+                    } else {
+                        createNewTitleBlockAndAttach(chart, titleOpts);
+                    }
+                } else if (titleBlock) {
+                    Chart.layoutService.removeBox(chart, titleBlock);
+                    delete chart.titleBlock;
+                }
+            }
+        };
+    };
 
 },{}],44:[function(require,module,exports){
-/*global window: false */
-"use strict";
+    'use strict';
 
-var moment = require(1);
-moment = typeof(moment) === 'function' ? moment : window.moment;
+    module.exports = function(Chart) {
 
-module.exports = function(Chart) {
+        var helpers = Chart.helpers;
+        // Default config for a category scale
+        var defaultConfig = {
+            position: 'bottom'
+        };
 
-	var helpers = Chart.helpers;
-	var time = {
-		units: [{
-			name: 'millisecond',
-			steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
-		}, {
-			name: 'second',
-			steps: [1, 2, 5, 10, 30]
-		}, {
-			name: 'minute',
-			steps: [1, 2, 5, 10, 30]
-		}, {
-			name: 'hour',
-			steps: [1, 2, 3, 6, 12]
-		}, {
-			name: 'day',
-			steps: [1, 2, 5]
-		}, {
-			name: 'week',
-			maxStep: 4
-		}, {
-			name: 'month',
-			maxStep: 3
-		}, {
-			name: 'quarter',
-			maxStep: 4
-		}, {
-			name: 'year',
-			maxStep: false
-		}]
-	};
+        var DatasetScale = Chart.Scale.extend({
+            /**
+             * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those
+             * else fall back to data.labels
+             * @private
+             */
+            getLabels: function() {
+                var data = this.chart.data;
+                return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
+            },
 
-	var defaultConfig = {
-		position: "bottom",
+            determineDataLimits: function() {
+                var me = this;
+                var labels = me.getLabels();
+                me.minIndex = 0;
+                me.maxIndex = labels.length - 1;
+                var findIndex;
 
-		time: {
-			parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
-			format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
-			unit: false, // false == automatic or override with week, month, year, etc.
-			round: false, // none, or override with week, month, year, etc.
-			displayFormat: false, // DEPRECATED
-			isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
+                if (me.options.ticks.min !== undefined) {
+                    // user specified min value
+                    findIndex = helpers.indexOf(labels, me.options.ticks.min);
+                    me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
+                }
 
-			// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
-			displayFormats: {
-				'millisecond': 'h:mm:ss.SSS a', // 11:20:01.123 AM,
-				'second': 'h:mm:ss a', // 11:20:01 AM
-				'minute': 'h:mm:ss a', // 11:20:01 AM
-				'hour': 'MMM D, hA', // Sept 4, 5PM
-				'day': 'll', // Sep 4 2015
-				'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
-				'month': 'MMM YYYY', // Sept 2015
-				'quarter': '[Q]Q - YYYY', // Q3
-				'year': 'YYYY' // 2015
-			}
-		},
-		ticks: {
-			autoSkip: false
-		}
-	};
+                if (me.options.ticks.max !== undefined) {
+                    // user specified max value
+                    findIndex = helpers.indexOf(labels, me.options.ticks.max);
+                    me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
+                }
 
-	var TimeScale = Chart.Scale.extend({
-		initialize: function() {
-			if (!moment) {
-				throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');
-			}
+                me.min = labels[me.minIndex];
+                me.max = labels[me.maxIndex];
+            },
 
-			Chart.Scale.prototype.initialize.call(this);
-		},
-		getLabelMoment: function(datasetIndex, index) {
-			if (typeof this.labelMoments[datasetIndex] != 'undefined') {
-				return this.labelMoments[datasetIndex][index];
-			}
+            buildTicks: function() {
+                var me = this;
+                var labels = me.getLabels();
+                // If we are viewing some subset of labels, slice the original array
+                me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
+            },
 
-			return null;
-		},
-		getMomentStartOf: function(tick) {
-			var me = this;
-			if (me.options.time.unit === 'week' && me.options.time.isoWeekday !== false) {
-				return tick.clone().startOf('isoWeek').isoWeekday(me.options.time.isoWeekday);
-			} else {
-				return tick.clone().startOf(me.tickUnit);
-			}
-		},
-		determineDataLimits: function() {
-			var me = this;
-			me.labelMoments = [];
+            getLabelForIndex: function(index, datasetIndex) {
+                var me = this;
+                var data = me.chart.data;
+                var isHorizontal = me.isHorizontal();
 
-			// Only parse these once. If the dataset does not have data as x,y pairs, we will use
-			// these
-			var scaleLabelMoments = [];
-			if (me.chart.data.labels && me.chart.data.labels.length > 0) {
-				helpers.each(me.chart.data.labels, function(label) {
-					var labelMoment = me.parseTime(label);
+                if (data.yLabels && !isHorizontal) {
+                    return me.getRightValue(data.datasets[datasetIndex].data[index]);
+                }
+                return me.ticks[index - me.minIndex];
+            },
 
-					if (labelMoment.isValid()) {
-						if (me.options.time.round) {
-							labelMoment.startOf(me.options.time.round);
-						}
-						scaleLabelMoments.push(labelMoment);
-					}
-				}, me);
+            // Used to get data value locations.  Value can either be an index or a numerical value
+            getPixelForValue: function(value, index, datasetIndex, includeOffset) {
+                var me = this;
+                // 1 is added because we need the length but we have the indexes
+                var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
 
-				me.firstTick = moment.min.call(me, scaleLabelMoments);
-				me.lastTick = moment.max.call(me, scaleLabelMoments);
-			} else {
-				me.firstTick = null;
-				me.lastTick = null;
-			}
+                // If value is a data object, then index is the index in the data array,
+                // not the index of the scale. We need to change that.
+                var valueCategory;
+                if (value !== undefined && value !== null) {
+                    valueCategory = me.isHorizontal() ? value.x : value.y;
+                }
+                if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
+                    var labels = me.getLabels();
+                    value = valueCategory || value;
+                    var idx = labels.indexOf(value);
+                    index = idx !== -1 ? idx : index;
+                }
 
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				var momentsForDataset = [];
-				var datasetVisible = me.chart.isDatasetVisible(datasetIndex);
+                if (me.isHorizontal()) {
+                    var valueWidth = me.width / offsetAmt;
+                    var widthOffset = (valueWidth * (index - me.minIndex));
 
-				if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null) {
-					helpers.each(dataset.data, function(value) {
-						var labelMoment = me.parseTime(me.getRightValue(value));
+                    if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {
+                        widthOffset += (valueWidth / 2);
+                    }
 
-						if (labelMoment.isValid()) {
-							if (me.options.time.round) {
-								labelMoment.startOf(me.options.time.round);
-							}
-							momentsForDataset.push(labelMoment);
+                    return me.left + Math.round(widthOffset);
+                }
+                var valueHeight = me.height / offsetAmt;
+                var heightOffset = (valueHeight * (index - me.minIndex));
 
-							if (datasetVisible) {
-								// May have gone outside the scale ranges, make sure we keep the first and last ticks updated
-								me.firstTick = me.firstTick !== null ? moment.min(me.firstTick, labelMoment) : labelMoment;
-								me.lastTick = me.lastTick !== null ? moment.max(me.lastTick, labelMoment) : labelMoment;
-							}
-						}
-					}, me);
-				} else {
-					// We have no labels. Use the ones from the scale
-					momentsForDataset = scaleLabelMoments;
-				}
+                if (me.options.gridLines.offsetGridLines && includeOffset) {
+                    heightOffset += (valueHeight / 2);
+                }
 
-				me.labelMoments.push(momentsForDataset);
-			}, me);
+                return me.top + Math.round(heightOffset);
+            },
+            getPixelForTick: function(index, includeOffset) {
+                return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);
+            },
+            getValueForPixel: function(pixel) {
+                var me = this;
+                var value;
+                var offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
+                var horz = me.isHorizontal();
+                var valueDimension = (horz ? me.width : me.height) / offsetAmt;
 
-			// Set these after we've done all the data
-			if (me.options.time.min) {
-				me.firstTick = me.parseTime(me.options.time.min);
-			}
+                pixel -= horz ? me.left : me.top;
 
-			if (me.options.time.max) {
-				me.lastTick = me.parseTime(me.options.time.max);
-			}
+                if (me.options.gridLines.offsetGridLines) {
+                    pixel -= (valueDimension / 2);
+                }
 
-			// We will modify these, so clone for later
-			me.firstTick = (me.firstTick || moment()).clone();
-			me.lastTick = (me.lastTick || moment()).clone();
-		},
-		buildTicks: function() {
-			var me = this;
+                if (pixel <= 0) {
+                    value = 0;
+                } else {
+                    value = Math.round(pixel / valueDimension);
+                }
 
-			me.ctx.save();
-			var tickFontSize = helpers.getValueOrDefault(me.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
-			var tickFontStyle = helpers.getValueOrDefault(me.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
-			var tickFontFamily = helpers.getValueOrDefault(me.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
-			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
-			me.ctx.font = tickLabelFont;
+                return value;
+            },
+            getBasePixel: function() {
+                return this.bottom;
+            }
+        });
 
-			me.ticks = [];
-			me.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step
-			me.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)
+        Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
 
-			// Set unit override if applicable
-			if (me.options.time.unit) {
-				me.tickUnit = me.options.time.unit || 'day';
-				me.displayFormat = me.options.time.displayFormats[me.tickUnit];
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, 1);
-			} else {
-				// Determine the smallest needed unit of the time
-				var innerWidth = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
+    };
 
-				// Crude approximation of what the label length might be
-				var tempFirstLabel = me.tickFormatFunction(me.firstTick, 0, []);
-				var tickLabelWidth = me.ctx.measureText(tempFirstLabel).width;
-				var cosRotation = Math.cos(helpers.toRadians(me.options.ticks.maxRotation));
-				var sinRotation = Math.sin(helpers.toRadians(me.options.ticks.maxRotation));
-				tickLabelWidth = (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
-				var labelCapacity = innerWidth / (tickLabelWidth);
+},{}],45:[function(require,module,exports){
+    'use strict';
 
-				// Start as small as possible
-				me.tickUnit = 'millisecond';
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				me.displayFormat = me.options.time.displayFormats[me.tickUnit];
+    module.exports = function(Chart) {
 
-				var unitDefinitionIndex = 0;
-				var unitDefinition = time.units[unitDefinitionIndex];
+        var helpers = Chart.helpers;
 
-				// While we aren't ideal and we don't have units left
-				while (unitDefinitionIndex < time.units.length) {
-					// Can we scale this unit. If `false` we can scale infinitely
-					me.unitScale = 1;
+        var defaultConfig = {
+            position: 'left',
+            ticks: {
+                callback: Chart.Ticks.formatters.linear
+            }
+        };
 
-					if (helpers.isArray(unitDefinition.steps) && Math.ceil(me.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {
-						// Use one of the prefedined steps
-						for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {
-							if (unitDefinition.steps[idx] >= Math.ceil(me.scaleSizeInUnits / labelCapacity)) {
-								me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, unitDefinition.steps[idx]);
-								break;
-							}
-						}
+        var LinearScale = Chart.LinearScaleBase.extend({
 
-						break;
-					} else if ((unitDefinition.maxStep === false) || (Math.ceil(me.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep)) {
-						// We have a max step. Scale this unit
-						me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, Math.ceil(me.scaleSizeInUnits / labelCapacity));
-						break;
-					} else {
-						// Move to the next unit up
-						++unitDefinitionIndex;
-						unitDefinition = time.units[unitDefinitionIndex];
+            determineDataLimits: function() {
+                var me = this;
+                var opts = me.options;
+                var chart = me.chart;
+                var data = chart.data;
+                var datasets = data.datasets;
+                var isHorizontal = me.isHorizontal();
+                var DEFAULT_MIN = 0;
+                var DEFAULT_MAX = 1;
 
-						me.tickUnit = unitDefinition.name;
-						var leadingUnitBuffer = me.firstTick.diff(me.getMomentStartOf(me.firstTick), me.tickUnit, true);
-						var trailingUnitBuffer = me.getMomentStartOf(me.lastTick.clone().add(1, me.tickUnit)).diff(me.lastTick, me.tickUnit, true);
-						me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer;
-						me.displayFormat = me.options.time.displayFormats[unitDefinition.name];
-					}
-				}
-			}
+                function IDMatches(meta) {
+                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+                }
 
-			var roundedStart;
+                // First Calculate the range
+                me.min = null;
+                me.max = null;
 
-			// Only round the first tick if we have no hard minimum
-			if (!me.options.time.min) {
-				me.firstTick = me.getMomentStartOf(me.firstTick);
-				roundedStart = me.firstTick;
-			} else {
-				roundedStart = me.getMomentStartOf(me.firstTick);
-			}
+                var hasStacks = opts.stacked;
+                if (hasStacks === undefined) {
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        if (hasStacks) {
+                            return;
+                        }
 
-			// Only round the last tick if we have no hard maximum
-			if (!me.options.time.max) {
-				var roundedEnd = me.getMomentStartOf(me.lastTick);
-				var delta = roundedEnd.diff(me.lastTick, me.tickUnit, true);
-				if (delta < 0) {
-					// Do not use end of because we need me to be in the next time unit
-					me.lastTick = me.getMomentStartOf(me.lastTick.add(1, me.tickUnit));
-				} else if (delta >= 0) {
-					me.lastTick = roundedEnd;
-				}
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+                            meta.stack !== undefined) {
+                            hasStacks = true;
+                        }
+                    });
+                }
 
-				me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-			}
+                if (opts.stacked || hasStacks) {
+                    var valuesPerStack = {};
 
-			me.smallestLabelSeparation = me.width;
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        var key = [
+                            meta.type,
+                            // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+                            ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+                            meta.stack
+                        ].join('.');
 
-			helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
-				for (var i = 1; i < me.labelMoments[datasetIndex].length; i++) {
-					me.smallestLabelSeparation = Math.min(me.smallestLabelSeparation, me.labelMoments[datasetIndex][i].diff(me.labelMoments[datasetIndex][i - 1], me.tickUnit, true));
-				}
-			}, me);
+                        if (valuesPerStack[key] === undefined) {
+                            valuesPerStack[key] = {
+                                positiveValues: [],
+                                negativeValues: []
+                            };
+                        }
 
-			// Tick displayFormat override
-			if (me.options.time.displayFormat) {
-				me.displayFormat = me.options.time.displayFormat;
-			}
+                        // Store these per type
+                        var positiveValues = valuesPerStack[key].positiveValues;
+                        var negativeValues = valuesPerStack[key].negativeValues;
 
-			// first tick. will have been rounded correctly if options.time.min is not specified
-			me.ticks.push(me.firstTick.clone());
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+                            helpers.each(dataset.data, function(rawValue, index) {
+                                var value = +me.getRightValue(rawValue);
+                                if (isNaN(value) || meta.data[index].hidden) {
+                                    return;
+                                }
 
-			// For every unit in between the first and last moment, create a moment and add it to the ticks tick
-			for (var i = 1; i <= me.scaleSizeInUnits; ++i) {
-				var newTick = roundedStart.clone().add(i, me.tickUnit);
+                                positiveValues[index] = positiveValues[index] || 0;
+                                negativeValues[index] = negativeValues[index] || 0;
 
-				// Are we greater than the max time
-				if (me.options.time.max && newTick.diff(me.lastTick, me.tickUnit, true) >= 0) {
-					break;
-				}
+                                if (opts.relativePoints) {
+                                    positiveValues[index] = 100;
+                                } else if (value < 0) {
+                                    negativeValues[index] += value;
+                                } else {
+                                    positiveValues[index] += value;
+                                }
+                            });
+                        }
+                    });
 
-				if (i % me.unitScale === 0) {
-					me.ticks.push(newTick);
-				}
-			}
+                    helpers.each(valuesPerStack, function(valuesForType) {
+                        var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
+                        var minVal = helpers.min(values);
+                        var maxVal = helpers.max(values);
+                        me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+                        me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+                    });
 
-			// Always show the right tick
-			var diff = me.ticks[me.ticks.length - 1].diff(me.lastTick, me.tickUnit);
-			if (diff !== 0 || me.scaleSizeInUnits === 0) {
-				// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
-				// but the last tick was not rounded.
-				if (me.options.time.max) {
-					me.ticks.push(me.lastTick.clone());
-					me.scaleSizeInUnits = me.lastTick.diff(me.ticks[0], me.tickUnit, true);
-				} else {
-					me.ticks.push(me.lastTick.clone());
-					me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
-				}
-			}
+                } else {
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+                            helpers.each(dataset.data, function(rawValue, index) {
+                                var value = +me.getRightValue(rawValue);
+                                if (isNaN(value) || meta.data[index].hidden) {
+                                    return;
+                                }
 
-			me.ctx.restore();
-		},
-		// Get tooltip label
-		getLabelForIndex: function(index, datasetIndex) {
-			var me = this;
-			var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';
+                                if (me.min === null) {
+                                    me.min = value;
+                                } else if (value < me.min) {
+                                    me.min = value;
+                                }
 
-			if (typeof me.chart.data.datasets[datasetIndex].data[0] === 'object') {
-				label = me.getRightValue(me.chart.data.datasets[datasetIndex].data[index]);
-			}
+                                if (me.max === null) {
+                                    me.max = value;
+                                } else if (value > me.max) {
+                                    me.max = value;
+                                }
+                            });
+                        }
+                    });
+                }
 
-			// Format nicely
-			if (me.options.time.tooltipFormat) {
-				label = me.parseTime(label).format(me.options.time.tooltipFormat);
-			}
+                me.min = isFinite(me.min) ? me.min : DEFAULT_MIN;
+                me.max = isFinite(me.max) ? me.max : DEFAULT_MAX;
 
-			return label;
-		},
-		// Function to format an individual tick mark
-		tickFormatFunction: function(tick, index, ticks) {
-			var formattedTick = tick.format(this.displayFormat);
-			var tickOpts = this.options.ticks;
-			var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);
+                // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+                this.handleTickRangeOptions();
+            },
+            getTickLimit: function() {
+                var maxTicks;
+                var me = this;
+                var tickOpts = me.options.ticks;
 
-			if (callback) {
-				return callback(formattedTick, index, ticks);
-			} else {
-				return formattedTick;
-			}
-		},
-		convertTicksToLabels: function() {
-			var me = this;
-			me.tickMoments = me.ticks;
-			me.ticks = me.ticks.map(me.tickFormatFunction, me);
-		},
-		getPixelForValue: function(value, index, datasetIndex) {
-			var me = this;
-			if (!value || !value.isValid) {
-				// not already a moment object
-				value = moment(me.getRightValue(value));
-			}
-			var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);
+                if (me.isHorizontal()) {
+                    maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
+                } else {
+                    // The factor of 2 used to scale the font size has been experimentally determined.
+                    var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);
+                    maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
+                }
 
-			if (labelMoment) {
-				var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);
+                return maxTicks;
+            },
+            // Called after the ticks are built. We need
+            handleDirectionalChanges: function() {
+                if (!this.isHorizontal()) {
+                    // We are in a vertical orientation. The top value is the highest. So reverse the array
+                    this.ticks.reverse();
+                }
+            },
+            getLabelForIndex: function(index, datasetIndex) {
+                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+            },
+            // Utils
+            getPixelForValue: function(value) {
+                // This must be called after fit has been run so that
+                // this.left, this.top, this.right, and this.bottom have been defined
+                var me = this;
+                var start = me.start;
 
-				var decimal = offset !== 0 ? offset / me.scaleSizeInUnits : offset;
+                var rightValue = +me.getRightValue(value);
+                var pixel;
+                var range = me.end - start;
 
-				if (me.isHorizontal()) {
-					var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
-					var valueOffset = (innerWidth * decimal) + me.paddingLeft;
+                if (me.isHorizontal()) {
+                    pixel = me.left + (me.width / range * (rightValue - start));
+                    return Math.round(pixel);
+                }
 
-					return me.left + Math.round(valueOffset);
-				} else {
-					var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
-					var heightOffset = (innerHeight * decimal) + me.paddingTop;
+                pixel = me.bottom - (me.height / range * (rightValue - start));
+                return Math.round(pixel);
+            },
+            getValueForPixel: function(pixel) {
+                var me = this;
+                var isHorizontal = me.isHorizontal();
+                var innerDimension = isHorizontal ? me.width : me.height;
+                var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;
+                return me.start + ((me.end - me.start) * offset);
+            },
+            getPixelForTick: function(index) {
+                return this.getPixelForValue(this.ticksAsNumbers[index]);
+            }
+        });
+        Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);
 
-					return me.top + Math.round(heightOffset);
-				}
-			}
-		},
-		getPixelForTick: function(index) {
-			return this.getPixelForValue(this.tickMoments[index], null, null);
-		},
-		getValueForPixel: function(pixel) {
-			var me = this;
-			var innerDimension = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
-			var offset = (pixel - (me.isHorizontal() ? me.left + me.paddingLeft : me.top + me.paddingTop)) / innerDimension;
-			offset *= me.scaleSizeInUnits;
-			return me.firstTick.clone().add(moment.duration(offset, me.tickUnit).asSeconds(), 'seconds');
-		},
-		parseTime: function(label) {
-			var me = this;
-			if (typeof me.options.time.parser === 'string') {
-				return moment(label, me.options.time.parser);
-			}
-			if (typeof me.options.time.parser === 'function') {
-				return me.options.time.parser(label);
-			}
-			// Date objects
-			if (typeof label.getMonth === 'function' || typeof label === 'number') {
-				return moment(label);
-			}
-			// Moment support
-			if (label.isValid && label.isValid()) {
-				return label;
-			}
-			// Custom parsing (return an instance of moment)
-			if (typeof me.options.time.format !== 'string' && me.options.time.format.call) {
-				console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale");
-				return me.options.time.format(label);
-			}
-			// Moment format parsing
-			return moment(label, me.options.time.format);
-		}
-	});
-	Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig);
+    };
 
-};
+},{}],46:[function(require,module,exports){
+    'use strict';
+
+    module.exports = function(Chart) {
+
+        var helpers = Chart.helpers,
+            noop = helpers.noop;
+
+        Chart.LinearScaleBase = Chart.Scale.extend({
+            handleTickRangeOptions: function() {
+                var me = this;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+
+                // If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
+                // do nothing since that would make the chart weird. If the user really wants a weird chart
+                // axis, they can manually override it
+                if (tickOpts.beginAtZero) {
+                    var minSign = helpers.sign(me.min);
+                    var maxSign = helpers.sign(me.max);
+
+                    if (minSign < 0 && maxSign < 0) {
+                        // move the top up to 0
+                        me.max = 0;
+                    } else if (minSign > 0 && maxSign > 0) {
+                        // move the bottom down to 0
+                        me.min = 0;
+                    }
+                }
+
+                if (tickOpts.min !== undefined) {
+                    me.min = tickOpts.min;
+                } else if (tickOpts.suggestedMin !== undefined) {
+                    if (me.min === null) {
+                        me.min = tickOpts.suggestedMin;
+                    } else {
+                        me.min = Math.min(me.min, tickOpts.suggestedMin);
+                    }
+                }
+
+                if (tickOpts.max !== undefined) {
+                    me.max = tickOpts.max;
+                } else if (tickOpts.suggestedMax !== undefined) {
+                    if (me.max === null) {
+                        me.max = tickOpts.suggestedMax;
+                    } else {
+                        me.max = Math.max(me.max, tickOpts.suggestedMax);
+                    }
+                }
+
+                if (me.min === me.max) {
+                    me.max++;
+
+                    if (!tickOpts.beginAtZero) {
+                        me.min--;
+                    }
+                }
+            },
+            getTickLimit: noop,
+            handleDirectionalChanges: noop,
+
+            buildTicks: function() {
+                var me = this;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+
+                // Figure out what the max number of ticks we can support it is based on the size of
+                // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
+                // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
+                // the graph. Make sure we always have at least 2 ticks
+                var maxTicks = me.getTickLimit();
+                maxTicks = Math.max(2, maxTicks);
+
+                var numericGeneratorOptions = {
+                    maxTicks: maxTicks,
+                    min: tickOpts.min,
+                    max: tickOpts.max,
+                    stepSize: helpers.getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
+                };
+                var ticks = me.ticks = Chart.Ticks.generators.linear(numericGeneratorOptions, me);
+
+                me.handleDirectionalChanges();
+
+                // At this point, we need to update our max and min given the tick values since we have expanded the
+                // range of the scale
+                me.max = helpers.max(ticks);
+                me.min = helpers.min(ticks);
+
+                if (tickOpts.reverse) {
+                    ticks.reverse();
+
+                    me.start = me.max;
+                    me.end = me.min;
+                } else {
+                    me.start = me.min;
+                    me.end = me.max;
+                }
+            },
+            convertTicksToLabels: function() {
+                var me = this;
+                me.ticksAsNumbers = me.ticks.slice();
+                me.zeroLineIndex = me.ticks.indexOf(0);
+
+                Chart.Scale.prototype.convertTicksToLabels.call(me);
+            }
+        });
+    };
+
+},{}],47:[function(require,module,exports){
+    'use strict';
+
+    module.exports = function(Chart) {
+
+        var helpers = Chart.helpers;
+
+        var defaultConfig = {
+            position: 'left',
+
+            // label settings
+            ticks: {
+                callback: Chart.Ticks.formatters.logarithmic
+            }
+        };
+
+        var LogarithmicScale = Chart.Scale.extend({
+            determineDataLimits: function() {
+                var me = this;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+                var chart = me.chart;
+                var data = chart.data;
+                var datasets = data.datasets;
+                var getValueOrDefault = helpers.getValueOrDefault;
+                var isHorizontal = me.isHorizontal();
+                function IDMatches(meta) {
+                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
+                }
+
+                // Calculate Range
+                me.min = null;
+                me.max = null;
+                me.minNotZero = null;
+
+                var hasStacks = opts.stacked;
+                if (hasStacks === undefined) {
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        if (hasStacks) {
+                            return;
+                        }
+
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
+                            meta.stack !== undefined) {
+                            hasStacks = true;
+                        }
+                    });
+                }
+
+                if (opts.stacked || hasStacks) {
+                    var valuesPerStack = {};
+
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        var key = [
+                            meta.type,
+                            // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
+                            ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
+                            meta.stack
+                        ].join('.');
+
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+                            if (valuesPerStack[key] === undefined) {
+                                valuesPerStack[key] = [];
+                            }
+
+                            helpers.each(dataset.data, function(rawValue, index) {
+                                var values = valuesPerStack[key];
+                                var value = +me.getRightValue(rawValue);
+                                if (isNaN(value) || meta.data[index].hidden) {
+                                    return;
+                                }
+
+                                values[index] = values[index] || 0;
+
+                                if (opts.relativePoints) {
+                                    values[index] = 100;
+                                } else {
+                                    // Don't need to split positive and negative since the log scale can't handle a 0 crossing
+                                    values[index] += value;
+                                }
+                            });
+                        }
+                    });
+
+                    helpers.each(valuesPerStack, function(valuesForType) {
+                        var minVal = helpers.min(valuesForType);
+                        var maxVal = helpers.max(valuesForType);
+                        me.min = me.min === null ? minVal : Math.min(me.min, minVal);
+                        me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
+                    });
+
+                } else {
+                    helpers.each(datasets, function(dataset, datasetIndex) {
+                        var meta = chart.getDatasetMeta(datasetIndex);
+                        if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
+                            helpers.each(dataset.data, function(rawValue, index) {
+                                var value = +me.getRightValue(rawValue);
+                                if (isNaN(value) || meta.data[index].hidden) {
+                                    return;
+                                }
+
+                                if (me.min === null) {
+                                    me.min = value;
+                                } else if (value < me.min) {
+                                    me.min = value;
+                                }
+
+                                if (me.max === null) {
+                                    me.max = value;
+                                } else if (value > me.max) {
+                                    me.max = value;
+                                }
+
+                                if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
+                                    me.minNotZero = value;
+                                }
+                            });
+                        }
+                    });
+                }
+
+                me.min = getValueOrDefault(tickOpts.min, me.min);
+                me.max = getValueOrDefault(tickOpts.max, me.max);
+
+                if (me.min === me.max) {
+                    if (me.min !== 0 && me.min !== null) {
+                        me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
+                        me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
+                    } else {
+                        me.min = 1;
+                        me.max = 10;
+                    }
+                }
+            },
+            buildTicks: function() {
+                var me = this;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+
+                var generationOptions = {
+                    min: tickOpts.min,
+                    max: tickOpts.max
+                };
+                var ticks = me.ticks = Chart.Ticks.generators.logarithmic(generationOptions, me);
+
+                if (!me.isHorizontal()) {
+                    // We are in a vertical orientation. The top value is the highest. So reverse the array
+                    ticks.reverse();
+                }
+
+                // At this point, we need to update our max and min given the tick values since we have expanded the
+                // range of the scale
+                me.max = helpers.max(ticks);
+                me.min = helpers.min(ticks);
+
+                if (tickOpts.reverse) {
+                    ticks.reverse();
+
+                    me.start = me.max;
+                    me.end = me.min;
+                } else {
+                    me.start = me.min;
+                    me.end = me.max;
+                }
+            },
+            convertTicksToLabels: function() {
+                this.tickValues = this.ticks.slice();
+
+                Chart.Scale.prototype.convertTicksToLabels.call(this);
+            },
+            // Get the correct tooltip label
+            getLabelForIndex: function(index, datasetIndex) {
+                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+            },
+            getPixelForTick: function(index) {
+                return this.getPixelForValue(this.tickValues[index]);
+            },
+            getPixelForValue: function(value) {
+                var me = this;
+                var innerDimension;
+                var pixel;
+
+                var start = me.start;
+                var newVal = +me.getRightValue(value);
+                var range;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+
+                if (me.isHorizontal()) {
+                    range = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0
+                    if (newVal === 0) {
+                        pixel = me.left;
+                    } else {
+                        innerDimension = me.width;
+                        pixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
+                    }
+                } else {
+                    // Bottom - top since pixels increase downward on a screen
+                    innerDimension = me.height;
+                    if (start === 0 && !tickOpts.reverse) {
+                        range = helpers.log10(me.end) - helpers.log10(me.minNotZero);
+                        if (newVal === start) {
+                            pixel = me.bottom;
+                        } else if (newVal === me.minNotZero) {
+                            pixel = me.bottom - innerDimension * 0.02;
+                        } else {
+                            pixel = me.bottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
+                        }
+                    } else if (me.end === 0 && tickOpts.reverse) {
+                        range = helpers.log10(me.start) - helpers.log10(me.minNotZero);
+                        if (newVal === me.end) {
+                            pixel = me.top;
+                        } else if (newVal === me.minNotZero) {
+                            pixel = me.top + innerDimension * 0.02;
+                        } else {
+                            pixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
+                        }
+                    } else if (newVal === 0) {
+                        pixel = tickOpts.reverse ? me.top : me.bottom;
+                    } else {
+                        range = helpers.log10(me.end) - helpers.log10(start);
+                        innerDimension = me.height;
+                        pixel = me.bottom - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));
+                    }
+                }
+                return pixel;
+            },
+            getValueForPixel: function(pixel) {
+                var me = this;
+                var range = helpers.log10(me.end) - helpers.log10(me.start);
+                var value, innerDimension;
+
+                if (me.isHorizontal()) {
+                    innerDimension = me.width;
+                    value = me.start * Math.pow(10, (pixel - me.left) * range / innerDimension);
+                } else {  // todo: if start === 0
+                    innerDimension = me.height;
+                    value = Math.pow(10, (me.bottom - pixel) * range / innerDimension) / me.start;
+                }
+                return value;
+            }
+        });
+        Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);
+
+    };
+
+},{}],48:[function(require,module,exports){
+    'use strict';
+
+    module.exports = function(Chart) {
+
+        var helpers = Chart.helpers;
+        var globalDefaults = Chart.defaults.global;
+
+        var defaultConfig = {
+            display: true,
+
+            // Boolean - Whether to animate scaling the chart from the centre
+            animate: true,
+            position: 'chartArea',
+
+            angleLines: {
+                display: true,
+                color: 'rgba(0, 0, 0, 0.1)',
+                lineWidth: 1
+            },
+
+            gridLines: {
+                circular: false
+            },
+
+            // label settings
+            ticks: {
+                // Boolean - Show a backdrop to the scale label
+                showLabelBackdrop: true,
+
+                // String - The colour of the label backdrop
+                backdropColor: 'rgba(255,255,255,0.75)',
+
+                // Number - The backdrop padding above & below the label in pixels
+                backdropPaddingY: 2,
+
+                // Number - The backdrop padding to the side of the label in pixels
+                backdropPaddingX: 2,
+
+                callback: Chart.Ticks.formatters.linear
+            },
+
+            pointLabels: {
+                // Boolean - if true, show point labels
+                display: true,
+
+                // Number - Point label font size in pixels
+                fontSize: 10,
+
+                // Function - Used to convert point labels
+                callback: function(label) {
+                    return label;
+                }
+            }
+        };
+
+        function getValueCount(scale) {
+            var opts = scale.options;
+            return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
+        }
+
+        function getPointLabelFontOptions(scale) {
+            var pointLabelOptions = scale.options.pointLabels;
+            var fontSize = helpers.getValueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
+            var fontStyle = helpers.getValueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
+            var fontFamily = helpers.getValueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
+            var font = helpers.fontString(fontSize, fontStyle, fontFamily);
+
+            return {
+                size: fontSize,
+                style: fontStyle,
+                family: fontFamily,
+                font: font
+            };
+        }
+
+        function measureLabelSize(ctx, fontSize, label) {
+            if (helpers.isArray(label)) {
+                return {
+                    w: helpers.longestText(ctx, ctx.font, label),
+                    h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
+                };
+            }
+
+            return {
+                w: ctx.measureText(label).width,
+                h: fontSize
+            };
+        }
+
+        function determineLimits(angle, pos, size, min, max) {
+            if (angle === min || angle === max) {
+                return {
+                    start: pos - (size / 2),
+                    end: pos + (size / 2)
+                };
+            } else if (angle < min || angle > max) {
+                return {
+                    start: pos - size - 5,
+                    end: pos
+                };
+            }
+
+            return {
+                start: pos,
+                end: pos + size + 5
+            };
+        }
+
+        /**
+         * Helper function to fit a radial linear scale with point labels
+         */
+        function fitWithPointLabels(scale) {
+            /*
+             * Right, this is really confusing and there is a lot of maths going on here
+             * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
+             *
+             * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
+             *
+             * Solution:
+             *
+             * We assume the radius of the polygon is half the size of the canvas at first
+             * at each index we check if the text overlaps.
+             *
+             * Where it does, we store that angle and that index.
+             *
+             * After finding the largest index and angle we calculate how much we need to remove
+             * from the shape radius to move the point inwards by that x.
+             *
+             * We average the left and right distances to get the maximum shape radius that can fit in the box
+             * along with labels.
+             *
+             * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
+             * on each side, removing that from the size, halving it and adding the left x protrusion width.
+             *
+             * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
+             * and position it in the most space efficient manner
+             *
+             * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
+             */
+
+            var plFont = getPointLabelFontOptions(scale);
+
+            // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
+            // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
+            var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+            var furthestLimits = {
+                r: scale.width,
+                l: 0,
+                t: scale.height,
+                b: 0
+            };
+            var furthestAngles = {};
+            var i;
+            var textSize;
+            var pointPosition;
+
+            scale.ctx.font = plFont.font;
+            scale._pointLabelSizes = [];
+
+            var valueCount = getValueCount(scale);
+            for (i = 0; i < valueCount; i++) {
+                pointPosition = scale.getPointPosition(i, largestPossibleRadius);
+                textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
+                scale._pointLabelSizes[i] = textSize;
+
+                // Add quarter circle to make degree 0 mean top of circle
+                var angleRadians = scale.getIndexAngle(i);
+                var angle = helpers.toDegrees(angleRadians) % 360;
+                var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
+                var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
+
+                if (hLimits.start < furthestLimits.l) {
+                    furthestLimits.l = hLimits.start;
+                    furthestAngles.l = angleRadians;
+                }
+
+                if (hLimits.end > furthestLimits.r) {
+                    furthestLimits.r = hLimits.end;
+                    furthestAngles.r = angleRadians;
+                }
+
+                if (vLimits.start < furthestLimits.t) {
+                    furthestLimits.t = vLimits.start;
+                    furthestAngles.t = angleRadians;
+                }
+
+                if (vLimits.end > furthestLimits.b) {
+                    furthestLimits.b = vLimits.end;
+                    furthestAngles.b = angleRadians;
+                }
+            }
+
+            scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
+        }
+
+        /**
+         * Helper function to fit a radial linear scale with no point labels
+         */
+        function fit(scale) {
+            var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
+            scale.drawingArea = Math.round(largestPossibleRadius);
+            scale.setCenterPoint(0, 0, 0, 0);
+        }
+
+        function getTextAlignForAngle(angle) {
+            if (angle === 0 || angle === 180) {
+                return 'center';
+            } else if (angle < 180) {
+                return 'left';
+            }
+
+            return 'right';
+        }
+
+        function fillText(ctx, text, position, fontSize) {
+            if (helpers.isArray(text)) {
+                var y = position.y;
+                var spacing = 1.5 * fontSize;
+
+                for (var i = 0; i < text.length; ++i) {
+                    ctx.fillText(text[i], position.x, y);
+                    y+= spacing;
+                }
+            } else {
+                ctx.fillText(text, position.x, position.y);
+            }
+        }
+
+        function adjustPointPositionForLabelHeight(angle, textSize, position) {
+            if (angle === 90 || angle === 270) {
+                position.y -= (textSize.h / 2);
+            } else if (angle > 270 || angle < 90) {
+                position.y -= textSize.h;
+            }
+        }
+
+        function drawPointLabels(scale) {
+            var ctx = scale.ctx;
+            var getValueOrDefault = helpers.getValueOrDefault;
+            var opts = scale.options;
+            var angleLineOpts = opts.angleLines;
+            var pointLabelOpts = opts.pointLabels;
+
+            ctx.lineWidth = angleLineOpts.lineWidth;
+            ctx.strokeStyle = angleLineOpts.color;
+
+            var outerDistance = scale.getDistanceFromCenterForValue(opts.reverse ? scale.min : scale.max);
+
+            // Point Label Font
+            var plFont = getPointLabelFontOptions(scale);
+
+            ctx.textBaseline = 'top';
+
+            for (var i = getValueCount(scale) - 1; i >= 0; i--) {
+                if (angleLineOpts.display) {
+                    var outerPosition = scale.getPointPosition(i, outerDistance);
+                    ctx.beginPath();
+                    ctx.moveTo(scale.xCenter, scale.yCenter);
+                    ctx.lineTo(outerPosition.x, outerPosition.y);
+                    ctx.stroke();
+                    ctx.closePath();
+                }
+
+                if (pointLabelOpts.display) {
+                    // Extra 3px out for some label spacing
+                    var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
+
+                    // Keep this in loop since we may support array properties here
+                    var pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);
+                    ctx.font = plFont.font;
+                    ctx.fillStyle = pointLabelFontColor;
+
+                    var angleRadians = scale.getIndexAngle(i);
+                    var angle = helpers.toDegrees(angleRadians);
+                    ctx.textAlign = getTextAlignForAngle(angle);
+                    adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
+                    fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
+                }
+            }
+        }
+
+        function drawRadiusLine(scale, gridLineOpts, radius, index) {
+            var ctx = scale.ctx;
+            ctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);
+            ctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
+
+            if (scale.options.gridLines.circular) {
+                // Draw circular arcs between the points
+                ctx.beginPath();
+                ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);
+                ctx.closePath();
+                ctx.stroke();
+            } else {
+                // Draw straight lines connecting each index
+                var valueCount = getValueCount(scale);
+
+                if (valueCount === 0) {
+                    return;
+                }
+
+                ctx.beginPath();
+                var pointPosition = scale.getPointPosition(0, radius);
+                ctx.moveTo(pointPosition.x, pointPosition.y);
+
+                for (var i = 1; i < valueCount; i++) {
+                    pointPosition = scale.getPointPosition(i, radius);
+                    ctx.lineTo(pointPosition.x, pointPosition.y);
+                }
+
+                ctx.closePath();
+                ctx.stroke();
+            }
+        }
+
+        function numberOrZero(param) {
+            return helpers.isNumber(param) ? param : 0;
+        }
+
+        var LinearRadialScale = Chart.LinearScaleBase.extend({
+            setDimensions: function() {
+                var me = this;
+                var opts = me.options;
+                var tickOpts = opts.ticks;
+                // Set the unconstrained dimension before label rotation
+                me.width = me.maxWidth;
+                me.height = me.maxHeight;
+                me.xCenter = Math.round(me.width / 2);
+                me.yCenter = Math.round(me.height / 2);
+
+                var minSize = helpers.min([me.height, me.width]);
+                var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+                me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
+            },
+            determineDataLimits: function() {
+                var me = this;
+                var chart = me.chart;
+                var min = Number.POSITIVE_INFINITY;
+                var max = Number.NEGATIVE_INFINITY;
+
+                helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
+                    if (chart.isDatasetVisible(datasetIndex)) {
+                        var meta = chart.getDatasetMeta(datasetIndex);
+
+                        helpers.each(dataset.data, function(rawValue, index) {
+                            var value = +me.getRightValue(rawValue);
+                            if (isNaN(value) || meta.data[index].hidden) {
+                                return;
+                            }
+
+                            min = Math.min(value, min);
+                            max = Math.max(value, max);
+                        });
+                    }
+                });
+
+                me.min = (min === Number.POSITIVE_INFINITY ? 0 : min);
+                me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);
+
+                // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
+                me.handleTickRangeOptions();
+            },
+            getTickLimit: function() {
+                var tickOpts = this.options.ticks;
+                var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+                return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
+            },
+            convertTicksToLabels: function() {
+                var me = this;
+                Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
+
+                // Point labels
+                me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
+            },
+            getLabelForIndex: function(index, datasetIndex) {
+                return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
+            },
+            fit: function() {
+                if (this.options.pointLabels.display) {
+                    fitWithPointLabels(this);
+                } else {
+                    fit(this);
+                }
+            },
+            /**
+             * Set radius reductions and determine new radius and center point
+             * @private
+             */
+            setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {
+                var me = this;
+                var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
+                var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
+                var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
+                var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
+
+                radiusReductionLeft = numberOrZero(radiusReductionLeft);
+                radiusReductionRight = numberOrZero(radiusReductionRight);
+                radiusReductionTop = numberOrZero(radiusReductionTop);
+                radiusReductionBottom = numberOrZero(radiusReductionBottom);
+
+                me.drawingArea = Math.min(
+                    Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
+                    Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));
+                me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
+            },
+            setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {
+                var me = this;
+                var maxRight = me.width - rightMovement - me.drawingArea,
+                    maxLeft = leftMovement + me.drawingArea,
+                    maxTop = topMovement + me.drawingArea,
+                    maxBottom = me.height - bottomMovement - me.drawingArea;
+
+                me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
+                me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);
+            },
+
+            getIndexAngle: function(index) {
+                var angleMultiplier = (Math.PI * 2) / getValueCount(this);
+                var startAngle = this.chart.options && this.chart.options.startAngle ?
+                    this.chart.options.startAngle :
+                    0;
+
+                var startAngleRadians = startAngle * Math.PI * 2 / 360;
+
+                // Start from the top instead of right, so remove a quarter of the circle
+                return index * angleMultiplier + startAngleRadians;
+            },
+            getDistanceFromCenterForValue: function(value) {
+                var me = this;
+
+                if (value === null) {
+                    return 0; // null always in center
+                }
+
+                // Take into account half font size + the yPadding of the top value
+                var scalingFactor = me.drawingArea / (me.max - me.min);
+                if (me.options.reverse) {
+                    return (me.max - value) * scalingFactor;
+                }
+                return (value - me.min) * scalingFactor;
+            },
+            getPointPosition: function(index, distanceFromCenter) {
+                var me = this;
+                var thisAngle = me.getIndexAngle(index) - (Math.PI / 2);
+                return {
+                    x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
+                    y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
+                };
+            },
+            getPointPositionForValue: function(index, value) {
+                return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
+            },
+
+            getBasePosition: function() {
+                var me = this;
+                var min = me.min;
+                var max = me.max;
+
+                return me.getPointPositionForValue(0,
+                    me.beginAtZero? 0:
+                        min < 0 && max < 0? max :
+                            min > 0 && max > 0? min :
+                                0);
+            },
+
+            draw: function() {
+                var me = this;
+                var opts = me.options;
+                var gridLineOpts = opts.gridLines;
+                var tickOpts = opts.ticks;
+                var getValueOrDefault = helpers.getValueOrDefault;
+
+                if (opts.display) {
+                    var ctx = me.ctx;
+
+                    // Tick Font
+                    var tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
+                    var tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
+                    var tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
+                    var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
+
+                    helpers.each(me.ticks, function(label, index) {
+                        // Don't draw a centre value (if it is minimum)
+                        if (index > 0 || opts.reverse) {
+                            var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
+                            var yHeight = me.yCenter - yCenterOffset;
+
+                            // Draw circular lines around the scale
+                            if (gridLineOpts.display && index !== 0) {
+                                drawRadiusLine(me, gridLineOpts, yCenterOffset, index);
+                            }
+
+                            if (tickOpts.display) {
+                                var tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
+                                ctx.font = tickLabelFont;
+
+                                if (tickOpts.showLabelBackdrop) {
+                                    var labelWidth = ctx.measureText(label).width;
+                                    ctx.fillStyle = tickOpts.backdropColor;
+                                    ctx.fillRect(
+                                        me.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,
+                                        yHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,
+                                        labelWidth + tickOpts.backdropPaddingX * 2,
+                                        tickFontSize + tickOpts.backdropPaddingY * 2
+                                    );
+                                }
+
+                                ctx.textAlign = 'center';
+                                ctx.textBaseline = 'middle';
+                                ctx.fillStyle = tickFontColor;
+                                ctx.fillText(label, me.xCenter, yHeight);
+                            }
+                        }
+                    });
+
+                    if (opts.angleLines.display || opts.pointLabels.display) {
+                        drawPointLabels(me);
+                    }
+                }
+            }
+        });
+        Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);
+
+    };
+
+},{}],49:[function(require,module,exports){
+    /* global window: false */
+    'use strict';
+
+    var moment = require(1);
+    moment = typeof(moment) === 'function' ? moment : window.moment;
+
+    module.exports = function(Chart) {
+
+        var helpers = Chart.helpers;
+        var interval = {
+            millisecond: {
+                size: 1,
+                steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
+            },
+            second: {
+                size: 1000,
+                steps: [1, 2, 5, 10, 30]
+            },
+            minute: {
+                size: 60000,
+                steps: [1, 2, 5, 10, 30]
+            },
+            hour: {
+                size: 3600000,
+                steps: [1, 2, 3, 6, 12]
+            },
+            day: {
+                size: 86400000,
+                steps: [1, 2, 5]
+            },
+            week: {
+                size: 604800000,
+                maxStep: 4
+            },
+            month: {
+                size: 2.628e9,
+                maxStep: 3
+            },
+            quarter: {
+                size: 7.884e9,
+                maxStep: 4
+            },
+            year: {
+                size: 3.154e10,
+                maxStep: false
+            }
+        };
+
+        var defaultConfig = {
+            position: 'bottom',
+
+            time: {
+                parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
+                format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
+                unit: false, // false == automatic or override with week, month, year, etc.
+                round: false, // none, or override with week, month, year, etc.
+                displayFormat: false, // DEPRECATED
+                isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
+                minUnit: 'millisecond',
+
+                // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
+                displayFormats: {
+                    millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
+                    second: 'h:mm:ss a', // 11:20:01 AM
+                    minute: 'h:mm:ss a', // 11:20:01 AM
+                    hour: 'MMM D, hA', // Sept 4, 5PM
+                    day: 'll', // Sep 4 2015
+                    week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
+                    month: 'MMM YYYY', // Sept 2015
+                    quarter: '[Q]Q - YYYY', // Q3
+                    year: 'YYYY' // 2015
+                },
+            },
+            ticks: {
+                autoSkip: false
+            }
+        };
+
+        /**
+         * Helper function to parse time to a moment object
+         * @param axis {TimeAxis} the time axis
+         * @param label {Date|string|number|Moment} The thing to parse
+         * @return {Moment} parsed time
+         */
+        function parseTime(axis, label) {
+            var timeOpts = axis.options.time;
+            if (typeof timeOpts.parser === 'string') {
+                return moment(label, timeOpts.parser);
+            }
+            if (typeof timeOpts.parser === 'function') {
+                return timeOpts.parser(label);
+            }
+            if (typeof label.getMonth === 'function' || typeof label === 'number') {
+                // Date objects
+                return moment(label);
+            }
+            if (label.isValid && label.isValid()) {
+                // Moment support
+                return label;
+            }
+            var format = timeOpts.format;
+            if (typeof format !== 'string' && format.call) {
+                // Custom parsing (return an instance of moment)
+                console.warn('options.time.format is deprecated and replaced by options.time.parser.');
+                return format(label);
+            }
+            // Moment format parsing
+            return moment(label, format);
+        }
+
+        /**
+         * Figure out which is the best unit for the scale
+         * @param minUnit {String} minimum unit to use
+         * @param min {Number} scale minimum
+         * @param max {Number} scale maximum
+         * @return {String} the unit to use
+         */
+        function determineUnit(minUnit, min, max, maxTicks) {
+            var units = Object.keys(interval);
+            var unit;
+            var numUnits = units.length;
+
+            for (var i = units.indexOf(minUnit); i < numUnits; i++) {
+                unit = units[i];
+                var unitDetails = interval[unit];
+                var steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;
+                if (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {
+                    break;
+                }
+            }
+
+            return unit;
+        }
+
+        /**
+         * Determines how we scale the unit
+         * @param min {Number} the scale minimum
+         * @param max {Number} the scale maximum
+         * @param unit {String} the unit determined by the {@see determineUnit} method
+         * @return {Number} the axis step size as a multiple of unit
+         */
+        function determineStepSize(min, max, unit, maxTicks) {
+            // Using our unit, figoure out what we need to scale as
+            var unitDefinition = interval[unit];
+            var unitSizeInMilliSeconds = unitDefinition.size;
+            var sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);
+            var multiplier = 1;
+            var range = max - min;
+
+            if (unitDefinition.steps) {
+                // Have an array of steps
+                var numSteps = unitDefinition.steps.length;
+                for (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {
+                    multiplier = unitDefinition.steps[i];
+                    sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
+                }
+            } else {
+                while (sizeInUnits > maxTicks && maxTicks > 0) {
+                    ++multiplier;
+                    sizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));
+                }
+            }
+
+            return multiplier;
+        }
+
+        /**
+         * Helper for generating axis labels.
+         * @param options {ITimeGeneratorOptions} the options for generation
+         * @param dataRange {IRange} the data range
+         * @param niceRange {IRange} the pretty range to display
+         * @return {Number[]} ticks
+         */
+        function generateTicks(options, dataRange, niceRange) {
+            var ticks = [];
+            if (options.maxTicks) {
+                var stepSize = options.stepSize;
+                ticks.push(options.min !== undefined ? options.min : niceRange.min);
+                var cur = moment(niceRange.min);
+                while (cur.add(stepSize, options.unit).valueOf() < niceRange.max) {
+                    ticks.push(cur.valueOf());
+                }
+                var realMax = options.max || niceRange.max;
+                if (ticks[ticks.length - 1] !== realMax) {
+                    ticks.push(realMax);
+                }
+            }
+            return ticks;
+        }
+
+        /**
+         * @function Chart.Ticks.generators.time
+         * @param options {ITimeGeneratorOptions} the options for generation
+         * @param dataRange {IRange} the data range
+         * @return {Number[]} ticks
+         */
+        Chart.Ticks.generators.time = function(options, dataRange) {
+            var niceMin;
+            var niceMax;
+            var isoWeekday = options.isoWeekday;
+            if (options.unit === 'week' && isoWeekday !== false) {
+                niceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();
+                niceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);
+                if (dataRange.max - niceMax > 0) {
+                    niceMax.add(1, 'week');
+                }
+                niceMax = niceMax.valueOf();
+            } else {
+                niceMin = moment(dataRange.min).startOf(options.unit).valueOf();
+                niceMax = moment(dataRange.max).startOf(options.unit);
+                if (dataRange.max - niceMax > 0) {
+                    niceMax.add(1, options.unit);
+                }
+                niceMax = niceMax.valueOf();
+            }
+            return generateTicks(options, dataRange, {
+                min: niceMin,
+                max: niceMax
+            });
+        };
+
+        var TimeScale = Chart.Scale.extend({
+            initialize: function() {
+                if (!moment) {
+                    throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');
+                }
+
+                Chart.Scale.prototype.initialize.call(this);
+            },
+            determineDataLimits: function() {
+                var me = this;
+                var timeOpts = me.options.time;
+
+                // We store the data range as unix millisecond timestamps so dataMin and dataMax will always be integers.
+                var dataMin = Number.MAX_SAFE_INTEGER;
+                var dataMax = Number.MIN_SAFE_INTEGER;
+
+                var chartData = me.chart.data;
+                var parsedData = {
+                    labels: [],
+                    datasets: []
+                };
+
+                var timestamp;
+
+                helpers.each(chartData.labels, function(label, labelIndex) {
+                    var labelMoment = parseTime(me, label);
+
+                    if (labelMoment.isValid()) {
+                        // We need to round the time
+                        if (timeOpts.round) {
+                            labelMoment.startOf(timeOpts.round);
+                        }
+
+                        timestamp = labelMoment.valueOf();
+                        dataMin = Math.min(timestamp, dataMin);
+                        dataMax = Math.max(timestamp, dataMax);
+
+                        // Store this value for later
+                        parsedData.labels[labelIndex] = timestamp;
+                    }
+                });
+
+                helpers.each(chartData.datasets, function(dataset, datasetIndex) {
+                    var timestamps = [];
+
+                    if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null && me.chart.isDatasetVisible(datasetIndex)) {
+                        // We have potential point data, so we need to parse this
+                        helpers.each(dataset.data, function(value, dataIndex) {
+                            var dataMoment = parseTime(me, me.getRightValue(value));
+
+                            if (dataMoment.isValid()) {
+                                if (timeOpts.round) {
+                                    dataMoment.startOf(timeOpts.round);
+                                }
+
+                                timestamp = dataMoment.valueOf();
+                                dataMin = Math.min(timestamp, dataMin);
+                                dataMax = Math.max(timestamp, dataMax);
+                                timestamps[dataIndex] = timestamp;
+                            }
+                        });
+                    } else {
+                        // We have no x coordinates, so use the ones from the labels
+                        timestamps = parsedData.labels.slice();
+                    }
+
+                    parsedData.datasets[datasetIndex] = timestamps;
+                });
+
+                me.dataMin = dataMin;
+                me.dataMax = dataMax;
+                me._parsedData = parsedData;
+            },
+            buildTicks: function() {
+                var me = this;
+                var timeOpts = me.options.time;
+
+                var minTimestamp;
+                var maxTimestamp;
+                var dataMin = me.dataMin;
+                var dataMax = me.dataMax;
+
+                if (timeOpts.min) {
+                    var minMoment = parseTime(me, timeOpts.min);
+                    if (timeOpts.round) {
+                        minMoment.round(timeOpts.round);
+                    }
+                    minTimestamp = minMoment.valueOf();
+                }
+
+                if (timeOpts.max) {
+                    maxTimestamp = parseTime(me, timeOpts.max).valueOf();
+                }
+
+                var maxTicks = me.getLabelCapacity(minTimestamp || dataMin);
+                var unit = timeOpts.unit || determineUnit(timeOpts.minUnit, minTimestamp || dataMin, maxTimestamp || dataMax, maxTicks);
+                me.displayFormat = timeOpts.displayFormats[unit];
+
+                var stepSize = timeOpts.stepSize || determineStepSize(minTimestamp || dataMin, maxTimestamp || dataMax, unit, maxTicks);
+                me.ticks = Chart.Ticks.generators.time({
+                    maxTicks: maxTicks,
+                    min: minTimestamp,
+                    max: maxTimestamp,
+                    stepSize: stepSize,
+                    unit: unit,
+                    isoWeekday: timeOpts.isoWeekday
+                }, {
+                    min: dataMin,
+                    max: dataMax
+                });
+
+                // At this point, we need to update our max and min given the tick values since we have expanded the
+                // range of the scale
+                me.max = helpers.max(me.ticks);
+                me.min = helpers.min(me.ticks);
+            },
+            // Get tooltip label
+            getLabelForIndex: function(index, datasetIndex) {
+                var me = this;
+                var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';
+                var value = me.chart.data.datasets[datasetIndex].data[index];
+
+                if (value !== null && typeof value === 'object') {
+                    label = me.getRightValue(value);
+                }
+
+                // Format nicely
+                if (me.options.time.tooltipFormat) {
+                    label = parseTime(me, label).format(me.options.time.tooltipFormat);
+                }
+
+                return label;
+            },
+            // Function to format an individual tick mark
+            tickFormatFunction: function(tick, index, ticks) {
+                var formattedTick = tick.format(this.displayFormat);
+                var tickOpts = this.options.ticks;
+                var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);
+
+                if (callback) {
+                    return callback(formattedTick, index, ticks);
+                }
+                return formattedTick;
+            },
+            convertTicksToLabels: function() {
+                var me = this;
+                me.ticksAsTimestamps = me.ticks;
+                me.ticks = me.ticks.map(function(tick) {
+                    return moment(tick);
+                }).map(me.tickFormatFunction, me);
+            },
+            getPixelForOffset: function(offset) {
+                var me = this;
+                var epochWidth = me.max - me.min;
+                var decimal = epochWidth ? (offset - me.min) / epochWidth : 0;
+
+                if (me.isHorizontal()) {
+                    var valueOffset = (me.width * decimal);
+                    return me.left + Math.round(valueOffset);
+                }
+
+                var heightOffset = (me.height * decimal);
+                return me.top + Math.round(heightOffset);
+            },
+            getPixelForValue: function(value, index, datasetIndex) {
+                var me = this;
+                var offset = null;
+                if (index !== undefined && datasetIndex !== undefined) {
+                    offset = me._parsedData.datasets[datasetIndex][index];
+                }
+
+                if (offset === null) {
+                    if (!value || !value.isValid) {
+                        // not already a moment object
+                        value = parseTime(me, me.getRightValue(value));
+                    }
+
+                    if (value && value.isValid && value.isValid()) {
+                        offset = value.valueOf();
+                    }
+                }
+
+                if (offset !== null) {
+                    return me.getPixelForOffset(offset);
+                }
+            },
+            getPixelForTick: function(index) {
+                return this.getPixelForOffset(this.ticksAsTimestamps[index]);
+            },
+            getValueForPixel: function(pixel) {
+                var me = this;
+                var innerDimension = me.isHorizontal() ? me.width : me.height;
+                var offset = (pixel - (me.isHorizontal() ? me.left : me.top)) / innerDimension;
+                return moment(me.min + (offset * (me.max - me.min)));
+            },
+            // Crude approximation of what the label width might be
+            getLabelWidth: function(label) {
+                var me = this;
+                var ticks = me.options.ticks;
+
+                var tickLabelWidth = me.ctx.measureText(label).width;
+                var cosRotation = Math.cos(helpers.toRadians(ticks.maxRotation));
+                var sinRotation = Math.sin(helpers.toRadians(ticks.maxRotation));
+                var tickFontSize = helpers.getValueOrDefault(ticks.fontSize, Chart.defaults.global.defaultFontSize);
+                return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
+            },
+            getLabelCapacity: function(exampleTime) {
+                var me = this;
+
+                me.displayFormat = me.options.time.displayFormats.millisecond;	// Pick the longest format for guestimation
+                var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, []);
+                var tickLabelWidth = me.getLabelWidth(exampleLabel);
+
+                var innerWidth = me.isHorizontal() ? me.width : me.height;
+                var labelCapacity = innerWidth / tickLabelWidth;
+                return labelCapacity;
+            }
+        });
+        Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig);
+
+    };
 
 },{"1":1}]},{},[7])(7)
 });
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/tp/Chart.min.js b/web/gui/src/main/webapp/tp/Chart.min.js
index 4d5cdcd..cf50797 100644
--- a/web/gui/src/main/webapp/tp/Chart.min.js
+++ b/web/gui/src/main/webapp/tp/Chart.min.js
@@ -1,14 +1,14 @@
 /*!
  * Chart.js
  * http://chartjs.org/
- * Version: 2.2.1
+ * Version: 2.6.0
  *
- * Copyright 2016 Nick Downie
+ * Copyright 2017 Nick Downie
  * Released under the MIT license
  * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
  */
-!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,a,i){function n(r,l){if(!a[r]){if(!e[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(o)return o(r,!0);var d=new Error("Cannot find module '"+r+"'");throw d.code="MODULE_NOT_FOUND",d}var u=a[r]={exports:{}};e[r][0].call(u.exports,function(t){var a=e[r][1][t];return n(a?a:t)},u,u.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)n(i[r]);return n}({1:[function(t,e,a){},{}],2:[function(t,e,a){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,a=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,n=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,o=/(\w+)/,r=[0,0,0],l=1,s=t.match(e);if(s){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s[d]+s[d],16)}else if(s=t.match(a)){s=s[1];for(var d=0;d<r.length;d++)r[d]=parseInt(s.slice(2*d,2*d+2),16)}else if(s=t.match(i)){for(var d=0;d<r.length;d++)r[d]=parseInt(s[d+1]);l=parseFloat(s[4])}else if(s=t.match(n)){for(var d=0;d<r.length;d++)r[d]=Math.round(2.55*parseFloat(s[d+1]));l=parseFloat(s[4])}else if(s=t.match(o)){if("transparent"==s[1])return[0,0,0,0];if(r=y[s[1]],!r)return}for(var d=0;d<r.length;d++)r[d]=v(r[d],0,255);return l=l||0==l?v(l,0,1):1,r[3]=l,r}}function n(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function o(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=v(parseInt(a[1]),0,360),o=v(parseFloat(a[2]),0,100),r=v(parseFloat(a[3]),0,100),l=v(isNaN(i)?1:i,0,1);return[n,o,r,l]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function l(t){var e=n(t);return e&&e.slice(0,3)}function s(t){var e=i(t);return e?e[3]:(e=n(t))?e[3]:(e=o(t))?e[3]:void 0}function d(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function u(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgb("+a+"%, "+i+"%, "+n+"%)"}function f(t,e){var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgba("+a+"%, "+i+"%, "+n+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function b(t){return k[t.slice(0,3)]}function v(t,e,a){return Math.min(Math.max(e,t),a)}function x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:n,getRgb:r,getHsl:l,getHwb:o,getAlpha:s,hexString:d,rgbString:u,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:b};var k={};for(var S in y)k[y[S]]=S},{6:6}],3:[function(t,e,a){var i=t(5),n=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=n.getRgba(t))this.setValues("rgb",e);else if(e=n.getHsla(t))this.setValues("hsl",e);else{if(!(e=n.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};o.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return n.hexString(this.values.rgb)},rgbString:function(){return n.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return n.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return n.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return n.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return n.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return n.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return n.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],a=0;a<t.length;a++){var i=t[a]/255;e[a]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),a=t.luminosity();return e>a?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=0>a?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),l=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,s=1-l;return this.rgb(l*a.red()+s*i.red(),l*a.green()+s*i.green(),l*a.blue()+s*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i<t.length;i++)a[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(a.a=e.alpha),a},o.prototype.setValues=function(t,e){var a,n=this.values,o=this.spaces,r=this.maxes,l=1;if("alpha"===t)l=e;else if(e.length)n[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(a=0;a<t.length;a++)n[t][a]=e[t.charAt(a)];l=e.a}else if(void 0!==e[o[t][0]]){var s=o[t];for(a=0;a<t.length;a++)n[t][a]=e[s[a]];l=e.alpha}if(n.alpha=Math.max(0,Math.min(1,void 0===l?n.alpha:l)),"alpha"===t)return!1;var d;for(a=0;a<t.length;a++)d=Math.max(0,Math.min(r[t][a],n[t][a])),n[t][a]=Math.round(d);for(var u in o)u!==t&&(n[u]=i[t][u](n[t]));return!0},o.prototype.setSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a),this)},o.prototype.setChannel=function(t,e,a){var i=this.values[t];return void 0===a?i[e]:a===i[e]?this:(i[e]=a,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,a){function i(t){var e,a,i,n=t[0]/255,o=t[1]/255,r=t[2]/255,l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=(l+s)/2,a=s==l?0:.5>=i?d/(s+l):d/(2-s-l),[e,100*a,100*i]}function n(t){var e,a,i,n=t[0],o=t[1],r=t[2],l=Math.min(n,o,r),s=Math.max(n,o,r),d=s-l;return a=0==s?0:d/s*1e3/10,s==l?e=0:n==s?e=(o-r)/d:o==s?e=2+(r-n)/d:r==s&&(e=4+(n-o)/d),e=Math.min(60*e,360),0>e&&(e+=360),i=s/255*1e3/10,[e,a,i]}function o(t){var e=t[0],a=t[1],n=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(a,n)),n=1-1/255*Math.max(e,Math.max(a,n));return[o,100*r,100*n]}function l(t){var e,a,i,n,o=t[0]/255,r=t[1]/255,l=t[2]/255;return n=Math.min(1-o,1-r,1-l),e=(1-o-n)/(1-n)||0,a=(1-r-n)/(1-n)||0,i=(1-l-n)/(1-n)||0,[100*e,100*a,100*i,100*n]}function s(t){return Z[JSON.stringify(t)]}function d(t){var e=t[0]/255,a=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function u(t){var e,a,i,n=d(t),o=n[0],r=n[1],l=n[2];return o/=95.047,r/=100,l/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,l=l>.008856?Math.pow(l,1/3):7.787*l+16/116,e=116*r-16,a=500*(o-r),i=200*(r-l),[e,a,i]}function c(t){return W(u(t))}function h(t){var e,a,i,n,o,r=t[0]/360,l=t[1]/100,s=t[2]/100;if(0==l)return o=255*s,[o,o,o];a=.5>s?s*(1+l):s+l-s*l,e=2*s-a,n=[0,0,0];for(var d=0;3>d;d++)i=r+1/3*-(d-1),0>i&&i++,i>1&&i--,o=1>6*i?e+6*(a-e)*i:1>2*i?a:2>3*i?e+(a-e)*(2/3-i)*6:e,n[d]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=1>=o?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return l(h(t))}function v(t){return s(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),l=255*i*(1-a*o),s=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,s,r];case 1:return[l,i,r];case 2:return[r,i,s];case 3:return[r,l,i];case 4:return[s,r,i];case 5:return[i,r,l]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=1>=a?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return l(x(t))}function w(t){return s(x(t))}function C(t){var e,a,i,n,o=t[0]/360,l=t[1]/100,s=t[2]/100,d=l+s;switch(d>1&&(l/=d,s/=d),e=Math.floor(6*o),a=1-s,i=6*o-e,0!=(1&e)&&(i=1-i),n=l+i*(a-l),e){default:case 6:case 0:r=a,g=n,b=l;break;case 1:r=n,g=a,b=l;break;case 2:r=l,g=a,b=n;break;case 3:r=l,g=n,b=a;break;case 4:r=n,g=l,b=a;break;case 5:r=a,g=l,b=n}return[255*r,255*g,255*b]}function M(t){return i(C(t))}function D(t){return n(C(t))}function A(t){return l(C(t))}function I(t){return s(C(t))}function T(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,l=t[3]/100;return e=1-Math.min(1,n*(1-l)+l),a=1-Math.min(1,o*(1-l)+l),i=1-Math.min(1,r*(1-l)+l),[255*e,255*a,255*i]}function F(t){return i(T(t))}function P(t){return n(T(t))}function R(t){return o(T(t))}function _(t){return s(T(t))}function V(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+-1.5372*o+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a=12.92*a,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function L(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function O(t){return W(L(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],l=t[2];return 8>=o?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=.008856>=e/95.047?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=.008859>=i/108.883?i=108.883*(n-l/200-16/116)/7.787:108.883*Math.pow(n-l/200,3),[e,a,i]}function W(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,0>a&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function z(t){return V(B(t))}function N(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function H(t){return B(N(t))}function E(t){return z(N(t))}function U(t){return Q[t]}function q(t){return i(U(t))}function j(t){return n(U(t))}function Y(t){return o(U(t))}function J(t){return l(U(t))}function X(t){return u(U(t))}function G(t){return d(U(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:l,rgb2keyword:s,rgb2xyz:d,rgb2lab:u,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:w,hwb2rgb:C,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:A,hwb2keyword:I,cmyk2rgb:T,cmyk2hsl:F,cmyk2hsv:P,cmyk2hwb:R,cmyk2keyword:_,keyword2rgb:U,keyword2hsl:q,keyword2hsv:j,keyword2hwb:Y,keyword2cmyk:J,keyword2lab:X,keyword2xyz:G,xyz2rgb:V,xyz2lab:L,xyz2lch:O,lab2xyz:B,lab2rgb:z,lab2lch:W,lch2lab:N,lch2xyz:H,lch2rgb:E};var Q={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Z={};for(var $ in Q)Z[JSON.stringify(Q[$])]=$},{}],5:[function(t,e,a){var i=t(4),n=function(){return new d};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),l=r[1],s=r[2];n[l]=n[l]||{},n[l][s]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n<a.length;n++)a[n]=Math.round(a[n]);return a}}(o)}var d=function(){this.convs={}};d.prototype.routeSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a))},d.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},d.prototype.getValues=function(t){var e=this.convs[t];if(!e){var a=this.space,i=this.convs[a];e=n[a][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){d.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=n},{4:4}],6:[function(t,e,a){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,a){var i=t(27)();t(26)(i),t(22)(i),t(25)(i),t(21)(i),t(23)(i),t(24)(i),t(28)(i),t(32)(i),t(30)(i),t(31)(i),t(33)(i),t(29)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(38)(i),t(41)(i),t(39)(i),t(40)(i),t(42)(i),t(43)(i),t(44)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,8:8,9:9}],8:[function(t,e,a){"use strict";e.exports=function(t){t.Bar=function(e,a){return a.type="bar",new t(e,a)}}},{}],9:[function(t,e,a){"use strict";e.exports=function(t){t.Bubble=function(e,a){return a.type="bubble",new t(e,a)}}},{}],10:[function(t,e,a){"use strict";e.exports=function(t){t.Doughnut=function(e,a){return a.type="doughnut",new t(e,a)}}},{}],11:[function(t,e,a){"use strict";e.exports=function(t){t.Line=function(e,a){return a.type="line",new t(e,a)}}},{}],12:[function(t,e,a){"use strict";e.exports=function(t){t.PolarArea=function(e,a){return a.type="polarArea",new t(e,a)}}},{}],13:[function(t,e,a){"use strict";e.exports=function(t){t.Radar=function(e,a){return a.options=t.helpers.configMerge({aspectRatio:1},a.options),a.type="radar",new t(e,a)}}},{}],14:[function(t,e,a){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,a){return a.type="scatter",new t(e,a)}}},{}],15:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,a){t.DatasetController.prototype.initialize.call(this,e,a),this.getMeta().bar=!0},getBarCount:function(){var t=this,a=0;return e.each(t.chart.data.datasets,function(e,i){var n=t.chart.getDatasetMeta(i);n.bar&&t.chart.isDatasetVisible(i)&&++a},t),a},update:function(t){var a=this;e.each(a.getMeta().data,function(e,i){a.updateElement(e,i,t)},a)},updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),l=n.getScaleForId(o.yAxisID),s=l.getBasePixel(),d=n.chart.options.elements.rectangle,u=t.custom||{},c=n.getDataset();e.extend(t,{_xScale:r,_yScale:l,_datasetIndex:n.index,_index:a,_model:{x:n.calculateBarX(a,n.index),y:i?s:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:c.label,base:i?s:n.calculateBarBase(n.index,a),width:n.calculateBarWidth(a),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,a,d.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:d.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(c.borderColor,a,d.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,a,d.borderWidth)}}),t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=0;if(n.options.stacked){for(var r=a.chart,l=r.data.datasets,s=Number(l[t].data[e]),d=0;t>d;d++){var u=l[d],c=r.getDatasetMeta(d);if(c.bar&&c.yAxisID===n.id&&r.isDatasetVisible(d)){var h=Number(u.data[e]);o+=0>s?Math.min(h,0):Math.max(h,0)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickWidth:e,categoryWidth:r,categorySpacing:l,fullBarWidth:s,barWidth:u,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID);if(e.options.barThickness)return e.options.barThickness;var a=this.getRuler(t);return e.options.stacked?a.categoryWidth:a.barWidth},getBarIndex:function(t){var e,a,i=0;for(a=0;t>a;++a)e=this.chart.getDatasetMeta(a),e.bar&&this.chart.isDatasetVisible(a)&&++i;return i},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickWidth/2:0,n.options.stacked?l+r.categoryWidth/2+r.categorySpacing:l+r.barWidth/2+r.categorySpacing+r.barWidth*o+r.barSpacing/2+r.barSpacing*o},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);if(u.bar&&u.yAxisID===n.id&&a.chart.isDatasetVisible(s)){var c=Number(d.data[t]);0>c?l+=c||0:r+=c||0}}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},draw:function(t){var a=this,i=t||1;e.each(a.getMeta().data,function(t,e){var n=a.getDataset().data[e];null===n||void 0===n||isNaN(n)||t.transition(i).draw()},a)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor?n.hoverBorderColor:e.getValueAtIndexOrDefault(a.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:e.getValueAtIndexOrDefault(a.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=n.backgroundColor?n.backgroundColor:e.getValueAtIndexOrDefault(a.backgroundColor,i,r.backgroundColor),o.borderColor=n.borderColor?n.borderColor:e.getValueAtIndexOrDefault(a.borderColor,i,r.borderColor),o.borderWidth=n.borderWidth?n.borderWidth:e.getValueAtIndexOrDefault(a.borderWidth,i,r.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var a="";return t.length>0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(a=e.labels[t[0].index])),a},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),l=n.getScaleForId(o.yAxisID),s=r.getBasePixel(),d=t.custom||{},u=n.getDataset(),c=n.chart.options.elements.rectangle;e.extend(t,{_xScale:r,_yScale:l,_datasetIndex:n.index,_index:a,_model:{x:i?s:n.calculateBarX(a,n.index),y:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:u.label,base:i?s:n.calculateBarBase(n.index,a),height:n.calculateBarHeight(a),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(u.backgroundColor,a,c.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:c.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(u.borderColor,a,c.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(u.borderWidth,a,c.borderWidth)},draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.height/2,n=a.y-i,o=a.y+i,r=a.base-(a.base-a.x),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[a.base,o],[a.base,n],[r,n],[r,o]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},inRange:function(t,e){var a=this._view,i=!1;return a&&(i=a.x<a.base?e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.x&&t<=a.base:e>=a.y-a.height/2&&e<=a.y+a.height/2&&t>=a.base&&t<=a.x),i}}),t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=0;
-if(n.options.stacked){for(var r=a.chart,l=r.data.datasets,s=Number(l[t].data[e]),d=0;t>d;d++){var u=l[d],c=r.getDatasetMeta(d);if(c.bar&&c.xAxisID===n.id&&r.isDatasetVisible(d)){var h=Number(u.data[e]);o+=0>s?Math.min(h,0):Math.max(h,0)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(t){var e,a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarCount();e="category"===n.options.type?n.getPixelForTick(t+1)-n.getPixelForTick(t):n.width/n.ticks.length;var r=e*n.options.categoryPercentage,l=(e-e*n.options.categoryPercentage)/2,s=r/o;if(n.ticks.length!==a.chart.data.labels.length){var d=n.ticks.length/a.chart.data.labels.length;s*=d}var u=s*n.options.barPercentage,c=s-s*n.options.barPercentage;return{datasetCount:o,tickHeight:e,categoryHeight:r,categorySpacing:l,fullBarHeight:s,barHeight:u,barSpacing:c}},calculateBarHeight:function(t){var e=this,a=e.getScaleForId(e.getMeta().yAxisID);if(a.options.barThickness)return a.options.barThickness;var i=e.getRuler(t);return a.options.stacked?i.categoryHeight:i.barHeight},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked){for(var r=0,l=0,s=0;e>s;s++){var d=a.chart.data.datasets[s],u=a.chart.getDatasetMeta(s);if(u.bar&&u.xAxisID===n.id&&a.chart.isDatasetVisible(s)){var c=Number(d.data[t]);0>c?l+=c||0:r+=c||0}}return 0>o?n.getPixelForValue(l+o):n.getPixelForValue(r+o)}return n.getPixelForValue(o)},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=a.getBarIndex(e),r=a.getRuler(t),l=n.getPixelForValue(null,t,e,a.chart.isCombo);return l-=a.chart.isCombo?r.tickHeight/2:0,n.options.stacked?l+r.categoryHeight/2+r.categorySpacing:l+r.barHeight/2+r.categorySpacing+r.barHeight*o+r.barSpacing/2+r.barSpacing*o}})}},{}],16:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return a+": ("+i.x+", "+i.y+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var a=this,i=a.getMeta(),n=i.data;e.each(n,function(e,i){a.updateElement(e,i,t)})},updateElement:function(a,i,n){var o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),d=a.custom||{},u=o.getDataset(),c=u.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(a,{_xScale:l,_yScale:s,_datasetIndex:f,_index:i,_model:{x:n?l.getPixelForDecimal(.5):l.getPixelForValue("object"==typeof c?c:NaN,i,f,o.chart.isCombo),y:n?s.getBasePixel():s.getPixelForValue(c,i,f),radius:n?0:d.radius?d.radius:o.getRadius(c),hitRadius:d.hitRadius?d.hitRadius:e.getValueAtIndexOrDefault(u.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,a,h);var g=a._model;g.skip=d.skip?d.skip:isNaN(g.x)||isNaN(g.y),a.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(a){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,a);var n=i.chart.data.datasets[a._datasetIndex],o=a._index,r=a.custom||{},l=a._model;l.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(n.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(n.data[o])},removeHoverStyle:function(e){var a=this;t.DatasetController.prototype.removeHoverStyle.call(a,e,a.chart.options.elements.point);var i=a.chart.data.datasets[e._datasetIndex].data[e._index],n=e.custom||{},o=e._model;o.radius=n.radius?n.radius:a.getRadius(i)}})}},{}],17:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults;a.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),n[o]&&e.push(n[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l&&l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+e.datasets[t.datasetIndex].data[t.index]}}}},a.pie=e.clone(a.doughnut),e.extend(a.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,a=0;t>a;++a)this.chart.isDatasetVisible(a)&&++e;return e},update:function(t){var a=this,i=a.chart,n=i.chartArea,o=i.options,r=o.elements.arc,l=n.right-n.left-r.borderWidth,s=n.bottom-n.top-r.borderWidth,d=Math.min(l,s),u={x:0,y:0},c=a.getMeta(),h=o.cutoutPercentage,f=o.circumference;if(f<2*Math.PI){var g=o.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},b={x:Math.cos(p),y:Math.sin(p)},v=0>=g&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,w={x:y?-1:Math.min(m.x*(m.x<0?1:S),b.x*(b.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),b.y*(b.y<0?1:S))},C={x:v?1:Math.max(m.x*(m.x>0?1:S),b.x*(b.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),b.y*(b.y>0?1:S))},M={width:.5*(C.x-w.x),height:.5*(C.y-w.y)};d=Math.min(l/M.width,s/M.height),u={x:(C.x+w.x)*-.5,y:(C.y+w.y)*-.5}}i.borderWidth=a.getMaxBorderWidth(c.data),i.outerRadius=Math.max((d-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=u.x*i.outerRadius,i.offsetY=u.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=a.outerRadius-i.radiusLength,e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,l=o.options,s=l.animation,d=(r.left+r.right)/2,u=(r.top+r.bottom)/2,c=l.rotation,h=l.rotation,f=n.getDataset(),g=i&&s.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(l.circumference/(2*Math.PI)),p=i&&s.animateScale?0:n.innerRadius,m=i&&s.animateScale?0:n.outerRadius,b=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:d+o.offsetX,y:u+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:b(f.label,a,o.data.labels[a])}});var v=t._model;this.removeHoverStyle(t),i&&s.animateRotate||(0===a?v.startAngle=l.rotation:v.startAngle=n.getMeta().data[a-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,a,i=0,n=this.index,o=t.length,r=0;o>r;r++)e=t[r]._model?t[r]._model.borderWidth:0,a=t[r]._chart?t[r]._chart.config.data.datasets[n].hoverBorderWidth:0,i=e>i?e:i,i=a>i?a:i;return i}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,addElementAndReset:function(a){var i=this,n=i.chart.options,o=i.getMeta();t.DatasetController.prototype.addElementAndReset.call(i,a),e(i.getDataset(),n)&&0!==o.dataset._model.tension&&i.updateBezierControlPoints()},update:function(t){var i,n,o,r=this,l=r.getMeta(),s=l.dataset,d=l.data||[],u=r.chart.options,c=u.elements.line,h=r.getScaleForId(l.yAxisID),f=r.getDataset(),g=e(f,u);for(g&&(o=s.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),s._scale=h,s._datasetIndex=r.index,s._children=d,s._model={spanGaps:f.spanGaps?f.spanGaps:u.spanGaps,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:a.getValueOrDefault(f.steppedLine,c.stepped),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},s.pivot()),i=0,n=d.length;n>i;++i)r.updateElement(d[i],i,t);for(g&&0!==s._model.tension&&r.updateBezierControlPoints(),i=0,n=d.length;n>i;++i)d[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.backgroundColor:n.pointBackgroundColor?i=a.getValueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),o=t.custom||{};return o.borderColor?i=o.borderColor:n.pointBorderColor?i=a.getValueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),o=t.custom||{};return o.borderWidth?i=o.borderWidth:n.pointBorderWidth?i=a.getValueAtIndexOrDefault(n.pointBorderWidth,e,i):n.borderWidth&&(i=n.borderWidth),i},updateElement:function(t,e,i){var n,o,r=this,l=r.getMeta(),s=t.custom||{},d=r.getDataset(),u=r.index,c=d.data[e],h=r.getScaleForId(l.yAxisID),f=r.getScaleForId(l.xAxisID),g=r.chart.options.elements.point;void 0!==d.radius&&void 0===d.pointRadius&&(d.pointRadius=d.radius),void 0!==d.hitRadius&&void 0===d.pointHitRadius&&(d.pointHitRadius=d.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,u,r.chart.isCombo),o=i?h.getBasePixel():r.calculatePointY(c,e,u),t._xScale=f,t._yScale=h,t._datasetIndex=u,t._index=e,t._model={x:n,y:o,skip:s.skip||isNaN(n)||isNaN(o),radius:s.radius||a.getValueAtIndexOrDefault(d.pointRadius,e,g.radius),pointStyle:s.pointStyle||a.getValueAtIndexOrDefault(d.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:l.dataset._model?l.dataset._model.tension:0,steppedLine:l.dataset._model?l.dataset._model.steppedLine:!1,hitRadius:s.hitRadius||a.getValueAtIndexOrDefault(d.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,a){var i,n,o,r=this,l=r.chart,s=r.getMeta(),d=r.getScaleForId(s.yAxisID),u=0,c=0;if(d.options.stacked){for(i=0;a>i;i++)if(n=l.data.datasets[i],o=l.getDatasetMeta(i),"line"===o.type&&o.yAxisID===d.id&&l.isDatasetVisible(i)){var h=Number(d.getRightValue(n.data[e]));0>h?c+=h||0:u+=h||0}var f=Number(d.getRightValue(t));return 0>f?d.getPixelForValue(c+f):d.getPixelForValue(u+f)}return d.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,a){return c?Math.max(Math.min(t,a),e):t}var e,i,n,o,r,l=this,s=l.getMeta(),d=l.chart.chartArea,u=(s.data||[]).filter(function(t){return!t._model.skip}),c=l.chart.options.elements.line.capBezierPoints;for(e=0,i=u.length;i>e;++e)n=u[e],o=n._model,r=a.splineCurve(a.previousItem(u,e)._model,o,a.nextItem(u,e)._model,s.dataset._model.tension),o.controlPointPreviousX=t(r.previous.x,d.left,d.right),o.controlPointPreviousY=t(r.previous.y,d.top,d.bottom),o.controlPointNextX=t(r.next.x,d.left,d.right),o.controlPointNextY=t(r.next.y,d.top,d.bottom)},draw:function(t){var a,i,n=this,o=n.getMeta(),r=o.data||[],l=t||1;for(a=0,i=r.length;i>a;++a)r[a].transition(l);for(e(n.getDataset(),n.chart.options)&&o.dataset.transition(l).draw(),a=0,i=r.length;i>a;++a)r[a].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.radius=n.hoverRadius||a.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=n.hoverBackgroundColor||a.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,a.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor||a.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,a.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth||a.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||a.getValueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{}],19:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0,ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'">'),n[o]&&e.push(n[o]),e.push("</span></li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],l=o.data[n],s=l.custom||{},d=e.getValueAtIndexOrDefault,u=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:d(r.backgroundColor,n,u.backgroundColor),h=s.borderColor?s.borderColor:d(r.borderColor,n,u.borderColor),f=s.borderWidth?s.borderWidth:d(r.borderWidth,n,u.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;i>a;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var a=this,i=a.chart,n=i.chartArea,o=a.getMeta(),r=i.options,l=r.elements.arc,s=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((s-l.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),a.outerRadius=i.outerRadius-i.radiusLength*a.index,a.innerRadius=a.outerRadius-i.radiusLength,o.count=a.countVisibleElements(),e.each(o.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){for(var n=this,o=n.chart,r=n.getDataset(),l=o.options,s=l.animation,d=o.scale,u=e.getValueAtIndexOrDefault,c=o.data.labels,h=n.calculateCircumference(r.data[a]),f=d.xCenter,g=d.yCenter,p=0,m=n.getMeta(),b=0;a>b;++b)isNaN(r.data[b])||m.data[b].hidden||++p;var v=l.startAngle,x=t.hidden?0:d.getDistanceFromCenterForValue(r.data[a]),y=v+h*p,k=y+(t.hidden?0:h),S=s.animateScale?0:d.getDistanceFromCenterForValue(r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:d,_model:{x:f,y:g,innerRadius:0,outerRadius:i?S:x,startAngle:i&&s.animateRotate?v:y,endAngle:i&&s.animateRotate?v:k,label:u(c,a,c[a])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),a=this.getMeta(),i=0;return e.each(a.data,function(e,a){isNaN(t.data[a])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,addElementAndReset:function(e){t.DatasetController.prototype.addElementAndReset.call(this,e),this.updateBezierControlPoints()},update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},l=a.getDataset(),s=a.chart.options.elements.line,d=a.chart.scale;void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(l.lineTension,s.tension),backgroundColor:r.backgroundColor?r.backgroundColor:l.backgroundColor||s.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:l.borderWidth||s.borderWidth,borderColor:r.borderColor?r.borderColor:l.borderColor||s.borderColor,fill:r.fill?r.fill:void 0!==l.fill?l.fill:s.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:l.borderCapStyle||s.borderCapStyle,borderDash:r.borderDash?r.borderDash:l.borderDash||s.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:l.borderDashOffset||s.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:l.borderJoinStyle||s.borderJoinStyle,scaleTop:d.top,scaleBottom:d.bottom,scaleZero:d.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),l=n.chart.scale,s=n.chart.options.elements.point,d=l.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:l,_model:{x:i?l.xCenter:d.x,y:i?l.yCenter:d.y,tension:o.tension?o.tension:e.getValueOrDefault(r.tension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,s.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,s.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,s.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,s.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,s.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,s.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o<n.animations.length;++o)if(n.animations[o].chartInstance===t)return void(n.animations[o].animationObject=e);n.animations.push({chartInstance:t,animationObject:e}),1===n.animations.length&&n.requestAnimationFrame()},cancelAnimation:function(t){var a=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==a&&(this.animations.splice(a,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),a=0;t.dropFrames>1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+a,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(t,e,a,i,n){var o,r,l,s,d,u;if("object"==typeof e&&(o=e.toString(),"[object HTMLImageElement]"===o||"[object HTMLCanvasElement]"===o))return void t.drawImage(e,i-e.width/2,n-e.height/2);if(!(isNaN(a)||0>=a)){switch(e){default:t.beginPath(),t.arc(i,n,a,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),r=3*a/Math.sqrt(3),d=r*Math.sqrt(3)/2,t.moveTo(i-r/2,n+d/3),t.lineTo(i+r/2,n+d/3),t.lineTo(i,n-2*d/3),t.closePath(),t.fill();break;case"rect":u=1/Math.SQRT2*a,t.beginPath(),t.fillRect(i-u,n-u,2*u,2*u),t.strokeRect(i-u,n-u,2*u,2*u);break;case"rectRot":u=1/Math.SQRT2*a,t.beginPath(),t.moveTo(i-u,n),t.lineTo(i,n+u),t.lineTo(i+u,n),t.lineTo(i,n-u),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,n+a),t.lineTo(i,n-a),t.moveTo(i-a,n),t.lineTo(i+a,n),t.closePath();break;case"crossRot":t.beginPath(),l=Math.cos(Math.PI/4)*a,s=Math.sin(Math.PI/4)*a,t.moveTo(i-l,n-s),t.lineTo(i+l,n+s),t.moveTo(i-l,n+s),t.lineTo(i+l,n-s),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,n+a),t.lineTo(i,n-a),t.moveTo(i-a,n),t.lineTo(i+a,n),l=Math.cos(Math.PI/4)*a,s=Math.sin(Math.PI/4)*a,t.moveTo(i-l,n-s),t.lineTo(i+l,n+s),t.moveTo(i-l,n+s),t.lineTo(i+l,n-s),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-a,n),t.lineTo(i+a,n),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,n),t.lineTo(i+a,n),t.closePath()}t.stroke()}}}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(a){return this.chart=a,this.config=a.config,this.options=this.config.options=e.configMerge(t.defaults.global,t.defaults[this.config.type],this.config.options||{}),this.id=e.uid(),Object.defineProperty(this,"data",{get:function(){return this.config.data}}),t.instances[this.id]=this,this.options.responsive&&this.resize(!0),this.initialize(),this},e.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return e.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(a){var i=this,n=i.chart,o=n.canvas,r=e.getMaximumWidth(o),l=n.aspectRatio,s=i.options.maintainAspectRatio&&isNaN(l)===!1&&isFinite(l)&&0!==l?r/l:e.getMaximumHeight(o),d=n.width!==r||n.height!==s;if(!d)return i;o.width=n.width=r,o.height=n.height=s,e.retinaScale(n);var u={width:r,height:s};return t.plugins.notify("resize",[i,u]),i.options.onResize&&i.options.onResize(i,u),a||(i.stop(),i.update(i.options.responsiveAnimationDuration)),i},ensureScalesHaveIDs:function(){var t=this.options,a=t.scales||{},i=t.scale;e.each(a.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),e.each(a.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildScales:function(){var a=this,i=a.options,n=a.scales={},o=[];i.scales&&(o=o.concat((i.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(i.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),i.scale&&o.push({options:i.scale,dtype:"radialLinear",isDefault:!0}),e.each(o,function(i){var o=i.options,r=e.getValueOrDefault(o.type,i.dtype),l=t.scaleService.getScaleConstructor(r);if(l){var s=new l({id:o.id,options:o,ctx:a.chart.ctx,chart:a});n[s.id]=s,i.isDefault&&(a.scale=s)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var a=this,i=[],n=[];if(e.each(a.data.datasets,function(e,o){var r=a.getDatasetMeta(o);r.type||(r.type=e.type||a.config.type),i.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](a,o),n.push(r.controller))},a),i.length>1)for(var o=1;o<i.length;o++)if(i[o]!==i[o-1]){a.isCombo=!0;break}return n},resetElements:function(){var t=this;e.each(t.data.datasets,function(e,a){t.getDatasetMeta(a).controller.reset()},t)},update:function(a,i){var n=this;t.plugins.notify("beforeUpdate",[n]),n.tooltip._data=n.data;var o=n.buildOrUpdateControllers();e.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.buildOrUpdateElements()},n),t.layoutService.update(n,n.chart.width,n.chart.height),t.plugins.notify("afterScaleUpdate",[n]),e.each(o,function(t){t.reset()}),n.updateDatasets(),t.plugins.notify("afterUpdate",[n]),n.render(a,i)},updateDatasets:function(){var e,a,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,a=i.data.datasets.length;a>e;++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(a,i){var n=this;t.plugins.notify("beforeRender",[n]);var o=n.options.animation;if(o&&("undefined"!=typeof a&&0!==a||"undefined"==typeof a&&0!==o.duration)){var r=new t.Animation;r.numSteps=(a||o.duration)/16.66,r.easing=o.easing,r.render=function(t,a){var i=e.easingEffects[a.easing],n=a.currentStep/a.numSteps,o=i(n);t.draw(o,n,a.currentStep)},r.onAnimationProgress=o.onProgress,r.onAnimationComplete=o.onComplete,t.animationService.addAnimation(n,r,a,i)}else n.draw(),o&&o.onComplete&&o.onComplete.call&&o.onComplete.call(n);return n},draw:function(a){var i=this,n=a||1;i.clear(),t.plugins.notify("beforeDraw",[i,n]),e.each(i.boxes,function(t){t.draw(i.chartArea)},i),i.scale&&i.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[i,n]),e.each(i.data.datasets,function(t,e){i.isDatasetVisible(e)&&i.getDatasetMeta(e).controller.draw(a)},i,!0),t.plugins.notify("afterDatasetsDraw",[i,n]),i.tooltip.transition(n).draw(),t.plugins.notify("afterDraw",[i,n])},getElementAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[];return e.each(a.data.datasets,function(t,o){if(a.isDatasetVisible(o)){var r=a.getDatasetMeta(o);e.each(r.data,function(t){return t.inRange(i.x,i.y)?(n.push(t),n):void 0})}}),n.slice(0,1)},getElementsAtEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[],o=function(){if(a.data.datasets)for(var t=0;t<a.data.datasets.length;t++){var e=a.getDatasetMeta(t);if(a.isDatasetVisible(t))for(var n=0;n<e.data.length;n++)if(e.data[n].inRange(i.x,i.y))return e.data[n]}}.call(a);return o?(e.each(a.data.datasets,function(t,e){if(a.isDatasetVisible(e)){var i=a.getDatasetMeta(e),r=i.data[o._index];r&&!r._view.skip&&n.push(r)}},a),n):n},getElementsAtXAxis:function(t){var a=this,i=e.getRelativePosition(t,a.chart),n=[],o=function(){if(a.data.datasets)for(var t=0;t<a.data.datasets.length;t++){var e=a.getDatasetMeta(t);if(a.isDatasetVisible(t))for(var n=0;n<e.data.length;n++)if(e.data[n].inLabelRange(i.x,i.y))return e.data[n]}}.call(a);return o?(e.each(a.data.datasets,function(t,i){if(a.isDatasetVisible(i)){var r=a.getDatasetMeta(i),l=e.findIndex(r.data,function(t){return o._model.x===t._model.x});-1===l||r.data[l]._view.skip||n.push(r.data[l])}},a),n):n},getElementsAtEventForMode:function(t,e){var a=this;switch(e){case"single":return a.getElementAtEvent(t);case"label":return a.getElementsAtEvent(t);case"dataset":return a.getDatasetAtEvent(t);case"x-axis":return a.getElementsAtXAxis(t);default:return t}},getDatasetAtEvent:function(t){var e=this.getElementAtEvent(t);return e.length>0&&(e=this.getDatasetMeta(e[0]._datasetIndex).data),e},getDatasetMeta:function(t){var e=this,a=e.data.datasets[t];a._meta||(a._meta={});var i=a._meta[e.id];return i||(i=a._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,a=this.data.datasets.length;a>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden;
-},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var a=this;a.stop(),a.clear(),e.unbindEvents(a,a.events),e.removeResizeListener(a.chart.canvas.parentNode);var i=a.chart.canvas;i.width=a.chart.width,i.height=a.chart.height,void 0!==a.chart.originalDevicePixelRatio&&a.chart.ctx.scale(1/a.chart.originalDevicePixelRatio,1/a.chart.originalDevicePixelRatio),i.style.width=a.chart.originalCanvasStyleWidth,i.style.height=a.chart.originalCanvasStyleHeight,t.plugins.notify("destroy",[a]),delete t.instances[a.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this;e.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,a){var i,n,o,r=a?"setHoverStyle":"removeHoverStyle";switch(e){case"single":t=[t[0]];break;case"label":case"dataset":case"x-axis":break;default:return}for(n=0,o=t.length;o>n;++n)i=t[n],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var a=this,i=a.tooltip,n=a.options||{},o=n.hover,r=n.tooltips;return a.lastActive=a.lastActive||[],a.lastTooltipActive=a.lastTooltipActive||[],"mouseout"===t.type?(a.active=[],a.tooltipActive=[]):(a.active=a.getElementsAtEventForMode(t,o.mode),a.tooltipActive=a.getElementsAtEventForMode(t,r.mode)),o.onHover&&o.onHover.call(a,a.active),("mouseup"===t.type||"click"===t.type)&&(n.onClick&&n.onClick.call(a,t,a.active),a.legend&&a.legend.handleEvent&&a.legend.handleEvent(t)),a.lastActive.length&&a.updateHoverStyle(a.lastActive,o.mode,!1),a.active.length&&o.mode&&a.updateHoverStyle(a.active,o.mode,!0),(r.enabled||r.custom)&&(i.initialize(),i._active=a.tooltipActive,i.update(!0)),i.pivot(),a.animating||e.arrayEquals(a.active,a.lastActive)&&e.arrayEquals(a.tooltipActive,a.lastTooltipActive)||(a.stop(),(r.enabled||r.custom)&&i.update(!0),a.render(o.animationDuration,!0)),a.lastActive=a.active,a.lastTooltipActive=a.tooltipActive,a}})}},{}],24:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.DatasetController=function(t,e){this.initialize.call(this,t,e)},e.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;e>t;++t)o[t]=o[t]||a.createMetaData(i,t);i.dataset=i.dataset||a.createMetaDataset()},addElementAndReset:function(t){var e=this,a=e.createMetaData(t);e.getMeta().data.splice(t,0,a),e.updateElement(a,t,!0)},buildOrUpdateElements:function(){var t=this.getMeta(),e=t.data,a=this.getDataset().data.length,i=e.length;if(i>a)e.splice(a,i-a);else if(a>i)for(var n=i;a>n;++n)this.addElementAndReset(n)},update:a,draw:function(t){var a=t||1;e.each(this.getMeta().data,function(t){t.transition(a).draw()})},removeHoverStyle:function(t,a){var i=this.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=e.getValueAtIndexOrDefault,l=t._model;l.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,n,a.backgroundColor),l.borderColor=o.borderColor?o.borderColor:r(i.borderColor,n,a.borderColor),l.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,n,a.borderWidth)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=e.getValueAtIndexOrDefault,r=e.getHoverColor,l=t._model;l.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o(a.hoverBackgroundColor,i,r(l.backgroundColor)),l.borderColor=n.hoverBorderColor?n.hoverBorderColor:o(a.hoverBorderColor,i,r(l.borderColor)),l.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o(a.hoverBorderWidth,i,l.borderWidth)}}),t.DatasetController.extend=e.inherits}},{}],25:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var a=this;return a._view||(a._view=e.clone(a._model)),1===t?(a._view=a._model,a._start=null,a):(a._start||a.pivot(),e.each(a._model,function(i,n){if("_"===n[0]);else if(a._view.hasOwnProperty(n))if(i===a._view[n]);else if("string"==typeof i)try{var o=e.color(a._model[n]).mix(e.color(a._start[n]),t);a._view[n]=o.rgbString()}catch(r){a._view[n]=i}else if("number"==typeof i){var l=void 0!==a._start[n]&&isNaN(a._start[n])===!1?a._start[n]:0;a._view[n]=(a._model[n]-l)*t+l}else a._view[n]=i;else"number"!=typeof i||isNaN(a._view[n])?a._view[n]=i:a._view[n]=i*t},a),a)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],26:[function(t,e,a){"use strict";var i=t(3);e.exports=function(t){function e(t,e,a){var i;return"string"==typeof t?(i=parseInt(t,10),-1!=t.indexOf("%")&&(i=i/100*e.parentNode[a])):i=t,i}function a(t){return void 0!==t&&null!==t&&"none"!==t}function n(t,i,n){var o=document.defaultView,r=t.parentNode,l=o.getComputedStyle(t)[i],s=o.getComputedStyle(r)[i],d=a(l),u=a(s),c=Number.POSITIVE_INFINITY;return d||u?Math.min(d?e(l,t,n):c,u?e(s,r,n):c):"none"}var o=t.helpers={};o.each=function(t,e,a,i){var n,r;if(o.isArray(t))if(r=t.length,i)for(n=r-1;n>=0;n--)e.call(a,t[n],n);else for(n=0;r>n;n++)e.call(a,t[n],n);else if("object"==typeof t){var l=Object.keys(t);for(r=l.length,n=0;r>n;n++)e.call(a,t[l[n]],l[n])}},o.clone=function(t){var e={};return o.each(t,function(t,a){o.isArray(t)?e[a]=t.slice(0):"object"==typeof t&&null!==t?e[a]=o.clone(t):e[a]=t}),e},o.extend=function(t){for(var e=function(e,a){t[a]=e},a=1,i=arguments.length;i>a;a++)o.each(arguments[a],e);return t},o.configMerge=function(e){var a=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){if("scales"===i)a[i]=o.scaleMerge(a.hasOwnProperty(i)?a[i]:{},e);else if("scale"===i)a[i]=o.configMerge(a.hasOwnProperty(i)?a[i]:{},t.scaleService.getScaleDefaults(e.type),e);else if(a.hasOwnProperty(i)&&o.isArray(a[i])&&o.isArray(e)){var n=a[i];o.each(e,function(t,e){e<n.length?"object"==typeof n[e]&&null!==n[e]&&"object"==typeof t&&null!==t?n[e]=o.configMerge(n[e],t):n[e]=t:n.push(t)})}else a.hasOwnProperty(i)&&"object"==typeof a[i]&&null!==a[i]&&"object"==typeof e?a[i]=o.configMerge(a[i],e):a[i]=e})}),a},o.scaleMerge=function(e,a){var i=o.clone(e);return o.each(a,function(e,a){"xAxes"===a||"yAxes"===a?i.hasOwnProperty(a)?o.each(e,function(e,n){var r=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear"),l=t.scaleService.getScaleDefaults(r);n>=i[a].length||!i[a][n].type?i[a].push(o.configMerge(l,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],l,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e<t.length?t[e]:a:t},o.getValueOrDefault=function(t,e){return void 0===t?e:t},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var a=0,i=t.length;i>a;++a)if(t[a]===e)return a;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var a=[];return o.each(t,function(t){e(t)&&a.push(t)}),a},o.findIndex=Array.prototype.findIndex?function(t,e,a){return t.findIndex(e,a)}:function(t,e,a){a=void 0===a?t:a;for(var i=0,n=t.length;n>i;++i)if(e.call(a,t[i],i,t))return i;return-1},o.findNextWhere=function(t,e,a){(void 0===a||null===a)&&(a=-1);for(var i=a+1;i<t.length;i++){var n=t[i];if(e(n))return n}},o.findPreviousWhere=function(t,e,a){(void 0===a||null===a)&&(a=t.length);for(var i=a-1;i>=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)<a},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,l=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),s=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),d=l/(l+s),u=s/(l+s);d=isNaN(d)?0:d,u=isNaN(u)?0:u;var c=i*d,h=i*u;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.nextItem=function(t,e,a){return a?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?1.5>n?1:3>n?2:7>n?5:10:1>=n?1:2>=n?2:5>=n?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)))},easeOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/a)+1)},easeInOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:2===(t/=.5)?1:(a||(a=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var a,i,n=t.originalEvent||t,r=t.currentTarget||t.srcElement,l=r.getBoundingClientRect(),s=n.touches;s&&s.length>0?(a=s[0].clientX,i=s[0].clientY):(a=n.clientX,i=n.clientY);var d=parseFloat(o.getStyle(r,"padding-left")),u=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=l.right-l.left-d-c,g=l.bottom-l.top-u-h;return a=Math.round((a-l.left-d)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-l.top-u)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.bindEvents=function(t,e,a){var i=t.events=t.events||{};o.each(e,function(e){i[e]=function(){a.apply(t,arguments)},o.addEvent(t.chart.canvas,e,i[e])})},o.unbindEvents=function(t,e){var a=t.chart.canvas;o.each(e,function(t,e){o.removeEvent(a,e,t)})},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"))+parseInt(o.getStyle(e,"padding-right")),i=e.clientWidth-a,n=o.getConstraintWidth(t);return isNaN(n)?i:Math.min(i,n)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"))+parseInt(o.getStyle(e,"padding-bottom")),i=e.clientHeight-a,n=o.getConstraintHeight(t);return isNaN(n)?i:Math.min(i,n)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.ctx,a=t.canvas,i=a.width,n=a.height,o=t.currentDevicePixelRatio=window.devicePixelRatio||1;1!==o&&(a.height=n*o,a.width=i*o,e.scale(o,o),t.originalDevicePixelRatio=t.originalDevicePixelRatio||o),a.style.width=i+"px",a.style.height=n+"px"},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var l=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?l=o.measureText(t,n,r,l,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(l=o.measureText(t,n,r,l,e))})});var s=r.length/2;if(s>a.length){for(var d=0;s>d;d++)delete n[r[d]];r.splice(0,s)}return l},o.measureText=function(t,e,a,i,n){var o=e[n];return o||(o=e[n]=t.measureText(n).width,a.push(n)),o>i&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.log("Color.js not found!"),e)},o.addResizeListener=function(t,e){var a=document.createElement("iframe"),i="chartjs-hidden-iframe";a.classlist?a.classlist.add(i):a.setAttribute("class",i);var n=a.style;n.width="100%",n.display="block",n.border=0,n.height=0,n.margin=0,n.position="absolute",n.left=0,n.right=0,n.top=0,n.bottom=0,t.insertBefore(a,t.firstChild),(a.contentWindow||a).onresize=function(){e&&e()}},o.removeResizeListener=function(t){var e=t.querySelector(".chartjs-hidden-iframe");e&&e.parentNode.removeChild(e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!=e.length)return!1;for(a=0,i=t.length;i>a;++a)if(n=t[a],r=e[a],n instanceof Array&&r instanceof Array){if(!o.arrayEquals(n,r))return!1}else if(n!=r)return!1;return!0},o.callCallback=function(t,e,a){t&&"function"==typeof t.call&&t.apply(a,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{3:3}],27:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){var i=this,n=t.helpers;return i.config=a||{data:{datasets:[]}},e.length&&e[0].getContext&&(e=e[0]),e.getContext&&(e=e.getContext("2d")),i.ctx=e,i.canvas=e.canvas,e.canvas.style.display=e.canvas.style.display||"block",i.width=e.canvas.width||parseInt(n.getStyle(e.canvas,"width"),10)||n.getMaximumWidth(e.canvas),i.height=e.canvas.height||parseInt(n.getStyle(e.canvas,"height"),10)||n.getMaximumHeight(e.canvas),i.aspectRatio=i.width/i.height,(isNaN(i.aspectRatio)||isFinite(i.aspectRatio)===!1)&&(i.aspectRatio=void 0!==a.aspectRatio?a.aspectRatio:2),i.originalCanvasStyleWidth=e.canvas.style.width,i.originalCanvasStyleHeight=e.canvas.style.height,n.retinaScale(i),i.controller=new t.Controller(i),n.addResizeListener(e.canvas.parentNode,function(){i.controller&&i.controller.config.options.responsive&&i.controller.resize()}),i.controller?i.controller:i};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"single",animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var a=0;a<t.data.datasets.length;a++)e.push('<li><span style="background-color:'+t.data.datasets[a].backgroundColor+'"></span>'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],28:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?p:k,y),S-=e.height):(e=t.update(x,v),k-=e.width),w.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(w,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:C,right:M,top:0,bottom:0};t.update(t.options.fullWidth?p:k,m/2,i)}else t.update(a.minSize.width,S)}function r(t){var a=e.findNextWhere(w,function(e){return e.box===t}),i={left:0,right:0,top:D,bottom:A};a&&t.update(a.minSize.width,S,i)}function l(t){t.isHorizontal()?(t.left=t.options.fullWidth?s:C,t.right=t.options.fullWidth?a-s:C+k,t.top=P,t.bottom=P+t.height,P=t.bottom):(t.left=F,t.right=F+t.width,t.top=D,t.bottom=D+S,F=t.right)}if(t){var s=0,d=0,u=e.where(t.boxes,function(t){return"left"===t.options.position}),c=e.where(t.boxes,function(t){return"right"===t.options.position}),h=e.where(t.boxes,function(t){return"top"===t.options.position}),f=e.where(t.boxes,function(t){return"bottom"===t.options.position}),g=e.where(t.boxes,function(t){return"chartArea"===t.options.position});h.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),f.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var p=a-2*s,m=i-2*d,b=p/2,v=m/2,x=(a-b)/(u.length+c.length),y=(i-v)/(h.length+f.length),k=p,S=m,w=[];e.each(u.concat(c,h,f),n);var C=s,M=s,D=d,A=d;e.each(u.concat(c),o),e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h.concat(f),o),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height}),e.each(u.concat(c),r),C=s,M=s,D=d,A=d,e.each(u,function(t){C+=t.width}),e.each(c,function(t){M+=t.width}),e.each(h,function(t){D+=t.height}),e.each(f,function(t){A+=t.height});var I=i-D-A,T=a-C-M;(T!==k||I!==S)&&(e.each(u,function(t){t.height=I}),e.each(c,function(t){t.height=I}),e.each(h,function(t){t.options.fullWidth||(t.width=T)}),e.each(f,function(t){t.options.fullWidth||(t.width=T)}),S=I,k=T);var F=s,P=d;e.each(u.concat(h),l),F+=k,P+=S,e.each(c,l),e.each(f,l),t.chartArea={left:C,top:D,right:C+k,bottom:D+S},e.each(g,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(k,S)})}}}}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},labels:{boxWidth:40,padding:10,generateLabels:function(t){var a=t.data;return e.isArray(a.datasets)?a.datasets.map(function(a,i){return{text:a.label,fillStyle:e.isArray(a.backgroundColor)?a.backgroundColor[0]:a.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){e.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:a,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=a.options,n=i.labels,o=i.display,r=a.ctx,l=t.defaults.global,s=e.getValueOrDefault,d=s(n.fontSize,l.defaultFontSize),u=s(n.fontStyle,l.defaultFontStyle),c=s(n.fontFamily,l.defaultFontFamily),h=e.fontString(d,u,c),f=a.legendHitBoxes=[],g=a.minSize,p=a.isHorizontal();if(p?(g.width=a.maxWidth,g.height=o?10:0):(g.width=o?10:0,g.height=a.maxHeight),o)if(r.font=h,p){var m=a.lineWidths=[0],b=a.legendItems.length?d+n.padding:0;r.textAlign="left",r.textBaseline="top",e.each(a.legendItems,function(t,e){var i=n.usePointStyle?d*Math.sqrt(2):n.boxWidth,o=i+d/2+r.measureText(t.text).width;m[m.length-1]+o+n.padding>=a.width&&(b+=d+n.padding,m[m.length]=a.left),f[e]={left:0,top:0,width:o,height:d},m[m.length-1]+=o+n.padding}),g.height+=b}else{var v=n.padding,x=a.columnWidths=[],y=n.padding,k=0,S=0,w=d+v;e.each(a.legendItems,function(t,e){var a=n.usePointStyle?2*n.boxWidth:n.boxWidth,i=a+d/2+r.measureText(t.text).width;S+w>g.height&&(y+=k+n.padding,x.push(k),k=0,S=0),k=Math.max(k,i),S+=w,f[e]={left:0,top:0,width:i,height:d}}),y+=k,x.push(k),g.width+=y}a.width=g.width,a.height=g.height},afterFit:a,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,i=a.options,n=i.labels,o=t.defaults.global,r=o.elements.line,l=a.width,s=a.lineWidths;if(i.display){var d,u=a.ctx,c=e.getValueOrDefault,h=c(n.fontColor,o.defaultFontColor),f=c(n.fontSize,o.defaultFontSize),g=c(n.fontStyle,o.defaultFontStyle),p=c(n.fontFamily,o.defaultFontFamily),m=e.fontString(f,g,p);u.textAlign="left",u.textBaseline="top",u.lineWidth=.5,u.strokeStyle=h,u.fillStyle=h,u.font=m;var b=n.boxWidth,v=a.legendHitBoxes,x=function(e,a,n){if(!(isNaN(b)||0>=b)){if(u.save(),u.fillStyle=c(n.fillStyle,o.defaultColor),u.lineCap=c(n.lineCap,r.borderCapStyle),u.lineDashOffset=c(n.lineDashOffset,r.borderDashOffset),u.lineJoin=c(n.lineJoin,r.borderJoinStyle),u.lineWidth=c(n.lineWidth,r.borderWidth),u.strokeStyle=c(n.strokeStyle,o.defaultColor),u.setLineDash&&u.setLineDash(c(n.lineDash,r.borderDash)),i.labels&&i.labels.usePointStyle){var l=f*Math.SQRT2/2,s=l/Math.SQRT2,d=e+s,h=a+s;t.canvasHelpers.drawPoint(u,n.pointStyle,l,d,h)}else u.strokeRect(e,a,b,f),u.fillRect(e,a,b,f);u.restore()}},y=function(t,e,a,i){u.fillText(a.text,b+f/2+t,e),a.hidden&&(u.beginPath(),u.lineWidth=2,u.moveTo(b+f/2+t,e+f/2),u.lineTo(b+f/2+t+i,e+f/2),u.stroke())},k=a.isHorizontal();d=k?{x:a.left+(l-s[0])/2,y:a.top+n.padding,line:0}:{x:a.left+n.padding,y:a.top+n.padding,line:0};var S=f+n.padding;e.each(a.legendItems,function(t,e){var i=u.measureText(t.text).width,o=n.usePointStyle?f+f/2+i:b+f/2+i,r=d.x,c=d.y;k?r+o>=l&&(c=d.y+=S,d.line++,r=d.x=a.left+(l-s[d.line])/2):c+S>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+n.padding,c=d.y=a.top,d.line++),x(r,c,t),v[e].left=r,v[e].top=c,y(r,c,t,i),k?d.x+=o+n.padding:d.y+=S})}},handleEvent:function(t){var a=this,i=e.getRelativePosition(t,a.chart.chart),n=i.x,o=i.y,r=a.options;if(n>=a.left&&n<=a.right&&o>=a.top&&o<=a.bottom)for(var l=a.legendHitBoxes,s=0;s<l.length;++s){var d=l[s];if(n>=d.left&&n<=d.left+d.width&&o>=d.top&&o<=d.top+d.height){r.onClick&&r.onClick.call(a,t,a.legendItems[s]);break}}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);-1!==a&&e.splice(a,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var a,i,n=this._plugins,o=n.length;for(a=0;o>a;++a)if(i=n[a],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:function(t){return e.isArray(t)?t:""+t}}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,a,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=a,n.margins=e.extend({left:0,right:0,top:0,bottom:0},i),n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeDataLimits(),n.determineDataLimits(),n.afterDataLimits(),n.beforeBuildTicks(),n.buildTicks(),n.afterBuildTicks(),n.beforeTickToLabelConversion(),n.convertTicksToLabels(),n.afterTickToLabelConversion(),n.beforeCalculateTickRotation(),n.calculateTickRotation(),n.afterCalculateTickRotation(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this;t.ticks=t.ticks.map(function(e,a,i){return t.options.ticks.userCallback?t.options.ticks.userCallback(e,a,i):t.options.ticks.callback(e,a,i)},t)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var a=this,i=a.ctx,n=t.defaults.global,o=a.options.ticks,r=e.getValueOrDefault(o.fontSize,n.defaultFontSize),l=e.getValueOrDefault(o.fontStyle,n.defaultFontStyle),s=e.getValueOrDefault(o.fontFamily,n.defaultFontFamily),d=e.fontString(r,l,s);i.font=d;var u,c=i.measureText(a.ticks[0]).width,h=i.measureText(a.ticks[a.ticks.length-1]).width;if(a.labelRotation=o.minRotation||0,a.paddingRight=0,a.paddingLeft=0,a.options.display&&a.isHorizontal()){a.paddingRight=h/2+3,a.paddingLeft=c/2+3,a.longestTextCache||(a.longestTextCache={});for(var f,g,p=e.longestText(i,d,a.ticks,a.longestTextCache),m=p,b=a.getPixelForTick(1)-a.getPixelForTick(0)-6;m>b&&a.labelRotation<o.maxRotation;){if(f=Math.cos(e.toRadians(a.labelRotation)),g=Math.sin(e.toRadians(a.labelRotation)),u=f*c,u+r/2>a.yLabelWidth&&(a.paddingLeft=u+r/2),a.paddingRight=r/2,g*p>a.maxHeight){a.labelRotation--;break}a.labelRotation++,m=f*p}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this]);
-},fit:function(){var a=this,i=a.minSize={width:0,height:0},n=a.options,o=t.defaults.global,r=n.ticks,l=n.scaleLabel,s=n.display,d=a.isHorizontal(),u=e.getValueOrDefault(r.fontSize,o.defaultFontSize),c=e.getValueOrDefault(r.fontStyle,o.defaultFontStyle),h=e.getValueOrDefault(r.fontFamily,o.defaultFontFamily),f=e.fontString(u,c,h),g=e.getValueOrDefault(l.fontSize,o.defaultFontSize),p=n.gridLines.tickMarkLength;if(d?i.width=a.isFullWidth()?a.maxWidth-a.margins.left-a.margins.right:a.maxWidth:i.width=s?p:0,d?i.height=s?p:0:i.height=a.maxHeight,l.display&&s&&(d?i.height+=1.5*g:i.width+=1.5*g),r.display&&s){a.longestTextCache||(a.longestTextCache={});var m=e.longestText(a.ctx,f,a.ticks,a.longestTextCache),b=e.numberOfLabelLines(a.ticks),v=.5*u;if(d){a.longestLabelWidth=m;var x=Math.sin(e.toRadians(a.labelRotation))*a.longestLabelWidth+u*b+v*b;i.height=Math.min(a.maxHeight,i.height+x),a.ctx.font=f;var y=a.ctx.measureText(a.ticks[0]).width,k=a.ctx.measureText(a.ticks[a.ticks.length-1]).width,S=Math.cos(e.toRadians(a.labelRotation)),w=Math.sin(e.toRadians(a.labelRotation));a.paddingLeft=0!==a.labelRotation?S*y+3:y/2+3,a.paddingRight=0!==a.labelRotation?w*(u/2)+3:k/2+3}else{var C=a.maxWidth-i.width,M=r.mirror;M?m=0:m+=a.options.ticks.padding,C>m?i.width+=m:i.width=a.maxWidth,a.paddingTop=u/2,a.paddingBottom=u/2}}a.margins&&(a.paddingLeft=Math.max(a.paddingLeft-a.margins.left,0),a.paddingTop=Math.max(a.paddingTop-a.margins.top,0),a.paddingRight=Math.max(a.paddingRight-a.margins.right,0),a.paddingBottom=Math.max(a.paddingBottom-a.margins.bottom,0)),a.width=i.width,a.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"==typeof t&&isNaN(t)?NaN:"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var l=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(l/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,a=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(a){var i=this,n=i.options;if(n.display){var o,r,l=i.ctx,s=t.defaults.global,d=n.ticks,u=n.gridLines,c=n.scaleLabel,h=0!==i.labelRotation,f=d.autoSkip,g=i.isHorizontal();d.maxTicksLimit&&(r=d.maxTicksLimit);var p=e.getValueOrDefault(d.fontColor,s.defaultFontColor),m=e.getValueOrDefault(d.fontSize,s.defaultFontSize),b=e.getValueOrDefault(d.fontStyle,s.defaultFontStyle),v=e.getValueOrDefault(d.fontFamily,s.defaultFontFamily),x=e.fontString(m,b,v),y=u.tickMarkLength,k=e.getValueOrDefault(c.fontColor,s.defaultFontColor),S=e.getValueOrDefault(c.fontSize,s.defaultFontSize),w=e.getValueOrDefault(c.fontStyle,s.defaultFontStyle),C=e.getValueOrDefault(c.fontFamily,s.defaultFontFamily),M=e.fontString(S,w,C),D=e.toRadians(i.labelRotation),A=Math.cos(D),I=i.longestLabelWidth*A;l.fillStyle=p;var T=[];if(g){if(o=!1,h&&(I/=2),(I+d.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(o=1+Math.floor((I+d.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),r&&i.ticks.length>r)for(;!o||i.ticks.length/(o||1)>r;)o||(o=1),o+=1;f||(o=!1)}var F="right"===n.position?i.left:i.right-y,P="right"===n.position?i.left+y:i.right,R="bottom"===n.position?i.top:i.bottom-y,_="bottom"===n.position?i.top+y:i.bottom;if(e.each(i.ticks,function(t,r){if(void 0!==t&&null!==t){var l=i.ticks.length===r+1,s=o>1&&r%o>0||r%o===0&&r+o>=i.ticks.length;if((!s||l)&&void 0!==t&&null!==t){var c,f;r===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=u.zeroLineWidth,f=u.zeroLineColor):(c=e.getValueAtIndexOrDefault(u.lineWidth,r),f=e.getValueAtIndexOrDefault(u.color,r));var p,m,b,v,x,k,S,w,C,M,A,I="middle";if(g){h||(I="top"===n.position?"bottom":"top"),A=h?"right":"center";var V=i.getPixelForTick(r)+e.aliasPixel(c);C=i.getPixelForTick(r,u.offsetGridLines)+d.labelOffset,M=h?i.top+12:"top"===n.position?i.bottom-y:i.top+y,p=b=x=S=V,m=R,v=_,k=a.top,w=a.bottom}else{"left"===n.position?d.mirror?(C=i.right+d.padding,A="left"):(C=i.right-d.padding,A="right"):d.mirror?(C=i.left-d.padding,A="right"):(C=i.left+d.padding,A="left");var L=i.getPixelForTick(r);L+=e.aliasPixel(c),M=i.getPixelForTick(r,u.offsetGridLines),p=F,b=P,x=a.left,S=a.right,m=v=k=w=L}T.push({tx1:p,ty1:m,tx2:b,ty2:v,x1:x,y1:k,x2:S,y2:w,labelX:C,labelY:M,glWidth:c,glColor:f,rotation:-1*D,label:t,textBaseline:I,textAlign:A})}}}),e.each(T,function(t){if(u.display&&(l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.beginPath(),u.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),u.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=x,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var a=t.label;if(e.isArray(a))for(var i=0,n=0;i<a.length;++i)l.fillText(""+a[i],0,n),n+=1.5*m;else l.fillText(a,0,0);l.restore()}}),c.display){var V,L,O=0;if(g)V=i.left+(i.right-i.left)/2,L="bottom"===n.position?i.bottom-S/2:i.top+S/2;else{var B="left"===n.position;V=B?i.left+S/2:i.right-S/2,L=i.top+(i.bottom-i.top)/2,O=B?-.5*Math.PI:.5*Math.PI}l.save(),l.translate(V,L),l.rotate(O),l.textAlign="center",l.textBaseline="middle",l.fillStyle=k,l.font=M,l.fillText(c.labelString,0,0),l.restore()}if(u.drawBorder){l.lineWidth=e.getValueAtIndexOrDefault(u.lineWidth,0),l.strokeStyle=e.getValueAtIndexOrDefault(u.color,0);var W=i.left,z=i.right,N=i.top,H=i.bottom,E=e.aliasPixel(l.lineWidth);g?(N=H="top"===n.position?i.bottom:i.top,N+=E,H+=E):(W=z="left"===n.position?i.right:i.left,W+=E,z+=E),l.beginPath(),l.moveTo(W,N),l.lineTo(z,H),l.stroke()}}}})}},{}],32:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,a,i){this.constructors[t]=a,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(a){return this.defaults.hasOwnProperty(a)?e.scaleMerge(t.defaults.scale,this.defaults[a]):{}},updateScaleDefaults:function(t,a){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],a))},addScalesToLayout:function(a){e.each(a.scales,function(e){t.layoutService.addBox(a,e)})}}}},{}],33:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var a=e.noop;t.Title=t.Element.extend({initialize:function(a){var i=this;e.extend(i,a),i.options=e.configMerge(t.defaults.global.title,a.options),i.legendHitBoxes=[]},beforeUpdate:function(){var a=this.chart.options;a&&a.title&&(this.options=e.configMerge(t.defaults.global.title,a.title))},update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:a,afterBuildLabels:a,beforeFit:a,fit:function(){var a=this,i=e.getValueOrDefault,n=a.options,o=t.defaults.global,r=n.display,l=i(n.fontSize,o.defaultFontSize),s=a.minSize;a.isHorizontal()?(s.width=a.maxWidth,s.height=r?l+2*n.padding:0):(s.width=r?l+2*n.padding:0,s.height=a.maxHeight),a.width=s.width,a.height=s.height},afterFit:a,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var a=this,i=a.ctx,n=e.getValueOrDefault,o=a.options,r=t.defaults.global;if(o.display){var l,s,d=n(o.fontSize,r.defaultFontSize),u=n(o.fontStyle,r.defaultFontStyle),c=n(o.fontFamily,r.defaultFontFamily),h=e.fontString(d,u,c),f=0,g=a.top,p=a.left,m=a.bottom,b=a.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=h,a.isHorizontal()?(l=p+(b-p)/2,s=g+(m-g)/2):(l="left"===o.position?p+d/2:b-d/2,s=g+(m-g)/2,f=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(l,s),i.rotate(f),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0),i.restore()}}}),t.plugins.register({beforeInit:function(e){var a=e.options,i=a.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],34:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return e&&(n.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function a(t){if(!t.length)return!1;var e,a,i=[],n=[];for(e=0,a=t.length;a>e;++e){var o=t[e];if(o&&o.hasValue()){var r=o.tooltipPosition();i.push(r.x),n.push(r.y)}}var l=0,s=0;for(e=0;e<i.length;++e)i[e]&&(l+=i[e],s+=n[e]);return{x:Math.round(l/i.length),y:Math.round(s/i.length)}}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n}}var n=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"single",backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,yAlign:"center",xAlign:"center",caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",callbacks:{beforeTitle:n.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.index<n&&(a=i[o.index])}return a},afterTitle:n.noop,beforeBody:n.noop,beforeLabel:n.noop,label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.yLabel},labelColor:function(t,e){var a=e.getDatasetMeta(t.datasetIndex),i=a.data[t.index],n=i._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},afterLabel:n.noop,afterBody:n.noop,beforeFooter:n.noop,footer:n.noop,afterFooter:n.noop}},t.Tooltip=t.Element.extend({initialize:function(){var e=this,a=t.defaults.global,i=e._options,o=n.getValueOrDefault;n.extend(e,{_model:{xPadding:i.xPadding,yPadding:i.yPadding,xAlign:i.xAlign,yAlign:i.yAlign,bodyFontColor:i.bodyFontColor,_bodyFontFamily:o(i.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:o(i.bodyFontStyle,a.defaultFontStyle),_bodyAlign:i.bodyAlign,bodyFontSize:o(i.bodyFontSize,a.defaultFontSize),bodySpacing:i.bodySpacing,titleFontColor:i.titleFontColor,_titleFontFamily:o(i.titleFontFamily,a.defaultFontFamily),_titleFontStyle:o(i.titleFontStyle,a.defaultFontStyle),titleFontSize:o(i.titleFontSize,a.defaultFontSize),_titleAlign:i.titleAlign,titleSpacing:i.titleSpacing,titleMarginBottom:i.titleMarginBottom,footerFontColor:i.footerFontColor,_footerFontFamily:o(i.footerFontFamily,a.defaultFontFamily),_footerFontStyle:o(i.footerFontStyle,a.defaultFontStyle),footerFontSize:o(i.footerFontSize,a.defaultFontSize),_footerAlign:i.footerAlign,footerSpacing:i.footerSpacing,footerMarginTop:i.footerMarginTop,caretSize:i.caretSize,cornerRadius:i.cornerRadius,backgroundColor:i.backgroundColor,opacity:0,legendColorBackground:i.multiKeyBackground}})},getTitle:function(){var t=this,a=t._options,i=a.callbacks,n=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),l=[];return l=e(l,n),l=e(l,o),l=e(l,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,a){var i=this,o=i._options.callbacks,r=[];return n.each(t,function(t){var n={before:[],lines:[],after:[]};e(n.before,o.beforeLabel.call(i,t,a)),e(n.lines,o.label.call(i,t,a)),e(n.after,o.afterLabel.call(i,t,a)),r.push(n)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return n.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,a=t._options.callbacks,i=a.beforeFooter.apply(t,arguments),n=a.footer.apply(t,arguments),o=a.afterFooter.apply(t,arguments),r=[];return r=e(r,i),r=e(r,n),r=e(r,o)},update:function(t){var e,o,r=this,l=r._options,s=r._model,d=r._active,u=r._data,c=r._chartInstance;if(d.length){s.opacity=1;var h=[],f=a(d),g=[];for(e=0,o=d.length;o>e;++e)g.push(i(d[e]));l.itemSort&&(g=g.sort(l.itemSort)),d.length>1&&n.each(g,function(t){h.push(l.callbacks.labelColor.call(r,t,c))}),n.extend(s,{title:r.getTitle(g,u),beforeBody:r.getBeforeBody(g,u),body:r.getBody(g,u),afterBody:r.getAfterBody(g,u),footer:r.getFooter(g,u),x:Math.round(f.x),y:Math.round(f.y),caretPadding:n.getValueOrDefault(f.padding,2),labelColors:h});var p=r.getTooltipSize(s);r.determineAlignment(p),n.extend(s,r.getBackgroundPoint(s,p))}else r._model.opacity=0;return t&&l.custom&&l.custom.call(r,s),r},getTooltipSize:function(t){var e=this._chart.ctx,a={height:2*t.yPadding,width:0},i=t.body,o=i.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=t.beforeBody.length+t.afterBody.length;var r=t.title.length,l=t.footer.length,s=t.titleFontSize,d=t.bodyFontSize,u=t.footerFontSize;a.height+=r*s,a.height+=(r-1)*t.titleSpacing,a.height+=r?t.titleMarginBottom:0,a.height+=o*d,a.height+=o?(o-1)*t.bodySpacing:0,a.height+=l?t.footerMarginTop:0,a.height+=l*u,a.height+=l?(l-1)*t.footerSpacing:0;var c=0,h=function(t){a.width=Math.max(a.width,e.measureText(t).width+c)};return e.font=n.fontString(s,t._titleFontStyle,t._titleFontFamily),n.each(t.title,h),e.font=n.fontString(d,t._bodyFontStyle,t._bodyFontFamily),n.each(t.beforeBody.concat(t.afterBody),h),c=i.length>1?d+2:0,n.each(i,function(t){n.each(t.before,h),n.each(t.lines,h),n.each(t.after,h)}),c=0,e.font=n.fontString(u,t._footerFontStyle,t._footerFontFamily),n.each(t.footer,h),a.width+=2*t.xPadding,a},determineAlignment:function(t){var e=this,a=e._model,i=e._chart,n=e._chartInstance.chartArea;a.y<t.height?a.yAlign="top":a.y>i.height-t.height&&(a.yAlign="bottom");var o,r,l,s,d,u=(n.left+n.right)/2,c=(n.top+n.bottom)/2;"center"===a.yAlign?(o=function(t){return u>=t},r=function(t){return t>u}):(o=function(e){return e<=t.width/2},r=function(e){return e>=i.width-t.width/2}),l=function(e){return e+t.width>i.width},s=function(e){return e-t.width<0},d=function(t){return c>=t?"top":"bottom"},o(a.x)?(a.xAlign="left",l(a.x)&&(a.xAlign="center",a.yAlign=d(a.y))):r(a.x)&&(a.xAlign="right",s(a.x)&&(a.xAlign="center",a.yAlign=d(a.y)))},getBackgroundPoint:function(t,e){var a={x:t.x,y:t.y},i=t.caretSize,n=t.caretPadding,o=t.cornerRadius,r=t.xAlign,l=t.yAlign,s=i+n,d=o+n;return"right"===r?a.x-=e.width:"center"===r&&(a.x-=e.width/2),"top"===l?a.y+=s:"bottom"===l?a.y-=e.height+s:a.y-=e.height/2,"center"===l?"left"===r?a.x+=s:"right"===r&&(a.x-=s):"left"===r?a.x-=d:"right"===r&&(a.x+=d),a},drawCaret:function(t,e,a){var i,o,r,l,s,d,u=this._view,c=this._chart.ctx,h=u.caretSize,f=u.cornerRadius,g=u.xAlign,p=u.yAlign,m=t.x,b=t.y,v=e.width,x=e.height;"center"===p?("left"===g?(i=m,o=i-h,r=i):(i=m+v,o=i+h,r=i),s=b+x/2,l=s-h,d=s+h):("left"===g?(i=m+f,o=i+h,r=o+h):"right"===g?(i=m+v-f,o=i-h,r=o-h):(o=m+v/2,i=o-h,r=o+h),"top"===p?(l=b,s=l-h,d=l):(l=b+x,s=l+h,d=l));var y=n.color(u.backgroundColor);c.fillStyle=y.alpha(a*y.alpha()).rgbString(),c.beginPath(),c.moveTo(i,l),c.lineTo(o,s),c.lineTo(r,d),c.closePath(),c.fill()},drawTitle:function(t,e,a,i){var o=e.title;if(o.length){a.textAlign=e._titleAlign,a.textBaseline="top";var r=e.titleFontSize,l=e.titleSpacing,s=n.color(e.titleFontColor);a.fillStyle=s.alpha(i*s.alpha()).rgbString(),a.font=n.fontString(r,e._titleFontStyle,e._titleFontFamily);var d,u;for(d=0,u=o.length;u>d;++d)a.fillText(o[d],t.x,t.y),t.y+=r+l,d+1===o.length&&(t.y+=e.titleMarginBottom-l)}},drawBody:function(t,e,a,i){var o=e.bodyFontSize,r=e.bodySpacing,l=e.body;a.textAlign=e._bodyAlign,a.textBaseline="top";var s=n.color(e.bodyFontColor),d=s.alpha(i*s.alpha()).rgbString();a.fillStyle=d,a.font=n.fontString(o,e._bodyFontStyle,e._bodyFontFamily);var u=0,c=function(e){a.fillText(e,t.x+u,t.y),t.y+=o+r};n.each(e.beforeBody,c);var h=l.length>1;u=h?o+2:0,n.each(l,function(r,l){n.each(r.before,c),n.each(r.lines,function(r){h&&(a.fillStyle=n.color(e.legendColorBackground).alpha(i).rgbaString(),a.fillRect(t.x,t.y,o,o),a.strokeStyle=n.color(e.labelColors[l].borderColor).alpha(i).rgbaString(),a.strokeRect(t.x,t.y,o,o),a.fillStyle=n.color(e.labelColors[l].backgroundColor).alpha(i).rgbaString(),a.fillRect(t.x+1,t.y+1,o-2,o-2),a.fillStyle=d),c(r)}),n.each(r.after,c)}),u=0,n.each(e.afterBody,c),t.y-=r},drawFooter:function(t,e,a,i){var o=e.footer;if(o.length){t.y+=e.footerMarginTop,a.textAlign=e._footerAlign,a.textBaseline="top";var r=n.color(e.footerFontColor);a.fillStyle=r.alpha(i*r.alpha()).rgbString(),a.font=n.fontString(e.footerFontSize,e._footerFontStyle,e._footerFontFamily),n.each(o,function(i){a.fillText(i,t.x,t.y),t.y+=e.footerFontSize+e.footerSpacing})}},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var a=this.getTooltipSize(e),i={x:e.x,y:e.y},o=Math.abs(e.opacity<.001)?0:e.opacity;if(this._options.enabled){var r=n.color(e.backgroundColor);t.fillStyle=r.alpha(o*r.alpha()).rgbString(),n.drawRoundedRectangle(t,i.x,i.y,a.width,a.height,e.cornerRadius),t.fill(),this.drawCaret(i,a,o),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,o),this.drawBody(i,e,t,o),this.drawFooter(i,e,t,o)}}}})}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;a.elements.arc={backgroundColor:a.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,a){var i=this._view;if(i){for(var n=e.getAngleFromPoint(i,{x:t,y:a}),o=n.angle,r=n.distance,l=i.startAngle,s=i.endAngle;l>s;)s+=2*Math.PI;for(;o>s;)o-=2*Math.PI;for(;l>o;)o+=2*Math.PI;var d=o>=l&&s>=o,u=r>=i.innerRadius&&r<=i.outerRadius;return d&&u}return!1},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var a=e._view;e._view.steppedLine===!0?(s.lineTo(e._view.x,t._view.y),s.lineTo(e._view.x,e._view.y)):0===e._view.tension?s.lineTo(a.x,a.y):s.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,a.controlPointPreviousX,a.controlPointPreviousY,a.x,a.y)}var i=this,n=i._view,o=n.spanGaps,r=n.scaleZero,l=i._loop,s=i._chart.ctx;s.save();var d=i._children.slice(),u=-1;l&&d.length&&d.push(d[0]);var c,h,f,g;if(d.length&&n.fill){for(s.beginPath(),c=0;c<d.length;++c)h=d[c],f=e.previousItem(d,c),g=h._view,0===c?(l?s.moveTo(r.x,r.y):s.moveTo(g.x,r),g.skip||(u=c,s.lineTo(g.x,g.y))):(f=-1===u?f:d[u],g.skip?o||u!==c-1||(l?s.lineTo(r.x,r.y):s.lineTo(f._view.x,r)):(u!==c-1?o&&-1!==u?t(f,h):l?s.lineTo(g.x,g.y):(s.lineTo(g.x,r),s.lineTo(g.x,g.y)):t(f,h),u=c));l||s.lineTo(d[u]._view.x,r),s.fillStyle=n.backgroundColor||a.defaultColor,s.closePath(),s.fill()}var p=a.elements.line;for(s.lineCap=n.borderCapStyle||p.borderCapStyle,s.setLineDash&&s.setLineDash(n.borderDash||p.borderDash),s.lineDashOffset=n.borderDashOffset||p.borderDashOffset,s.lineJoin=n.borderJoinStyle||p.borderJoinStyle,s.lineWidth=n.borderWidth||p.borderWidth,s.strokeStyle=n.borderColor||a.defaultColor,s.beginPath(),u=-1,c=0;c<d.length;++c)h=d[c],f=e.previousItem(d,c),g=h._view,0===c?g.skip||(s.moveTo(g.x,g.y),u=c):(f=-1===u?f:d[u],g.skip||(u!==c-1&&!o||-1===u?s.moveTo(g.x,g.y):t(f,h),u=c));s.stroke(),s.restore()}})}},{}],37:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:i,borderWidth:1,borderColor:i,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var a=this._view;return a?Math.pow(t-a.x,2)+Math.pow(e-a.y,2)<Math.pow(a.hitRadius+a.radius,2):!1},inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var n=this._view,o=this._chart.ctx,r=n.pointStyle,l=n.radius,s=n.x,d=n.y;n.skip||(o.strokeStyle=n.borderColor||i,o.lineWidth=e.getValueOrDefault(n.borderWidth,a.elements.point.borderWidth),o.fillStyle=n.backgroundColor||i,t.canvasHelpers.drawPoint(o,r,l,s,d))}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.defaults.global;e.elements.rectangle={backgroundColor:e.defaultColor,borderWidth:0,borderColor:e.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return s[(u+t)%4]}var e=this._chart.ctx,a=this._view,i=a.width/2,n=a.x-i,o=a.x+i,r=a.base-(a.base-a.y),l=a.borderWidth/2;a.borderWidth&&(n+=l,o-=l,r+=l),e.beginPath(),e.fillStyle=a.backgroundColor,e.strokeStyle=a.borderColor,e.lineWidth=a.borderWidth;var s=[[n,a.base],[n,r],[o,r],[o,a.base]],d=["bottom","left","top","right"],u=d.indexOf(a.borderSkipped,0);-1===u&&(u=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),a.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var a=this._view;return a?a.y<a.base?t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.y&&e<=a.base:t>=a.x-a.width/2&&t<=a.x+a.width/2&&e>=a.base&&e<=a.y:!1},inLabelRange:function(t){var e=this._view;return e?t>=e.x-e.width/2&&t<=e.x+e.width/2:!1},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],39:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,a=t.getLabels();t.minIndex=0,t.maxIndex=a.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(a,t.options.ticks.min),t.minIndex=-1!==i?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(a,t.options.ticks.max),t.maxIndex=-1!==i?i:t.maxIndex),t.min=a[t.minIndex],t.max=a[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t){return this.ticks[t]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t){var r=n.getLabels(),l=r.indexOf(t);e=-1!==l?l:e}if(n.isHorizontal()){var s=n.width-(n.paddingLeft+n.paddingRight),d=s/o,u=d*(e-n.minIndex)+n.paddingLeft;return n.options.gridLines.offsetGridLines&&i&&(u+=d/2),n.left+Math.round(u)}var c=n.height-(n.paddingTop+n.paddingBottom),h=c/o,f=h*(e-n.minIndex)+n.paddingTop;return n.options.gridLines.offsetGridLines&&i&&(f+=h/2),n.top+Math.round(f)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=n?a.width-(a.paddingLeft+a.paddingRight):a.height-(a.paddingTop+a.paddingBottom),r=o/i;return t-=n?a.left:a.top,a.options.gridLines.offsetGridLines&&(t-=r/2),t-=n?a.paddingLeft:a.paddingTop,e=0>=t?0:Math.round(t/r)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,a)}},{}],40:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var l=-1*Math.floor(o);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r}}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=a.chart,o=n.data,r=o.datasets,l=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var s={},d=!1,u=!1;e.each(r,function(o,r){var l=n.getDatasetMeta(r);void 0===s[l.type]&&(s[l.type]={positiveValues:[],negativeValues:[]});var c=s[l.type].positiveValues,h=s[l.type].negativeValues;n.isDatasetVisible(r)&&t(l)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||l.data[e].hidden||(c[e]=c[e]||0,h[e]=h[e]||0,i.relativePoints?c[e]=100:0>n?(u=!0,h[e]+=n):(d=!0,c[e]+=n))})}),e.each(s,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,a,i=this,n=i.paddingLeft,o=i.paddingBottom,r=i.start,l=+i.getRightValue(t),s=i.end-r;return i.isHorizontal()?(a=i.width-(n+i.paddingRight),e=i.left+a/s*(l-r),Math.round(e+n)):(a=i.height-(i.paddingTop+o),e=i.bottom-o-a/s*(l-r),Math.round(e))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=e.paddingLeft,n=e.paddingBottom,o=a?e.width-(i+e.paddingRight):e.height-(e.paddingTop+n),r=(a?t-e.left-i:e.bottom-n-t)/o;return e.start+(e.end-e.start)*r},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,a)}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);0>n&&0>o?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var t=this,a=t.options,i=t.ticks=[],n=a.ticks,o=e.getValueOrDefault,r=t.getTickLimit();r=Math.max(2,r);var l,s=n.fixedStepSize&&n.fixedStepSize>0||n.stepSize&&n.stepSize>0;if(s)l=o(n.fixedStepSize,n.stepSize);else{var d=e.niceNum(t.max-t.min,!1);l=e.niceNum(d/(r-1),!0)}var u=Math.floor(t.min/l)*l,c=Math.ceil(t.max/l)*l,h=(c-u)/l;h=e.almostEquals(h,Math.round(h),l/1e3)?Math.round(h):Math.ceil(h),i.push(void 0!==n.min?n.min:u);for(var f=1;h>f;++f)i.push(u+f*l);i.push(void 0!==n.max?n.max:c),t.handleDirectionalChanges(),t.max=e.max(i),t.min=e.min(i),n.reverse?(i.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],42:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return d?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,l=r.datasets,s=e.getValueOrDefault,d=a.isHorizontal();if(a.min=null,a.max=null,i.stacked){var u={};e.each(l,function(n,r){var l=o.getDatasetMeta(r);o.isDatasetVisible(r)&&t(l)&&(void 0===u[l.type]&&(u[l.type]=[]),e.each(n.data,function(t,e){var n=u[l.type],o=+a.getRightValue(t);isNaN(o)||l.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(u,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(l,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});a.min=s(n.min,a.min),a.max=s(n.max,a.max),a.min===a.max&&(0!==a.min&&null!==a.min?(a.min=Math.pow(10,Math.floor(e.log10(a.min))-1),a.max=Math.pow(10,Math.floor(e.log10(a.max))+1)):(a.min=1,a.max=10))},buildTicks:function(){for(var t=this,a=t.options,i=a.ticks,n=e.getValueOrDefault,o=t.ticks=[],r=n(i.min,Math.pow(10,Math.floor(e.log10(t.min))));r<t.max;){o.push(r);var l=Math.floor(e.log10(r)),s=Math.floor(r/Math.pow(10,l))+1;10===s&&(s=1,++l),r=s*Math.pow(10,l)}var d=n(i.max,r);o.push(d),t.isHorizontal()||o.reverse(),t.max=e.max(o),t.min=e.min(o),i.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var a,i,n=this,o=n.start,r=+n.getRightValue(t),l=e.log10(n.end)-e.log10(o),s=n.paddingTop,d=n.paddingBottom,u=n.paddingLeft;return n.isHorizontal()?0===r?i=n.left+u:(a=n.width-(u+n.paddingRight),i=n.left+a/l*(e.log10(r)-e.log10(o)),i+=u):0===r?i=n.top+s:(a=n.height-(s+d),i=n.bottom-d-a/l*(e.log10(r)-e.log10(o))),i},getValueForPixel:function(t){var a,i,n=this,o=e.log10(n.end)-e.log10(n.start);return n.isHorizontal()?(i=n.width-(n.paddingLeft+n.paddingRight),a=n.start*Math.pow(10,(t-n.left-n.paddingLeft)*o/i)):(i=n.height-(n.paddingTop+n.paddingBottom),a=Math.pow(10,(n.bottom-n.paddingBottom-t)*o/i)/n.start),a}});t.scaleService.registerScaleType("logarithmic",i,a)}},{}],43:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global,i={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2},pointLabels:{fontSize:10,callback:function(t){return t}}},n=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length;
-},setDimensions:function(){var t=this,i=t.options,n=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var o=e.min([t.height,t.width]),r=e.getValueOrDefault(n.fontSize,a.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,a=t.chart;t.min=null,t.max=null,e.each(a.data.datasets,function(i,n){if(a.isDatasetVisible(n)){var o=a.getDatasetMeta(n);e.each(i.data,function(e,a){var i=+t.getRightValue(e);isNaN(i)||o.data[a].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,a.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,n,o,r,l,s,d,u,c,h,f,g=this.options.pointLabels,p=e.getValueOrDefault(g.fontSize,a.defaultFontSize),m=e.getValueOrDefault(g.fontStyle,a.defaultFontStyle),b=e.getValueOrDefault(g.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=e.min([this.height/2-p-5,this.width/2]),y=this.width,k=0;for(this.ctx.font=v,i=0;i<this.getValueCount();i++){t=this.getPointPosition(i,x),n=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5;var S=this.getIndexAngle(i)+Math.PI/2,w=360*S/(2*Math.PI)%360;0===w||180===w?(o=n/2,t.x+o>y&&(y=t.x+o,r=i),t.x-o<k&&(k=t.x-o,s=i)):180>w?t.x+n>y&&(y=t.x+n,r=i):t.x-n<k&&(k=t.x-n,s=i)}u=k,c=Math.ceil(y-this.width),l=this.getIndexAngle(r),d=this.getIndexAngle(s),h=c/Math.sin(l+Math.PI/2),f=u/Math.sin(d+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(x-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var a=this,i=a.width-e-a.drawingArea,n=t+a.drawingArea;a.xCenter=Math.round((n+i)/2+a.left),a.yCenter=Math.round(a.height/2+a.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount(),a=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,i=a*Math.PI*2/360;return t*e-Math.PI/2+i},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var a=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*a:(t-e.min)*a},getPointPosition:function(t,e){var a=this,i=a.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+a.xCenter,y:Math.round(Math.sin(i)*e)+a.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,a=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>a?a:e>0&&a>0?e:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,r=i.angleLines,l=i.pointLabels,s=e.getValueOrDefault;if(i.display){var d=t.ctx,u=s(o.fontSize,a.defaultFontSize),c=s(o.fontStyle,a.defaultFontStyle),h=s(o.fontFamily,a.defaultFontFamily),f=e.fontString(u,c,h);if(e.each(t.ticks,function(r,l){if(l>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-c;if(n.display&&0!==l)if(d.strokeStyle=e.getValueAtIndexOrDefault(n.color,l-1),d.lineWidth=e.getValueAtIndexOrDefault(n.lineWidth,l-1),i.lineArc)d.beginPath(),d.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),d.closePath(),d.stroke();else{d.beginPath();for(var g=0;g<t.getValueCount();g++){var p=t.getPointPosition(g,c);0===g?d.moveTo(p.x,p.y):d.lineTo(p.x,p.y)}d.closePath(),d.stroke()}if(o.display){var m=s(o.fontColor,a.defaultFontColor);if(d.font=f,o.showLabelBackdrop){var b=d.measureText(r).width;d.fillStyle=o.backdropColor,d.fillRect(t.xCenter-b/2-o.backdropPaddingX,h-u/2-o.backdropPaddingY,b+2*o.backdropPaddingX,u+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=m,d.fillText(r,t.xCenter,h)}}}),!i.lineArc){d.lineWidth=r.lineWidth,d.strokeStyle=r.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),p=s(l.fontSize,a.defaultFontSize),m=s(l.fontStyle,a.defaultFontStyle),b=s(l.fontFamily,a.defaultFontFamily),v=e.fontString(p,m,b),x=t.getValueCount()-1;x>=0;x--){if(r.display){var y=t.getPointPosition(x,g);d.beginPath(),d.moveTo(t.xCenter,t.yCenter),d.lineTo(y.x,y.y),d.stroke(),d.closePath()}var k=t.getPointPosition(x,g+5),S=s(l.fontColor,a.defaultFontColor);d.font=v,d.fillStyle=S;var w=t.pointLabels,C=this.getIndexAngle(x)+Math.PI/2,M=360*C/(2*Math.PI)%360;0===M||180===M?d.textAlign="center":180>M?d.textAlign="left":d.textAlign="right",90===M||270===M?d.textBaseline="middle":M>270||90>M?d.textBaseline="bottom":d.textBaseline="top",d.fillText(w[x]?w[x]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",n,i)}},{}],44:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],l=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),r.push(a),l&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildTicks:function(){var i=this;i.ctx.save();var n=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),l=e.fontString(n,o,r);if(i.ctx.font=l,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var s=i.isHorizontal()?i.width-(i.paddingLeft+i.paddingRight):i.height-(i.paddingTop+i.paddingBottom),d=i.tickFormatFunction(i.firstTick,0,[]),u=i.ctx.measureText(d).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));u=u*c+n*h;var f=s/u;i.tickUnit="millisecond",i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,p=a.units[g];g<a.units.length;){if(i.unitScale=1,e.isArray(p.steps)&&Math.ceil(i.scaleSizeInUnits/f)<e.max(p.steps)){for(var m=0;m<p.steps.length;++m)if(p.steps[m]>=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,p.steps[m]);break}break}if(p.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)<p.maxStep){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,Math.ceil(i.scaleSizeInUnits/f));break}++g,p=a.units[g],i.tickUnit=p.name;var b=i.firstTick.diff(i.getMomentStartOf(i.firstTick),i.tickUnit,!0),v=i.getMomentStartOf(i.lastTick.clone().add(1,i.tickUnit)).diff(i.lastTick,i.tickUnit,!0);i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)+b+v,i.displayFormat=i.options.time.displayFormats[p.name]}}var x;if(i.options.time.min?x=i.getMomentStartOf(i.firstTick):(i.firstTick=i.getMomentStartOf(i.firstTick),x=i.firstTick),!i.options.time.max){var y=i.getMomentStartOf(i.lastTick),k=y.diff(i.lastTick,i.tickUnit,!0);0>k?i.lastTick=i.getMomentStartOf(i.lastTick.add(1,i.tickUnit)):k>=0&&(i.lastTick=y),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.smallestLabelSeparation=i.width,e.each(i.chart.data.datasets,function(t,e){for(var a=1;a<i.labelMoments[e].length;a++)i.smallestLabelSeparation=Math.min(i.smallestLabelSeparation,i.labelMoments[e][a].diff(i.labelMoments[e][a-1],i.tickUnit,!0))},i),i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var S=1;S<=i.scaleSizeInUnits;++S){var w=x.clone().add(S,i.tickUnit);if(i.options.time.max&&w.diff(i.lastTick,i.tickUnit,!0)>=0)break;S%i.unitScale===0&&i.ticks.push(w)}var C=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);(0!==C||0===i.scaleSizeInUnits)&&(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore()},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t<a.chart.data.labels.length?a.chart.data.labels[t]:"";return"object"==typeof a.chart.data.datasets[e].data[0]&&(i=a.getRightValue(a.chart.data.datasets[e].data[t])),a.options.time.tooltipFormat&&(i=a.parseTime(i).format(a.options.time.tooltipFormat)),i},tickFormatFunction:function(t,a,i){var n=t.format(this.displayFormat),o=this.options.ticks,r=e.getValueOrDefault(o.callback,o.userCallback);return r?r(n,a,i):n},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,a){var n=this;t&&t.isValid||(t=i(n.getRightValue(t)));var o=t&&t.isValid&&t.isValid()?t:n.getLabelMoment(a,e);if(o){var r=o.diff(n.firstTick,n.tickUnit,!0),l=0!==r?r/n.scaleSizeInUnits:r;if(n.isHorizontal()){var s=n.width-(n.paddingLeft+n.paddingRight),d=s*l+n.paddingLeft;return n.left+Math.round(d)}var u=n.height-(n.paddingTop+n.paddingBottom),c=u*l+n.paddingTop;return n.top+Math.round(c)}},getPixelForTick:function(t){return this.getPixelForValue(this.tickMoments[t],null,null)},getValueForPixel:function(t){var e=this,a=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),n=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/a;return n*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(n,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",o,n)}},{1:1}]},{},[7])(7)});
\ No newline at end of file
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,n,i){function a(r,l){if(!n[r]){if(!e[r]){var s="function"==typeof require&&require;if(!l&&s)return s(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[r]={exports:{}};e[r][0].call(d.exports,function(t){var n=e[r][1][t];return a(n?n:t)},d,d.exports,t,e,n,i)}return n[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)a(i[r]);return a}({1:[function(t,e,n){},{}],2:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,n=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,o=/(\w+)/,r=[0,0,0],l=1,s=t.match(e);if(s){s=s[1];for(var u=0;u<r.length;u++)r[u]=parseInt(s[u]+s[u],16)}else if(s=t.match(n)){s=s[1];for(var u=0;u<r.length;u++)r[u]=parseInt(s.slice(2*u,2*u+2),16)}else if(s=t.match(i)){for(var u=0;u<r.length;u++)r[u]=parseInt(s[u+1]);l=parseFloat(s[4])}else if(s=t.match(a)){for(var u=0;u<r.length;u++)r[u]=Math.round(2.55*parseFloat(s[u+1]));l=parseFloat(s[4])}else if(s=t.match(o)){if("transparent"==s[1])return[0,0,0,0];if(r=y[s[1]],!r)return}for(var u=0;u<r.length;u++)r[u]=b(r[u],0,255);return l=l||0==l?b(l,0,1):1,r[3]=l,r}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),o=b(parseFloat(n[2]),0,100),r=b(parseFloat(n[3]),0,100),l=b(isNaN(i)?1:i,0,1);return[a,o,r,l]}}}function o(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),o=b(parseFloat(n[2]),0,100),r=b(parseFloat(n[3]),0,100),l=b(isNaN(i)?1:i,0,1);return[a,o,r,l]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function l(t){var e=a(t);return e&&e.slice(0,3)}function s(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=o(t))?e[3]:void 0}function u(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function d(t,e){return e<1||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"}function f(t,e){var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgba("+n+"%, "+i+"%, "+a+"%, "+(e||t[3]||1)+")"}function g(t,e){return e<1||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function v(t){return k[t.slice(0,3)]}function b(t,e,n){return Math.min(Math.max(e,t),n)}function x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:a,getRgb:r,getHsl:l,getHwb:o,getAlpha:s,hexString:u,rgbString:d,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:v};var k={};for(var w in y)k[y[w]]=w},{6:6}],3:[function(t,e,n){var i=t(5),a=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;"string"==typeof t?(e=a.getRgba(t),e?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e)):"object"==typeof t&&(e=t,void 0!==e.r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e))};o.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=t<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return e<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,o=2*a-1,r=n.alpha()-i.alpha(),l=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,s=1-l;return this.rgb(l*n.red()+s*i.red(),l*n.green()+s*i.green(),l*n.blue()+s*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new o,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},o.prototype.setValues=function(t,e){var n,a=this.values,o=this.spaces,r=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)a[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];l=e.a}else if(void 0!==e[o[t][0]]){var s=o[t];for(n=0;n<t.length;n++)a[t][n]=e[s[n]];l=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===l?a.alpha:l)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(r[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in o)d!==t&&(a[d]=i[t][d](a[t]));return!0},o.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},o.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,o=t[1]/255,r=t[2]/255,l=Math.min(a,o,r),s=Math.max(a,o,r),u=s-l;return s==l?e=0:a==s?e=(o-r)/u:o==s?e=2+(r-a)/u:r==s&&(e=4+(a-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=(l+s)/2,n=s==l?0:i<=.5?u/(s+l):u/(2-s-l),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],o=t[1],r=t[2],l=Math.min(a,o,r),s=Math.max(a,o,r),u=s-l;return n=0==s?0:u/s*1e3/10,s==l?e=0:a==s?e=(o-r)/u:o==s?e=2+(r-a)/u:r==s&&(e=4+(a-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=s/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(n,a)),a=1-1/255*Math.max(e,Math.max(n,a));return[o,100*r,100*a]}function l(t){var e,n,i,a,o=t[0]/255,r=t[1]/255,l=t[2]/255;return a=Math.min(1-o,1-r,1-l),e=(1-o-a)/(1-a)||0,n=(1-r-a)/(1-a)||0,i=(1-l-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function s(t){return Z[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var a=.4124*e+.3576*n+.1805*i,o=.2126*e+.7152*n+.0722*i,r=.0193*e+.1192*n+.9505*i;return[100*a,100*o,100*r]}function d(t){var e,n,i,a=u(t),o=a[0],r=a[1],l=a[2];return o/=95.047,r/=100,l/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,l=l>.008856?Math.pow(l,1/3):7.787*l+16/116,e=116*r-16,n=500*(o-r),i=200*(r-l),[e,n,i]}function c(t){return B(d(t))}function h(t){var e,n,i,a,o,r=t[0]/360,l=t[1]/100,s=t[2]/100;if(0==l)return o=255*s,[o,o,o];n=s<.5?s*(1+l):s+l-s*l,e=2*s-n,a=[0,0,0];for(var u=0;u<3;u++)i=r+1/3*-(u-1),i<0&&i++,i>1&&i--,o=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*o;return a}function f(t){var e,n,i=t[0],a=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,a*=o<=1?o:2-o,n=(o+a)/2,e=2*a/(o+a),[i,100*e,100*n])}function p(t){return o(h(t))}function m(t){return l(h(t))}function v(t){return s(h(t))}function x(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-n),l=255*i*(1-n*o),s=255*i*(1-n*(1-o)),i=255*i;switch(a){case 0:return[i,s,r];case 1:return[l,i,r];case 2:return[r,i,s];case 3:return[r,l,i];case 4:return[s,r,i];case 5:return[i,r,l]}}function y(t){var e,n,i=t[0],a=t[1]/100,o=t[2]/100;return n=(2-a)*o,e=a*o,e/=n<=1?n:2-n,e=e||0,n/=2,[i,100*e,100*n]}function k(t){return o(x(t))}function w(t){return l(x(t))}function M(t){return s(x(t))}function S(t){var e,n,i,a,o=t[0]/360,l=t[1]/100,s=t[2]/100,u=l+s;switch(u>1&&(l/=u,s/=u),e=Math.floor(6*o),n=1-s,i=6*o-e,0!=(1&e)&&(i=1-i),a=l+i*(n-l),e){default:case 6:case 0:r=n,g=a,b=l;break;case 1:r=a,g=n,b=l;break;case 2:r=l,g=n,b=a;break;case 3:r=l,g=a,b=n;break;case 4:r=a,g=l,b=n;break;case 5:r=n,g=l,b=a}return[255*r,255*g,255*b]}function C(t){return i(S(t))}function D(t){return a(S(t))}function I(t){return l(S(t))}function A(t){return s(S(t))}function P(t){var e,n,i,a=t[0]/100,o=t[1]/100,r=t[2]/100,l=t[3]/100;return e=1-Math.min(1,a*(1-l)+l),n=1-Math.min(1,o*(1-l)+l),i=1-Math.min(1,r*(1-l)+l),[255*e,255*n,255*i]}function _(t){return i(P(t))}function T(t){return a(P(t))}function F(t){return o(P(t))}function R(t){return s(P(t))}function L(t){var e,n,i,a=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*a+o*-1.5372+r*-.4986,n=a*-.9689+1.8758*o+.0415*r,i=.0557*a+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function V(t){var e,n,i,a=t[0],o=t[1],r=t[2];return a/=95.047,o/=100,r/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,n=500*(a-o),i=200*(o-r),[e,n,i]}function O(t){return B(V(t))}function z(t){var e,n,i,a,o=t[0],r=t[1],l=t[2];return o<=8?(n=100*o/903.3,a=7.787*(n/100)+16/116):(n=100*Math.pow((o+16)/116,3),a=Math.pow(n/100,1/3)),e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i=i/108.883<=.008859?i=108.883*(a-l/200-16/116)/7.787:108.883*Math.pow(a-l/200,3),[e,n,i]}function B(t){var e,n,i,a=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),n=360*e/2/Math.PI,n<0&&(n+=360),i=Math.sqrt(o*o+r*r),[a,i,n]}function W(t){return L(z(t))}function N(t){var e,n,i,a=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),n=o*Math.sin(i),[a,e,n]}function E(t){return z(N(t))}function H(t){return W(N(t))}function q(t){return J[t]}function j(t){return i(q(t))}function Y(t){return a(q(t))}function U(t){return o(q(t))}function X(t){return l(q(t))}function K(t){return d(q(t))}function G(t){return u(q(t))}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:l,rgb2keyword:s,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:w,hsv2keyword:M,hwb2rgb:S,hwb2hsl:C,hwb2hsv:D,hwb2cmyk:I,hwb2keyword:A,cmyk2rgb:P,cmyk2hsl:_,cmyk2hsv:T,cmyk2hwb:F,cmyk2keyword:R,keyword2rgb:q,keyword2hsl:j,keyword2hsv:Y,keyword2hwb:U,keyword2cmyk:X,keyword2lab:K,keyword2xyz:G,xyz2rgb:L,xyz2lab:V,xyz2lch:O,lab2xyz:z,lab2rgb:W,lab2lch:B,lch2lab:N,lch2xyz:E,lch2rgb:H};var J={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Z={};for(var Q in J)Z[JSON.stringify(J[Q])]=Q},{}],5:[function(t,e,n){var i=t(4),a=function(){return new u};for(var o in i){a[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),l=r[1],s=r[2];a[l]=a[l]||{},a[l][s]=a[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(o)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{4:4}],6:[function(t,e,n){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,n){var i=t(28)();t(26)(i),t(40)(i),t(22)(i),t(25)(i),t(30)(i),t(21)(i),t(23)(i),t(24)(i),t(29)(i),t(32)(i),t(33)(i),t(31)(i),t(27)(i),t(34)(i),t(35)(i),t(36)(i),t(37)(i),t(38)(i),t(46)(i),t(44)(i),t(45)(i),t(47)(i),t(48)(i),t(49)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i);var a=[];a.push(t(41)(i),t(42)(i),t(43)(i)),i.plugins.register(a),e.exports=i,"undefined"!=typeof window&&(window.Chart=i)},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,40:40,41:41,42:42,43:43,44:44,45:45,46:46,47:47,48:48,49:49,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(){var e,n=this;t.DatasetController.prototype.initialize.apply(n,arguments),e=n.getMeta(),e.stack=n.getDataset().stack,e.bar=!0},update:function(t){var e,n,i=this,a=i.getMeta().data;for(i._ruler=i.getRuler(),e=0,n=a.length;e<n;++e)i.updateElement(a[e],e,t)},updateElement:function(t,n,i){var a=this,o=a.chart,r=a.getMeta(),l=a.getDataset(),s=t.custom||{},u=o.options.elements.rectangle;t._xScale=a.getScaleForId(r.xAxisID),t._yScale=a.getScaleForId(r.yAxisID),t._datasetIndex=a.index,t._index=n,t._model={datasetLabel:l.label,label:o.data.labels[n],borderSkipped:s.borderSkipped?s.borderSkipped:u.borderSkipped,backgroundColor:s.backgroundColor?s.backgroundColor:e.getValueAtIndexOrDefault(l.backgroundColor,n,u.backgroundColor),borderColor:s.borderColor?s.borderColor:e.getValueAtIndexOrDefault(l.borderColor,n,u.borderColor),borderWidth:s.borderWidth?s.borderWidth:e.getValueAtIndexOrDefault(l.borderWidth,n,u.borderWidth)},a.updateElementGeometry(t,n,i),t.pivot()},updateElementGeometry:function(t,e,n){var i=this,a=t._model,o=i.getValueScale(),r=o.getBasePixel(),l=o.isHorizontal(),s=i._ruler||i.getRuler(),u=i.calculateBarValuePixels(i.index,e),d=i.calculateBarIndexPixels(i.index,e,s);a.horizontal=l,a.base=n?r:u.base,a.x=l?n?r:u.head:d.center,a.y=l?d.center:n?r:u.head,a.height=l?d.size:void 0,a.width=l?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},getStackCount:function(t){var e,n,i=this,a=i.chart,o=i.getIndexScale(),r=o.options.stacked,l=void 0===t?a.data.datasets.length:t+1,s=[];for(e=0;e<l;++e)n=a.getDatasetMeta(e),n.bar&&a.isDatasetVisible(e)&&(r===!1||r===!0&&s.indexOf(n.stack)===-1||void 0===r&&(void 0===n.stack||s.indexOf(n.stack)===-1))&&s.push(n.stack);return s.length},getStackIndex:function(t){return this.getStackCount(t)-1},getRuler:function(){var t=this,n=t.getIndexScale(),i=n.options,a=t.getStackCount(),o=n.isHorizontal()?n.width:n.height,r=o/n.ticks.length,l=r*i.categoryPercentage,s=l/a,u=s*i.barPercentage;return u=Math.min(e.getValueOrDefault(i.barThickness,u),e.getValueOrDefault(i.maxBarThickness,1/0)),{stackCount:a,tickSize:r,categorySize:l,categorySpacing:r-l,fullBarSize:s,barSize:u,barSpacing:s-u,scale:n}},calculateBarValuePixels:function(t,e){var n,i,a,o,r,l,s=this,u=s.chart,d=s.getMeta(),c=s.getValueScale(),h=u.data.datasets,f=Number(h[t].data[e]),g=c.options.stacked,p=d.stack,m=0;if(g||void 0===g&&void 0!==p)for(n=0;n<t;++n)i=u.getDatasetMeta(n),i.bar&&i.stack===p&&i.controller.getValueScaleId()===c.id&&u.isDatasetVisible(n)&&(a=Number(h[n].data[e]),(f<0&&a<0||f>=0&&a>0)&&(m+=a));return o=c.getPixelForValue(m),r=c.getPixelForValue(m+f),l=(r-o)/2,{size:l,base:o,head:r,center:r+l/2}},calculateBarIndexPixels:function(t,e,n){var i=this,a=n.scale,o=i.chart.isCombo,r=i.getStackIndex(t),l=a.getPixelForValue(null,e,t,o),s=n.barSize;return l-=o?n.tickSize/2:0,l+=n.fullBarSize*r,l+=n.categorySpacing/2,l+=n.barSpacing/2,{size:s,base:l,head:l+s,center:l+s/2}},draw:function(){var t,n=this,i=n.chart,a=n.getMeta().data,o=n.getDataset(),r=a.length,l=0;for(e.canvas.clipArea(i.ctx,i.chartArea);l<r;++l)t=o.data[l],null===t||void 0===t||isNaN(t)||a[l].draw();e.canvas.unclipArea(i.ctx)},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;o.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=a.hoverBorderColor?a.hoverBorderColor:e.getValueAtIndexOrDefault(n.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:e.getValueAtIndexOrDefault(n.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=a.backgroundColor?a.backgroundColor:e.getValueAtIndexOrDefault(n.backgroundColor,i,r.backgroundColor),o.borderColor=a.borderColor?a.borderColor:e.getValueAtIndexOrDefault(n.borderColor,i,r.borderColor),o.borderWidth=a.borderWidth?a.borderWidth:e.getValueAtIndexOrDefault(n.borderWidth,i,r.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{}],16:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var n=this,i=n.getMeta(),a=i.data;e.each(a,function(e,i){n.updateElement(e,i,t)})},updateElement:function(n,i,a){var o=this,r=o.getMeta(),l=o.getScaleForId(r.xAxisID),s=o.getScaleForId(r.yAxisID),u=n.custom||{},d=o.getDataset(),c=d.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(n,{_xScale:l,_yScale:s,_datasetIndex:f,_index:i,_model:{x:a?l.getPixelForDecimal(.5):l.getPixelForValue("object"==typeof c?c:NaN,i,f,o.chart.isCombo),y:a?s.getBasePixel():s.getPixelForValue(c,i,f),radius:a?0:u.radius?u.radius:o.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,n,h);var g=n._model;g.skip=u.skip?u.skip:isNaN(g.x)||isNaN(g.y),n.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(n){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,n);var a=i.chart.data.datasets[n._datasetIndex],o=n._index,r=n.custom||{},l=n._model;
+    l.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(a.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(a.data[o])},removeHoverStyle:function(e){var n=this;t.DatasetController.prototype.removeHoverStyle.call(n,e,n.chart.options.elements.point);var i=n.chart.data.datasets[e._datasetIndex].data[e._index],a=e.custom||{},o=e._model;o.radius=a.radius?a.radius:n.getRadius(i)}})}},{}],17:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults;n.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var o=t.getDatasetMeta(0),r=n.datasets[0],l=o.data[a],s=l&&l.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:u(r.backgroundColor,a,d.backgroundColor),h=s.borderColor?s.borderColor:u(r.borderColor,a,d.borderColor),f=s.borderWidth?s.borderWidth:u(r.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[a])||o.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,o=e.index,r=this.chart;for(n=0,i=(r.data.datasets||[]).length;n<i;++n)a=r.getDatasetMeta(n),a.data[o]&&(a.data[o].hidden=!a.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,n){var i=n.labels[t.index],a=": "+n.datasets[t.datasetIndex].data[t.index];return e.isArray(i)?(i=i.slice(),i[0]+=a):i+=a,i}}}},n.pie=e.clone(n.doughnut),e.extend(n.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var n=this,i=n.chart,a=i.chartArea,o=i.options,r=o.elements.arc,l=a.right-a.left-r.borderWidth,s=a.bottom-a.top-r.borderWidth,u=Math.min(l,s),d={x:0,y:0},c=n.getMeta(),h=o.cutoutPercentage,f=o.circumference;if(f<2*Math.PI){var g=o.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(p),y:Math.sin(p)},b=g<=0&&0<=p||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,w=h/100,M={x:y?-1:Math.min(m.x*(m.x<0?1:w),v.x*(v.x<0?1:w)),y:k?-1:Math.min(m.y*(m.y<0?1:w),v.y*(v.y<0?1:w))},S={x:b?1:Math.max(m.x*(m.x>0?1:w),v.x*(v.x>0?1:w)),y:x?1:Math.max(m.y*(m.y>0?1:w),v.y*(v.y>0?1:w))},C={width:.5*(S.x-M.x),height:.5*(S.y-M.y)};u=Math.min(l/C.width,s/C.height),d={x:(S.x+M.x)*-.5,y:(S.y+M.y)*-.5}}i.borderWidth=n.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=n.calculateTotal(),n.outerRadius=i.outerRadius-i.radiusLength*n.getRingIndex(n.index),n.innerRadius=Math.max(n.outerRadius-i.radiusLength,0),e.each(c.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){var a=this,o=a.chart,r=o.chartArea,l=o.options,s=l.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=l.rotation,h=l.rotation,f=a.getDataset(),g=i&&s.animateRotate?0:t.hidden?0:a.calculateCircumference(f.data[n])*(l.circumference/(2*Math.PI)),p=i&&s.animateScale?0:a.innerRadius,m=i&&s.animateScale?0:a.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:a.index,_index:n,_model:{x:u+o.offsetX,y:d+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,n,o.data.labels[n])}});var b=t._model;this.removeHoverStyle(t),i&&s.animateRotate||(0===n?b.startAngle=l.rotation:b.startAngle=a.getMeta().data[n-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,n=this.getDataset(),i=this.getMeta(),a=0;return e.each(i.data,function(e,i){t=n.data[i],isNaN(t)||e.hidden||(a+=Math.abs(t))}),a},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,n=t[r]._chart?t[r]._chart.config.data.datasets[a].hoverBorderWidth:0,i=e>i?e:i,i=n>i?n:i;return i}})}},{}],18:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return n.getValueOrDefault(t.showLine,e.showLines)}var n=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,a,o,r=this,l=r.getMeta(),s=l.dataset,u=l.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(l.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(o=s.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),s._scale=h,s._datasetIndex=r.index,s._children=u,s._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:o.tension?o.tension:n.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:n.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:o.cubicInterpolationMode?o.cubicInterpolationMode:n.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},s.pivot()),i=0,a=u.length;i<a;++i)r.updateElement(u[i],i,t);for(g&&0!==s._model.tension&&r.updateBezierControlPoints(),i=0,a=u.length;i<a;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,a=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.backgroundColor:a.pointBackgroundColor?i=n.getValueAtIndexOrDefault(a.pointBackgroundColor,e,i):a.backgroundColor&&(i=a.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,a=this.getDataset(),o=t.custom||{};return o.borderColor?i=o.borderColor:a.pointBorderColor?i=n.getValueAtIndexOrDefault(a.pointBorderColor,e,i):a.borderColor&&(i=a.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,a=this.getDataset(),o=t.custom||{};return isNaN(o.borderWidth)?isNaN(a.pointBorderWidth)?isNaN(a.borderWidth)||(i=a.borderWidth):i=n.getValueAtIndexOrDefault(a.pointBorderWidth,e,i):i=o.borderWidth,i},updateElement:function(t,e,i){var a,o,r=this,l=r.getMeta(),s=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(l.yAxisID),f=r.getScaleForId(l.xAxisID),g=r.chart.options.elements.point,p=r.chart.data.labels||[],m=1===p.length||1===u.data.length||r.chart.isCombo;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),a=f.getPixelForValue("object"==typeof c?c:NaN,e,d,m),o=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:a,y:o,skip:s.skip||isNaN(a)||isNaN(o),radius:s.radius||n.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:s.pointStyle||n.getValueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:l.dataset._model?l.dataset._model.tension:0,steppedLine:!!l.dataset._model&&l.dataset._model.steppedLine,hitRadius:s.hitRadius||n.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,o,r=this,l=r.chart,s=r.getMeta(),u=r.getScaleForId(s.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;i<n;i++)if(a=l.data.datasets[i],o=l.getDatasetMeta(i),"line"===o.type&&o.yAxisID===u.id&&l.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));h<0?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return f<0?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,i,a,o,r,l=this,s=l.getMeta(),u=l.chart.chartArea,d=s.data||[];if(s.dataset._model.spanGaps&&(d=d.filter(function(t){return!t._model.skip})),"monotone"===s.dataset._model.cubicInterpolationMode)n.splineCurveMonotone(d);else for(e=0,i=d.length;e<i;++e)a=d[e],o=a._model,r=n.splineCurve(n.previousItem(d,e)._model,o,n.nextItem(d,e)._model,s.dataset._model.tension),o.controlPointPreviousX=r.previous.x,o.controlPointPreviousY=r.previous.y,o.controlPointNextX=r.next.x,o.controlPointNextY=r.next.y;if(l.chart.options.elements.line.capBezierPoints)for(e=0,i=d.length;e<i;++e)o=d[e]._model,o.controlPointPreviousX=t(o.controlPointPreviousX,u.left,u.right),o.controlPointPreviousY=t(o.controlPointPreviousY,u.top,u.bottom),o.controlPointNextX=t(o.controlPointNextX,u.left,u.right),o.controlPointNextY=t(o.controlPointNextY,u.top,u.bottom)},draw:function(){var n=this,i=n.chart,a=n.getMeta(),o=a.data||[],r=i.chartArea,l=o.length,s=0;for(t.canvasHelpers.clipArea(i.ctx,r),e(n.getDataset(),i.options)&&a.dataset.draw(),t.canvasHelpers.unclipArea(i.ctx);s<l;++s)o[s].draw(r)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;o.radius=a.hoverRadius||n.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=a.hoverBackgroundColor||n.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,n.getHoverColor(o.backgroundColor)),o.borderColor=a.hoverBorderColor||n.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,n.getHoverColor(o.borderColor)),o.borderWidth=a.hoverBorderWidth||n.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||n.getValueAtIndexOrDefault(i.pointRadius,a,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,a),r.borderColor=e.getPointBorderColor(t,a),r.borderWidth=e.getPointBorderWidth(t,a)}})}},{}],19:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var o=t.getDatasetMeta(0),r=n.datasets[0],l=o.data[a],s=l.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=s.backgroundColor?s.backgroundColor:u(r.backgroundColor,a,d.backgroundColor),h=s.borderColor?s.borderColor:u(r.borderColor,a,d.borderColor),f=s.borderWidth?s.borderWidth:u(r.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[a])||o.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,o=e.index,r=this.chart;for(n=0,i=(r.data.datasets||[]).length;n<i;++n)a=r.getDatasetMeta(n),a.data[o].hidden=!a.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var n=this,i=n.chart,a=i.chartArea,o=n.getMeta(),r=i.options,l=r.elements.arc,s=Math.min(a.right-a.left,a.bottom-a.top);i.outerRadius=Math.max((s-l.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),n.outerRadius=i.outerRadius-i.radiusLength*n.index,n.innerRadius=n.outerRadius-i.radiusLength,o.count=n.countVisibleElements(),e.each(o.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){for(var a=this,o=a.chart,r=a.getDataset(),l=o.options,s=l.animation,u=o.scale,d=e.getValueAtIndexOrDefault,c=o.data.labels,h=a.calculateCircumference(r.data[n]),f=u.xCenter,g=u.yCenter,p=0,m=a.getMeta(),v=0;v<n;++v)isNaN(r.data[v])||m.data[v].hidden||++p;var b=l.startAngle,x=t.hidden?0:u.getDistanceFromCenterForValue(r.data[n]),y=b+h*p,k=y+(t.hidden?0:h),w=s.animateScale?0:u.getDistanceFromCenterForValue(r.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:u,_model:{x:f,y:g,innerRadius:0,outerRadius:i?w:x,startAngle:i&&s.animateRotate?b:y,endAngle:i&&s.animateRotate?b:k,label:d(c,n,c[n])}}),a.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),n=this.getMeta(),i=0;return e.each(n.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var n=this,i=n.getMeta(),a=i.dataset,o=i.data,r=a.custom||{},l=n.getDataset(),s=n.chart.options.elements.line,u=n.chart.scale;void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),e.extend(i.dataset,{_datasetIndex:n.index,_scale:u,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(l.lineTension,s.tension),backgroundColor:r.backgroundColor?r.backgroundColor:l.backgroundColor||s.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:l.borderWidth||s.borderWidth,borderColor:r.borderColor?r.borderColor:l.borderColor||s.borderColor,fill:r.fill?r.fill:void 0!==l.fill?l.fill:s.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:l.borderCapStyle||s.borderCapStyle,borderDash:r.borderDash?r.borderDash:l.borderDash||s.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:l.borderDashOffset||s.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:l.borderJoinStyle||s.borderJoinStyle}}),i.dataset.pivot(),e.each(o,function(e,i){n.updateElement(e,i,t)},n),n.updateBezierControlPoints()},updateElement:function(t,n,i){var a=this,o=t.custom||{},r=a.getDataset(),l=a.chart.scale,s=a.chart.options.elements.point,u=l.getPointPositionForValue(n,r.data[n]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),e.extend(t,{_datasetIndex:a.index,_index:n,_scale:l,_model:{x:i?l.xCenter:u.x,y:i?l.yCenter:u.y,tension:o.tension?o.tension:e.getValueOrDefault(r.lineTension,a.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,n,s.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,n,s.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,n,s.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,n,s.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,n,s.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.pointHitRadius,n,s.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,n=this.getMeta();e.each(n.data,function(i,a){var o=i._model,r=e.splineCurve(e.previousItem(n.data,a,!0)._model,o,e.nextItem(n.data,a,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(n.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.pointHoverBackgroundColor,a,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(n.pointHoverBorderColor,a,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(n.pointHoverBorderWidth,a,o.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(n.pointRadius,a,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(n.pointBackgroundColor,a,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(n.pointBorderColor,a,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(n.pointBorderWidth,a,r.borderWidth)}})}},{}],21:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a,o,r=this.animations;for(e.chart=t,i||(t.animating=!0),a=0,o=r.length;a<o;++a)if(r[a].chart===t)return void(r[a]=e);r.push(e),1===r.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var n=e.findIndex(this.animations,function(e){return e.chart===t});n!==-1&&(this.animations.splice(n,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+n);var i=Date.now();t.dropFrames+=(i-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var n,i,a=this.animations,o=0;o<a.length;)n=a[o],i=n.chart,n.currentStep=(n.currentStep||0)+t,n.currentStep=Math.min(n.currentStep,n.numSteps),e.callback(n.render,[i,n],i),e.callback(n.onAnimationProgress,[n],i),n.currentStep>=n.numSteps?(e.callback(n.onAnimationComplete,[n],i),i.animating=!1,a.splice(o,1)):++o}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{}],22:[function(t,e,n){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(e,n,i,a,o){var r,l,s,u,d,c;if("object"==typeof n&&(r=n.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void e.drawImage(n,a-n.width/2,o-n.height/2,n.width,n.height);if(!(isNaN(i)||i<=0)){switch(n){default:e.beginPath(),e.arc(a,o,i,0,2*Math.PI),e.closePath(),e.fill();break;case"triangle":e.beginPath(),l=3*i/Math.sqrt(3),d=l*Math.sqrt(3)/2,e.moveTo(a-l/2,o+d/3),e.lineTo(a+l/2,o+d/3),e.lineTo(a,o-2*d/3),e.closePath(),e.fill();break;case"rect":c=1/Math.SQRT2*i,e.beginPath(),e.fillRect(a-c,o-c,2*c,2*c),e.strokeRect(a-c,o-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=a-h,g=o-h,p=Math.SQRT2*i;t.helpers.drawRoundedRectangle(e,f,g,p,p,i/2),e.fill();break;case"rectRot":c=1/Math.SQRT2*i,e.beginPath(),e.moveTo(a-c,o),e.lineTo(a,o+c),e.lineTo(a+c,o),e.lineTo(a,o-c),e.closePath(),e.fill();break;case"cross":e.beginPath(),e.moveTo(a,o+i),e.lineTo(a,o-i),e.moveTo(a-i,o),e.lineTo(a+i,o),e.closePath();break;case"crossRot":e.beginPath(),s=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(a-s,o-u),e.lineTo(a+s,o+u),e.moveTo(a-s,o+u),e.lineTo(a+s,o-u),e.closePath();break;case"star":e.beginPath(),e.moveTo(a,o+i),e.lineTo(a,o-i),e.moveTo(a-i,o),e.lineTo(a+i,o),s=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(a-s,o-u),e.lineTo(a+s,o+u),e.moveTo(a-s,o+u),e.lineTo(a+s,o-u),e.closePath();break;case"line":e.beginPath(),e.moveTo(a-i,o),e.lineTo(a+i,o),e.closePath();break;case"dash":e.beginPath(),e.moveTo(a,o),e.lineTo(a+i,o),e.closePath()}e.stroke()}},e.clipArea=function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},e.unclipArea=function(t){t.restore()},e.lineTo=function(t,e,n,i){return n.steppedLine?("after"===n.steppedLine?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y)):n.tension?void t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):void t.lineTo(n.x,n.y)},t.helpers.canvas=e}},{}],23:[function(t,e,n){"use strict";e.exports=function(t){function e(e){e=e||{};var n=e.data=e.data||{};return n.datasets=n.datasets||[],n.labels=n.labels||[],e.options=a.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}function n(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}function i(t){return"top"===t||"bottom"===t}var a=t.helpers,o=t.plugins,r=t.platform;t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(n,i){var o=this;i=e(i);var l=r.acquireContext(n,i),s=l&&l.canvas,u=s&&s.height,d=s&&s.width;return o.id=a.uid(),o.ctx=l,o.canvas=s,o.config=i,o.width=d,o.height=u,o.aspectRatio=u?d/u:null,o.options=i.options,o._bufferedRender=!1,o.chart=o,o.controller=o,t.instances[o.id]=o,Object.defineProperty(o,"data",{get:function(){return o.config.data},set:function(t){o.config.data=t}}),l&&s?(o.initialize(),void o.update()):void console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return o.notify(t,"beforeInit"),a.retinaScale(t),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),o.notify(t,"afterInit"),t},clear:function(){return a.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,r=n.maintainAspectRatio&&e.aspectRatio||null,l=Math.floor(a.getMaximumWidth(i)),s=Math.floor(r?l/r:a.getMaximumHeight(i));if((e.width!==l||e.height!==s)&&(i.width=e.width=l,i.height=e.height=s,i.style.width=l+"px",i.style.height=s+"px",a.retinaScale(e),!t)){var u={width:l,height:s};o.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,o=e.scales={},r=[];n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=a.getValueOrDefault(r.type,n.dtype),s=t.scaleService.getScaleConstructor(l);if(s){i(r.position)!==i(n.dposition)&&(r.position=n.dposition);var u=new s({id:r.id,options:r,ctx:e.ctx,chart:e});o[u.id]=u,n.isDefault&&(e.scale=u)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];if(a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o);if(r.type||(r.type=a.type||e.config.type),n.push(r.type),r.controller)r.controller.updateIndex(o);else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),i.push(r.controller)}},e),n.length>1)for(var o=1;o<n.length;o++)if(n[o]!==n[o-1]){e.isCombo=!0;break}return i},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t,e){var i=this;if(n(i),o.notify(i,"beforeUpdate")!==!1){i.tooltip._data=i.data;var r=i.buildOrUpdateControllers();a.each(i.data.datasets,function(t,e){i.getDatasetMeta(e).controller.buildOrUpdateElements()},i),i.updateLayout(),a.each(r,function(t){t.reset()}),i.updateDatasets(),o.notify(i,"afterUpdate"),i._bufferedRender?i._bufferedRequest={lazy:e,duration:t}:i.render(t,e)}},updateLayout:function(){var e=this;o.notify(e,"beforeLayout")!==!1&&(t.layoutService.update(this,this.width,this.height),o.notify(e,"afterScaleUpdate"),o.notify(e,"afterLayout"))},updateDatasets:function(){var t=this;if(o.notify(t,"beforeDatasetsUpdate")!==!1){for(var e=0,n=t.data.datasets.length;e<n;++e)t.updateDataset(e);o.notify(t,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this,n=e.getDatasetMeta(t),i={meta:n,index:t};o.notify(e,"beforeDatasetUpdate",[i])!==!1&&(n.controller.update(),o.notify(e,"afterDatasetUpdate",[i]))},render:function(e,n){var i=this;if(o.notify(i,"beforeRender")!==!1){var r=i.options.animation,l=function(t){o.notify(i,"afterRender"),a.callback(r&&r.onComplete,[t],i)};if(r&&("undefined"!=typeof e&&0!==e||"undefined"==typeof e&&0!==r.duration)){var s=new t.Animation({numSteps:(e||r.duration)/16.66,easing:r.easing,render:function(t,e){var n=a.easingEffects[e.easing],i=e.currentStep,o=i/e.numSteps;t.draw(n(o),o,i)},onAnimationProgress:r.onProgress,onAnimationComplete:l});t.animationService.addAnimation(i,s,e,n)}else i.draw(),l(new t.Animation({numSteps:0,chart:i}));return i}},draw:function(t){var e=this;e.clear(),void 0!==t&&null!==t||(t=1),e.transition(t),o.notify(e,"beforeDraw",[t])!==!1&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e.tooltip.draw(),o.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=this,n=0,i=(e.data.datasets||[]).length;n<i;++n)e.isDatasetVisible(n)&&e.getDatasetMeta(n).controller.transition(t);e.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(o.notify(e,"beforeDatasetsDraw",[t])!==!1){for(var n=(e.data.datasets||[]).length-1;n>=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);o.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this,i=n.getDatasetMeta(t),a={meta:i,index:t,easingValue:e};o.notify(n,"beforeDatasetDraw",[a])!==!1&&(i.controller.draw(e),o.notify(n,"afterDatasetDraw",[a]))},getElementAtEvent:function(e){return t.Interaction.modes.single(this,e)},getElementsAtEvent:function(e){return t.Interaction.modes.label(this,e,{intersect:!0})},getElementsAtXAxis:function(e){return t.Interaction.modes["x-axis"](this,e,{intersect:!0})},getElementsAtEventForMode:function(e,n,i){var a=t.Interaction.modes[n];return"function"==typeof a?a(this,e,i):[]},getDatasetAtEvent:function(e){return t.Interaction.modes.dataset(this,e,{intersect:!0})},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var e,n,i,l=this,s=l.canvas;for(l.stop(),n=0,i=l.data.datasets.length;n<i;++n)e=l.getDatasetMeta(n),e.controller&&(e.controller.destroy(),e.controller=null);s&&(l.unbindEvents(),a.clear(l),r.releaseContext(l.ctx),l.canvas=null,l.ctx=null),o.notify(l,"destroy"),delete t.instances[l.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e),e.tooltip.initialize()},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(i){r.addEventListener(t,i,n),e[i]=n}),t.options.responsive&&(n=function(){t.resize()},r.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,n){r.removeEventListener(t,n,e)}))},updateHoverStyle:function(t,e,n){var i,a,o,r=n?"setHoverStyle":"removeHoverStyle";for(a=0,o=t.length;a<o;++a)i=t[a],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var e=this,n=e.tooltip;if(o.notify(e,"beforeEvent",[t])!==!1){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);i|=n&&n.handleEvent(t),o.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a.duration,a.lazy):i&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,o=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),i.onHover&&i.onHover.call(e,t.native,e.active),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(e,t.native,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),o=!a.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,o}}),t.Controller=t}},{}],24:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t._chartjs?void t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),void a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),o=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),o}})}))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,o=i.indexOf(e);
+    o!==-1&&i.splice(o,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],o=i.data;for(t=0,e=a.length;t<e;++t)o[t]=o[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=i.getValueAtIndexOrDefault,l=t._model;l.backgroundColor=o.backgroundColor?o.backgroundColor:r(n.backgroundColor,a,e.backgroundColor),l.borderColor=o.borderColor?o.borderColor:r(n.borderColor,a,e.borderColor),l.borderWidth=o.borderWidth?o.borderWidth:r(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},o=i.getValueAtIndexOrDefault,r=i.getHoverColor,l=t._model;l.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:o(e.hoverBackgroundColor,n,r(l.backgroundColor)),l.borderColor=a.hoverBorderColor?a.hoverBorderColor:o(e.hoverBorderColor,n,r(l.borderColor)),l.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:o(e.hoverBorderWidth,n,l.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;a<i?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{}],25:[function(t,e,n){"use strict";var i=t(3);e.exports=function(t){function e(t,e,n,a){var o,r,l,s,u,d,c,h,f,g=Object.keys(n);for(o=0,r=g.length;o<r;++o)if(l=g[o],d=n[l],e.hasOwnProperty(l)||(e[l]=d),s=e[l],s!==d&&"_"!==l[0]){if(t.hasOwnProperty(l)||(t[l]=s),u=t[l],c=typeof d,c===typeof u)if("string"===c){if(h=i(u),h.valid&&(f=i(d),f.valid)){e[l]=f.mix(h,a).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[l]=u+(d-u)*a;continue}e[l]=d}}var n=t.helpers;t.elements={},t.Element=function(t){n.extend(this,t),this.initialize.apply(this,arguments)},n.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=n.clone(t._model)),t._start={},t},transition:function(t){var n=this,i=n._model,a=n._start,o=n._view;return i&&1!==t?(o||(o=n._view={}),a||(a=n._start={}),e(a,o,i,t),n):(n._view=i,n._start=null,n)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return n.isNumber(this._model.x)&&n.isNumber(this._model.y)}}),t.Element.extend=n.inherits}},{3:3}],26:[function(t,e,n){"use strict";var i=t(3);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),t.indexOf("%")!==-1&&(i=i/100*e.parentNode[n])):i=t,i}function n(t){return void 0!==t&&null!==t&&"none"!==t}function a(t,i,a){var o=document.defaultView,r=t.parentNode,l=o.getComputedStyle(t)[i],s=o.getComputedStyle(r)[i],u=n(l),d=n(s),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(l,t,a):c,d?e(s,r,a):c):"none"}var o=t.helpers={};o.each=function(t,e,n,i){var a,r;if(o.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if("object"==typeof t){var l=Object.keys(t);for(r=l.length,a=0;a<r;a++)e.call(n,t[l[a]],l[a])}},o.clone=function(t){var e={};return o.each(t,function(t,n){o.isArray(t)?e[n]=t.slice(0):"object"==typeof t&&null!==t?e[n]=o.clone(t):e[n]=t}),e},o.extend=function(t){for(var e=function(e,n){t[n]=e},n=1,i=arguments.length;n<i;n++)o.each(arguments[n],e);return t},o.configMerge=function(e){var n=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){var a=n.hasOwnProperty(i),r=a?n[i]:{};"scales"===i?n[i]=o.scaleMerge(r,e):"scale"===i?n[i]=o.configMerge(r,t.scaleService.getScaleDefaults(e.type),e):!a||"object"!=typeof r||o.isArray(r)||null===r||"object"!=typeof e||o.isArray(e)?n[i]=e:n[i]=o.configMerge(r,e)})}),n},o.scaleMerge=function(e,n){var i=o.clone(e);return o.each(n,function(e,n){"xAxes"===n||"yAxes"===n?i.hasOwnProperty(n)?o.each(e,function(e,a){var r=o.getValueOrDefault(e.type,"xAxes"===n?"category":"linear"),l=t.scaleService.getScaleDefaults(r);a>=i[n].length||!i[n][a].type?i[n].push(o.configMerge(l,e)):e.type&&e.type!==i[n][a].type?i[n][a]=o.configMerge(i[n][a],l,e):i[n][a]=o.configMerge(i[n][a],e)}):(i[n]=[],o.each(e,function(e){var a=o.getValueOrDefault(e.type,"xAxes"===n?"category":"linear");i[n].push(o.configMerge(t.scaleService.getScaleDefaults(a),e))})):i.hasOwnProperty(n)&&"object"==typeof i[n]&&null!==i[n]&&"object"==typeof e?i[n]=o.configMerge(i[n],e):i[n]=e}),i},o.getValueAtIndexOrDefault=function(t,e,n){return void 0===t||null===t?n:o.isArray(t)?e<t.length?t[e]:n:t},o.getValueOrDefault=function(t,e){return void 0===t?e:t},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var n=0,i=t.length;n<i;++n)if(t[n]===e)return n;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return o.each(t,function(t){e(t)&&n.push(t)}),n},o.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},o.findNextWhere=function(t,e,n){void 0!==n&&null!==n||(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},o.findPreviousWhere=function(t,e,n){void 0!==n&&null!==n||(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},o.inherits=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=o.inherits,t&&o.extend(n.prototype,t),n.__super__=e.prototype,n},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,n){return Math.abs(t-e)<n},o.almostWhole=function(t,e){var n=Math.round(t);return n-e<t&&n+e>t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),o=Math.atan2(i,n);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,n,i){var a=t.skip?e:t,o=e,r=n.skip?e:n,l=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),s=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=l/(l+s),d=s/(l+s);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,n,i,a,r=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),l=r.length;for(e=0;e<l;++e)if(i=r[e],!i.model.skip){if(n=e>0?r[e-1]:null,a=e<l-1?r[e+1]:null,a&&!a.model.skip){var s=a.model.x-i.model.x;i.deltaK=0!==s?(a.model.y-i.model.y)/s:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}var u,d,c,h;for(e=0;e<l-1;++e)i=r[e],a=r[e+1],i.model.skip||a.model.skip||(o.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(u=i.mK/i.deltaK,d=a.mK/i.deltaK,h=Math.pow(u,2)+Math.pow(d,2),h<=9||(c=3/Math.sqrt(h),i.mK=u*c*i.deltaK,a.mK=d*c*i.deltaK)));var f;for(e=0;e<l;++e)i=r[e],i.model.skip||(n=e>0?r[e-1]:null,a=e<l-1?r[e+1]:null,n&&!n.model.skip&&(f=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-f,i.model.controlPointPreviousY=i.model.y-f*i.mK),a&&!a.model.skip&&(f=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+f,i.model.controlPointNextY=i.model.y+f*i.mK))},o.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var n,i=Math.floor(o.log10(t)),a=t/Math.pow(10,i);return n=e?a<1.5?1:a<3?2:a<7?5:10:a<=1?1:a<=2?2:a<=5?5:10,n*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2===(t/=.5)?1:(n||(n=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):t<2/2.75?1*(7.5625*(t-=1.5/2.75)*t+.75):t<2.5/2.75?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return t<.5?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return"undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,l=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=l.right-l.left-u-c,g=l.bottom-l.top-d-h;return n=Math.round((n-l.left-u)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-l.top-d)/g*r.height/e.currentDevicePixelRatio),{x:n,y:i}},o.addEvent=function(t,e,n){t.addEventListener?t.addEventListener(e,n):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n},o.removeEvent=function(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=o.noop},o.getConstraintWidth=function(t){return a(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return a(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,n=parseInt(o.getStyle(e,"padding-left"),10),i=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode,n=parseInt(o.getStyle(e,"padding-top"),10),i=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var n=t.canvas,i=t.height,a=t.width;n.height=i*e,n.width=a*e,t.ctx.scale(e,e),n.style.height=i+"px",n.style.width=a+"px"}},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,n){return e+" "+t+"px "+n},o.longestText=function(t,e,n,i){i=i||{};var a=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var l=0;o.each(n,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?l=o.measureText(t,a,r,l,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(l=o.measureText(t,a,r,l,e))})});var s=r.length/2;if(s>n.length){for(var u=0;u<s;u++)delete a[r[u]];r.splice(0,s)}return l},o.measureText=function(t,e,n,i,a){var o=e[a];return o||(o=e[a]=t.measureText(a).width,n.push(a)),o>i&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,n,i,a,o){t.beginPath(),t.moveTo(e+o,n),t.lineTo(e+i-o,n),t.quadraticCurveTo(e+i,n,e+i,n+o),t.lineTo(e+i,n+a-o),t.quadraticCurveTo(e+i,n+a,e+i-o,n+a),t.lineTo(e+o,n+a),t.quadraticCurveTo(e,n+a,e,n+a-o),t.lineTo(e,n+o),t.quadraticCurveTo(e,n,e+o,n),t.closePath()},o.color=i?function(e){return e instanceof CanvasGradient&&(e=t.defaults.global.defaultColor),i(e)}:function(t){return console.error("Color.js not found!"),t},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!o.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},o.callback=function(t,e,n){t&&"function"==typeof t.call&&t.apply(n,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()},o.callCallback=o.callback}},{3:3}],27:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.native?{x:t.x,y:t.y}:r.getRelativePosition(t,e)}function n(t,e){var n,i,a,o,r,l=t.data.datasets;for(i=0,o=l.length;i<o;++i)if(t.isDatasetVisible(i))for(n=t.getDatasetMeta(i),a=0,r=n.data.length;a<r;++a){var s=n.data[a];s._view.skip||e(s)}}function i(t,e){var i=[];return n(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function a(t,e,i,a){var o=Number.POSITIVE_INFINITY,l=[];return a||(a=r.distanceBetweenPoints),n(t,function(t){if(!i||t.inRange(e.x,e.y)){var n=t.getCenterPoint(),r=a(e,n);r<o?(l=[t],o=r):r===o&&l.push(t)}}),l}function o(t,n,o){var r=e(n,t),l=function(t,e){return Math.abs(t.x-e.x)},s=o.intersect?i(t,r):a(t,r,!1,l),u=[];return s.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n),a=i.data[s[0]._index];a&&!a._view.skip&&u.push(a)}}),u):[]}var r=t.helpers;t.Interaction={modes:{single:function(t,i){var a=e(i,t),o=[];return n(t,function(t){if(t.inRange(a.x,a.y))return o.push(t),o}),o.slice(0,1)},label:o,index:o,dataset:function(t,n,o){var r=e(n,t),l=o.intersect?i(t,r):a(t,r,!1);return l.length>0&&(l=t.getDatasetMeta(l[0]._datasetIndex).data),l},"x-axis":function(t,e){return o(t,e,!0)},point:function(t,n){var a=e(n,t);return i(t,a)},nearest:function(t,n,i){var o=e(n,t),r=a(t,o,i.intersect);return r.length>1&&r.sort(function(t,e){var n=t.getArea(),i=e.getArea(),a=n-i;return 0===a&&(a=t._datasetIndex-e._datasetIndex),a}),r.slice(0,1)},x:function(t,i,a){var o=e(i,t),r=[],l=!1;return n(t,function(t){t.inXRange(o.x)&&r.push(t),t.inRange(o.x,o.y)&&(l=!0)}),a.intersect&&!l&&(r=[]),r},y:function(t,i,a){var o=e(i,t),r=[],l=!1;return n(t,function(t){t.inYRange(o.y)&&r.push(t),t.inRange(o.x,o.y)&&(l=!0)}),a.intersect&&!l&&(r=[]),r}}}}},{}],28:[function(t,e,n){"use strict";e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return i.where(t,function(t){return t.position===e})}function n(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i._tmpIndex_-a._tmpIndex_:i.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}var i=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;n!==-1&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],o=a.length,r=0;r<o;++r)i=a[r],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,a,o){function r(t){var e,n=t.isHorizontal();n?(e=t.update(t.fullWidth?k:I,D),A-=e.height):(e=t.update(C,S),I-=e.width),P.push({horizontal:n,minSize:e,box:t})}function l(t){var e=i.findNextWhere(P,function(e){return e.box===t});if(e)if(t.isHorizontal()){var n={left:Math.max(L,_),right:Math.max(V,T),top:0,bottom:0};t.update(t.fullWidth?k:I,w/2,n)}else t.update(e.minSize.width,A)}function s(t){var e=i.findNextWhere(P,function(e){return e.box===t}),n={left:0,right:0,top:O,bottom:z};e&&t.update(e.minSize.width,A,n)}function u(t){t.isHorizontal()?(t.left=t.fullWidth?h:L,t.right=t.fullWidth?a-f:L+I,t.top=q,t.bottom=q+t.height,q=t.bottom):(t.left=H,t.right=H+t.width,t.top=O,t.bottom=O+A,H=t.right)}if(t){var d=t.options.layout,c=d?d.padding:null,h=0,f=0,g=0,p=0;isNaN(c)?(h=c.left||0,f=c.right||0,g=c.top||0,p=c.bottom||0):(h=c,f=c,g=c,p=c);var m=e(t.boxes,"left"),v=e(t.boxes,"right"),b=e(t.boxes,"top"),x=e(t.boxes,"bottom"),y=e(t.boxes,"chartArea");n(m,!0),n(v,!1),n(b,!0),n(x,!1);var k=a-h-f,w=o-g-p,M=k/2,S=w/2,C=(a-M)/(m.length+v.length),D=(o-S)/(b.length+x.length),I=k,A=w,P=[];i.each(m.concat(v,b,x),r);var _=0,T=0,F=0,R=0;i.each(b.concat(x),function(t){if(t.getPadding){var e=t.getPadding();_=Math.max(_,e.left),T=Math.max(T,e.right)}}),i.each(m.concat(v),function(t){if(t.getPadding){var e=t.getPadding();F=Math.max(F,e.top),R=Math.max(R,e.bottom)}});var L=h,V=f,O=g,z=p;i.each(m.concat(v),l),i.each(m,function(t){L+=t.width}),i.each(v,function(t){V+=t.width}),i.each(b.concat(x),l),i.each(b,function(t){O+=t.height}),i.each(x,function(t){z+=t.height}),i.each(m.concat(v),s),L=h,V=f,O=g,z=p,i.each(m,function(t){L+=t.width}),i.each(v,function(t){V+=t.width}),i.each(b,function(t){O+=t.height}),i.each(x,function(t){z+=t.height});var B=Math.max(_-L,0);L+=B,V+=Math.max(T-V,0);var W=Math.max(F-O,0);O+=W,z+=Math.max(R-z,0);var N=o-O-z,E=a-L-V;E===I&&N===A||(i.each(m,function(t){t.height=N}),i.each(v,function(t){t.height=N}),i.each(b,function(t){t.fullWidth||(t.width=E)}),i.each(x,function(t){t.fullWidth||(t.width=E)}),A=N,I=E);var H=h+B,q=g+W;i.each(m.concat(b),u),H+=I,q+=A,i.each(v,u),i.each(x,u),t.chartArea={left:L,top:O,right:L+I,bottom:O+A},i.each(y,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(I,A)})}}}}},{}],30:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.plugins={},t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){e.indexOf(t)===-1&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);n!==-1&&e.splice(n,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,o,r,l,s=this.descriptors(t),u=s.length;for(i=0;i<u;++i)if(a=s[i],o=a.plugin,l=o[e],"function"==typeof l&&(r=[t].concat(n||[]),r.push(a.options),l.apply(o,r)===!1))return!1;return!0},descriptors:function(n){var i=n._plugins||(n._plugins={});if(i.id===this._cacheId)return i.descriptors;var a=[],o=[],r=n&&n.config||{},l=t.defaults.global.plugins,s=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){var n=a.indexOf(t);if(n===-1){var i=t.id,r=s[i];r!==!1&&(r===!0&&(r=e.clone(l[i])),a.push(t),o.push({plugin:t,options:r||{}}))}}),i.descriptors=o,i.id=this._cacheId,o}},t.pluginService=t.plugins,t.PluginBase=t.Element.extend({})}},{}],31:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e,n){return i.isArray(e)?i.longestText(t,n,e):t.measureText(e).width}function n(e){var n=i.getValueOrDefault,a=t.defaults.global,o=n(e.fontSize,a.defaultFontSize),r=n(e.fontStyle,a.defaultFontStyle),l=n(e.fontFamily,a.defaultFontFamily);return{size:o,style:r,family:l,font:i.fontString(o,r,l)}}var i=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:t.Ticks.formatters.values}},t.Scale=t.Element.extend({getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},beforeUpdate:function(){i.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=e,a.margins=i.extend({left:0,right:0,top:0,bottom:0},n),a.longestTextCache=a.longestTextCache||{},a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeDataLimits(),a.determineDataLimits(),a.afterDataLimits(),a.beforeBuildTicks(),a.buildTicks(),a.afterBuildTicks(),a.beforeTickToLabelConversion(),a.convertTicksToLabels(),a.afterTickToLabelConversion(),a.beforeCalculateTickRotation(),a.calculateTickRotation(),a.afterCalculateTickRotation(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:function(){i.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){i.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){i.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){i.callback(this.options.beforeDataLimits,[this])},determineDataLimits:i.noop,afterDataLimits:function(){i.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){i.callback(this.options.beforeBuildTicks,[this])},buildTicks:i.noop,afterBuildTicks:function(){i.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){i.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback)},afterTickToLabelConversion:function(){i.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){i.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,a=t.options.ticks,o=n(a);e.font=o.font;var r=a.minRotation||0;if(t.options.display&&t.isHorizontal())for(var l,s,u=i.longestText(e,o.font,t.ticks,t.longestTextCache),d=u,c=t.getPixelForTick(1)-t.getPixelForTick(0)-6;d>c&&r<a.maxRotation;){var h=i.toRadians(r);if(l=Math.cos(h),s=Math.sin(h),s*u>t.maxHeight){r--;break}r++,d=l*u}t.labelRotation=r},afterCalculateTickRotation:function(){i.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callback(this.options.beforeFit,[this])},fit:function(){var t=this,a=t.minSize={width:0,height:0},o=t.options,r=o.ticks,l=o.scaleLabel,s=o.gridLines,u=o.display,d=t.isHorizontal(),c=n(r),h=1.5*n(l).size,f=o.gridLines.tickMarkLength;if(d?a.width=t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:a.width=u&&s.drawTicks?f:0,d?a.height=u&&s.drawTicks?f:0:a.height=t.maxHeight,l.display&&u&&(d?a.height+=h:a.width+=h),r.display&&u){var g=i.longestText(t.ctx,c.font,t.ticks,t.longestTextCache),p=i.numberOfLabelLines(t.ticks),m=.5*c.size;if(d){t.longestLabelWidth=g;var v=i.toRadians(t.labelRotation),b=Math.cos(v),x=Math.sin(v),y=x*g+c.size*p+m*p;a.height=Math.min(t.maxHeight,a.height+y),t.ctx.font=c.font;var k=t.ticks[0],w=e(t.ctx,k,c.font),M=t.ticks[t.ticks.length-1],S=e(t.ctx,M,c.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?b*w+3:b*m+3,t.paddingRight="bottom"===o.position?b*m+3:b*S+3):(t.paddingLeft=w/2+3,t.paddingRight=S/2+3)}else r.mirror?g=0:g+=t.options.ticks.padding,a.width=Math.min(t.maxWidth,a.width+g),t.paddingTop=c.size/2,t.paddingBottom=c.size/2}t.handleMargins(),t.width=a.width,t.height=a.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.noop,getPixelForTick:function(t,e){var n=this;if(n.isHorizontal()){var i=n.width-(n.paddingLeft+n.paddingRight),a=i/Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),o=a*t+n.paddingLeft;e&&(o+=a/2);var r=n.left+Math.round(o);return r+=n.isFullWidth()?n.margins.left:0}var l=n.height-(n.paddingTop+n.paddingBottom);return n.top+t*(l/(n.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=e.width-(e.paddingLeft+e.paddingRight),i=n*t+e.paddingLeft,a=e.left+Math.round(i);return a+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,n=t.max;return t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0},draw:function(e){var a=this,o=a.options;if(o.display){var r,l,s=a.ctx,u=t.defaults.global,d=o.ticks,c=o.gridLines,h=o.scaleLabel,f=0!==a.labelRotation,g=d.autoSkip,p=a.isHorizontal();d.maxTicksLimit&&(l=d.maxTicksLimit);var m=i.getValueOrDefault(d.fontColor,u.defaultFontColor),v=n(d),b=c.drawTicks?c.tickMarkLength:0,x=i.getValueOrDefault(h.fontColor,u.defaultFontColor),y=n(h),k=i.toRadians(a.labelRotation),w=Math.cos(k),M=a.longestLabelWidth*w;s.fillStyle=m;var S=[];if(p){if(r=!1,(M+d.autoSkipPadding)*a.ticks.length>a.width-(a.paddingLeft+a.paddingRight)&&(r=1+Math.floor((M+d.autoSkipPadding)*a.ticks.length/(a.width-(a.paddingLeft+a.paddingRight)))),l&&a.ticks.length>l)for(;!r||a.ticks.length/(r||1)>l;)r||(r=1),r+=1;g||(r=!1)}var C="right"===o.position?a.left:a.right-b,D="right"===o.position?a.left+b:a.right,I="bottom"===o.position?a.top:a.bottom-b,A="bottom"===o.position?a.top+b:a.bottom;if(i.each(a.ticks,function(t,n){if(void 0!==t&&null!==t){var l=a.ticks.length===n+1,s=r>1&&n%r>0||n%r===0&&n+r>=a.ticks.length;if((!s||l)&&void 0!==t&&null!==t){var h,g,m,v;n===("undefined"!=typeof a.zeroLineIndex?a.zeroLineIndex:0)?(h=c.zeroLineWidth,g=c.zeroLineColor,m=c.zeroLineBorderDash,v=c.zeroLineBorderDashOffset):(h=i.getValueAtIndexOrDefault(c.lineWidth,n),g=i.getValueAtIndexOrDefault(c.color,n),m=i.getValueOrDefault(c.borderDash,u.borderDash),v=i.getValueOrDefault(c.borderDashOffset,u.borderDashOffset));var x,y,w,M,P,_,T,F,R,L,V="middle",O="middle";if(p){"bottom"===o.position?(O=f?"middle":"top",V=f?"right":"center",L=a.top+b):(O=f?"middle":"bottom",V=f?"left":"center",L=a.bottom-b);var z=a.getPixelForTick(n)+i.aliasPixel(h);R=a.getPixelForTick(n,c.offsetGridLines)+d.labelOffset,x=w=P=T=z,y=I,M=A,_=e.top,F=e.bottom}else{var B,W="left"===o.position,N=d.padding;d.mirror?(V=W?"left":"right",B=N):(V=W?"right":"left",
+        B=b+N),R=W?a.right-B:a.left+B;var E=a.getPixelForTick(n);E+=i.aliasPixel(h),L=a.getPixelForTick(n,c.offsetGridLines),x=C,w=D,P=e.left,T=e.right,y=M=_=F=E}S.push({tx1:x,ty1:y,tx2:w,ty2:M,x1:P,y1:_,x2:T,y2:F,labelX:R,labelY:L,glWidth:h,glColor:g,glBorderDash:m,glBorderDashOffset:v,rotation:-1*k,label:t,textBaseline:O,textAlign:V})}}}),i.each(S,function(t){if(c.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),c.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),c.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),d.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=v.font,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var e=t.label;if(i.isArray(e))for(var n=0,a=0;n<e.length;++n)s.fillText(""+e[n],0,a),a+=1.5*v.size;else s.fillText(e,0,0);s.restore()}}),h.display){var P,_,T=0;if(p)P=a.left+(a.right-a.left)/2,_="bottom"===o.position?a.bottom-y.size/2:a.top+y.size/2;else{var F="left"===o.position;P=F?a.left+y.size/2:a.right-y.size/2,_=a.top+(a.bottom-a.top)/2,T=F?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(P,_),s.rotate(T),s.textAlign="center",s.textBaseline="middle",s.fillStyle=x,s.font=y.font,s.fillText(h.labelString,0,0),s.restore()}if(c.drawBorder){s.lineWidth=i.getValueAtIndexOrDefault(c.lineWidth,0),s.strokeStyle=i.getValueAtIndexOrDefault(c.color,0);var R=a.left,L=a.right,V=a.top,O=a.bottom,z=i.aliasPixel(s.lineWidth);p?(V=O="top"===o.position?a.bottom:a.top,V+=z,O+=z):(R=L="left"===o.position?a.right:a.left,R+=z,L+=z),s.beginPath(),s.moveTo(R,V),s.lineTo(L,O),s.stroke()}}}})}},{}],32:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,n,i){this.constructors[t]=n,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(n){return this.defaults.hasOwnProperty(n)?e.scaleMerge(t.defaults.scale,this.defaults[n]):{}},updateScaleDefaults:function(t,n){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],n))},addScalesToLayout:function(n){e.each(n.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,t.layoutService.addBox(n,e)})}}}},{}],33:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.Ticks={generators:{linear:function(t,n){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=e.niceNum(n.max-n.min,!1);i=e.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(n.min/i)*i,l=Math.ceil(n.max/i)*i;t.min&&t.max&&t.stepSize&&e.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,l=t.max);var s=(l-r)/i;s=e.almostEquals(s,Math.round(s),i/1e3)?Math.round(s):Math.ceil(s),a.push(void 0!==t.min?t.min:r);for(var u=1;u<s;++u)a.push(r+u*i);return a.push(void 0!==t.max?t.max:l),a},logarithmic:function(t,n){var i,a,o=[],r=e.getValueOrDefault,l=r(t.min,Math.pow(10,Math.floor(e.log10(n.min)))),s=Math.floor(e.log10(n.max)),u=Math.ceil(n.max/Math.pow(10,s));0===l?(i=Math.floor(e.log10(n.minNotZero)),a=Math.floor(n.minNotZero/Math.pow(10,i)),o.push(l),l=a*Math.pow(10,i)):(i=Math.floor(e.log10(l)),a=Math.floor(l/Math.pow(10,i)));do o.push(l),++a,10===a&&(a=1,++i),l=a*Math.pow(10,i);while(i<s||i===s&&a<u);var d=r(t.max,l);return o.push(d),o}},formatters:{values:function(t){return e.isArray(t)?t:""+t},linear:function(t,n,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var o=e.log10(Math.abs(a)),r="";if(0!==t){var l=-1*Math.floor(o);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,n,i){var a=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===n||n===i.length-1?t.toExponential():""}}}}},{}],34:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=s.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(s.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a,x:t._model.x,y:t._model.y}}function a(e){var n=t.defaults.global,i=s.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,n.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,n.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,n.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,n.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,n.defaultFontStyle),titleFontSize:i(e.titleFontSize,n.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,_footerFontFamily:i(e.footerFontFamily,n.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,n.defaultFontStyle),footerFontSize:i(e.footerFontSize,n.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors,borderColor:e.borderColor,borderWidth:e.borderWidth}}function o(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=l*d,i+=l?(l-1)*e.titleSpacing:0,i+=l?e.titleMarginBottom:0,i+=r*c,i+=r?(r-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=s.fontString(d,e._titleFontStyle,e._titleFontFamily),s.each(e.title,g),n.font=s.fontString(c,e._bodyFontStyle,e._bodyFontFamily),s.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,s.each(o,function(t){s.each(t.before,g),s.each(t.lines,g),s.each(t.after,g)}),f=0,n.font=s.fontString(h,e._footerFontStyle,e._footerFontFamily),s.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function r(t,e){var n=t._model,i=t._chart,a=t._chart.chartArea,o="center",r="center";n.y<e.height?r="top":n.y>i.height-e.height&&(r="bottom");var l,s,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===r?(l=function(t){return t<=h},s=function(t){return t>h}):(l=function(t){return t<=e.width/2},s=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},l(n.x)?(o="left",u(n.x)&&(o="center",r=c(n.y))):s(n.x)&&(o="right",d(n.x)&&(o="center",r=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:r}}function l(t,e,n){var i=t.x,a=t.y,o=t.caretSize,r=t.caretPadding,l=t.cornerRadius,s=n.xAlign,u=n.yAlign,d=o+r,c=l+r;return"right"===s?i-=e.width:"center"===s&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===s?i+=d:"right"===s&&(i-=d):"left"===s?i-=c:"right"===s&&(i+=c),{x:i,y:a}}var s=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:s.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?n=o.xLabel:a>0&&o.index<a&&(n=i[o.index])}return n},afterTitle:s.noop,beforeBody:s.noop,beforeLabel:s.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),n+=t.yLabel},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex),i=n.data[t.index],a=i._view;return{borderColor:a.borderColor,backgroundColor:a.backgroundColor}},afterLabel:s.noop,afterBody:s.noop,beforeFooter:s.noop,footer:s.noop,afterFooter:s.noop}},t.Tooltip=t.Element.extend({initialize:function(){this._model=a(this._options)},getTitle:function(){var t=this,e=t._options,i=e.callbacks,a=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),l=[];return l=n(l,a),l=n(l,o),l=n(l,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return s.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,o=[];return s.each(t,function(t){var r={before:[],lines:[],after:[]};n(r.before,a.beforeLabel.call(i,t,e)),n(r.lines,a.label.call(i,t,e)),n(r.after,a.afterLabel.call(i,t,e)),o.push(r)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return s.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),o=e.afterFooter.apply(t,arguments),r=[];return r=n(r,i),r=n(r,a),r=n(r,o)},update:function(e){var n,u,d=this,c=d._options,h=d._model,f=d._model=a(c),g=d._active,p=d._data,m={xAlign:h.xAlign,yAlign:h.yAlign},v={x:h.x,y:h.y},b={width:h.width,height:h.height},x={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var y=[];x=t.Tooltip.positioners[c.position](g,d._eventPosition);var k=[];for(n=0,u=g.length;n<u;++n)k.push(i(g[n]));c.filter&&(k=k.filter(function(t){return c.filter(t,p)})),c.itemSort&&(k=k.sort(function(t,e){return c.itemSort(t,e,p)})),s.each(k,function(t){y.push(c.callbacks.labelColor.call(d,t,d._chart))}),f.title=d.getTitle(k,p),f.beforeBody=d.getBeforeBody(k,p),f.body=d.getBody(k,p),f.afterBody=d.getAfterBody(k,p),f.footer=d.getFooter(k,p),f.x=Math.round(x.x),f.y=Math.round(x.y),f.caretPadding=c.caretPadding,f.labelColors=y,f.dataPoints=k,b=o(this,f),m=r(this,b),v=l(f,b,m)}else f.opacity=0;return f.xAlign=m.xAlign,f.yAlign=m.yAlign,f.x=v.x,f.y=v.y,f.width=b.width,f.height=b.height,f.caretX=x.x,f.caretY=x.y,d._model=f,e&&c.custom&&c.custom.call(d,f),d},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,o,r,l,s,u=n.caretSize,d=n.cornerRadius,c=n.xAlign,h=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)l=g+m/2,"left"===c?(i=f,a=i-u,o=i,r=l+u,s=l-u):(i=f+p,a=i+u,o=i,r=l-u,s=l+u);else if("left"===c?(a=f+d+u,i=a-u,o=a+u):"right"===c?(a=f+p-d-u,i=a-u,o=a+u):(a=f+p/2,i=a-u,o=a+u),"top"===h)r=g,l=r-u,s=r;else{r=g+m,l=r+u,s=r;var v=o;o=i,i=v}return{x1:i,x2:a,x3:o,y1:r,y2:l,y3:s}},drawTitle:function(t,n,i,a){var o=n.title;if(o.length){i.textAlign=n._titleAlign,i.textBaseline="top";var r=n.titleFontSize,l=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=s.fontString(r,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=o.length;u<d;++u)i.fillText(o[u],t.x,t.y),t.y+=r+l,u+1===o.length&&(t.y+=n.titleMarginBottom-l)}},drawBody:function(t,n,i,a){var o=n.bodyFontSize,r=n.bodySpacing,l=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top";var u=e(n.bodyFontColor,a);i.fillStyle=u,i.font=s.fontString(o,n._bodyFontStyle,n._bodyFontFamily);var d=0,c=function(e){i.fillText(e,t.x+d,t.y),t.y+=o+r};s.each(n.beforeBody,c);var h=n.displayColors;d=h?o+2:0,s.each(l,function(r,l){s.each(r.before,c),s.each(r.lines,function(r){h&&(i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,o,o),i.strokeStyle=e(n.labelColors[l].borderColor,a),i.strokeRect(t.x,t.y,o,o),i.fillStyle=e(n.labelColors[l].backgroundColor,a),i.fillRect(t.x+1,t.y+1,o-2,o-2),i.fillStyle=u),c(r)}),s.each(r.after,c)}),d=0,s.each(n.afterBody,c),t.y-=r},drawFooter:function(t,n,i,a){var o=n.footer;o.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=s.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),s.each(o,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,o){i.fillStyle=e(n.backgroundColor,o),i.strokeStyle=e(n.borderColor,o),i.lineWidth=n.borderWidth;var r=n.xAlign,l=n.yAlign,s=t.x,u=t.y,d=a.width,c=a.height,h=n.cornerRadius;i.beginPath(),i.moveTo(s+h,u),"top"===l&&this.drawCaret(t,a),i.lineTo(s+d-h,u),i.quadraticCurveTo(s+d,u,s+d,u+h),"center"===l&&"right"===r&&this.drawCaret(t,a),i.lineTo(s+d,u+c-h),i.quadraticCurveTo(s+d,u+c,s+d-h,u+c),"bottom"===l&&this.drawCaret(t,a),i.lineTo(s+h,u+c),i.quadraticCurveTo(s,u+c,s,u+c-h),"center"===l&&"left"===r&&this.drawCaret(t,a),i.lineTo(s,u+h),i.quadraticCurveTo(s,u,s+h,u),i.closePath(),i.fill(),n.borderWidth>0&&i.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(i,e,t,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chart.getElementsAtEventForMode(t,n.mode,n),i=!s.arrayEquals(e._active,e._lastActive),!i)return!1;if(e._lastActive=e._active,n.enabled||n.custom){e._eventPosition={x:t.x,y:t.y};var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,o=0;for(e=0,n=t.length;e<n;++e){var r=t[e];if(r&&r.hasValue()){var l=r.tooltipPosition();i+=l.x,a+=l.y,++o}}return{x:Math.round(i/o),y:Math.round(a/o)}},nearest:function(t,e){var n,i,a,o=e.x,r=e.y,l=Number.POSITIVE_INFINITY;for(i=0,a=t.length;i<a;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=s.distanceBetweenPoints(e,d);c<l&&(l=c,n=u)}}if(n){var h=n.tooltipPosition();o=h.x,r=h.y}return{x:o,y:r}}}}},{}],35:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;n.elements.arc={backgroundColor:n.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,n){var i=this._view;if(i){for(var a=e.getAngleFromPoint(i,{x:t,y:n}),o=a.angle,r=a.distance,l=i.startAngle,s=i.endAngle;s<l;)s+=2*Math.PI;for(;o>s;)o-=2*Math.PI;for(;o<l;)o+=2*Math.PI;var u=o>=l&&o<=s,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],36:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:n.defaultColor,borderWidth:3,borderColor:n.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){var t,i,a,o,r=this,l=r._view,s=r._chart.ctx,u=l.spanGaps,d=r._children.slice(),c=n.elements.line,h=-1;for(r._loop&&d.length&&d.push(d[0]),s.save(),s.lineCap=l.borderCapStyle||c.borderCapStyle,s.setLineDash&&s.setLineDash(l.borderDash||c.borderDash),s.lineDashOffset=l.borderDashOffset||c.borderDashOffset,s.lineJoin=l.borderJoinStyle||c.borderJoinStyle,s.lineWidth=l.borderWidth||c.borderWidth,s.strokeStyle=l.borderColor||n.defaultColor,s.beginPath(),h=-1,t=0;t<d.length;++t)i=d[t],a=e.previousItem(d,t),o=i._view,0===t?o.skip||(s.moveTo(o.x,o.y),h=t):(a=h===-1?a:d[h],o.skip||(h!==t-1&&!u||h===-1?s.moveTo(o.x,o.y):e.canvas.lineTo(s,a._view,i._view),h=t));s.stroke(),s.restore()}})}},{}],37:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2)}function n(t){var e=this._view;return!!e&&Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2)}var i=t.helpers,a=t.defaults.global,o=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:o,borderWidth:1,borderColor:o,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:e,inXRange:e,inYRange:n,getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(e){var n=this._view,r=this._model,l=this._chart.ctx,s=n.pointStyle,u=n.radius,d=n.x,c=n.y,h=t.helpers.color,f=1.01,g=0;n.skip||(l.strokeStyle=n.borderColor||o,l.lineWidth=i.getValueOrDefault(n.borderWidth,a.elements.point.borderWidth),l.fillStyle=n.backgroundColor||o,void 0!==e&&(r.x<e.left||e.right*f<r.x||r.y<e.top||e.bottom*f<r.y)&&(r.x<e.left?g=(d-r.x)/(e.left-r.x):e.right*f<r.x?g=(r.x-d)/(r.x-e.right):r.y<e.top?g=(c-r.y)/(e.top-r.y):e.bottom*f<r.y&&(g=(r.y-c)/(r.y-e.bottom)),g=Math.round(100*g)/100,l.strokeStyle=h(l.strokeStyle).alpha(g).rgbString(),l.fillStyle=h(l.fillStyle).alpha(g).rgbString()),t.canvasHelpers.drawPoint(l,s,u,d,c))}})}},{}],38:[function(t,e,n){"use strict";e.exports=function(t){function e(t){return void 0!==t._view.width}function n(t){var n,i,a,o,r=t._view;if(e(t)){var l=r.width/2;n=r.x-l,i=r.x+l,a=Math.min(r.y,r.base),o=Math.max(r.y,r.base)}else{var s=r.height/2;n=Math.min(r.x,r.base),i=Math.max(r.x,r.base),a=r.y-s,o=r.y+s}return{left:n,top:a,right:i,bottom:o}}var i=t.defaults.global;i.elements.rectangle={backgroundColor:i.defaultColor,borderWidth:0,borderColor:i.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return v[(x+t)%4]}var e,n,i,a,o,r,l,s=this._chart.ctx,u=this._view,d=u.borderWidth;if(u.horizontal?(e=u.base,n=u.x,i=u.y-u.height/2,a=u.y+u.height/2,o=n>e?1:-1,r=1,l=u.borderSkipped||"left"):(e=u.x-u.width/2,n=u.x+u.width/2,i=u.y,a=u.base,o=1,r=a>i?1:-1,l=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-n),Math.abs(i-a));d=d>c?c:d;var h=d/2,f=e+("left"!==l?h*o:0),g=n+("right"!==l?-h*o:0),p=i+("top"!==l?h*r:0),m=a+("bottom"!==l?-h*r:0);f!==g&&(i=p,a=m),p!==m&&(e=f,n=g)}s.beginPath(),s.fillStyle=u.backgroundColor,s.strokeStyle=u.borderColor,s.lineWidth=d;var v=[[e,a],[e,i],[n,i],[n,a]],b=["bottom","left","top","right"],x=b.indexOf(l,0);x===-1&&(x=0);var y=t(0);s.moveTo(y[0],y[1]);for(var k=1;k<4;k++)y=t(k),s.lineTo(y[0],y[1]);s.fill(),d&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var a=n(this);i=t>=a.left&&t<=a.right&&e>=a.top&&e<=a.bottom}return i},inLabelRange:function(t,i){var a=this;if(!a._view)return!1;var o=!1,r=n(a);return o=e(a)?t>=r.left&&t<=r.right:i>=r.top&&i<=r.bottom},inXRange:function(t){var e=n(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=n(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,n,i=this._view;return e(this)?(t=i.x,n=(i.y+i.base)/2):(t=(i.x+i.base)/2,n=i.y),{x:t,y:n}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],39:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=s.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}function n(t,n){var i=t.style,a=t.getAttribute("height"),o=t.getAttribute("width");if(t._chartjs={initial:{height:a,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=e(t,"width");void 0!==r&&(t.width=r)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(n.options.aspectRatio||2);else{var l=e(t,"height");void 0!==r&&(t.height=l)}return t}function i(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function a(t,e){var n=u[t.type]||t.type,a=s.getRelativePosition(t,e);return i(n,e,a.x,a.y,t)}function o(t){var e=document.createElement("iframe");return e.className="chartjs-hidden-iframe",e.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",e.tabIndex=-1,s.addEvent(e,"load",function(){s.addEvent(e.contentWindow||e,"resize",t),t()}),e}function r(t,e,n){var a=t._chartjs={ticking:!1},r=function(){a.ticking||(a.ticking=!0,s.requestAnimFrame.call(window,function(){if(a.resizer)return a.ticking=!1,e(i("resize",n))}))};a.resizer=o(r),t.insertBefore(a.resizer,t.firstChild)}function l(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}}var s=t.helpers,u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};return{acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(n(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e._chartjs){var n=e._chartjs.initial;["height","width"].forEach(function(t){var i=n[t];void 0===i||null===i?e.removeAttribute(t):e.setAttribute(t,i)}),s.each(n.style||{},function(t,n){e.style[n]=t}),e.width=e.width,delete e._chartjs}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"===e)return void r(i.parentNode,n,t);var o=n._chartjs||(n._chartjs={}),l=o.proxies||(o.proxies={}),u=l[t.id+"_"+e]=function(e){n(a(e,t))};s.addEvent(i,e,u)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"===e)return void l(i.parentNode,n);var a=n._chartjs||{},o=a.proxies||{},r=o[t.id+"_"+e];r&&s.removeEvent(i,e,r)}}}},{}],40:[function(t,e,n){"use strict";var i=t(39);e.exports=function(t){t.platform={acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},t.helpers.extend(t.platform,i(t))}},{39:39}],41:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e,n){var i,a=t._model||{},o=a.fill;if(void 0===o&&(o=!!a.backgroundColor),o===!1||null===o)return!1;if(o===!0)return"origin";if(i=parseFloat(o,10),isFinite(i)&&Math.floor(i)===i)return"-"!==o[0]&&"+"!==o[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function n(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?o=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?o=n.scaleZero:i.getBasePosition?o=i.getBasePosition():i.getBasePixel&&(o=i.getBasePixel()),void 0!==o&&null!==o){if(void 0!==o.x&&void 0!==o.y)return o;if("number"==typeof o&&isFinite(o))return e=i.isHorizontal(),{x:e?o:null,y:e?null:o}}return null}function i(t,e,n){var i,a=t[e],o=a.fill,r=[e];if(!n)return o;for(;o!==!1&&r.indexOf(o)===-1;){if(!isFinite(o))return o;if(i=t[o],!i)return!1;if(i.visible)return o;r.push(o),o=i.fill}return!1}function a(t){var e=t.fill,n="dataset";return e===!1?null:(isFinite(e)||(n="boundary"),d[n](t))}function o(t){return t&&!t.skip}function r(t,e,n,i,a){var o;if(i&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o<i;++o)u.canvas.lineTo(t,e[o-1],e[o]);for(t.lineTo(n[a-1].x,n[a-1].y),o=a-1;o>0;--o)u.canvas.lineTo(t,n[o],n[o-1],!0)}}function l(t,e,n,i,a,l){var s,u,d,c,h,f,g,p=e.length,m=i.spanGaps,v=[],b=[],x=0,y=0;for(t.beginPath(),s=0,u=p+!!l;s<u;++s)d=s%p,c=e[d]._view,h=n(c,d,i),f=o(c),g=o(h),f&&g?(x=v.push(c),y=b.push(h)):x&&y&&(m?(f&&v.push(c),g&&b.push(h)):(r(t,v,b,x,y),x=y=0,v=[],b=[]));r(t,v,b,x,y),t.closePath(),t.fillStyle=a,t.fill()}t.defaults.global.plugins.filler={propagate:!0};var s=t.defaults,u=t.helpers,d={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e),o=a&&i.dataset._children||[];return o.length?function(t,e){return o[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};return{id:"filler",afterDatasetsUpdate:function(o,r){var l,s,u,d,c=(o.data.datasets||[]).length,h=r.propagate,f=[];for(s=0;s<c;++s)l=o.getDatasetMeta(s),u=l.dataset,d=null,u&&u._model&&u instanceof t.elements.Line&&(d={visible:o.isDatasetVisible(s),fill:e(u,s,c),chart:o,el:u}),l.$filler=d,f.push(d);for(s=0;s<c;++s)d=f[s],d&&(d.fill=i(f,s,h),d.boundary=n(d),d.mapper=a(d))},beforeDatasetDraw:function(t,e){var n=e.meta.$filler;if(n){var i=n.el,a=i._view,o=i._children||[],r=n.mapper,u=a.backgroundColor||s.global.defaultColor;r&&u&&o.length&&l(t.ctx,o,r,a,u,i._loop)}}}}},{}],42:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function n(e,n){var i=new t.Legend({ctx:e.ctx,options:n,chart:e});a.configure(e,i,n),a.addBox(e,i),e.legend=i}var i=t.helpers,a=t.layoutService,o=i.noop;return t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return i.isArray(e.datasets)?e.datasets.map(function(e,n){return{text:e.label,fillStyle:i.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(n),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:n}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:o,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:function(){var t=this,e=t.options.labels,n=e.generateLabels.call(t,t.chart);e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:o,beforeFit:o,fit:function(){var n=this,a=n.options,o=a.labels,r=a.display,l=n.ctx,s=t.defaults.global,u=i.getValueOrDefault,d=u(o.fontSize,s.defaultFontSize),c=u(o.fontStyle,s.defaultFontStyle),h=u(o.fontFamily,s.defaultFontFamily),f=i.fontString(d,c,h),g=n.legendHitBoxes=[],p=n.minSize,m=n.isHorizontal();if(m?(p.width=n.maxWidth,p.height=r?10:0):(p.width=r?10:0,p.height=n.maxHeight),r)if(l.font=f,m){var v=n.lineWidths=[0],b=n.legendItems.length?d+o.padding:0;l.textAlign="left",l.textBaseline="top",i.each(n.legendItems,function(t,i){var a=e(o,d),r=a+d/2+l.measureText(t.text).width;v[v.length-1]+r+o.padding>=n.width&&(b+=d+o.padding,v[v.length]=n.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+o.padding}),p.height+=b}else{var x=o.padding,y=n.columnWidths=[],k=o.padding,w=0,M=0,S=d+x;i.each(n.legendItems,function(t,n){var i=e(o,d),a=i+d/2+l.measureText(t.text).width;M+S>p.height&&(k+=w+o.padding,y.push(w),w=0,M=0),w=Math.max(w,a),M+=S,g[n]={left:0,top:0,width:a,height:d}}),k+=w,y.push(w),p.width+=k}n.width=p.width,n.height=p.height},afterFit:o,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var n=this,a=n.options,o=a.labels,r=t.defaults.global,l=r.elements.line,s=n.width,u=n.lineWidths;if(a.display){var d,c=n.ctx,h=i.getValueOrDefault,f=h(o.fontColor,r.defaultFontColor),g=h(o.fontSize,r.defaultFontSize),p=h(o.fontStyle,r.defaultFontStyle),m=h(o.fontFamily,r.defaultFontFamily),v=i.fontString(g,p,m);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(o,g),x=n.legendHitBoxes,y=function(e,n,i){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(i.fillStyle,r.defaultColor),c.lineCap=h(i.lineCap,l.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,l.borderDashOffset),c.lineJoin=h(i.lineJoin,l.borderJoinStyle),c.lineWidth=h(i.lineWidth,l.borderWidth),c.strokeStyle=h(i.strokeStyle,r.defaultColor);var o=0===h(i.lineWidth,l.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,l.borderDash)),a.labels&&a.labels.usePointStyle){var s=g*Math.SQRT2/2,u=s/Math.SQRT2,d=e+u,f=n+u;t.canvasHelpers.drawPoint(c,i.pointStyle,s,d,f)}else o||c.strokeRect(e,n,b,g),c.fillRect(e,n,b,g);c.restore()}},k=function(t,e,n,i){c.fillText(n.text,b+g/2+t,e),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},w=n.isHorizontal();d=w?{x:n.left+(s-u[0])/2,y:n.top+o.padding,line:0}:{x:n.left+o.padding,y:n.top+o.padding,line:0};var M=g+o.padding;i.each(n.legendItems,function(t,e){var i=c.measureText(t.text).width,a=b+g/2+i,r=d.x,l=d.y;w?r+a>=s&&(l=d.y+=M,d.line++,r=d.x=n.left+(s-u[d.line])/2):l+M>n.bottom&&(r=d.x=r+n.columnWidths[d.line]+o.padding,l=d.y=n.top+o.padding,d.line++),y(r,l,t),x[e].left=r,x[e].top=l,k(r,l,t,i),w?d.x+=a+o.padding:d.y+=M})}},handleEvent:function(t){var e=this,n=e.options,i="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===i){if(!n.onHover)return}else{if("click"!==i)return;if(!n.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var l=e.legendHitBoxes,s=0;s<l.length;++s){var u=l[s];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===i){n.onClick.call(e,t.native,e.legendItems[s]),a=!0;break}if("mousemove"===i){n.onHover.call(e,t.native,e.legendItems[s]),a=!0;break}}}return a}}),{id:"legend",beforeInit:function(t){var e=t.options.legend;e&&n(t,e)},beforeUpdate:function(e){var o=e.options.legend,r=e.legend;o?(o=i.configMerge(t.defaults.global.legend,o),r?(a.configure(e,r,o),r.options=o):n(e,o)):r&&(a.removeBox(e,r),delete e.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}}},{}],43:[function(t,e,n){"use strict";e.exports=function(t){function e(e,n){var a=new t.Title({ctx:e.ctx,options:n,chart:e});i.configure(e,a,n),i.addBox(e,a),e.titleBlock=a}var n=t.helpers,i=t.layoutService,a=n.noop;return t.defaults.global.title={display:!1,position:"top",fullWidth:!0,weight:2e3,fontStyle:"bold",padding:10,text:""},t.Title=t.Element.extend({initialize:function(t){var e=this;n.extend(e,t),e.legendHitBoxes=[];
+},beforeUpdate:a,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:a,beforeSetDimensions:a,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:a,beforeBuildLabels:a,buildLabels:a,afterBuildLabels:a,beforeFit:a,fit:function(){var e=this,i=n.getValueOrDefault,a=e.options,o=t.defaults.global,r=a.display,l=i(a.fontSize,o.defaultFontSize),s=e.minSize;e.isHorizontal()?(s.width=e.maxWidth,s.height=r?l+2*a.padding:0):(s.width=r?l+2*a.padding:0,s.height=e.maxHeight),e.width=s.width,e.height=s.height},afterFit:a,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var e=this,i=e.ctx,a=n.getValueOrDefault,o=e.options,r=t.defaults.global;if(o.display){var l,s,u,d=a(o.fontSize,r.defaultFontSize),c=a(o.fontStyle,r.defaultFontStyle),h=a(o.fontFamily,r.defaultFontFamily),f=n.fontString(d,c,h),g=0,p=e.top,m=e.left,v=e.bottom,b=e.right;i.fillStyle=a(o.fontColor,r.defaultFontColor),i.font=f,e.isHorizontal()?(l=m+(b-m)/2,s=p+(v-p)/2,u=b-m):(l="left"===o.position?m+d/2:b-d/2,s=p+(v-p)/2,u=v-p,g=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(l,s),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0,u),i.restore()}}}),{id:"title",beforeInit:function(t){var n=t.options.title;n&&e(t,n)},beforeUpdate:function(a){var o=a.options.title,r=a.titleBlock;o?(o=n.configMerge(t.defaults.global.title,o),r?(i.configure(a,r,o),r.options=o):e(a,o)):r&&(t.layoutService.removeBox(a,r),delete a.titleBlock)}}}},{}],44:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,n=t.getLabels();t.minIndex=0,t.maxIndex=n.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(n,t.options.ticks.min),t.minIndex=i!==-1?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(n,t.options.ticks.max),t.maxIndex=i!==-1?i:t.maxIndex),t.min=n[t.minIndex],t.max=n[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e,n,i){var a,o=this,r=Math.max(o.maxIndex+1-o.minIndex-(o.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&null!==t&&(a=o.isHorizontal()?t.x:t.y),void 0!==a||void 0!==t&&isNaN(e)){var l=o.getLabels();t=a||t;var s=l.indexOf(t);e=s!==-1?s:e}if(o.isHorizontal()){var u=o.width/r,d=u*(e-o.minIndex);return(o.options.gridLines.offsetGridLines&&i||o.maxIndex===o.minIndex&&i)&&(d+=u/2),o.left+Math.round(d)}var c=o.height/r,h=c*(e-o.minIndex);return o.options.gridLines.offsetGridLines&&i&&(h+=c/2),o.top+Math.round(h)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,n=this,i=Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),a=n.isHorizontal(),o=(a?n.width:n.height)/i;return t-=a?n.left:n.top,n.options.gridLines.offsetGridLines&&(t-=o/2),e=t<=0?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,n)}},{}],45:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=n.chart,o=a.data,r=o.datasets,l=n.isHorizontal(),s=0,u=1;n.min=null,n.max=null;var d=i.stacked;if(void 0===d&&e.each(r,function(e,n){if(!d){var i=a.getDatasetMeta(n);a.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(r,function(o,r){var l=a.getDatasetMeta(r),s=[l.type,void 0===i.stacked&&void 0===l.stack?r:"",l.stack].join(".");void 0===c[s]&&(c[s]={positiveValues:[],negativeValues:[]});var u=c[s].positiveValues,d=c[s].negativeValues;a.isDatasetVisible(r)&&t(l)&&e.each(o.data,function(t,e){var a=+n.getRightValue(t);isNaN(a)||l.data[e].hidden||(u[e]=u[e]||0,d[e]=d[e]||0,i.relativePoints?u[e]=100:a<0?d[e]+=a:u[e]+=a)})}),e.each(c,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),o=e.max(i);n.min=null===n.min?a:Math.min(n.min,a),n.max=null===n.max?o:Math.max(n.max,o)})}else e.each(r,function(i,o){var r=a.getDatasetMeta(o);a.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i))})});n.min=isFinite(n.min)?n.min:s,n.max=isFinite(n.max)?n.max:u,this.handleTickRangeOptions()},getTickLimit:function(){var n,i=this,a=i.options.ticks;if(i.isHorizontal())n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(a.fontSize,t.defaults.global.defaultFontSize);n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return n},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,n=this,i=n.start,a=+n.getRightValue(t),o=n.end-i;return n.isHorizontal()?(e=n.left+n.width/o*(a-i),Math.round(e)):(e=n.bottom-n.height/o*(a-i),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=n?e.width:e.height,a=(n?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,n)}},{}],46:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,n=t.options,i=n.ticks;if(i.beginAtZero){var a=e.sign(t.min),o=e.sign(t.max);a<0&&o<0?t.max=0:a>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(null===t.min?t.min=i.suggestedMin:t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(null===t.max?t.max=i.suggestedMax:t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:n,handleDirectionalChanges:n,buildTicks:function(){var n=this,i=n.options,a=i.ticks,o=n.getTickLimit();o=Math.max(2,o);var r={maxTicks:o,min:a.min,max:a.max,stepSize:e.getValueOrDefault(a.fixedStepSize,a.stepSize)},l=n.ticks=t.Ticks.generators.linear(r,n);n.handleDirectionalChanges(),n.max=e.max(l),n.min=e.min(l),a.reverse?(l.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],47:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=i.ticks,o=n.chart,r=o.data,l=r.datasets,s=e.getValueOrDefault,u=n.isHorizontal();n.min=null,n.max=null,n.minNotZero=null;var d=i.stacked;if(void 0===d&&e.each(l,function(e,n){if(!d){var i=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(l,function(a,r){var l=o.getDatasetMeta(r),s=[l.type,void 0===i.stacked&&void 0===l.stack?r:"",l.stack].join(".");o.isDatasetVisible(r)&&t(l)&&(void 0===c[s]&&(c[s]=[]),e.each(a.data,function(t,e){var a=c[s],o=+n.getRightValue(t);isNaN(o)||l.data[e].hidden||(a[e]=a[e]||0,i.relativePoints?a[e]=100:a[e]+=o)}))}),e.each(c,function(t){var i=e.min(t),a=e.max(t);n.min=null===n.min?i:Math.min(n.min,i),n.max=null===n.max?a:Math.max(n.max,a)})}else e.each(l,function(i,a){var r=o.getDatasetMeta(a);o.isDatasetVisible(a)&&t(r)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i),0!==i&&(null===n.minNotZero||i<n.minNotZero)&&(n.minNotZero=i))})});n.min=s(a.min,n.min),n.max=s(a.max,n.max),n.min===n.max&&(0!==n.min&&null!==n.min?(n.min=Math.pow(10,Math.floor(e.log10(n.min))-1),n.max=Math.pow(10,Math.floor(e.log10(n.max))+1)):(n.min=1,n.max=10))},buildTicks:function(){var n=this,i=n.options,a=i.ticks,o={min:a.min,max:a.max},r=n.ticks=t.Ticks.generators.logarithmic(o,n);n.isHorizontal()||r.reverse(),n.max=e.max(r),n.min=e.min(r),a.reverse?(r.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var n,i,a,o=this,r=o.start,l=+o.getRightValue(t),s=o.options,u=s.ticks;return o.isHorizontal()?(a=e.log10(o.end)-e.log10(r),0===l?i=o.left:(n=o.width,i=o.left+n/a*(e.log10(l)-e.log10(r)))):(n=o.height,0!==r||u.reverse?0===o.end&&u.reverse?(a=e.log10(o.start)-e.log10(o.minNotZero),i=l===o.end?o.top:l===o.minNotZero?o.top+.02*n:o.top+.02*n+.98*n/a*(e.log10(l)-e.log10(o.minNotZero))):0===l?i=u.reverse?o.top:o.bottom:(a=e.log10(o.end)-e.log10(r),n=o.height,i=o.bottom-n/a*(e.log10(l)-e.log10(r))):(a=e.log10(o.end)-e.log10(o.minNotZero),i=l===r?o.bottom:l===o.minNotZero?o.bottom-.02*n:o.bottom-.02*n-.98*n/a*(e.log10(l)-e.log10(o.minNotZero)))),i},getValueForPixel:function(t){var n,i,a=this,o=e.log10(a.end)-e.log10(a.start);return a.isHorizontal()?(i=a.width,n=a.start*Math.pow(10,(t-a.left)*o/i)):(i=a.height,n=Math.pow(10,(a.bottom-t)*o/i)/a.start),n}});t.scaleService.registerScaleType("logarithmic",i,n)}},{}],48:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function n(t){var e=t.options.pointLabels,n=f.getValueOrDefault(e.fontSize,g.defaultFontSize),i=f.getValueOrDefault(e.fontStyle,g.defaultFontStyle),a=f.getValueOrDefault(e.fontFamily,g.defaultFontFamily),o=f.fontString(n,i,a);return{size:n,style:i,family:a,font:o}}function i(t,e,n){return f.isArray(n)?{w:f.longestText(t,t.font,n),h:n.length*e+1.5*(n.length-1)*e}:{w:t.measureText(n).width,h:e}}function a(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n-5,end:e}:{start:e,end:e+n+5}}function o(t){var o,r,l,s=n(t),u=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},c={};t.ctx.font=s.font,t._pointLabelSizes=[];var h=e(t);for(o=0;o<h;o++){l=t.getPointPosition(o,u),r=i(t.ctx,s.size,t.pointLabels[o]||""),t._pointLabelSizes[o]=r;var g=t.getIndexAngle(o),p=f.toDegrees(g)%360,m=a(p,l.x,r.w,0,180),v=a(p,l.y,r.h,90,270);m.start<d.l&&(d.l=m.start,c.l=g),m.end>d.r&&(d.r=m.end,c.r=g),v.start<d.t&&(d.t=v.start,c.t=g),v.end>d.b&&(d.b=v.end,c.b=g)}t.setReductions(u,d,c)}function r(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function l(t){return 0===t||180===t?"center":t<180?"left":"right"}function s(t,e,n,i){if(f.isArray(e))for(var a=n.y,o=1.5*i,r=0;r<e.length;++r)t.fillText(e[r],n.x,a),a+=o;else t.fillText(e,n.x,n.y)}function u(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function d(t){var i=t.ctx,a=f.getValueOrDefault,o=t.options,r=o.angleLines,d=o.pointLabels;i.lineWidth=r.lineWidth,i.strokeStyle=r.color;var c=t.getDistanceFromCenterForValue(o.reverse?t.min:t.max),h=n(t);i.textBaseline="top";for(var p=e(t)-1;p>=0;p--){if(r.display){var m=t.getPointPosition(p,c);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}if(d.display){var v=t.getPointPosition(p,c+5),b=a(d.fontColor,g.defaultFontColor);i.font=h.font,i.fillStyle=b;var x=t.getIndexAngle(p),y=f.toDegrees(x);i.textAlign=l(y),u(y,t._pointLabelSizes[p],v),s(i,t.pointLabels[p]||"",v,h.size)}}}function c(t,n,i,a){var o=t.ctx;if(o.strokeStyle=f.getValueAtIndexOrDefault(n.color,a-1),o.lineWidth=f.getValueAtIndexOrDefault(n.lineWidth,a-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var r=e(t);if(0===r)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var s=1;s<r;s++)l=t.getPointPosition(s,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}function h(t){return f.isNumber(t)?t:0}var f=t.helpers,g=t.defaults.global,p={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:t.Ticks.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}},m=t.LinearScaleBase.extend({setDimensions:function(){var t=this,e=t.options,n=e.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=f.min([t.height,t.width]),a=f.getValueOrDefault(n.fontSize,g.defaultFontSize);t.drawingArea=e.display?i/2-(a/2+n.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;f.each(e.data.datasets,function(a,o){if(e.isDatasetVisible(o)){var r=e.getDatasetMeta(o);f.each(a.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||r.data[a].hidden||(n=Math.min(o,n),i=Math.max(o,i))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,e=f.getValueOrDefault(t.fontSize,g.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*e)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){this.options.pointLabels.display?o(this):r(this)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),o=Math.max(e.r-i.width,0)/Math.sin(n.r),r=-e.t/Math.cos(n.t),l=-Math.max(e.b-i.height,0)/Math.cos(n.b);a=h(a),o=h(o),r=h(r),l=h(l),i.drawingArea=Math.min(Math.round(t-(a+o)/2),Math.round(t-(r+l)/2)),i.setCenterPoint(a,o,r,l)},setCenterPoint:function(t,e,n,i){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,l=n+a.drawingArea,s=a.height-i-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((l+s)/2+a.top)},getIndexAngle:function(t){var n=2*Math.PI/e(this),i=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,a=i*Math.PI*2/360;return t*n+a},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},draw:function(){var t=this,e=t.options,n=e.gridLines,i=e.ticks,a=f.getValueOrDefault;if(e.display){var o=t.ctx,r=a(i.fontSize,g.defaultFontSize),l=a(i.fontStyle,g.defaultFontStyle),s=a(i.fontFamily,g.defaultFontFamily),u=f.fontString(r,l,s);f.each(t.ticks,function(l,s){if(s>0||e.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]),h=t.yCenter-d;if(n.display&&0!==s&&c(t,n,d,s),i.display){var f=a(i.fontColor,g.defaultFontColor);if(o.font=u,i.showLabelBackdrop){var p=o.measureText(l).width;o.fillStyle=i.backdropColor,o.fillRect(t.xCenter-p/2-i.backdropPaddingX,h-r/2-i.backdropPaddingY,p+2*i.backdropPaddingX,r+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=f,o.fillText(l,t.xCenter,h)}}}),(e.angleLines.display||e.pointLabels.display)&&d(t)}}});t.scaleService.registerScaleType("radialLinear",m,p)}},{}],49:[function(t,e,n){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){function e(t,e){var n=t.options.time;if("string"==typeof n.parser)return i(e,n.parser);if("function"==typeof n.parser)return n.parser(e);if("function"==typeof e.getMonth||"number"==typeof e)return i(e);if(e.isValid&&e.isValid())return e;var a=n.format;return"string"!=typeof a&&a.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser."),a(e)):i(e,a)}function n(t,e,n,i){for(var a,o=Object.keys(l),r=o.length,s=o.indexOf(t);s<r;s++){a=o[s];var u=l[a],d=u.steps&&u.steps[u.steps.length-1]||u.maxStep;if(void 0===d||Math.ceil((n-e)/(d*u.size))<=i)break}return a}function a(t,e,n,i){var a=l[n],o=a.size,r=Math.ceil((e-t)/o),s=1,u=e-t;if(a.steps)for(var d=a.steps.length,c=0;c<d&&r>i;c++)s=a.steps[c],r=Math.ceil(u/(o*s));else for(;r>i&&i>0;)++s,r=Math.ceil(u/(o*s));return s}function o(t,e,n){var a=[];if(t.maxTicks){var o=t.stepSize;a.push(void 0!==t.min?t.min:n.min);for(var r=i(n.min);r.add(o,t.unit).valueOf()<n.max;)a.push(r.valueOf());var l=t.max||n.max;a[a.length-1]!==l&&a.push(l)}return a}var r=t.helpers,l={millisecond:{size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{size:1e3,steps:[1,2,5,10,30]},minute:{size:6e4,steps:[1,2,5,10,30]},hour:{size:36e5,steps:[1,2,3,6,12]},day:{size:864e5,steps:[1,2,5]},week:{size:6048e5,maxStep:4},month:{size:2628e6,maxStep:3},quarter:{size:7884e6,maxStep:4},year:{size:3154e7,maxStep:!1}},s={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}};t.Ticks.generators.time=function(t,e){var n,a,r=t.isoWeekday;return"week"===t.unit&&r!==!1?(n=i(e.min).startOf("isoWeek").isoWeekday(r).valueOf(),a=i(e.max).startOf("isoWeek").isoWeekday(r),e.max-a>0&&a.add(1,"week"),a=a.valueOf()):(n=i(e.min).startOf(t.unit).valueOf(),a=i(e.max).startOf(t.unit),e.max-a>0&&a.add(1,t.unit),a=a.valueOf()),o(t,e,{min:n,max:a})};var u=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},determineDataLimits:function(){var t,n=this,i=n.options.time,a=Number.MAX_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,l=n.chart.data,s={labels:[],datasets:[]};r.each(l.labels,function(r,l){var u=e(n,r);u.isValid()&&(i.round&&u.startOf(i.round),t=u.valueOf(),a=Math.min(t,a),o=Math.max(t,o),s.labels[l]=t)}),r.each(l.datasets,function(l,u){var d=[];"object"==typeof l.data[0]&&null!==l.data[0]&&n.chart.isDatasetVisible(u)?r.each(l.data,function(r,l){var s=e(n,n.getRightValue(r));s.isValid()&&(i.round&&s.startOf(i.round),t=s.valueOf(),a=Math.min(t,a),o=Math.max(t,o),d[l]=t)}):d=s.labels.slice(),s.datasets[u]=d}),n.dataMin=a,n.dataMax=o,n._parsedData=s},buildTicks:function(){var i,o,l=this,s=l.options.time,u=l.dataMin,d=l.dataMax;if(s.min){var c=e(l,s.min);s.round&&c.round(s.round),i=c.valueOf()}s.max&&(o=e(l,s.max).valueOf());var h=l.getLabelCapacity(i||u),f=s.unit||n(s.minUnit,i||u,o||d,h);l.displayFormat=s.displayFormats[f];var g=s.stepSize||a(i||u,o||d,f,h);l.ticks=t.Ticks.generators.time({maxTicks:h,min:i,max:o,stepSize:g,unit:f,isoWeekday:s.isoWeekday},{min:u,max:d}),l.max=r.max(l.ticks),l.min=r.min(l.ticks)},getLabelForIndex:function(t,n){var i=this,a=i.chart.data.labels&&t<i.chart.data.labels.length?i.chart.data.labels[t]:"",o=i.chart.data.datasets[n].data[t];return null!==o&&"object"==typeof o&&(a=i.getRightValue(o)),i.options.time.tooltipFormat&&(a=e(i,a).format(i.options.time.tooltipFormat)),a},tickFormatFunction:function(t,e,n){var i=t.format(this.displayFormat),a=this.options.ticks,o=r.getValueOrDefault(a.callback,a.userCallback);return o?o(i,e,n):i},convertTicksToLabels:function(){var t=this;t.ticksAsTimestamps=t.ticks,t.ticks=t.ticks.map(function(t){return i(t)}).map(t.tickFormatFunction,t)},getPixelForOffset:function(t){var e=this,n=e.max-e.min,i=n?(t-e.min)/n:0;if(e.isHorizontal()){var a=e.width*i;return e.left+Math.round(a)}var o=e.height*i;return e.top+Math.round(o)},getPixelForValue:function(t,n,i){var a=this,o=null;if(void 0!==n&&void 0!==i&&(o=a._parsedData.datasets[i][n]),null===o&&(t&&t.isValid||(t=e(a,a.getRightValue(t))),t&&t.isValid&&t.isValid()&&(o=t.valueOf())),null!==o)return a.getPixelForOffset(o)},getPixelForTick:function(t){return this.getPixelForOffset(this.ticksAsTimestamps[t])},getValueForPixel:function(t){var e=this,n=e.isHorizontal()?e.width:e.height,a=(t-(e.isHorizontal()?e.left:e.top))/n;return i(e.min+a*(e.max-e.min))},getLabelWidth:function(e){var n=this,i=n.options.ticks,a=n.ctx.measureText(e).width,o=Math.cos(r.toRadians(i.maxRotation)),l=Math.sin(r.toRadians(i.maxRotation)),s=r.getValueOrDefault(i.fontSize,t.defaults.global.defaultFontSize);return a*o+s*l},getLabelCapacity:function(t){var e=this;e.displayFormat=e.options.time.displayFormats.millisecond;var n=e.tickFormatFunction(i(t),0,[]),a=e.getLabelWidth(n),o=e.isHorizontal()?e.width:e.height,r=o/a;return r}});t.scaleService.registerScaleType("time",u,s)}},{1:1}]},{},[7])(7)});
\ No newline at end of file
