text: /*
   * React Chartkick
   * Create beautiful JavaScript charts with one line of React
   * https://github.com/ankane/react-chartkick
   * v0.2.0
   * MIT License
   */
  
  (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
    typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
    (factory((global.ReactChartkick = {}),global.React));
  }(this, (function (exports,React) { 'use strict';
  
    React = React && React.hasOwnProperty('default') ? React['default'] : React;
  
    /*
     * Chartkick.js
     * Create beautiful charts with one line of JavaScript
     * https://github.com/ankane/chartkick.js
     * v2.3.5
     * MIT License
     */
  
    function isArray(variable) {
      return Object.prototype.toString.call(variable) === "[object Array]";
    }
  
    function isFunction(variable) {
      return variable instanceof Function;
    }
  
    function isPlainObject(variable) {
      return !isFunction(variable) && variable instanceof Object;
    }
  
    // https://github.com/madrobby/zepto/blob/master/src/zepto.js
    function extend(target, source) {
      var key;
      for (key in source) {
        if (isPlainObject(source[key]) || isArray(source[key])) {
          if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
            target[key] = {};
          }
          if (isArray(source[key]) && !isArray(target[key])) {
            target[key] = [];
          }
          extend(target[key], source[key]);
        } else if (source[key] !== undefined) {
          target[key] = source[key];
        }
      }
    }
  
    function merge(obj1, obj2) {
      var target = {};
      extend(target, obj1);
      extend(target, obj2);
      return target;
    }
  
    var DATE_PATTERN = /^(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)$/i;
  
    // https://github.com/Do/iso8601.js
    var ISO8601_PATTERN = /(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)(T)?(\d\d)(:)?(\d\d)?(:)?(\d\d)?([.,]\d+)?($|Z|([+-])(\d\d)(:)?(\d\d)?)/i;
    var DECIMAL_SEPARATOR = String(1.5).charAt(1);
  
    function parseISO8601(input) {
      var day, hour, matches, milliseconds, minutes, month, offset, result, seconds, type, year;
      type = Object.prototype.toString.call(input);
      if (type === "[object Date]") {
        return input;
      }
      if (type !== "[object String]") {
        return;
      }
      matches = input.match(ISO8601_PATTERN);
      if (matches) {
        year = parseInt(matches[1], 10);
        month = parseInt(matches[3], 10) - 1;
        day = parseInt(matches[5], 10);
        hour = parseInt(matches[7], 10);
        minutes = matches[9] ? parseInt(matches[9], 10) : 0;
        seconds = matches[11] ? parseInt(matches[11], 10) : 0;
        milliseconds = matches[12] ? parseFloat(DECIMAL_SEPARATOR + matches[12].slice(1)) * 1000 : 0;
        result = Date.UTC(year, month, day, hour, minutes, seconds, milliseconds);
        if (matches[13] && matches[14]) {
          offset = matches[15] * 60;
          if (matches[17]) {
            offset += parseInt(matches[17], 10);
          }
          offset *= matches[14] === "-" ? -1 : 1;
          result -= offset * 60 * 1000;
        }
        return new Date(result);
      }
    }
    // end iso8601.js
  
    function negativeValues(series) {
      var i, j, data;
      for (i = 0; i < series.length; i++) {
        data = series[i].data;
        for (j = 0; j < data.length; j++) {
          if (data[j][1] < 0) {
            return true;
          }
        }
      }
      return false;
    }
  
    function toStr(n) {
      return "" + n;
    }
  
    function toFloat(n) {
      return parseFloat(n);
    }
  
    function toDate(n) {
      var matches, year, month, day;
      if (typeof n !== "object") {
        if (typeof n === "number") {
          n = new Date(n * 1000); // ms
        } else {
          n = toStr(n);
          if ((matches = n.match(DATE_PATTERN))) {
          year = parseInt(matches[1], 10);
          month = parseInt(matches[3], 10) - 1;
          day = parseInt(matches[5], 10);
          return new Date(year, month, day);
          } else { // str
            // try our best to get the str into iso8601
            // TODO be smarter about this
            var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
            n = parseISO8601(str) || new Date(n);
          }
        }
      }
      return n;
    }
  
    function toArr(n) {
      if (!isArray(n)) {
        var arr = [], i;
        for (i in n) {
          if (n.hasOwnProperty(i)) {
            arr.push([i, n[i]]);
          }
        }
        n = arr;
      }
      return n;
    }
  
    function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
      return function (chart, opts, chartOptions) {
        var series = chart.data;
        var options = merge({}, defaultOptions);
        options = merge(options, chartOptions || {});
  
        if (chart.hideLegend || "legend" in opts) {
          hideLegend(options, opts.legend, chart.hideLegend);
        }
  
        if (opts.title) {
          setTitle(options, opts.title);
        }
  
        // min
        if ("min" in opts) {
          setMin(options, opts.min);
        } else if (!negativeValues(series)) {
          setMin(options, 0);
        }
  
        // max
        if (opts.max) {
          setMax(options, opts.max);
        }
  
        if ("stacked" in opts) {
          setStacked(options, opts.stacked);
        }
  
        if (opts.colors) {
          options.colors = opts.colors;
        }
  
        if (opts.xtitle) {
          setXtitle(options, opts.xtitle);
        }
  
        if (opts.ytitle) {
          setYtitle(options, opts.ytitle);
        }
  
        // merge library last
        options = merge(options, opts.library || {});
  
        return options;
      };
    }
  
    function sortByTime(a, b) {
      return a[0].getTime() - b[0].getTime();
    }
  
    function sortByNumberSeries(a, b) {
      return a[0] - b[0];
    }
  
    function sortByNumber(a, b) {
      return a - b;
    }
  
    function isMinute(d) {
      return d.getMilliseconds() === 0 && d.getSeconds() === 0;
    }
  
    function isHour(d) {
      return isMinute(d) && d.getMinutes() === 0;
    }
  
    function isDay(d) {
      return isHour(d) && d.getHours() === 0;
    }
  
    function isWeek(d, dayOfWeek) {
      return isDay(d) && d.getDay() === dayOfWeek;
    }
  
    function isMonth(d) {
      return isDay(d) && d.getDate() === 1;
    }
  
    function isYear(d) {
      return isMonth(d) && d.getMonth() === 0;
    }
  
    function isDate(obj) {
      return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
    }
  
    function formatValue(pre, value, options) {
      pre = pre || "";
      if (options.prefix) {
        if (value < 0) {
          value = value * -1;
          pre += "-";
        }
        pre += options.prefix;
      }
  
      if (options.thousands || options.decimal) {
        value = toStr(value);
        var parts = value.split(".");
        value = parts[0];
        if (options.thousands) {
          value = value.replace(/\B(?=(\d{3})+(?!\d))/g, options.thousands);
        }
        if (parts.length > 1) {
          value += (options.decimal || ".") + parts[1];
        }
      }
  
      return pre + value + (options.suffix || "");
    }
  
    function allZeros(data) {
      var i, j, d;
      for (i = 0; i < data.length; i++) {
        d = data[i].data;
        for (j = 0; j < d.length; j++) {
          if (d[j][1] != 0) {
            return false;
          }
        }
      }
      return true;
    }
  
    var baseOptions = {
      maintainAspectRatio: false,
      animation: false,
      tooltips: {
        displayColors: false,
        callbacks: {}
      },
      legend: {},
      title: {fontSize: 20, fontColor: "#333"}
    };
  
    var defaultOptions = {
      scales: {
        yAxes: [
          {
            ticks: {
              maxTicksLimit: 4
            },
            scaleLabel: {
              fontSize: 16,
              // fontStyle: "bold",
              fontColor: "#333"
            }
          }
        ],
        xAxes: [
          {
            gridLines: {
              drawOnChartArea: false
            },
            scaleLabel: {
              fontSize: 16,
              // fontStyle: "bold",
              fontColor: "#333"
            },
            time: {},
            ticks: {}
          }
        ]
      }
    };
  
    // http://there4.io/2012/05/02/google-chart-color-list/
    var defaultColors = [
      "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
      "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
      "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
    ];
  
    var hideLegend = function (options, legend, hideLegend) {
      if (legend !== undefined) {
        options.legend.display = !!legend;
        if (legend && legend !== true) {
          options.legend.position = legend;
        }
      } else if (hideLegend) {
        options.legend.display = false;
      }
    };
  
    var setTitle = function (options, title) {
      options.title.display = true;
      options.title.text = title;
    };
  
    var setMin = function (options, min) {
      if (min !== null) {
        options.scales.yAxes[0].ticks.min = toFloat(min);
      }
    };
  
    var setMax = function (options, max) {
      options.scales.yAxes[0].ticks.max = toFloat(max);
    };
  
    var setBarMin = function (options, min) {
      if (min !== null) {
        options.scales.xAxes[0].ticks.min = toFloat(min);
      }
    };
  
    var setBarMax = function (options, max) {
      options.scales.xAxes[0].ticks.max = toFloat(max);
    };
  
    var setStacked = function (options, stacked) {
      options.scales.xAxes[0].stacked = !!stacked;
      options.scales.yAxes[0].stacked = !!stacked;
    };
  
    var setXtitle = function (options, title) {
      options.scales.xAxes[0].scaleLabel.display = true;
      options.scales.xAxes[0].scaleLabel.labelString = title;
    };
  
    var setYtitle = function (options, title) {
      options.scales.yAxes[0].scaleLabel.display = true;
      options.scales.yAxes[0].scaleLabel.labelString = title;
    };
  
    // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
    var addOpacity = function(hex, opacity) {
      var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
      return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
    };
  
    var setLabelSize = function (chart, data, options) {
      var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
      if (maxLabelSize > 25) {
        maxLabelSize = 25;
      }
      options.scales.xAxes[0].ticks.callback = function (value) {
        value = toStr(value);
        if (value.length > maxLabelSize) {
          return value.substring(0, maxLabelSize - 2) + "...";
        } else {
          return value;
        }
      };
    };
  
    var setFormatOptions = function(chart, options, chartType) {
      var formatOptions = {
        prefix: chart.options.prefix,
        suffix: chart.options.suffix,
        thousands: chart.options.thousands,
        decimal: chart.options.decimal
      };
  
      if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
        if (chartType !== "pie") {
          var myAxes = options.scales.yAxes;
          if (chartType === "bar") {
            myAxes = options.scales.xAxes;
          }
  
          if (!myAxes[0].ticks.callback) {
            myAxes[0].ticks.callback = function (value) {
              return formatValue("", value, formatOptions);
            };
          }
        }
  
        if (!options.tooltips.callbacks.label) {
          if (chartType !== "pie") {
            var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
            options.tooltips.callbacks.label = function (tooltipItem, data) {
              var label = data.datasets[tooltipItem.datasetIndex].label || '';
              if (label) {
                label += ': ';
              }
              return formatValue(label, tooltipItem[valueLabel], formatOptions);
            };
          } else {
            // need to use separate label for pie charts
            options.tooltips.callbacks.label = function (tooltipItem, data) {
              var dataLabel = data.labels[tooltipItem.index];
              var value = ': ';
  
              if (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 formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
            };
          }
        }
      }
    };
  
    var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
  
    var createDataTable = function (chart, options, chartType) {
      var datasets = [];
      var labels = [];
  
      var colors = chart.options.colors || defaultColors;
  
      var day = true;
      var week = true;
      var dayOfWeek;
      var month = true;
      var year = true;
      var hour = true;
      var minute = true;
      var detectType = (chartType === "line" || chartType === "area") && !chart.discrete;
  
      var series = chart.data;
  
      var sortedLabels = [];
  
      var i, j, s, d, key, rows = [];
      for (i = 0; i < series.length; i++) {
        s = series[i];
  
        for (j = 0; j < s.data.length; j++) {
          d = s.data[j];
          key = detectType ? d[0].getTime() : d[0];
          if (!rows[key]) {
            rows[key] = new Array(series.length);
          }
          rows[key][i] = toFloat(d[1]);
          if (sortedLabels.indexOf(key) === -1) {
            sortedLabels.push(key);
          }
        }
      }
  
      if (detectType || chart.options.xtype === "number") {
        sortedLabels.sort(sortByNumber);
      }
  
      var rows2 = [];
      for (j = 0; j < series.length; j++) {
        rows2.push([]);
      }
  
      var value;
      var k;
      for (k = 0; k < sortedLabels.length; k++) {
        i = sortedLabels[k];
        if (detectType) {
          value = new Date(toFloat(i));
          // TODO make this efficient
          day = day && isDay(value);
          if (!dayOfWeek) {
            dayOfWeek = value.getDay();
          }
          week = week && isWeek(value, dayOfWeek);
          month = month && isMonth(value);
          year = year && isYear(value);
          hour = hour && isHour(value);
          minute = minute && isMinute(value);
        } else {
          value = i;
        }
        labels.push(value);
        for (j = 0; j < series.length; j++) {
          // Chart.js doesn't like undefined
          rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
        }
      }
  
      for (i = 0; i < series.length; i++) {
        s = series[i];
  
        var color = s.color || colors[i];
        var backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
  
        var dataset = {
          label: s.name,
          data: rows2[i],
          fill: chartType === "area",
          borderColor: color,
          backgroundColor: backgroundColor,
          pointBackgroundColor: color,
          borderWidth: 2
        };
  
        if (s.stack) {
          dataset.stack = s.stack;
        }
  
        if (chart.options.curve === false) {
          dataset.lineTension = 0;
        }
  
        if (chart.options.points === false) {
          dataset.pointRadius = 0;
          dataset.pointHitRadius = 5;
        }
  
        datasets.push(merge(dataset, s.library || {}));
      }
  
      if (detectType && labels.length > 0) {
        var minTime = labels[0].getTime();
        var maxTime = labels[0].getTime();
        for (i = 1; i < labels.length; i++) {
          value = labels[i].getTime();
          if (value < minTime) {
            minTime = value;
          }
          if (value > maxTime) {
            maxTime = value;
          }
        }
  
        var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
  
        if (!options.scales.xAxes[0].time.unit) {
          var step;
          if (year || timeDiff > 365 * 10) {
            options.scales.xAxes[0].time.unit = "year";
            step = 365;
          } else if (month || timeDiff > 30 * 10) {
            options.scales.xAxes[0].time.unit = "month";
            step = 30;
          } else if (day || timeDiff > 10) {
            options.scales.xAxes[0].time.unit = "day";
            step = 1;
          } else if (hour || timeDiff > 0.5) {
            options.scales.xAxes[0].time.displayFormats = {hour: "MMM D, h a"};
            options.scales.xAxes[0].time.unit = "hour";
            step = 1 / 24.0;
          } else if (minute) {
            options.scales.xAxes[0].time.displayFormats = {minute: "h:mm a"};
            options.scales.xAxes[0].time.unit = "minute";
            step = 1 / 24.0 / 60.0;
          }
  
          if (step && timeDiff > 0) {
            var unitStepSize = Math.ceil(timeDiff / step / (chart.element.offsetWidth / 100.0));
            if (week && step === 1) {
              unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
            }
            options.scales.xAxes[0].time.unitStepSize = unitStepSize;
          }
        }
  
        if (!options.scales.xAxes[0].time.tooltipFormat) {
          if (day) {
            options.scales.xAxes[0].time.tooltipFormat = "ll";
          } else if (hour) {
            options.scales.xAxes[0].time.tooltipFormat = "MMM D, h a";
          } else if (minute) {
            options.scales.xAxes[0].time.tooltipFormat = "h:mm a";
          }
        }
      }
  
      var data = {
        labels: labels,
        datasets: datasets
      };
  
      return data;
    };
  
    var defaultExport = function defaultExport(library) {
      this.name = "chartjs";
      this.library = library;
    };
  
    defaultExport.prototype.renderLineChart = function renderLineChart (chart, chartType) {
      if (chart.options.xtype === "number") {
        return this.renderScatterChart(chart, chartType, true);
      }
  
      var chartOptions = {};
      // fix for https://github.com/chartjs/Chart.js/issues/2441
      if (!chart.options.max && allZeros(chart.data)) {
        chartOptions.max = 1;
      }
  
      var options = jsOptions(chart, merge(chartOptions, chart.options));
      setFormatOptions(chart, options, chartType);
  
      var data = createDataTable(chart, options, chartType || "line");
  
      options.scales.xAxes[0].type = chart.discrete ? "category" : "time";
  
      this.drawChart(chart, "line", data, options);
    };
  
    defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
      var options = merge({}, baseOptions);
      if (chart.options.donut) {
        options.cutoutPercentage = 50;
      }
  
      if ("legend" in chart.options) {
        hideLegend(options, chart.options.legend);
      }
  
      if (chart.options.title) {
        setTitle(options, chart.options.title);
      }
  
      options = merge(options, chart.options.library || {});
      setFormatOptions(chart, options, "pie");
  
      var labels = [];
      var values = [];
      for (var i = 0; i < chart.data.length; i++) {
        var point = chart.data[i];
        labels.push(point[0]);
        values.push(point[1]);
      }
  
      var data = {
        labels: labels,
        datasets: [
          {
            data: values,
            backgroundColor: chart.options.colors || defaultColors
          }
        ]
      };
  
      this.drawChart(chart, "pie", data, options);
    };
  
    defaultExport.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
      var options;
      if (chartType === "bar") {
        options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
      } else {
        options = jsOptions(chart, chart.options);
      }
      setFormatOptions(chart, options, chartType);
      var data = createDataTable(chart, options, "column");
      if (chartType !== "bar") {
        setLabelSize(chart, data, options);
      }
      this.drawChart(chart, (chartType === "bar" ? "horizontalBar" : "bar"), data, options);
    };
  
    defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
      this.renderLineChart(chart, "area");
    };
  
    defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
      this.renderColumnChart(chart, "bar");
    };
  
    defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType, lineChart) {
      chartType = chartType || "line";
  
      var options = jsOptions(chart, chart.options);
      if (!lineChart) {
        setFormatOptions(chart, options, chartType);
      }
  
      var colors = chart.options.colors || defaultColors;
  
      var datasets = [];
      var series = chart.data;
      for (var i = 0; i < series.length; i++) {
        var s = series[i];
        var d = [];
        for (var j = 0; j < s.data.length; j++) {
          var point = {
            x: toFloat(s.data[j][0]),
            y: toFloat(s.data[j][1])
          };
          if (chartType === "bubble") {
            point.r = toFloat(s.data[j][2]);
          }
          d.push(point);
        }
  
        var color = s.color || colors[i];
        var backgroundColor = chartType === "area" ? addOpacity(color, 0.5) : color;
  
        datasets.push({
          label: s.name,
          showLine: lineChart || false,
          data: d,
          borderColor: color,
          backgroundColor: backgroundColor,
          pointBackgroundColor: color,
          fill: chartType === "area"
        });
      }
  
      if (chartType === "area") {
        chartType = "line";
      }
  
      var data = {datasets: datasets};
  
      options.scales.xAxes[0].type = "linear";
      options.scales.xAxes[0].position = "bottom";
  
      this.drawChart(chart, chartType, data, options);
    };
  
    defaultExport.prototype.renderBubbleChart = function renderBubbleChart (chart) {
      this.renderScatterChart(chart, "bubble");
    };
  
    defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
      if (chart.chart) {
        chart.chart.destroy();
      }
  
      chart.element.innerHTML = "<canvas></canvas>";
      var ctx = chart.element.getElementsByTagName("CANVAS")[0];
      chart.chart = new this.library(ctx, {
        type: type,
        data: data,
        options: options
      });
    };
  
    var defaultOptions$1 = {
      chart: {},
      xAxis: {
        title: {
          text: null
        },
        labels: {
          style: {
            fontSize: "12px"
          }
        }
      },
      yAxis: {
        title: {
          text: null
        },
        labels: {
          style: {
            fontSize: "12px"
          }
        }
      },
      title: {
        text: null
      },
      credits: {
        enabled: false
      },
      legend: {
        borderWidth: 0
      },
      tooltip: {
        style: {
          fontSize: "12px"
        }
      },
      plotOptions: {
        areaspline: {},
        series: {
          marker: {}
        }
      }
    };
  
    var hideLegend$1 = function (options, legend, hideLegend) {
      if (legend !== undefined) {
        options.legend.enabled = !!legend;
        if (legend && legend !== true) {
          if (legend === "top" || legend === "bottom") {
            options.legend.verticalAlign = legend;
          } else {
            options.legend.layout = "vertical";
            options.legend.verticalAlign = "middle";
            options.legend.align = legend;
          }
        }
      } else if (hideLegend) {
        options.legend.enabled = false;
      }
    };
  
    var setTitle$1 = function (options, title) {
      options.title.text = title;
    };
  
    var setMin$1 = function (options, min) {
      options.yAxis.min = min;
    };
  
    var setMax$1 = function (options, max) {
      options.yAxis.max = max;
    };
  
    var setStacked$1 = function (options, stacked) {
      options.plotOptions.series.stacking = stacked ? (stacked === true ? "normal" : stacked) : null;
    };
  
    var setXtitle$1 = function (options, title) {
      options.xAxis.title.text = title;
    };
  
    var setYtitle$1 = function (options, title) {
      options.yAxis.title.text = title;
    };
  
    var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
  
    var setFormatOptions$1 = function(chart, options, chartType) {
      var formatOptions = {
        prefix: chart.options.prefix,
        suffix: chart.options.suffix,
        thousands: chart.options.thousands,
        decimal: chart.options.decimal
      };
  
      if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
        if (chartType !== "pie" && !options.yAxis.labels.formatter) {
          options.yAxis.labels.formatter = function () {
            return formatValue("", this.value, formatOptions);
          };
        }
  
        if (!options.tooltip.pointFormatter) {
          options.tooltip.pointFormatter = function () {
            return '<span style="color:' + this.color + '>\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
          };
        }
      }
    };
  
    var defaultExport$1 = function defaultExport(library) {
      this.name = "highcharts";
      this.library = library;
    };
  
    defaultExport$1.prototype.renderLineChart = function renderLineChart (chart, chartType) {
      chartType = chartType || "spline";
      var chartOptions = {};
      if (chartType === "areaspline") {
        chartOptions = {
          plotOptions: {
            areaspline: {
              stacking: "normal"
            },
            area: {
              stacking: "normal"
            },
            series: {
              marker: {
                enabled: false
              }
            }
          }
        };
      }
  
      if (chart.options.curve === false) {
        if (chartType === "areaspline") {
          chartType = "area";
        } else if (chartType === "spline") {
          chartType = "line";
        }
      }
  
      var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
      options.xAxis.type = chart.discrete ? "category" : "datetime";
      if (!options.chart.type) {
        options.chart.type = chartType;
      }
      setFormatOptions$1(chart, options, chartType);
  
      var series = chart.data;
      for (i = 0; i < series.length; i++) {
        data = series[i].data;
        if (!chart.discrete) {
          for (j = 0; j < data.length; j++) {
            data[j][0] = data[j][0].getTime();
          }
        }
        series[i].marker = {symbol: "circle"};
        if (chart.options.points === false) {
          series[i].marker.enabled = false;
        }
      }
  
      this.drawChart(chart, series, options);
    };
  
    defaultExport$1.prototype.renderScatterChart = function renderScatterChart (chart) {
      var options = jsOptions$1(chart, chart.options, {});
      options.chart.type = "scatter";
      this.drawChart(chart, chart.data, options);
    };
  
    defaultExport$1.prototype.renderPieChart = function renderPieChart (chart) {
      var chartOptions = merge(defaultOptions$1, {});
  
      if (chart.options.colors) {
        chartOptions.colors = chart.options.colors;
      }
      if (chart.options.donut) {
        chartOptions.plotOptions = {pie: {innerSize: "50%"}};
      }
  
      if ("legend" in chart.options) {
        hideLegend$1(chartOptions, chart.options.legend);
      }
  
      if (chart.options.title) {
        setTitle$1(chartOptions, chart.options.title);
      }
  
      var options = merge(chartOptions, chart.options.library || {});
      setFormatOptions$1(chart, options, "pie");
      var series = [{
        type: "pie",
        name: chart.options.label || "Value",
        data: chart.data
      }];
  
      this.drawChart(chart, series, options);
    };
  
    defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
      chartType = chartType || "column";
      var series = chart.data;
      var options = jsOptions$1(chart, chart.options), i, j, s, d, rows = [], categories = [];
      options.chart.type = chartType;
      setFormatOptions$1(chart, options, chartType);
  
      for (i = 0; i < series.length; i++) {
        s = series[i];
  
        for (j = 0; j < s.data.length; j++) {
          d = s.data[j];
          if (!rows[d[0]]) {
            rows[d[0]] = new Array(series.length);
            categories.push(d[0]);
          }
          rows[d[0]][i] = d[1];
        }
      }
  
      if (chart.options.xtype === "number") {
        categories.sort(sortByNumber);
      }
  
      options.xAxis.categories = categories;
  
      var newSeries = [], d2;
      for (i = 0; i < series.length; i++) {
        d = [];
        for (j = 0; j < categories.length; j++) {
          d.push(rows[categories[j]][i] || 0);
        }
  
        d2 = {
          name: series[i].name,
          data: d
        };
        if (series[i].stack) {
          d2.stack = series[i].stack;
        }
  
        newSeries.push(d2);
      }
  
      this.drawChart(chart, newSeries, options);
    };
  
    defaultExport$1.prototype.renderBarChart = function renderBarChart (chart) {
      this.renderColumnChart(chart, "bar");
    };
  
    defaultExport$1.prototype.renderAreaChart = function renderAreaChart (chart) {
      this.renderLineChart(chart, "areaspline");
    };
  
    defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
      if (chart.chart) {
        chart.chart.destroy();
      }
  
      options.chart.renderTo = chart.element.id;
      options.series = data;
      chart.chart = new this.library.Chart(options);
    };
  
    var loaded = {};
    var callbacks = [];
  
    // Set chart options
    var defaultOptions$2 = {
      chartArea: {},
      fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
      pointSize: 6,
      legend: {
        textStyle: {
          fontSize: 12,
          color: "#444"
        },
        alignment: "center",
        position: "right"
      },
      curveType: "function",
      hAxis: {
        textStyle: {
          color: "#666",
          fontSize: 12
        },
        titleTextStyle: {},
        gridlines: {
          color: "transparent"
        },
        baselineColor: "#ccc",
        viewWindow: {}
      },
      vAxis: {
        textStyle: {
          color: "#666",
          fontSize: 12
        },
        titleTextStyle: {},
        baselineColor: "#ccc",
        viewWindow: {}
      },
      tooltip: {
        textStyle: {
          color: "#666",
          fontSize: 12
        }
      }
    };
  
    var hideLegend$2 = function (options, legend, hideLegend) {
      if (legend !== undefined) {
        var position;
        if (!legend) {
          position = "none";
        } else if (legend === true) {
          position = "right";
        } else {
          position = legend;
        }
        options.legend.position = position;
      } else if (hideLegend) {
        options.legend.position = "none";
      }
    };
  
    var setTitle$2 = function (options, title) {
      options.title = title;
      options.titleTextStyle = {color: "#333", fontSize: "20px"};
    };
  
    var setMin$2 = function (options, min) {
      options.vAxis.viewWindow.min = min;
    };
  
    var setMax$2 = function (options, max) {
      options.vAxis.viewWindow.max = max;
    };
  
    var setBarMin$1 = function (options, min) {
      options.hAxis.viewWindow.min = min;
    };
  
    var setBarMax$1 = function (options, max) {
      options.hAxis.viewWindow.max = max;
    };
  
    var setStacked$2 = function (options, stacked) {
      options.isStacked = stacked ? stacked : false;
    };
  
    var setXtitle$2 = function (options, title) {
      options.hAxis.title = title;
      options.hAxis.titleTextStyle.italic = false;
    };
  
    var setYtitle$2 = function (options, title) {
      options.vAxis.title = title;
      options.vAxis.titleTextStyle.italic = false;
    };
  
    var jsOptions$2 = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
  
    var resize = function (callback) {
      if (window.attachEvent) {
        window.attachEvent("onresize", callback);
      } else if (window.addEventListener) {
        window.addEventListener("resize", callback, true);
      }
      callback();
    };
  
    var defaultExport$2 = function defaultExport(library) {
      this.name = "google";
      this.library = library;
    };
  
    defaultExport$2.prototype.renderLineChart = function renderLineChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {};
  
        if (chart.options.curve === false) {
          chartOptions.curveType = "none";
        }
  
        if (chart.options.points === false) {
          chartOptions.pointSize = 0;
        }
  
        var options = jsOptions$2(chart, chart.options, chartOptions);
        var columnType = chart.discrete ? "string" : "datetime";
        if (chart.options.xtype === "number") {
          columnType = "number";
        }
        var data = this$1.createDataTable(chart.data, columnType);
  
        this$1.drawChart(chart, this$1.library.visualization.LineChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {
          chartArea: {
            top: "10%",
            height: "80%"
          },
          legend: {}
        };
        if (chart.options.colors) {
          chartOptions.colors = chart.options.colors;
        }
        if (chart.options.donut) {
          chartOptions.pieHole = 0.5;
        }
        if ("legend" in chart.options) {
          hideLegend$2(chartOptions, chart.options.legend);
        }
        if (chart.options.title) {
          setTitle$2(chartOptions, chart.options.title);
        }
        var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
  
        var data = new this$1.library.visualization.DataTable();
        data.addColumn("string", "");
        data.addColumn("number", "Value");
        data.addRows(chart.data);
  
        this$1.drawChart(chart, this$1.library.visualization.PieChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var options = jsOptions$2(chart, chart.options);
        var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
  
        this$1.drawChart(chart, this$1.library.visualization.ColumnChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {
          hAxis: {
            gridlines: {
              color: "#ccc"
            }
          }
        };
        var options = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options, chartOptions);
        var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
  
        this$1.drawChart(chart, this$1.library.visualization.BarChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {
          isStacked: true,
          pointSize: 0,
          areaOpacity: 0.5
        };
  
        var options = jsOptions$2(chart, chart.options, chartOptions);
        var columnType = chart.discrete ? "string" : "datetime";
        if (chart.options.xtype === "number") {
          columnType = "number";
        }
        var data = this$1.createDataTable(chart.data, columnType);
  
        this$1.drawChart(chart, this$1.library.visualization.AreaChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderGeoChart = function renderGeoChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {
          legend: "none",
          colorAxis: {
            colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
          }
        };
        var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
  
        var data = new this$1.library.visualization.DataTable();
        data.addColumn("string", "");
        data.addColumn("number", chart.options.label || "Value");
        data.addRows(chart.data);
  
        this$1.drawChart(chart, this$1.library.visualization.GeoChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, function () {
        var chartOptions = {};
        var options = jsOptions$2(chart, chart.options, chartOptions);
  
        var series = chart.data, rows2 = [], i, j, data, d;
        for (i = 0; i < series.length; i++) {
          d = series[i].data;
          for (j = 0; j < d.length; j++) {
            var row = new Array(series.length + 1);
            row[0] = d[j][0];
            row[i + 1] = d[j][1];
            rows2.push(row);
          }
        }
  
        data = new this$1.library.visualization.DataTable();
        data.addColumn("number", "");
        for (i = 0; i < series.length; i++) {
          data.addColumn("number", series[i].name);
        }
        data.addRows(rows2);
  
        this$1.drawChart(chart, this$1.library.visualization.ScatterChart, data, options);
      });
    };
  
    defaultExport$2.prototype.renderTimeline = function renderTimeline (chart) {
        var this$1 = this;
  
      this.waitForLoaded(chart, "timeline", function () {
        var chartOptions = {
          legend: "none"
        };
  
        if (chart.options.colors) {
          chartOptions.colors = chart.options.colors;
        }
        var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
  
        var data = new this$1.library.visualization.DataTable();
        data.addColumn({type: "string", id: "Name"});
        data.addColumn({type: "date", id: "Start"});
        data.addColumn({type: "date", id: "End"});
        data.addRows(chart.data);
  
        chart.element.style.lineHeight = "normal";
  
        this$1.drawChart(chart, this$1.library.visualization.Timeline, data, options);
      });
    };
  
    defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
      if (chart.chart) {
        chart.chart.clearChart();
      }
  
      chart.chart = new type(chart.element);
      resize(function () {
        chart.chart.draw(data, options);
      });
    };
  
    defaultExport$2.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
        var this$1 = this;
  
      if (!callback) {
        callback = pack;
        pack = "corechart";
      }
  
      callbacks.push({pack: pack, callback: callback});
  
      if (loaded[pack]) {
        this.runCallbacks();
      } else {
        loaded[pack] = true;
  
        // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
        var loadOptions = {
          packages: [pack],
          callback: function () { this$1.runCallbacks(); }
        };
        var config = chart.__config();
        if (config.language) {
          loadOptions.language = config.language;
        }
        if (pack === "corechart" && config.mapsApiKey) {
          loadOptions.mapsApiKey = config.mapsApiKey;
        }
  
        if (this.library.setOnLoadCallback) {
          this.library.load("visualization", "1", loadOptions);
        } else {
          this.library.charts.load("current", loadOptions);
        }
      }
    };
  
    defaultExport$2.prototype.runCallbacks = function runCallbacks () {
        var this$1 = this;
  
      var cb, call;
      for (var i = 0; i < callbacks.length; i++) {
        cb = callbacks[i];
        call = this$1.library.visualization && ((cb.pack === "corechart" && this$1.library.visualization.LineChart) || (cb.pack === "timeline" && this$1.library.visualization.Timeline));
        if (call) {
          cb.callback();
          callbacks.splice(i, 1);
          i--;
        }
      }
    };
  
    // cant use object as key
    defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType, xtype) {
      var i, j, s, d, key, rows = [], sortedLabels = [];
      for (i = 0; i < series.length; i++) {
        s = series[i];
  
        for (j = 0; j < s.data.length; j++) {
          d = s.data[j];
          key = (columnType === "datetime") ? d[0].getTime() : d[0];
          if (!rows[key]) {
            rows[key] = new Array(series.length);
            sortedLabels.push(key);
          }
          rows[key][i] = toFloat(d[1]);
        }
      }
  
      var rows2 = [];
      var day = true;
      var value;
      for (j = 0; j < sortedLabels.length; j++) {
        i = sortedLabels[j];
        if (columnType === "datetime") {
          value = new Date(toFloat(i));
          day = day && isDay(value);
        } else if (columnType === "number") {
          value = toFloat(i);
        } else {
          value = i;
        }
        rows2.push([value].concat(rows[i]));
      }
      if (columnType === "datetime") {
        rows2.sort(sortByTime);
      } else if (columnType === "number") {
        rows2.sort(sortByNumberSeries);
      }
  
      if (xtype === "number") {
        rows2.sort(sortByNumberSeries);
  
        for (i = 0; i < rows2.length; i++) {
          rows2[i][0] = toStr(rows2[i][0]);
        }
      }
  
      // create datatable
      var data = new this.library.visualization.DataTable();
      columnType = columnType === "datetime" && day ? "date" : columnType;
      data.addColumn(columnType, "");
      for (i = 0; i < series.length; i++) {
        data.addColumn("number", series[i].name);
      }
      data.addRows(rows2);
  
      return data;
    };
  
    var pendingRequests = [], runningRequests = 0, maxRequests = 4;
  
    function pushRequest(url, success, error) {
      pendingRequests.push([url, success, error]);
      runNext();
    }
  
    function runNext() {
      if (runningRequests < maxRequests) {
        var request = pendingRequests.shift();
        if (request) {
          runningRequests++;
          getJSON(request[0], request[1], request[2]);
          runNext();
        }
      }
    }
  
    function requestComplete() {
      runningRequests--;
      runNext();
    }
  
    function getJSON(url, success, error) {
      ajaxCall(url, success, function (jqXHR, textStatus, errorThrown) {
        var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
        error(message);
      });
    }
  
    function ajaxCall(url, success, error) {
      var $ = window.jQuery || window.Zepto || window.$;
  
      if ($) {
        $.ajax({
          dataType: "json",
          url: url,
          success: success,
          error: error,
          complete: requestComplete
        });
      } else {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.onload = function () {
          requestComplete();
          if (xhr.status === 200) {
            success(JSON.parse(xhr.responseText), xhr.statusText, xhr);
          } else {
            error(xhr, "error", xhr.statusText);
          }
        };
        xhr.send();
      }
    }
  
    var config = (typeof window !== "undefined" && window.Chartkick) || {};
    var adapters = [];
  
    // helpers
  
    function setText(element, text) {
      if (document.body.innerText) {
        element.innerText = text;
      } else {
        element.textContent = text;
      }
    }
  
    function chartError(element, message) {
      setText(element, "Error Loading Chart: " + message);
      element.style.color = "#ff0000";
    }
  
    function errorCatcher(chart) {
      try {
        chart.__render();
      } catch (err) {
        chartError(chart.element, err.message);
        throw err;
      }
    }
  
    function fetchDataSource(chart, dataSource) {
      if (typeof dataSource === "string") {
        pushRequest(dataSource, function (data) {
          chart.rawData = data;
          errorCatcher(chart);
        }, function (message) {
          chartError(chart.element, message);
        });
      } else {
        chart.rawData = dataSource;
        errorCatcher(chart);
      }
    }
  
    function addDownloadButton(chart) {
      var element = chart.element;
      var link = document.createElement("a");
      link.download = chart.options.download === true ? "chart.png" : chart.options.download; // http://caniuse.com/download
      link.style.position = "absolute";
      link.style.top = "20px";
      link.style.right = "20px";
      link.style.zIndex = 1000;
      link.style.lineHeight = "20px";
      link.target = "_blank"; // for safari
      var image = document.createElement("img");
      image.alt = "Download";
      image.style.border = "none";
      // icon from font-awesome
      // http://fa2png.io/
      image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
      link.appendChild(image);
      element.style.position = "relative";
  
      chart.downloadAttached = true;
  
      // mouseenter
      addEvent(element, "mouseover", function(e) {
        var related = e.relatedTarget;
        // check download option again to ensure it wasn't changed
        if (!related || (related !== this && !childOf(this, related)) && chart.options.download) {
          link.href = chart.toImage();
          element.appendChild(link);
        }
      });
  
      // mouseleave
      addEvent(element, "mouseout", function(e) {
        var related = e.relatedTarget;
        if (!related || (related !== this && !childOf(this, related))) {
          if (link.parentNode) {
            link.parentNode.removeChild(link);
          }
        }
      });
    }
  
    // http://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
    function addEvent(elem, event, fn) {
      if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
      } else {
        elem.attachEvent("on" + event, function() {
          // set the this pointer same as addEventListener when fn is called
          return(fn.call(elem, window.event));
        });
      }
    }
  
    // https://gist.github.com/shawnbot/4166283
    function childOf(p, c) {
      if (p === c) { return false; }
      while (c && c !== p) { c = c.parentNode; }
      return c === p;
    }
  
    function getAdapterType(library) {
      if (library) {
        if (library.product === "Highcharts") {
          return defaultExport$1;
        } else if (library.setOnLoadCallback || library.charts) {
          return defaultExport$2;
        } else if (isFunction(library)) {
          return defaultExport;
        }
      }
      throw new Error("Unknown adapter");
    }
  
    function addAdapter(library) {
      var adapterType = getAdapterType(library);
      var adapter = new adapterType(library);
  
      if (adapters.indexOf(adapter) === -1) {
        adapters.push(adapter);
      }
    }
  
    function loadAdapters() {
      if ("Chart" in window) {
        addAdapter(window.Chart);
      }
  
      if ("Highcharts" in window) {
        addAdapter(window.Highcharts);
      }
  
      if (window.google && (window.google.setOnLoadCallback || window.google.charts)) {
        addAdapter(window.google);
      }
    }
  
    function dataEmpty(data, chartType) {
      if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
        return data.length === 0;
      } else {
        for (var i = 0; i < data.length; i++) {
          if (data[i].data.length > 0) {
            return false;
          }
        }
        return true;
      }
    }
  
    function renderChart(chartType, chart) {
      if (chart.options.messages && chart.options.messages.empty && dataEmpty(chart.data, chartType)) {
        setText(chart.element, chart.options.messages.empty);
      } else {
        callAdapter(chartType, chart);
        if (chart.options.download && !chart.downloadAttached && chart.adapter === "chartjs") {
          addDownloadButton(chart);
        }
      }
    }
  
    // TODO remove chartType if cross-browser way
    // to get the name of the chart class
    function callAdapter(chartType, chart) {
      var i, adapter, fnName, adapterName;
      fnName = "render" + chartType;
      adapterName = chart.options.adapter;
  
      loadAdapters();
  
      for (i = 0; i < adapters.length; i++) {
        adapter = adapters[i];
        if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
          chart.adapter = adapter.name;
          return adapter[fnName](chart);
        }
      }
  
      if (adapters.length > 0) {
        throw new Error("No charting library found for " + chartType);
      } else {
        throw new Error("No charting libraries found - be sure to include one before your charts");
      }
    }
  
    // process data
  
    var toFormattedKey = function (key, keyType) {
      if (keyType === "number") {
        key = toFloat(key);
      } else if (keyType === "datetime") {
        key = toDate(key);
      } else {
        key = toStr(key);
      }
      return key;
    };
  
    var formatSeriesData = function (data, keyType) {
      var r = [], key, j;
      for (j = 0; j < data.length; j++) {
        if (keyType === "bubble") {
          r.push([toFloat(data[j][0]), toFloat(data[j][1]), toFloat(data[j][2])]);
        } else {
          key = toFormattedKey(data[j][0], keyType);
          r.push([key, toFloat(data[j][1])]);
        }
      }
      if (keyType === "datetime") {
        r.sort(sortByTime);
      } else if (keyType === "number") {
        r.sort(sortByNumberSeries);
      }
      return r;
    };
  
    function detectDiscrete(series) {
      var i, j, data;
      for (i = 0; i < series.length; i++) {
        data = toArr(series[i].data);
        for (j = 0; j < data.length; j++) {
          if (!isDate(data[j][0])) {
            return true;
          }
        }
      }
      return false;
    }
  
    // creates a shallow copy of each element of the array
    // elements are expected to be objects
    function copySeries(series) {
      var newSeries = [], i, j;
      for (i = 0; i < series.length; i++) {
        var copy = {};
        for (j in series[i]) {
          if (series[i].hasOwnProperty(j)) {
            copy[j] = series[i][j];
          }
        }
        newSeries.push(copy);
      }
      return newSeries;
    }
  
    function processSeries(chart, keyType) {
      var i;
  
      var opts = chart.options;
      var series = chart.rawData;
  
      // see if one series or multiple
      if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
        series = [{name: opts.label || "Value", data: series}];
        chart.hideLegend = true;
      } else {
        chart.hideLegend = false;
      }
      if ((opts.discrete === null || opts.discrete === undefined) && keyType !== "bubble" && keyType !== "number") {
        chart.discrete = detectDiscrete(series);
      } else {
        chart.discrete = opts.discrete;
      }
      if (chart.discrete) {
        keyType = "string";
      }
      if (chart.options.xtype) {
        keyType = chart.options.xtype;
      }
  
      // right format
      series = copySeries(series);
      for (i = 0; i < series.length; i++) {
        series[i].data = formatSeriesData(toArr(series[i].data), keyType);
      }
  
      return series;
    }
  
    function processSimple(chart) {
      var perfectData = toArr(chart.rawData), i;
      for (i = 0; i < perfectData.length; i++) {
        perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
      }
      return perfectData;
    }
  
    // define classes
  
    var Chart = function Chart(element, dataSource, options) {
      var elementId;
      if (typeof element === "string") {
        elementId = element;
        element = document.getElementById(element);
        if (!element) {
          throw new Error("No element with id " + elementId);
        }
      }
      this.element = element;
      this.options = merge(Chartkick.options, options || {});
      this.dataSource = dataSource;
  
      Chartkick.charts[element.id] = this;
  
      fetchDataSource(this, dataSource);
  
      if (this.options.refresh) {
        this.startRefresh();
      }
    };
  
    Chart.prototype.getElement = function getElement () {
      return this.element;
    };
  
    Chart.prototype.getDataSource = function getDataSource () {
      return this.dataSource;
    };
  
    Chart.prototype.getData = function getData () {
      return this.data;
    };
  
    Chart.prototype.getOptions = function getOptions () {
      return this.options;
    };
  
    Chart.prototype.getChartObject = function getChartObject () {
      return this.chart;
    };
  
    Chart.prototype.getAdapter = function getAdapter () {
      return this.adapter;
    };
  
    Chart.prototype.updateData = function updateData (dataSource, options) {
      this.dataSource = dataSource;
      if (options) {
        this.__updateOptions(options);
      }
      fetchDataSource(this, dataSource);
    };
  
    Chart.prototype.setOptions = function setOptions (options) {
      this.__updateOptions(options);
      this.redraw();
    };
  
    Chart.prototype.redraw = function redraw () {
      fetchDataSource(this, this.rawData);
    };
  
    Chart.prototype.refreshData = function refreshData () {
      if (typeof this.dataSource === "string") {
        // prevent browser from caching
        var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
        var url = this.dataSource + sep + "_=" + (new Date()).getTime();
        fetchDataSource(this, url);
      }
    };
  
    Chart.prototype.startRefresh = function startRefresh () {
        var this$1 = this;
  
      var refresh = this.options.refresh;
  
      if (!this.intervalId) {
        if (refresh) {
          this.intervalId = setInterval( function () {
            this$1.refreshData();
          }, refresh * 1000);
        } else {
          throw new Error("No refresh interval");
        }
      }
    };
  
    Chart.prototype.stopRefresh = function stopRefresh () {
      if (this.intervalId) {
        clearInterval(this.intervalId);
        this.intervalId = null;
      }
    };
  
    Chart.prototype.toImage = function toImage () {
      if (this.adapter === "chartjs") {
        return this.chart.toBase64Image();
      } else {
        return null;
      }
    };
  
    Chart.prototype.__updateOptions = function __updateOptions (options) {
      var updateRefresh = options.refresh && options.refresh !== this.options.refresh;
      this.options = merge(Chartkick.options, options);
      if (updateRefresh) {
        this.stopRefresh();
        this.startRefresh();
      }
    };
  
    Chart.prototype.__render = function __render () {
      this.data = this.__processData();
      renderChart(this.__chartName(), this);
    };
  
    Chart.prototype.__config = function __config () {
      return config;
    };
  
    var LineChart = (function (Chart) {
      function LineChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { LineChart.__proto__ = Chart; }
      LineChart.prototype = Object.create( Chart && Chart.prototype );
      LineChart.prototype.constructor = LineChart;
  
      LineChart.prototype.__processData = function __processData () {
        return processSeries(this, "datetime");
      };
  
      LineChart.prototype.__chartName = function __chartName () {
        return "LineChart";
      };
  
      return LineChart;
    }(Chart));
  
    var PieChart = (function (Chart) {
      function PieChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { PieChart.__proto__ = Chart; }
      PieChart.prototype = Object.create( Chart && Chart.prototype );
      PieChart.prototype.constructor = PieChart;
  
      PieChart.prototype.__processData = function __processData () {
        return processSimple(this);
      };
  
      PieChart.prototype.__chartName = function __chartName () {
        return "PieChart";
      };
  
      return PieChart;
    }(Chart));
  
    var ColumnChart = (function (Chart) {
      function ColumnChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { ColumnChart.__proto__ = Chart; }
      ColumnChart.prototype = Object.create( Chart && Chart.prototype );
      ColumnChart.prototype.constructor = ColumnChart;
  
      ColumnChart.prototype.__processData = function __processData () {
        return processSeries(this, "string");
      };
  
      ColumnChart.prototype.__chartName = function __chartName () {
        return "ColumnChart";
      };
  
      return ColumnChart;
    }(Chart));
  
    var BarChart = (function (Chart) {
      function BarChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { BarChart.__proto__ = Chart; }
      BarChart.prototype = Object.create( Chart && Chart.prototype );
      BarChart.prototype.constructor = BarChart;
  
      BarChart.prototype.__processData = function __processData () {
        return processSeries(this, "string");
      };
  
      BarChart.prototype.__chartName = function __chartName () {
        return "BarChart";
      };
  
      return BarChart;
    }(Chart));
  
    var AreaChart = (function (Chart) {
      function AreaChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { AreaChart.__proto__ = Chart; }
      AreaChart.prototype = Object.create( Chart && Chart.prototype );
      AreaChart.prototype.constructor = AreaChart;
  
      AreaChart.prototype.__processData = function __processData () {
        return processSeries(this, "datetime");
      };
  
      AreaChart.prototype.__chartName = function __chartName () {
        return "AreaChart";
      };
  
      return AreaChart;
    }(Chart));
  
    var GeoChart = (function (Chart) {
      function GeoChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { GeoChart.__proto__ = Chart; }
      GeoChart.prototype = Object.create( Chart && Chart.prototype );
      GeoChart.prototype.constructor = GeoChart;
  
      GeoChart.prototype.__processData = function __processData () {
        return processSimple(this);
      };
  
      GeoChart.prototype.__chartName = function __chartName () {
        return "GeoChart";
      };
  
      return GeoChart;
    }(Chart));
  
    var ScatterChart = (function (Chart) {
      function ScatterChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { ScatterChart.__proto__ = Chart; }
      ScatterChart.prototype = Object.create( Chart && Chart.prototype );
      ScatterChart.prototype.constructor = ScatterChart;
  
      ScatterChart.prototype.__processData = function __processData () {
        return processSeries(this, "number");
      };
  
      ScatterChart.prototype.__chartName = function __chartName () {
        return "ScatterChart";
      };
  
      return ScatterChart;
    }(Chart));
  
    var BubbleChart = (function (Chart) {
      function BubbleChart () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { BubbleChart.__proto__ = Chart; }
      BubbleChart.prototype = Object.create( Chart && Chart.prototype );
      BubbleChart.prototype.constructor = BubbleChart;
  
      BubbleChart.prototype.__processData = function __processData () {
        return processSeries(this, "bubble");
      };
  
      BubbleChart.prototype.__chartName = function __chartName () {
        return "BubbleChart";
      };
  
      return BubbleChart;
    }(Chart));
  
    var Timeline = (function (Chart) {
      function Timeline () {
        Chart.apply(this, arguments);
      }
  
      if ( Chart ) { Timeline.__proto__ = Chart; }
      Timeline.prototype = Object.create( Chart && Chart.prototype );
      Timeline.prototype.constructor = Timeline;
  
      Timeline.prototype.__processData = function __processData () {
        var i, data = this.rawData;
        for (i = 0; i < data.length; i++) {
          data[i][1] = toDate(data[i][1]);
          data[i][2] = toDate(data[i][2]);
        }
        return data;
      };
  
      Timeline.prototype.__chartName = function __chartName () {
        return "Timeline";
      };
  
      return Timeline;
    }(Chart));
  
    var Chartkick = {
      LineChart: LineChart,
      PieChart: PieChart,
      ColumnChart: ColumnChart,
      BarChart: BarChart,
      AreaChart: AreaChart,
      GeoChart: GeoChart,
      ScatterChart: ScatterChart,
      BubbleChart: BubbleChart,
      Timeline: Timeline,
      charts: {},
      configure: function (options) {
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            config[key] = options[key];
          }
        }
      },
      eachChart: function (callback) {
        for (var chartId in Chartkick.charts) {
          if (Chartkick.charts.hasOwnProperty(chartId)) {
            callback(Chartkick.charts[chartId]);
          }
        }
      },
      config: config,
      options: {},
      adapters: adapters,
      addAdapter: addAdapter
    };
  
    var chartId = 1;
  
    var ChartComponent = (function (superclass) {
      function ChartComponent () {
        superclass.apply(this, arguments);
      }
  
      if ( superclass ) ChartComponent.__proto__ = superclass;
      ChartComponent.prototype = Object.create( superclass && superclass.prototype );
      ChartComponent.prototype.constructor = ChartComponent;
  
      ChartComponent.prototype.newChartType = function newChartType (props) {
        var data = props.data;
        var options = {};
        for (var prop in props) {
          if (props.hasOwnProperty(prop) && prop !== "data" && prop !== "id" && prop !== "height" && prop !== "width") {
            options[prop] = props[prop];
          }
        }
        if (this.element) {
          new props.chartType(this.element, data, options);
        }
      };
  
      ChartComponent.prototype.componentDidMount = function componentDidMount () {
        this.newChartType(this.props);
      };
  
      ChartComponent.prototype.componentDidUpdate = function componentDidUpdate () {
        this.newChartType(this.props);
      };
  
      ChartComponent.prototype.render = function render () {
        var this$1 = this;
  
        var props = this.props;
        var style = {
          height: props.height || "300px",
          lineHeight: props.height || "300px",
          width: props.width || "100%",
          textAlign: "center",
          color: "#999",
          fontSize: "14px",
          fontFamily: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif"
        };
        this.chartId = props.id || this.chartId || ("chart-" + chartId++);
        return (
          React.createElement("div", {id: this.chartId, style: style, ref: function (element) { return this$1.element = element; }},
            "Loading..."
          )
        )
      };
  
      return ChartComponent;
    }(React.Component));
  
    var createComponent = function (chartType) {
      return function (props) {
        return React.createElement(ChartComponent, Object.assign({}, props, {chartType: chartType}))
      }
    };
  
    var LineChart$1 = createComponent(Chartkick.LineChart);
    var PieChart$1 = createComponent(Chartkick.PieChart);
    var ColumnChart$1 = createComponent(Chartkick.ColumnChart);
    var BarChart$1 = createComponent(Chartkick.BarChart);
    var AreaChart$1 = createComponent(Chartkick.AreaChart);
    var ScatterChart$1 = createComponent(Chartkick.ScatterChart);
    var GeoChart$1 = createComponent(Chartkick.GeoChart);
    var Timeline$1 = createComponent(Chartkick.Timeline);
  
    var index = {
      addAdapter: function(library) {
        Chartkick.addAdapter(library);
      }
    }
  
    exports.LineChart = LineChart$1;
    exports.PieChart = PieChart$1;
    exports.ColumnChart = ColumnChart$1;
    exports.BarChart = BarChart$1;
    exports.AreaChart = AreaChart$1;
    exports.ScatterChart = ScatterChart$1;
    exports.GeoChart = GeoChart$1;
    exports.Timeline = Timeline$1;
    exports.default = index;
  
    Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  