text: (function () {
      'use strict';
    
      if (typeof Chart === 'undefined') {
          console.error('Can not find Chart object.');
          return;
      }
    
      if (typeof Object.assign != 'function') {
          Object.assign = function (target, varArgs) {
              if (target == null) {
                  throw new TypeError('Cannot convert undefined or null to object');
              }
              var to = Object(target);
              for (var index = 1; index < arguments.length; index++) {
                  var nextSource = arguments[index];
                  if (nextSource != null) {
                      for (var nextKey in nextSource) {
                          if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                              to[nextKey] = nextSource[nextKey];
                          }
                      }
                  }
              }
              return to;
          };
      }
    
      var SUPPORTED_TYPES = {};
      ['pie', 'doughnut', 'polarArea', 'bar'].forEach(function (t) {
          SUPPORTED_TYPES[t] = true;
      });
    
      function Label() {
          this.renderToDataset = this.renderToDataset.bind(this);
      }
    
      Label.prototype.setup = function (chart, options) {
          this.chart = chart;
          this.ctx = chart.ctx;
          this.args = {};
          this.barTotal = {};
          var chartOptions = chart.config.options;
          this.options = Object.assign({
              position: 'default',
              precision: 0,
              fontSize: chartOptions.defaultFontSize,
              fontColor: chartOptions.defaultFontColor,
              fontStyle: chartOptions.defaultFontStyle,
              fontFamily: chartOptions.defaultFontFamily,
              shadowOffsetX: 3,
              shadowOffsetY: 3,
              shadowColor: 'rgba(0,0,0,0.3)',
              shadowBlur: 6,
              images: [],
              outsidePadding: 2,
              textMargin: 2,
              overlap: true
          }, options);
          if (chart.config.type === 'bar') {
              this.options.position = 'default';
              this.options.arc = false;
              this.options.overlap = true;
          }
      };
    
      Label.prototype.render = function () {
          this.labelBounds = [];
          this.chart.data.datasets.forEach(this.renderToDataset);
      };
    
      Label.prototype.renderToDataset = function (dataset, index) {
          this.totalPercentage = 0;
          this.total = null;
          var arg = this.args[index];
          arg.meta.data.forEach(function (element, index) {
              this.renderToElement(dataset, arg, element, index);
          }.bind(this));
      };
    
      Label.prototype.renderToElement = function (dataset, arg, element, index) {
          if (!this.shouldRenderToElement(arg.meta, element)) {
              return;
          }
          this.percentage = null;
          var label = this.getLabel(dataset, element, index);
          if (!label) {
              return;
          }
          var ctx = this.ctx;
          ctx.save();
          ctx.font = Chart.helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
          var renderInfo = this.getRenderInfo(element, label);
          if (!this.drawable(element, label, renderInfo)) {
              ctx.restore();
              return;
          }
          ctx.beginPath();
          ctx.fillStyle = this.getFontColor(dataset, element, index);
          this.renderLabel(label, renderInfo);
          ctx.restore();
      };
    
      Label.prototype.renderLabel = function (label, renderInfo) {
           return this.options.arc ? this.renderArcLabel(label, renderInfo) : this.renderBaseLabel(label, renderInfo);
      };
    
      Label.prototype.renderBaseLabel = function (label, position) {
          var ctx = this.ctx;
          if (typeof label === 'object') {
              ctx.drawImage(label, position.x - label.width / 2, position.y - label.height / 2, label.width, label.height);
          } else {
              ctx.save();
              ctx.textBaseline = 'top';
              ctx.textAlign = 'center';
  
              if (this.options.textShadow) {
                  ctx.shadowOffsetX = this.options.shadowOffsetX;
                  ctx.shadowOffsetY = this.options.shadowOffsetY;
                  ctx.shadowColor = this.options.shadowColor;
                  ctx.shadowBlur = this.options.shadowBlur;
              }
  
              var lines = label.split('\n');
              for (var i = 0; i < lines.length; i++) {
                  var y = position.y - this.options.fontSize / 2 * lines.length + this.options.fontSize * i;
                  ctx.fillText(lines[i], position.x, y);
              }
              ctx.restore();
          }
      };
    
      Label.prototype.renderArcLabel = function (label, renderInfo) {
          var ctx = this.ctx, radius = renderInfo.radius, view = renderInfo.view;
          ctx.save();
          ctx.translate(view.x, view.y);
          if (typeof label === 'string') {
              ctx.rotate(renderInfo.startAngle);
              ctx.textBaseline = 'middle';
              ctx.textAlign = 'left';
              var lines = label.split('\n'), max = 0, widths = [], offset = 0;
              if (this.options.position === 'border') {
                  offset = (lines.length - 1) * this.options.fontSize / 2;
              }
              for (var j = 0; j < lines.length; ++j) {
                  var mertrics = ctx.measureText(lines[j]);
                  if (mertrics.width > max) {
                      max = mertrics.width;
                  }
                  widths.push(mertrics.width);
              }
              for (var j = 0; j < lines.length; ++j) {
                  var line = lines[j];
                  var y = (lines.length - 1 - j) * -this.options.fontSize + offset;
                  ctx.save();
                  var padding = (max - widths[j]) / 2;
                  ctx.rotate(padding / radius);
                  for (var i = 0; i < line.length; i++) {
                      var char = line.charAt(i);
                      mertrics = ctx.measureText(char);
                      ctx.save();
                      ctx.translate(0, -1 * radius);
                      ctx.fillText(char, 0, y);
                      ctx.restore();
                      ctx.rotate(mertrics.width / radius);
                  }
                  ctx.restore();
              }
          } else {
              ctx.rotate((view.startAngle + Math.PI / 2 + renderInfo.endAngle) / 2);
              ctx.translate(0, -1 * radius);
              this.renderLabel(label, { x: 0, y: 0 });
          }
          ctx.restore();
      };
    
      Label.prototype.shouldRenderToElement = function (meta, element) {
          return !meta.hidden && !element.hidden && (
              this.options.showZero ||
              this.chart.config.type === 'polarArea' ? element._view.outerRadius !== 0 : element._view.circumference !== 0
          );
      };
    
      Label.prototype.getLabel = function (dataset, element, index) {
          var label;
          if (typeof this.options.render === 'function') {
              label = this.options.render({
                          label: this.chart.config.data.labels[index],
                          value: dataset.data[index],
                          percentage: this.getPercentage(dataset, element, index),
                          dataset: dataset,
                          index: index
                      });
          } else {
              switch (this.options.render) {
              case 'value':
                  label = dataset.data[index];
                  break;
              case 'label':
                  label = this.chart.config.data.labels[index];
                  break;
              case 'image':
                  label = this.options.images[index] ? this.loadImage(this.options.images[index]) : '';
                  break;
              case 'percentage':
              default:
                  label = this.getPercentage(dataset, element, index) + '%';
                  break;
              }
          }
          if (typeof label === 'object') {
              label = this.loadImage(label);
          } else if (label !== null && label !== undefined) {
              label = label.toString();
          }
          return label;
      };
    
      Label.prototype.getFontColor = function (dataset, element, index) {
          var fontColor = this.options.fontColor;
          if (typeof fontColor === 'function') {
              fontColor = fontColor({
              label: this.chart.config.data.labels[index],
              value: dataset.data[index],
              percentage: this.getPercentage(dataset, element, index),
              backgroundColor: dataset.backgroundColor[index],
              dataset: dataset,
              index: index
              });
          } else if (typeof fontColor !== 'string') {
              fontColor = fontColor[index] || this.chart.config.options.defaultFontColor;
          }
          return fontColor;
      };
    
      Label.prototype.getPercentage = function (dataset, element, index) {
          if (this.percentage !== null) {
              return this.percentage;
          }
          var percentage;
          if (this.chart.config.type === 'polarArea') {
              if (this.total === null) {
                  this.total = 0;
                  for (var i = 0;i < dataset.data.length; ++i) {
                      this.total += dataset.data[i];
                  }
              }
              percentage = dataset.data[index] / this.total * 100;
          } else if (this.chart.config.type === 'bar') {
              if (this.barTotal[index] === undefined) {
                  this.barTotal[index] = 0;
                  for (var i = 0;i < this.chart.data.datasets.length; ++i) {
                      this.barTotal[index] += this.chart.data.datasets[i].data[index];
                  }
              }
              percentage = dataset.data[index] / this.barTotal[index] * 100;
          } else {
              percentage = element._view.circumference / this.chart.config.options.circumference * 100;
          }
  
          // percentage = parseFloat(percentage.toFixed(this.options.precision));
          percentage = numeral(percentage).format('0,0.00')
          if (!this.options.showActualPercentages) {
              if (this.chart.config.type === 'bar') {
                  this.totalPercentage = this.barTotalPercentage[index] || 0;
              }
              this.totalPercentage += percentage;
              if (this.totalPercentage > 100) {
                  percentage -= this.totalPercentage - 100;
                  percentage = parseFloat(percentage.toFixed(this.options.precision));
              }
              if (this.chart.config.type === 'bar') {
                  this.barTotalPercentage[index] = this.totalPercentage
              }
          }
          this.percentage = percentage;
  
          return percentage;
      };
    
      Label.prototype.getRenderInfo = function (element, label) {
          if (this.chart.config.type === 'bar') {
              return this.getBarRenderInfo(element, label);
          } else {
              return this.options.arc ? this.getArcRenderInfo(element, label) : this.getBaseRenderInfo(element, label);
          }
      };
    
      Label.prototype.getBaseRenderInfo = function (element, label) {
          if (this.options.position === 'outside' || this.options.position === 'border') {
              var renderInfo, rangeFromCentre,
              view = element._view,
              centreAngle = view.startAngle + (view.endAngle - view.startAngle) / 2,
              innerRadius = view.outerRadius / 2;
              if (this.options.position === 'border') {
                  rangeFromCentre = (view.outerRadius - innerRadius) / 2 + innerRadius;
              } else if (this.options.position === 'outside') {
                  rangeFromCentre = (view.outerRadius - innerRadius) + innerRadius + this.options.textMargin;
              }
              renderInfo = {
                              x: view.x + (Math.cos(centreAngle) * rangeFromCentre),
                              y: view.y + (Math.sin(centreAngle) * rangeFromCentre)
                          };
              if (this.options.position === 'outside') {
                  var offset = this.options.textMargin + this.measureLabel(label).width / 2;
                  renderInfo.x += renderInfo.x < view.x ? -offset : offset;
              }
              return renderInfo;
          } else {
              return element.tooltipPosition();
          }
      };
    
      Label.prototype.getArcRenderInfo = function (element, label) {
          var radius, view = element._view;
          if (this.options.position === 'outside') {
              radius = view.outerRadius + this.options.fontSize + this.options.textMargin;
          } else if (this.options.position === 'border') {
              radius = (view.outerRadius / 2 + view.outerRadius) / 2;
          } else {
              radius = (view.innerRadius + view.outerRadius) / 2;
          }
          var startAngle = view.startAngle, endAngle = view.endAngle;
          var totalAngle = endAngle - startAngle;
          startAngle += Math.PI / 2;
          endAngle += Math.PI / 2;
          var mertrics = this.measureLabel(label);
          startAngle += (endAngle - (mertrics.width / radius + startAngle)) / 2;
          return {
              radius: radius,
              startAngle: startAngle,
              endAngle: endAngle,
              totalAngle: totalAngle,
              view: view
          }
      };
    
      Label.prototype.getBarRenderInfo = function (element, label) {
          var renderInfo = element.tooltipPosition();
          renderInfo.y -= this.measureLabel(label).height / 2 + this.options.textMargin;
          return renderInfo;
      };
    
      Label.prototype.drawable = function (element, label, renderInfo) {
          if (this.options.overlap) {
              return true;
          } else if (this.options.arc) {
              return renderInfo.endAngle - renderInfo.startAngle <= renderInfo.totalAngle;
          } else {
              var mertrics = this.measureLabel(label),
              left = renderInfo.x - mertrics.width / 2,
              right = renderInfo.x + mertrics.width / 2,
              top = renderInfo.y - mertrics.height / 2,
              bottom = renderInfo.y + mertrics.height / 2;
              if (this.options.renderInfo === 'outside') {
                  return this.outsideInRange(left, right, top, bottom);
              } else {
                  return element.inRange(left, top) && element.inRange(left, bottom) &&
                      element.inRange(right, top) && element.inRange(right, bottom);
              }
          }
      };
    
      Label.prototype.outsideInRange = function (left, right, top, bottom) {
          var labelBounds = this.labelBounds;
          for (var i = 0;i < labelBounds.length;++i) {
              var bound = labelBounds[i];
              var potins = [
                              [left, top],
                              [left, bottom],
                              [right, top],
                              [right, bottom]
                          ];
              for (var j = 0;j < potins.length;++j) {
                  var x = potins[j][0];
                  var y = potins[j][1];
                  if (x >= bound.left && x <= bound.right && y >= bound.top && y <= bound.bottom) {
                      return false;
                  }
              }
              potins = [
              [bound.left, bound.top],
              [bound.left, bound.bottom],
              [bound.right, bound.top],
              [bound.right, bound.bottom]
              ];
              for (var j = 0;j < potins.length;++j) {
                  var x = potins[j][0];
                  var y = potins[j][1];
                  if (x >= left && x <= right && y >= top && y <= bottom) {
                      return false;
                  }
              }
          }
          labelBounds.push({
              left: left,
              right: right,
              top: top,
              bottom: bottom
          });
          return true;
      };
    
      Label.prototype.measureLabel = function (label) {
          if (typeof label === 'object') {
              return { width: label.width, height: label.height };
          } else {
              var width = 0;
              var lines = label.split('\n');
              for (var i = 0; i < lines.length; ++i) {
                  var result = this.ctx.measureText(lines[i]);
                  if (result.width > width) {
                      width = result.width;
                  }
              }
              return { width: width, height: this.options.fontSize * lines.length };
          }
      };
    
      Label.prototype.loadImage = function (obj) {
          var image = new Image();
          image.src = obj.src;
          image.width = obj.width;
          image.height = obj.height;
          return image;
      };
    
      Chart.plugins.register({
          id: 'labels',
          beforeDatasetsUpdate: function (chart, options) {
              if (!SUPPORTED_TYPES[chart.config.type]) {
                  return;
              }
              if (!Array.isArray(options)) {
                  options = [options];
              }
              var count = options.length;
              if (!chart._labels || count !== chart._labels.length) {
                  chart._labels = options.map(function () {
                      return new Label();
                  });
              }
              var someOutside = false, maxPadding = 0;
              for (var i = 0; i < count; ++i) {
                  var label = chart._labels[i];
                  label.setup(chart, options[i]);
                  if (label.options.position === 'outside') {
                      someOutside = true;
                      var padding = label.options.fontSize * 1.5 + label.options.outsidePadding;
                      if (padding > maxPadding) {
                          maxPadding = padding;
                      }
                  }
              }
              if (someOutside) {
                  chart.chartArea.top += maxPadding;
                  chart.chartArea.bottom -= maxPadding;
              }
          },
          afterDatasetUpdate: function (chart, args, options) {
              if (!SUPPORTED_TYPES[chart.config.type]) {
                  return;
              }
              chart._labels.forEach(function (label) {
                  label.args[args.index] = args;
              });
          },
          beforeDraw: function (chart) {
              if (!SUPPORTED_TYPES[chart.config.type]) {
                  return;
              }
              chart._labels.forEach(function (label) {
                  label.barTotalPercentage = {};
              });
          },
          afterDatasetsDraw: function (chart) {
              if (!SUPPORTED_TYPES[chart.config.type]) {
                  return;
              }
              chart._labels.forEach(function (label) {
                  label.render();
              });
          }
      });
    })();