/*!
 * Chart.js
 * http://chartjs.org/
 * Version: 2.6.0
 *
 * 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;
    }

},{"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.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 */

    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,

        hsv2rgb: hsv2rgb,
        hsv2hsl: hsv2hsl,
        hsv2hwb: hsv2hwb,
        hsv2cmyk: hsv2cmyk,
        hsv2keyword: hsv2keyword,

        hwb2rgb: hwb2rgb,
        hwb2hsl: hwb2hsl,
        hwb2hsv: hwb2hsv,
        hwb2cmyk: hwb2cmyk,
        hwb2keyword: hwb2keyword,

        cmyk2rgb: cmyk2rgb,
        cmyk2hsl: cmyk2hsl,
        cmyk2hsv: cmyk2hsv,
        cmyk2hwb: cmyk2hwb,
        cmyk2keyword: cmyk2keyword,

        keyword2rgb: keyword2rgb,
        keyword2hsl: keyword2hsl,
        keyword2hsv: keyword2hsv,
        keyword2hwb: keyword2hwb,
        keyword2cmyk: keyword2cmyk,
        keyword2lab: keyword2lab,
        keyword2xyz: keyword2xyz,

        xyz2rgb: xyz2rgb,
        xyz2lab: xyz2lab,
        xyz2lch: xyz2lch,

        lab2xyz: lab2xyz,
        lab2rgb: lab2rgb,
        lab2lch: lab2lch,

        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;

        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);

        if (h < 0)
            h += 360;

        l = (min + max) / 2;

        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];
    }

    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 == 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);

        if (h < 0)
            h += 360;

        v = ((max / 255) * 1000) / 10;

        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));

        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;

        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 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);

        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];
    }

    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 = 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);

        return [l, a, b];
    }

    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;

        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;

        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;

            rgb[i] = val * 255;
        }

        return rgb;
    }

    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];
        }

        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 hsl2cmyk(args) {
        return rgb2cmyk(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;

        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];
        }
    }

    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];
    }

    function hsv2hwb(args) {
        return rgb2hwb(hsv2rgb(args))
    }

    function hsv2cmyk(args) {
        return rgb2cmyk(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;

        // 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

        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];
    }

    function hwb2hsl(args) {
        return rgb2hsl(hwb2rgb(args));
    }

    function hwb2hsv(args) {
        return rgb2hsv(hwb2rgb(args));
    }

    function hwb2cmyk(args) {
        return rgb2cmyk(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;

        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 cmyk2hsv(args) {
        return rgb2hsv(cmyk2rgb(args));
    }

    function cmyk2hwb(args) {
        return rgb2hwb(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;

        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);

        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);

        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];
    }

    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 = 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);

        return [l, a, b];
    }

    function xyz2lch(args) {
        return lab2lch(xyz2lab(args));
    }

    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);
        }

        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);

        return [x, y, z];
    }

    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];
    }

    function lab2rgb(args) {
        return xyz2rgb(lab2xyz(args));
    }

    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];
    }

    function lch2xyz(args) {
        return lab2xyz(lch2lab(args));
    }

    function lch2rgb(args) {
        return lab2rgb(lch2lab(args));
    }

    function keyword2rgb(keyword) {
        return cssKeywords[keyword];
    }

    function keyword2hsl(args) {
        return rgb2hsl(keyword2rgb(args));
    }

    function keyword2hsv(args) {
        return rgb2hsv(keyword2rgb(args));
    }

    function keyword2hwb(args) {
        return rgb2hwb(keyword2rgb(args));
    }

    function keyword2cmyk(args) {
        return rgb2cmyk(keyword2rgb(args));
    }

    function keyword2lab(args) {
        return rgb2lab(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 reverseKeywords = {};
    for (var key in cssKeywords) {
        reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
    }

},{}],5:[function(require,module,exports){
    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);
            }
        })(func);

        var pair = /(\w+)2(\w+)/.exec(func),
            from = pair[1],
            to = pair[2];

        // export rgb2hsl and ["rgb"]["hsl"]
        convert[from] = convert[from] || {};

        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);
    }


    /* 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);
        }

        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;
    };

    /* 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);

            this.convs[space] = vals;
        }
        return vals;
    };

    ["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]
    };
},{}],7:[function(require,module,exports){
    /**
     * @namespace Chart
     */
    var Chart = require(28)();

    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(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(8)(Chart);
    require(9)(Chart);
    require(10)(Chart);
    require(11)(Chart);
    require(12)(Chart);
    require(13)(Chart);
    require(14)(Chart);

// Loading built-it plugins
    var plugins = [];

    plugins.push(
        require(41)(Chart),
        require(42)(Chart),
        require(43)(Chart)
    );

    Chart.plugins.register(plugins);

    module.exports = Chart;
    if (typeof window !== 'undefined') {
        window.Chart = Chart;
    }

},{"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';

    module.exports = function(Chart) {

        Chart.Bubble = function(context, config) {
            config.type = 'bubble';
            return new Chart(context, config);
        };

    };

},{}],10:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        Chart.Doughnut = function(context, config) {
            config.type = 'doughnut';

            return new Chart(context, config);
        };

    };

},{}],11:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        Chart.Line = function(context, config) {
            config.type = 'line';

            return new Chart(context, config);
        };

    };

},{}],12:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        Chart.PolarArea = function(context, config) {
            config.type = 'polarArea';

            return new Chart(context, config);
        };

    };

},{}],13:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        Chart.Radar = function(context, config) {
            config.type = 'radar';

            return new Chart(context, config);
        };

    };

},{}],14:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        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'
                }]
            },

            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;

        // Scatter charts use line controllers
        Chart.controllers.scatter = Chart.controllers.line;

        Chart.Scatter = function(context, config) {
            config.type = 'scatter';
            return new Chart(context, config);
        };

    };

},{}],15:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.bar = {
            hover: {
                mode: 'label'
            },

            scales: {
                xAxes: [{
                    type: 'category',

                    // Specific to Bar Controller
                    categoryPercentage: 0.8,
                    barPercentage: 0.9,

                    // grid line settings
                    gridLines: {
                        offsetGridLines: true
                    }
                }],
                yAxes: [{
                    type: 'linear'
                }]
            }
        };

        Chart.controllers.bar = Chart.DatasetController.extend({

            dataElementType: Chart.elements.Rectangle,

            initialize: function() {
                var me = this;
                var meta;

                Chart.DatasetController.prototype.initialize.apply(me, arguments);

                meta = me.getMeta();
                meta.stack = me.getDataset().stack;
                meta.bar = true;
            },

            update: function(reset) {
                var me = this;
                var elements = me.getMeta().data;
                var i, ilen;

                me._ruler = me.getRuler();

                for (i = 0, ilen = elements.length; i < ilen; ++i) {
                    me.updateElement(elements[i], i, reset);
                }
            },

            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;

                rectangle._xScale = me.getScaleForId(meta.xAxisID);
                rectangle._yScale = me.getScaleForId(meta.yAxisID);
                rectangle._datasetIndex = me.index;
                rectangle._index = index;

                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)
                };

                me.updateElementGeometry(rectangle, index, reset);

                rectangle.pivot();
            },

            /**
             * @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);

                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;
            },

            /**
             * @private
             */
            getValueScaleId: function() {
                return this.getMeta().yAxisID;
            },

            /**
             * @private
             */
            getIndexScaleId: function() {
                return this.getMeta().xAxisID;
            },

            /**
             * @private
             */
            getValueScale: function() {
                return this.getScaleForId(this.getValueScaleId());
            },

            /**
             * @private
             */
            getIndexScale: function() {
                return this.getScaleForId(this.getIndexScaleId());
            },

            /**
             * 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;

                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 stacks.length;
            },

            /**
             * Returns the stack index for the given dataset based on groups and bar visibility.
             * @private
             */
            getStackIndex: function(datasetIndex) {
                return this.getStackCount(datasetIndex) - 1;
            },

            /**
             * @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;

                barSize = Math.min(
                    helpers.getValueOrDefault(options.barThickness, barSize),
                    helpers.getValueOrDefault(options.maxBarThickness, Infinity));

                return {
                    stackCount: stackCount,
                    tickSize: tickSize,
                    categorySize: categorySize,
                    categorySpacing: tickSize - categorySize,
                    fullBarSize: fullBarSize,
                    barSize: barSize,
                    barSpacing: fullBarSize - barSize,
                    scale: scale
                };
            },

            /**
             * 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;

                if (stacked || (stacked === undefined && stack !== undefined)) {
                    for (i = 0; i < datasetIndex; ++i) {
                        imeta = chart.getDatasetMeta(i);

                        if (imeta.bar &&
                            imeta.stack === stack &&
                            imeta.controller.getValueScaleId() === scale.id &&
                            chart.isDatasetVisible(i)) {

                            ivalue = Number(datasets[i].data[index]);
                            if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
                                start += ivalue;
                            }
                        }
                    }
                }

                base = scale.getPixelForValue(start);
                head = scale.getPixelForValue(start + value);
                size = (head - base) / 2;

                return {
                    size: size,
                    base: base,
                    head: head,
                    center: head + size / 2
                };
            },

            /**
             * @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;

                base -= isCombo? ruler.tickSize / 2 : 0;
                base += ruler.fullBarSize * stackIndex;
                base += ruler.categorySpacing / 2;
                base += ruler.barSpacing / 2;

                return {
                    size: size,
                    base: base,
                    head: base + size,
                    center: base + size / 2
                };
            },

            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;

                helpers.canvas.clipArea(chart.ctx, chart.chartArea);

                for (; i<ilen; ++i) {
                    d = dataset.data[i];
                    if (d !== null && d !== undefined && !isNaN(d)) {
                        elements[i].draw();
                    }
                }

                helpers.canvas.unclipArea(chart.ctx);
            },

            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({
            /**
             * @private
             */
            getValueScaleId: function() {
                return this.getMeta().xAxisID;
            },

            /**
             * @private
             */
            getIndexScaleId: function() {
                return this.getMeta().yAxisID;
            }
        });
    };

},{}],16:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        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'
                }]
            },

            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({

            dataElementType: Chart.elements.Point,

            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);
                });
            },

            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;

                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),

                        // 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);

                var model = point._model;
                model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));

                point.pivot();
            },

            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);

                // 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);

                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);
            }
        });
    };

},{}],17:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        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">');

                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>');
                    }
                }

                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,

                                    // 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;

                    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();
                }
            },

            // 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 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) {
                        var dataLabel = data.labels[tooltipItem.index];
                        var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];

                        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;
                        }

                        return dataLabel;
                    }
                }
            }
        };

        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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.line = {
            showLines: true,
            spanGaps: false,

            hover: {
                mode: 'label'
            },

            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);
        }

        Chart.controllers.line = Chart.DatasetController.extend({

            datasetElementType: Chart.elements.Line,

            dataElementType: Chart.elements.Point,

            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);

                // Update Line
                if (showLine) {
                    custom = line.custom || {};

                    // 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;
                    }

                    // 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),
                    };

                    line.pivot();
                }

                // Update Points
                for (i=0, ilen=points.length; i<ilen; ++i) {
                    me.updateElement(points[i], i, reset);
                }

                if (showLine && line._model.tension !== 0) {
                    me.updateBezierControlPoints();
                }

                // Now pivot the point for animation
                for (i=0, ilen=points.length; i<ilen; ++i) {
                    points[i].pivot();
                }
            },

            getPointBackgroundColor: function(point, index) {
                var backgroundColor = this.chart.options.elements.point.backgroundColor;
                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;
                }

                return backgroundColor;
            },

            getPointBorderColor: function(point, index) {
                var borderColor = this.chart.options.elements.point.borderColor;
                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;
                }

                return borderColor;
            },

            getPointBorderWidth: function(point, index) {
                var borderWidth = this.chart.options.elements.point.borderWidth;
                var dataset = this.getDataset();
                var custom = point.custom || {};

                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 borderWidth;
            },

            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;

                // 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;
                }

                x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);
                y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);

                // Utility
                point._xScale = xScale;
                point._yScale = yScale;
                point._datasetIndex = datasetIndex;
                point._index = index;

                // 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)
                };
            },

            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;

                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;
                            }
                        }
                    }

                    var rightValue = Number(yScale.getRightValue(value));
                    if (rightValue < 0) {
                        return yScale.getPixelForValue(sumNeg + rightValue);
                    }
                    return yScale.getPixelForValue(sumPos + rightValue);
                }

                return yScale.getPixelForValue(value);
            },

            updateBezierControlPoints: function() {
                var me = this;
                var meta = me.getMeta();
                var area = me.chart.chartArea;
                var points = (meta.data || []);
                var i, ilen, point, model, controlPoints;

                // 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;
                    });
                }

                function capControlPoint(pt, min, max) {
                    return Math.max(Math.min(pt, max), min);
                }

                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;
                    }
                }

                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);
                    }
                }
            },

            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;

                Chart.canvasHelpers.clipArea(chart.ctx, area);

                if (lineEnabled(me.getDataset(), chart.options)) {
                    meta.dataset.draw();
                }

                Chart.canvasHelpers.unclipArea(chart.ctx);

                // Draw the points
                for (; i<ilen; ++i) {
                    points[i].draw(area);
                }
            },

            setHoverStyle: function(point) {
                // Point
                var dataset = this.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);
            },

            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);
            }
        });
    };

},{}],19:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.polarArea = {

            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
            },

            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;

                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);

                                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
                                };
                            });
                        }
                        return [];
                    }
                },

                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;
                    }

                    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;
                    }
                }
            }
        };

        Chart.controllers.polarArea = Chart.DatasetController.extend({

            dataElementType: Chart.elements.Arc,

            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();

                me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
                me.innerRadius = me.outerRadius - chart.radiusLength;

                meta.count = me.countVisibleElements();

                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;

                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;
                    }
                }

                // 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]);

                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])
                    }
                });

                // Apply border and fill style
                me.removeHoverStyle(arc);

                arc.pivot();
            },

            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;

                helpers.each(meta.data, function(element, index) {
                    if (!isNaN(dataset.data[index]) && !element.hidden) {
                        count++;
                    }
                });

                return count;
            },

            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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.radar = {
            aspectRatio: 1,
            scale: {
                type: 'radialLinear'
            },
            elements: {
                line: {
                    tension: 0 // no bezier in radar
                }
            }
        };

        Chart.controllers.radar = Chart.DatasetController.extend({

            datasetElementType: Chart.elements.Line,

            dataElementType: Chart.elements.Point,

            linkScales: helpers.noop,

            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;

                // 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;
                }

                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),
                    }
                });

                meta.dataset.pivot();

                // Update Points
                helpers.each(points, function(point, index) {
                    me.updateElement(point, index, reset);
                }, me);

                // 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]);

                // 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;
                }

                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,

                        // 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),

                        // Tooltip
                        hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
                    }
                });

                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();

                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
                    );

                    // 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);

                    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);

                    // Now pivot the point for animation
                    point.pivot();
                });
            },

            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.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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.global.animation = {
            duration: 1000,
            easing: 'easeOutQuart',
            onProgress: helpers.noop,
            onComplete: helpers.noop
        };

        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
        });

        Chart.animationService = {
            frameDuration: 17,
            animations: [],
            dropFrames: 0,
            request: null,

            /**
             * @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;

                animation.chart = chart;

                if (!lazy) {
                    chart.animating = true;
                }

                for (i=0, ilen=animations.length; i < ilen; ++i) {
                    if (animations[i].chart === chart) {
                        animations[i] = animation;
                        return;
                    }
                }

                animations.push(animation);

                // If there are no animations queued, manually kickstart a digest, for lack of a better word
                if (animations.length === 1) {
                    this.requestAnimationFrame();
                }
            },

            cancelAnimation: function(chart) {
                var index = helpers.findIndex(this.animations, function(animation) {
                    return animation.chart === chart;
                });

                if (index !== -1) {
                    this.animations.splice(index, 1);
                    chart.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();
                    });
                }
            },

            /**
             * @private
             */
            startDigest: function() {
                var me = this;
                var startTime = Date.now();
                var framesToDrop = 0;

                if (me.dropFrames > 1) {
                    framesToDrop = Math.floor(me.dropFrames);
                    me.dropFrames = me.dropFrames % 1;
                }

                me.advance(1 + framesToDrop);

                var endTime = Date.now();

                me.dropFrames += (endTime - startTime) / me.frameDuration;

                // Do we have more stuff to animate?
                if (me.animations.length > 0) {
                    me.requestAnimationFrame();
                }
            },

            /**
             * @private
             */
            advance: function(count) {
                var animations = this.animations;
                var animation, chart;
                var i = 0;

                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';

    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;

            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;
            }

            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();
        };

        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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;
        var plugins = Chart.plugins;
        var platform = Chart.platform;

        // Create a dictionary of chart types, to allow for extension of existing types
        Chart.types = {};

        // 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 = {};

        // Controllers available for dataset visualization eg. bar, line, slice, etc.
        Chart.controllers = {};

        /**
         * Initializes the given config with global and chart default values.
         */
        function initConfig(config) {
            config = config || {};

            // 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 || [];

            config.options = helpers.configMerge(
                Chart.defaults.global,
                Chart.defaults[config.type],
                config.options || {});

            return config;
        }

        /**
         * Updates the config of the chart
         * @param chart {Chart} chart to update the options for
         */
        function updateConfig(chart) {
            var newOptions = chart.options;

            // 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;
                });
            }

            // Tooltip
            chart.tooltip._options = newOptions.tooltips;
        }

        function positionIsHorizontal(position) {
            return position === 'top' || position === 'bottom';
        }

        helpers.extend(Chart.prototype, /** @lends Chart */ {
            /**
             * @private
             */
            construct: function(item, config) {
                var me = this;

                config = initConfig(config);

                var context = platform.acquireContext(item, config);
                var canvas = context && context.canvas;
                var height = canvas && canvas.height;
                var width = canvas && canvas.width;

                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;

                /**
                 * 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

                // Add the chart instance to the global namespace
                Chart.instances[me.id] = me;

                // 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;
                    }
                });

                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;
                }

                me.initialize();
                me.update();
            },

            /**
             * @private
             */
            initialize: function() {
                var me = this;

                // Before init plugin notification
                plugins.notify(me, 'beforeInit');

                helpers.retinaScale(me);

                me.bindEvents();

                if (me.options.responsive) {
                    // Initial resize before chart draws (must be silent to preserve initial animations).
                    me.resize(true);
                }

                // Make sure scales have IDs and are built before we build any controllers.
                me.ensureScalesHaveIDs();
                me.buildScales();
                me.initToolTip();

                // After init plugin notification
                plugins.notify(me, 'afterInit');

                return me;
            },

            clear: function() {
                helpers.clear(this);
                return this;
            },

            stop: function() {
                // Stops any current animation loop occurring
                Chart.animationService.cancelAnimation(this);
                return this;
            },

            resize: function(silent) {
                var me = this;
                var options = me.options;
                var canvas = me.canvas;
                var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;

                // 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 (me.width === newWidth && me.height === newHeight) {
                    return;
                }

                canvas.width = me.width = newWidth;
                canvas.height = me.height = newHeight;
                canvas.style.width = newWidth + 'px';
                canvas.style.height = newHeight + 'px';

                helpers.retinaScale(me);

                if (!silent) {
                    // Notify any plugins about the resize
                    var newSize = {width: newWidth, height: newHeight};
                    plugins.notify(me, 'resize', [newSize]);

                    // Notify of resize
                    if (me.options.onResize) {
                        me.options.onResize(me, newSize);
                    }

                    me.stop();
                    me.update(me.options.responsiveAnimationDuration);
                }
            },

            ensureScalesHaveIDs: function() {
                var options = this.options;
                var scalesOptions = options.scales || {};
                var scaleOptions = options.scale;

                helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
                    xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
                });

                helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
                    yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
                });

                if (scaleOptions) {
                    scaleOptions.id = scaleOptions.id || 'scale';
                }
            },

            /**
             * 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 (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'};
                        })
                    );
                }

                if (options.scale) {
                    items.push({
                        options: options.scale,
                        dtype: 'radialLinear',
                        isDefault: true,
                        dposition: 'chartArea'
                    });
                }

                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;
                    }

                    if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
                        scaleOptions.position = item.dposition;
                    }

                    var scale = new scaleClass({
                        id: scaleOptions.id,
                        options: scaleOptions,
                        ctx: me.ctx,
                        chart: me
                    });

                    scales[scale.id] = scale;

                    // 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.scaleService.addScalesToLayout(this);
            },

            buildOrUpdateControllers: function() {
                var me = this;
                var types = [];
                var newControllers = [];

                helpers.each(me.data.datasets, function(dataset, datasetIndex) {
                    var meta = me.getDatasetMeta(datasetIndex);
                    if (!meta.type) {
                        meta.type = dataset.type || me.config.type;
                    }

                    types.push(meta.type);

                    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.');
                        }

                        meta.controller = new ControllerClass(me, datasetIndex);
                        newControllers.push(meta.controller);
                    }
                }, me);

                if (types.length > 1) {
                    for (var i = 1; i < types.length; i++) {
                        if (types[i] !== types[i - 1]) {
                            me.isCombo = true;
                            break;
                        }
                    }
                }

                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;
                }

                me.transition(easingValue);

                if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
                    return;
                }

                // Draw all the scales
                helpers.each(me.boxes, function(box) {
                    box.draw(me.chartArea);
                }, me);

                if (me.scale) {
                    me.scale.draw();
                }

                me.drawDatasets(easingValue);

                // Finally draw the tooltip
                me.tooltip.draw();

                plugins.notify(me, 'afterDraw', [easingValue]);
            },

            /**
             * @private
             */
            transition: function(easingValue) {
                var me = this;

                for (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {
                    if (me.isDatasetVisible(i)) {
                        me.getDatasetMeta(i).controller.transition(easingValue);
                    }
                }

                me.tooltip.transition(easingValue);
            },

            /**
             * 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;

                if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
                    return;
                }

                // 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);
                    }
                }

                plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
            },

            /**
             * 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
                };

                if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
                    return;
                }

                meta.controller.draw(easingValue);

                plugins.notify(me, 'afterDatasetDraw', [args]);
            },

            // 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);
            },

            getElementsAtEvent: function(e) {
                return Chart.Interaction.modes.label(this, e, {intersect: true});
            },

            getElementsAtXAxis: function(e) {
                return Chart.Interaction.modes['x-axis'](this, e, {intersect: true});
            },

            getElementsAtEventForMode: function(e, mode, options) {
                var method = Chart.Interaction.modes[mode];
                if (typeof method === 'function') {
                    return method(this, e, options);
                }

                return [];
            },

            getDatasetAtEvent: function(e) {
                return Chart.Interaction.modes.dataset(this, e, {intersect: true});
            },

            getDatasetMeta: function(datasetIndex) {
                var me = this;
                var dataset = me.data.datasets[datasetIndex];
                if (!dataset._meta) {
                    dataset._meta = {};
                }

                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
                    };
                }

                return meta;
            },

            getVisibleDatasetCount: function() {
                var count = 0;
                for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
                    if (this.isDatasetVisible(i)) {
                        count++;
                    }
                }
                return count;
            },

            isDatasetVisible: function(datasetIndex) {
                var meta = this.getDatasetMeta(datasetIndex);

                // 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;
            },

            generateLegend: function() {
                return this.options.legendCallback(this);
            },

            destroy: function() {
                var me = this;
                var canvas = me.canvas;
                var meta, i, ilen;

                me.stop();

                // 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;
                    }
                }

                if (canvas) {
                    me.unbindEvents();
                    helpers.clear(me);
                    platform.releaseContext(me.ctx);
                    me.canvas = null;
                    me.ctx = null;
                }

                plugins.notify(me, 'destroy');

                delete Chart.instances[me.id];
            },

            toBase64Image: function() {
                return this.canvas.toDataURL.apply(this.canvas, arguments);
            },

            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();
            },

            /**
             * @private
             */
            bindEvents: function() {
                var me = this;
                var listeners = me._listeners = {};
                var listener = function() {
                    me.eventHandler.apply(me, arguments);
                };

                helpers.each(me.options.events, function(type) {
                    platform.addEventListener(me, type, listener);
                    listeners[type] = listener;
                });

                // 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();
                    };

                    platform.addEventListener(me, 'resize', listener);
                    listeners.resize = listener;
                }
            },

            /**
             * @private
             */
            unbindEvents: function() {
                var me = this;
                var listeners = me._listeners;
                if (!listeners) {
                    return;
                }

                delete me._listeners;
                helpers.each(listeners, function(listener, type) {
                    platform.removeEventListener(me, type, listener);
                });
            },

            updateHoverStyle: function(elements, mode, enabled) {
                var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
                var element, i, ilen;

                for (i=0, ilen=elements.length; i<ilen; ++i) {
                    element = elements[i];
                    if (element) {
                        this.getDatasetMeta(element._datasetIndex).controller[method](element);
                    }
                }
            },

            /**
             * @private
             */
            eventHandler: function(e) {
                var me = this;
                var tooltip = me.tooltip;

                if (plugins.notify(me, 'beforeEvent', [e]) === false) {
                    return;
                }

                // Buffer any update calls so that renders do not occur
                me._bufferedRender = true;
                me._bufferedRequest = null;

                var changed = me.handleEvent(e);
                changed |= tooltip && tooltip.handleEvent(e);

                plugins.notify(me, 'afterEvent', [e]);

                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();

                    // 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._bufferedRender = false;
                me._bufferedRequest = null;

                return me;
            },

            /**
             * 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;

                me.lastActive = me.lastActive || [];

                // Find Active Elements for hover and tooltips
                if (e.type === 'mouseout') {
                    me.active = [];
                } else {
                    me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
                }

                // 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);
                }

                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);
                    }
                }

                // Remove styling for last active (even if it may still be active)
                if (me.lastActive.length) {
                    me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
                }

                // Built in hover styling
                if (me.active.length && hoverOptions.mode) {
                    me.updateHoverStyle(me.active, hoverOptions.mode, true);
                }

                changed = !helpers.arrayEquals(me.active, me.lastActive);

                // Remember Last Actives
                me.lastActive = me.active;

                return changed;
            }
        });

        /**
         * 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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];

        /**
         * 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;
            }

            Object.defineProperty(array, '_chartjs', {
                configurable: true,
                enumerable: false,
                value: {
                    listeners: [listener]
                }
            });

            arrayEvents.forEach(function(key) {
                var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
                var base = array[key];

                Object.defineProperty(array, key, {
                    configurable: true,
                    enumerable: false,
                    value: function() {
                        var args = Array.prototype.slice.call(arguments);
                        var res = base.apply(this, args);

                        helpers.each(array._chartjs.listeners, function(object) {
                            if (typeof object[method] === 'function') {
                                object[method].apply(object, args);
                            }
                        });

                        return res;
                    }
                });
            });
        }

        /**
         * 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;
            }

            var listeners = stub.listeners;
            var index = listeners.indexOf(listener);
            if (index !== -1) {
                listeners.splice(index, 1);
            }

            if (listeners.length > 0) {
                return;
            }

            arrayEvents.forEach(function(key) {
                delete array[key];
            });

            delete array._chartjs;
        }

        // Base class for all dataset controllers (line, bar, etc)
        Chart.DatasetController = function(chart, datasetIndex) {
            this.initialize(chart, datasetIndex);
        };

        helpers.extend(Chart.DatasetController.prototype, {

            /**
             * Element type used to generate a meta dataset (e.g. Chart.element.Line).
             * @type {Chart.core.element}
             */
            datasetElementType: null,

            /**
             * Element type used to generate a meta data (e.g. Chart.element.Point).
             * @type {Chart.core.element}
             */
            dataElementType: null,

            initialize: function(chart, datasetIndex) {
                var me = this;
                me.chart = chart;
                me.index = datasetIndex;
                me.linkScales();
                me.addElements();
            },

            updateIndex: function(datasetIndex) {
                this.index = datasetIndex;
            },

            linkScales: function() {
                var me = this;
                var meta = me.getMeta();
                var dataset = me.getDataset();

                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;
                }
            },

            getDataset: function() {
                return this.chart.data.datasets[this.index];
            },

            getMeta: function() {
                return this.chart.getDatasetMeta(this.index);
            },

            getScaleForId: function(scaleID) {
                return this.chart.scales[scaleID];
            },

            reset: function() {
                this.update(true);
            },

            /**
             * @private
             */
            destroy: function() {
                if (this._data) {
                    unlistenArrayEvents(this._data, this);
                }
            },

            createMetaDataset: function() {
                var me = this;
                var type = me.datasetElementType;
                return type && new type({
                        _chart: me.chart,
                        _datasetIndex: me.index
                    });
            },

            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';

    var color = require(3);

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        function interpolate(start, view, model, ease) {
            var keys = Object.keys(model);
            var i, ilen, key, actual, origin, target, type, c0, c1;

            for (i=0, ilen=keys.length; i<ilen; ++i) {
                key = keys[i];

                target = model[key];

                // 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;
                }

                actual = view[key];

                if (actual === target || key[0] === '_') {
                    continue;
                }

                if (!start.hasOwnProperty(key)) {
                    start[key] = actual;
                }

                origin = start[key];

                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;
            }
        }

        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;
        }

        /**
         * 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 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;
            }

            var canvas = chart.canvas;
            var height = chart.height;
            var width = chart.width;

            canvas.height = height * pixelRatio;
            canvas.width = width * pixelRatio;
            chart.ctx.scale(pixelRatio, pixelRatio);

            // 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 || [];

            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 = !color?
            function(value) {
                console.error('Color.js not found!');
                return value;
            } :
            function(value) {
                /* global CanvasGradient */
                if (value instanceof CanvasGradient) {
                    value = Chart.defaults.global.defaultColor;
                }

                return color(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;

            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.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();
        };

        /**
         * 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';

    module.exports = function(Chart) {
        var helpers = Chart.helpers;

        /**
         * 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
                };
            }

            return helpers.getRelativePosition(e, chart);
        }

        /**
         * 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;

            for (i = 0, ilen = datasets.length; i < ilen; ++i) {
                if (!chart.isDatasetVisible(i)) {
                    continue;
                }

                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);
                    }
                }
            }
        }

        /**
         * 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 = [];

            parseVisibleItems(chart, function(element) {
                if (element.inRange(position.x, position.y)) {
                    elements.push(element);
                }
            });

            return elements;
        }

        /**
         * 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 = [];

            if (!distanceMetric) {
                distanceMetric = helpers.distanceBetweenPoints;
            }

            parseVisibleItems(chart, function(element) {
                if (intersect && !element.inRange(position.x, position.y)) {
                    return;
                }

                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);
                }
            });

            return nearestItems;
        }

        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 = [];

            if (!items.length) {
                return [];
            }

            chart.data.datasets.forEach(function(dataset, datasetIndex) {
                if (chart.isDatasetVisible(datasetIndex)) {
                    var meta = chart.getDatasetMeta(datasetIndex),
                        element = meta.data[items[0]._index];

                    // don't count items that are skipped (null data)
                    if (element && !element._view.skip) {
                        elements.push(element);
                    }
                }
            });

            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';

    module.exports = function() {

        // Occupy the global variable of Chart, and create a simple base class
        var Chart = function(item, config) {
            this.construct(item, config);
            return this;
        };

        // 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,

                // Element defaults defined in element extensions
                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>');

                    return text.join('');
                }
            }
        };

        Chart.Chart = Chart;

        return Chart;
    };

},{}],29:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        function filterByPosition(array, position) {
            return helpers.where(array, function(v) {
                return v.position === position;
            });
        }

        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_;
            });
        }

        /**
         * @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
         */

        // 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: {},

            /**
             * 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 = [];
                }

                // initialize item with default values
                item.fullWidth = item.fullWidth || false;
                item.position = item.position || 'top';
                item.weight = item.weight || 0;

                chart.boxes.push(item);
            },

            /**
             * 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);
                }
            },

            /**
             * 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;

                for (; i<ilen; ++i) {
                    prop = props[i];
                    if (options.hasOwnProperty(prop)) {
                        item[prop] = options[prop];
                    }
                }
            },

            /**
             * 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;
                }

                var layoutOptions = chart.options.layout;
                var padding = layoutOptions ? layoutOptions.padding : null;

                var leftPadding = 0;
                var rightPadding = 0;
                var topPadding = 0;
                var bottomPadding = 0;

                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;
                }

                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');

                // 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);

                // 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 - 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);

                // Step 3
                var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);

                // Step 4
                var maxChartAreaWidth = chartWidth;
                var maxChartAreaHeight = chartHeight;
                var minBoxSizes = [];

                function getMinimumBoxSize(box) {
                    var minSize;
                    var isHorizontal = box.isHorizontal();

                    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,
                    });
                }

                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;

                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);
                    }
                });

                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);
                    }
                });

                // 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;

                // Function to fit a box
                function fitBox(box) {
                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
                        return minBox.box === box;
                    });

                    if (minBoxSize) {
                        if (box.isHorizontal()) {
                            var scaleMargin = {
                                left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
                                right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
                                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.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
                        } else {
                            box.update(minBoxSize.minSize.width, maxChartAreaHeight);
                        }
                    }
                }

                // 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);

                // 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;
                });

                function finalFitVerticalBox(box) {
                    var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
                        return minSize.box === box;
                    });

                    var scaleMargin = {
                        left: 0,
                        right: 0,
                        top: totalTopBoxesHeight,
                        bottom: totalBottomBoxesHeight
                    };

                    if (minBoxSize) {
                        box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
                    }
                }

                // Let the left layout know the final margin
                helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);

                // 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;

                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;
                });

                // 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);

                var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
                totalTopBoxesHeight += topPaddingAddition;
                totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);

                // 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.fullWidth) {
                            box.width = newMaxChartAreaWidth;
                        }
                    });

                    helpers.each(bottomBoxes, function(box) {
                        if (!box.fullWidth) {
                            box.width = newMaxChartAreaWidth;
                        }
                    });

                    maxChartAreaHeight = newMaxChartAreaHeight;
                    maxChartAreaWidth = newMaxChartAreaWidth;
                }

                // Step 7 - Position the boxes
                var left = leftPadding + leftPaddingAddition;
                var top = topPadding + topPaddingAddition;

                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;

                        // 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;
                    }
                }

                helpers.each(leftBoxes.concat(topBoxes), placeBox);

                // Account for chart width and height
                left += maxChartAreaWidth;
                top += maxChartAreaHeight;

                helpers.each(rightBoxes, placeBox);
                helpers.each(bottomBoxes, placeBox);

                // Step 8
                chart.chartArea = {
                    left: totalLeftBoxesWidth,
                    top: totalTopBoxesHeight,
                    right: totalLeftBoxesWidth + maxChartAreaWidth,
                    bottom: totalTopBoxesHeight + maxChartAreaHeight
                };

                // 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;

                    box.update(maxChartAreaWidth, maxChartAreaHeight);
                });
            }
        };
    };

},{}],30:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        Chart.defaults.global.plugins = {};

        /**
         * The plugin service singleton
         * @namespace Chart.plugins
         * @since 2.1.0
         */
        Chart.plugins = {
            /**
             * Globally registered plugins.
             * @private
             */
            _plugins: [],

            /**
             * 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,

            /**
             * 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);
                    }
                });

                this._cacheId++;
            },

            /**
             * 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._cacheId++;
            },

            /**
             * Remove all registered plugins.
             * @since 2.1.5
             */
            clear: function() {
                this._plugins = [];
                this._cacheId++;
            },

            /**
             * Returns the number of registered plugins?
             * @returns {Number}
             * @since 2.1.5
             */
            count: function() {
                return this._plugins.length;
            },

            /**
             * Returns all registered plugin instances.
             * @returns {Array} array of plugin objects.
             * @since 2.1.5
             */
            getAll: function() {
                return this._plugins;
            },

            /**
             * 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;

                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;
                        }
                    }
                }

                return true;
            },

            /**
             * 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;
                }

                var plugins = [];
                var descriptors = [];
                var config = (chart && chart.config) || {};
                var defaults = Chart.defaults.global.plugins;
                var options = (config.options && config.options.plugins) || {};

                this._plugins.concat(config.plugins || []).forEach(function(plugin) {
                    var idx = plugins.indexOf(plugin);
                    if (idx !== -1) {
                        return;
                    }

                    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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        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)',
                zeroLineBorderDash: [],
                zeroLineBorderDashOffset: 0.0,
                offsetGridLines: false,
                borderDash: [],
                borderDashOffset: 0.0
            },

            // scale label
            scaleLabel: {
                // actual label
                labelString: '',

                // display property
                display: false
            },

            // 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
            }
        };

        function computeTextSize(context, tick, font) {
            return helpers.isArray(tick) ?
                helpers.longestText(context, font, tick) :
                context.measureText(tick).width;
        }

        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);

            return {
                size: size,
                style: style,
                family: family,
                font: helpers.fontString(size, style, family)
            };
        }

        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
                };
            },

            // 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

            beforeUpdate: function() {
                helpers.callback(this.options.beforeUpdate, [this]);
            },
            update: function(maxWidth, maxHeight, margins) {
                var me = this;

                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
                me.beforeUpdate();

                // 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 || {};

                // Dimensions
                me.beforeSetDimensions();
                me.setDimensions();
                me.afterSetDimensions();

                // Data min/max
                me.beforeDataLimits();
                me.determineDataLimits();
                me.afterDataLimits();

                // Ticks
                me.beforeBuildTicks();
                me.buildTicks();
                me.afterBuildTicks();

                me.beforeTickToLabelConversion();
                me.convertTicksToLabels();
                me.afterTickToLabelConversion();

                // Tick Rotation
                me.beforeCalculateTickRotation();
                me.calculateTickRotation();
                me.afterCalculateTickRotation();
                // Fit
                me.beforeFit();
                me.fit();
                me.afterFit();
                //
                me.afterUpdate();

                return me.minSize;

            },
            afterUpdate: function() {
                helpers.callback(this.options.afterUpdate, [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;

                    // Reset position before calculating rotation
                    me.top = 0;
                    me.bottom = me.height;
                }

                // 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]);
            },

            //
            beforeBuildTicks: function() {
                helpers.callback(this.options.beforeBuildTicks, [this]);
            },
            buildTicks: helpers.noop,
            afterBuildTicks: function() {
                helpers.callback(this.options.afterBuildTicks, [this]);
            },

            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]);
            },

            //

            beforeCalculateTickRotation: function() {
                helpers.callback(this.options.beforeCalculateTickRotation, [this]);
            },
            calculateTickRotation: function() {
                var me = this;
                var context = me.ctx;
                var tickOpts = me.options.ticks;

                // 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;

                var labelRotation = tickOpts.minRotation || 0;

                if (me.options.display && me.isHorizontal()) {
                    var originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);
                    var labelWidth = originalLabelWidth;
                    var cosRotation;
                    var sinRotation;

                    // Allow 3 pixels x2 padding either side for label readability
                    var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;

                    // 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);

                        if (sinRotation * originalLabelWidth > me.maxHeight) {
                            // go back one step
                            labelRotation--;
                            break;
                        }

                        labelRotation++;
                        labelWidth = cosRotation * originalLabelWidth;
                    }
                }

                me.labelRotation = labelRotation;
            },
            afterCalculateTickRotation: function() {
                helpers.callback(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();

                var tickFont = parseFontOptions(tickOpts);
                var scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;
                var tickMarkLength = opts.gridLines.tickMarkLength;

                // 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;
                }

                // height
                if (isHorizontal) {
                    minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
                } else {
                    minSize.height = me.maxHeight; // fill all the height
                }

                // Are we showing a title for the scale?
                if (scaleLabelOpts.display && display) {
                    if (isHorizontal) {
                        minSize.height += scaleLabelFontSize;
                    } else {
                        minSize.width += scaleLabelFontSize;
                    }
                }

                // 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;

                    if (isHorizontal) {
                        // A horizontal axis is more constrained by the height.
                        me.longestLabelWidth = largestTextWidth;

                        var angleRadians = helpers.toRadians(me.labelRotation);
                        var cosRotation = Math.cos(angleRadians);
                        var sinRotation = Math.sin(angleRadians);

                        // TODO - improve this calculation
                        var labelHeight = (sinRotation * largestTextWidth)
                            + (tickFont.size * tallestLabelHeightInLines)
                            + (lineSpace * tallestLabelHeightInLines);

                        minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);
                        me.ctx.font = tickFont.font;

                        var firstTick = me.ticks[0];
                        var firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);

                        var lastTick = me.ticks[me.ticks.length - 1];
                        var lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);

                        // 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

                        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;
                    }
                }

                me.handleMargins();

                me.width = minSize.width;
                me.height = minSize.height;
            },

            /**
             * 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);
                }
            },

            afterFit: function() {
                helpers.callback(this.options.afterFit, [this]);
            },

            // Shared Methods
            isHorizontal: function() {
                return this.options.position === 'top' || this.options.position === 'bottom';
            },
            isFullWidth: function() {
                return (this.options.fullWidth);
            },

            // 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);
                }

                // Value is good, return it
                return rawValue;
            },

            // 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 to get data value locations.  Value can either be an index or a numerical value
            getPixelForValue: helpers.noop,

            // Used to get the data value from a given pixel. This is the inverse of getPixelForValue
            getValueForPixel: 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;

                    if (includeOffset) {
                        pixel += tickWidth / 2;
                    }

                    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)));
            },

            // 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;

                    var finalVal = me.left + Math.round(valueOffset);
                    finalVal += me.isFullWidth() ? me.margins.left : 0;
                    return finalVal;
                }
                return me.top + (decimal * me.height);
            },

            getBasePixel: function() {
                return this.getPixelForValue(this.getBaseValue());
            },

            getBaseValue: function() {
                var me = this;
                var min = me.min;
                var max = me.max;

                return me.beginAtZero ? 0:
                    min < 0 && max < 0? max :
                        min > 0 && max > 0? min :
                            0;
            },

            // 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;
                }

                var context = me.ctx;
                var globalDefaults = Chart.defaults.global;
                var optionTicks = options.ticks;
                var gridLines = options.gridLines;
                var scaleLabel = options.scaleLabel;

                var isRotated = me.labelRotation !== 0;
                var skipRatio;
                var useAutoskipper = optionTicks.autoSkip;
                var isHorizontal = me.isHorizontal();

                // figure out the maximum number of gridlines to show
                var maxTicks;
                if (optionTicks.maxTicksLimit) {
                    maxTicks = optionTicks.maxTicksLimit;
                }

                var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
                var tickFont = parseFontOptions(optionTicks);

                var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;

                var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
                var scaleLabelFont = parseFontOptions(scaleLabel);

                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;

                var itemsToDraw = [];

                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)));
                    }

                    // 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 isLastTick = me.ticks.length === index + 1;

                    // 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 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);
                    }

                    // Common properties
                    var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
                    var textAlign = 'middle';
                    var textBaseline = 'middle';

                    if (isHorizontal) {

                        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;
                        }

                        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)

                        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;

                        if (optionTicks.mirror) {
                            textAlign = isLeft ? 'left' : 'right';
                            labelXOffset = tickPadding;
                        } else {
                            textAlign = isLeft ? 'right' : 'left';
                            labelXOffset = tl + tickPadding;
                        }

                        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);

                        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,
                        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.save();
                        context.lineWidth = itemToDraw.glWidth;
                        context.strokeStyle = itemToDraw.glColor;
                        if (context.setLineDash) {
                            context.setLineDash(itemToDraw.glBorderDash);
                            context.lineDashOffset = itemToDraw.glBorderDashOffset;
                        }

                        context.beginPath();

                        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);
                        }

                        context.stroke();
                        context.restore();
                    }

                    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 += (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 (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.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;

                    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();
                }
            }
        });
    };

},{}],32:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        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

            // 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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        /**
         * 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
                 */

                /**
                 * 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.

                    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;

                    // 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;
                        }
                    }

                    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);
                    }

                    // 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);

                    return ticks;
                },

                /**
                 * 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;

                    // 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))));

                    var endExp = Math.floor(helpers.log10(dataRange.max));
                    var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
                    var exp;
                    var significand;

                    if (tickVal === 0) {
                        exp = Math.floor(helpers.log10(dataRange.minNotZero));
                        significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));

                        ticks.push(tickVal);
                        tickVal = significand * Math.pow(10, exp);
                    } else {
                        exp = Math.floor(helpers.log10(tickVal));
                        significand = Math.floor(tickVal / Math.pow(10, exp));
                    }

                    do {
                        ticks.push(tickVal);

                        ++significand;
                        if (significand === 10) {
                            significand = 1;
                            ++exp;
                        }

                        tickVal = significand * Math.pow(10, exp);
                    } while (exp < endExp || (exp === endExp && significand < endSignificand));

                    var lastTick = getValueOrDefault(generationOptions.max, tickVal);
                    ticks.push(lastTick);

                    return ticks;
                }
            },

            /**
             * 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;
                },

                /**
                 * 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);
                        }
                    }

                    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
                    }

                    return tickString;
                },

                logarithmic: function(tickValue, index, ticks) {
                    var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));

                    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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        /**
         * 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();
        }

        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 (tooltipItems.length > 0) {
                        var item = tooltipItems[0];

                        if (item.xLabel) {
                            title = item.xLabel;
                        } else if (labelCount > 0 && item.index < labelCount) {
                            title = labels[item.index];
                        }
                    }

                    return title;
                },
                afterTitle: helpers.noop,

                // Args are: (tooltipItems, data)
                beforeBody: helpers.noop,

                // Args are: (tooltipItem, data)
                beforeLabel: helpers.noop,
                label: function(tooltipItem, data) {
                    var label = data.datasets[tooltipItem.datasetIndex].label || '';

                    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,

                // Args are: (tooltipItems, data)
                afterBody: helpers.noop,

                // Args are: (tooltipItems, data)
                beforeFooter: helpers.noop,
                footer: helpers.noop,
                afterFooter: 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);
                }
            }

            return base;
        }

        // 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;

            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
            };
        }

        /**
         * 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;

            return {
                // Positioning
                xPadding: tooltipOpts.xPadding,
                yPadding: tooltipOpts.yPadding,
                xAlign: tooltipOpts.xAlign,
                yAlign: tooltipOpts.yAlign,

                // 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,

                // 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,

                // 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,

                // Appearance
                caretSize: tooltipOpts.caretSize,
                cornerRadius: tooltipOpts.cornerRadius,
                backgroundColor: tooltipOpts.backgroundColor,
                opacity: 0,
                legendColorBackground: tooltipOpts.multiKeyBackground,
                displayColors: tooltipOpts.displayColors,
                borderColor: tooltipOpts.borderColor,
                borderWidth: tooltipOpts.borderWidth
            };
        }

        /**
         * Get the size of the tooltip
         */
        function getTooltipSize(tooltip, model) {
            var ctx = tooltip._chart.ctx;

            var height = model.yPadding * 2; // Tooltip Padding
            var width = 0;

            // 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;

            var titleLineCount = model.title.length;
            var footerLineCount = model.footer.length;
            var titleFontSize = model.titleFontSize,
                bodyFontSize = model.bodyFontSize,
                footerFontSize = model.footerFontSize;

            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

            // Title width
            var widthPadding = 0;
            var maxLineWidth = function(line) {
                width = Math.max(width, ctx.measureText(line).width + widthPadding);
            };

            ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
            helpers.each(model.title, maxLineWidth);

            // Body width
            ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
            helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);

            // 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);
            });

            // Reset back to 0
            widthPadding = 0;

            // Footer width
            ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
            helpers.each(model.footer, maxLineWidth);

            // Add padding
            width += 2 * model.xPadding;

            return {
                width: width,
                height: height
            };
        }

        /**
         * 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';

            if (model.y < size.height) {
                yAlign = 'top';
            } else if (model.y > (chart.height - size.height)) {
                yAlign = 'bottom';
            }

            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;

            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));
                };
            }

            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';
            };

            if (lf(model.x)) {
                xAlign = 'left';

                // 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';

                // Is tooltip too wide and goes outside left edge of canvas?
                if (orf(model.x)) {
                    xAlign = 'center';
                    yAlign = yf(model.y);
                }
            }

            var opts = tooltip._options;
            return {
                xAlign: opts.xAlign ? opts.xAlign : xAlign,
                yAlign: opts.yAlign ? opts.yAlign : yAlign
            };
        }

        /**
         * @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);

                    // Initial positioning and colors
                    model.x = Math.round(tooltipPosition.x);
                    model.y = Math.round(tooltipPosition.y);
                    model.caretPadding = opts.caretPadding;
                    model.labelColors = labelColors;

                    // data points
                    model.dataPoints = tooltipItems;

                    // 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;
                }

                model.xAlign = alignment.xAlign;
                model.yAlign = alignment.yAlign;
                model.x = backgroundPoint.x;
                model.y = backgroundPoint.y;
                model.width = tooltipSize.width;
                model.height = tooltipSize.height;

                // Point where the caret on the tooltip points to
                model.caretX = tooltipPosition.x;
                model.caretY = tooltipPosition.y;

                me._model = model;

                if (changed && opts.custom) {
                    opts.custom.call(me, model);
                }

                return me;
            },
            drawCaret: function(tooltipPoint, size) {
                var ctx = this._chart.ctx;
                var vm = this._view;
                var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);

                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;

                if (yAlign === 'center') {
                    y2 = ptY + (height / 2);

                    if (xAlign === 'left') {
                        x1 = ptX;
                        x2 = x1 - caretSize;
                        x3 = x1;

                        y1 = y2 + caretSize;
                        y3 = y2 - caretSize;
                    } else {
                        x1 = ptX + width;
                        x2 = x1 + caretSize;
                        x3 = x1;

                        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;

                if (title.length) {
                    ctx.textAlign = vm._titleAlign;
                    ctx.textBaseline = 'top';

                    var titleFontSize = vm.titleFontSize,
                        titleSpacing = vm.titleSpacing;

                    ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
                    ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);

                    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 (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;

                ctx.textAlign = vm._bodyAlign;
                ctx.textBaseline = 'top';

                var textColor = mergeOpacity(vm.bodyFontColor, opacity);
                ctx.fillStyle = textColor;
                ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);

                // Before Body
                var xLinePadding = 0;
                var fillLineOfText = function(line) {
                    ctx.fillText(line, pt.x + xLinePadding, pt.y);
                    pt.y += bodyFontSize + bodySpacing;
                };

                // Before body lines
                helpers.each(vm.beforeBody, fillLineOfText);

                var drawColorBoxes = vm.displayColors;
                xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;

                // Draw body lines now
                helpers.each(body, function(bodyItem, i) {
                    helpers.each(bodyItem.before, fillLineOfText);

                    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);

                            // Border
                            ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
                            ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);

                            // Inner square
                            ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
                            ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);

                            ctx.fillStyle = textColor;
                        }

                        fillLineOfText(line);
                    });

                    helpers.each(bodyItem.after, fillLineOfText);
                });

                // Reset back to 0 for after body
                xLinePadding = 0;

                // 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;

                if (footer.length) {
                    pt.y += vm.footerMarginTop;

                    ctx.textAlign = vm._footerAlign;
                    ctx.textBaseline = 'top';

                    ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
                    ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);

                    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;

                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();

                ctx.fill();

                if (vm.borderWidth > 0) {
                    ctx.stroke();
                }
            },
            draw: function() {
                var ctx = this._chart.ctx;
                var vm = this._view;

                if (vm.opacity === 0) {
                    return;
                }

                var tooltipSize = {
                    width: vm.width,
                    height: vm.height
                };
                var pt = {
                    x: vm.x,
                    y: vm.y
                };

                // IE11/Edge does not like very small opacities, so snap to 0
                var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;

                // Truthy/falsey value for empty tooltip
                var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;

                if (this._options.enabled && hasTooltipContent) {
                    // Draw Background
                    this.drawBackground(pt, vm, ctx, tooltipSize, opacity);

                    // Draw Title, Body, and Footer
                    pt.x += vm.xPadding;
                    pt.y += vm.yPadding;

                    // Titles
                    this.drawTitle(pt, vm, ctx, opacity);

                    // Body
                    this.drawBody(pt, vm, ctx, opacity);

                    // Footer
                    this.drawFooter(pt, vm, ctx, opacity);
                }
            },

            /**
             * 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;

                me._lastActive = me._lastActive || [];

                // Find Active Elements for tooltips
                if (e.type === 'mouseout') {
                    me._active = [];
                } else {
                    me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
                }

                // Remember Last Actives
                changed = !helpers.arrayEquals(me._active, me._lastActive);

                // If tooltip didn't change, do not handle the target event
                if (!changed) {
                    return false;
                }

                me._lastActive = me._active;

                if (options.enabled || options.custom) {
                    me._eventPosition = {
                        x: e.x,
                        y: e.y
                    };

                    var model = me._model;
                    me.update(true);
                    me.pivot();

                    // See if our tooltip position changed
                    changed |= (model.x !== me._model.x) || (model.y !== me._model.y);
                }

                return changed;
            }
        });

        /**
         * @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 i, len;
                var x = 0;
                var y = 0;
                var count = 0;

                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;
                    }
                }

                return {
                    x: Math.round(x / count),
                    y: Math.round(y / count)
                };
            },

            /**
             * 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;

                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);

                        if (d < minDistance) {
                            minDistance = d;
                            nearestElement = el;
                        }
                    }
                }

                if (nearestElement) {
                    var tp = nearestElement.tooltipPosition();
                    x = tp.x;
                    y = tp.y;
                }

                return {
                    x: x,
                    y: y
                };
            }
        };
    };

},{}],35:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers,
            globalOpts = Chart.defaults.global;

        globalOpts.elements.arc = {
            backgroundColor: globalOpts.defaultColor,
            borderColor: '#fff',
            borderWidth: 2
        };

        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));
                }
                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;

                    // 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);

                    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 ctx = this._chart.ctx,
                    vm = this._view,
                    sA = vm.startAngle,
                    eA = vm.endAngle;

                ctx.beginPath();

                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.fillStyle = vm.backgroundColor;

                ctx.fill();
                ctx.lineJoin = 'bevel';

                if (vm.borderWidth) {
                    ctx.stroke();
                }
            }
        });
    };

},{}],36:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        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.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;

                // If we are looping, adding the first point again
                if (me._loop && points.length) {
                    points.push(points[0]);
                }

                ctx.save();

                // Stroke Line Options
                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) {
                            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
                                helpers.canvas.lineTo(ctx, previous._view, current._view);
                            }
                            lastDrawnIndex = index;
                        }
                    }
                }

                ctx.stroke();
                ctx.restore();
            }
        });
    };

},{}],37:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        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
        };

        function xRange(mouseX) {
            var vm = this._view;
            return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
        }

        function yRange(mouseY) {
            var vm = this._view;
            return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
        }

        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: 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';

    module.exports = function(Chart) {

        var globalOpts = Chart.defaults.global;

        globalOpts.elements.rectangle = {
            backgroundColor: globalOpts.defaultColor,
            borderWidth: 0,
            borderColor: globalOpts.defaultColor,
            borderSkipped: 'bottom'
        };

        function isVertical(bar) {
            return bar._view.width !== undefined;
        }

        /**
         * 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;

            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;
            }

            return {
                left: x1,
                top: y1,
                right: x2,
                bottom: y2
            };
        }

        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;

                if (!vm.horizontal) {
                    // bar
                    left = vm.x - vm.width / 2;
                    right = vm.x + vm.width / 2;
                    top = vm.y;
                    bottom = vm.base;
                    signX = 1;
                    signY = bottom > top? 1: -1;
                    borderSkipped = vm.borderSkipped || 'bottom';
                } else {
                    // horizontal bar
                    left = vm.base;
                    right = vm.x;
                    top = vm.y - vm.height / 2;
                    bottom = vm.y + vm.height / 2;
                    signX = right > left? 1: -1;
                    signY = 1;
                    borderSkipped = vm.borderSkipped || 'left';
                }

                // Canvas doesn't allow us to stroke inside the width so we can
                // adjust the sizes to fit if we're setting a stroke on the line
                if (borderWidth) {
                    // borderWidth shold be less than bar width and bar height.
                    var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
                    borderWidth = borderWidth > barSize? barSize: borderWidth;
                    var halfStroke = borderWidth / 2;
                    // Adjust borderWidth when bar top position is near vm.base(zero).
                    var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
                    var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
                    var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
                    var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
                    // not become a vertical line?
                    if (borderLeft !== borderRight) {
                        top = borderTop;
                        bottom = borderBottom;
                    }
                    // not become a horizontal line?
                    if (borderTop !== borderBottom) {
                        left = borderLeft;
                        right = borderRight;
                    }
                }

                ctx.beginPath();
                ctx.fillStyle = vm.backgroundColor;
                ctx.strokeStyle = vm.borderColor;
                ctx.lineWidth = borderWidth;

                // Corner points, from bottom-left to bottom-right clockwise
                // | 1 2 |
                // | 0 3 |
                var corners = [
                    [left, bottom],
                    [left, top],
                    [right, top],
                    [right, bottom]
                ];

                // Find first (starting) corner with fallback to 'bottom'
                var borders = ['bottom', 'left', 'top', 'right'];
                var startCorner = borders.indexOf(borderSkipped, 0);
                if (startCorner === -1) {
                    startCorner = 0;
                }

                function cornerAt(index) {
                    return corners[(startCorner + index) % 4];
                }

                // Draw rectangle from 'startCorner'
                var corner = cornerAt(0);
                ctx.moveTo(corner[0], corner[1]);

                for (var i = 1; i < 4; i++) {
                    corner = cornerAt(i);
                    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';

// Chart.Platform implementation for targeting a web browser
    module.exports = function(Chart) {
        var helpers = Chart.helpers;

        // 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',

            // Pointer events
            pointerenter: 'mouseenter',
            pointerdown: 'mousedown',
            pointermove: 'mousemove',
            pointerup: 'mouseup',
            pointerleave: 'mouseout',
            pointerout: 'mouseout'
        };

        /**
         * 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;
        }

        /**
         * 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;

            // 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');

            // 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
                    }
                }
            };

            // 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';

            if (renderWidth === null || renderWidth === '') {
                var displayWidth = readUsedSize(canvas, 'width');
                if (displayWidth !== undefined) {
                    canvas.width = displayWidth;
                }
            }

            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;
                    }
                }
            }

            return canvas;
        }

        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,
            };
        }

        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);
        }

        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;';

            // Prevent the iframe to gain focus on tab.
            // https://github.com/chartjs/Chart.js/issues/3090
            iframe.tabIndex = -1;

            // 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);

                // The iframe size might have changed while loading, which can also
                // happen if the size has been changed while detached from the DOM.
                handler();
            });

            return iframe;
        }

        function addResizeListener(node, listener, chart) {
            var stub = node._chartjs = {
                ticking: false
            };

            // 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';

// By default, select the browser (DOM) platform.
// @TODO Make possible to select another platform at build time.
    var implementation = require(39);

    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() {},

            /**
             * 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() {},

            /**
             * 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() {},

            /**
             * 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() {}
        };

        /**
         * @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
         */

        /**
         * @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)
         */

        Chart.helpers.extend(Chart.platform, implementation(Chart));
    };

},{"39":39}],41:[function(require,module,exports){
    'use strict';

    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
        };

        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) || [];

                return !points.length? null : function(point, i) {
                    return points[i]._view || null;
                };
            },

            boundary: function(source) {
                var boundary = source.boundary;
                var x = boundary? boundary.x : null;
                var y = boundary? boundary.y : null;

                return function(point) {
                    return {
                        x: x === null? point.x : x,
                        y: y === null? point.y : y,
                    };
                };
            }
        };

        // @todo if (fill[0] === '#')
        function decodeFill(el, index, count) {
            var model = el._model || {};
            var fill = model.fill;
            var target;

            if (fill === undefined) {
                fill = !!model.backgroundColor;
            }

            if (fill === false || fill === null) {
                return false;
            }

            if (fill === true) {
                return 'origin';
            }

            target = parseFloat(fill, 10);
            if (isFinite(target) && Math.floor(target) === target) {
                if (fill[0] === '-' || fill[0] === '+') {
                    target = index + target;
                }

                if (target === index || target < 0 || target >= count) {
                    return false;
                }

                return target;
            }

            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;
            }
        }

        function computeBoundary(source) {
            var model = source.el._model || {};
            var scale = source.el._scale || {};
            var fill = source.fill;
            var target = null;
            var horizontal;

            if (isFinite(fill)) {
                return null;
            }

            // 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).

            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();
            }

            if (target !== undefined && target !== null) {
                if (target.x !== undefined && target.y !== undefined) {
                    return target;
                }

                if (typeof target === 'number' && isFinite(target)) {
                    horizontal = scale.isHorizontal();
                    return {
                        x: horizontal? target : null,
                        y: horizontal? null : target
                    };
                }
            }

            return null;
        }

        function resolveTarget(sources, index, propagate) {
            var source = sources[index];
            var fill = source.fill;
            var visited = [index];
            var target;

            if (!propagate) {
                return fill;
            }

            while (fill !== false && visited.indexOf(fill) === -1) {
                if (!isFinite(fill)) {
                    return fill;
                }

                target = sources[fill];
                if (!target) {
                    return false;
                }

                if (target.visible) {
                    return fill;
                }

                visited.push(fill);
                fill = target.fill;
            }

            return false;
        }

        function createMapper(source) {
            var fill = source.fill;
            var type = 'dataset';

            if (fill === false) {
                return null;
            }

            if (!isFinite(fill)) {
                type = 'boundary';
            }

            return mappers[type](source);
        }

        function isDrawable(point) {
            return point && !point.skip;
        }

        function drawArea(ctx, curve0, curve1, len0, len1) {
            var i;

            if (!len0 || !len1) {
                return;
            }

            // 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]);
            }

            // joining the two area curves
            ctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);

            // building opposite area curve (reverse)
            for (i=len1-1; i>0; --i) {
                helpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);
            }
        }

        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;

            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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;
        var layout = Chart.layoutService;
        var noop = helpers.noop;

        Chart.defaults.global.legend = {
            display: true,
            position: 'top',
            fullWidth: true,
            reverse: false,
            weight: 1000,

            // a callback that will handle
            onClick: function(e, legendItem) {
                var index = legendItem.datasetIndex;
                var ci = this.chart;
                var meta = ci.getDatasetMeta(index);

                // See controller.isDatasetVisible comment
                meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;

                // We hid a dataset ... rerender the chart
                ci.update();
            },

            onHover: null,

            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,

                            // Below is extra data used for toggling the datasets
                            datasetIndex: i
                        };
                    }, this) : [];
                }
            }
        };

        /**
         * 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;
        }

        Chart.Legend = Chart.Element.extend({

            initialize: function(config) {
                helpers.extend(this, config);

                // Contains hit boxes for each dataset (in dataset order)
                this.legendHitBoxes = [];

                // Are we in doughnut mode which has a different data type
                this.doughnutMode = false;
            },

            // 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

            beforeUpdate: noop,
            update: function(maxWidth, maxHeight, margins) {
                var me = this;

                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
                me.beforeUpdate();

                // Absorb the master measurements
                me.maxWidth = maxWidth;
                me.maxHeight = maxHeight;
                me.margins = margins;

                // Dimensions
                me.beforeSetDimensions();
                me.setDimensions();
                me.afterSetDimensions();
                // Labels
                me.beforeBuildLabels();
                me.buildLabels();
                me.afterBuildLabels();

                // Fit
                me.beforeFit();
                me.fit();
                me.afterFit();
                //
                me.afterUpdate();

                return me.minSize;
            },
            afterUpdate: noop,

            //

            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;

                    // Reset position before calculating rotation
                    me.top = 0;
                    me.bottom = me.height;
                }

                // Reset padding
                me.paddingLeft = 0;
                me.paddingTop = 0;
                me.paddingRight = 0;
                me.paddingBottom = 0;

                // Reset minSize
                me.minSize = {
                    width: 0,
                    height: 0
                };
            },
            afterSetDimensions: noop,

            //

            beforeBuildLabels: noop,
            buildLabels: function() {
                var me = this;
                var labelOpts = me.options.labels;
                var legendItems = labelOpts.generateLabels.call(me, me.chart);

                if (labelOpts.filter) {
                    legendItems = legendItems.filter(function(item) {
                        return labelOpts.filter(item, me.chart.data);
                    });
                }

                if (me.options.reverse) {
                    legendItems.reverse();
                }

                me.legendItems = legendItems;
            },
            afterBuildLabels: noop,

            //

            beforeFit: noop,
            fit: function() {
                var me = this;
                var opts = me.options;
                var labelOpts = opts.labels;
                var display = opts.display;

                var ctx = me.ctx;

                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);

                // Reset hit boxes
                var hitboxes = me.legendHitBoxes = [];

                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';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;
        var layout = Chart.layoutService;
        var noop = helpers.noop;

        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,

            // actual title
            text: ''
        };

        Chart.Title = Chart.Element.extend({
            initialize: function(config) {
                var me = this;
                helpers.extend(me, config);

                // Contains hit boxes for each dataset (in dataset order)
                me.legendHitBoxes = [];
            },

            // These methods are ordered by lifecycle. Utilities then follow.

            beforeUpdate: noop,
            update: function(maxWidth, maxHeight, margins) {
                var me = this;

                // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
                me.beforeUpdate();

                // Absorb the master measurements
                me.maxWidth = maxWidth;
                me.maxHeight = maxHeight;
                me.margins = margins;

                // Dimensions
                me.beforeSetDimensions();
                me.setDimensions();
                me.afterSetDimensions();
                // Labels
                me.beforeBuildLabels();
                me.buildLabels();
                me.afterBuildLabels();

                // Fit
                me.beforeFit();
                me.fit();
                me.afterFit();
                //
                me.afterUpdate();

                return me.minSize;

            },
            afterUpdate: noop,

            //

            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;

                    // Reset position before calculating rotation
                    me.top = 0;
                    me.bottom = me.height;
                }

                // Reset padding
                me.paddingLeft = 0;
                me.paddingTop = 0;
                me.paddingRight = 0;
                me.paddingBottom = 0;

                // Reset minSize
                me.minSize = {
                    width: 0,
                    height: 0
                };
            },
            afterSetDimensions: noop,

            //

            beforeBuildLabels: noop,
            buildLabels: noop,
            afterBuildLabels: noop,

            //

            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;

                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
                }

                me.width = minSize.width;
                me.height = minSize.height;

            },
            afterFit: noop,

            // Shared Methods
            isHorizontal: function() {
                var pos = this.options.position;
                return pos === 'top' || pos === 'bottom';
            },

            // 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;

                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;

                    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
                        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);
                    }

                    ctx.save();
                    ctx.translate(titleX, titleY);
                    ctx.rotate(rotation);
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText(opts.text, 0, 0, maxWidth);
                    ctx.restore();
                }
            }
        });

        function createNewTitleBlockAndAttach(chart, titleOpts) {
            var title = new Chart.Title({
                ctx: chart.ctx,
                options: titleOpts,
                chart: chart
            });

            layout.configure(chart, title, titleOpts);
            layout.addBox(chart, title);
            chart.titleBlock = title;
        }

        return {
            id: 'title',

            beforeInit: function(chart) {
                var titleOpts = chart.options.title;

                if (titleOpts) {
                    createNewTitleBlockAndAttach(chart, titleOpts);
                }
            },

            beforeUpdate: function(chart) {
                var titleOpts = chart.options.title;
                var titleBlock = chart.titleBlock;

                if (titleOpts) {
                    titleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);

                    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){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;
        // Default config for a category scale
        var defaultConfig = {
            position: 'bottom'
        };

        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;
            },

            determineDataLimits: function() {
                var me = this;
                var labels = me.getLabels();
                me.minIndex = 0;
                me.maxIndex = labels.length - 1;
                var findIndex;

                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;
                }

                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;
                }

                me.min = labels[me.minIndex];
                me.max = labels[me.maxIndex];
            },

            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);
            },

            getLabelForIndex: function(index, datasetIndex) {
                var me = this;
                var data = me.chart.data;
                var isHorizontal = me.isHorizontal();

                if (data.yLabels && !isHorizontal) {
                    return me.getRightValue(data.datasets[datasetIndex].data[index]);
                }
                return me.ticks[index - me.minIndex];
            },

            // 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 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;
                }

                if (me.isHorizontal()) {
                    var valueWidth = me.width / offsetAmt;
                    var widthOffset = (valueWidth * (index - me.minIndex));

                    if (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {
                        widthOffset += (valueWidth / 2);
                    }

                    return me.left + Math.round(widthOffset);
                }
                var valueHeight = me.height / offsetAmt;
                var heightOffset = (valueHeight * (index - me.minIndex));

                if (me.options.gridLines.offsetGridLines && includeOffset) {
                    heightOffset += (valueHeight / 2);
                }

                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;

                pixel -= horz ? me.left : me.top;

                if (me.options.gridLines.offsetGridLines) {
                    pixel -= (valueDimension / 2);
                }

                if (pixel <= 0) {
                    value = 0;
                } else {
                    value = Math.round(pixel / valueDimension);
                }

                return value;
            },
            getBasePixel: function() {
                return this.bottom;
            }
        });

        Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);

    };

},{}],45:[function(require,module,exports){
    'use strict';

    module.exports = function(Chart) {

        var helpers = Chart.helpers;

        var defaultConfig = {
            position: 'left',
            ticks: {
                callback: Chart.Ticks.formatters.linear
            }
        };

        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();
                var DEFAULT_MIN = 0;
                var DEFAULT_MAX = 1;

                function IDMatches(meta) {
                    return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
                }

                // First Calculate the range
                me.min = null;
                me.max = 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 (valuesPerStack[key] === undefined) {
                            valuesPerStack[key] = {
                                positiveValues: [],
                                negativeValues: []
                            };
                        }

                        // Store these per type
                        var positiveValues = valuesPerStack[key].positiveValues;
                        var negativeValues = valuesPerStack[key].negativeValues;

                        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;
                                }

                                positiveValues[index] = positiveValues[index] || 0;
                                negativeValues[index] = negativeValues[index] || 0;

                                if (opts.relativePoints) {
                                    positiveValues[index] = 100;
                                } else if (value < 0) {
                                    negativeValues[index] += value;
                                } else {
                                    positiveValues[index] += value;
                                }
                            });
                        }
                    });

                    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);
                    });

                } 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;
                                }
                            });
                        }
                    });
                }

                me.min = isFinite(me.min) ? me.min : DEFAULT_MIN;
                me.max = isFinite(me.max) ? me.max : DEFAULT_MAX;

                // 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 (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)));
                }

                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 rightValue = +me.getRightValue(value);
                var pixel;
                var range = me.end - start;

                if (me.isHorizontal()) {
                    pixel = me.left + (me.width / range * (rightValue - start));
                    return Math.round(pixel);
                }

                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);

    };

},{}],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)
});