/*!
 * Copyright (c) HANDSONCODE sp. z o. o.
 *
 * HANDSONTABLE is a software distributed by HANDSONCODE sp. z o. o.,
 * a Polish corporation, based in Gdynia, Poland, at 96/98 Aleja Zwycięstwa,
 * registered with the National Court Register under number 538651,
 * EU tax ID number: PL5862294002, share capital: PLN 62,800.00.
 *
 * This software is protected by applicable copyright laws, including
 * international treaties, and dual-licensed – depending on whether
 * your use is intended for or may result in commercial advantage
 * or monetary compensation (commercial purposes), or not.
 *
 * If your use involves only such purposes as research, private study,
 * evaluation and the like, you agree to be bound by the terms included
 * in the “handsontable-non-commercial-license.pdf” file, available
 * in the main directory of this software repository.
 *
 * By installing, copying, or otherwise using this software for
 * commercial purposes, you agree to be bound by the terms included
 * in the “handsontable-general-terms.pdf” file, available in the main
 * directory of this software repository.
 *
 * HANDSONCODE PROVIDES THIS SOFTWARE ON AN “AS IS” BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND. IN NO EVENT
 * AND UNDER NO LEGAL THEORY, SHALL HANDSONCODE BE LIABLE
 * TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL,
 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING
 * FROM USE OR INABILITY TO USE THIS SOFTWARE.
 *
 * Version: 7.0.1
 * Release date: 08/04/2019 (built at 29/03/2019 11:28:56)
 */
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define("Handsontable", [], factory);
	else if(typeof exports === 'object')
		exports["Handsontable"] = factory();
	else
		root["Handsontable"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 505);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : {
    "default": obj
  };
}

module.exports = _interopRequireDefault;

/***/ }),
/* 1 */
/***/ (function(module, exports) {

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

module.exports = _classCallCheck;

/***/ }),
/* 2 */
/***/ (function(module, exports) {

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

module.exports = _createClass;

/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(59);

__webpack_require__(12);

__webpack_require__(14);

exports.__esModule = true;
exports.to2dArray = to2dArray;
exports.extendArray = extendArray;
exports.pivot = pivot;
exports.arrayReduce = arrayReduce;
exports.arrayFilter = arrayFilter;
exports.arrayMap = arrayMap;
exports.arrayEach = arrayEach;
exports.arraySum = arraySum;
exports.arrayMax = arrayMax;
exports.arrayMin = arrayMin;
exports.arrayAvg = arrayAvg;
exports.arrayFlatten = arrayFlatten;
exports.arrayUnique = arrayUnique;

function to2dArray(arr) {
  var ilen = arr.length;
  var i = 0;

  while (i < ilen) {
    arr[i] = [arr[i]];
    i += 1;
  }
}

function extendArray(arr, extension) {
  var ilen = extension.length;
  var i = 0;

  while (i < ilen) {
    arr.push(extension[i]);
    i += 1;
  }
}

function pivot(arr) {
  var pivotedArr = [];

  if (!arr || arr.length === 0 || !arr[0] || arr[0].length === 0) {
    return pivotedArr;
  }

  var rowCount = arr.length;
  var colCount = arr[0].length;

  for (var i = 0; i < rowCount; i++) {
    for (var j = 0; j < colCount; j++) {
      if (!pivotedArr[j]) {
        pivotedArr[j] = [];
      }

      pivotedArr[j][i] = arr[i][j];
    }
  }

  return pivotedArr;
}
/**
 * A specialized version of `.reduce` for arrays without support for callback
 * shorthands and `this` binding.
 *
 * {@link https://github.com/lodash/lodash/blob/master/lodash.js}
 *
 * @param {Array} array The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} [accumulator] The initial value.
 * @param {Boolean} [initFromArray] Specify using the first element of `array` as the initial value.
 * @returns {*} Returns the accumulated value.
 */


function arrayReduce(array, iteratee, accumulator, initFromArray) {
  var index = -1;
  var iterable = array;
  var result = accumulator;

  if (!Array.isArray(array)) {
    iterable = Array.from(array);
  }

  var length = iterable.length;

  if (initFromArray && length) {
    index += 1;
    result = iterable[index];
  }

  index += 1;

  while (index < length) {
    result = iteratee(result, iterable[index], index, iterable);
    index += 1;
  }

  return result;
}
/**
 * A specialized version of `.filter` for arrays without support for callback
 * shorthands and `this` binding.
 *
 * {@link https://github.com/lodash/lodash/blob/master/lodash.js}
 *
 * @param {Array} array The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */


function arrayFilter(array, predicate) {
  var index = 0;
  var iterable = array;

  if (!Array.isArray(array)) {
    iterable = Array.from(array);
  }

  var length = iterable.length;
  var result = [];
  var resIndex = -1;

  while (index < length) {
    var value = iterable[index];

    if (predicate(value, index, iterable)) {
      resIndex += 1;
      result[resIndex] = value;
    }

    index += 1;
  }

  return result;
}
/**
 * A specialized version of `.map` for arrays without support for callback
 * shorthands and `this` binding.
 *
 * @param {Array} array The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */


function arrayMap(array, iteratee) {
  var index = 0;
  var iterable = array;

  if (!Array.isArray(array)) {
    iterable = Array.from(array);
  }

  var length = iterable.length;
  var result = [];
  var resIndex = -1;

  while (index < length) {
    var value = iterable[index];
    resIndex += 1;
    result[resIndex] = iteratee(value, index, iterable);
    index += 1;
  }

  return result;
}
/**
 * A specialized version of `.forEach` for arrays without support for callback
 * shorthands and `this` binding.
 *
 * {@link https://github.com/lodash/lodash/blob/master/lodash.js}
 *
 * @param {Array|*} array The array to iterate over or an any element with implemented iterator protocol.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */


function arrayEach(array, iteratee) {
  var index = 0;
  var iterable = array;

  if (!Array.isArray(array)) {
    iterable = Array.from(array);
  }

  var length = iterable.length;

  while (index < length) {
    if (iteratee(iterable[index], index, iterable) === false) {
      break;
    }

    index += 1;
  }

  return array;
}
/**
 * Calculate sum value for each item of the array.
 *
 * @param {Array} array The array to process.
 * @returns {Number} Returns calculated sum value.
 */


function arraySum(array) {
  return arrayReduce(array, function (a, b) {
    return a + b;
  }, 0);
}
/**
 * Returns the highest value from an array. Can be array of numbers or array of strings.
 * NOTICE: Mixed values is not supported.
 *
 * @param {Array} array The array to process.
 * @returns {Number} Returns the highest value from an array.
 */


function arrayMax(array) {
  return arrayReduce(array, function (a, b) {
    return a > b ? a : b;
  }, Array.isArray(array) ? array[0] : void 0);
}
/**
 * Returns the lowest value from an array. Can be array of numbers or array of strings.
 * NOTICE: Mixed values is not supported.
 *
 * @param {Array} array The array to process.
 * @returns {Number} Returns the lowest value from an array.
 */


function arrayMin(array) {
  return arrayReduce(array, function (a, b) {
    return a < b ? a : b;
  }, Array.isArray(array) ? array[0] : void 0);
}
/**
 * Calculate average value for each item of the array.
 *
 * @param {Array} array The array to process.
 * @returns {Number} Returns calculated average value.
 */


function arrayAvg(array) {
  if (!array.length) {
    return 0;
  }

  return arraySum(array) / array.length;
}
/**
 * Flatten multidimensional array.
 *
 * @param {Array} array Array of Arrays
 * @returns {Array}
 */


function arrayFlatten(array) {
  return arrayReduce(array, function (initial, value) {
    return initial.concat(Array.isArray(value) ? arrayFlatten(value) : value);
  }, []);
}
/**
 * Unique values in the array.
 *
 * @param {Array} array The array to process.
 * @returns {Array}
 */


function arrayUnique(array) {
  var unique = [];
  arrayEach(array, function (value) {
    if (unique.indexOf(value) === -1) {
      unique.push(value);
    }
  });
  return unique;
}

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(46);

exports.__esModule = true;
exports.duckSchema = duckSchema;
exports.inherit = inherit;
exports.extend = extend;
exports.deepExtend = deepExtend;
exports.deepClone = deepClone;
exports.clone = clone;
exports.mixin = mixin;
exports.isObjectEqual = isObjectEqual;
exports.isObject = isObject;
exports.defineGetter = defineGetter;
exports.objectEach = objectEach;
exports.getProperty = getProperty;
exports.deepObjectSize = deepObjectSize;
exports.createObjectPropListener = createObjectPropListener;
exports.hasOwnProperty = hasOwnProperty;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _array = __webpack_require__(3);

/**
 * Generate schema for passed object.
 *
 * @param {Array|Object} object
 * @returns {Array|Object}
 */
function duckSchema(object) {
  var schema;

  if (Array.isArray(object)) {
    schema = [];
  } else {
    schema = {};
    objectEach(object, function (value, key) {
      if (key === '__children') {
        return;
      }

      if (value && (0, _typeof2.default)(value) === 'object' && !Array.isArray(value)) {
        schema[key] = duckSchema(value);
      } else if (Array.isArray(value)) {
        if (value.length && (0, _typeof2.default)(value[0]) === 'object' && !Array.isArray(value[0])) {
          schema[key] = [duckSchema(value[0])];
        } else {
          schema[key] = [];
        }
      } else {
        schema[key] = null;
      }
    });
  }

  return schema;
}
/**
 * Inherit without without calling parent constructor, and setting `Child.prototype.constructor` to `Child` instead of `Parent`.
 * Creates temporary dummy function to call it as constructor.
 * Described in ticket: https://github.com/handsontable/handsontable/pull/516
 *
 * @param  {Object} Child  child class
 * @param  {Object} Parent parent class
 * @return {Object}        extended Child
 */


function inherit(Child, Parent) {
  Parent.prototype.constructor = Parent;
  Child.prototype = new Parent();
  Child.prototype.constructor = Child;
  return Child;
}
/**
 * Perform shallow extend of a target object with extension's own properties.
 *
 * @param {Object} target An object that will receive the new properties.
 * @param {Object} extension An object containing additional properties to merge into the target.
 */


function extend(target, extension) {
  objectEach(extension, function (value, key) {
    target[key] = value;
  });
  return target;
}
/**
 * Perform deep extend of a target object with extension's own properties.
 *
 * @param {Object} target An object that will receive the new properties.
 * @param {Object} extension An object containing additional properties to merge into the target.
 */


function deepExtend(target, extension) {
  objectEach(extension, function (value, key) {
    if (extension[key] && (0, _typeof2.default)(extension[key]) === 'object') {
      if (!target[key]) {
        if (Array.isArray(extension[key])) {
          target[key] = [];
        } else if (Object.prototype.toString.call(extension[key]) === '[object Date]') {
          target[key] = extension[key];
        } else {
          target[key] = {};
        }
      }

      deepExtend(target[key], extension[key]);
    } else {
      target[key] = extension[key];
    }
  });
}
/**
 * Perform deep clone of an object.
 * WARNING! Only clones JSON properties. Will cause error when `obj` contains a function, Date, etc.
 *
 * @param {Object} obj An object that will be cloned
 * @return {Object}
 */


function deepClone(obj) {
  if ((0, _typeof2.default)(obj) === 'object') {
    return JSON.parse(JSON.stringify(obj));
  }

  return obj;
}
/**
 * Shallow clone object.
 *
 * @param {Object} object
 * @returns {Object}
 */


function clone(object) {
  var result = {};
  objectEach(object, function (value, key) {
    result[key] = value;
  });
  return result;
}
/**
 * Extend the Base object (usually prototype) of the functionality the `mixins` objects.
 *
 * @param {Object} Base Base object which will be extended.
 * @param {Object} mixins The object of the functionality will be "copied".
 * @returns {Object}
 */


function mixin(Base) {
  if (!Base.MIXINS) {
    Base.MIXINS = [];
  }

  for (var _len = arguments.length, mixins = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    mixins[_key - 1] = arguments[_key];
  }

  (0, _array.arrayEach)(mixins, function (mixinItem) {
    Base.MIXINS.push(mixinItem.MIXIN_NAME);
    objectEach(mixinItem, function (value, key) {
      if (Base.prototype[key] !== void 0) {
        throw new Error("Mixin conflict. Property '".concat(key, "' already exist and cannot be overwritten."));
      }

      if (typeof value === 'function') {
        Base.prototype[key] = value;
      } else {
        var getter = function _getter(property, initialValue) {
          var propertyName = "_".concat(property);

          var initValue = function initValue(newValue) {
            var result = newValue;

            if (Array.isArray(result) || isObject(result)) {
              result = deepClone(result);
            }

            return result;
          };

          return function () {
            if (this[propertyName] === void 0) {
              this[propertyName] = initValue(initialValue);
            }

            return this[propertyName];
          };
        };

        var setter = function _setter(property) {
          var propertyName = "_".concat(property);
          return function (newValue) {
            this[propertyName] = newValue;
          };
        };

        Object.defineProperty(Base.prototype, key, {
          get: getter(key, value),
          set: setter(key),
          configurable: true
        });
      }
    });
  });
  return Base;
}
/**
 * Checks if two objects or arrays are (deep) equal
 *
 * @param {Object|Array} object1
 * @param {Object|Array} object2
 * @returns {Boolean}
 */


function isObjectEqual(object1, object2) {
  return JSON.stringify(object1) === JSON.stringify(object2);
}
/**
 * Determines whether given object is a plain Object.
 * Note: String and Array are not plain Objects
 * @param {*} obj
 * @returns {boolean}
 */


function isObject(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

function defineGetter(object, property, value, options) {
  options.value = value;
  options.writable = options.writable !== false;
  options.enumerable = options.enumerable !== false;
  options.configurable = options.configurable !== false;
  Object.defineProperty(object, property, options);
}
/**
 * A specialized version of `.forEach` for objects.
 *
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Object} Returns `object`.
 */


function objectEach(object, iteratee) {
  // eslint-disable-next-line no-restricted-syntax
  for (var key in object) {
    if (!object.hasOwnProperty || object.hasOwnProperty && Object.prototype.hasOwnProperty.call(object, key)) {
      if (iteratee(object[key], key, object) === false) {
        break;
      }
    }
  }

  return object;
}
/**
 * Get object property by its name. Access to sub properties can be achieved by dot notation (e.q. `'foo.bar.baz'`).
 *
 * @param {Object} object Object which value will be exported.
 * @param {String} name Object property name.
 * @returns {*}
 */


function getProperty(object, name) {
  var names = name.split('.');
  var result = object;
  objectEach(names, function (nameItem) {
    result = result[nameItem];

    if (result === void 0) {
      result = void 0;
      return false;
    }
  });
  return result;
}
/**
 * Return object length (recursively).
 *
 * @param {*} object Object for which we want get length.
 * @returns {Number}
 */


function deepObjectSize(object) {
  if (!isObject(object)) {
    return 0;
  }

  var recursObjLen = function recursObjLen(obj) {
    var result = 0;

    if (isObject(obj)) {
      objectEach(obj, function (key) {
        result += recursObjLen(key);
      });
    } else {
      result += 1;
    }

    return result;
  };

  return recursObjLen(object);
}
/**
 * Create object with property where its value change will be observed.
 *
 * @param {*} [defaultValue=undefined] Default value.
 * @param {String} [propertyToListen='value'] Property to listen.
 * @returns {Object}
 */


function createObjectPropListener(defaultValue) {
  var _holder;

  var propertyToListen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'value';
  var privateProperty = "_".concat(propertyToListen);
  var holder = (_holder = {
    _touched: false
  }, (0, _defineProperty2.default)(_holder, privateProperty, defaultValue), (0, _defineProperty2.default)(_holder, "isTouched", function isTouched() {
    return this._touched;
  }), _holder);
  Object.defineProperty(holder, propertyToListen, {
    get: function get() {
      return this[privateProperty];
    },
    set: function set(value) {
      this._touched = true;
      this[privateProperty] = value;
    },
    enumerable: true,
    configurable: true
  });
  return holder;
}
/**
 * Check if at specified `key` there is any value for `object`.
 *
 * @param {Object} object Object to search value at specyfic key.
 * @param {String} key String key to check.
 */


function hasOwnProperty(object, key) {
  return Object.prototype.hasOwnProperty.call(object, key);
}

/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(54);

__webpack_require__(40);

__webpack_require__(10);

__webpack_require__(130);

__webpack_require__(36);

__webpack_require__(39);

__webpack_require__(37);

__webpack_require__(46);

__webpack_require__(105);

exports.__esModule = true;
exports.getParent = getParent;
exports.closest = closest;
exports.closestDown = closestDown;
exports.isChildOf = isChildOf;
exports.isChildOfWebComponentTable = isChildOfWebComponentTable;
exports.polymerWrap = polymerWrap;
exports.polymerUnwrap = polymerUnwrap;
exports.index = index;
exports.overlayContainsElement = overlayContainsElement;
exports.hasClass = hasClass;
exports.addClass = addClass;
exports.removeClass = removeClass;
exports.removeTextNodes = removeTextNodes;
exports.empty = empty;
exports.fastInnerHTML = fastInnerHTML;
exports.fastInnerText = fastInnerText;
exports.isVisible = isVisible;
exports.offset = offset;
exports.getWindowScrollTop = getWindowScrollTop;
exports.getWindowScrollLeft = getWindowScrollLeft;
exports.getScrollTop = getScrollTop;
exports.getScrollLeft = getScrollLeft;
exports.getScrollableElement = getScrollableElement;
exports.getTrimmingContainer = getTrimmingContainer;
exports.getStyle = getStyle;
exports.getComputedStyle = getComputedStyle;
exports.outerWidth = outerWidth;
exports.outerHeight = outerHeight;
exports.innerHeight = innerHeight;
exports.innerWidth = innerWidth;
exports.addEvent = addEvent;
exports.removeEvent = removeEvent;
exports.getCaretPosition = getCaretPosition;
exports.getSelectionEndPosition = getSelectionEndPosition;
exports.getSelectionText = getSelectionText;
exports.clearTextSelection = clearTextSelection;
exports.setCaretPosition = setCaretPosition;
exports.getScrollbarWidth = getScrollbarWidth;
exports.hasVerticalScrollbar = hasVerticalScrollbar;
exports.hasHorizontalScrollbar = hasHorizontalScrollbar;
exports.setOverlayPosition = setOverlayPosition;
exports.getCssTransform = getCssTransform;
exports.resetCssTransform = resetCssTransform;
exports.isInput = isInput;
exports.isOutsideInput = isOutsideInput;
exports.selectElementIfAllowed = selectElementIfAllowed;
exports.HTML_CHARACTERS = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _browser = __webpack_require__(72);

var _feature = __webpack_require__(73);

/**
 * Get the parent of the specified node in the DOM tree.
 *
 * @param  {HTMLElement} element Element from which traversing is started.
 * @param  {Number} [level=0] Traversing deep level.
 * @return {HTMLElement|null}
 */
function getParent(element) {
  var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  var iteration = -1;
  var parent = null;
  var elementToCheck = element;

  while (elementToCheck !== null) {
    if (iteration === level) {
      parent = elementToCheck;
      break;
    }

    if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      elementToCheck = elementToCheck.host;
    } else {
      iteration += 1;
      elementToCheck = elementToCheck.parentNode;
    }
  }

  return parent;
}
/**
 * Goes up the DOM tree (including given element) until it finds an element that matches the nodes or nodes name.
 * This method goes up through web components.
 *
 * @param {HTMLElement} element Element from which traversing is started
 * @param {Array} nodes Array of elements or Array of elements name
 * @param {HTMLElement} [until]
 * @returns {HTMLElement|null}
 */


function closest(element, nodes, until) {
  var elementToCheck = element;

  while (elementToCheck !== null && elementToCheck !== until) {
    if (elementToCheck.nodeType === Node.ELEMENT_NODE && (nodes.indexOf(elementToCheck.nodeName) > -1 || nodes.indexOf(elementToCheck) > -1)) {
      return elementToCheck;
    }

    if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      elementToCheck = elementToCheck.host;
    } else {
      elementToCheck = elementToCheck.parentNode;
    }
  }

  return null;
}
/**
 * Goes "down" the DOM tree (including given element) until it finds an element that matches the nodes or nodes name.
 *
 * @param {HTMLElement} element Element from which traversing is started
 * @param {Array} nodes Array of elements or Array of elements name
 * @param {HTMLElement} [until]
 * @returns {HTMLElement|null}
 */


function closestDown(element, nodes, until) {
  var matched = [];
  var elementToCheck = element;

  while (elementToCheck) {
    elementToCheck = closest(elementToCheck, nodes, until);

    if (!elementToCheck || until && !until.contains(elementToCheck)) {
      break;
    }

    matched.push(elementToCheck);

    if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      elementToCheck = elementToCheck.host;
    } else {
      elementToCheck = elementToCheck.parentNode;
    }
  }

  var length = matched.length;
  return length ? matched[length - 1] : null;
}
/**
 * Goes up the DOM tree and checks if element is child of another element.
 *
 * @param child Child element
 * @param {Object|String} parent Parent element OR selector of the parent element.
 *                               If string provided, function returns `true` for the first occurrence of element with that class.
 * @returns {Boolean}
 */


function isChildOf(child, parent) {
  var node = child.parentNode;
  var queriedParents = [];

  if (typeof parent === 'string') {
    queriedParents = Array.prototype.slice.call(child.ownerDocument.querySelectorAll(parent), 0);
  } else {
    queriedParents.push(parent);
  }

  while (node !== null) {
    if (queriedParents.indexOf(node) > -1) {
      return true;
    }

    node = node.parentNode;
  }

  return false;
}
/**
 * Check if an element is part of `hot-table` web component.
 *
 * @param {Element} element
 * @returns {Boolean}
 */


function isChildOfWebComponentTable(element) {
  var hotTableName = 'hot-table';
  var result = false;
  var parentNode = polymerWrap(element);

  function isHotTable(testElement) {
    return testElement.nodeType === Node.ELEMENT_NODE && testElement.nodeName === hotTableName.toUpperCase();
  }

  while (parentNode !== null) {
    if (isHotTable(parentNode)) {
      result = true;
      break;
    } else if (parentNode.host && parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      result = isHotTable(parentNode.host);

      if (result) {
        break;
      }

      parentNode = parentNode.host;
    }

    parentNode = parentNode.parentNode;
  }

  return result;
}
/* global Polymer wrap unwrap */

/**
 * Wrap element into polymer/webcomponent container if exists
 *
 * @param element
 * @returns {*}
 */


function polymerWrap(element) {
  return typeof Polymer !== 'undefined' && typeof wrap === 'function' ? wrap(element) : element;
}
/**
 * Unwrap element from polymer/webcomponent container if exists
 *
 * @param element
 * @returns {*}
 */


function polymerUnwrap(element) {
  return typeof Polymer !== 'undefined' && typeof unwrap === 'function' ? unwrap(element) : element;
}
/**
 * Counts index of element within its parent
 * WARNING: for performance reasons, assumes there are only element nodes (no text nodes). This is true for Walkotnable
 * Otherwise would need to check for nodeType or use previousElementSibling
 *
 * @see http://jsperf.com/sibling-index/10
 * @param {Element} element
 * @return {Number}
 */


function index(element) {
  var i = 0;
  var elementToCheck = element;

  if (elementToCheck.previousSibling) {
    /* eslint-disable no-cond-assign */
    while (elementToCheck = elementToCheck.previousSibling) {
      i += 1;
    }
  }

  return i;
}
/**
 * Check if the provided overlay contains the provided element
 *
 * @param {String} overlay
 * @param {HTMLElement} element
 * @returns {boolean}
 */


function overlayContainsElement(overlayType, element) {
  var overlayElement = element.ownerDocument.querySelector(".ht_clone_".concat(overlayType));
  return overlayElement ? overlayElement.contains(element) : null;
}

var _hasClass;

var _addClass;

var _removeClass;

function filterEmptyClassNames(classNames) {
  var result = [];

  if (!classNames || !classNames.length) {
    return result;
  }

  var len = 0;

  while (classNames[len]) {
    result.push(classNames[len]);
    len += 1;
  }

  return result;
}

if ((0, _feature.isClassListSupported)()) {
  var isSupportMultipleClassesArg = function isSupportMultipleClassesArg(rootDocument) {
    var element = rootDocument.createElement('div');
    element.classList.add('test', 'test2');
    return element.classList.contains('test2');
  };

  _hasClass = function _hasClass(element, className) {
    if (element.classList === void 0 || typeof className !== 'string' || className === '') {
      return false;
    }

    return element.classList.contains(className);
  };

  _addClass = function _addClass(element, classes) {
    var rootDocument = element.ownerDocument;
    var className = classes;

    if (typeof className === 'string') {
      className = className.split(' ');
    }

    className = filterEmptyClassNames(className);

    if (className.length > 0) {
      if (isSupportMultipleClassesArg(rootDocument)) {
        var _element$classList;

        (_element$classList = element.classList).add.apply(_element$classList, (0, _toConsumableArray2.default)(className));
      } else {
        var len = 0;

        while (className && className[len]) {
          element.classList.add(className[len]);
          len += 1;
        }
      }
    }
  };

  _removeClass = function _removeClass(element, classes) {
    var className = classes;

    if (typeof className === 'string') {
      className = className.split(' ');
    }

    className = filterEmptyClassNames(className);

    if (className.length > 0) {
      if (isSupportMultipleClassesArg) {
        var _element$classList2;

        (_element$classList2 = element.classList).remove.apply(_element$classList2, (0, _toConsumableArray2.default)(className));
      } else {
        var len = 0;

        while (className && className[len]) {
          element.classList.remove(className[len]);
          len += 1;
        }
      }
    }
  };
} else {
  var createClassNameRegExp = function createClassNameRegExp(className) {
    return new RegExp("(\\s|^)".concat(className, "(\\s|$)"));
  };

  _hasClass = function _hasClass(element, className) {
    // http://snipplr.com/view/3561/addclass-removeclass-hasclass/
    return element.className !== void 0 && createClassNameRegExp(className).test(element.className);
  };

  _addClass = function _addClass(element, classes) {
    var len = 0;
    var _className = element.className;
    var className = classes;

    if (typeof className === 'string') {
      className = className.split(' ');
    }

    if (_className === '') {
      _className = className.join(' ');
    } else {
      while (className && className[len]) {
        if (!createClassNameRegExp(className[len]).test(_className)) {
          _className += " ".concat(className[len]);
        }

        len += 1;
      }
    }

    element.className = _className;
  };

  _removeClass = function _removeClass(element, classes) {
    var len = 0;
    var _className = element.className;
    var className = classes;

    if (typeof className === 'string') {
      className = className.split(' ');
    }

    while (className && className[len]) {
      // String.prototype.trim is defined in polyfill.js
      _className = _className.replace(createClassNameRegExp(className[len]), ' ').trim();
      len += 1;
    }

    if (element.className !== _className) {
      element.className = _className;
    }
  };
}
/**
 * Checks if element has class name
 *
 * @param {HTMLElement} element
 * @param {String} className Class name to check
 * @returns {Boolean}
 */


function hasClass(element, className) {
  return _hasClass(element, className);
}
/**
 * Add class name to an element
 *
 * @param {HTMLElement} element
 * @param {String|Array} className Class name as string or array of strings
 */


function addClass(element, className) {
  return _addClass(element, className);
}
/**
 * Remove class name from an element
 *
 * @param {HTMLElement} element
 * @param {String|Array} className Class name as string or array of strings
 */


function removeClass(element, className) {
  return _removeClass(element, className);
}

function removeTextNodes(element, parent) {
  if (element.nodeType === 3) {
    parent.removeChild(element); // bye text nodes!
  } else if (['TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TR'].indexOf(element.nodeName) > -1) {
    var childs = element.childNodes;

    for (var i = childs.length - 1; i >= 0; i--) {
      removeTextNodes(childs[i], element);
    }
  }
}
/**
 * Remove childs function
 * WARNING - this doesn't unload events and data attached by jQuery
 * http://jsperf.com/jquery-html-vs-empty-vs-innerhtml/9
 * http://jsperf.com/jquery-html-vs-empty-vs-innerhtml/11 - no siginificant improvement with Chrome remove() method
 *
 * @param element
 * @returns {void}
 */
//


function empty(element) {
  var child;
  /* eslint-disable no-cond-assign */

  while (child = element.lastChild) {
    element.removeChild(child);
  }
}

var HTML_CHARACTERS = /(<(.*)>|&(.*);)/;
/**
 * Insert content into element trying avoid innerHTML method.
 * @return {void}
 */

exports.HTML_CHARACTERS = HTML_CHARACTERS;

function fastInnerHTML(element, content) {
  if (HTML_CHARACTERS.test(content)) {
    element.innerHTML = content;
  } else {
    fastInnerText(element, content);
  }
}
/**
 * Insert text content into element
 * @return {Boolean}
 */


function fastInnerText(element, content) {
  var child = element.firstChild;

  if (child && child.nodeType === 3 && child.nextSibling === null) {
    // fast lane - replace existing text node
    if (_feature.isTextContentSupported) {
      // http://jsperf.com/replace-text-vs-reuse
      child.textContent = content;
    } else {
      // http://jsperf.com/replace-text-vs-reuse
      child.data = content;
    }
  } else {
    // slow lane - empty element and insert a text node
    empty(element);
    element.appendChild(element.ownerDocument.createTextNode(content));
  }
}
/**
 * Returns true if element is attached to the DOM and visible, false otherwise
 * @param elem
 * @returns {boolean}
 */


function isVisible(elem) {
  var documentElement = elem.ownerDocument.documentElement;
  var next = elem;

  while (polymerUnwrap(next) !== documentElement) {
    // until <html> reached
    if (next === null) {
      // parent detached from DOM
      return false;
    } else if (next.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      if (next.host) {
        // this is Web Components Shadow DOM
        // see: http://w3c.github.io/webcomponents/spec/shadow/#encapsulation
        // according to spec, should be if (next.ownerDocument !== window.document), but that doesn't work yet
        if (next.host.impl) {
          // Chrome 33.0.1723.0 canary (2013-11-29) Web Platform features disabled
          return isVisible(next.host.impl);
        } else if (next.host) {
          // Chrome 33.0.1723.0 canary (2013-11-29) Web Platform features enabled
          return isVisible(next.host);
        }

        throw new Error('Lost in Web Components world');
      } else {
        return false; // this is a node detached from document in IE8
      }
    } else if (next.style && next.style.display === 'none') {
      return false;
    }

    next = next.parentNode;
  }

  return true;
}
/**
 * Returns elements top and left offset relative to the document. Function is not compatible with jQuery offset.
 *
 * @param {HTMLElement} elem
 * @return {Object} Returns object with `top` and `left` props
 */


function offset(elem) {
  var rootDocument = elem.ownerDocument;
  var rootWindow = rootDocument.defaultView;
  var documentElement = rootDocument.documentElement;
  var elementToCheck = elem;
  var offsetLeft;
  var offsetTop;
  var lastElem;
  var box;

  if ((0, _feature.hasCaptionProblem)() && elementToCheck.firstChild && elementToCheck.firstChild.nodeName === 'CAPTION') {
    // fixes problem with Firefox ignoring <caption> in TABLE offset (see also export outerHeight)
    // http://jsperf.com/offset-vs-getboundingclientrect/8
    box = elementToCheck.getBoundingClientRect();
    return {
      top: box.top + (rootWindow.pageYOffset || documentElement.scrollTop) - (documentElement.clientTop || 0),
      left: box.left + (rootWindow.pageXOffset || documentElement.scrollLeft) - (documentElement.clientLeft || 0)
    };
  }

  offsetLeft = elementToCheck.offsetLeft;
  offsetTop = elementToCheck.offsetTop;
  lastElem = elementToCheck;
  /* eslint-disable no-cond-assign */

  while (elementToCheck = elementToCheck.offsetParent) {
    // from my observation, document.body always has scrollLeft/scrollTop == 0
    if (elementToCheck === rootDocument.body) {
      break;
    }

    offsetLeft += elementToCheck.offsetLeft;
    offsetTop += elementToCheck.offsetTop;
    lastElem = elementToCheck;
  } // slow - http://jsperf.com/offset-vs-getboundingclientrect/6


  if (lastElem && lastElem.style.position === 'fixed') {
    // if(lastElem !== document.body) { //faster but does gives false positive in Firefox
    offsetLeft += rootWindow.pageXOffset || documentElement.scrollLeft;
    offsetTop += rootWindow.pageYOffset || documentElement.scrollTop;
  }

  return {
    left: offsetLeft,
    top: offsetTop
  };
}
/**
 * Returns the document's scrollTop property.
 *
 * @param {Window} rootWindow
 * @returns {Number}
 */
// eslint-disable-next-line no-restricted-globals


function getWindowScrollTop() {
  var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
  var res = rootWindow.scrollY;

  if (res === void 0) {
    // IE8-11
    res = rootWindow.document.documentElement.scrollTop;
  }

  return res;
}
/**
 * Returns the document's scrollLeft property.
 *
 * @param {Window} rootWindow
 * @returns {Number}
 */
// eslint-disable-next-line no-restricted-globals


function getWindowScrollLeft() {
  var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
  var res = rootWindow.scrollX;

  if (res === void 0) {
    // IE8-11
    res = rootWindow.document.documentElement.scrollLeft;
  }

  return res;
}
/**
 * Returns the provided element's scrollTop property.
 *
 * @param element
 * @param {Window} rootWindow
 * @returns {Number}
 */
// eslint-disable-next-line no-restricted-globals


function getScrollTop(element) {
  var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;

  if (element === rootWindow) {
    return getWindowScrollTop(rootWindow);
  }

  return element.scrollTop;
}
/**
 * Returns the provided element's scrollLeft property.
 *
 * @param element
 * @param {Window} rootWindow
 * @returns {Number}
 */
// eslint-disable-next-line no-restricted-globals


function getScrollLeft(element) {
  var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;

  if (element === rootWindow) {
    return getWindowScrollLeft(rootWindow);
  }

  return element.scrollLeft;
}
/**
 * Returns a DOM element responsible for scrolling of the provided element.
 *
 * @param {HTMLElement} element
 * @returns {HTMLElement} Element's scrollable parent
 */


function getScrollableElement(element) {
  var rootDocument = element.ownerDocument;
  var rootWindow = rootDocument ? rootDocument.defaultView : void 0;

  if (!rootDocument) {
    rootDocument = element.document ? element.document : element;
    rootWindow = rootDocument.defaultView;
  }

  var props = ['auto', 'scroll'];
  var supportedGetComputedStyle = (0, _feature.isGetComputedStyleSupported)();
  var el = element.parentNode;

  while (el && el.style && rootDocument.body !== el) {
    var _el$style = el.style,
        overflow = _el$style.overflow,
        overflowX = _el$style.overflowX,
        overflowY = _el$style.overflowY;

    if ([overflow, overflowX, overflowY].includes('scroll')) {
      return el;
    } else if (supportedGetComputedStyle) {
      var _rootWindow$getComput = rootWindow.getComputedStyle(el);

      overflow = _rootWindow$getComput.overflow;
      overflowX = _rootWindow$getComput.overflowX;
      overflowY = _rootWindow$getComput.overflowY;

      if (props.includes(overflow) || props.includes(overflowX) || props.includes(overflowY)) {
        return el;
      }
    } // The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome.


    if (el.clientHeight <= el.scrollHeight + 1 && (props.includes(overflowY) || props.includes(overflow))) {
      return el;
    }

    if (el.clientWidth <= el.scrollWidth + 1 && (props.includes(overflowX) || props.includes(overflow))) {
      return el;
    }

    el = el.parentNode;
  }

  return rootWindow;
}
/**
 * Returns a DOM element responsible for trimming the provided element.
 *
 * @param {HTMLElement} base Base element
 * @returns {HTMLElement} Base element's trimming parent
 */


function getTrimmingContainer(base) {
  var rootDocument = base.ownerDocument;
  var rootWindow = rootDocument.defaultView;
  var el = base.parentNode;

  while (el && el.style && rootDocument.body !== el) {
    if (el.style.overflow !== 'visible' && el.style.overflow !== '') {
      return el;
    }

    var computedStyle = getComputedStyle(el, rootWindow);
    var allowedProperties = ['scroll', 'hidden', 'auto'];
    var property = computedStyle.getPropertyValue('overflow');
    var propertyY = computedStyle.getPropertyValue('overflow-y');
    var propertyX = computedStyle.getPropertyValue('overflow-x');

    if (allowedProperties.includes(property) || allowedProperties.includes(propertyY) || allowedProperties.includes(propertyX)) {
      return el;
    }

    el = el.parentNode;
  }

  return rootWindow;
}
/**
 * Returns a style property for the provided element. (Be it an inline or external style).
 *
 * @param {HTMLElement} element
 * @param {String} prop Wanted property
 * @param {Window} rootWindow
 * @returns {String|undefined} Element's style property
 */
// eslint-disable-next-line no-restricted-globals


function getStyle(element, prop) {
  var rootWindow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window;

  if (!element) {
    return;
  } else if (element === rootWindow) {
    if (prop === 'width') {
      return "".concat(rootWindow.innerWidth, "px");
    } else if (prop === 'height') {
      return "".concat(rootWindow.innerHeight, "px");
    }

    return;
  }

  var styleProp = element.style[prop];

  if (styleProp !== '' && styleProp !== void 0) {
    return styleProp;
  }

  var computedStyle = getComputedStyle(element, rootWindow);

  if (computedStyle[prop] !== '' && computedStyle[prop] !== void 0) {
    return computedStyle[prop];
  }
}
/**
 * Returns a computed style object for the provided element. (Needed if style is declared in external stylesheet).
 *
 * @param element
 * @param {Window} rootWindow
 * @returns {IEElementStyle|CssStyle} Elements computed style object
 */
// eslint-disable-next-line no-restricted-globals


function getComputedStyle(element) {
  var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
  return element.currentStyle || rootWindow.getComputedStyle(element);
}
/**
 * Returns the element's outer width.
 *
 * @param element
 * @returns {number} Element's outer width
 */


function outerWidth(element) {
  return element.offsetWidth;
}
/**
 * Returns the element's outer height
 *
 * @param elem
 * @returns {number} Element's outer height
 */


function outerHeight(elem) {
  if ((0, _feature.hasCaptionProblem)() && elem.firstChild && elem.firstChild.nodeName === 'CAPTION') {
    // fixes problem with Firefox ignoring <caption> in TABLE.offsetHeight
    // jQuery (1.10.1) still has this unsolved
    // may be better to just switch to getBoundingClientRect
    // http://bililite.com/blog/2009/03/27/finding-the-size-of-a-table/
    // http://lists.w3.org/Archives/Public/www-style/2009Oct/0089.html
    // http://bugs.jquery.com/ticket/2196
    // http://lists.w3.org/Archives/Public/www-style/2009Oct/0140.html#start140
    return elem.offsetHeight + elem.firstChild.offsetHeight;
  }

  return elem.offsetHeight;
}
/**
 * Returns the element's inner height.
 *
 * @param element
 * @returns {number} Element's inner height
 */


function innerHeight(element) {
  return element.clientHeight || element.innerHeight;
}
/**
 * Returns the element's inner width.
 *
 * @param element
 * @returns {number} Element's inner width
 */


function innerWidth(element) {
  return element.clientWidth || element.innerWidth;
}

function addEvent(element, event, callback) {
  var rootWindow = element.defaultView;

  if (!rootWindow) {
    rootWindow = element.document ? element : element.ownerDocument.defaultView;
  }

  if (rootWindow.addEventListener) {
    element.addEventListener(event, callback, false);
  } else {
    element.attachEvent("on".concat(event), callback);
  }
}

function removeEvent(element, event, callback) {
  var rootWindow = element.defaultView;

  if (!rootWindow) {
    rootWindow = element.document ? element : element.ownerDocument.defaultView;
  }

  if (rootWindow.removeEventListener) {
    element.removeEventListener(event, callback, false);
  } else {
    element.detachEvent("on".concat(event), callback);
  }
}
/**
 * Returns caret position in text input
 *
 * @author https://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
 * @return {Number}
 */


function getCaretPosition(el) {
  var rootDocument = el.ownerDocument;

  if (el.selectionStart) {
    return el.selectionStart;
  } else if (rootDocument.selection) {
    // IE8
    el.focus();
    var r = rootDocument.selection.createRange();

    if (r === null) {
      return 0;
    }

    var re = el.createTextRange();
    var rc = re.duplicate();
    re.moveToBookmark(r.getBookmark());
    rc.setEndPoint('EndToStart', re);
    return rc.text.length;
  }

  return 0;
}
/**
 * Returns end of the selection in text input
 *
 * @return {Number}
 */


function getSelectionEndPosition(el) {
  var rootDocument = el.ownerDocument;

  if (el.selectionEnd) {
    return el.selectionEnd;
  } else if (rootDocument.selection) {
    // IE8
    var r = rootDocument.selection.createRange();

    if (r === null) {
      return 0;
    }

    var re = el.createTextRange();
    return re.text.indexOf(r.text) + r.text.length;
  }

  return 0;
}
/**
 * Returns text under selection.
 *
 * @param {Window} rootWindow
 * @returns {String}
 */
// eslint-disable-next-line no-restricted-globals


function getSelectionText() {
  var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
  var rootDocument = rootWindow.document;
  var text = '';

  if (rootWindow.getSelection) {
    text = rootWindow.getSelection().toString();
  } else if (rootDocument.selection && rootDocument.selection.type !== 'Control') {
    text = rootDocument.selection.createRange().text;
  }

  return text;
}
/**
 * Cross-platform helper to clear text selection.
 *
 * @param {Window} rootWindow
 */
// eslint-disable-next-line no-restricted-globals


function clearTextSelection() {
  var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
  var rootDocument = rootWindow.document; // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript

  if (rootWindow.getSelection) {
    if (rootWindow.getSelection().empty) {
      // Chrome
      rootWindow.getSelection().empty();
    } else if (rootWindow.getSelection().removeAllRanges) {
      // Firefox
      rootWindow.getSelection().removeAllRanges();
    }
  } else if (rootDocument.selection) {
    // IE?
    rootDocument.selection.empty();
  }
}
/**
 * Sets caret position in text input.
 *
 * @author http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/
 * @param {Element} element
 * @param {Number} pos
 * @param {Number} endPos
 */


function setCaretPosition(element, pos, endPos) {
  if (endPos === void 0) {
    endPos = pos;
  }

  if (element.setSelectionRange) {
    element.focus();

    try {
      element.setSelectionRange(pos, endPos);
    } catch (err) {
      var elementParent = element.parentNode;
      var parentDisplayValue = elementParent.style.display;
      elementParent.style.display = 'block';
      element.setSelectionRange(pos, endPos);
      elementParent.style.display = parentDisplayValue;
    }
  } else if (element.createTextRange) {
    // IE8
    var range = element.createTextRange();
    range.collapse(true);
    range.moveEnd('character', endPos);
    range.moveStart('character', pos);
    range.select();
  }
}

var cachedScrollbarWidth;
/**
 * Helper to calculate scrollbar width.
 * Source: https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes
 *
 * @private
 * @param {Document} rootDocument
 */
// eslint-disable-next-line no-restricted-globals

function walkontableCalculateScrollbarWidth() {
  var rootDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
  var inner = rootDocument.createElement('div');
  inner.style.height = '200px';
  inner.style.width = '100%';
  var outer = rootDocument.createElement('div');
  outer.style.boxSizing = 'content-box';
  outer.style.height = '150px';
  outer.style.left = '0px';
  outer.style.overflow = 'hidden';
  outer.style.position = 'absolute';
  outer.style.top = '0px';
  outer.style.width = '200px';
  outer.style.visibility = 'hidden';
  outer.appendChild(inner);
  (rootDocument.body || rootDocument.documentElement).appendChild(outer);
  var w1 = inner.offsetWidth;
  outer.style.overflow = 'scroll';
  var w2 = inner.offsetWidth;

  if (w1 === w2) {
    w2 = outer.clientWidth;
  }

  (rootDocument.body || rootDocument.documentElement).removeChild(outer);
  return w1 - w2;
}
/**
 * Returns the computed width of the native browser scroll bar.
 *
 * @param {Document} rootDocument
 * @return {Number} width
 */
// eslint-disable-next-line no-restricted-globals


function getScrollbarWidth() {
  var rootDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;

  if (cachedScrollbarWidth === void 0) {
    cachedScrollbarWidth = walkontableCalculateScrollbarWidth(rootDocument);
  }

  return cachedScrollbarWidth;
}
/**
 * Checks if the provided element has a vertical scrollbar.
 *
 * @param {HTMLElement} element
 * @returns {Boolean}
 */


function hasVerticalScrollbar(element) {
  return element.offsetWidth !== element.clientWidth;
}
/**
 * Checks if the provided element has a vertical scrollbar.
 *
 * @param {HTMLElement} element
 * @returns {Boolean}
 */


function hasHorizontalScrollbar(element) {
  return element.offsetHeight !== element.clientHeight;
}
/**
 * Sets overlay position depending on it's type and used browser
 */


function setOverlayPosition(overlayElem, left, top) {
  if ((0, _browser.isIE8)() || (0, _browser.isIE9)()) {
    overlayElem.style.top = top;
    overlayElem.style.left = left;
  } else if ((0, _browser.isSafari)()) {
    overlayElem.style['-webkit-transform'] = "translate3d(".concat(left, ",").concat(top, ",0)");
    overlayElem.style['-webkit-transform'] = "translate3d(".concat(left, ",").concat(top, ",0)");
  } else {
    overlayElem.style.transform = "translate3d(".concat(left, ",").concat(top, ",0)");
  }
}

function getCssTransform(element) {
  var transform;

  if (element.style.transform && (transform = element.style.transform) !== '') {
    return ['transform', transform];
  } else if (element.style['-webkit-transform'] && (transform = element.style['-webkit-transform']) !== '') {
    return ['-webkit-transform', transform];
  }

  return -1;
}

function resetCssTransform(element) {
  if (element.style.transform && element.style.transform !== '') {
    element.style.transform = '';
  } else if (element.style['-webkit-transform'] && element.style['-webkit-transform'] !== '') {
    element.style['-webkit-transform'] = '';
  }
}
/**
 * Determines if the given DOM element is an input field.
 * Notice: By 'input' we mean input, textarea and select nodes
 *
 * @param {HTMLElement} element - DOM element
 * @returns {Boolean}
 */


function isInput(element) {
  var inputs = ['INPUT', 'SELECT', 'TEXTAREA'];
  return element && (inputs.indexOf(element.nodeName) > -1 || element.contentEditable === 'true');
}
/**
 * Determines if the given DOM element is an input field placed OUTSIDE of HOT.
 * Notice: By 'input' we mean input, textarea and select nodes
 *
 * @param {HTMLElement} element - DOM element
 * @returns {Boolean}
 */


function isOutsideInput(element) {
  return isInput(element) && element.className.indexOf('handsontableInput') === -1 && element.className.indexOf('copyPaste') === -1;
}
/**
 * Check if the given DOM element can be focused (by using "select" method).
 *
 * @param {HTMLElement} element - DOM element
 */


function selectElementIfAllowed(element) {
  var activeElement = element.ownerDocument.activeElement;

  if (!isOutsideInput(activeElement)) {
    element.select();
  }
}

/***/ }),
/* 6 */
/***/ (function(module, exports) {

function _getPrototypeOf(o) {
  module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}

module.exports = _getPrototypeOf;

/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

var _typeof = __webpack_require__(44);

var assertThisInitialized = __webpack_require__(26);

function _possibleConstructorReturn(self, call) {
  if (call && (_typeof(call) === "object" || typeof call === "function")) {
    return call;
  }

  return assertThisInitialized(self);
}

module.exports = _possibleConstructorReturn;

/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {

var setPrototypeOf = __webpack_require__(522);

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }

  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  if (superClass) setPrototypeOf(subClass, superClass);
}

module.exports = _inherits;

/***/ }),
/* 9 */
/***/ (function(module, exports) {

function _interopRequireWildcard(obj) {
  if (obj && obj.__esModule) {
    return obj;
  } else {
    var newObj = {};

    if (obj != null) {
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};

          if (desc.get || desc.set) {
            Object.defineProperty(newObj, key, desc);
          } else {
            newObj[key] = obj[key];
          }
        }
      }
    }

    newObj["default"] = obj;
    return newObj;
  }
}

module.exports = _interopRequireWildcard;

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

var toString = __webpack_require__(514);
var ObjectPrototype = Object.prototype;

// `Object.prototype.toString` method
// https://tc39.github.io/ecma262/#sec-object.prototype.tostring
if (toString !== ObjectPrototype.toString) {
  __webpack_require__(65)(ObjectPrototype, 'toString', toString, { unsafe: true });
}


/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = exports.FILTERS_BUTTONS_PLACEHOLDER_VALUE = exports.FILTERS_BUTTONS_PLACEHOLDER_SEARCH = exports.FILTERS_BUTTONS_CANCEL = exports.FILTERS_BUTTONS_OK = exports.FILTERS_BUTTONS_CLEAR = exports.FILTERS_BUTTONS_SELECT_ALL = exports.FILTERS_VALUES_BLANK_CELLS = exports.FILTERS_LABELS_DISJUNCTION = exports.FILTERS_LABELS_CONJUNCTION = exports.FILTERS_DIVS_FILTER_BY_VALUE = exports.FILTERS_DIVS_FILTER_BY_CONDITION = exports.FILTERS_CONDITIONS_YESTERDAY = exports.FILTERS_CONDITIONS_TOMORROW = exports.FILTERS_CONDITIONS_TODAY = exports.FILTERS_CONDITIONS_BEFORE = exports.FILTERS_CONDITIONS_AFTER = exports.FILTERS_CONDITIONS_NOT_BETWEEN = exports.FILTERS_CONDITIONS_BETWEEN = exports.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = exports.FILTERS_CONDITIONS_LESS_THAN = exports.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = exports.FILTERS_CONDITIONS_GREATER_THAN = exports.FILTERS_CONDITIONS_BY_VALUE = exports.FILTERS_CONDITIONS_NOT_CONTAIN = exports.FILTERS_CONDITIONS_CONTAINS = exports.FILTERS_CONDITIONS_ENDS_WITH = exports.FILTERS_CONDITIONS_BEGINS_WITH = exports.FILTERS_CONDITIONS_NOT_EQUAL = exports.FILTERS_CONDITIONS_EQUAL = exports.FILTERS_CONDITIONS_NOT_EMPTY = exports.FILTERS_CONDITIONS_EMPTY = exports.FILTERS_CONDITIONS_NONE = exports.FILTERS_CONDITIONS_NAMESPACE = exports.FILTERS_NAMESPACE = exports.CONTEXTMENU_ITEMS_SHOW_ROW = exports.CONTEXTMENU_ITEMS_HIDE_ROW = exports.CONTEXTMENU_ITEMS_SHOW_COLUMN = exports.CONTEXTMENU_ITEMS_HIDE_COLUMN = exports.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = exports.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = exports.CONTEXTMENU_ITEMS_REMOVE_BORDERS = exports.CONTEXTMENU_ITEMS_BORDERS_LEFT = exports.CONTEXTMENU_ITEMS_BORDERS_BOTTOM = exports.CONTEXTMENU_ITEMS_BORDERS_RIGHT = exports.CONTEXTMENU_ITEMS_BORDERS_TOP = exports.CONTEXTMENU_ITEMS_BORDERS = exports.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = exports.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = exports.CONTEXTMENU_ITEMS_ALIGNMENT_TOP = exports.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = exports.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = exports.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = exports.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = exports.CONTEXTMENU_ITEMS_ALIGNMENT = exports.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = exports.CONTEXTMENU_ITEMS_REMOVE_COMMENT = exports.CONTEXTMENU_ITEMS_EDIT_COMMENT = exports.CONTEXTMENU_ITEMS_ADD_COMMENT = exports.CONTEXTMENU_ITEMS_UNMERGE_CELLS = exports.CONTEXTMENU_ITEMS_MERGE_CELLS = exports.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = exports.CONTEXTMENU_ITEMS_FREEZE_COLUMN = exports.CONTEXTMENU_ITEMS_CUT = exports.CONTEXTMENU_ITEMS_COPY = exports.CONTEXTMENU_ITEMS_CLEAR_COLUMN = exports.CONTEXTMENU_ITEMS_READ_ONLY = exports.CONTEXTMENU_ITEMS_REDO = exports.CONTEXTMENU_ITEMS_UNDO = exports.CONTEXTMENU_ITEMS_REMOVE_COLUMN = exports.CONTEXTMENU_ITEMS_REMOVE_ROW = exports.CONTEXTMENU_ITEMS_INSERT_RIGHT = exports.CONTEXTMENU_ITEMS_INSERT_LEFT = exports.CONTEXTMENU_ITEMS_ROW_BELOW = exports.CONTEXTMENU_ITEMS_ROW_ABOVE = exports.CONTEXTMENU_ITEMS_NO_ITEMS = exports.CONTEXT_MENU_ITEMS_NAMESPACE = void 0;

/**
 * Constants for parts of translation.
 */
var CONTEXT_MENU_ITEMS_NAMESPACE = 'ContextMenu:items';
exports.CONTEXT_MENU_ITEMS_NAMESPACE = CONTEXT_MENU_ITEMS_NAMESPACE;
var CONTEXTMENU_ITEMS_NO_ITEMS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".noItems");
exports.CONTEXTMENU_ITEMS_NO_ITEMS = CONTEXTMENU_ITEMS_NO_ITEMS;
var CONTEXTMENU_ITEMS_ROW_ABOVE = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertRowAbove");
exports.CONTEXTMENU_ITEMS_ROW_ABOVE = CONTEXTMENU_ITEMS_ROW_ABOVE;
var CONTEXTMENU_ITEMS_ROW_BELOW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertRowBelow");
exports.CONTEXTMENU_ITEMS_ROW_BELOW = CONTEXTMENU_ITEMS_ROW_BELOW;
var CONTEXTMENU_ITEMS_INSERT_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertColumnOnTheLeft");
exports.CONTEXTMENU_ITEMS_INSERT_LEFT = CONTEXTMENU_ITEMS_INSERT_LEFT;
var CONTEXTMENU_ITEMS_INSERT_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertColumnOnTheRight");
exports.CONTEXTMENU_ITEMS_INSERT_RIGHT = CONTEXTMENU_ITEMS_INSERT_RIGHT;
var CONTEXTMENU_ITEMS_REMOVE_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeRow");
exports.CONTEXTMENU_ITEMS_REMOVE_ROW = CONTEXTMENU_ITEMS_REMOVE_ROW;
var CONTEXTMENU_ITEMS_REMOVE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeColumn");
exports.CONTEXTMENU_ITEMS_REMOVE_COLUMN = CONTEXTMENU_ITEMS_REMOVE_COLUMN;
var CONTEXTMENU_ITEMS_UNDO = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".undo");
exports.CONTEXTMENU_ITEMS_UNDO = CONTEXTMENU_ITEMS_UNDO;
var CONTEXTMENU_ITEMS_REDO = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".redo");
exports.CONTEXTMENU_ITEMS_REDO = CONTEXTMENU_ITEMS_REDO;
var CONTEXTMENU_ITEMS_READ_ONLY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".readOnly");
exports.CONTEXTMENU_ITEMS_READ_ONLY = CONTEXTMENU_ITEMS_READ_ONLY;
var CONTEXTMENU_ITEMS_CLEAR_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".clearColumn");
exports.CONTEXTMENU_ITEMS_CLEAR_COLUMN = CONTEXTMENU_ITEMS_CLEAR_COLUMN;
var CONTEXTMENU_ITEMS_COPY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".copy");
exports.CONTEXTMENU_ITEMS_COPY = CONTEXTMENU_ITEMS_COPY;
var CONTEXTMENU_ITEMS_CUT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".cut");
exports.CONTEXTMENU_ITEMS_CUT = CONTEXTMENU_ITEMS_CUT;
var CONTEXTMENU_ITEMS_FREEZE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".freezeColumn");
exports.CONTEXTMENU_ITEMS_FREEZE_COLUMN = CONTEXTMENU_ITEMS_FREEZE_COLUMN;
var CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".unfreezeColumn");
exports.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = CONTEXTMENU_ITEMS_UNFREEZE_COLUMN;
var CONTEXTMENU_ITEMS_MERGE_CELLS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".mergeCells");
exports.CONTEXTMENU_ITEMS_MERGE_CELLS = CONTEXTMENU_ITEMS_MERGE_CELLS;
var CONTEXTMENU_ITEMS_UNMERGE_CELLS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".unmergeCells");
exports.CONTEXTMENU_ITEMS_UNMERGE_CELLS = CONTEXTMENU_ITEMS_UNMERGE_CELLS;
var CONTEXTMENU_ITEMS_ADD_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".addComment");
exports.CONTEXTMENU_ITEMS_ADD_COMMENT = CONTEXTMENU_ITEMS_ADD_COMMENT;
var CONTEXTMENU_ITEMS_EDIT_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".editComment");
exports.CONTEXTMENU_ITEMS_EDIT_COMMENT = CONTEXTMENU_ITEMS_EDIT_COMMENT;
var CONTEXTMENU_ITEMS_REMOVE_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeComment");
exports.CONTEXTMENU_ITEMS_REMOVE_COMMENT = CONTEXTMENU_ITEMS_REMOVE_COMMENT;
var CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".readOnlyComment");
exports.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = CONTEXTMENU_ITEMS_READ_ONLY_COMMENT;
var CONTEXTMENU_ITEMS_ALIGNMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align");
exports.CONTEXTMENU_ITEMS_ALIGNMENT = CONTEXTMENU_ITEMS_ALIGNMENT;
var CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.left");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = CONTEXTMENU_ITEMS_ALIGNMENT_LEFT;
var CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.center");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = CONTEXTMENU_ITEMS_ALIGNMENT_CENTER;
var CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.right");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT;
var CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.justify");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY;
var CONTEXTMENU_ITEMS_ALIGNMENT_TOP = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.top");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_TOP = CONTEXTMENU_ITEMS_ALIGNMENT_TOP;
var CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.middle");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE;
var CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.bottom");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM;
var CONTEXTMENU_ITEMS_BORDERS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders");
exports.CONTEXTMENU_ITEMS_BORDERS = CONTEXTMENU_ITEMS_BORDERS;
var CONTEXTMENU_ITEMS_BORDERS_TOP = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.top");
exports.CONTEXTMENU_ITEMS_BORDERS_TOP = CONTEXTMENU_ITEMS_BORDERS_TOP;
var CONTEXTMENU_ITEMS_BORDERS_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.right");
exports.CONTEXTMENU_ITEMS_BORDERS_RIGHT = CONTEXTMENU_ITEMS_BORDERS_RIGHT;
var CONTEXTMENU_ITEMS_BORDERS_BOTTOM = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.bottom");
exports.CONTEXTMENU_ITEMS_BORDERS_BOTTOM = CONTEXTMENU_ITEMS_BORDERS_BOTTOM;
var CONTEXTMENU_ITEMS_BORDERS_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.left");
exports.CONTEXTMENU_ITEMS_BORDERS_LEFT = CONTEXTMENU_ITEMS_BORDERS_LEFT;
var CONTEXTMENU_ITEMS_REMOVE_BORDERS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.remove");
exports.CONTEXTMENU_ITEMS_REMOVE_BORDERS = CONTEXTMENU_ITEMS_REMOVE_BORDERS;
var CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".nestedHeaders.insertChildRow");
exports.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD;
var CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".nestedHeaders.detachFromParent");
exports.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD;
var CONTEXTMENU_ITEMS_HIDE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".hideColumn");
exports.CONTEXTMENU_ITEMS_HIDE_COLUMN = CONTEXTMENU_ITEMS_HIDE_COLUMN;
var CONTEXTMENU_ITEMS_SHOW_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".showColumn");
exports.CONTEXTMENU_ITEMS_SHOW_COLUMN = CONTEXTMENU_ITEMS_SHOW_COLUMN;
var CONTEXTMENU_ITEMS_HIDE_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".hideRow");
exports.CONTEXTMENU_ITEMS_HIDE_ROW = CONTEXTMENU_ITEMS_HIDE_ROW;
var CONTEXTMENU_ITEMS_SHOW_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".showRow");
exports.CONTEXTMENU_ITEMS_SHOW_ROW = CONTEXTMENU_ITEMS_SHOW_ROW;
var FILTERS_NAMESPACE = 'Filters:';
exports.FILTERS_NAMESPACE = FILTERS_NAMESPACE;
var FILTERS_CONDITIONS_NAMESPACE = "".concat(FILTERS_NAMESPACE, "conditions");
exports.FILTERS_CONDITIONS_NAMESPACE = FILTERS_CONDITIONS_NAMESPACE;
var FILTERS_CONDITIONS_NONE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".none");
exports.FILTERS_CONDITIONS_NONE = FILTERS_CONDITIONS_NONE;
var FILTERS_CONDITIONS_EMPTY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isEmpty");
exports.FILTERS_CONDITIONS_EMPTY = FILTERS_CONDITIONS_EMPTY;
var FILTERS_CONDITIONS_NOT_EMPTY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotEmpty");
exports.FILTERS_CONDITIONS_NOT_EMPTY = FILTERS_CONDITIONS_NOT_EMPTY;
var FILTERS_CONDITIONS_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isEqualTo");
exports.FILTERS_CONDITIONS_EQUAL = FILTERS_CONDITIONS_EQUAL;
var FILTERS_CONDITIONS_NOT_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotEqualTo");
exports.FILTERS_CONDITIONS_NOT_EQUAL = FILTERS_CONDITIONS_NOT_EQUAL;
var FILTERS_CONDITIONS_BEGINS_WITH = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".beginsWith");
exports.FILTERS_CONDITIONS_BEGINS_WITH = FILTERS_CONDITIONS_BEGINS_WITH;
var FILTERS_CONDITIONS_ENDS_WITH = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".endsWith");
exports.FILTERS_CONDITIONS_ENDS_WITH = FILTERS_CONDITIONS_ENDS_WITH;
var FILTERS_CONDITIONS_CONTAINS = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".contains");
exports.FILTERS_CONDITIONS_CONTAINS = FILTERS_CONDITIONS_CONTAINS;
var FILTERS_CONDITIONS_NOT_CONTAIN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".doesNotContain");
exports.FILTERS_CONDITIONS_NOT_CONTAIN = FILTERS_CONDITIONS_NOT_CONTAIN;
var FILTERS_CONDITIONS_BY_VALUE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".byValue");
exports.FILTERS_CONDITIONS_BY_VALUE = FILTERS_CONDITIONS_BY_VALUE;
var FILTERS_CONDITIONS_GREATER_THAN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".greaterThan");
exports.FILTERS_CONDITIONS_GREATER_THAN = FILTERS_CONDITIONS_GREATER_THAN;
var FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".greaterThanOrEqualTo");
exports.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL;
var FILTERS_CONDITIONS_LESS_THAN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".lessThan");
exports.FILTERS_CONDITIONS_LESS_THAN = FILTERS_CONDITIONS_LESS_THAN;
var FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".lessThanOrEqualTo");
exports.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL;
var FILTERS_CONDITIONS_BETWEEN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isBetween");
exports.FILTERS_CONDITIONS_BETWEEN = FILTERS_CONDITIONS_BETWEEN;
var FILTERS_CONDITIONS_NOT_BETWEEN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotBetween");
exports.FILTERS_CONDITIONS_NOT_BETWEEN = FILTERS_CONDITIONS_NOT_BETWEEN;
var FILTERS_CONDITIONS_AFTER = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".after");
exports.FILTERS_CONDITIONS_AFTER = FILTERS_CONDITIONS_AFTER;
var FILTERS_CONDITIONS_BEFORE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".before");
exports.FILTERS_CONDITIONS_BEFORE = FILTERS_CONDITIONS_BEFORE;
var FILTERS_CONDITIONS_TODAY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".today");
exports.FILTERS_CONDITIONS_TODAY = FILTERS_CONDITIONS_TODAY;
var FILTERS_CONDITIONS_TOMORROW = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".tomorrow");
exports.FILTERS_CONDITIONS_TOMORROW = FILTERS_CONDITIONS_TOMORROW;
var FILTERS_CONDITIONS_YESTERDAY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".yesterday");
exports.FILTERS_CONDITIONS_YESTERDAY = FILTERS_CONDITIONS_YESTERDAY;
var FILTERS_DIVS_FILTER_BY_CONDITION = "".concat(FILTERS_NAMESPACE, "labels.filterByCondition");
exports.FILTERS_DIVS_FILTER_BY_CONDITION = FILTERS_DIVS_FILTER_BY_CONDITION;
var FILTERS_DIVS_FILTER_BY_VALUE = "".concat(FILTERS_NAMESPACE, "labels.filterByValue");
exports.FILTERS_DIVS_FILTER_BY_VALUE = FILTERS_DIVS_FILTER_BY_VALUE;
var FILTERS_LABELS_CONJUNCTION = "".concat(FILTERS_NAMESPACE, "labels.conjunction");
exports.FILTERS_LABELS_CONJUNCTION = FILTERS_LABELS_CONJUNCTION;
var FILTERS_LABELS_DISJUNCTION = "".concat(FILTERS_NAMESPACE, "labels.disjunction");
exports.FILTERS_LABELS_DISJUNCTION = FILTERS_LABELS_DISJUNCTION;
var FILTERS_VALUES_BLANK_CELLS = "".concat(FILTERS_NAMESPACE, "values.blankCells");
exports.FILTERS_VALUES_BLANK_CELLS = FILTERS_VALUES_BLANK_CELLS;
var FILTERS_BUTTONS_SELECT_ALL = "".concat(FILTERS_NAMESPACE, "buttons.selectAll");
exports.FILTERS_BUTTONS_SELECT_ALL = FILTERS_BUTTONS_SELECT_ALL;
var FILTERS_BUTTONS_CLEAR = "".concat(FILTERS_NAMESPACE, "buttons.clear");
exports.FILTERS_BUTTONS_CLEAR = FILTERS_BUTTONS_CLEAR;
var FILTERS_BUTTONS_OK = "".concat(FILTERS_NAMESPACE, "buttons.ok");
exports.FILTERS_BUTTONS_OK = FILTERS_BUTTONS_OK;
var FILTERS_BUTTONS_CANCEL = "".concat(FILTERS_NAMESPACE, "buttons.cancel");
exports.FILTERS_BUTTONS_CANCEL = FILTERS_BUTTONS_CANCEL;
var FILTERS_BUTTONS_PLACEHOLDER_SEARCH = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.search");
exports.FILTERS_BUTTONS_PLACEHOLDER_SEARCH = FILTERS_BUTTONS_PLACEHOLDER_SEARCH;
var FILTERS_BUTTONS_PLACEHOLDER_VALUE = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.value");
exports.FILTERS_BUTTONS_PLACEHOLDER_VALUE = FILTERS_BUTTONS_PLACEHOLDER_VALUE;
var FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.secondValue");
exports.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE;

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalIndexOf = __webpack_require__(140)(false);
var nativeIndexOf = [].indexOf;

var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
var SLOPPY_METHOD = __webpack_require__(126)('indexOf');

// `Array.prototype.indexOf` method
// https://tc39.github.io/ecma262/#sec-array.prototype.indexof
__webpack_require__(22)({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || SLOPPY_METHOD }, {
  indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? nativeIndexOf.apply(this, arguments) || 0
      : internalIndexOf(this, searchElement, arguments[1]);
  }
});


/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

var getPrototypeOf = __webpack_require__(6);

var superPropBase = __webpack_require__(535);

function _get(target, property, receiver) {
  if (typeof Reflect !== "undefined" && Reflect.get) {
    module.exports = _get = Reflect.get;
  } else {
    module.exports = _get = function _get(target, property, receiver) {
      var base = superPropBase(target, property);
      if (!base) return;
      var desc = Object.getOwnPropertyDescriptor(base, property);

      if (desc.get) {
        return desc.get.call(receiver);
      }

      return desc.value;
    };
  }

  return _get(target, property, receiver || target);
}

module.exports = _get;

/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var codePointAt = __webpack_require__(146);
var InternalStateModule = __webpack_require__(87);
var defineIterator = __webpack_require__(144);
var STRING_ITERATOR = 'String Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);

// `String.prototype[@@iterator]` method
// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator
defineIterator(String, 'String', function (iterated) {
  setInternalState(this, {
    type: STRING_ITERATOR,
    string: String(iterated),
    index: 0
  });
// `%StringIteratorPrototype%.next` method
// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next
}, function next() {
  var state = getInternalState(this);
  var string = state.string;
  var index = state.index;
  var point;
  if (index >= string.length) return { value: undefined, done: true };
  point = codePointAt(string, index, true);
  state.index += point.length;
  return { value: point, done: false };
});


/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(37);

exports.__esModule = true;
exports.isNumeric = isNumeric;
exports.rangeEach = rangeEach;
exports.rangeEachReverse = rangeEachReverse;
exports.valueAccordingPercent = valueAccordingPercent;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

/**
 * Checks if value of n is a numeric one
 * http://jsperf.com/isnan-vs-isnumeric/4
 * @param n
 * @returns {boolean}
 */
function isNumeric(n) {
  /* eslint-disable */
  var t = (0, _typeof2.default)(n);
  return t == 'number' ? !isNaN(n) && isFinite(n) : t == 'string' ? !n.length ? false : n.length == 1 ? /\d/.test(n) : /^\s*[+-]?\s*(?:(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?)|(?:0x[a-f\d]+))\s*$/i.test(n) : t == 'object' ? !!n && typeof n.valueOf() == 'number' && !(n instanceof Date) : false;
}
/**
 * A specialized version of `.forEach` defined by ranges.
 *
 * @param {Number} rangeFrom The number from start iterate.
 * @param {Number|Function} rangeTo The number where finish iterate or function as a iteratee.
 * @param {Function} [iteratee] The function invoked per iteration.
 */


function rangeEach(rangeFrom, rangeTo, iteratee) {
  var index = -1;

  if (typeof rangeTo === 'function') {
    iteratee = rangeTo;
    rangeTo = rangeFrom;
  } else {
    index = rangeFrom - 1;
  }

  while (++index <= rangeTo) {
    if (iteratee(index) === false) {
      break;
    }
  }
}
/**
 * A specialized version of `.forEach` defined by ranges iterable in reverse order.
 *
 * @param {Number} rangeFrom The number from start iterate.
 * @param {Number|Function} rangeTo The number where finish iterate or function as a iteratee.
 * @param {Function} [iteratee] The function invoked per iteration.
 */


function rangeEachReverse(rangeFrom, rangeTo, iteratee) {
  var index = rangeFrom + 1;

  if (typeof rangeTo === 'function') {
    iteratee = rangeTo;
    rangeTo = 0;
  }

  while (--index >= rangeTo) {
    if (iteratee(index) === false) {
      break;
    }
  }
}
/**
 * Calculate value from percent.
 *
 * @param {Number} value Base value from percent will be calculated.
 * @param {String|Number} percent Can be Number or String (eq. `'33%'`).
 * @returns {Number}
 */


function valueAccordingPercent(value, percent) {
  percent = parseInt(percent.toString().replace('%', ''), 10);
  percent = parseInt(value * percent / 100, 10);
  return percent;
}

/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toIndexedObject = __webpack_require__(69);
var addToUnscopables = __webpack_require__(121);
var Iterators = __webpack_require__(100);
var InternalStateModule = __webpack_require__(87);
var defineIterator = __webpack_require__(144);
var ARRAY_ITERATOR = 'Array Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);

// `Array.prototype.entries` method
// https://tc39.github.io/ecma262/#sec-array.prototype.entries
// `Array.prototype.keys` method
// https://tc39.github.io/ecma262/#sec-array.prototype.keys
// `Array.prototype.values` method
// https://tc39.github.io/ecma262/#sec-array.prototype.values
// `Array.prototype[@@iterator]` method
// https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator
// `CreateArrayIterator` internal method
// https://tc39.github.io/ecma262/#sec-createarrayiterator
module.exports = defineIterator(Array, 'Array', function (iterated, kind) {
  setInternalState(this, {
    type: ARRAY_ITERATOR,
    target: toIndexedObject(iterated), // target
    index: 0,                          // next index
    kind: kind                         // kind
  });
// `%ArrayIteratorPrototype%.next` method
// https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next
}, function () {
  var state = getInternalState(this);
  var target = state.target;
  var kind = state.kind;
  var index = state.index++;
  if (!target || index >= target.length) {
    state.target = undefined;
    return { value: undefined, done: true };
  }
  if (kind == 'keys') return { value: index, done: false };
  if (kind == 'values') return { value: target[index], done: false };
  return { value: [index, target[index]], done: false };
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values%
// https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
// https://tc39.github.io/ecma262/#sec-createmappedargumentsobject
Iterators.Arguments = Iterators.Array;

// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');


/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {

var DOMIterables = __webpack_require__(191);
var ArrayIteratorMethods = __webpack_require__(16);
var global = __webpack_require__(32);
var hide = __webpack_require__(61);
var wellKnownSymbol = __webpack_require__(35);
var ITERATOR = wellKnownSymbol('iterator');
var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var ArrayValues = ArrayIteratorMethods.values;

for (var COLLECTION_NAME in DOMIterables) {
  var Collection = global[COLLECTION_NAME];
  var CollectionPrototype = Collection && Collection.prototype;
  if (CollectionPrototype) {
    // some Chrome versions have non-configurable methods on DOMTokenList
    if (CollectionPrototype[ITERATOR] !== ArrayValues) try {
      hide(CollectionPrototype, ITERATOR, ArrayValues);
    } catch (e) {
      CollectionPrototype[ITERATOR] = ArrayValues;
    }
    if (!CollectionPrototype[TO_STRING_TAG]) hide(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);
    if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) {
      // some Chrome versions have non-configurable methods on DOMTokenList
      if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try {
        hide(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]);
      } catch (e) {
        CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME];
      }
    }
  }
}


/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var isArray = __webpack_require__(124);
var isObject = __webpack_require__(42);
var toObject = __webpack_require__(62);
var toLength = __webpack_require__(48);
var createProperty = __webpack_require__(127);
var arraySpeciesCreate = __webpack_require__(151);
var IS_CONCAT_SPREADABLE = __webpack_require__(35)('isConcatSpreadable');
var MAX_SAFE_INTEGER = 0x1fffffffffffff;
var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';

var IS_CONCAT_SPREADABLE_SUPPORT = !__webpack_require__(29)(function () {
  var array = [];
  array[IS_CONCAT_SPREADABLE] = false;
  return array.concat()[0] !== array;
});

var SPECIES_SUPPORT = __webpack_require__(103)('concat');

var isConcatSpreadable = function (O) {
  if (!isObject(O)) return false;
  var spreadable = O[IS_CONCAT_SPREADABLE];
  return spreadable !== undefined ? !!spreadable : isArray(O);
};

var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;

// `Array.prototype.concat` method
// https://tc39.github.io/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: FORCED }, {
  concat: function concat(arg) { // eslint-disable-line no-unused-vars
    var O = toObject(this);
    var A = arraySpeciesCreate(O, 0);
    var n = 0;
    var i, k, length, len, E;
    for (i = -1, length = arguments.length; i < length; i++) {
      E = i === -1 ? O : arguments[i];
      if (isConcatSpreadable(E)) {
        len = toLength(E.length);
        if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
        for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
      } else {
        if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
        createProperty(A, n++, E);
      }
    }
    A.length = n;
    return A;
  }
});


/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {

var arrayWithHoles = __webpack_require__(332);

var iterableToArrayLimit = __webpack_require__(527);

var nonIterableRest = __webpack_require__(333);

function _slicedToArray(arr, i) {
  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
}

module.exports = _slicedToArray;

/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(76);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.registerPlugin = registerPlugin;
exports.getPlugin = getPlugin;
exports.getRegistredPluginNames = getRegistredPluginNames;
exports.getPluginName = getPluginName;

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _object = __webpack_require__(4);

var _string = __webpack_require__(68);

/**
 * Utility to register plugins and common namespace for keeping reference to all plugins classes
 */
var registeredPlugins = new WeakMap();
/**
 * Registers plugin under given name
 *
 * @param {String} pluginName
 * @param {Function} PluginClass
 */

function registerPlugin(pluginName, PluginClass) {
  var correctedPluginName = (0, _string.toUpperCaseFirst)(pluginName);

  _pluginHooks.default.getSingleton().add('construct', function () {
    if (!registeredPlugins.has(this)) {
      registeredPlugins.set(this, {});
    }

    var holder = registeredPlugins.get(this);

    if (!holder[correctedPluginName]) {
      holder[correctedPluginName] = new PluginClass(this);
    }
  });

  _pluginHooks.default.getSingleton().add('afterDestroy', function () {
    if (registeredPlugins.has(this)) {
      var pluginsHolder = registeredPlugins.get(this);
      (0, _object.objectEach)(pluginsHolder, function (plugin) {
        return plugin.destroy();
      });
      registeredPlugins.delete(this);
    }
  });
}
/**
 * @param {Object} instance
 * @param {String|Function} pluginName
 * @returns {Function} pluginClass Returns plugin instance if exists or `undefined` if not exists.
 */


function getPlugin(instance, pluginName) {
  if (typeof pluginName !== 'string') {
    throw Error('Only strings can be passed as "plugin" parameter');
  }

  var _pluginName = (0, _string.toUpperCaseFirst)(pluginName);

  if (!registeredPlugins.has(instance) || !registeredPlugins.get(instance)[_pluginName]) {
    return void 0;
  }

  return registeredPlugins.get(instance)[_pluginName];
}
/**
 * Get all registred plugins names for concrete Handsontable instance.
 *
 * @param {Object} hotInstance
 * @returns {Array}
 */


function getRegistredPluginNames(hotInstance) {
  return registeredPlugins.has(hotInstance) ? Object.keys(registeredPlugins.get(hotInstance)) : [];
}
/**
 * Get plugin name.
 *
 * @param {Object} hotInstance
 * @param {Object} plugin
 * @returns {String|null}
 */


function getPluginName(hotInstance, plugin) {
  var pluginName = null;

  if (registeredPlugins.has(hotInstance)) {
    (0, _object.objectEach)(registeredPlugins.get(hotInstance), function (pluginInstance, name) {
      if (pluginInstance === plugin) {
        pluginName = name;
      }
    });
  }

  return pluginName;
}

/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(33);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _recordTranslator = __webpack_require__(90);

var _plugins = __webpack_require__(20);

var privatePool = new WeakMap();
var initializedPlugins = null;
/**
 * @util
 */

var BasePlugin =
/*#__PURE__*/
function () {
  /**
   * @param {Object} hotInstance Handsontable instance.
   */
  function BasePlugin(hotInstance) {
    var _this = this;

    (0, _classCallCheck2.default)(this, BasePlugin);

    /**
     * Handsontable instance.
     *
     * @type {Core}
     */
    (0, _object.defineGetter)(this, 'hot', hotInstance, {
      writable: false
    });
    (0, _object.defineGetter)(this, 't', (0, _recordTranslator.getTranslator)(hotInstance), {
      writable: false
    });
    privatePool.set(this, {
      hooks: {}
    });
    initializedPlugins = null;
    this.pluginName = null;
    this.pluginsInitializedCallbacks = [];
    this.isPluginsReady = false;
    this.enabled = false;
    this.initialized = false;
    this.hot.addHook('afterPluginsInitialized', function () {
      return _this.onAfterPluginsInitialized();
    });
    this.hot.addHook('afterUpdateSettings', function (newSettings) {
      return _this.onUpdateSettings(newSettings);
    });
    this.hot.addHook('beforeInit', function () {
      return _this.init();
    });
  }

  (0, _createClass2.default)(BasePlugin, [{
    key: "init",
    value: function init() {
      this.pluginName = (0, _plugins.getPluginName)(this.hot, this);

      if (this.isEnabled && this.isEnabled()) {
        this.enablePlugin();
      }

      if (!initializedPlugins) {
        initializedPlugins = (0, _plugins.getRegistredPluginNames)(this.hot);
      }

      if (initializedPlugins.indexOf(this.pluginName) >= 0) {
        initializedPlugins.splice(initializedPlugins.indexOf(this.pluginName), 1);
      }

      if (!initializedPlugins.length) {
        this.hot.runHooks('afterPluginsInitialized');
      }

      this.initialized = true;
    }
    /**
     * Enable plugin for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      this.enabled = true;
    }
    /**
     * Disable plugin for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      if (this.eventManager) {
        this.eventManager.clear();
      }

      this.clearHooks();
      this.enabled = false;
    }
    /**
     * Add listener to plugin hooks system.
     *
     * @param {String} name
     * @param {Function} callback
     */

  }, {
    key: "addHook",
    value: function addHook(name, callback) {
      privatePool.get(this).hooks[name] = privatePool.get(this).hooks[name] || [];
      var hooks = privatePool.get(this).hooks[name];
      this.hot.addHook(name, callback);
      hooks.push(callback);
      privatePool.get(this).hooks[name] = hooks;
    }
    /**
     * Remove all hooks listeners by hook name.
     *
     * @param {String} name
     */

  }, {
    key: "removeHooks",
    value: function removeHooks(name) {
      var _this2 = this;

      (0, _array.arrayEach)(privatePool.get(this).hooks[name] || [], function (callback) {
        _this2.hot.removeHook(name, callback);
      });
    }
    /**
     * Clear all hooks.
     */

  }, {
    key: "clearHooks",
    value: function clearHooks() {
      var _this3 = this;

      var hooks = privatePool.get(this).hooks;
      (0, _object.objectEach)(hooks, function (callbacks, name) {
        return _this3.removeHooks(name);
      });
      hooks.length = 0;
    }
    /**
     * Register function which will be immediately called after all plugins initialized.
     *
     * @param {Function} callback
     */

  }, {
    key: "callOnPluginsReady",
    value: function callOnPluginsReady(callback) {
      if (this.isPluginsReady) {
        callback();
      } else {
        this.pluginsInitializedCallbacks.push(callback);
      }
    }
    /**
     * On after plugins initialized listener.
     *
     * @private
     */

  }, {
    key: "onAfterPluginsInitialized",
    value: function onAfterPluginsInitialized() {
      (0, _array.arrayEach)(this.pluginsInitializedCallbacks, function (callback) {
        return callback();
      });
      this.pluginsInitializedCallbacks.length = 0;
      this.isPluginsReady = true;
    }
    /**
     * On update settings listener.
     *
     * @private
     */

  }, {
    key: "onUpdateSettings",
    value: function onUpdateSettings() {
      if (this.isEnabled) {
        if (this.enabled && !this.isEnabled()) {
          this.disablePlugin();
        }

        if (!this.enabled && this.isEnabled()) {
          this.enablePlugin();
        }

        if (this.enabled && this.isEnabled()) {
          this.updatePlugin();
        }
      }
    }
    /**
     * Updates the plugin to use the latest options you have specified.
     *
     * @private
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {}
    /**
     * Destroy plugin.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      var _this4 = this;

      if (this.eventManager) {
        this.eventManager.destroy();
      }

      this.clearHooks();
      (0, _object.objectEach)(this, function (value, property) {
        if (property !== 'hot' && property !== 't') {
          _this4[property] = null;
        }
      });
      delete this.t;
      delete this.hot;
    }
  }]);
  return BasePlugin;
}();

var _default = BasePlugin;
exports.default = _default;

/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var getOwnPropertyDescriptor = __webpack_require__(115).f;
var hide = __webpack_require__(61);
var redefine = __webpack_require__(65);
var setGlobal = __webpack_require__(143);
var copyConstructorProperties = __webpack_require__(179);
var isForced = __webpack_require__(120);

/*
  options.target      - name of the target object
  options.global      - target is the global object
  options.stat        - export as static methods of target
  options.proto       - export as prototype methods of target
  options.real        - real prototype method for the `pure` version
  options.forced      - export even if the native feature is available
  options.bind        - bind methods to the target, required for the `pure` version
  options.wrap        - wrap constructors to preventing global pollution, required for the `pure` version
  options.unsafe      - use the simple assignment of property instead of delete + defineProperty
  options.sham        - add a flag to not completely full polyfills
  options.enumerable  - export as enumerable property
  options.noTargetGet - prevent calling a getter on target
*/
module.exports = function (options, source) {
  var TARGET = options.target;
  var GLOBAL = options.global;
  var STATIC = options.stat;
  var FORCED, target, key, targetProperty, sourceProperty, descriptor;
  if (GLOBAL) {
    target = global;
  } else if (STATIC) {
    target = global[TARGET] || setGlobal(TARGET, {});
  } else {
    target = (global[TARGET] || {}).prototype;
  }
  if (target) for (key in source) {
    sourceProperty = source[key];
    if (options.noTargetGet) {
      descriptor = getOwnPropertyDescriptor(target, key);
      targetProperty = descriptor && descriptor.value;
    } else targetProperty = target[key];
    FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
    // contained in target
    if (!FORCED && targetProperty !== undefined) {
      if (typeof sourceProperty === typeof targetProperty) continue;
      copyConstructorProperties(sourceProperty, targetProperty);
    }
    // add a flag to not completely full polyfills
    if (options.sham || (targetProperty && targetProperty.sham)) {
      hide(sourceProperty, 'sham', true);
    }
    // extend global
    redefine(target, key, sourceProperty, options);
  }
};


/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(33);

exports.__esModule = true;
exports.getListenersCounter = getListenersCounter;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _feature = __webpack_require__(73);

var _event = __webpack_require__(31);

/**
 * Counter which tracks unregistered listeners (useful for detecting memory leaks).
 *
 * @type {Number}
 */
var listenersCounter = 0;
/**
 * Event DOM manager for internal use in Handsontable.
 *
 * @class EventManager
 * @util
 */

var EventManager =
/*#__PURE__*/
function () {
  /**
   * @param {Object} [context=null]
   * @private
   */
  function EventManager() {
    var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
    (0, _classCallCheck2.default)(this, EventManager);
    this.context = context || this;

    if (!this.context.eventListeners) {
      this.context.eventListeners = [];
    }
  }
  /**
   * Register specified listener (`eventName`) to the element.
   *
   * @param {Element} element Target element.
   * @param {String} eventName Event name.
   * @param {Function} callback Function which will be called after event occur.
   * @param {AddEventListenerOptions|Boolean} [options] Listener options if object or useCapture if boolean.
   * @returns {Function} Returns function which you can easily call to remove that event
   */


  (0, _createClass2.default)(EventManager, [{
    key: "addEventListener",
    value: function addEventListener(element, eventName, callback) {
      var _this = this;

      var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
      var context = this.context;

      function callbackProxy(event) {
        callback.call(this, extendEvent(context, event));
      }

      if (typeof options !== 'boolean' && !(0, _feature.isPassiveEventSupported)()) {
        options = false;
      }

      this.context.eventListeners.push({
        element: element,
        event: eventName,
        callback: callback,
        callbackProxy: callbackProxy,
        options: options
      });
      element.addEventListener(eventName, callbackProxy, options);
      listenersCounter += 1;
      return function () {
        _this.removeEventListener(element, eventName, callback);
      };
    }
    /**
     * Remove the event listener previously registered.
     *
     * @param {Element} element Target element.
     * @param {String} eventName Event name.
     * @param {Function} callback Function to remove from the event target. It must be the same as during registration listener.
     */

  }, {
    key: "removeEventListener",
    value: function removeEventListener(element, eventName, callback) {
      var len = this.context.eventListeners.length;
      var tmpEvent;

      while (len) {
        len -= 1;
        tmpEvent = this.context.eventListeners[len];

        if (tmpEvent.event === eventName && tmpEvent.element === element) {
          if (callback && callback !== tmpEvent.callback) {
            /* eslint-disable no-continue */
            continue;
          }

          this.context.eventListeners.splice(len, 1);
          tmpEvent.element.removeEventListener(tmpEvent.event, tmpEvent.callbackProxy, tmpEvent.options);
          listenersCounter -= 1;
        }
      }
    }
    /**
     * Clear all previously registered events.
     *
     * @private
     * @since 0.15.0-beta3
     */

  }, {
    key: "clearEvents",
    value: function clearEvents() {
      if (!this.context) {
        return;
      }

      var len = this.context.eventListeners.length;

      while (len) {
        len -= 1;
        var event = this.context.eventListeners[len];

        if (event) {
          this.removeEventListener(event.element, event.event, event.callback);
        }
      }
    }
    /**
     * Clear all previously registered events.
     */

  }, {
    key: "clear",
    value: function clear() {
      this.clearEvents();
    }
    /**
     * Destroy instance of EventManager.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.clearEvents();
      this.context = null;
    }
    /**
     * Trigger event at the specified target element.
     *
     * @param {Element} element Target element.
     * @param {String} eventName Event name.
     */

  }, {
    key: "fireEvent",
    value: function fireEvent(element, eventName) {
      var rootDocument = element.document;
      var rootWindow = element;

      if (!rootDocument) {
        rootDocument = element.ownerDocument ? element.ownerDocument : element;
        rootWindow = rootDocument.defaultView;
      }

      var options = {
        bubbles: true,
        cancelable: eventName !== 'mousemove',
        view: rootWindow,
        detail: 0,
        screenX: 0,
        screenY: 0,
        clientX: 1,
        clientY: 1,
        ctrlKey: false,
        altKey: false,
        shiftKey: false,
        metaKey: false,
        button: 0,
        relatedTarget: undefined
      };
      var event;

      if (rootDocument.createEvent) {
        event = rootDocument.createEvent('MouseEvents');
        event.initMouseEvent(eventName, options.bubbles, options.cancelable, options.view, options.detail, options.screenX, options.screenY, options.clientX, options.clientY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, options.relatedTarget || rootDocument.body.parentNode);
      } else {
        event = rootDocument.createEventObject();
      }

      if (element.dispatchEvent) {
        element.dispatchEvent(event);
      } else {
        element.fireEvent("on".concat(eventName), event);
      }
    }
  }]);
  return EventManager;
}();
/**
 * @param {Object} context
 * @param {Event} event
 * @private
 * @returns {*}
 */


function extendEvent(context, event) {
  var componentName = 'HOT-TABLE';
  var isHotTableSpotted;
  var fromElement;
  var realTarget;
  var target;
  var len;
  event.isTargetWebComponent = false;
  event.realTarget = event.target;
  var nativeStopImmediatePropagation = event.stopImmediatePropagation;

  event.stopImmediatePropagation = function () {
    nativeStopImmediatePropagation.apply(this);
    (0, _event.stopImmediatePropagation)(this);
  };

  if (!EventManager.isHotTableEnv) {
    return event;
  } // eslint-disable-next-line no-param-reassign


  event = (0, _element.polymerWrap)(event);
  len = event.path ? event.path.length : 0;

  while (len) {
    len -= 1;

    if (event.path[len].nodeName === componentName) {
      isHotTableSpotted = true;
    } else if (isHotTableSpotted && event.path[len].shadowRoot) {
      target = event.path[len];
      break;
    }

    if (len === 0 && !target) {
      target = event.path[len];
    }
  }

  if (!target) {
    target = event.target;
  }

  event.isTargetWebComponent = true;

  if ((0, _feature.isWebComponentSupportedNatively)()) {
    event.realTarget = event.srcElement || event.toElement;
  } else if ((0, _object.hasOwnProperty)(context, 'hot') || context.isHotTableEnv || context.wtTable) {
    // Polymer doesn't support `event.target` property properly we must emulate it ourselves
    if ((0, _object.hasOwnProperty)(context, 'hot')) {
      // Custom element
      fromElement = context.hot ? context.hot.view.wt.wtTable.TABLE : null;
    } else if (context.isHotTableEnv) {
      // Handsontable.Core
      fromElement = context.view.activeWt.wtTable.TABLE.parentNode.parentNode;
    } else if (context.wtTable) {
      // Walkontable
      fromElement = context.wtTable.TABLE.parentNode.parentNode;
    }

    realTarget = (0, _element.closest)(event.target, [componentName], fromElement);

    if (realTarget) {
      event.realTarget = fromElement.querySelector(componentName) || event.target;
    } else {
      event.realTarget = event.target;
    }
  }

  Object.defineProperty(event, 'target', {
    get: function get() {
      return (0, _element.polymerWrap)(target);
    },
    enumerable: true,
    configurable: true
  });
  return event;
}

var _default = EventManager;
exports.default = _default;

function getListenersCounter() {
  return listenersCounter;
}

/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global = __webpack_require__(32);
var redefineAll = __webpack_require__(147);
var InternalMetadataModule = __webpack_require__(123);
var weak = __webpack_require__(186);
var isObject = __webpack_require__(42);
var enforceIternalState = __webpack_require__(87).enforce;
var NATIVE_WEAK_MAP = __webpack_require__(178);
var IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;
var isExtensible = Object.isExtensible;
var InternalWeakMap;

var wrapper = function (get) {
  return function WeakMap() {
    return get(this, arguments.length > 0 ? arguments[0] : undefined);
  };
};

// `WeakMap` constructor
// https://tc39.github.io/ecma262/#sec-weakmap-constructor
var $WeakMap = module.exports = __webpack_require__(125)('WeakMap', wrapper, weak, true, true);

// IE11 WeakMap frozen keys fix
// We can't use feature detection because it crash some old IE builds
// https://github.com/zloirock/core-js/issues/485
if (NATIVE_WEAK_MAP && IS_IE11) {
  InternalWeakMap = weak.getConstructor(wrapper, 'WeakMap', true);
  InternalMetadataModule.REQUIRED = true;
  var WeakMapPrototype = $WeakMap.prototype;
  var nativeDelete = WeakMapPrototype['delete'];
  var nativeHas = WeakMapPrototype.has;
  var nativeGet = WeakMapPrototype.get;
  var nativeSet = WeakMapPrototype.set;
  redefineAll(WeakMapPrototype, {
    'delete': function (key) {
      if (isObject(key) && !isExtensible(key)) {
        var state = enforceIternalState(this);
        if (!state.frozen) state.frozen = new InternalWeakMap();
        return nativeDelete.call(this, key) || state.frozen['delete'](key);
      } return nativeDelete.call(this, key);
    },
    has: function has(key) {
      if (isObject(key) && !isExtensible(key)) {
        var state = enforceIternalState(this);
        if (!state.frozen) state.frozen = new InternalWeakMap();
        return nativeHas.call(this, key) || state.frozen.has(key);
      } return nativeHas.call(this, key);
    },
    get: function get(key) {
      if (isObject(key) && !isExtensible(key)) {
        var state = enforceIternalState(this);
        if (!state.frozen) state.frozen = new InternalWeakMap();
        return nativeHas.call(this, key) ? nativeGet.call(this, key) : state.frozen.get(key);
      } return nativeGet.call(this, key);
    },
    set: function set(key, value) {
      if (isObject(key) && !isExtensible(key)) {
        var state = enforceIternalState(this);
        if (!state.frozen) state.frozen = new InternalWeakMap();
        nativeHas.call(this, key) ? nativeSet.call(this, key, value) : state.frozen.set(key, value);
      } else nativeSet.call(this, key, value);
      return this;
    }
  });
}


/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;

var _viewportColumns = _interopRequireDefault(__webpack_require__(198));

exports.ViewportColumnsCalculator = _viewportColumns.default;

var _viewportRows = _interopRequireDefault(__webpack_require__(199));

exports.ViewportRowsCalculator = _viewportRows.default;

var _coords = _interopRequireDefault(__webpack_require__(106));

exports.CellCoords = _coords.default;

var _range = _interopRequireDefault(__webpack_require__(200));

exports.CellRange = _range.default;

var _column = _interopRequireDefault(__webpack_require__(201));

exports.ColumnFilter = _column.default;

var _row = _interopRequireDefault(__webpack_require__(202));

exports.RowFilter = _row.default;

var _debug = _interopRequireDefault(__webpack_require__(523));

exports.DebugOverlay = _debug.default;

var _left = _interopRequireDefault(__webpack_require__(528));

exports.LeftOverlay = _left.default;

var _top = _interopRequireDefault(__webpack_require__(529));

exports.TopOverlay = _top.default;

var _topLeftCorner = _interopRequireDefault(__webpack_require__(530));

exports.TopLeftCornerOverlay = _topLeftCorner.default;

var _bottom = _interopRequireDefault(__webpack_require__(531));

exports.BottomOverlay = _bottom.default;

var _bottomLeftCorner = _interopRequireDefault(__webpack_require__(532));

exports.BottomLeftCornerOverlay = _bottomLeftCorner.default;

var _border = _interopRequireDefault(__webpack_require__(336));

exports.Border = _border.default;

var _core = _interopRequireDefault(__webpack_require__(326));

exports.default = _core.default;
exports.Core = _core.default;

var _event = _interopRequireDefault(__webpack_require__(327));

exports.Event = _event.default;

var _overlays = _interopRequireDefault(__webpack_require__(328));

exports.Overlays = _overlays.default;

var _scroll = _interopRequireDefault(__webpack_require__(329));

exports.Scroll = _scroll.default;

var _selection = _interopRequireDefault(__webpack_require__(533));

exports.Selection = _selection.default;

var _settings = _interopRequireDefault(__webpack_require__(330));

exports.Settings = _settings.default;

var _table = _interopRequireDefault(__webpack_require__(331));

exports.Table = _table.default;

var _tableRenderer = _interopRequireDefault(__webpack_require__(334));

exports.TableRenderer = _tableRenderer.default;

var _viewport = _interopRequireDefault(__webpack_require__(335));

exports.Viewport = _viewport.default;

/***/ }),
/* 26 */
/***/ (function(module, exports) {

function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }

  return self;
}

module.exports = _assertThisInitialized;

/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(524);

__webpack_require__(204);

__webpack_require__(37);

__webpack_require__(46);

exports.__esModule = true;
exports.stringify = stringify;
exports.isDefined = isDefined;
exports.isUndefined = isUndefined;
exports.isEmpty = isEmpty;
exports.isRegExp = isRegExp;
exports._injectProductInfo = _injectProductInfo;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _moment = _interopRequireDefault(__webpack_require__(63));

var _templateLiteralTag = __webpack_require__(67);

function _templateObject6() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable is missing. Use your purchased key to activate the product. \n    Alternatively, you can activate Handsontable to use for non-commercial purposes by \n    passing the key: 'non-commercial-and-evaluation'. \n    <a href=\"https://handsontable.com/docs/tutorial-license-key.html\" target=\"_blank\">Read more</a> about it in \n    the documentation or contact us at <a href=\"mailto:support@handsontable.com\">support@handsontable.com</a>."], ["\n    The license key for Handsontable is missing. Use your purchased key to activate the product.\\x20\n    Alternatively, you can activate Handsontable to use for non-commercial purposes by\\x20\n    passing the key: 'non-commercial-and-evaluation'.\\x20\n    <a href=\"https://handsontable.com/docs/tutorial-license-key.html\" target=\"_blank\">Read more</a> about it in\\x20\n    the documentation or contact us at <a href=\"mailto:support@handsontable.com\">support@handsontable.com</a>."]);

  _templateObject6 = function _templateObject6() {
    return data;
  };

  return data;
}

function _templateObject5() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable expired on ", ", and is not valid for the installed \n    version ", ". <a href=\"https://handsontable.com/pricing\" target=\"_blank\">Renew</a> your \n    license key or downgrade to a version released prior to ", ". If you need any \n    help, contact us at <a href=\"mailto:sales@handsontable.com\">sales@handsontable.com</a>."], ["\n    The license key for Handsontable expired on ", ", and is not valid for the installed\\x20\n    version ", ". <a href=\"https://handsontable.com/pricing\" target=\"_blank\">Renew</a> your\\x20\n    license key or downgrade to a version released prior to ", ". If you need any\\x20\n    help, contact us at <a href=\"mailto:sales@handsontable.com\">sales@handsontable.com</a>."]);

  _templateObject5 = function _templateObject5() {
    return data;
  };

  return data;
}

function _templateObject4() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable is invalid. \n    <a href=\"https://handsontable.com/docs/tutorial-license-key.html\" target=\"_blank\">Read more</a> on how to \n    install it properly or contact us at <a href=\"mailto:support@handsontable.com\">support@handsontable.com</a>."], ["\n    The license key for Handsontable is invalid.\\x20\n    <a href=\"https://handsontable.com/docs/tutorial-license-key.html\" target=\"_blank\">Read more</a> on how to\\x20\n    install it properly or contact us at <a href=\"mailto:support@handsontable.com\">support@handsontable.com</a>."]);

  _templateObject4 = function _templateObject4() {
    return data;
  };

  return data;
}

function _templateObject3() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable is missing. Use your purchased key to activate the product. \n    Alternatively, you can activate Handsontable to use for non-commercial purposes by \n    passing the key: 'non-commercial-and-evaluation'. If you need any help, contact \n    us at support@handsontable.com."], ["\n    The license key for Handsontable is missing. Use your purchased key to activate the product.\\x20\n    Alternatively, you can activate Handsontable to use for non-commercial purposes by\\x20\n    passing the key: 'non-commercial-and-evaluation'. If you need any help, contact\\x20\n    us at support@handsontable.com."]);

  _templateObject3 = function _templateObject3() {
    return data;
  };

  return data;
}

function _templateObject2() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable expired on ", ", and is not valid for the installed \n    version ", ". Renew your license key at handsontable.com or downgrade to a version released prior \n    to ", ". If you need any help, contact us at sales@handsontable.com."], ["\n    The license key for Handsontable expired on ", ", and is not valid for the installed\\x20\n    version ", ". Renew your license key at handsontable.com or downgrade to a version released prior\\x20\n    to ", ". If you need any help, contact us at sales@handsontable.com."]);

  _templateObject2 = function _templateObject2() {
    return data;
  };

  return data;
}

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["\n    The license key for Handsontable is invalid. \n    If you need any help, contact us at support@handsontable.com."], ["\n    The license key for Handsontable is invalid.\\x20\n    If you need any help, contact us at support@handsontable.com."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * Converts any value to string.
 *
 * @param {*} value
 * @returns {String}
 */
function stringify(value) {
  var result;

  switch ((0, _typeof2.default)(value)) {
    case 'string':
    case 'number':
      result = "".concat(value);
      break;

    case 'object':
      result = value === null ? '' : value.toString();
      break;

    case 'undefined':
      result = '';
      break;

    default:
      result = value.toString();
      break;
  }

  return result;
}
/**
 * Checks if given variable is defined.
 *
 * @param {*} variable Variable to check.
 * @returns {Boolean}
 */


function isDefined(variable) {
  return typeof variable !== 'undefined';
}
/**
 * Checks if given variable is undefined.
 *
 * @param {*} variable Variable to check.
 * @returns {Boolean}
 */


function isUndefined(variable) {
  return typeof variable === 'undefined';
}
/**
 * Check if given variable is null, empty string or undefined.
 *
 * @param {*} variable Variable to check.
 * @returns {Boolean}
 */


function isEmpty(variable) {
  return variable === null || variable === '' || isUndefined(variable);
}
/**
 * Check if given variable is a regular expression.
 *
 * @param {*} variable Variable to check.
 * @returns {Boolean}
 */


function isRegExp(variable) {
  return Object.prototype.toString.call(variable) === '[object RegExp]';
}
/* eslint-disable */


var _m = '\x6C\x65\x6E\x67\x74\x68';

var _hd = function _hd(v) {
  return parseInt(v, 16);
};

var _pi = function _pi(v) {
  return parseInt(v, 10);
};

var _ss = function _ss(v, s, l) {
  return v['\x73\x75\x62\x73\x74\x72'](s, l);
};

var _cp = function _cp(v) {
  return v['\x63\x6F\x64\x65\x50\x6F\x69\x6E\x74\x41\x74'](0) - 65;
};

var _norm = function _norm(v) {
  return "".concat(v).replace(/\-/g, '');
};

var _extractTime = function _extractTime(v) {
  return _hd(_ss(_norm(v), _hd('12'), _cp('\x46'))) / (_hd(_ss(_norm(v), _cp('\x42'), ~~![][_m])) || 9);
};

var _ignored = function _ignored() {
  return typeof location !== 'undefined' && /^([a-z0-9\-]+\.)?\x68\x61\x6E\x64\x73\x6F\x6E\x74\x61\x62\x6C\x65\x2E\x63\x6F\x6D$/i.test(location.host);
};

var _notified = false;
var consoleMessages = {
  invalid: function invalid() {
    return (0, _templateLiteralTag.toSingleLine)(_templateObject());
  },
  expired: function expired(_ref) {
    var keyValidityDate = _ref.keyValidityDate,
        hotVersion = _ref.hotVersion;
    return (0, _templateLiteralTag.toSingleLine)(_templateObject2(), keyValidityDate, hotVersion, keyValidityDate);
  },
  missing: function missing() {
    return (0, _templateLiteralTag.toSingleLine)(_templateObject3());
  },
  non_commercial: function non_commercial() {
    return '';
  }
};
var domMessages = {
  invalid: function invalid() {
    return (0, _templateLiteralTag.toSingleLine)(_templateObject4());
  },
  expired: function expired(_ref2) {
    var keyValidityDate = _ref2.keyValidityDate,
        hotVersion = _ref2.hotVersion;
    return (0, _templateLiteralTag.toSingleLine)(_templateObject5(), keyValidityDate, hotVersion, keyValidityDate);
  },
  missing: function missing() {
    return (0, _templateLiteralTag.toSingleLine)(_templateObject6());
  },
  non_commercial: function non_commercial() {
    return '';
  }
};

function _injectProductInfo(key, element) {
  var hasValidType = !isEmpty(key);
  var isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
  var hotVersion = "7.0.1";
  var keyValidityDate;
  var consoleMessageState = 'invalid';
  var domMessageState = 'invalid';
  key = _norm(key || '');

  var schemaValidity = _checkKeySchema(key);

  if (hasValidType || isNonCommercial || schemaValidity) {
    if (schemaValidity) {
      var releaseDate = (0, _moment.default)("08/04/2019", 'DD/MM/YYYY');
      var releaseDays = Math.floor(releaseDate.toDate().getTime() / 8.64e7);

      var keyValidityDays = _extractTime(key);

      keyValidityDate = (0, _moment.default)((keyValidityDays + 1) * 8.64e7, 'x').format('MMMM DD, YYYY');

      if (releaseDays > keyValidityDays) {
        var daysAfterRelease = (0, _moment.default)().diff(releaseDate, 'days');
        consoleMessageState = daysAfterRelease <= 1 ? 'valid' : 'expired';
        domMessageState = daysAfterRelease <= 15 ? 'valid' : 'expired';
      } else {
        consoleMessageState = 'valid';
        domMessageState = 'valid';
      }
    } else if (isNonCommercial) {
      consoleMessageState = 'non_commercial';
      domMessageState = 'valid';
    } else {
      consoleMessageState = 'invalid';
      domMessageState = 'invalid';
    }
  } else {
    consoleMessageState = 'missing';
    domMessageState = 'missing';
  }

  if (_ignored()) {
    consoleMessageState = 'valid';
    domMessageState = 'valid';
  }

  if (!_notified && consoleMessageState !== 'valid') {
    var message = consoleMessages[consoleMessageState]({
      keyValidityDate: keyValidityDate,
      hotVersion: hotVersion
    });

    if (message) {
      console[consoleMessageState === 'non_commercial' ? 'info' : 'warn'](consoleMessages[consoleMessageState]({
        keyValidityDate: keyValidityDate,
        hotVersion: hotVersion
      }));
    }

    _notified = true;
  }

  if (domMessageState !== 'valid' && element.parentNode) {
    var _message = domMessages[domMessageState]({
      keyValidityDate: keyValidityDate,
      hotVersion: hotVersion
    });

    if (_message) {
      var messageNode = document.createElement('div');
      messageNode.id = 'hot-display-license-info';
      messageNode.innerHTML = domMessages[domMessageState]({
        keyValidityDate: keyValidityDate,
        hotVersion: hotVersion
      });
      element.parentNode.insertBefore(messageNode, element.nextSibling);
    }
  }
}

function _checkKeySchema(v) {
  var z = [][_m];
  var p = z;

  if (v[_m] !== _cp('\x5A')) {
    return false;
  }

  for (var c = '', i = '\x42\x3C\x48\x34\x50\x2B'.split(''), j = _cp(i.shift()); j; j = _cp(i.shift() || 'A')) {
    --j < ''[_m] ? p = p | (_pi("".concat(_pi(_hd(c) + (_hd(_ss(v, Math.abs(j), 2)) + []).padStart(2, '0')))) % 97 || 2) >> 1 : c = _ss(v, j, !j ? 6 : i[_m] === 1 ? 9 : 8);
  }

  return p === z;
}
/* eslint-enable */

/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.getCondition = getCondition;
exports.getConditionDescriptor = getConditionDescriptor;
exports.registerCondition = registerCondition;
exports.conditions = void 0;
var conditions = {};
/**
 * Get condition closure with pre-bound arguments.
 *
 * @param {String} name Condition name.
 * @param {Array} args Condition arguments.
 * @returns {Function}
 */

exports.conditions = conditions;

function getCondition(name, args) {
  if (!conditions[name]) {
    throw Error("Filter condition \"".concat(name, "\" does not exist."));
  }

  var _conditions$name = conditions[name],
      condition = _conditions$name.condition,
      descriptor = _conditions$name.descriptor;
  var conditionArguments = args;

  if (descriptor.inputValuesDecorator) {
    conditionArguments = descriptor.inputValuesDecorator(conditionArguments);
  }

  return function (dataRow) {
    return condition.apply(dataRow.meta.instance, [].concat([dataRow], [conditionArguments]));
  };
}
/**
 * Get condition object descriptor which defines some additional informations about this condition.
 *
 * @param {String} name Condition name.
 * @returns {Object}
 */


function getConditionDescriptor(name) {
  if (!conditions[name]) {
    throw Error("Filter condition \"".concat(name, "\" does not exist."));
  }

  return conditions[name].descriptor;
}
/**
 * Condition registerer.
 *
 * @param {String} name Condition name.
 * @param {Function} condition Condition function
 * @param {Object} descriptor Condition descriptor
 */


function registerCondition(name, condition, descriptor) {
  descriptor.key = name;
  conditions[name] = {
    condition: condition,
    descriptor: descriptor
  };
}

/***/ }),
/* 29 */
/***/ (function(module, exports) {

module.exports = function (exec) {
  try {
    return !!exec();
  } catch (e) {
    return true;
  }
};


/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {

// ie9- setTimeout & setInterval additional parameters fix
var global = __webpack_require__(32);
var userAgent = __webpack_require__(203);
var slice = [].slice;

var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check

var wrap = function (set) {
  return function (fn, time /* , ...args */) {
    var boundArgs = arguments.length > 2;
    var args = boundArgs ? slice.call(arguments, 2) : false;
    return set(boundArgs ? function () {
      // eslint-disable-next-line no-new-func
      (typeof fn == 'function' ? fn : Function(fn)).apply(this, args);
    } : fn, time);
  };
};

__webpack_require__(22)({ global: true, bind: true, forced: MSIE }, {
  setTimeout: wrap(global.setTimeout),
  setInterval: wrap(global.setInterval)
});


/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.stopImmediatePropagation = stopImmediatePropagation;
exports.isImmediatePropagationStopped = isImmediatePropagationStopped;
exports.stopPropagation = stopPropagation;
exports.pageX = pageX;
exports.pageY = pageY;
exports.isRightClick = isRightClick;
exports.isLeftClick = isLeftClick;

var _element = __webpack_require__(5);

/**
 * Prevent other listeners of the same event from being called.
 *
 * @param {Event} event
 */
function stopImmediatePropagation(event) {
  event.isImmediatePropagationEnabled = false;
  event.cancelBubble = true;
}
/**
 * Check if event was stopped by `stopImmediatePropagation`.
 *
 * @param event {Event}
 * @returns {Boolean}
 */


function isImmediatePropagationStopped(event) {
  return event.isImmediatePropagationEnabled === false;
}
/**
 * Prevent further propagation of the current event (prevent bubbling).
 *
 * @param event {Event}
 */


function stopPropagation(event) {
  // ie8
  // http://msdn.microsoft.com/en-us/library/ie/ff975462(v=vs.85).aspx
  if (typeof event.stopPropagation === 'function') {
    event.stopPropagation();
  } else {
    event.cancelBubble = true;
  }
}
/**
 * Get horizontal coordinate of the event object relative to the whole document.
 *
 * @param {Event} event
 * @returns {Number}
 */


function pageX(event) {
  if (event.pageX) {
    return event.pageX;
  }

  var rootWindow = event.target.ownerDocument.defaultView;
  return event.clientX + (0, _element.getWindowScrollLeft)(rootWindow);
}
/**
 * Get vertical coordinate of the event object relative to the whole document.
 *
 * @param {Event} event
 * @returns {Number}
 */


function pageY(event) {
  if (event.pageY) {
    return event.pageY;
  }

  var rootWindow = event.target.ownerDocument.defaultView;
  return event.clientY + (0, _element.getWindowScrollTop)(rootWindow);
}
/**
 * Check if provided event was triggered by clicking the right mouse button.
 *
 * @param {Event} event DOM Event.
 * @returns {Boolean}
 */


function isRightClick(event) {
  return event.button === 2;
}
/**
 * Check if provided event was triggered by clicking the left mouse button.
 *
 * @param {Event} event DOM Event.
 * @returns {Boolean}
 */


function isLeftClick(event) {
  return event.button === 0;
}

/***/ }),
/* 32 */
/***/ (function(module, exports) {

// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
module.exports = typeof window == 'object' && window && window.Math == Math ? window
  : typeof self == 'object' && self && self.Math == Math ? self
  // eslint-disable-next-line no-new-func
  : Function('return this')();


/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toAbsoluteIndex = __webpack_require__(114);
var toInteger = __webpack_require__(86);
var toLength = __webpack_require__(48);
var toObject = __webpack_require__(62);
var arraySpeciesCreate = __webpack_require__(151);
var createProperty = __webpack_require__(127);
var max = Math.max;
var min = Math.min;
var MAX_SAFE_INTEGER = 0x1fffffffffffff;
var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';

var SPECIES_SUPPORT = __webpack_require__(103)('splice');

// `Array.prototype.splice` method
// https://tc39.github.io/ecma262/#sec-array.prototype.splice
// with adding support of @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
  splice: function splice(start, deleteCount /* , ...items */) {
    var O = toObject(this);
    var len = toLength(O.length);
    var actualStart = toAbsoluteIndex(start, len);
    var argumentsLength = arguments.length;
    var insertCount, actualDeleteCount, A, k, from, to;
    if (argumentsLength === 0) {
      insertCount = actualDeleteCount = 0;
    } else if (argumentsLength === 1) {
      insertCount = 0;
      actualDeleteCount = len - actualStart;
    } else {
      insertCount = argumentsLength - 2;
      actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
    }
    if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
      throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
    }
    A = arraySpeciesCreate(O, actualDeleteCount);
    for (k = 0; k < actualDeleteCount; k++) {
      from = actualStart + k;
      if (from in O) createProperty(A, k, O[from]);
    }
    A.length = actualDeleteCount;
    if (insertCount < actualDeleteCount) {
      for (k = actualStart; k < len - actualDeleteCount; k++) {
        from = k + actualDeleteCount;
        to = k + insertCount;
        if (from in O) O[to] = O[from];
        else delete O[to];
      }
      for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
    } else if (insertCount > actualDeleteCount) {
      for (k = len - actualDeleteCount; k > actualStart; k--) {
        from = k + actualDeleteCount - 1;
        to = k + insertCount - 1;
        if (from in O) O[to] = O[from];
        else delete O[to];
      }
    }
    for (k = 0; k < insertCount; k++) {
      O[k + actualStart] = arguments[k + 2];
    }
    O.length = len - actualDeleteCount + insertCount;
    return A;
  }
});


/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalIncludes = __webpack_require__(140)(true);

// `Array.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
__webpack_require__(22)({ target: 'Array', proto: true }, {
  includes: function includes(el /* , fromIndex = 0 */) {
    return internalIncludes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
__webpack_require__(121)('includes');


/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {

var store = __webpack_require__(98)('wks');
var uid = __webpack_require__(118);
var Symbol = __webpack_require__(32).Symbol;
var NATIVE_SYMBOL = __webpack_require__(180);

module.exports = function (name) {
  return store[name] || (store[name] = NATIVE_SYMBOL && Symbol[name]
    || (NATIVE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};


/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var anObject = __webpack_require__(45);
var fails = __webpack_require__(29);
var flags = __webpack_require__(153);
var DESCRIPTORS = __webpack_require__(52);
var TO_STRING = 'toString';
var nativeToString = /./[TO_STRING];

var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
// FF44- RegExp#toString has a wrong name
var INCORRECT_NAME = nativeToString.name != TO_STRING;

// `RegExp.prototype.toString` method
// https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring
if (NOT_GENERIC || INCORRECT_NAME) {
  __webpack_require__(65)(RegExp.prototype, TO_STRING, function toString() {
    var R = anObject(this);
    return '/'.concat(R.source, '/',
      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? flags.call(R) : undefined);
  }, { unsafe: true });
}


/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var anObject = __webpack_require__(45);
var toObject = __webpack_require__(62);
var toLength = __webpack_require__(48);
var toInteger = __webpack_require__(86);
var requireObjectCoercible = __webpack_require__(58);
var advanceStringIndex = __webpack_require__(155);
var regExpExec = __webpack_require__(128);
var max = Math.max;
var min = Math.min;
var floor = Math.floor;
var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;

var maybeToString = function (it) {
  return it === undefined ? it : String(it);
};

// @@replace logic
__webpack_require__(129)(
  'replace',
  2,
  function (REPLACE, nativeReplace, maybeCallNative) {
    return [
      // `String.prototype.replace` method
      // https://tc39.github.io/ecma262/#sec-string.prototype.replace
      function replace(searchValue, replaceValue) {
        var O = requireObjectCoercible(this);
        var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
        return replacer !== undefined
          ? replacer.call(searchValue, O, replaceValue)
          : nativeReplace.call(String(O), searchValue, replaceValue);
      },
      // `RegExp.prototype[@@replace]` method
      // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
      function (regexp, replaceValue) {
        var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
        if (res.done) return res.value;

        var rx = anObject(regexp);
        var S = String(this);

        var functionalReplace = typeof replaceValue === 'function';
        if (!functionalReplace) replaceValue = String(replaceValue);

        var global = rx.global;
        if (global) {
          var fullUnicode = rx.unicode;
          rx.lastIndex = 0;
        }
        var results = [];
        while (true) {
          var result = regExpExec(rx, S);
          if (result === null) break;

          results.push(result);
          if (!global) break;

          var matchStr = String(result[0]);
          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
        }

        var accumulatedResult = '';
        var nextSourcePosition = 0;
        for (var i = 0; i < results.length; i++) {
          result = results[i];

          var matched = String(result[0]);
          var position = max(min(toInteger(result.index), S.length), 0);
          var captures = [];
          // NOTE: This is equivalent to
          //   captures = result.slice(1).map(maybeToString)
          // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
          // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
          // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
          for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
          var namedCaptures = result.groups;
          if (functionalReplace) {
            var replacerArgs = [matched].concat(captures, position, S);
            if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
            var replacement = String(replaceValue.apply(undefined, replacerArgs));
          } else {
            replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
          }
          if (position >= nextSourcePosition) {
            accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
            nextSourcePosition = position + matched.length;
          }
        }
        return accumulatedResult + S.slice(nextSourcePosition);
      }
    ];

    // https://tc39.github.io/ecma262/#sec-getsubstitution
    function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
      var tailPos = position + matched.length;
      var m = captures.length;
      var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
      if (namedCaptures !== undefined) {
        namedCaptures = toObject(namedCaptures);
        symbols = SUBSTITUTION_SYMBOLS;
      }
      return nativeReplace.call(replacement, symbols, function (match, ch) {
        var capture;
        switch (ch.charAt(0)) {
          case '$': return '$';
          case '&': return matched;
          case '`': return str.slice(0, position);
          case "'": return str.slice(tailPos);
          case '<':
            capture = namedCaptures[ch.slice(1, -1)];
            break;
          default: // \d\d?
            var n = +ch;
            if (n === 0) return match;
            if (n > m) {
              var f = floor(n / 10);
              if (f === 0) return match;
              if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
              return match;
            }
            capture = captures[n - 1];
        }
        return capture === undefined ? '' : capture;
      });
    }
  }
);


/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {

var arrayWithoutHoles = __webpack_require__(517);

var iterableToArray = __webpack_require__(195);

var nonIterableSpread = __webpack_require__(518);

function _toConsumableArray(arr) {
  return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}

module.exports = _toConsumableArray;

/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var validateArguments = __webpack_require__(157);
var INCLUDES = 'includes';

var CORRECT_IS_REGEXP_LOGIC = __webpack_require__(158)(INCLUDES);

// `String.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-string.prototype.includes
__webpack_require__(22)({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, {
  includes: function includes(searchString /* , position = 0 */) {
    return !!~validateArguments(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var isObject = __webpack_require__(42);
var isArray = __webpack_require__(124);
var toAbsoluteIndex = __webpack_require__(114);
var toLength = __webpack_require__(48);
var toIndexedObject = __webpack_require__(69);
var createProperty = __webpack_require__(127);
var SPECIES = __webpack_require__(35)('species');
var nativeSlice = [].slice;
var max = Math.max;

var SPECIES_SUPPORT = __webpack_require__(103)('slice');

// `Array.prototype.slice` method
// https://tc39.github.io/ecma262/#sec-array.prototype.slice
// fallback for not array-like ES3 strings and DOM objects
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
  slice: function slice(start, end) {
    var O = toIndexedObject(this);
    var length = toLength(O.length);
    var k = toAbsoluteIndex(start, length);
    var fin = toAbsoluteIndex(end === undefined ? length : end, length);
    // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
    var Constructor, result, n;
    if (isArray(O)) {
      Constructor = O.constructor;
      // cross-realm fallback
      if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
        Constructor = undefined;
      } else if (isObject(Constructor)) {
        Constructor = Constructor[SPECIES];
        if (Constructor === null) Constructor = undefined;
      }
      if (Constructor === Array || Constructor === undefined) {
        return nativeSlice.call(O, k, fin);
      }
    }
    result = new (Constructor === undefined ? Array : Constructor)(max(fin - k, 0));
    for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
    result.length = n;
    return result;
  }
});


/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.getRenderer = _getItem;
exports.getRegisteredRenderers = exports.getRegisteredRendererNames = exports.hasRenderer = exports.registerRenderer = void 0;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _cellDecorator = _interopRequireDefault(__webpack_require__(547));

var _autocompleteRenderer = _interopRequireDefault(__webpack_require__(548));

var _checkboxRenderer = _interopRequireDefault(__webpack_require__(549));

var _htmlRenderer = _interopRequireDefault(__webpack_require__(550));

var _numericRenderer = _interopRequireDefault(__webpack_require__(551));

var _passwordRenderer = _interopRequireDefault(__webpack_require__(552));

var _textRenderer = _interopRequireDefault(__webpack_require__(553));

var _staticRegister = (0, _staticRegister2.default)('renderers'),
    register = _staticRegister.register,
    getItem = _staticRegister.getItem,
    hasItem = _staticRegister.hasItem,
    getNames = _staticRegister.getNames,
    getValues = _staticRegister.getValues;

exports.getRegisteredRenderers = getValues;
exports.getRegisteredRendererNames = getNames;
exports.hasRenderer = hasItem;
exports.registerRenderer = register;
register('base', _cellDecorator.default);
register('autocomplete', _autocompleteRenderer.default);
register('checkbox', _checkboxRenderer.default);
register('html', _htmlRenderer.default);
register('numeric', _numericRenderer.default);
register('password', _passwordRenderer.default);
register('text', _textRenderer.default);
/**
 * Retrieve renderer function.
 *
 * @param {String} name Renderer identification.
 * @returns {Function} Returns renderer function.
 */

function _getItem(name) {
  if (typeof name === 'function') {
    return name;
  }

  if (!hasItem(name)) {
    throw Error("No registered renderer found under \"".concat(name, "\" name"));
  }

  return getItem(name);
}

/***/ }),
/* 42 */
/***/ (function(module, exports) {

module.exports = function (it) {
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};


/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

/**
 * @description
 * Handsontable events are the common interface that function in 2 ways: as __callbacks__ and as __hooks__.
 *
 * @example
 *
 * ```js
 * // Using events as callbacks:
 * ...
 * const hot1 = new Handsontable(document.getElementById('example1'), {
 *   afterChange: function(changes, source) {
 *     $.ajax({
 *       url: "save.php',
 *       data: change
 *     });
 *   }
 * });
 * ...
 * ```
 *
 * ```js
 * // Using events as plugin hooks:
 * ...
 * const hot1 = new Handsontable(document.getElementById('example1'), {
 *   myPlugin: true
 * });
 *
 * const hot2 = new Handsontable(document.getElementById('example2'), {
 *   myPlugin: false
 * });
 *
 * // global hook
 * Handsontable.hooks.add('afterChange', function() {
 *   // Fired twice - for hot1 and hot2
 *   if (this.getSettings().myPlugin) {
 *     // function body - will only run for hot1
 *   }
 * });
 *
 * // local hook (has same effect as a callback)
 * hot2.addHook('afterChange', function() {
 *   // function body - will only run in #example2
 * });
 * ```
 * ...
 */
// @TODO: Move plugin description hooks to plugin?
var REGISTERED_HOOKS = [
/**
 * Fired after resetting a cell's meta. This happens when the {@link Core#updateSettings} method is called.
 *
 * @event Hooks#afterCellMetaReset
 */
'afterCellMetaReset',
/**
 * Fired after one or more cells has been changed. The changes are triggered in any situation when the
 * value is entered using an editor or changed using API (e.q setDataAtCell)
 *
 * __Note:__ For performance reasons, the `changes` array is null for `"loadData"` source.
 *
 * @event Hooks#afterChange
 * @param {Array} changes 2D array containing information about each of the edited cells `[[row, prop, oldVal, newVal], ...]`.
 * @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 * @example
 * ```js
 * new Handsontable(element, {
 *   afterChange: (changes) => {
 *     changes.forEach(([row, prop, oldValue, newValue]) => {
 *       // Some logic...
 *     });
 *   }
 * })
 * ```
 */
'afterChange',
/**
 * Fired by {@link ObserveChanges} plugin after detecting changes in the data source. This hook is fired when
 * {@link Options#observeChanges} option is enabled.
 *
 * @event Hooks#afterChangesObserved
 */
'afterChangesObserved',
/**
 * Fired each time user opens {@link ContextMenu} and after setting up the Context Menu's default options. These options are a collection
 * which user can select by setting an array of keys or an array of objects in {@link Options#contextMenu} option.
 *
 * @event Hooks#afterContextMenuDefaultOptions
 * @param {Array} predefinedItems An array of objects containing information about the pre-defined Context Menu items.
 */
'afterContextMenuDefaultOptions',
/**
 * Fired each time user opens {@link ContextMenu} plugin before setting up the Context Menu's items but after filtering these options by
 * user (`contextMenu` option). This hook can by helpful to determine if user use specified menu item or to set up
 * one of the menu item to by always visible.
 *
 * @event Hooks#beforeContextMenuSetItems
 * @param {Object[]} menuItems An array of objects containing information about to generated Context Menu items.
 */
'beforeContextMenuSetItems',
/**
 * Fired by {@link DropdownMenu} plugin after setting up the Dropdown Menu's default options. These options are a
 * collection which user can select by setting an array of keys or an array of objects in {@link Options#dropdownMenu}
 * option.
 *
 * @event Hooks#afterDropdownMenuDefaultOptions
 * @param {Object[]} predefinedItems An array of objects containing information about the pre-defined Context Menu items.
 */
'afterDropdownMenuDefaultOptions',
/**
 * Fired by {@link DropdownMenu} plugin before setting up the Dropdown Menu's items but after filtering these options
 * by user (`dropdownMenu` option). This hook can by helpful to determine if user use specified menu item or to set
 * up one of the menu item to by always visible.
 *
 * @event Hooks#beforeDropdownMenuSetItems
 * @param {Object[]} menuItems An array of objects containing information about to generated Dropdown Menu items.
 */
'beforeDropdownMenuSetItems',
/**
 * Fired by {@link ContextMenu} plugin after hiding the Context Menu. This hook is fired when {@link Options#contextMenu}
 * option is enabled.
 *
 * @event Hooks#afterContextMenuHide
 * @param {Object} context The Context Menu plugin instance.
 */
'afterContextMenuHide',
/**
 * Fired by {@link ContextMenu} plugin before opening the Context Menu. This hook is fired when {@link Options#contextMenu}
 * option is enabled.
 *
 * @event Hooks#beforeContextMenuShow
 * @param {Object} context The Context Menu instance.
 */
'beforeContextMenuShow',
/**
 * Fired by {@link ContextMenu} plugin after opening the Context Menu. This hook is fired when {@link Options#contextMenu}
 * option is enabled.
 *
 * @event Hooks#afterContextMenuShow
 * @param {Object} context The Context Menu plugin instance.
 */
'afterContextMenuShow',
/**
 * Fired by {@link CopyPaste} plugin after reaching the copy limit while copying data. This hook is fired when
 * {@link Options#copyPaste} option is enabled.
 *
 * @event Hooks#afterCopyLimit
 * @param {Number} selectedRows Count of selected copyable rows.
 * @param {Number} selectedColumns Count of selected copyable columns.
 * @param {Number} copyRowsLimit Current copy rows limit.
 * @param {Number} copyColumnsLimit Current copy columns limit.
 */
'afterCopyLimit',
/**
 * Fired before created a new column.
 *
 * @event Hooks#beforeCreateCol
 * @param {Number} index Represents the visual index of first newly created column in the data source array.
 * @param {Number} amount Number of newly created columns in the data source array.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeCreateCol',
/**
 * Fired after created a new column.
 *
 * @event Hooks#afterCreateCol
 * @param {Number} index Represents the visual index of first newly created column in the data source.
 * @param {Number} amount Number of newly created columns in the data source.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterCreateCol',
/**
 * Fired before created a new row.
 *
 * @event Hooks#beforeCreateRow
 * @param {Number} index Represents the visual index of first newly created row in the data source array.
 * @param {Number} amount Number of newly created rows in the data source array.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeCreateRow',
/**
 * Fired after created a new row.
 *
 * @event Hooks#afterCreateRow
 * @param {Number} index Represents the visual index of first newly created row in the data source array.
 * @param {Number} amount Number of newly created rows in the data source array.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterCreateRow',
/**
 * Fired after the current cell is deselected.
 *
 * @event Hooks#afterDeselect
 */
'afterDeselect',
/**
 * Fired after destroying the Handsontable instance.
 *
 * @event Hooks#afterDestroy
 */
'afterDestroy',
/**
 * General hook which captures `keydown` events attached to the document body. These events are delegated to the
 * hooks system and consumed by Core and internal modules (e.g plugins, editors).
 *
 * @event Hooks#afterDocumentKeyDown
 * @param {Event} event A native `keydown` event object.
 */
'afterDocumentKeyDown',
/**
 * Fired inside the Walkontable's selection `draw` method. Can be used to add additional class names to cells, depending on the current selection.
 *
 * @event Hooks#afterDrawSelection
 * @param {Number} currentRow Row index of the currently processed cell.
 * @param {Number} currentColumn Column index of the currently cell.
 * @param {Number[]} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
 * @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
 * @since 0.38.1
 * @returns {String|undefined} Can return a `String`, which will act as an additional `className` to be added to the currently processed cell.
 */
'afterDrawSelection',
/**
 * Fired inside the Walkontable's `refreshSelections` method. Can be used to remove additional class names from all cells in the table.
 *
 * @event Hooks#beforeRemoveCellClassNames
 * @since 0.38.1
 * @returns {String[]|undefined} Can return an `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
 */
'beforeRemoveCellClassNames',
/**
 * Fired after getting the cell settings.
 *
 * @event Hooks#afterGetCellMeta
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {Object} cellProperties Object containing the cell properties.
 */
'afterGetCellMeta',
/**
 * Fired after retrieving information about a column header and appending it to the table header.
 *
 * @event Hooks#afterGetColHeader
 * @param {Number} column Visual column index.
 * @param {HTMLTableCellElement} TH Header's TH element.
 */
'afterGetColHeader',
/**
 * Fired after retrieving information about a row header and appending it to the table header.
 *
 * @event Hooks#afterGetRowHeader
 * @param {Number} row Visual row index.
 * @param {HTMLTableCellElement} TH Header's TH element.
 */
'afterGetRowHeader',
/**
 * Fired after the Handsontable instance is initiated.
 *
 * @event Hooks#afterInit
 */
'afterInit',
/**
 * Fired after new data is loaded (by `loadData` or `updateSettings` method) into the data source array.
 *
 * @event Hooks#afterLoadData
 * @param {Boolean} initialLoad flag that determines whether the data has been loaded during the initialization.
 */
'afterLoadData',
/**
 * Fired after a scroll event, which is identified as a momentum scroll (e.g. on an iPad).
 *
 * @event Hooks#afterMomentumScroll
 */
'afterMomentumScroll',
/**
 * Fired after a `mousedown` event is triggered on the cell corner (the drag handle).
 *
 * @event Hooks#afterOnCellCornerMouseDown
 * @param {Event} event `mousedown` event object.
 */
'afterOnCellCornerMouseDown',
/**
 * Fired after a `dblclick` event is triggered on the cell corner (the drag handle).
 *
 * @event Hooks#afterOnCellCornerDblClick
 * @param {Event} event `dblclick` event object.
 */
'afterOnCellCornerDblClick',
/**
 * Fired after clicking on a cell or row/column header. In case the row/column header was clicked, the coordinate
 * indexes are negative.
 *
 * For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseDown` called
 * with coordinates `{row: 0, col: -1}`.
 *
 * @event Hooks#afterOnCellMouseDown
 * @param {Event} event `mousedown` event object.
 * @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
 * @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
 */
'afterOnCellMouseDown',
/**
 * Fired after clicking on a cell or row/column header. In case the row/column header was clicked, the coordinate
 * indexes are negative.
 *
 * For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseUp` called
 * with coordinates `{row: 0, col: -1}`.
 *
 * @event Hooks#afterOnCellMouseUp
 * @param {Event} event `mouseup` event object.
 * @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
 * @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
 */
'afterOnCellMouseUp',
/**
 * Fired after clicking right mouse button on a cell or row/column header.
 *
 * For example clicking on the row header of cell (0, 0) results with `afterOnCellContextMenu` called
 * with coordinates `{row: 0, col: -1}`.
 *
 * @event Hooks#afterOnCellContextMenu
 * @since 4.1.0
 * @param {Event} event `contextmenu` event object.
 * @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
 * @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
 */
'afterOnCellContextMenu',
/**
 * Fired after hovering a cell or row/column header with the mouse cursor. In case the row/column header was
 * hovered, the index is negative.
 *
 * For example, hovering over the row header of cell (0, 0) results with `afterOnCellMouseOver` called
 * with coords `{row: 0, col: -1}`.
 *
 * @event Hooks#afterOnCellMouseOver
 * @param {Event} event `mouseover` event object.
 * @param {CellCoords} coords Hovered cell's visual coordinate object.
 * @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
 */
'afterOnCellMouseOver',
/**
 * Fired after leaving a cell or row/column header with the mouse cursor.
 *
 * @event Hooks#afterOnCellMouseOut
 * @param {Event} event `mouseout` event object.
 * @param {CellCoords} coords Leaved cell's visual coordinate object.
 * @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
 */
'afterOnCellMouseOut',
/**
 * Fired after one or more columns are removed.
 *
 * @event Hooks#afterRemoveCol
 * @param {Number} index Visual index of starter column.
 * @param {Number} amount An amount of removed columns.
 * @param {Number[]} physicalColumns An array of physical columns removed from the data source.
 * @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterRemoveCol',
/**
 * Fired after one or more rows are removed.
 *
 * @event Hooks#afterRemoveRow
 * @param {Number} index Visual index of starter row.
 * @param {Number} amount An amount of removed rows.
 * @param {Number[]} physicalRows An array of physical rows removed from the data source.
 * @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterRemoveRow',
/**
 * Fired after the Handsontable table is rendered.
 *
 * @event Hooks#afterRender
 * @param {Boolean} isForced Is `true` if rendering was triggered by a change of settings or data; or `false` if
 *                           rendering was triggered by scrolling or moving selection.
 */
'afterRender',
/**
 * Fired before starting rendering the cell.
 *
 * @event Hooks#beforeRenderer
 * @param {HTMLTableCellElement} TD Currently rendered cell's TD element.
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
 * @param {*} value Value of the rendered cell.
 * @param {Object} cellProperties Object containing the cell's properties.
 */
'beforeRenderer',
/**
 * Fired after finishing rendering the cell (after the renderer finishes).
 *
 * @event Hooks#afterRenderer
 * @param {HTMLTableCellElement} TD Currently rendered cell's TD element.
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
 * @param {*} value Value of the rendered cell.
 * @param {Object} cellProperties Object containing the cell's properties.
 */
'afterRenderer',
/**
 * Fired after the horizontal scroll event.
 *
 * @event Hooks#afterScrollHorizontally
 */
'afterScrollHorizontally',
/**
 * Fired after the vertical scroll event.
 *
 * @event Hooks#afterScrollVertically
 */
'afterScrollVertically',
/**
 * Fired after one or more cells are selected (e.g. during mouse move).
 *
 * @event Hooks#afterSelection
 * @param {Number} row Selection start visual row index.
 * @param {Number} column Selection start visual column index.
 * @param {Number} row2 Selection end visual row index.
 * @param {Number} column2 Selection end visual column index.
 * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
 * @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
 * @example
 * ```js
 * new Handsontable(element, {
 *   afterSelection: (row, column, row2, column2, preventScrolling, selectionLayerLevel) => {
 *     // setting if prevent scrolling after selection
 *     preventScrolling.value = true;
 *   }
 * })
 * ```
 */
'afterSelection',
/**
 * Fired after one or more cells are selected.
 *
 * The `prop` and `prop2` arguments represent the source object property name instead of the column number.
 *
 * @event Hooks#afterSelectionByProp
 * @param {Number} row Selection start visual row index.
 * @param {String} prop Selection start data source object property name.
 * @param {Number} row2 Selection end visual row index.
 * @param {String} prop2 Selection end data source object property name.
 * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
 * @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
 * @example
 * ```js
 * new Handsontable(element, {
 *   afterSelectionByProp: (row, column, row2, column2, preventScrolling, selectionLayerLevel) => {
 *     // setting if prevent scrolling after selection
 *     preventScrolling.value = true;
 *   }
 * })
 * ```
 */
'afterSelectionByProp',
/**
 * Fired after one or more cells are selected (e.g. on mouse up).
 *
 * @event Hooks#afterSelectionEnd
 * @param {Number} row Selection start visual row index.
 * @param {Number} column Selection start visual column index.
 * @param {Number} row2 Selection end visual row index.
 * @param {Number} column2 Selection end visual column index.
 * @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
 */
'afterSelectionEnd',
/**
 * Fired after one or more cells are selected (e.g. on mouse up).
 *
 * The `prop` and `prop2` arguments represent the source object property name instead of the column number.
 *
 * @event Hooks#afterSelectionEndByProp
 * @param {Number} row Selection start visual row index.
 * @param {String} prop Selection start data source object property index.
 * @param {Number} row2 Selection end visual row index.
 * @param {String} prop2 Selection end data source object property index.
 * @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
 */
'afterSelectionEndByProp',
/**
 * Fired after cell meta is changed.
 *
 * @event Hooks#afterSetCellMeta
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {String} key The updated meta key.
 * @param {*} value The updated meta value.
 */
'afterSetCellMeta',
/**
 * Fired after cell meta is removed.
 *
 * @event Hooks#afterRemoveCellMeta
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {String} key The removed meta key.
 * @param {*} value Value which was under removed key of cell meta.
 */
'afterRemoveCellMeta',
/**
 * Fired after cell data was changed.
 *
 * @event Hooks#afterSetDataAtCell
 * @param {Array} changes An array of changes in format `[[row, column, oldValue, value], ...]`.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterSetDataAtCell',
/**
 * Fired after cell data was changed.
 *
 * @event Hooks#afterSetDataAtRowProp
 * @param {Array} changes An array of changes in format `[[row, prop, oldValue, value], ...]`.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterSetDataAtRowProp',
/**
 * Fired after calling the `updateSettings` method.
 *
 * @event Hooks#afterUpdateSettings
 * @param {Object} newSettings New settings object.
 */
'afterUpdateSettings',
/**
 * @description
 * A plugin hook executed after validator function, only if validator function is defined.
 * Validation result is the first parameter. This can be used to determinate if validation passed successfully or not.
 *
 * __Returning false from the callback will mark the cell as invalid.__
 *
 * @event Hooks#afterValidate
 * @param {Boolean} isValid `true` if valid, `false` if not.
 * @param {*} value The value in question.
 * @param {Number} row Visual row index.
 * @param {String|Number} prop Property name / visual column index.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'afterValidate',
/**
 * Fired before successful change of language (when proper language code was set)
 *
 * @event Hooks#beforeLanguageChange
 * @since 0.35.0
 * @param {String} languageCode New language code.
 */
'beforeLanguageChange',
/**
 * Fired after successful change of language (when proper language code was set).
 *
 * @event Hooks#afterLanguageChange
 * @since 0.35.0
 * @param {String} languageCode New language code.
 */
'afterLanguageChange',
/**
 * Fired by {@link Autofill} plugin before populating the data in the autofill feature. This hook is fired when
 * {@link Options#fillHandle} option is enabled.
 *
 * @event Hooks#beforeAutofill
 * @param {CellCoords} start Object containing information about first filled cell: `{row: 2, col: 0}`.
 * @param {CellCoords} end Object containing information about last filled cell: `{row: 4, col: 1}`.
 * @param {Array[]} data 2D array containing information about fill pattern: `[["1", "Ted"], ["1", "John"]]`.
 */
'beforeAutofill',
/**
 * Fired before aligning the cell contents.
 *
 * @event Hooks#beforeCellAlignment
 * @param {Object} stateBefore An object with class names defining the cell alignment.
 * @param {CellRange[]} range An array of CellRange coordinates where the alignment will be applied.
 * @param {String} type Type of the alignment - either `horizontal` or `vertical`.
 * @param {String} alignmentClass String defining the alignment class added to the cell.
 * Possible values:
 * * `htLeft`
 * * `htCenter`
 * * `htRight`
 * * `htJustify`
 * * `htTop`
 * * `htMiddle`
 * * `htBottom`
 */
'beforeCellAlignment',
/**
 * Fired before one or more cells is changed. Its main purpose is to alter changes silently after input and before
 * table rendering.
 *
 * @event Hooks#beforeChange
 * @param {Array[]} changes 2D array containing information about each of the edited cells.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 * @example
 * ```js
 * // To disregard a single change, set changes[i] to null or remove it from array using changes.splice(i, 1).
 * new Handsontable(element, {
 *   beforeChange: (changes, source) => {
 *     // [[row, prop, oldVal, newVal], ...]
 *     changes[0] = null;
 *   }
 * });
 * // To alter a single change, overwrite the desired value to changes[i][3].
 * new Handsontable(element, {
 *   beforeChange: (changes, source) => {
 *     // [[row, prop, oldVal, newVal], ...]
 *     changes[0][3] = 10;
 *   }
 * });
 * // To cancel all edit, return false from the callback or set array length to 0 (changes.length = 0).
 * new Handsontable(element, {
 *   beforeChange: (changes, source) => {
 *     // [[row, prop, oldVal, newVal], ...]
 *     return false;
 *   }
 * });
 * ```
 */
'beforeChange',
/**
 * Fired right before rendering the changes.
 *
 * @event Hooks#beforeChangeRender
 * @param {Array[]} changes Array in form of `[row, prop, oldValue, newValue]`.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeChangeRender',
/**
 * Fired before drawing the borders.
 *
 * @event Hooks#beforeDrawBorders
 * @param {Array} corners Array specifying the current selection borders.
 * @param {String} borderClassName Specifies the border class name.
 */
'beforeDrawBorders',
/**
 * Fired before getting cell settings.
 *
 * @event Hooks#beforeGetCellMeta
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {Object} cellProperties Object containing the cell's properties.
 */
'beforeGetCellMeta',
/**
 * Fired before cell meta is removed.
 *
 * @event Hooks#beforeRemoveCellMeta
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {String} key The removed meta key.
 * @param {*} value Value which is under removed key of cell meta.
 */
'beforeRemoveCellMeta',
/**
 * Fired before the Handsontable instance is initiated.
 *
 * @event Hooks#beforeInit
 */
'beforeInit',
/**
 * Fired before the Walkontable instance is initiated.
 *
 * @event Hooks#beforeInitWalkontable
 * @param {Object} walkontableConfig Walkontable configuration object.
 */
'beforeInitWalkontable',
/**
 * Fired before keydown event is handled. It can be used to overwrite default key bindings.
 *
 * __Note__: To prevent default behavior you need to call `event.stopImmediatePropagation()` in your `beforeKeyDown`
 * handler.
 *
 * @event Hooks#beforeKeyDown
 * @param {Event} event Original DOM event.
 */
'beforeKeyDown',
/**
 * Fired after the user clicked a cell, but before all the calculations related with it.
 *
 * @event Hooks#beforeOnCellMouseDown
 * @param {Event} event The `mousedown` event object.
 * @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
 * @param {HTMLTableCellElement} TD TD element.
 * @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
 *                            object allows or disallows changing the selection for the particular axies.
 */
'beforeOnCellMouseDown',
/**
 * Fired after the user clicked a cell.
 *
 * @event Hooks#beforeOnCellMouseUp
 * @param {Event} event The `mouseup` event object.
 * @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
 * @param {HTMLTableCellElement} TD TD element.
 * @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
 *                            object allows or disallows changing the selection for the particular axies.
 */
'beforeOnCellMouseUp',
/**
 * Fired after the user clicked a cell, but before all the calculations related with it.
 *
 * @event Hooks#beforeOnCellContextMenu
 * @since 4.1.0
 * @param {Event} event The `contextmenu` event object.
 * @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
 * @param {HTMLTableCellElement} TD TD element.
 */
'beforeOnCellContextMenu',
/**
 * Fired after the user moved cursor over a cell, but before all the calculations related with it.
 *
 * @event Hooks#beforeOnCellMouseOver
 * @param {Event} event The `mouseover` event object.
 * @param {CellCoords} coords CellCoords object containing the visual coordinates of the clicked cell.
 * @param {HTMLTableCellElement} TD TD element.
 * @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
 *                            object allows or disallows changing the selection for the particular axies.
 */
'beforeOnCellMouseOver',
/**
 * Fired after the user moved cursor out from a cell, but before all the calculations related with it.
 *
 * @event Hooks#beforeOnCellMouseOut
 * @param {Event} event The `mouseout` event object.
 * @param {CellCoords} coords CellCoords object containing the visual coordinates of the leaved cell.
 * @param {HTMLTableCellElement} TD TD element.
 */
'beforeOnCellMouseOut',
/**
 * Fired before one or more columns are about to be removed.
 *
 * @event Hooks#beforeRemoveCol
 * @param {Number} index Visual index of starter column.
 * @param {Number} amount Amount of columns to be removed.
 * @param {Number[]} physicalColumns An array of physical columns removed from the data source.
 * @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeRemoveCol',
/**
 * Fired when one or more rows are about to be removed.
 *
 * @event Hooks#beforeRemoveRow
 * @param {Number} index Visual index of starter column.
 * @param {Number} amount Amount of columns to be removed.
 * @param {Number[]} physicalRows An array of physical rows removed from the data source.
 * @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeRemoveRow',
/**
 * Fired before the Handsontable table is rendered.
 *
 * @event Hooks#beforeRender
 * @param {Boolean} isForced If `true` rendering was triggered by a change of settings or data; or `false` if
 *                           rendering was triggered by scrolling or moving selection.
 */
'beforeRender',
/**
 * Fired before setting range is started but not finished yet.
 *
 * @event Hooks#beforeSetRangeStartOnly
 * @param {CellCoords} coords CellCoords instance.
 */
'beforeSetRangeStartOnly',
/**
 * Fired before setting range is started.
 *
 * @event Hooks#beforeSetRangeStart
 * @param {CellCoords} coords CellCoords instance.
 */
'beforeSetRangeStart',
/**
 * Fired before setting range is ended.
 *
 * @event Hooks#beforeSetRangeEnd
 * @param {CellCoords} coords CellCoords instance.
 */
'beforeSetRangeEnd',
/**
 * Fired before the logic of handling a touch scroll, when user started scrolling on a touch-enabled device.
 *
 * @event Hooks#beforeTouchScroll
 */
'beforeTouchScroll',
/**
 * Fired before cell validation, only if validator function is defined. This can be used to manipulate the value
 * of changed cell before it is applied to the validator function.
 *
 * __Note:__ this will not affect values of changes. This will change value *ONLY* for validation
 *
 * @event Hooks#beforeValidate
 * @param {*} value Value of the cell.
 * @param {Number} row Visual row index.
 * @param {String|Number} prop Property name / column index.
 * @param {String} [source] String that identifies source of hook call
 *                          ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
 */
'beforeValidate',
/**
 * Fired before cell value is rendered into the DOM (through renderer function). This can be used to manipulate the
 * value which is passed to the renderer without modifying the renderer itself.
 *
 * @event Hooks#beforeValueRender
 * @param {*} value Cell value to render.
 * @param {Object} cellProperties An object containing the cell properties.
 */
'beforeValueRender',
/**
 * Fired after Handsontable instance is constructed (using `new` operator).
 *
 * @event Hooks#construct
 */
'construct',
/**
 * Fired after Handsontable instance is initiated but before table is rendered.
 *
 * @event Hooks#init
 */
'init',
/**
 * Fired when a column index is about to be modified by a callback function.
 *
 * @event Hooks#modifyCol
 * @param {Number} column Visual column index.
 */
'modifyCol',
/**
 * Fired when a column index is about to be de-modified by a callback function.
 *
 * @event Hooks#unmodifyCol
 * @param {Number} column Physical column index.
 */
'unmodifyCol',
/**
 * Fired when a physical row index is about to be de-modified by a callback function.
 *
 * @event Hooks#unmodifyRow
 * @param {Number} row Physical row index.
 */
'unmodifyRow',
/**
 * Fired when a column header index is about to be modified by a callback function.
 *
 * @event Hooks#modifyColHeader
 * @param {Number} column Visual column header index.
 */
'modifyColHeader',
/**
 * Fired when a column width is about to be modified by a callback function.
 *
 * @event Hooks#modifyColWidth
 * @param {Number} width Current column width.
 * @param {Number} column Visual column index.
 */
'modifyColWidth',
/**
 * Fired when a row index is about to be modified by a callback function.
 *
 * @event Hooks#modifyRow
 * @param {Number} row Visual row index.
 */
'modifyRow',
/**
 * Fired when a row header index is about to be modified by a callback function.
 *
 * @event Hooks#modifyRowHeader
 * @param {Number} row Visual row header index.
 */
'modifyRowHeader',
/**
 * Fired when a row height is about to be modified by a callback function.
 *
 * @event Hooks#modifyRowHeight
 * @param {Number} height Row height.
 * @param {Number} row Visual row index.
 */
'modifyRowHeight',
/**
 * Fired when a data was retrieved or modified.
 *
 * @event Hooks#modifyData
 * @param {Number} row Row height.
 * @param {Number} column Column index.
 * @param {Object} valueHolder Object which contains original value which can be modified by overwriting `.value` property.
 * @param {String} ioMode String which indicates for what operation hook is fired (`get` or `set`).
 */
'modifyData',
/**
 * Fired when a data was retrieved or modified.
 *
 * @event Hooks#modifyRowData
 * @param {Number} row Physical row index.
 */
'modifyRowData',
/**
 * Used to modify the cell coordinates when using the `getCell` method.
 *
 * @event Hooks#modifyGetCellCoords
 * @since 0.36.0
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {Boolean} topmost If set to `true`, it returns the TD element from the topmost overlay. For example,
 *                          if the wanted cell is in the range of fixed rows, it will return a TD element
 *                          from the `top` overlay.
 */
'modifyGetCellCoords',
/**
 * Fired by {@link PersistentState} plugin, after loading value, saved under given key, from browser local storage. This hook is fired when
 * {@link Options#persistentState} option is enabled.
 *
 * @event Hooks#persistentStateLoad
 * @param {String} key Key.
 * @param {Object} valuePlaceholder Object containing the loaded value under `valuePlaceholder.value` (if no value have been saved, `value` key will be undefined).
 */
'persistentStateLoad',
/**
 * Fired by {@link PersistentState} plugin after resetting data from local storage. If no key is given, all values associated with table will be cleared.
 * This hook is fired when {@link Options#persistentState} option is enabled.
 *
 * @event Hooks#persistentStateReset
 * @param {String} [key] Key.
 */
'persistentStateReset',
/**
 * Fired by {@link PersistentState} plugin, after saving value under given key in browser local storage. This hook is fired when
 * {@link Options#persistentState} option is enabled.
 *
 * @event Hooks#persistentStateSave
 * @param {String} key Key.
 * @param {Mixed} value Value to save.
 */
'persistentStateSave',
/**
 * Fired by {@link ColumnSorting} and {@link MultiColumnSorting} plugins before sorting the column. If you return `false` value inside callback for hook, then sorting
 * will be not applied by the Handsontable (useful for server-side sorting).
 *
 * This hook is fired when {@link Options#columnSorting} or {@link Options#multiColumnSorting} option is enabled.
 *
 * @event Hooks#beforeColumnSort
 * @param {Array} currentSortConfig Current sort configuration (for all sorted columns).
 * @param {Array} destinationSortConfigs Destination sort configuration (for all sorted columns).
 */
'beforeColumnSort',
/**
 * Fired by {@link ColumnSorting} and {@link MultiColumnSorting} plugins after sorting the column. This hook is fired when {@link Options#columnSorting}
 * or {@link Options#multiColumnSorting} option is enabled.
 *
 * @event Hooks#afterColumnSort
 * @param {Array} currentSortConfig Current sort configuration (for all sorted columns).
 * @param {Array} destinationSortConfigs Destination sort configuration (for all sorted columns).
 */
'afterColumnSort',
/**
 * Fired by {@link Autofill} plugin after setting range of autofill. This hook is fired when {@link Options#fillHandle}
 * option is enabled.
 *
 * @event Hooks#modifyAutofillRange
 * @param {Array} startArea Array of visual coordinates of the starting point for the drag-down operation (`[startRow, startColumn, endRow, endColumn]`).
 * @param {Array} entireArea Array of visual coordinates of the entire area of the drag-down operation (`[startRow, startColumn, endRow, endColumn]`).
 */
'modifyAutofillRange',
/**
 * Fired to allow modifying the copyable range with a callback function.
 *
 * @event Hooks#modifyCopyableRange
 * @param {Array[]} copyableRanges Array of objects defining copyable cells.
 */
'modifyCopyableRange',
/**
 * Fired by {@link CopyPaste} plugin before copying the values into clipboard and before clearing values of
 * the selected cells. This hook is fired when {@link Options#copyPaste} option is enabled.
 *
 * @event Hooks#beforeCut
 * @param {Array[]} data An array of arrays which contains data to cut.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                       which will be cut out.
 * @returns {*} If returns `false` then operation of the cutting out is canceled.
 * @example
 * ```js
 * // To disregard a single row, remove it from the array using data.splice(i, 1).
 * new Handsontable(element, {
 *   beforeCut: function(data, coords) {
 *     // data -> [[1, 2, 3], [4, 5, 6]]
 *     data.splice(0, 1);
 *     // data -> [[4, 5, 6]]
 *     // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
 *   }
 * });
 * // To cancel a cutting action, just return `false`.
 * new Handsontable(element, {
 *   beforeCut: function(data, coords) {
 *     return false;
 *   }
 * });
 * ```
 */
'beforeCut',
/**
 * Fired by {@link CopyPaste} plugin after data was cut out from the table. This hook is fired when
 * {@link Options#copyPaste} option is enabled.
 *
 * @event Hooks#afterCut
 * @param {Array[]} data An array of arrays which contains the cutted out data.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                       which was cut out.
 */
'afterCut',
/**
 * Fired before values are copied into clipboard.
 *
 * @event Hooks#beforeCopy
 * @param {Array[]} data An array of arrays which contains data to copied.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                         which will copied.
 * @returns {*} If returns `false` then copying is canceled.
 *
 * @example
 * ```js
 * // To disregard a single row, remove it from array using data.splice(i, 1).
 * ...
 * new Handsontable(document.getElementById('example'), {
 *   beforeCopy: (data, coords) => {
 *     // data -> [[1, 2, 3], [4, 5, 6]]
 *     data.splice(0, 1);
 *     // data -> [[4, 5, 6]]
 *     // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
 *   }
 * });
 * ...
 *
 * // To cancel copying, return false from the callback.
 * ...
 * new Handsontable(document.getElementById('example'), {
 *   beforeCopy: (data, coords) => {
 *     return false;
 *   }
 * });
 * ...
 * ```
 */
'beforeCopy',
/**
 * Fired by {@link CopyPaste} plugin after data are pasted into table. This hook is fired when {@link Options#copyPaste}
 * option is enabled.
 *
 * @event Hooks#afterCopy
 * @param {Array[]} data An array of arrays which contains the copied data.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                         which was copied.
 */
'afterCopy',
/**
 * Fired by {@link CopyPaste} plugin before values are pasted into table. This hook is fired when
 * {@link Options#copyPaste} option is enabled.
 *
 * @event Hooks#beforePaste
 * @param {Array[]} data An array of arrays which contains data to paste.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                       that correspond to the previously selected area.
 * @returns {*} If returns `false` then pasting is canceled.
 * @example
 * ```js
 * // To disregard a single row, remove it from array using data.splice(i, 1).
 * new Handsontable(example, {
 *   beforePaste: (data, coords) => {
 *     // data -> [[1, 2, 3], [4, 5, 6]]
 *     data.splice(0, 1);
 *     // data -> [[4, 5, 6]]
 *     // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
 *   }
 * });
 * // To cancel pasting, return false from the callback.
 * new Handsontable(example, {
 *   beforePaste: (data, coords) => {
 *     return false;
 *   }
 * });
 * ```
 */
'beforePaste',
/**
 * Fired by {@link CopyPaste} plugin after values are pasted into table. This hook is fired when
 * {@link Options#copyPaste} option is enabled.
 *
 * @event Hooks#afterPaste
 * @param {Array[]} data An array of arrays which contains the pasted data.
 * @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
 *                       that correspond to the previously selected area.
 */
'afterPaste',
/**
 * Fired by {@link ManualColumnMove} plugin before change order of the visual indexes. This hook is fired when
 * {@link Options#manualColumnMove} option is enabled.
 *
 * @event Hooks#beforeColumnMove
 * @param {Number[]} columns Array of visual column indexes to be moved.
 * @param {Number} target Visual column index being a target for moved columns.
 */
'beforeColumnMove',
/**
 * Fired by {@link ManualColumnMove} plugin after changing order of the visual indexes. This hook is fired when
 * {@link Options#manualColumnMove} option is enabled.
 *
 * @event Hooks#afterColumnMove
 * @param {Number[]} columns Array of visual column indexes that were moved.
 * @param {Number} target Visual column index being a target for moved columns.
 */
'afterColumnMove',
/**
 * Fired by {@link ManualRowMove} plugin before change order of the visual indexes. This hook is fired when
 * {@link Options#manualRowMove} option is enabled.
 *
 * @event Hooks#beforeRowMove
 * @param {Number[]} rows An array of visual row indexes to be moved.
 * @param {Number} target Visual row index being a target for moved rows.
 */
'beforeRowMove',
/**
 * Fired by {@link ManualRowMove} plugin after change order of the visual indexes. This hook is fired when
 * {@link Options#manualRowMove} option is enabled.
 *
 * @event Hooks#afterRowMove
 * @param {Number[]} rows An array of visual row indexes that were moved.
 * @param {Number} target Visual row index being a target for moved rows.
 */
'afterRowMove',
/**
 * Fired by {@link ManualColumnResize} plugin before rendering the table with modified column sizes. This hook is
 * fired when {@link Options#manualColumnResize} option is enabled.
 *
 * @event Hooks#beforeColumnResize
 * @param {Number} currentColumn Visual index of the resized column.
 * @param {Number} newSize Calculated new column width.
 * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
 * @returns {Number} Returns a new column size or `undefined`, if column size should be calculated automatically.
 */
'beforeColumnResize',
/**
 * Fired by {@link ManualColumnResize} plugin after rendering the table with modified column sizes. This hook is
 * fired when {@link Options#manualColumnResize} option is enabled.
 *
 * @event Hooks#afterColumnResize
 * @param {Number} currentColumn Visual index of the resized column.
 * @param {Number} newSize Calculated new column width.
 * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
 */
'afterColumnResize',
/**
 * Fired by {@link ManualRowResize} plugin before rendering the table with modified row sizes. This hook is
 * fired when {@link Options#manualRowResize} option is enabled.
 *
 * @event Hooks#beforeRowResize
 * @param {Number} currentRow Visual index of the resized row.
 * @param {Number} newSize Calculated new row height.
 * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
 * @returns {Number} Returns the new row size or `undefined` if row size should be calculated automatically.
 */
'beforeRowResize',
/**
 * Fired by {@link ManualRowResize} plugin after rendering the table with modified row sizes. This hook is
 * fired when {@link Options#manualRowResize} option is enabled.
 *
 * @event Hooks#afterRowResize
 * @param {Number} currentRow Visual index of the resized row.
 * @param {Number} newSize Calculated new row height.
 * @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
 */
'afterRowResize',
/**
 * Fired after getting the column header renderers.
 *
 * @event Hooks#afterGetColumnHeaderRenderers
 * @param {Function[]} renderers An array of the column header renderers.
 */
'afterGetColumnHeaderRenderers',
/**
 * Fired after getting the row header renderers.
 *
 * @event Hooks#afterGetRowHeaderRenderers
 * @param {Function[]} renderers An array of the row header renderers.
 */
'afterGetRowHeaderRenderers',
/**
 * Fired before applying stretched column width to column.
 *
 * @event Hooks#beforeStretchingColumnWidth
 * @param {Number} stretchedWidth Calculated width.
 * @param {Number} column Visual column index.
 * @returns {Number} Returns new width which will be applied to the column element.
 */
'beforeStretchingColumnWidth',
/**
 * Fired by {@link Filters} plugin before applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}. This hook is fired when
 * {@link Options#filters} option is enabled.
 *
 * @event Hooks#beforeFilter
 * @param {Object[]} conditionsStack An array of objects with added formulas.
 * ```js
 * // Example format of the conditionsStack argument:
 * [
 *   {
 *     column: 2,
 *     conditions: [
 *       {name: 'begins_with', args: [['S']]}
 *     ],
 *     operation: 'conjunction'
 *   },
 *   {
 *     column: 4,
 *     conditions: [
 *       {name: 'not_empty', args: []}
 *     ],
 *     operation: 'conjunction'
 *   },
 * ]
 * ```
 * @returns {Boolean} If hook returns `false` value then filtering won't be applied on the UI side (server-side filtering).
 */
'beforeFilter',
/**
 * Fired by {@link Filters} plugin after applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}. This hook is fired when
 * {@link Options#filters} option is enabled.
 *
 * @event Hooks#afterFilter
 * @param {Object[]} conditionsStack An array of objects with added conditions.
 * ```js
 * // Example format of the conditionsStack argument:
 * [
 *   {
 *     column: 2,
 *     conditions: [
 *       {name: 'begins_with', args: [['S']]}
 *     ],
 *     operation: 'conjunction'
 *   },
 *   {
 *     column: 4,
 *     conditions: [
 *       {name: 'not_empty', args: []}
 *     ],
 *     operation: 'conjunction'
 *   },
 * ]
 * ```
 */
'afterFilter',
/**
 * Fired while retrieving the column header height.
 *
 * @event Hooks#modifyColumnHeaderHeight
 */
'modifyColumnHeaderHeight',
/**
 * Fired by {@link UndoRedo} plugin before the undo action. Contains information about the action that is being undone.
 * This hook is fired when {@link Options#undo} option is enabled.
 *
 * @event Hooks#beforeUndo
 * @param {Object} action The action object. Contains information about the action being undone. The `actionType`
 *                        property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
 */
'beforeUndo',
/**
 * Fired by {@link UndoRedo} plugin after the undo action. Contains information about the action that is being undone.
 * This hook is fired when {@link Options#undo} option is enabled.
 *
 * @event Hooks#afterUndo
 * @param {Object} action The action object. Contains information about the action being undone. The `actionType`
 *                        property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
 */
'afterUndo',
/**
 * Fired by {@link UndoRedo} plugin before the redo action. Contains information about the action that is being redone.
 * This hook is fired when {@link Options#undo} option is enabled.
 *
 * @event Hooks#beforeRedo
 * @param {Object} action The action object. Contains information about the action being redone. The `actionType`
 *                        property of the object specifies the type of the action in a String format (e.g. `'remove_row'`).
 */
'beforeRedo',
/**
 * Fired by {@link UndoRedo} plugin after the redo action. Contains information about the action that is being redone.
 * This hook is fired when {@link Options#undo} option is enabled.
 *
 * @event Hooks#afterRedo
 * @param {Object} action The action object. Contains information about the action being redone. The `actionType`
 *                        property of the object specifies the type of the action in a String format (e.g. `'remove_row'`).
 */
'afterRedo',
/**
 * Fired while retrieving the row header width.
 *
 * @event Hooks#modifyRowHeaderWidth
 * @param {Number} rowHeaderWidth Row header width.
 */
'modifyRowHeaderWidth',
/**
 * Fired from the `populateFromArray` method during the `autofill` process. Fired for each "autofilled" cell individually.
 *
 * @event Hooks#beforeAutofillInsidePopulate
 * @param {Object} index Object containing `row` and `col` properties, defining the number of rows/columns from the initial cell of the autofill.
 * @param {String} direction Declares the direction of the autofill. Possible values: `up`, `down`, `left`, `right`.
 * @param {Array[]} input Contains an array of rows with data being used in the autofill.
 * @param {Array} deltas The deltas array passed to the `populateFromArray` method.
 */
'beforeAutofillInsidePopulate',
/**
 * Fired when the start of the selection is being modified (e.g. moving the selection with the arrow keys).
 *
 * @event Hooks#modifyTransformStart
 * @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
 */
'modifyTransformStart',
/**
 * Fired when the end of the selection is being modified (e.g. moving the selection with the arrow keys).
 *
 * @event Hooks#modifyTransformEnd
 * @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
 */
'modifyTransformEnd',
/**
 * Fired after the start of the selection is being modified (e.g. moving the selection with the arrow keys).
 *
 * @event Hooks#afterModifyTransformStart
 * @param {CellCoords} coords Coords of the freshly selected cell.
 * @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
 * @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
 */
'afterModifyTransformStart',
/**
 * Fired after the end of the selection is being modified (e.g. moving the selection with the arrow keys).
 *
 * @event Hooks#afterModifyTransformEnd
 * @param {CellCoords} coords Visual coords of the freshly selected cell.
 * @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
 * @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
 */
'afterModifyTransformEnd',
/**
 * Fired inside the `viewportRowCalculatorOverride` method. Allows modifying the row calculator parameters.
 *
 * @event Hooks#afterViewportRowCalculatorOverride
 * @param {Object} calc The row calculator.
 */
'afterViewportRowCalculatorOverride',
/**
 * Fired inside the `viewportColumnCalculatorOverride` method. Allows modifying the row calculator parameters.
 *
 * @event Hooks#afterViewportColumnCalculatorOverride
 * @param {Object} calc The row calculator.
 */
'afterViewportColumnCalculatorOverride',
/**
 * Fired after initializing all the plugins.
 *
 * @event Hooks#afterPluginsInitialized
 */
'afterPluginsInitialized',
/**
 * Used to skip the length cache calculation for a defined period of time.
 *
 * @event Hooks#skipLengthCache
 * @param {Number} delay The delay in milliseconds.
 */
'skipLengthCache',
/**
 * Fired by {@link HiddenRows} plugin before marking the rows as hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
 * Returning `false` in the callback will prevent the hiding action from completing.
 *
 * @event Hooks#beforeHideRows
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
 * @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
 */
'beforeHideRows',
/**
 * Fired by {@link HiddenRows} plugin after marking the rows as hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
 *
 * @event Hooks#afterHideRows
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
 * @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any non-hidden rows, `false` otherwise.
 */
'afterHideRows',
/**
 * Fired by {@link HiddenRows} plugin before marking the rows as not hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
 * Returning `false` in the callback will prevent the row revealing action from completing.
 *
 * @event Hooks#beforeUnhideRows
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
 * @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the revealing action will not be completed.
 */
'beforeUnhideRows',
/**
 * Fired by {@link HiddenRows} plugin after marking the rows as not hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
 *
 * @event Hooks#afterUnhideRows
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
 * @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any hidden rows, `false` otherwise.
 */
'afterUnhideRows',
/**
 * Fired by {@link HiddenColumns} plugin before marking the columns as hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
 * Returning `false` in the callback will prevent the hiding action from completing.
 *
 * @event Hooks#beforeHideColumns
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
 * @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
 */
'beforeHideColumns',
/**
 * Fired by {@link HiddenColumns} plugin after marking the columns as hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
 *
 * @event Hooks#afterHideColumns
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
 * @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any non-hidden columns, `false` otherwise.
 */
'afterHideColumns',
/**
 * Fired by {@link HiddenColumns} plugin before marking the columns as not hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
 * Returning `false` in the callback will prevent the column revealing action from completing.
 *
 * @event Hooks#beforeUnhideColumns
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
 * @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
 */
'beforeUnhideColumns',
/**
 * Fired by {@link HiddenColumns} plugin after marking the columns as not hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
 *
 * @event Hooks#afterUnhideColumns
 * @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
 * @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
 * @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any hidden columns, `false` otherwise.
 */
'afterUnhideColumns',
/**
 * Fired by {@link TrimRows} plugin before trimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
 *
 * @event Hooks#beforeTrimRow
 * @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
 * @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
 * @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the trimming action will not be completed.
 */
'beforeTrimRow',
/**
 * Fired by {@link TrimRows} plugin after trimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
 *
 * @event Hooks#afterTrimRow
 * @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
 * @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
 * @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any non-trimmed rows, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the trimming action will not be completed.
 */
'afterTrimRow',
/**
 * Fired by {@link TrimRows} plugin before untrimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
 *
 * @event Hooks#beforeUntrimRow
 * @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
 * @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
 * @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the untrimming action will not be completed.
 */
'beforeUntrimRow',
/**
 * Fired by {@link TrimRows} plugin after untrimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
 *
 * @event Hooks#afterUntrimRow
 * @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
 * @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
 * @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
 * @param {Boolean} stateChanged `true`, if the action affected any trimmed rows, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the untrimming action will not be completed.
 */
'afterUntrimRow',
/**
 * Fired by {@link DropdownMenu} plugin before opening the dropdown menu. This hook is fired when {@link Options#dropdownMenu}
 * option is enabled.
 *
 * @event Hooks#beforeDropdownMenuShow
 * @param {DropdownMenu} dropdownMenu The DropdownMenu instance.
 */
'beforeDropdownMenuShow',
/**
 * Fired by {@link DropdownMenu} plugin after opening the Dropdown Menu. This hook is fired when {@link Options#dropdownMenu}
 * option is enabled.
 *
 * @event Hooks#afterDropdownMenuShow
 * @param {DropdownMenu} dropdownMenu The DropdownMenu instance.
 */
'afterDropdownMenuShow',
/**
 * Fired by {@link DropdownMenu} plugin after hiding the Dropdown Menu. This hook is fired when {@link Options#dropdownMenu}
 * option is enabled.
 *
 * @event Hooks#afterDropdownMenuHide
 * @param {DropdownMenu} instance The DropdownMenu instance.
 */
'afterDropdownMenuHide',
/**
 * Fired by {@link HiddenRows} plugin to check whether the provided row index is hidden. This hook is fired when
 * {@link Options#hiddenRows} option is enabled.
 *
 * @event Hooks#hiddenRow
 * @param {Number} row The visual row index in question.
 */
'hiddenRow',
/**
 * Fired by {@link HiddenColumns} plugin to check whether the provided column index is hidden. This hook is fired when
 * {@link Options#hiddenColumns} option is enabled.
 *
 * @event Hooks#hiddenColumn
 * @param {Number} column The visual column index in question.
 */
'hiddenColumn',
/**
 * Fired by {@link NestedRows} plugin before adding a children to the NestedRows structure. This hook is fired when
 * {@link Options#nestedRows} option is enabled.
 *
 * @event Hooks#beforeAddChild
 * @param {Object} parent The parent object.
 * @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
 * @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
 */
'beforeAddChild',
/**
 * Fired by {@link NestedRows} plugin after adding a children to the NestedRows structure. This hook is fired when
 * {@link Options#nestedRows} option is enabled.
 *
 * @event Hooks#afterAddChild
 * @param {Object} parent The parent object.
 * @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
 * @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
 */
'afterAddChild',
/**
 * Fired by {@link NestedRows} plugin before detaching a child from its parent. This hook is fired when
 * {@link Options#nestedRows} option is enabled.
 *
 * @event Hooks#beforeDetachChild
 * @param {Object} parent An object representing the parent from which the element is to be detached.
 * @param {Object} element The detached element.
 */
'beforeDetachChild',
/**
 * Fired by {@link NestedRows} plugin after detaching a child from its parent. This hook is fired when
 * {@link Options#nestedRows} option is enabled.
 *
 * @event Hooks#afterDetachChild
 * @param {Object} parent An object representing the parent from which the element was detached.
 * @param {Object} element The detached element.
 */
'afterDetachChild',
/**
 * Fired after the editor is opened and rendered.
 *
 * @event Hooks#afterBeginEditing
 * @param {Number} row Visual row index of the edited cell.
 * @param {Number} column Visual column index of the edited cell.
 */
'afterBeginEditing',
/**
 * Fired by {@link MergeCells} plugin before cell merging. This hook is fired when {@link Options#mergeCells}
 * option is enabled.
 *
 * @event Hooks#beforeMergeCells
 * @param {CellRange} cellRange Selection cell range.
 * @param {Boolean} [auto=false] `true` if called automatically by the plugin.
 */
'beforeMergeCells',
/**
 * Fired by {@link MergeCells} plugin after cell merging. This hook is fired when {@link Options#mergeCells}
 * option is enabled.
 *
 * @event Hooks#afterMergeCells
 * @param {CellRange} cellRange Selection cell range.
 * @param {Object} mergeParent The parent collection of the provided cell range.
 * @param {Boolean} [auto=false] `true` if called automatically by the plugin.
 */
'afterMergeCells',
/**
 * Fired by {@link MergeCells} plugin before unmerging the cells. This hook is fired when {@link Options#mergeCells}
 * option is enabled.
 *
 * @event Hooks#beforeUnmergeCells
 * @param {CellRange} cellRange Selection cell range.
 * @param {Boolean} [auto=false] `true` if called automatically by the plugin.
 */
'beforeUnmergeCells',
/**
 * Fired by {@link MergeCells} plugin after unmerging the cells. This hook is fired when {@link Options#mergeCells}
 * option is enabled.
 *
 * @event Hooks#afterUnmergeCells
 * @param {CellRange} cellRange Selection cell range.
 * @param {Boolean} [auto=false] `true` if called automatically by the plugin.
 */
'afterUnmergeCells',
/**
 * Fired after the table was switched into listening mode. This allows Handsontable to capture keyboard events and
 * respond in the right way.
 *
 * @event Hooks#afterListen
 */
'afterListen',
/**
 * Fired after the table was switched off from the listening mode. This makes the Handsontable inert for any
 * keyboard events.
 *
 * @event Hooks#afterUnlisten
 */
'afterUnlisten',
/**
 * Fired after the window was resized.
 *
 * @event Hooks#afterRefreshDimensions
 * @param {Object} previousDimensions Previous dimensions of the container.
 * @param {Object} currentDimensions Current dimensions of the container.
 * @param {Boolean} stateChanged `true`, if the container was re-render, `false` otherwise.
 */
'afterRefreshDimensions',
/**
 * Cancellable hook, called after resizing a window, but before redrawing a table.
 *
 * @event Hooks#beforeRefreshDimensions
 * @param {Object} previousDimensions Previous dimensions of the container.
 * @param {Object} currentDimensions Current dimensions of the container.
 * @param {Boolean} actionPossible `true`, if current and previous dimensions are different, `false` otherwise.
 * @returns {undefined|Boolean} If the callback returns `false`, the refresh action will not be completed.
 */
'beforeRefreshDimensions'];

var Hooks =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(Hooks, null, [{
    key: "getSingleton",
    value: function getSingleton() {
      return getGlobalSingleton();
    }
    /**
     *
     */

  }]);

  function Hooks() {
    (0, _classCallCheck2.default)(this, Hooks);
    this.globalBucket = this.createEmptyBucket();
  }
  /**
   * Returns a new object with empty handlers related to every registered hook name.
   *
   * @returns {Object} The empty bucket object.
   *
   * @example
   * ```js
   * Handsontable.hooks.createEmptyBucket();
   * // Results:
   * {
   * ...
   * afterCreateCol: [],
   * afterCreateRow: [],
   * beforeInit: [],
   * ...
   * }
   * ```
   */


  (0, _createClass2.default)(Hooks, [{
    key: "createEmptyBucket",
    value: function createEmptyBucket() {
      var bucket = Object.create(null); // eslint-disable-next-line no-return-assign

      (0, _array.arrayEach)(REGISTERED_HOOKS, function (hook) {
        return bucket[hook] = [];
      });
      return bucket;
    }
    /**
     * Get hook bucket based on the context of the object or if argument is `undefined`, get the global hook bucket.
     *
     * @param {Object} [context=null] A Handsontable instance.
     * @returns {Object} Returns a global or Handsontable instance bucket.
     */

  }, {
    key: "getBucket",
    value: function getBucket() {
      var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;

      if (context) {
        if (!context.pluginHookBucket) {
          context.pluginHookBucket = this.createEmptyBucket();
        }

        return context.pluginHookBucket;
      }

      return this.globalBucket;
    }
    /**
     * Adds a listener (globally or locally) to a specified hook name.
     * If the `context` parameter is provided, the hook will be added only to the instance it references.
     * Otherwise, the callback will be used everytime the hook fires on any Handsontable instance.
     * You can provide an array of callback functions as the `callback` argument, this way they will all be fired
     * once the hook is triggered.
     *
     * @see Core#addHook
     * @param {String} key Hook name.
     * @param {Function|Array} callback Callback function or an array of functions.
     * @param {Object} [context=null] The context for the hook callback to be added - a Handsontable instance or leave empty.
     * @returns {Hooks} Instance of Hooks.
     *
     * @example
     * ```js
     * // single callback, added locally
     * Handsontable.hooks.add('beforeInit', myCallback, hotInstance);
     *
     * // single callback, added globally
     * Handsontable.hooks.add('beforeInit', myCallback);
     *
     * // multiple callbacks, added locally
     * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback], hotInstance);
     *
     * // multiple callbacks, added globally
     * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback]);
     * ```
     */

  }, {
    key: "add",
    value: function add(key, callback) {
      var _this = this;

      var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;

      if (Array.isArray(callback)) {
        (0, _array.arrayEach)(callback, function (c) {
          return _this.add(key, c, context);
        });
      } else {
        var bucket = this.getBucket(context);

        if (typeof bucket[key] === 'undefined') {
          this.register(key);
          bucket[key] = [];
        }

        callback.skip = false;

        if (bucket[key].indexOf(callback) === -1) {
          // only add a hook if it has not already been added (adding the same hook twice is now silently ignored)
          var foundInitialHook = false;

          if (callback.initialHook) {
            (0, _array.arrayEach)(bucket[key], function (cb, i) {
              if (cb.initialHook) {
                bucket[key][i] = callback;
                foundInitialHook = true;
                return false;
              }
            });
          }

          if (!foundInitialHook) {
            bucket[key].push(callback);
          }
        }
      }

      return this;
    }
    /**
     * Adds a listener to a specified hook. After the hook runs this listener will be automatically removed from the bucket.
     *
     * @see Core#addHookOnce
     * @param {String} key Hook/Event name.
     * @param {Function|Array} callback Callback function.
     * @param {Object} [context=null] A Handsontable instance.
     *
     * @example
     * ```js
     * Handsontable.hooks.once('beforeInit', myCallback, hotInstance);
     * ```
     */

  }, {
    key: "once",
    value: function once(key, callback) {
      var _this2 = this;

      var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;

      if (Array.isArray(callback)) {
        (0, _array.arrayEach)(callback, function (c) {
          return _this2.once(key, c, context);
        });
      } else {
        callback.runOnce = true;
        this.add(key, callback, context);
      }
    }
    /**
     * Removes a listener from a hook with a given name. If the `context` argument is provided, it removes a listener from a local hook assigned to the given Handsontable instance.
     *
     * @see Core#removeHook
     * @param {String} key Hook/Event name.
     * @param {Function} callback Callback function (needs the be the function that was previously added to the hook).
     * @param {Object} [context=null] Handsontable instance.
     * @return {Boolean} Returns `true` if hook was removed, `false` otherwise.
     *
     * @example
     * ```js
     * Handsontable.hooks.remove('beforeInit', myCallback);
     * ```
     */

  }, {
    key: "remove",
    value: function remove(key, callback) {
      var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
      var bucket = this.getBucket(context);

      if (typeof bucket[key] !== 'undefined') {
        if (bucket[key].indexOf(callback) >= 0) {
          callback.skip = true;
          return true;
        }
      }

      return false;
    }
    /**
     * Checks whether there are any registered listeners for the provided hook name.
     * If the `context` parameter is provided, it only checks for listeners assigned to the given Handsontable instance.
     *
     * @param {String} key Hook name.
     * @param {Object} [context=null] A Handsontable instance.
     * @returns {Boolean} `true` for success, `false` otherwise.
     */

  }, {
    key: "has",
    value: function has(key) {
      var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
      var bucket = this.getBucket(context);
      return !!(bucket[key] !== void 0 && bucket[key].length);
    }
    /**
     * Runs all local and global callbacks assigned to the hook identified by the `key` parameter.
     * It returns either a return value from the last called callback or the first parameter (`p1`) passed to the `run` function.
     *
     * @see Core#runHooks
     * @param {Object} context Handsontable instance.
     * @param {String} key Hook/Event name.
     * @param {*} [p1] Parameter to be passed as an argument to the callback function.
     * @param {*} [p2] Parameter to be passed as an argument to the callback function.
     * @param {*} [p3] Parameter to be passed as an argument to the callback function.
     * @param {*} [p4] Parameter to be passed as an argument to the callback function.
     * @param {*} [p5] Parameter to be passed as an argument to the callback function.
     * @param {*} [p6] Parameter to be passed as an argument to the callback function.
     * @returns {*} Either a return value from the last called callback or `p1`.
     *
     * @example
     * ```js
     * Handsontable.hooks.run(hot, 'beforeInit');
     * ```
     */

  }, {
    key: "run",
    value: function run(context, key, p1, p2, p3, p4, p5, p6) {
      {
        var globalHandlers = this.globalBucket[key];
        var length = globalHandlers ? globalHandlers.length : 0;
        var index = 0;

        if (length) {
          // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
          while (index < length) {
            if (!globalHandlers[index] || globalHandlers[index].skip) {
              index += 1;
              /* eslint-disable no-continue */

              continue;
            } // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture


            var res = globalHandlers[index].call(context, p1, p2, p3, p4, p5, p6);

            if (res !== void 0) {
              // eslint-disable-next-line no-param-reassign
              p1 = res;
            }

            if (globalHandlers[index] && globalHandlers[index].runOnce) {
              this.remove(key, globalHandlers[index]);
            }

            index += 1;
          }
        }
      }
      {
        var localHandlers = this.getBucket(context)[key];

        var _length = localHandlers ? localHandlers.length : 0;

        var _index = 0;

        if (_length) {
          // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
          while (_index < _length) {
            if (!localHandlers[_index] || localHandlers[_index].skip) {
              _index += 1;
              /* eslint-disable no-continue */

              continue;
            } // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture


            var _res = localHandlers[_index].call(context, p1, p2, p3, p4, p5, p6);

            if (_res !== void 0) {
              // eslint-disable-next-line no-param-reassign
              p1 = _res;
            }

            if (localHandlers[_index] && localHandlers[_index].runOnce) {
              this.remove(key, localHandlers[_index], context);
            }

            _index += 1;
          }
        }
      }
      return p1;
    }
    /**
     * Destroy all listeners connected to the context. If no context is provided, the global listeners will be destroyed.
     *
     * @param {Object} [context=null] A Handsontable instance.
     * @example
     * ```js
     * // destroy the global listeners
     * Handsontable.hooks.destroy();
     *
     * // destroy the local listeners
     * Handsontable.hooks.destroy(hotInstance);
     * ```
     */

  }, {
    key: "destroy",
    value: function destroy() {
      var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      // eslint-disable-next-line no-return-assign
      (0, _object.objectEach)(this.getBucket(context), function (value, key, bucket) {
        return bucket[key].length = 0;
      });
    }
    /**
     * Registers a hook name (adds it to the list of the known hook names). Used by plugins.
     * It is not necessary to call register, but if you use it, your plugin hook will be used returned by
     * the `getRegistered` method. (which itself is used in the demo http://docs.handsontable.com/tutorial-callbacks.html).
     *
     * @param key {String} The hook name.
     *
     * @example
     * ```js
     * Handsontable.hooks.register('myHook');
     * ```
     */

  }, {
    key: "register",
    value: function register(key) {
      if (!this.isRegistered(key)) {
        REGISTERED_HOOKS.push(key);
      }
    }
    /**
     * Deregisters a hook name (removes it from the list of known hook names).
     *
     * @param key {String} Hook name.
     *
     * @example
     * ```js
     * Handsontable.hooks.deregister('myHook');
     * ```
     */

  }, {
    key: "deregister",
    value: function deregister(key) {
      if (this.isRegistered(key)) {
        REGISTERED_HOOKS.splice(REGISTERED_HOOKS.indexOf(key), 1);
      }
    }
    /**
     * Returns a boolean depending on if a hook by such name has been registered.
     *
     * @param key {String} Hook name.
     * @returns {Boolean} `true` for success, `false` otherwise.
     *
     * @example
     * ```js
     * Handsontable.hooks.isRegistered('beforeInit');
     *
     * // Results:
     * true
     * ```
     */

  }, {
    key: "isRegistered",
    value: function isRegistered(key) {
      return REGISTERED_HOOKS.indexOf(key) >= 0;
    }
    /**
     * Returns an array of registered hooks.
     *
     * @returns {Array} An array of registered hooks.
     *
     * @example
     * ```js
     * Handsontable.hooks.getRegistered();
     *
     * // Results:
     * [
     * ...
     *   'beforeInit',
     *   'beforeRender',
     *   'beforeSetRangeEnd',
     *   'beforeDrawBorders',
     *   'beforeChange',
     * ...
     * ]
     * ```
     */

  }, {
    key: "getRegistered",
    value: function getRegistered() {
      return REGISTERED_HOOKS;
    }
  }]);
  return Hooks;
}();

var globalSingleton = new Hooks();

function getGlobalSingleton() {
  return globalSingleton;
}

var _default = Hooks;
exports.default = _default;

/***/ }),
/* 44 */
/***/ (function(module, exports) {

function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }

function _typeof(obj) {
  if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
    module.exports = _typeof = function _typeof(obj) {
      return _typeof2(obj);
    };
  } else {
    module.exports = _typeof = function _typeof(obj) {
      return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
    };
  }

  return _typeof(obj);
}

module.exports = _typeof;

/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);

module.exports = function (it) {
  if (!isObject(it)) {
    throw TypeError(String(it) + ' is not an object');
  } return it;
};


/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var isRegExp = __webpack_require__(154);
var anObject = __webpack_require__(45);
var requireObjectCoercible = __webpack_require__(58);
var speciesConstructor = __webpack_require__(520);
var advanceStringIndex = __webpack_require__(155);
var toLength = __webpack_require__(48);
var callRegExpExec = __webpack_require__(128);
var regexpExec = __webpack_require__(156);
var fails = __webpack_require__(29);
var arrayPush = [].push;
var min = Math.min;
var MAX_UINT32 = 0xffffffff;

// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });

// @@split logic
__webpack_require__(129)(
  'split',
  2,
  function (SPLIT, nativeSplit, maybeCallNative) {
    var internalSplit;
    if (
      'abbc'.split(/(b)*/)[1] == 'c' ||
      'test'.split(/(?:)/, -1).length != 4 ||
      'ab'.split(/(?:ab)*/).length != 2 ||
      '.'.split(/(.?)(.?)/).length != 4 ||
      '.'.split(/()()/).length > 1 ||
      ''.split(/.?/).length
    ) {
      // based on es5-shim implementation, need to rework it
      internalSplit = function (separator, limit) {
        var string = String(requireObjectCoercible(this));
        var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
        if (lim === 0) return [];
        if (separator === undefined) return [string];
        // If `separator` is not a regex, use native split
        if (!isRegExp(separator)) {
          return nativeSplit.call(string, separator, lim);
        }
        var output = [];
        var flags = (separator.ignoreCase ? 'i' : '') +
                    (separator.multiline ? 'm' : '') +
                    (separator.unicode ? 'u' : '') +
                    (separator.sticky ? 'y' : '');
        var lastLastIndex = 0;
        // Make `global` and avoid `lastIndex` issues by working with a copy
        var separatorCopy = new RegExp(separator.source, flags + 'g');
        var match, lastIndex, lastLength;
        while (match = regexpExec.call(separatorCopy, string)) {
          lastIndex = separatorCopy.lastIndex;
          if (lastIndex > lastLastIndex) {
            output.push(string.slice(lastLastIndex, match.index));
            if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
            lastLength = match[0].length;
            lastLastIndex = lastIndex;
            if (output.length >= lim) break;
          }
          if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
        }
        if (lastLastIndex === string.length) {
          if (lastLength || !separatorCopy.test('')) output.push('');
        } else output.push(string.slice(lastLastIndex));
        return output.length > lim ? output.slice(0, lim) : output;
      };
    // Chakra, V8
    } else if ('0'.split(undefined, 0).length) {
      internalSplit = function (separator, limit) {
        return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
      };
    } else internalSplit = nativeSplit;

    return [
      // `String.prototype.split` method
      // https://tc39.github.io/ecma262/#sec-string.prototype.split
      function split(separator, limit) {
        var O = requireObjectCoercible(this);
        var splitter = separator == undefined ? undefined : separator[SPLIT];
        return splitter !== undefined
          ? splitter.call(separator, O, limit)
          : internalSplit.call(String(O), separator, limit);
      },
      // `RegExp.prototype[@@split]` method
      // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
      //
      // NOTE: This cannot be properly polyfilled in engines that don't support
      // the 'y' flag.
      function (regexp, limit) {
        var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
        if (res.done) return res.value;

        var rx = anObject(regexp);
        var S = String(this);
        var C = speciesConstructor(rx, RegExp);

        var unicodeMatching = rx.unicode;
        var flags = (rx.ignoreCase ? 'i' : '') +
                    (rx.multiline ? 'm' : '') +
                    (rx.unicode ? 'u' : '') +
                    (SUPPORTS_Y ? 'y' : 'g');

        // ^(? + rx + ) is needed, in combination with some S slicing, to
        // simulate the 'y' flag.
        var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
        var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
        if (lim === 0) return [];
        if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];
        var p = 0;
        var q = 0;
        var A = [];
        while (q < S.length) {
          splitter.lastIndex = SUPPORTS_Y ? q : 0;
          var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));
          var e;
          if (
            z === null ||
            (e = min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
          ) {
            q = advanceStringIndex(S, q, unicodeMatching);
          } else {
            A.push(S.slice(p, q));
            if (A.length === lim) return A;
            for (var i = 1; i <= z.length - 1; i++) {
              A.push(z[i]);
              if (A.length === lim) return A;
            }
            q = p = e;
          }
        }
        A.push(S.slice(p));
        return A;
      }
    ];
  },
  !SUPPORTS_Y
);


/***/ }),
/* 47 */
/***/ (function(module, exports) {

var hasOwnProperty = {}.hasOwnProperty;

module.exports = function (it, key) {
  return hasOwnProperty.call(it, key);
};


/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__(86);
var min = Math.min;

// `ToLength` abstract operation
// https://tc39.github.io/ecma262/#sec-tolength
module.exports = function (argument) {
  return argument > 0 ? min(toInteger(argument), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};


/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__(52);
var IE8_DOM_DEFINE = __webpack_require__(176);
var anObject = __webpack_require__(45);
var toPrimitive = __webpack_require__(97);
var nativeDefineProperty = Object.defineProperty;

exports.f = DESCRIPTORS ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
  anObject(O);
  P = toPrimitive(P, true);
  anObject(Attributes);
  if (IE8_DOM_DEFINE) try {
    return nativeDefineProperty(O, P, Attributes);
  } catch (e) { /* empty */ }
  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
  if ('value' in Attributes) O[P] = Attributes.value;
  return O;
};


/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(39);

__webpack_require__(46);

exports.__esModule = true;
exports.isPrintableChar = isPrintableChar;
exports.isMetaKey = isMetaKey;
exports.isCtrlKey = isCtrlKey;
exports.isCtrlMetaKey = isCtrlMetaKey;
exports.isKey = isKey;
exports.KEY_CODES = void 0;

var _array = __webpack_require__(3);

var KEY_CODES = {
  MOUSE_LEFT: 1,
  MOUSE_RIGHT: 3,
  MOUSE_MIDDLE: 2,
  BACKSPACE: 8,
  COMMA: 188,
  INSERT: 45,
  DELETE: 46,
  END: 35,
  ENTER: 13,
  ESCAPE: 27,
  CONTROL: 17,
  COMMAND_LEFT: 91,
  COMMAND_RIGHT: 93,
  COMMAND_FIREFOX: 224,
  ALT: 18,
  HOME: 36,
  PAGE_DOWN: 34,
  PAGE_UP: 33,
  PERIOD: 190,
  SPACE: 32,
  SHIFT: 16,
  CAPS_LOCK: 20,
  TAB: 9,
  ARROW_RIGHT: 39,
  ARROW_LEFT: 37,
  ARROW_UP: 38,
  ARROW_DOWN: 40,
  F1: 112,
  F2: 113,
  F3: 114,
  F4: 115,
  F5: 116,
  F6: 117,
  F7: 118,
  F8: 119,
  F9: 120,
  F10: 121,
  F11: 122,
  F12: 123,
  A: 65,
  C: 67,
  D: 68,
  F: 70,
  L: 76,
  O: 79,
  P: 80,
  S: 83,
  V: 86,
  X: 88
};
/**
 * Returns true if keyCode represents a printable character.
 *
 * @param {Number} keyCode
 * @returns {Boolean}
 */

exports.KEY_CODES = KEY_CODES;

function isPrintableChar(keyCode) {
  return keyCode === 32 || // space
  keyCode >= 48 && keyCode <= 57 || // 0-9
  keyCode >= 96 && keyCode <= 111 || // numpad
  keyCode >= 186 && keyCode <= 192 || // ;=,-./`
  keyCode >= 219 && keyCode <= 222 || // []{}\|"'
  keyCode >= 226 || // special chars (229 for Asian chars)
  keyCode >= 65 && keyCode <= 90; // a-z
}
/**
 * @param {Number} keyCode
 * @returns {Boolean}
 */


function isMetaKey(keyCode) {
  var metaKeys = [KEY_CODES.ARROW_DOWN, KEY_CODES.ARROW_UP, KEY_CODES.ARROW_LEFT, KEY_CODES.ARROW_RIGHT, KEY_CODES.HOME, KEY_CODES.END, KEY_CODES.DELETE, KEY_CODES.BACKSPACE, KEY_CODES.F1, KEY_CODES.F2, KEY_CODES.F3, KEY_CODES.F4, KEY_CODES.F5, KEY_CODES.F6, KEY_CODES.F7, KEY_CODES.F8, KEY_CODES.F9, KEY_CODES.F10, KEY_CODES.F11, KEY_CODES.F12, KEY_CODES.TAB, KEY_CODES.PAGE_DOWN, KEY_CODES.PAGE_UP, KEY_CODES.ENTER, KEY_CODES.ESCAPE, KEY_CODES.SHIFT, KEY_CODES.CAPS_LOCK, KEY_CODES.ALT];
  return metaKeys.indexOf(keyCode) !== -1;
}
/**
 * Checks if passed key code is ctrl or cmd key. Depends on what OS the code runs it check key code based on
 * different meta key codes.
 *
 * @param {Number} keyCode Key code to check.
 * @returns {Boolean}
 */


function isCtrlKey(keyCode) {
  var keys = [];

  if (navigator.platform.includes('Mac')) {
    keys.push(KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT, KEY_CODES.COMMAND_FIREFOX);
  } else {
    keys.push(KEY_CODES.CONTROL);
  }

  return keys.includes(keyCode);
}
/**
 * Checks if passed key code is ctrl or cmd key. This helper checks if the key code matches to meta keys
 * regardless of the OS on which it is running.
 *
 * @param {Number} keyCode Key code to check.
 * @returns {Boolean}
 */


function isCtrlMetaKey(keyCode) {
  return [KEY_CODES.CONTROL, KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT, KEY_CODES.COMMAND_FIREFOX].includes(keyCode);
}
/**
 * @param {Number} keyCode
 * @param {String} baseCode
 * @returns {Boolean}
 */


function isKey(keyCode, baseCode) {
  var keys = baseCode.split('|');
  var result = false;
  (0, _array.arrayEach)(keys, function (key) {
    if (keyCode === KEY_CODES[key]) {
      result = true;
      return false;
    }
  });
  return result;
}

/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__(52);
var defineProperty = __webpack_require__(49).f;
var FunctionPrototype = Function.prototype;
var FunctionPrototypeToString = FunctionPrototype.toString;
var nameRE = /^\s*function ([^ (]*)/;
var NAME = 'name';

// Function instances `.name` property
// https://tc39.github.io/ecma262/#sec-function-instances-name
if (DESCRIPTORS && !(NAME in FunctionPrototype)) {
  defineProperty(FunctionPrototype, NAME, {
    configurable: true,
    get: function () {
      try {
        return FunctionPrototypeToString.call(this).match(nameRE)[1];
      } catch (e) {
        return '';
      }
    }
  });
}


/***/ }),
/* 52 */
/***/ (function(module, exports, __webpack_require__) {

// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(29)(function () {
  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});


/***/ }),
/* 53 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.RegisteredEditor = RegisteredEditor;
exports.getEditorInstance = exports._getEditorInstance = _getEditorInstance;
exports.registerEditor = _register;
exports.getEditor = _getItem;
exports.getRegisteredEditors = exports.getRegisteredEditorNames = exports.hasEditor = void 0;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _baseEditor = _interopRequireDefault(__webpack_require__(104));

var _autocompleteEditor = _interopRequireDefault(__webpack_require__(337));

var _checkboxEditor = _interopRequireDefault(__webpack_require__(537));

var _dateEditor = _interopRequireDefault(__webpack_require__(538));

var _dropdownEditor = _interopRequireDefault(__webpack_require__(543));

var _handsontableEditor = _interopRequireDefault(__webpack_require__(338));

var _numericEditor = _interopRequireDefault(__webpack_require__(544));

var _passwordEditor = _interopRequireDefault(__webpack_require__(545));

var _selectEditor = _interopRequireDefault(__webpack_require__(546));

var _textEditor = _interopRequireDefault(__webpack_require__(107));

/**
 * Utility to register editors and common namespace for keeping reference to all editor classes
 */
var registeredEditorClasses = new WeakMap();

var _staticRegister = (0, _staticRegister2.default)('editors'),
    register = _staticRegister.register,
    getItem = _staticRegister.getItem,
    hasItem = _staticRegister.hasItem,
    getNames = _staticRegister.getNames,
    getValues = _staticRegister.getValues;

exports.getRegisteredEditors = getValues;
exports.getRegisteredEditorNames = getNames;
exports.hasEditor = hasItem;

_register('base', _baseEditor.default);

_register('autocomplete', _autocompleteEditor.default);

_register('checkbox', _checkboxEditor.default);

_register('date', _dateEditor.default);

_register('dropdown', _dropdownEditor.default);

_register('handsontable', _handsontableEditor.default);

_register('numeric', _numericEditor.default);

_register('password', _passwordEditor.default);

_register('select', _selectEditor.default);

_register('text', _textEditor.default);

function RegisteredEditor(editorClass) {
  var instances = {};
  var Clazz = editorClass;

  this.getConstructor = function () {
    return editorClass;
  };

  this.getInstance = function (hotInstance) {
    if (!(hotInstance.guid in instances)) {
      instances[hotInstance.guid] = new Clazz(hotInstance);
    }

    return instances[hotInstance.guid];
  };

  _pluginHooks.default.getSingleton().add('afterDestroy', function () {
    instances[this.guid] = null;
  });
}
/**
 * Returns instance (singleton) of editor class.
 *
 * @param {String} name Name of an editor under which it has been stored.
 * @param {Object} hotInstance Instance of Handsontable.
 * @returns {Function} Returns instance of editor.
 */


function _getEditorInstance(name, hotInstance) {
  var editor;

  if (typeof name === 'function') {
    if (!registeredEditorClasses.get(name)) {
      _register(null, name);
    }

    editor = registeredEditorClasses.get(name);
  } else if (typeof name === 'string') {
    editor = getItem(name);
  } else {
    throw Error('Only strings and functions can be passed as "editor" parameter');
  }

  if (!editor) {
    throw Error("No editor registered under name \"".concat(name, "\""));
  }

  return editor.getInstance(hotInstance);
}
/**
 * Retrieve editor class.
 *
 * @param {String} name Editor identification.
 * @returns {Function} Returns editor class.
 */


function _getItem(name) {
  if (!hasItem(name)) {
    throw Error("No registered editor found under \"".concat(name, "\" name"));
  }

  return getItem(name).getConstructor();
}
/**
 * Register editor class under specified name.
 *
 * @param {String} name Editor identification.
 * @param {Function} editorClass Editor class.
 */


function _register(name, editorClass) {
  var editorWrapper = new RegisteredEditor(editorClass);

  if (typeof name === 'string') {
    register(name, editorWrapper);
  }

  registeredEditorClasses.set(editorClass, editorWrapper);
}

/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toIndexedObject = __webpack_require__(69);
var nativeJoin = [].join;

var ES3_STRINGS = __webpack_require__(113) != Object;
var SLOPPY_METHOD = __webpack_require__(126)('join', ',');

// `Array.prototype.join` method
// https://tc39.github.io/ecma262/#sec-array.prototype.join
__webpack_require__(22)({ target: 'Array', proto: true, forced: ES3_STRINGS || SLOPPY_METHOD }, {
  join: function join(separator) {
    return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
  }
});


/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.log = log;
exports.warn = warn;
exports.info = info;
exports.error = error;

var _mixed = __webpack_require__(27);

/* eslint-disable no-console */

/* eslint-disable no-restricted-globals */

/**
 * "In Internet Explorer 9 (and 8), the console object is only exposed when the developer tools are opened
 * for a particular tab."
 *
 * Source: https://stackoverflow.com/a/5473193
 */

/**
 * Logs message to the console if the `console` object is exposed.
 *
 * @param {...*} args Values which will be logged.
 */
function log() {
  if ((0, _mixed.isDefined)(console)) {
    var _console;

    (_console = console).log.apply(_console, arguments);
  }
}
/**
 * Logs warn to the console if the `console` object is exposed.
 *
 * @param {...*} args Values which will be logged.
 */


function warn() {
  if ((0, _mixed.isDefined)(console)) {
    var _console2;

    (_console2 = console).warn.apply(_console2, arguments);
  }
}
/**
 * Logs info to the console if the `console` object is exposed.
 *
 * @param {...*} args Values which will be logged.
 */


function info() {
  if ((0, _mixed.isDefined)(console)) {
    var _console3;

    (_console3 = console).info.apply(_console3, arguments);
  }
}
/**
 * Logs error to the console if the `console` object is exposed.
 *
 * @param {...*} args Values which will be logged.
 */


function error() {
  if ((0, _mixed.isDefined)(console)) {
    var _console4;

    (_console4 = console).error.apply(_console4, arguments);
  }
}

/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalFilter = __webpack_require__(102)(2);

var SPECIES_SUPPORT = __webpack_require__(103)('filter');

// `Array.prototype.filter` method
// https://tc39.github.io/ecma262/#sec-array.prototype.filter
// with adding support of @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
  filter: function filter(callbackfn /* , thisArg */) {
    return internalFilter(this, callbackfn, arguments[1]);
  }
});


/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var MIXIN_NAME = 'localHooks';
/**
 * Mixin object to extend objects functionality for local hooks.
 *
 * @type {Object}
 */

var localHooks = {
  /**
   * Internal hooks storage.
   */
  _localHooks: Object.create(null),

  /**
   * Add hook to the collection.
   *
   * @param {String} key Hook name.
   * @param {Function} callback Hook callback
   * @returns {Object}
   */
  addLocalHook: function addLocalHook(key, callback) {
    if (!this._localHooks[key]) {
      this._localHooks[key] = [];
    }

    this._localHooks[key].push(callback);

    return this;
  },

  /**
   * Run hooks.
   *
   * @param {String} key Hook name.
   * @param {*} params
   */
  runLocalHooks: function runLocalHooks(key) {
    var _this = this;

    for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      params[_key - 1] = arguments[_key];
    }

    if (this._localHooks[key]) {
      (0, _array.arrayEach)(this._localHooks[key], function (callback) {
        return callback.apply(_this, params);
      });
    }
  },

  /**
   * Clear all added hooks.
   *
   * @returns {Object}
   */
  clearLocalHooks: function clearLocalHooks() {
    this._localHooks = {};
    return this;
  }
};
(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, {
  writable: false,
  enumerable: false
});
var _default = localHooks;
exports.default = _default;

/***/ }),
/* 58 */
/***/ (function(module, exports) {

// `RequireObjectCoercible` abstract operation
// https://tc39.github.io/ecma262/#sec-requireobjectcoercible
module.exports = function (it) {
  if (it == undefined) throw TypeError("Can't call method on " + it);
  return it;
};


/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {

var INCORRECT_ITERATION = !__webpack_require__(190)(function (iterable) {
  Array.from(iterable);
});

// `Array.from` method
// https://tc39.github.io/ecma262/#sec-array.from
__webpack_require__(22)({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, {
  from: __webpack_require__(519)
});


/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(12);

__webpack_require__(40);

__webpack_require__(51);

__webpack_require__(37);

exports.__esModule = true;
exports.normalizeSelection = normalizeSelection;
exports.isSeparator = isSeparator;
exports.hasSubMenu = hasSubMenu;
exports.isDisabled = isDisabled;
exports.isSelectionDisabled = isSelectionDisabled;
exports.getValidSelection = getValidSelection;
exports.prepareVerticalAlignClass = prepareVerticalAlignClass;
exports.prepareHorizontalAlignClass = prepareHorizontalAlignClass;
exports.getAlignmentClasses = getAlignmentClasses;
exports.align = align;
exports.checkSelectionConsistency = checkSelectionConsistency;
exports.markLabelAsSelected = markLabelAsSelected;
exports.isItemHidden = isItemHidden;
exports.filterSeparators = filterSeparators;

var _array = __webpack_require__(3);

var _element = __webpack_require__(5);

var _separator = __webpack_require__(166);

function normalizeSelection(selRanges) {
  return (0, _array.arrayMap)(selRanges, function (range) {
    return {
      start: range.getTopLeftCorner(),
      end: range.getBottomRightCorner()
    };
  });
}

function isSeparator(cell) {
  return (0, _element.hasClass)(cell, 'htSeparator');
}

function hasSubMenu(cell) {
  return (0, _element.hasClass)(cell, 'htSubmenu');
}

function isDisabled(cell) {
  return (0, _element.hasClass)(cell, 'htDisabled');
}

function isSelectionDisabled(cell) {
  return (0, _element.hasClass)(cell, 'htSelectionDisabled');
}

function getValidSelection(hot) {
  var selected = hot.getSelected();

  if (!selected) {
    return null;
  }

  if (selected[0] < 0) {
    return null;
  }

  return selected;
}

function prepareVerticalAlignClass(className, alignment) {
  if (className.indexOf(alignment) !== -1) {
    return className;
  }

  var replacedClassName = className.replace('htTop', '').replace('htMiddle', '').replace('htBottom', '').replace('  ', '');
  return "".concat(replacedClassName, " ").concat(alignment);
}

function prepareHorizontalAlignClass(className, alignment) {
  if (className.indexOf(alignment) !== -1) {
    return className;
  }

  var replacedClassName = className.replace('htLeft', '').replace('htCenter', '').replace('htRight', '').replace('htJustify', '').replace('  ', '');
  return "".concat(replacedClassName, " ").concat(alignment);
}

function getAlignmentClasses(ranges, callback) {
  var classes = {};
  (0, _array.arrayEach)(ranges, function (_ref) {
    var from = _ref.from,
        to = _ref.to;

    for (var row = from.row; row <= to.row; row++) {
      for (var col = from.col; col <= to.col; col++) {
        if (!classes[row]) {
          classes[row] = [];
        }

        classes[row][col] = callback(row, col);
      }
    }
  });
  return classes;
}

function align(ranges, type, alignment, cellDescriptor, propertySetter) {
  (0, _array.arrayEach)(ranges, function (_ref2) {
    var from = _ref2.from,
        to = _ref2.to;

    if (from.row === to.row && from.col === to.col) {
      applyAlignClassName(from.row, from.col, type, alignment, cellDescriptor, propertySetter);
    } else {
      for (var row = from.row; row <= to.row; row++) {
        for (var col = from.col; col <= to.col; col++) {
          applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter);
        }
      }
    }
  });
}

function applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter) {
  var cellMeta = cellDescriptor(row, col);
  var className = alignment;

  if (cellMeta.className) {
    if (type === 'vertical') {
      className = prepareVerticalAlignClass(cellMeta.className, alignment);
    } else {
      className = prepareHorizontalAlignClass(cellMeta.className, alignment);
    }
  }

  propertySetter(row, col, 'className', className);
}

function checkSelectionConsistency(ranges, comparator) {
  var result = false;

  if (Array.isArray(ranges)) {
    (0, _array.arrayEach)(ranges, function (range) {
      range.forAll(function (row, col) {
        if (comparator(row, col)) {
          result = true;
          return false;
        }
      });
      return result;
    });
  }

  return result;
}

function markLabelAsSelected(label) {
  // workaround for https://github.com/handsontable/handsontable/issues/1946
  return "<span class=\"selected\">".concat(String.fromCharCode(10003), "</span>").concat(label);
}

function isItemHidden(item, instance) {
  return !item.hidden || !(typeof item.hidden === 'function' && item.hidden.call(instance));
}

function shiftSeparators(items, separator) {
  var result = items.slice(0);

  for (var i = 0; i < result.length;) {
    if (result[i].name === separator) {
      result.shift();
    } else {
      break;
    }
  }

  return result;
}

function popSeparators(items, separator) {
  var result = items.slice(0);
  result.reverse();
  result = shiftSeparators(result, separator);
  result.reverse();
  return result;
}

function removeDuplicatedSeparators(items) {
  var result = [];
  (0, _array.arrayEach)(items, function (value, index) {
    if (index > 0) {
      if (result[result.length - 1].name !== value.name) {
        result.push(value);
      }
    } else {
      result.push(value);
    }
  });
  return result;
}

function filterSeparators(items) {
  var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _separator.KEY;
  var result = items.slice(0);
  result = shiftSeparators(result, separator);
  result = popSeparators(result, separator);
  result = removeDuplicatedSeparators(result);
  return result;
}

/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {

var definePropertyModule = __webpack_require__(49);
var createPropertyDescriptor = __webpack_require__(96);

module.exports = __webpack_require__(52) ? function (object, key, value) {
  return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
  object[key] = value;
  return object;
};


/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {

var requireObjectCoercible = __webpack_require__(58);

// `ToObject` abstract operation
// https://tc39.github.io/ecma262/#sec-toobject
module.exports = function (argument) {
  return Object(requireObjectCoercible(argument));
};


/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js
//! version : 2.20.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

;(function (global, factory) {
     true ? module.exports = factory() :
    undefined
}(this, (function () { 'use strict';

var hookCallback;

function hooks () {
    return hookCallback.apply(null, arguments);
}

// This is done to register the method called with moment()
// without creating circular dependencies.
function setHookCallback (callback) {
    hookCallback = callback;
}

function isArray(input) {
    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
}

function isObject(input) {
    // IE8 will treat undefined and null as object if it wasn't for
    // input != null
    return input != null && Object.prototype.toString.call(input) === '[object Object]';
}

function isObjectEmpty(obj) {
    if (Object.getOwnPropertyNames) {
        return (Object.getOwnPropertyNames(obj).length === 0);
    } else {
        var k;
        for (k in obj) {
            if (obj.hasOwnProperty(k)) {
                return false;
            }
        }
        return true;
    }
}

function isUndefined(input) {
    return input === void 0;
}

function isNumber(input) {
    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
}

function isDate(input) {
    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
}

function map(arr, fn) {
    var res = [], i;
    for (i = 0; i < arr.length; ++i) {
        res.push(fn(arr[i], i));
    }
    return res;
}

function hasOwnProp(a, b) {
    return Object.prototype.hasOwnProperty.call(a, b);
}

function extend(a, b) {
    for (var i in b) {
        if (hasOwnProp(b, i)) {
            a[i] = b[i];
        }
    }

    if (hasOwnProp(b, 'toString')) {
        a.toString = b.toString;
    }

    if (hasOwnProp(b, 'valueOf')) {
        a.valueOf = b.valueOf;
    }

    return a;
}

function createUTC (input, format, locale, strict) {
    return createLocalOrUTC(input, format, locale, strict, true).utc();
}

function defaultParsingFlags() {
    // We need to deep clone this object.
    return {
        empty           : false,
        unusedTokens    : [],
        unusedInput     : [],
        overflow        : -2,
        charsLeftOver   : 0,
        nullInput       : false,
        invalidMonth    : null,
        invalidFormat   : false,
        userInvalidated : false,
        iso             : false,
        parsedDateParts : [],
        meridiem        : null,
        rfc2822         : false,
        weekdayMismatch : false
    };
}

function getParsingFlags(m) {
    if (m._pf == null) {
        m._pf = defaultParsingFlags();
    }
    return m._pf;
}

var some;
if (Array.prototype.some) {
    some = Array.prototype.some;
} else {
    some = function (fun) {
        var t = Object(this);
        var len = t.length >>> 0;

        for (var i = 0; i < len; i++) {
            if (i in t && fun.call(this, t[i], i, t)) {
                return true;
            }
        }

        return false;
    };
}

function isValid(m) {
    if (m._isValid == null) {
        var flags = getParsingFlags(m);
        var parsedParts = some.call(flags.parsedDateParts, function (i) {
            return i != null;
        });
        var isNowValid = !isNaN(m._d.getTime()) &&
            flags.overflow < 0 &&
            !flags.empty &&
            !flags.invalidMonth &&
            !flags.invalidWeekday &&
            !flags.weekdayMismatch &&
            !flags.nullInput &&
            !flags.invalidFormat &&
            !flags.userInvalidated &&
            (!flags.meridiem || (flags.meridiem && parsedParts));

        if (m._strict) {
            isNowValid = isNowValid &&
                flags.charsLeftOver === 0 &&
                flags.unusedTokens.length === 0 &&
                flags.bigHour === undefined;
        }

        if (Object.isFrozen == null || !Object.isFrozen(m)) {
            m._isValid = isNowValid;
        }
        else {
            return isNowValid;
        }
    }
    return m._isValid;
}

function createInvalid (flags) {
    var m = createUTC(NaN);
    if (flags != null) {
        extend(getParsingFlags(m), flags);
    }
    else {
        getParsingFlags(m).userInvalidated = true;
    }

    return m;
}

// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
var momentProperties = hooks.momentProperties = [];

function copyConfig(to, from) {
    var i, prop, val;

    if (!isUndefined(from._isAMomentObject)) {
        to._isAMomentObject = from._isAMomentObject;
    }
    if (!isUndefined(from._i)) {
        to._i = from._i;
    }
    if (!isUndefined(from._f)) {
        to._f = from._f;
    }
    if (!isUndefined(from._l)) {
        to._l = from._l;
    }
    if (!isUndefined(from._strict)) {
        to._strict = from._strict;
    }
    if (!isUndefined(from._tzm)) {
        to._tzm = from._tzm;
    }
    if (!isUndefined(from._isUTC)) {
        to._isUTC = from._isUTC;
    }
    if (!isUndefined(from._offset)) {
        to._offset = from._offset;
    }
    if (!isUndefined(from._pf)) {
        to._pf = getParsingFlags(from);
    }
    if (!isUndefined(from._locale)) {
        to._locale = from._locale;
    }

    if (momentProperties.length > 0) {
        for (i = 0; i < momentProperties.length; i++) {
            prop = momentProperties[i];
            val = from[prop];
            if (!isUndefined(val)) {
                to[prop] = val;
            }
        }
    }

    return to;
}

var updateInProgress = false;

// Moment prototype object
function Moment(config) {
    copyConfig(this, config);
    this._d = new Date(config._d != null ? config._d.getTime() : NaN);
    if (!this.isValid()) {
        this._d = new Date(NaN);
    }
    // Prevent infinite loop in case updateOffset creates new moment
    // objects.
    if (updateInProgress === false) {
        updateInProgress = true;
        hooks.updateOffset(this);
        updateInProgress = false;
    }
}

function isMoment (obj) {
    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
}

function absFloor (number) {
    if (number < 0) {
        // -0 -> 0
        return Math.ceil(number) || 0;
    } else {
        return Math.floor(number);
    }
}

function toInt(argumentForCoercion) {
    var coercedNumber = +argumentForCoercion,
        value = 0;

    if (coercedNumber !== 0 && isFinite(coercedNumber)) {
        value = absFloor(coercedNumber);
    }

    return value;
}

// compare two arrays, return the number of differences
function compareArrays(array1, array2, dontConvert) {
    var len = Math.min(array1.length, array2.length),
        lengthDiff = Math.abs(array1.length - array2.length),
        diffs = 0,
        i;
    for (i = 0; i < len; i++) {
        if ((dontConvert && array1[i] !== array2[i]) ||
            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
            diffs++;
        }
    }
    return diffs + lengthDiff;
}

function warn(msg) {
    if (hooks.suppressDeprecationWarnings === false &&
            (typeof console !==  'undefined') && console.warn) {
        console.warn('Deprecation warning: ' + msg);
    }
}

function deprecate(msg, fn) {
    var firstTime = true;

    return extend(function () {
        if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(null, msg);
        }
        if (firstTime) {
            var args = [];
            var arg;
            for (var i = 0; i < arguments.length; i++) {
                arg = '';
                if (typeof arguments[i] === 'object') {
                    arg += '\n[' + i + '] ';
                    for (var key in arguments[0]) {
                        arg += key + ': ' + arguments[0][key] + ', ';
                    }
                    arg = arg.slice(0, -2); // Remove trailing comma and space
                } else {
                    arg = arguments[i];
                }
                args.push(arg);
            }
            warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
            firstTime = false;
        }
        return fn.apply(this, arguments);
    }, fn);
}

var deprecations = {};

function deprecateSimple(name, msg) {
    if (hooks.deprecationHandler != null) {
        hooks.deprecationHandler(name, msg);
    }
    if (!deprecations[name]) {
        warn(msg);
        deprecations[name] = true;
    }
}

hooks.suppressDeprecationWarnings = false;
hooks.deprecationHandler = null;

function isFunction(input) {
    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
}

function set (config) {
    var prop, i;
    for (i in config) {
        prop = config[i];
        if (isFunction(prop)) {
            this[i] = prop;
        } else {
            this['_' + i] = prop;
        }
    }
    this._config = config;
    // Lenient ordinal parsing accepts just a number in addition to
    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
    // TODO: Remove "ordinalParse" fallback in next major release.
    this._dayOfMonthOrdinalParseLenient = new RegExp(
        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
            '|' + (/\d{1,2}/).source);
}

function mergeConfigs(parentConfig, childConfig) {
    var res = extend({}, parentConfig), prop;
    for (prop in childConfig) {
        if (hasOwnProp(childConfig, prop)) {
            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                res[prop] = {};
                extend(res[prop], parentConfig[prop]);
                extend(res[prop], childConfig[prop]);
            } else if (childConfig[prop] != null) {
                res[prop] = childConfig[prop];
            } else {
                delete res[prop];
            }
        }
    }
    for (prop in parentConfig) {
        if (hasOwnProp(parentConfig, prop) &&
                !hasOwnProp(childConfig, prop) &&
                isObject(parentConfig[prop])) {
            // make sure changes to properties don't modify parent config
            res[prop] = extend({}, res[prop]);
        }
    }
    return res;
}

function Locale(config) {
    if (config != null) {
        this.set(config);
    }
}

var keys;

if (Object.keys) {
    keys = Object.keys;
} else {
    keys = function (obj) {
        var i, res = [];
        for (i in obj) {
            if (hasOwnProp(obj, i)) {
                res.push(i);
            }
        }
        return res;
    };
}

var defaultCalendar = {
    sameDay : '[Today at] LT',
    nextDay : '[Tomorrow at] LT',
    nextWeek : 'dddd [at] LT',
    lastDay : '[Yesterday at] LT',
    lastWeek : '[Last] dddd [at] LT',
    sameElse : 'L'
};

function calendar (key, mom, now) {
    var output = this._calendar[key] || this._calendar['sameElse'];
    return isFunction(output) ? output.call(mom, now) : output;
}

var defaultLongDateFormat = {
    LTS  : 'h:mm:ss A',
    LT   : 'h:mm A',
    L    : 'MM/DD/YYYY',
    LL   : 'MMMM D, YYYY',
    LLL  : 'MMMM D, YYYY h:mm A',
    LLLL : 'dddd, MMMM D, YYYY h:mm A'
};

function longDateFormat (key) {
    var format = this._longDateFormat[key],
        formatUpper = this._longDateFormat[key.toUpperCase()];

    if (format || !formatUpper) {
        return format;
    }

    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
        return val.slice(1);
    });

    return this._longDateFormat[key];
}

var defaultInvalidDate = 'Invalid date';

function invalidDate () {
    return this._invalidDate;
}

var defaultOrdinal = '%d';
var defaultDayOfMonthOrdinalParse = /\d{1,2}/;

function ordinal (number) {
    return this._ordinal.replace('%d', number);
}

var defaultRelativeTime = {
    future : 'in %s',
    past   : '%s ago',
    s  : 'a few seconds',
    ss : '%d seconds',
    m  : 'a minute',
    mm : '%d minutes',
    h  : 'an hour',
    hh : '%d hours',
    d  : 'a day',
    dd : '%d days',
    M  : 'a month',
    MM : '%d months',
    y  : 'a year',
    yy : '%d years'
};

function relativeTime (number, withoutSuffix, string, isFuture) {
    var output = this._relativeTime[string];
    return (isFunction(output)) ?
        output(number, withoutSuffix, string, isFuture) :
        output.replace(/%d/i, number);
}

function pastFuture (diff, output) {
    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
    return isFunction(format) ? format(output) : format.replace(/%s/i, output);
}

var aliases = {};

function addUnitAlias (unit, shorthand) {
    var lowerCase = unit.toLowerCase();
    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
}

function normalizeUnits(units) {
    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
}

function normalizeObjectUnits(inputObject) {
    var normalizedInput = {},
        normalizedProp,
        prop;

    for (prop in inputObject) {
        if (hasOwnProp(inputObject, prop)) {
            normalizedProp = normalizeUnits(prop);
            if (normalizedProp) {
                normalizedInput[normalizedProp] = inputObject[prop];
            }
        }
    }

    return normalizedInput;
}

var priorities = {};

function addUnitPriority(unit, priority) {
    priorities[unit] = priority;
}

function getPrioritizedUnits(unitsObj) {
    var units = [];
    for (var u in unitsObj) {
        units.push({unit: u, priority: priorities[u]});
    }
    units.sort(function (a, b) {
        return a.priority - b.priority;
    });
    return units;
}

function zeroFill(number, targetLength, forceSign) {
    var absNumber = '' + Math.abs(number),
        zerosToFill = targetLength - absNumber.length,
        sign = number >= 0;
    return (sign ? (forceSign ? '+' : '') : '-') +
        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}

var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

var formatFunctions = {};

var formatTokenFunctions = {};

// token:    'M'
// padded:   ['MM', 2]
// ordinal:  'Mo'
// callback: function () { this.month() + 1 }
function addFormatToken (token, padded, ordinal, callback) {
    var func = callback;
    if (typeof callback === 'string') {
        func = function () {
            return this[callback]();
        };
    }
    if (token) {
        formatTokenFunctions[token] = func;
    }
    if (padded) {
        formatTokenFunctions[padded[0]] = function () {
            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
        };
    }
    if (ordinal) {
        formatTokenFunctions[ordinal] = function () {
            return this.localeData().ordinal(func.apply(this, arguments), token);
        };
    }
}

function removeFormattingTokens(input) {
    if (input.match(/\[[\s\S]/)) {
        return input.replace(/^\[|\]$/g, '');
    }
    return input.replace(/\\/g, '');
}

function makeFormatFunction(format) {
    var array = format.match(formattingTokens), i, length;

    for (i = 0, length = array.length; i < length; i++) {
        if (formatTokenFunctions[array[i]]) {
            array[i] = formatTokenFunctions[array[i]];
        } else {
            array[i] = removeFormattingTokens(array[i]);
        }
    }

    return function (mom) {
        var output = '', i;
        for (i = 0; i < length; i++) {
            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
        }
        return output;
    };
}

// format date using native date object
function formatMoment(m, format) {
    if (!m.isValid()) {
        return m.localeData().invalidDate();
    }

    format = expandFormat(format, m.localeData());
    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

    return formatFunctions[format](m);
}

function expandFormat(format, locale) {
    var i = 5;

    function replaceLongDateFormatTokens(input) {
        return locale.longDateFormat(input) || input;
    }

    localFormattingTokens.lastIndex = 0;
    while (i >= 0 && localFormattingTokens.test(format)) {
        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
        localFormattingTokens.lastIndex = 0;
        i -= 1;
    }

    return format;
}

var match1         = /\d/;            //       0 - 9
var match2         = /\d\d/;          //      00 - 99
var match3         = /\d{3}/;         //     000 - 999
var match4         = /\d{4}/;         //    0000 - 9999
var match6         = /[+-]?\d{6}/;    // -999999 - 999999
var match1to2      = /\d\d?/;         //       0 - 99
var match3to4      = /\d\d\d\d?/;     //     999 - 9999
var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
var match1to3      = /\d{1,3}/;       //       0 - 999
var match1to4      = /\d{1,4}/;       //       0 - 9999
var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999

var matchUnsigned  = /\d+/;           //       0 - inf
var matchSigned    = /[+-]?\d+/;      //    -inf - inf

var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

// any word (or two) characters or numbers including two/three word month in arabic.
// includes scottish gaelic two word and hyphenated months
var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;


var regexes = {};

function addRegexToken (token, regex, strictRegex) {
    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
        return (isStrict && strictRegex) ? strictRegex : regex;
    };
}

function getParseRegexForToken (token, config) {
    if (!hasOwnProp(regexes, token)) {
        return new RegExp(unescapeFormat(token));
    }

    return regexes[token](config._strict, config._locale);
}

// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function unescapeFormat(s) {
    return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
        return p1 || p2 || p3 || p4;
    }));
}

function regexEscape(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

var tokens = {};

function addParseToken (token, callback) {
    var i, func = callback;
    if (typeof token === 'string') {
        token = [token];
    }
    if (isNumber(callback)) {
        func = function (input, array) {
            array[callback] = toInt(input);
        };
    }
    for (i = 0; i < token.length; i++) {
        tokens[token[i]] = func;
    }
}

function addWeekParseToken (token, callback) {
    addParseToken(token, function (input, array, config, token) {
        config._w = config._w || {};
        callback(input, config._w, config, token);
    });
}

function addTimeToArrayFromToken(token, input, config) {
    if (input != null && hasOwnProp(tokens, token)) {
        tokens[token](input, config._a, config, token);
    }
}

var YEAR = 0;
var MONTH = 1;
var DATE = 2;
var HOUR = 3;
var MINUTE = 4;
var SECOND = 5;
var MILLISECOND = 6;
var WEEK = 7;
var WEEKDAY = 8;

// FORMATTING

addFormatToken('Y', 0, 0, function () {
    var y = this.year();
    return y <= 9999 ? '' + y : '+' + y;
});

addFormatToken(0, ['YY', 2], 0, function () {
    return this.year() % 100;
});

addFormatToken(0, ['YYYY',   4],       0, 'year');
addFormatToken(0, ['YYYYY',  5],       0, 'year');
addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

// ALIASES

addUnitAlias('year', 'y');

// PRIORITIES

addUnitPriority('year', 1);

// PARSING

addRegexToken('Y',      matchSigned);
addRegexToken('YY',     match1to2, match2);
addRegexToken('YYYY',   match1to4, match4);
addRegexToken('YYYYY',  match1to6, match6);
addRegexToken('YYYYYY', match1to6, match6);

addParseToken(['YYYYY', 'YYYYYY'], YEAR);
addParseToken('YYYY', function (input, array) {
    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
});
addParseToken('YY', function (input, array) {
    array[YEAR] = hooks.parseTwoDigitYear(input);
});
addParseToken('Y', function (input, array) {
    array[YEAR] = parseInt(input, 10);
});

// HELPERS

function daysInYear(year) {
    return isLeapYear(year) ? 366 : 365;
}

function isLeapYear(year) {
    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}

// HOOKS

hooks.parseTwoDigitYear = function (input) {
    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
};

// MOMENTS

var getSetYear = makeGetSet('FullYear', true);

function getIsLeapYear () {
    return isLeapYear(this.year());
}

function makeGetSet (unit, keepTime) {
    return function (value) {
        if (value != null) {
            set$1(this, unit, value);
            hooks.updateOffset(this, keepTime);
            return this;
        } else {
            return get(this, unit);
        }
    };
}

function get (mom, unit) {
    return mom.isValid() ?
        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
}

function set$1 (mom, unit, value) {
    if (mom.isValid() && !isNaN(value)) {
        if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
        }
        else {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
        }
    }
}

// MOMENTS

function stringGet (units) {
    units = normalizeUnits(units);
    if (isFunction(this[units])) {
        return this[units]();
    }
    return this;
}


function stringSet (units, value) {
    if (typeof units === 'object') {
        units = normalizeObjectUnits(units);
        var prioritized = getPrioritizedUnits(units);
        for (var i = 0; i < prioritized.length; i++) {
            this[prioritized[i].unit](units[prioritized[i].unit]);
        }
    } else {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units](value);
        }
    }
    return this;
}

function mod(n, x) {
    return ((n % x) + x) % x;
}

var indexOf;

if (Array.prototype.indexOf) {
    indexOf = Array.prototype.indexOf;
} else {
    indexOf = function (o) {
        // I know
        var i;
        for (i = 0; i < this.length; ++i) {
            if (this[i] === o) {
                return i;
            }
        }
        return -1;
    };
}

function daysInMonth(year, month) {
    if (isNaN(year) || isNaN(month)) {
        return NaN;
    }
    var modMonth = mod(month, 12);
    year += (month - modMonth) / 12;
    return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
}

// FORMATTING

addFormatToken('M', ['MM', 2], 'Mo', function () {
    return this.month() + 1;
});

addFormatToken('MMM', 0, 0, function (format) {
    return this.localeData().monthsShort(this, format);
});

addFormatToken('MMMM', 0, 0, function (format) {
    return this.localeData().months(this, format);
});

// ALIASES

addUnitAlias('month', 'M');

// PRIORITY

addUnitPriority('month', 8);

// PARSING

addRegexToken('M',    match1to2);
addRegexToken('MM',   match1to2, match2);
addRegexToken('MMM',  function (isStrict, locale) {
    return locale.monthsShortRegex(isStrict);
});
addRegexToken('MMMM', function (isStrict, locale) {
    return locale.monthsRegex(isStrict);
});

addParseToken(['M', 'MM'], function (input, array) {
    array[MONTH] = toInt(input) - 1;
});

addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
    var month = config._locale.monthsParse(input, token, config._strict);
    // if we didn't find a month name, mark the date as invalid.
    if (month != null) {
        array[MONTH] = month;
    } else {
        getParsingFlags(config).invalidMonth = input;
    }
});

// LOCALES

var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
function localeMonths (m, format) {
    if (!m) {
        return isArray(this._months) ? this._months :
            this._months['standalone'];
    }
    return isArray(this._months) ? this._months[m.month()] :
        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
}

var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
function localeMonthsShort (m, format) {
    if (!m) {
        return isArray(this._monthsShort) ? this._monthsShort :
            this._monthsShort['standalone'];
    }
    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}

function handleStrictParse(monthName, format, strict) {
    var i, ii, mom, llc = monthName.toLocaleLowerCase();
    if (!this._monthsParse) {
        // this is not used
        this._monthsParse = [];
        this._longMonthsParse = [];
        this._shortMonthsParse = [];
        for (i = 0; i < 12; ++i) {
            mom = createUTC([2000, i]);
            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
        }
    }

    if (strict) {
        if (format === 'MMM') {
            ii = indexOf.call(this._shortMonthsParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._longMonthsParse, llc);
            return ii !== -1 ? ii : null;
        }
    } else {
        if (format === 'MMM') {
            ii = indexOf.call(this._shortMonthsParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._longMonthsParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._longMonthsParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortMonthsParse, llc);
            return ii !== -1 ? ii : null;
        }
    }
}

function localeMonthsParse (monthName, format, strict) {
    var i, mom, regex;

    if (this._monthsParseExact) {
        return handleStrictParse.call(this, monthName, format, strict);
    }

    if (!this._monthsParse) {
        this._monthsParse = [];
        this._longMonthsParse = [];
        this._shortMonthsParse = [];
    }

    // TODO: add sorting
    // Sorting makes sure if one month (or abbr) is a prefix of another
    // see sorting in computeMonthsParse
    for (i = 0; i < 12; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, i]);
        if (strict && !this._longMonthsParse[i]) {
            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
        }
        if (!strict && !this._monthsParse[i]) {
            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
        }
        // test the regex
        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
            return i;
        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
            return i;
        } else if (!strict && this._monthsParse[i].test(monthName)) {
            return i;
        }
    }
}

// MOMENTS

function setMonth (mom, value) {
    var dayOfMonth;

    if (!mom.isValid()) {
        // No op
        return mom;
    }

    if (typeof value === 'string') {
        if (/^\d+$/.test(value)) {
            value = toInt(value);
        } else {
            value = mom.localeData().monthsParse(value);
            // TODO: Another silent failure?
            if (!isNumber(value)) {
                return mom;
            }
        }
    }

    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
    return mom;
}

function getSetMonth (value) {
    if (value != null) {
        setMonth(this, value);
        hooks.updateOffset(this, true);
        return this;
    } else {
        return get(this, 'Month');
    }
}

function getDaysInMonth () {
    return daysInMonth(this.year(), this.month());
}

var defaultMonthsShortRegex = matchWord;
function monthsShortRegex (isStrict) {
    if (this._monthsParseExact) {
        if (!hasOwnProp(this, '_monthsRegex')) {
            computeMonthsParse.call(this);
        }
        if (isStrict) {
            return this._monthsShortStrictRegex;
        } else {
            return this._monthsShortRegex;
        }
    } else {
        if (!hasOwnProp(this, '_monthsShortRegex')) {
            this._monthsShortRegex = defaultMonthsShortRegex;
        }
        return this._monthsShortStrictRegex && isStrict ?
            this._monthsShortStrictRegex : this._monthsShortRegex;
    }
}

var defaultMonthsRegex = matchWord;
function monthsRegex (isStrict) {
    if (this._monthsParseExact) {
        if (!hasOwnProp(this, '_monthsRegex')) {
            computeMonthsParse.call(this);
        }
        if (isStrict) {
            return this._monthsStrictRegex;
        } else {
            return this._monthsRegex;
        }
    } else {
        if (!hasOwnProp(this, '_monthsRegex')) {
            this._monthsRegex = defaultMonthsRegex;
        }
        return this._monthsStrictRegex && isStrict ?
            this._monthsStrictRegex : this._monthsRegex;
    }
}

function computeMonthsParse () {
    function cmpLenRev(a, b) {
        return b.length - a.length;
    }

    var shortPieces = [], longPieces = [], mixedPieces = [],
        i, mom;
    for (i = 0; i < 12; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, i]);
        shortPieces.push(this.monthsShort(mom, ''));
        longPieces.push(this.months(mom, ''));
        mixedPieces.push(this.months(mom, ''));
        mixedPieces.push(this.monthsShort(mom, ''));
    }
    // Sorting makes sure if one month (or abbr) is a prefix of another it
    // will match the longer piece.
    shortPieces.sort(cmpLenRev);
    longPieces.sort(cmpLenRev);
    mixedPieces.sort(cmpLenRev);
    for (i = 0; i < 12; i++) {
        shortPieces[i] = regexEscape(shortPieces[i]);
        longPieces[i] = regexEscape(longPieces[i]);
    }
    for (i = 0; i < 24; i++) {
        mixedPieces[i] = regexEscape(mixedPieces[i]);
    }

    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
    this._monthsShortRegex = this._monthsRegex;
    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
}

function createDate (y, m, d, h, M, s, ms) {
    // can't just apply() to create a date:
    // https://stackoverflow.com/q/181348
    var date = new Date(y, m, d, h, M, s, ms);

    // the date constructor remaps years 0-99 to 1900-1999
    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
        date.setFullYear(y);
    }
    return date;
}

function createUTCDate (y) {
    var date = new Date(Date.UTC.apply(null, arguments));

    // the Date.UTC function remaps years 0-99 to 1900-1999
    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
        date.setUTCFullYear(y);
    }
    return date;
}

// start-of-first-week - start-of-year
function firstWeekOffset(year, dow, doy) {
    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
        fwd = 7 + dow - doy,
        // first-week day local weekday -- which local weekday is fwd
        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

    return -fwdlw + fwd - 1;
}

// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
    var localWeekday = (7 + weekday - dow) % 7,
        weekOffset = firstWeekOffset(year, dow, doy),
        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
        resYear, resDayOfYear;

    if (dayOfYear <= 0) {
        resYear = year - 1;
        resDayOfYear = daysInYear(resYear) + dayOfYear;
    } else if (dayOfYear > daysInYear(year)) {
        resYear = year + 1;
        resDayOfYear = dayOfYear - daysInYear(year);
    } else {
        resYear = year;
        resDayOfYear = dayOfYear;
    }

    return {
        year: resYear,
        dayOfYear: resDayOfYear
    };
}

function weekOfYear(mom, dow, doy) {
    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
        resWeek, resYear;

    if (week < 1) {
        resYear = mom.year() - 1;
        resWeek = week + weeksInYear(resYear, dow, doy);
    } else if (week > weeksInYear(mom.year(), dow, doy)) {
        resWeek = week - weeksInYear(mom.year(), dow, doy);
        resYear = mom.year() + 1;
    } else {
        resYear = mom.year();
        resWeek = week;
    }

    return {
        week: resWeek,
        year: resYear
    };
}

function weeksInYear(year, dow, doy) {
    var weekOffset = firstWeekOffset(year, dow, doy),
        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
}

// FORMATTING

addFormatToken('w', ['ww', 2], 'wo', 'week');
addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

// ALIASES

addUnitAlias('week', 'w');
addUnitAlias('isoWeek', 'W');

// PRIORITIES

addUnitPriority('week', 5);
addUnitPriority('isoWeek', 5);

// PARSING

addRegexToken('w',  match1to2);
addRegexToken('ww', match1to2, match2);
addRegexToken('W',  match1to2);
addRegexToken('WW', match1to2, match2);

addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
    week[token.substr(0, 1)] = toInt(input);
});

// HELPERS

// LOCALES

function localeWeek (mom) {
    return weekOfYear(mom, this._week.dow, this._week.doy).week;
}

var defaultLocaleWeek = {
    dow : 0, // Sunday is the first day of the week.
    doy : 6  // The week that contains Jan 1st is the first week of the year.
};

function localeFirstDayOfWeek () {
    return this._week.dow;
}

function localeFirstDayOfYear () {
    return this._week.doy;
}

// MOMENTS

function getSetWeek (input) {
    var week = this.localeData().week(this);
    return input == null ? week : this.add((input - week) * 7, 'd');
}

function getSetISOWeek (input) {
    var week = weekOfYear(this, 1, 4).week;
    return input == null ? week : this.add((input - week) * 7, 'd');
}

// FORMATTING

addFormatToken('d', 0, 'do', 'day');

addFormatToken('dd', 0, 0, function (format) {
    return this.localeData().weekdaysMin(this, format);
});

addFormatToken('ddd', 0, 0, function (format) {
    return this.localeData().weekdaysShort(this, format);
});

addFormatToken('dddd', 0, 0, function (format) {
    return this.localeData().weekdays(this, format);
});

addFormatToken('e', 0, 0, 'weekday');
addFormatToken('E', 0, 0, 'isoWeekday');

// ALIASES

addUnitAlias('day', 'd');
addUnitAlias('weekday', 'e');
addUnitAlias('isoWeekday', 'E');

// PRIORITY
addUnitPriority('day', 11);
addUnitPriority('weekday', 11);
addUnitPriority('isoWeekday', 11);

// PARSING

addRegexToken('d',    match1to2);
addRegexToken('e',    match1to2);
addRegexToken('E',    match1to2);
addRegexToken('dd',   function (isStrict, locale) {
    return locale.weekdaysMinRegex(isStrict);
});
addRegexToken('ddd',   function (isStrict, locale) {
    return locale.weekdaysShortRegex(isStrict);
});
addRegexToken('dddd',   function (isStrict, locale) {
    return locale.weekdaysRegex(isStrict);
});

addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
    var weekday = config._locale.weekdaysParse(input, token, config._strict);
    // if we didn't get a weekday name, mark the date as invalid
    if (weekday != null) {
        week.d = weekday;
    } else {
        getParsingFlags(config).invalidWeekday = input;
    }
});

addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
    week[token] = toInt(input);
});

// HELPERS

function parseWeekday(input, locale) {
    if (typeof input !== 'string') {
        return input;
    }

    if (!isNaN(input)) {
        return parseInt(input, 10);
    }

    input = locale.weekdaysParse(input);
    if (typeof input === 'number') {
        return input;
    }

    return null;
}

function parseIsoWeekday(input, locale) {
    if (typeof input === 'string') {
        return locale.weekdaysParse(input) % 7 || 7;
    }
    return isNaN(input) ? null : input;
}

// LOCALES

var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
function localeWeekdays (m, format) {
    if (!m) {
        return isArray(this._weekdays) ? this._weekdays :
            this._weekdays['standalone'];
    }
    return isArray(this._weekdays) ? this._weekdays[m.day()] :
        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
}

var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
function localeWeekdaysShort (m) {
    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
}

var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
function localeWeekdaysMin (m) {
    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
}

function handleStrictParse$1(weekdayName, format, strict) {
    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
    if (!this._weekdaysParse) {
        this._weekdaysParse = [];
        this._shortWeekdaysParse = [];
        this._minWeekdaysParse = [];

        for (i = 0; i < 7; ++i) {
            mom = createUTC([2000, 1]).day(i);
            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
        }
    }

    if (strict) {
        if (format === 'dddd') {
            ii = indexOf.call(this._weekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else if (format === 'ddd') {
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        }
    } else {
        if (format === 'dddd') {
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else if (format === 'ddd') {
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._minWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        } else {
            ii = indexOf.call(this._minWeekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._weekdaysParse, llc);
            if (ii !== -1) {
                return ii;
            }
            ii = indexOf.call(this._shortWeekdaysParse, llc);
            return ii !== -1 ? ii : null;
        }
    }
}

function localeWeekdaysParse (weekdayName, format, strict) {
    var i, mom, regex;

    if (this._weekdaysParseExact) {
        return handleStrictParse$1.call(this, weekdayName, format, strict);
    }

    if (!this._weekdaysParse) {
        this._weekdaysParse = [];
        this._minWeekdaysParse = [];
        this._shortWeekdaysParse = [];
        this._fullWeekdaysParse = [];
    }

    for (i = 0; i < 7; i++) {
        // make the regex if we don't have it already

        mom = createUTC([2000, 1]).day(i);
        if (strict && !this._fullWeekdaysParse[i]) {
            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
        }
        if (!this._weekdaysParse[i]) {
            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
        }
        // test the regex
        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
            return i;
        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
            return i;
        }
    }
}

// MOMENTS

function getSetDayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
    if (input != null) {
        input = parseWeekday(input, this.localeData());
        return this.add(input - day, 'd');
    } else {
        return day;
    }
}

function getSetLocaleDayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
    return input == null ? weekday : this.add(input - weekday, 'd');
}

function getSetISODayOfWeek (input) {
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }

    // behaves the same as moment#day except
    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
    // as a setter, sunday should belong to the previous week.

    if (input != null) {
        var weekday = parseIsoWeekday(input, this.localeData());
        return this.day(this.day() % 7 ? weekday : weekday - 7);
    } else {
        return this.day() || 7;
    }
}

var defaultWeekdaysRegex = matchWord;
function weekdaysRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysStrictRegex;
        } else {
            return this._weekdaysRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            this._weekdaysRegex = defaultWeekdaysRegex;
        }
        return this._weekdaysStrictRegex && isStrict ?
            this._weekdaysStrictRegex : this._weekdaysRegex;
    }
}

var defaultWeekdaysShortRegex = matchWord;
function weekdaysShortRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysShortStrictRegex;
        } else {
            return this._weekdaysShortRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysShortRegex')) {
            this._weekdaysShortRegex = defaultWeekdaysShortRegex;
        }
        return this._weekdaysShortStrictRegex && isStrict ?
            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
    }
}

var defaultWeekdaysMinRegex = matchWord;
function weekdaysMinRegex (isStrict) {
    if (this._weekdaysParseExact) {
        if (!hasOwnProp(this, '_weekdaysRegex')) {
            computeWeekdaysParse.call(this);
        }
        if (isStrict) {
            return this._weekdaysMinStrictRegex;
        } else {
            return this._weekdaysMinRegex;
        }
    } else {
        if (!hasOwnProp(this, '_weekdaysMinRegex')) {
            this._weekdaysMinRegex = defaultWeekdaysMinRegex;
        }
        return this._weekdaysMinStrictRegex && isStrict ?
            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
    }
}


function computeWeekdaysParse () {
    function cmpLenRev(a, b) {
        return b.length - a.length;
    }

    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
        i, mom, minp, shortp, longp;
    for (i = 0; i < 7; i++) {
        // make the regex if we don't have it already
        mom = createUTC([2000, 1]).day(i);
        minp = this.weekdaysMin(mom, '');
        shortp = this.weekdaysShort(mom, '');
        longp = this.weekdays(mom, '');
        minPieces.push(minp);
        shortPieces.push(shortp);
        longPieces.push(longp);
        mixedPieces.push(minp);
        mixedPieces.push(shortp);
        mixedPieces.push(longp);
    }
    // Sorting makes sure if one weekday (or abbr) is a prefix of another it
    // will match the longer piece.
    minPieces.sort(cmpLenRev);
    shortPieces.sort(cmpLenRev);
    longPieces.sort(cmpLenRev);
    mixedPieces.sort(cmpLenRev);
    for (i = 0; i < 7; i++) {
        shortPieces[i] = regexEscape(shortPieces[i]);
        longPieces[i] = regexEscape(longPieces[i]);
        mixedPieces[i] = regexEscape(mixedPieces[i]);
    }

    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
    this._weekdaysShortRegex = this._weekdaysRegex;
    this._weekdaysMinRegex = this._weekdaysRegex;

    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
}

// FORMATTING

function hFormat() {
    return this.hours() % 12 || 12;
}

function kFormat() {
    return this.hours() || 24;
}

addFormatToken('H', ['HH', 2], 0, 'hour');
addFormatToken('h', ['hh', 2], 0, hFormat);
addFormatToken('k', ['kk', 2], 0, kFormat);

addFormatToken('hmm', 0, 0, function () {
    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
});

addFormatToken('hmmss', 0, 0, function () {
    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
        zeroFill(this.seconds(), 2);
});

addFormatToken('Hmm', 0, 0, function () {
    return '' + this.hours() + zeroFill(this.minutes(), 2);
});

addFormatToken('Hmmss', 0, 0, function () {
    return '' + this.hours() + zeroFill(this.minutes(), 2) +
        zeroFill(this.seconds(), 2);
});

function meridiem (token, lowercase) {
    addFormatToken(token, 0, 0, function () {
        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
    });
}

meridiem('a', true);
meridiem('A', false);

// ALIASES

addUnitAlias('hour', 'h');

// PRIORITY
addUnitPriority('hour', 13);

// PARSING

function matchMeridiem (isStrict, locale) {
    return locale._meridiemParse;
}

addRegexToken('a',  matchMeridiem);
addRegexToken('A',  matchMeridiem);
addRegexToken('H',  match1to2);
addRegexToken('h',  match1to2);
addRegexToken('k',  match1to2);
addRegexToken('HH', match1to2, match2);
addRegexToken('hh', match1to2, match2);
addRegexToken('kk', match1to2, match2);

addRegexToken('hmm', match3to4);
addRegexToken('hmmss', match5to6);
addRegexToken('Hmm', match3to4);
addRegexToken('Hmmss', match5to6);

addParseToken(['H', 'HH'], HOUR);
addParseToken(['k', 'kk'], function (input, array, config) {
    var kInput = toInt(input);
    array[HOUR] = kInput === 24 ? 0 : kInput;
});
addParseToken(['a', 'A'], function (input, array, config) {
    config._isPm = config._locale.isPM(input);
    config._meridiem = input;
});
addParseToken(['h', 'hh'], function (input, array, config) {
    array[HOUR] = toInt(input);
    getParsingFlags(config).bigHour = true;
});
addParseToken('hmm', function (input, array, config) {
    var pos = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos));
    array[MINUTE] = toInt(input.substr(pos));
    getParsingFlags(config).bigHour = true;
});
addParseToken('hmmss', function (input, array, config) {
    var pos1 = input.length - 4;
    var pos2 = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos1));
    array[MINUTE] = toInt(input.substr(pos1, 2));
    array[SECOND] = toInt(input.substr(pos2));
    getParsingFlags(config).bigHour = true;
});
addParseToken('Hmm', function (input, array, config) {
    var pos = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos));
    array[MINUTE] = toInt(input.substr(pos));
});
addParseToken('Hmmss', function (input, array, config) {
    var pos1 = input.length - 4;
    var pos2 = input.length - 2;
    array[HOUR] = toInt(input.substr(0, pos1));
    array[MINUTE] = toInt(input.substr(pos1, 2));
    array[SECOND] = toInt(input.substr(pos2));
});

// LOCALES

function localeIsPM (input) {
    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
    // Using charAt should be more compatible.
    return ((input + '').toLowerCase().charAt(0) === 'p');
}

var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
function localeMeridiem (hours, minutes, isLower) {
    if (hours > 11) {
        return isLower ? 'pm' : 'PM';
    } else {
        return isLower ? 'am' : 'AM';
    }
}


// MOMENTS

// Setting the hour should keep the time, because the user explicitly
// specified which hour he wants. So trying to maintain the same hour (in
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
var getSetHour = makeGetSet('Hours', true);

// months
// week
// weekdays
// meridiem
var baseConfig = {
    calendar: defaultCalendar,
    longDateFormat: defaultLongDateFormat,
    invalidDate: defaultInvalidDate,
    ordinal: defaultOrdinal,
    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
    relativeTime: defaultRelativeTime,

    months: defaultLocaleMonths,
    monthsShort: defaultLocaleMonthsShort,

    week: defaultLocaleWeek,

    weekdays: defaultLocaleWeekdays,
    weekdaysMin: defaultLocaleWeekdaysMin,
    weekdaysShort: defaultLocaleWeekdaysShort,

    meridiemParse: defaultLocaleMeridiemParse
};

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return null;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            __webpack_require__(526)("./" + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {}
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
    }

    return globalLocale._abbr;
}

function defineLocale (name, config) {
    if (config !== null) {
        var parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                if (!localeFamilies[config.parentLocale]) {
                    localeFamilies[config.parentLocale] = [];
                }
                localeFamilies[config.parentLocale].push({
                    name: name,
                    config: config
                });
                return null;
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);


        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

function listLocales() {
    return keys(locales);
}

function checkOverflow (m) {
    var overflow;
    var a = m._a;

    if (a && getParsingFlags(m).overflow === -2) {
        overflow =
            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
            -1;

        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
            overflow = DATE;
        }
        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
            overflow = WEEK;
        }
        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
            overflow = WEEKDAY;
        }

        getParsingFlags(m).overflow = overflow;
    }

    return m;
}

// Pick the first defined of two or three arguments.
function defaults(a, b, c) {
    if (a != null) {
        return a;
    }
    if (b != null) {
        return b;
    }
    return c;
}

function currentDateArray(config) {
    // hooks is actually the exported moment object
    var nowValue = new Date(hooks.now());
    if (config._useUTC) {
        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
    }
    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
}

// convert an array to a date.
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
function configFromArray (config) {
    var i, date, input = [], currentDate, expectedWeekday, yearToUse;

    if (config._d) {
        return;
    }

    currentDate = currentDateArray(config);

    //compute day of the year from weeks and weekdays
    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
        dayOfYearFromWeekInfo(config);
    }

    //if the day of the year is set, figure out what it is
    if (config._dayOfYear != null) {
        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
            getParsingFlags(config)._overflowDayOfYear = true;
        }

        date = createUTCDate(yearToUse, 0, config._dayOfYear);
        config._a[MONTH] = date.getUTCMonth();
        config._a[DATE] = date.getUTCDate();
    }

    // Default to current date.
    // * if no year, month, day of month are given, default to today
    // * if day of month is given, default month and year
    // * if month is given, default only year
    // * if year is given, don't default anything
    for (i = 0; i < 3 && config._a[i] == null; ++i) {
        config._a[i] = input[i] = currentDate[i];
    }

    // Zero out whatever was not defaulted, including time
    for (; i < 7; i++) {
        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
    }

    // Check for 24:00:00.000
    if (config._a[HOUR] === 24 &&
            config._a[MINUTE] === 0 &&
            config._a[SECOND] === 0 &&
            config._a[MILLISECOND] === 0) {
        config._nextDay = true;
        config._a[HOUR] = 0;
    }

    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
    expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();

    // Apply timezone offset from input. The actual utcOffset can be changed
    // with parseZone.
    if (config._tzm != null) {
        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
    }

    if (config._nextDay) {
        config._a[HOUR] = 24;
    }

    // check for mismatching day of week
    if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
        getParsingFlags(config).weekdayMismatch = true;
    }
}

function dayOfYearFromWeekInfo(config) {
    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

    w = config._w;
    if (w.GG != null || w.W != null || w.E != null) {
        dow = 1;
        doy = 4;

        // TODO: We need to take the current isoWeekYear, but that depends on
        // how we interpret now (local, utc, fixed offset). So create
        // a now version of current config (take local/utc/offset flags, and
        // create now).
        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
        week = defaults(w.W, 1);
        weekday = defaults(w.E, 1);
        if (weekday < 1 || weekday > 7) {
            weekdayOverflow = true;
        }
    } else {
        dow = config._locale._week.dow;
        doy = config._locale._week.doy;

        var curWeek = weekOfYear(createLocal(), dow, doy);

        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);

        // Default to current week.
        week = defaults(w.w, curWeek.week);

        if (w.d != null) {
            // weekday -- low day numbers are considered next week
            weekday = w.d;
            if (weekday < 0 || weekday > 6) {
                weekdayOverflow = true;
            }
        } else if (w.e != null) {
            // local weekday -- counting starts from begining of week
            weekday = w.e + dow;
            if (w.e < 0 || w.e > 6) {
                weekdayOverflow = true;
            }
        } else {
            // default to begining of week
            weekday = dow;
        }
    }
    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
        getParsingFlags(config)._overflowWeeks = true;
    } else if (weekdayOverflow != null) {
        getParsingFlags(config)._overflowWeekday = true;
    } else {
        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
        config._a[YEAR] = temp.year;
        config._dayOfYear = temp.dayOfYear;
    }
}

// iso 8601 regex
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;

var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

var isoDates = [
    ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
    ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
    ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
    ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
    ['YYYY-DDD', /\d{4}-\d{3}/],
    ['YYYY-MM', /\d{4}-\d\d/, false],
    ['YYYYYYMMDD', /[+-]\d{10}/],
    ['YYYYMMDD', /\d{8}/],
    // YYYYMM is NOT allowed by the standard
    ['GGGG[W]WWE', /\d{4}W\d{3}/],
    ['GGGG[W]WW', /\d{4}W\d{2}/, false],
    ['YYYYDDD', /\d{7}/]
];

// iso time formats and regexes
var isoTimes = [
    ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
    ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
    ['HH:mm:ss', /\d\d:\d\d:\d\d/],
    ['HH:mm', /\d\d:\d\d/],
    ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
    ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
    ['HHmmss', /\d\d\d\d\d\d/],
    ['HHmm', /\d\d\d\d/],
    ['HH', /\d\d/]
];

var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

// date from iso format
function configFromISO(config) {
    var i, l,
        string = config._i,
        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
        allowTime, dateFormat, timeFormat, tzFormat;

    if (match) {
        getParsingFlags(config).iso = true;

        for (i = 0, l = isoDates.length; i < l; i++) {
            if (isoDates[i][1].exec(match[1])) {
                dateFormat = isoDates[i][0];
                allowTime = isoDates[i][2] !== false;
                break;
            }
        }
        if (dateFormat == null) {
            config._isValid = false;
            return;
        }
        if (match[3]) {
            for (i = 0, l = isoTimes.length; i < l; i++) {
                if (isoTimes[i][1].exec(match[3])) {
                    // match[2] should be 'T' or space
                    timeFormat = (match[2] || ' ') + isoTimes[i][0];
                    break;
                }
            }
            if (timeFormat == null) {
                config._isValid = false;
                return;
            }
        }
        if (!allowTime && timeFormat != null) {
            config._isValid = false;
            return;
        }
        if (match[4]) {
            if (tzRegex.exec(match[4])) {
                tzFormat = 'Z';
            } else {
                config._isValid = false;
                return;
            }
        }
        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
        configFromStringAndFormat(config);
    } else {
        config._isValid = false;
    }
}

// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;

function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
    var result = [
        untruncateYear(yearStr),
        defaultLocaleMonthsShort.indexOf(monthStr),
        parseInt(dayStr, 10),
        parseInt(hourStr, 10),
        parseInt(minuteStr, 10)
    ];

    if (secondStr) {
        result.push(parseInt(secondStr, 10));
    }

    return result;
}

function untruncateYear(yearStr) {
    var year = parseInt(yearStr, 10);
    if (year <= 49) {
        return 2000 + year;
    } else if (year <= 999) {
        return 1900 + year;
    }
    return year;
}

function preprocessRFC2822(s) {
    // Remove comments and folding whitespace and replace multiple-spaces with a single space
    return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim();
}

function checkWeekday(weekdayStr, parsedInput, config) {
    if (weekdayStr) {
        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
        var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
            weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
        if (weekdayProvided !== weekdayActual) {
            getParsingFlags(config).weekdayMismatch = true;
            config._isValid = false;
            return false;
        }
    }
    return true;
}

var obsOffsets = {
    UT: 0,
    GMT: 0,
    EDT: -4 * 60,
    EST: -5 * 60,
    CDT: -5 * 60,
    CST: -6 * 60,
    MDT: -6 * 60,
    MST: -7 * 60,
    PDT: -7 * 60,
    PST: -8 * 60
};

function calculateOffset(obsOffset, militaryOffset, numOffset) {
    if (obsOffset) {
        return obsOffsets[obsOffset];
    } else if (militaryOffset) {
        // the only allowed military tz is Z
        return 0;
    } else {
        var hm = parseInt(numOffset, 10);
        var m = hm % 100, h = (hm - m) / 100;
        return h * 60 + m;
    }
}

// date and time from ref 2822 format
function configFromRFC2822(config) {
    var match = rfc2822.exec(preprocessRFC2822(config._i));
    if (match) {
        var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
        if (!checkWeekday(match[1], parsedArray, config)) {
            return;
        }

        config._a = parsedArray;
        config._tzm = calculateOffset(match[8], match[9], match[10]);

        config._d = createUTCDate.apply(null, config._a);
        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);

        getParsingFlags(config).rfc2822 = true;
    } else {
        config._isValid = false;
    }
}

// date from iso format or fallback
function configFromString(config) {
    var matched = aspNetJsonRegex.exec(config._i);

    if (matched !== null) {
        config._d = new Date(+matched[1]);
        return;
    }

    configFromISO(config);
    if (config._isValid === false) {
        delete config._isValid;
    } else {
        return;
    }

    configFromRFC2822(config);
    if (config._isValid === false) {
        delete config._isValid;
    } else {
        return;
    }

    // Final attempt, use Input Fallback
    hooks.createFromInputFallback(config);
}

hooks.createFromInputFallback = deprecate(
    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
    'discouraged and will be removed in an upcoming major release. Please refer to ' +
    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
    function (config) {
        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
    }
);

// constant that refers to the ISO standard
hooks.ISO_8601 = function () {};

// constant that refers to the RFC 2822 form
hooks.RFC_2822 = function () {};

// date from string and format string
function configFromStringAndFormat(config) {
    // TODO: Move this to another part of the creation flow to prevent circular deps
    if (config._f === hooks.ISO_8601) {
        configFromISO(config);
        return;
    }
    if (config._f === hooks.RFC_2822) {
        configFromRFC2822(config);
        return;
    }
    config._a = [];
    getParsingFlags(config).empty = true;

    // This array is used to make a Date, either with `new Date` or `Date.UTC`
    var string = '' + config._i,
        i, parsedInput, tokens, token, skipped,
        stringLength = string.length,
        totalParsedInputLength = 0;

    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

    for (i = 0; i < tokens.length; i++) {
        token = tokens[i];
        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
        // console.log('token', token, 'parsedInput', parsedInput,
        //         'regex', getParseRegexForToken(token, config));
        if (parsedInput) {
            skipped = string.substr(0, string.indexOf(parsedInput));
            if (skipped.length > 0) {
                getParsingFlags(config).unusedInput.push(skipped);
            }
            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
            totalParsedInputLength += parsedInput.length;
        }
        // don't parse if it's not a known token
        if (formatTokenFunctions[token]) {
            if (parsedInput) {
                getParsingFlags(config).empty = false;
            }
            else {
                getParsingFlags(config).unusedTokens.push(token);
            }
            addTimeToArrayFromToken(token, parsedInput, config);
        }
        else if (config._strict && !parsedInput) {
            getParsingFlags(config).unusedTokens.push(token);
        }
    }

    // add remaining unparsed input length to the string
    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
    if (string.length > 0) {
        getParsingFlags(config).unusedInput.push(string);
    }

    // clear _12h flag if hour is <= 12
    if (config._a[HOUR] <= 12 &&
        getParsingFlags(config).bigHour === true &&
        config._a[HOUR] > 0) {
        getParsingFlags(config).bigHour = undefined;
    }

    getParsingFlags(config).parsedDateParts = config._a.slice(0);
    getParsingFlags(config).meridiem = config._meridiem;
    // handle meridiem
    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

    configFromArray(config);
    checkOverflow(config);
}


function meridiemFixWrap (locale, hour, meridiem) {
    var isPm;

    if (meridiem == null) {
        // nothing to do
        return hour;
    }
    if (locale.meridiemHour != null) {
        return locale.meridiemHour(hour, meridiem);
    } else if (locale.isPM != null) {
        // Fallback
        isPm = locale.isPM(meridiem);
        if (isPm && hour < 12) {
            hour += 12;
        }
        if (!isPm && hour === 12) {
            hour = 0;
        }
        return hour;
    } else {
        // this is not supposed to happen
        return hour;
    }
}

// date from string and array of format strings
function configFromStringAndArray(config) {
    var tempConfig,
        bestMoment,

        scoreToBeat,
        i,
        currentScore;

    if (config._f.length === 0) {
        getParsingFlags(config).invalidFormat = true;
        config._d = new Date(NaN);
        return;
    }

    for (i = 0; i < config._f.length; i++) {
        currentScore = 0;
        tempConfig = copyConfig({}, config);
        if (config._useUTC != null) {
            tempConfig._useUTC = config._useUTC;
        }
        tempConfig._f = config._f[i];
        configFromStringAndFormat(tempConfig);

        if (!isValid(tempConfig)) {
            continue;
        }

        // if there is any input that was not parsed add a penalty for that format
        currentScore += getParsingFlags(tempConfig).charsLeftOver;

        //or tokens
        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

        getParsingFlags(tempConfig).score = currentScore;

        if (scoreToBeat == null || currentScore < scoreToBeat) {
            scoreToBeat = currentScore;
            bestMoment = tempConfig;
        }
    }

    extend(config, bestMoment || tempConfig);
}

function configFromObject(config) {
    if (config._d) {
        return;
    }

    var i = normalizeObjectUnits(config._i);
    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
        return obj && parseInt(obj, 10);
    });

    configFromArray(config);
}

function createFromConfig (config) {
    var res = new Moment(checkOverflow(prepareConfig(config)));
    if (res._nextDay) {
        // Adding is smart enough around DST
        res.add(1, 'd');
        res._nextDay = undefined;
    }

    return res;
}

function prepareConfig (config) {
    var input = config._i,
        format = config._f;

    config._locale = config._locale || getLocale(config._l);

    if (input === null || (format === undefined && input === '')) {
        return createInvalid({nullInput: true});
    }

    if (typeof input === 'string') {
        config._i = input = config._locale.preparse(input);
    }

    if (isMoment(input)) {
        return new Moment(checkOverflow(input));
    } else if (isDate(input)) {
        config._d = input;
    } else if (isArray(format)) {
        configFromStringAndArray(config);
    } else if (format) {
        configFromStringAndFormat(config);
    }  else {
        configFromInput(config);
    }

    if (!isValid(config)) {
        config._d = null;
    }

    return config;
}

function configFromInput(config) {
    var input = config._i;
    if (isUndefined(input)) {
        config._d = new Date(hooks.now());
    } else if (isDate(input)) {
        config._d = new Date(input.valueOf());
    } else if (typeof input === 'string') {
        configFromString(config);
    } else if (isArray(input)) {
        config._a = map(input.slice(0), function (obj) {
            return parseInt(obj, 10);
        });
        configFromArray(config);
    } else if (isObject(input)) {
        configFromObject(config);
    } else if (isNumber(input)) {
        // from milliseconds
        config._d = new Date(input);
    } else {
        hooks.createFromInputFallback(config);
    }
}

function createLocalOrUTC (input, format, locale, strict, isUTC) {
    var c = {};

    if (locale === true || locale === false) {
        strict = locale;
        locale = undefined;
    }

    if ((isObject(input) && isObjectEmpty(input)) ||
            (isArray(input) && input.length === 0)) {
        input = undefined;
    }
    // object construction must be done this way.
    // https://github.com/moment/moment/issues/1423
    c._isAMomentObject = true;
    c._useUTC = c._isUTC = isUTC;
    c._l = locale;
    c._i = input;
    c._f = format;
    c._strict = strict;

    return createFromConfig(c);
}

function createLocal (input, format, locale, strict) {
    return createLocalOrUTC(input, format, locale, strict, false);
}

var prototypeMin = deprecate(
    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
    function () {
        var other = createLocal.apply(null, arguments);
        if (this.isValid() && other.isValid()) {
            return other < this ? this : other;
        } else {
            return createInvalid();
        }
    }
);

var prototypeMax = deprecate(
    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
    function () {
        var other = createLocal.apply(null, arguments);
        if (this.isValid() && other.isValid()) {
            return other > this ? this : other;
        } else {
            return createInvalid();
        }
    }
);

// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
// first element is an array of moment objects.
function pickBy(fn, moments) {
    var res, i;
    if (moments.length === 1 && isArray(moments[0])) {
        moments = moments[0];
    }
    if (!moments.length) {
        return createLocal();
    }
    res = moments[0];
    for (i = 1; i < moments.length; ++i) {
        if (!moments[i].isValid() || moments[i][fn](res)) {
            res = moments[i];
        }
    }
    return res;
}

// TODO: Use [].sort instead?
function min () {
    var args = [].slice.call(arguments, 0);

    return pickBy('isBefore', args);
}

function max () {
    var args = [].slice.call(arguments, 0);

    return pickBy('isAfter', args);
}

var now = function () {
    return Date.now ? Date.now() : +(new Date());
};

var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];

function isDurationValid(m) {
    for (var key in m) {
        if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
            return false;
        }
    }

    var unitHasDecimal = false;
    for (var i = 0; i < ordering.length; ++i) {
        if (m[ordering[i]]) {
            if (unitHasDecimal) {
                return false; // only allow non-integers for smallest unit
            }
            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                unitHasDecimal = true;
            }
        }
    }

    return true;
}

function isValid$1() {
    return this._isValid;
}

function createInvalid$1() {
    return createDuration(NaN);
}

function Duration (duration) {
    var normalizedInput = normalizeObjectUnits(duration),
        years = normalizedInput.year || 0,
        quarters = normalizedInput.quarter || 0,
        months = normalizedInput.month || 0,
        weeks = normalizedInput.week || 0,
        days = normalizedInput.day || 0,
        hours = normalizedInput.hour || 0,
        minutes = normalizedInput.minute || 0,
        seconds = normalizedInput.second || 0,
        milliseconds = normalizedInput.millisecond || 0;

    this._isValid = isDurationValid(normalizedInput);

    // representation for dateAddRemove
    this._milliseconds = +milliseconds +
        seconds * 1e3 + // 1000
        minutes * 6e4 + // 1000 * 60
        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
    // Because of dateAddRemove treats 24 hours as different from a
    // day when working around DST, we need to store them separately
    this._days = +days +
        weeks * 7;
    // It is impossible to translate months into days without knowing
    // which months you are are talking about, so we have to store
    // it separately.
    this._months = +months +
        quarters * 3 +
        years * 12;

    this._data = {};

    this._locale = getLocale();

    this._bubble();
}

function isDuration (obj) {
    return obj instanceof Duration;
}

function absRound (number) {
    if (number < 0) {
        return Math.round(-1 * number) * -1;
    } else {
        return Math.round(number);
    }
}

// FORMATTING

function offset (token, separator) {
    addFormatToken(token, 0, 0, function () {
        var offset = this.utcOffset();
        var sign = '+';
        if (offset < 0) {
            offset = -offset;
            sign = '-';
        }
        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
    });
}

offset('Z', ':');
offset('ZZ', '');

// PARSING

addRegexToken('Z',  matchShortOffset);
addRegexToken('ZZ', matchShortOffset);
addParseToken(['Z', 'ZZ'], function (input, array, config) {
    config._useUTC = true;
    config._tzm = offsetFromString(matchShortOffset, input);
});

// HELPERS

// timezone chunker
// '+10:00' > ['10',  '00']
// '-1530'  > ['-15', '30']
var chunkOffset = /([\+\-]|\d\d)/gi;

function offsetFromString(matcher, string) {
    var matches = (string || '').match(matcher);

    if (matches === null) {
        return null;
    }

    var chunk   = matches[matches.length - 1] || [];
    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
    var minutes = +(parts[1] * 60) + toInt(parts[2]);

    return minutes === 0 ?
      0 :
      parts[0] === '+' ? minutes : -minutes;
}

// Return a moment from input, that is local/utc/zone equivalent to model.
function cloneWithOffset(input, model) {
    var res, diff;
    if (model._isUTC) {
        res = model.clone();
        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
        // Use low-level api, because this fn is low-level api.
        res._d.setTime(res._d.valueOf() + diff);
        hooks.updateOffset(res, false);
        return res;
    } else {
        return createLocal(input).local();
    }
}

function getDateOffset (m) {
    // On Firefox.24 Date#getTimezoneOffset returns a floating point.
    // https://github.com/moment/moment/pull/1871
    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
}

// HOOKS

// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
hooks.updateOffset = function () {};

// MOMENTS

// keepLocalTime = true means only change the timezone, without
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
// +0200, so we adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
function getSetOffset (input, keepLocalTime, keepMinutes) {
    var offset = this._offset || 0,
        localAdjust;
    if (!this.isValid()) {
        return input != null ? this : NaN;
    }
    if (input != null) {
        if (typeof input === 'string') {
            input = offsetFromString(matchShortOffset, input);
            if (input === null) {
                return this;
            }
        } else if (Math.abs(input) < 16 && !keepMinutes) {
            input = input * 60;
        }
        if (!this._isUTC && keepLocalTime) {
            localAdjust = getDateOffset(this);
        }
        this._offset = input;
        this._isUTC = true;
        if (localAdjust != null) {
            this.add(localAdjust, 'm');
        }
        if (offset !== input) {
            if (!keepLocalTime || this._changeInProgress) {
                addSubtract(this, createDuration(input - offset, 'm'), 1, false);
            } else if (!this._changeInProgress) {
                this._changeInProgress = true;
                hooks.updateOffset(this, true);
                this._changeInProgress = null;
            }
        }
        return this;
    } else {
        return this._isUTC ? offset : getDateOffset(this);
    }
}

function getSetZone (input, keepLocalTime) {
    if (input != null) {
        if (typeof input !== 'string') {
            input = -input;
        }

        this.utcOffset(input, keepLocalTime);

        return this;
    } else {
        return -this.utcOffset();
    }
}

function setOffsetToUTC (keepLocalTime) {
    return this.utcOffset(0, keepLocalTime);
}

function setOffsetToLocal (keepLocalTime) {
    if (this._isUTC) {
        this.utcOffset(0, keepLocalTime);
        this._isUTC = false;

        if (keepLocalTime) {
            this.subtract(getDateOffset(this), 'm');
        }
    }
    return this;
}

function setOffsetToParsedOffset () {
    if (this._tzm != null) {
        this.utcOffset(this._tzm, false, true);
    } else if (typeof this._i === 'string') {
        var tZone = offsetFromString(matchOffset, this._i);
        if (tZone != null) {
            this.utcOffset(tZone);
        }
        else {
            this.utcOffset(0, true);
        }
    }
    return this;
}

function hasAlignedHourOffset (input) {
    if (!this.isValid()) {
        return false;
    }
    input = input ? createLocal(input).utcOffset() : 0;

    return (this.utcOffset() - input) % 60 === 0;
}

function isDaylightSavingTime () {
    return (
        this.utcOffset() > this.clone().month(0).utcOffset() ||
        this.utcOffset() > this.clone().month(5).utcOffset()
    );
}

function isDaylightSavingTimeShifted () {
    if (!isUndefined(this._isDSTShifted)) {
        return this._isDSTShifted;
    }

    var c = {};

    copyConfig(c, this);
    c = prepareConfig(c);

    if (c._a) {
        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
        this._isDSTShifted = this.isValid() &&
            compareArrays(c._a, other.toArray()) > 0;
    } else {
        this._isDSTShifted = false;
    }

    return this._isDSTShifted;
}

function isLocal () {
    return this.isValid() ? !this._isUTC : false;
}

function isUtcOffset () {
    return this.isValid() ? this._isUTC : false;
}

function isUtc () {
    return this.isValid() ? this._isUTC && this._offset === 0 : false;
}

// ASP.NET json date format regex
var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
// and further modified to allow for strings containing both week and day
var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;

function createDuration (input, key) {
    var duration = input,
        // matching against regexp is expensive, do it on demand
        match = null,
        sign,
        ret,
        diffRes;

    if (isDuration(input)) {
        duration = {
            ms : input._milliseconds,
            d  : input._days,
            M  : input._months
        };
    } else if (isNumber(input)) {
        duration = {};
        if (key) {
            duration[key] = input;
        } else {
            duration.milliseconds = input;
        }
    } else if (!!(match = aspNetRegex.exec(input))) {
        sign = (match[1] === '-') ? -1 : 1;
        duration = {
            y  : 0,
            d  : toInt(match[DATE])                         * sign,
            h  : toInt(match[HOUR])                         * sign,
            m  : toInt(match[MINUTE])                       * sign,
            s  : toInt(match[SECOND])                       * sign,
            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
        };
    } else if (!!(match = isoRegex.exec(input))) {
        sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
        duration = {
            y : parseIso(match[2], sign),
            M : parseIso(match[3], sign),
            w : parseIso(match[4], sign),
            d : parseIso(match[5], sign),
            h : parseIso(match[6], sign),
            m : parseIso(match[7], sign),
            s : parseIso(match[8], sign)
        };
    } else if (duration == null) {// checks for null or undefined
        duration = {};
    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));

        duration = {};
        duration.ms = diffRes.milliseconds;
        duration.M = diffRes.months;
    }

    ret = new Duration(duration);

    if (isDuration(input) && hasOwnProp(input, '_locale')) {
        ret._locale = input._locale;
    }

    return ret;
}

createDuration.fn = Duration.prototype;
createDuration.invalid = createInvalid$1;

function parseIso (inp, sign) {
    // We'd normally use ~~inp for this, but unfortunately it also
    // converts floats to ints.
    // inp may be undefined, so careful calling replace on it.
    var res = inp && parseFloat(inp.replace(',', '.'));
    // apply sign while we're at it
    return (isNaN(res) ? 0 : res) * sign;
}

function positiveMomentsDifference(base, other) {
    var res = {milliseconds: 0, months: 0};

    res.months = other.month() - base.month() +
        (other.year() - base.year()) * 12;
    if (base.clone().add(res.months, 'M').isAfter(other)) {
        --res.months;
    }

    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

    return res;
}

function momentsDifference(base, other) {
    var res;
    if (!(base.isValid() && other.isValid())) {
        return {milliseconds: 0, months: 0};
    }

    other = cloneWithOffset(other, base);
    if (base.isBefore(other)) {
        res = positiveMomentsDifference(base, other);
    } else {
        res = positiveMomentsDifference(other, base);
        res.milliseconds = -res.milliseconds;
        res.months = -res.months;
    }

    return res;
}

// TODO: remove 'name' arg after deprecation is removed
function createAdder(direction, name) {
    return function (val, period) {
        var dur, tmp;
        //invert the arguments, but complain about it
        if (period !== null && !isNaN(+period)) {
            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
            tmp = val; val = period; period = tmp;
        }

        val = typeof val === 'string' ? +val : val;
        dur = createDuration(val, period);
        addSubtract(this, dur, direction);
        return this;
    };
}

function addSubtract (mom, duration, isAdding, updateOffset) {
    var milliseconds = duration._milliseconds,
        days = absRound(duration._days),
        months = absRound(duration._months);

    if (!mom.isValid()) {
        // No op
        return;
    }

    updateOffset = updateOffset == null ? true : updateOffset;

    if (months) {
        setMonth(mom, get(mom, 'Month') + months * isAdding);
    }
    if (days) {
        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
    }
    if (milliseconds) {
        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
    }
    if (updateOffset) {
        hooks.updateOffset(mom, days || months);
    }
}

var add      = createAdder(1, 'add');
var subtract = createAdder(-1, 'subtract');

function getCalendarFormat(myMoment, now) {
    var diff = myMoment.diff(now, 'days', true);
    return diff < -6 ? 'sameElse' :
            diff < -1 ? 'lastWeek' :
            diff < 0 ? 'lastDay' :
            diff < 1 ? 'sameDay' :
            diff < 2 ? 'nextDay' :
            diff < 7 ? 'nextWeek' : 'sameElse';
}

function calendar$1 (time, formats) {
    // We want to compare the start of today, vs this.
    // Getting start-of-today depends on whether we're local/utc/offset or not.
    var now = time || createLocal(),
        sod = cloneWithOffset(now, this).startOf('day'),
        format = hooks.calendarFormat(this, sod) || 'sameElse';

    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
}

function clone () {
    return new Moment(this);
}

function isAfter (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input);
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() > localInput.valueOf();
    } else {
        return localInput.valueOf() < this.clone().startOf(units).valueOf();
    }
}

function isBefore (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input);
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() < localInput.valueOf();
    } else {
        return this.clone().endOf(units).valueOf() < localInput.valueOf();
    }
}

function isBetween (from, to, units, inclusivity) {
    inclusivity = inclusivity || '()';
    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
}

function isSame (input, units) {
    var localInput = isMoment(input) ? input : createLocal(input),
        inputMs;
    if (!(this.isValid() && localInput.isValid())) {
        return false;
    }
    units = normalizeUnits(units || 'millisecond');
    if (units === 'millisecond') {
        return this.valueOf() === localInput.valueOf();
    } else {
        inputMs = localInput.valueOf();
        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
    }
}

function isSameOrAfter (input, units) {
    return this.isSame(input, units) || this.isAfter(input,units);
}

function isSameOrBefore (input, units) {
    return this.isSame(input, units) || this.isBefore(input,units);
}

function diff (input, units, asFloat) {
    var that,
        zoneDelta,
        delta, output;

    if (!this.isValid()) {
        return NaN;
    }

    that = cloneWithOffset(input, this);

    if (!that.isValid()) {
        return NaN;
    }

    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

    units = normalizeUnits(units);

    switch (units) {
        case 'year': output = monthDiff(this, that) / 12; break;
        case 'month': output = monthDiff(this, that); break;
        case 'quarter': output = monthDiff(this, that) / 3; break;
        case 'second': output = (this - that) / 1e3; break; // 1000
        case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
        case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
        case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
        case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
        default: output = this - that;
    }

    return asFloat ? output : absFloor(output);
}

function monthDiff (a, b) {
    // difference in months
    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
        // b is in (anchor - 1 month, anchor + 1 month)
        anchor = a.clone().add(wholeMonthDiff, 'months'),
        anchor2, adjust;

    if (b - anchor < 0) {
        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
        // linear across the month
        adjust = (b - anchor) / (anchor - anchor2);
    } else {
        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
        // linear across the month
        adjust = (b - anchor) / (anchor2 - anchor);
    }

    //check for negative zero, return zero if negative zero
    return -(wholeMonthDiff + adjust) || 0;
}

hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

function toString () {
    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
}

function toISOString(keepOffset) {
    if (!this.isValid()) {
        return null;
    }
    var utc = keepOffset !== true;
    var m = utc ? this.clone().utc() : this;
    if (m.year() < 0 || m.year() > 9999) {
        return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
    }
    if (isFunction(Date.prototype.toISOString)) {
        // native implementation is ~50x faster, use it when we can
        if (utc) {
            return this.toDate().toISOString();
        } else {
            return new Date(this._d.valueOf()).toISOString().replace('Z', formatMoment(m, 'Z'));
        }
    }
    return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
}

/**
 * Return a human readable representation of a moment that can
 * also be evaluated to get a new moment which is the same
 *
 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
 */
function inspect () {
    if (!this.isValid()) {
        return 'moment.invalid(/* ' + this._i + ' */)';
    }
    var func = 'moment';
    var zone = '';
    if (!this.isLocal()) {
        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
        zone = 'Z';
    }
    var prefix = '[' + func + '("]';
    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
    var datetime = '-MM-DD[T]HH:mm:ss.SSS';
    var suffix = zone + '[")]';

    return this.format(prefix + year + datetime + suffix);
}

function format (inputString) {
    if (!inputString) {
        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
    }
    var output = formatMoment(this, inputString);
    return this.localeData().postformat(output);
}

function from (time, withoutSuffix) {
    if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
             createLocal(time).isValid())) {
        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
    } else {
        return this.localeData().invalidDate();
    }
}

function fromNow (withoutSuffix) {
    return this.from(createLocal(), withoutSuffix);
}

function to (time, withoutSuffix) {
    if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
             createLocal(time).isValid())) {
        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
    } else {
        return this.localeData().invalidDate();
    }
}

function toNow (withoutSuffix) {
    return this.to(createLocal(), withoutSuffix);
}

// If passed a locale key, it will set the locale for this
// instance.  Otherwise, it will return the locale configuration
// variables for this instance.
function locale (key) {
    var newLocaleData;

    if (key === undefined) {
        return this._locale._abbr;
    } else {
        newLocaleData = getLocale(key);
        if (newLocaleData != null) {
            this._locale = newLocaleData;
        }
        return this;
    }
}

var lang = deprecate(
    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
    function (key) {
        if (key === undefined) {
            return this.localeData();
        } else {
            return this.locale(key);
        }
    }
);

function localeData () {
    return this._locale;
}

function startOf (units) {
    units = normalizeUnits(units);
    // the following switch intentionally omits break keywords
    // to utilize falling through the cases.
    switch (units) {
        case 'year':
            this.month(0);
            /* falls through */
        case 'quarter':
        case 'month':
            this.date(1);
            /* falls through */
        case 'week':
        case 'isoWeek':
        case 'day':
        case 'date':
            this.hours(0);
            /* falls through */
        case 'hour':
            this.minutes(0);
            /* falls through */
        case 'minute':
            this.seconds(0);
            /* falls through */
        case 'second':
            this.milliseconds(0);
    }

    // weeks are a special case
    if (units === 'week') {
        this.weekday(0);
    }
    if (units === 'isoWeek') {
        this.isoWeekday(1);
    }

    // quarters are also special
    if (units === 'quarter') {
        this.month(Math.floor(this.month() / 3) * 3);
    }

    return this;
}

function endOf (units) {
    units = normalizeUnits(units);
    if (units === undefined || units === 'millisecond') {
        return this;
    }

    // 'date' is an alias for 'day', so it should be considered as such.
    if (units === 'date') {
        units = 'day';
    }

    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
}

function valueOf () {
    return this._d.valueOf() - ((this._offset || 0) * 60000);
}

function unix () {
    return Math.floor(this.valueOf() / 1000);
}

function toDate () {
    return new Date(this.valueOf());
}

function toArray () {
    var m = this;
    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
}

function toObject () {
    var m = this;
    return {
        years: m.year(),
        months: m.month(),
        date: m.date(),
        hours: m.hours(),
        minutes: m.minutes(),
        seconds: m.seconds(),
        milliseconds: m.milliseconds()
    };
}

function toJSON () {
    // new Date(NaN).toJSON() === null
    return this.isValid() ? this.toISOString() : null;
}

function isValid$2 () {
    return isValid(this);
}

function parsingFlags () {
    return extend({}, getParsingFlags(this));
}

function invalidAt () {
    return getParsingFlags(this).overflow;
}

function creationData() {
    return {
        input: this._i,
        format: this._f,
        locale: this._locale,
        isUTC: this._isUTC,
        strict: this._strict
    };
}

// FORMATTING

addFormatToken(0, ['gg', 2], 0, function () {
    return this.weekYear() % 100;
});

addFormatToken(0, ['GG', 2], 0, function () {
    return this.isoWeekYear() % 100;
});

function addWeekYearFormatToken (token, getter) {
    addFormatToken(0, [token, token.length], 0, getter);
}

addWeekYearFormatToken('gggg',     'weekYear');
addWeekYearFormatToken('ggggg',    'weekYear');
addWeekYearFormatToken('GGGG',  'isoWeekYear');
addWeekYearFormatToken('GGGGG', 'isoWeekYear');

// ALIASES

addUnitAlias('weekYear', 'gg');
addUnitAlias('isoWeekYear', 'GG');

// PRIORITY

addUnitPriority('weekYear', 1);
addUnitPriority('isoWeekYear', 1);


// PARSING

addRegexToken('G',      matchSigned);
addRegexToken('g',      matchSigned);
addRegexToken('GG',     match1to2, match2);
addRegexToken('gg',     match1to2, match2);
addRegexToken('GGGG',   match1to4, match4);
addRegexToken('gggg',   match1to4, match4);
addRegexToken('GGGGG',  match1to6, match6);
addRegexToken('ggggg',  match1to6, match6);

addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
    week[token.substr(0, 2)] = toInt(input);
});

addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
    week[token] = hooks.parseTwoDigitYear(input);
});

// MOMENTS

function getSetWeekYear (input) {
    return getSetWeekYearHelper.call(this,
            input,
            this.week(),
            this.weekday(),
            this.localeData()._week.dow,
            this.localeData()._week.doy);
}

function getSetISOWeekYear (input) {
    return getSetWeekYearHelper.call(this,
            input, this.isoWeek(), this.isoWeekday(), 1, 4);
}

function getISOWeeksInYear () {
    return weeksInYear(this.year(), 1, 4);
}

function getWeeksInYear () {
    var weekInfo = this.localeData()._week;
    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
}

function getSetWeekYearHelper(input, week, weekday, dow, doy) {
    var weeksTarget;
    if (input == null) {
        return weekOfYear(this, dow, doy).year;
    } else {
        weeksTarget = weeksInYear(input, dow, doy);
        if (week > weeksTarget) {
            week = weeksTarget;
        }
        return setWeekAll.call(this, input, week, weekday, dow, doy);
    }
}

function setWeekAll(weekYear, week, weekday, dow, doy) {
    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

    this.year(date.getUTCFullYear());
    this.month(date.getUTCMonth());
    this.date(date.getUTCDate());
    return this;
}

// FORMATTING

addFormatToken('Q', 0, 'Qo', 'quarter');

// ALIASES

addUnitAlias('quarter', 'Q');

// PRIORITY

addUnitPriority('quarter', 7);

// PARSING

addRegexToken('Q', match1);
addParseToken('Q', function (input, array) {
    array[MONTH] = (toInt(input) - 1) * 3;
});

// MOMENTS

function getSetQuarter (input) {
    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
}

// FORMATTING

addFormatToken('D', ['DD', 2], 'Do', 'date');

// ALIASES

addUnitAlias('date', 'D');

// PRIOROITY
addUnitPriority('date', 9);

// PARSING

addRegexToken('D',  match1to2);
addRegexToken('DD', match1to2, match2);
addRegexToken('Do', function (isStrict, locale) {
    // TODO: Remove "ordinalParse" fallback in next major release.
    return isStrict ?
      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
      locale._dayOfMonthOrdinalParseLenient;
});

addParseToken(['D', 'DD'], DATE);
addParseToken('Do', function (input, array) {
    array[DATE] = toInt(input.match(match1to2)[0]);
});

// MOMENTS

var getSetDayOfMonth = makeGetSet('Date', true);

// FORMATTING

addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

// ALIASES

addUnitAlias('dayOfYear', 'DDD');

// PRIORITY
addUnitPriority('dayOfYear', 4);

// PARSING

addRegexToken('DDD',  match1to3);
addRegexToken('DDDD', match3);
addParseToken(['DDD', 'DDDD'], function (input, array, config) {
    config._dayOfYear = toInt(input);
});

// HELPERS

// MOMENTS

function getSetDayOfYear (input) {
    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
}

// FORMATTING

addFormatToken('m', ['mm', 2], 0, 'minute');

// ALIASES

addUnitAlias('minute', 'm');

// PRIORITY

addUnitPriority('minute', 14);

// PARSING

addRegexToken('m',  match1to2);
addRegexToken('mm', match1to2, match2);
addParseToken(['m', 'mm'], MINUTE);

// MOMENTS

var getSetMinute = makeGetSet('Minutes', false);

// FORMATTING

addFormatToken('s', ['ss', 2], 0, 'second');

// ALIASES

addUnitAlias('second', 's');

// PRIORITY

addUnitPriority('second', 15);

// PARSING

addRegexToken('s',  match1to2);
addRegexToken('ss', match1to2, match2);
addParseToken(['s', 'ss'], SECOND);

// MOMENTS

var getSetSecond = makeGetSet('Seconds', false);

// FORMATTING

addFormatToken('S', 0, 0, function () {
    return ~~(this.millisecond() / 100);
});

addFormatToken(0, ['SS', 2], 0, function () {
    return ~~(this.millisecond() / 10);
});

addFormatToken(0, ['SSS', 3], 0, 'millisecond');
addFormatToken(0, ['SSSS', 4], 0, function () {
    return this.millisecond() * 10;
});
addFormatToken(0, ['SSSSS', 5], 0, function () {
    return this.millisecond() * 100;
});
addFormatToken(0, ['SSSSSS', 6], 0, function () {
    return this.millisecond() * 1000;
});
addFormatToken(0, ['SSSSSSS', 7], 0, function () {
    return this.millisecond() * 10000;
});
addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
    return this.millisecond() * 100000;
});
addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
    return this.millisecond() * 1000000;
});


// ALIASES

addUnitAlias('millisecond', 'ms');

// PRIORITY

addUnitPriority('millisecond', 16);

// PARSING

addRegexToken('S',    match1to3, match1);
addRegexToken('SS',   match1to3, match2);
addRegexToken('SSS',  match1to3, match3);

var token;
for (token = 'SSSS'; token.length <= 9; token += 'S') {
    addRegexToken(token, matchUnsigned);
}

function parseMs(input, array) {
    array[MILLISECOND] = toInt(('0.' + input) * 1000);
}

for (token = 'S'; token.length <= 9; token += 'S') {
    addParseToken(token, parseMs);
}
// MOMENTS

var getSetMillisecond = makeGetSet('Milliseconds', false);

// FORMATTING

addFormatToken('z',  0, 0, 'zoneAbbr');
addFormatToken('zz', 0, 0, 'zoneName');

// MOMENTS

function getZoneAbbr () {
    return this._isUTC ? 'UTC' : '';
}

function getZoneName () {
    return this._isUTC ? 'Coordinated Universal Time' : '';
}

var proto = Moment.prototype;

proto.add               = add;
proto.calendar          = calendar$1;
proto.clone             = clone;
proto.diff              = diff;
proto.endOf             = endOf;
proto.format            = format;
proto.from              = from;
proto.fromNow           = fromNow;
proto.to                = to;
proto.toNow             = toNow;
proto.get               = stringGet;
proto.invalidAt         = invalidAt;
proto.isAfter           = isAfter;
proto.isBefore          = isBefore;
proto.isBetween         = isBetween;
proto.isSame            = isSame;
proto.isSameOrAfter     = isSameOrAfter;
proto.isSameOrBefore    = isSameOrBefore;
proto.isValid           = isValid$2;
proto.lang              = lang;
proto.locale            = locale;
proto.localeData        = localeData;
proto.max               = prototypeMax;
proto.min               = prototypeMin;
proto.parsingFlags      = parsingFlags;
proto.set               = stringSet;
proto.startOf           = startOf;
proto.subtract          = subtract;
proto.toArray           = toArray;
proto.toObject          = toObject;
proto.toDate            = toDate;
proto.toISOString       = toISOString;
proto.inspect           = inspect;
proto.toJSON            = toJSON;
proto.toString          = toString;
proto.unix              = unix;
proto.valueOf           = valueOf;
proto.creationData      = creationData;

// Year
proto.year       = getSetYear;
proto.isLeapYear = getIsLeapYear;

// Week Year
proto.weekYear    = getSetWeekYear;
proto.isoWeekYear = getSetISOWeekYear;

// Quarter
proto.quarter = proto.quarters = getSetQuarter;

// Month
proto.month       = getSetMonth;
proto.daysInMonth = getDaysInMonth;

// Week
proto.week           = proto.weeks        = getSetWeek;
proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
proto.weeksInYear    = getWeeksInYear;
proto.isoWeeksInYear = getISOWeeksInYear;

// Day
proto.date       = getSetDayOfMonth;
proto.day        = proto.days             = getSetDayOfWeek;
proto.weekday    = getSetLocaleDayOfWeek;
proto.isoWeekday = getSetISODayOfWeek;
proto.dayOfYear  = getSetDayOfYear;

// Hour
proto.hour = proto.hours = getSetHour;

// Minute
proto.minute = proto.minutes = getSetMinute;

// Second
proto.second = proto.seconds = getSetSecond;

// Millisecond
proto.millisecond = proto.milliseconds = getSetMillisecond;

// Offset
proto.utcOffset            = getSetOffset;
proto.utc                  = setOffsetToUTC;
proto.local                = setOffsetToLocal;
proto.parseZone            = setOffsetToParsedOffset;
proto.hasAlignedHourOffset = hasAlignedHourOffset;
proto.isDST                = isDaylightSavingTime;
proto.isLocal              = isLocal;
proto.isUtcOffset          = isUtcOffset;
proto.isUtc                = isUtc;
proto.isUTC                = isUtc;

// Timezone
proto.zoneAbbr = getZoneAbbr;
proto.zoneName = getZoneName;

// Deprecations
proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

function createUnix (input) {
    return createLocal(input * 1000);
}

function createInZone () {
    return createLocal.apply(null, arguments).parseZone();
}

function preParsePostFormat (string) {
    return string;
}

var proto$1 = Locale.prototype;

proto$1.calendar        = calendar;
proto$1.longDateFormat  = longDateFormat;
proto$1.invalidDate     = invalidDate;
proto$1.ordinal         = ordinal;
proto$1.preparse        = preParsePostFormat;
proto$1.postformat      = preParsePostFormat;
proto$1.relativeTime    = relativeTime;
proto$1.pastFuture      = pastFuture;
proto$1.set             = set;

// Month
proto$1.months            =        localeMonths;
proto$1.monthsShort       =        localeMonthsShort;
proto$1.monthsParse       =        localeMonthsParse;
proto$1.monthsRegex       = monthsRegex;
proto$1.monthsShortRegex  = monthsShortRegex;

// Week
proto$1.week = localeWeek;
proto$1.firstDayOfYear = localeFirstDayOfYear;
proto$1.firstDayOfWeek = localeFirstDayOfWeek;

// Day of Week
proto$1.weekdays       =        localeWeekdays;
proto$1.weekdaysMin    =        localeWeekdaysMin;
proto$1.weekdaysShort  =        localeWeekdaysShort;
proto$1.weekdaysParse  =        localeWeekdaysParse;

proto$1.weekdaysRegex       =        weekdaysRegex;
proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
proto$1.weekdaysMinRegex    =        weekdaysMinRegex;

// Hours
proto$1.isPM = localeIsPM;
proto$1.meridiem = localeMeridiem;

function get$1 (format, index, field, setter) {
    var locale = getLocale();
    var utc = createUTC().set(setter, index);
    return locale[field](utc, format);
}

function listMonthsImpl (format, index, field) {
    if (isNumber(format)) {
        index = format;
        format = undefined;
    }

    format = format || '';

    if (index != null) {
        return get$1(format, index, field, 'month');
    }

    var i;
    var out = [];
    for (i = 0; i < 12; i++) {
        out[i] = get$1(format, i, field, 'month');
    }
    return out;
}

// ()
// (5)
// (fmt, 5)
// (fmt)
// (true)
// (true, 5)
// (true, fmt, 5)
// (true, fmt)
function listWeekdaysImpl (localeSorted, format, index, field) {
    if (typeof localeSorted === 'boolean') {
        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';
    } else {
        format = localeSorted;
        index = format;
        localeSorted = false;

        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';
    }

    var locale = getLocale(),
        shift = localeSorted ? locale._week.dow : 0;

    if (index != null) {
        return get$1(format, (index + shift) % 7, field, 'day');
    }

    var i;
    var out = [];
    for (i = 0; i < 7; i++) {
        out[i] = get$1(format, (i + shift) % 7, field, 'day');
    }
    return out;
}

function listMonths (format, index) {
    return listMonthsImpl(format, index, 'months');
}

function listMonthsShort (format, index) {
    return listMonthsImpl(format, index, 'monthsShort');
}

function listWeekdays (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
}

function listWeekdaysShort (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
}

function listWeekdaysMin (localeSorted, format, index) {
    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
}

getSetGlobalLocale('en', {
    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
    ordinal : function (number) {
        var b = number % 10,
            output = (toInt(number % 100 / 10) === 1) ? 'th' :
            (b === 1) ? 'st' :
            (b === 2) ? 'nd' :
            (b === 3) ? 'rd' : 'th';
        return number + output;
    }
});

// Side effect imports
hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);

var mathAbs = Math.abs;

function abs () {
    var data           = this._data;

    this._milliseconds = mathAbs(this._milliseconds);
    this._days         = mathAbs(this._days);
    this._months       = mathAbs(this._months);

    data.milliseconds  = mathAbs(data.milliseconds);
    data.seconds       = mathAbs(data.seconds);
    data.minutes       = mathAbs(data.minutes);
    data.hours         = mathAbs(data.hours);
    data.months        = mathAbs(data.months);
    data.years         = mathAbs(data.years);

    return this;
}

function addSubtract$1 (duration, input, value, direction) {
    var other = createDuration(input, value);

    duration._milliseconds += direction * other._milliseconds;
    duration._days         += direction * other._days;
    duration._months       += direction * other._months;

    return duration._bubble();
}

// supports only 2.0-style add(1, 's') or add(duration)
function add$1 (input, value) {
    return addSubtract$1(this, input, value, 1);
}

// supports only 2.0-style subtract(1, 's') or subtract(duration)
function subtract$1 (input, value) {
    return addSubtract$1(this, input, value, -1);
}

function absCeil (number) {
    if (number < 0) {
        return Math.floor(number);
    } else {
        return Math.ceil(number);
    }
}

function bubble () {
    var milliseconds = this._milliseconds;
    var days         = this._days;
    var months       = this._months;
    var data         = this._data;
    var seconds, minutes, hours, years, monthsFromDays;

    // if we have a mix of positive and negative values, bubble down first
    // check: https://github.com/moment/moment/issues/2166
    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
            (milliseconds <= 0 && days <= 0 && months <= 0))) {
        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
        days = 0;
        months = 0;
    }

    // The following code bubbles up values, see the tests for
    // examples of what that means.
    data.milliseconds = milliseconds % 1000;

    seconds           = absFloor(milliseconds / 1000);
    data.seconds      = seconds % 60;

    minutes           = absFloor(seconds / 60);
    data.minutes      = minutes % 60;

    hours             = absFloor(minutes / 60);
    data.hours        = hours % 24;

    days += absFloor(hours / 24);

    // convert days to months
    monthsFromDays = absFloor(daysToMonths(days));
    months += monthsFromDays;
    days -= absCeil(monthsToDays(monthsFromDays));

    // 12 months -> 1 year
    years = absFloor(months / 12);
    months %= 12;

    data.days   = days;
    data.months = months;
    data.years  = years;

    return this;
}

function daysToMonths (days) {
    // 400 years have 146097 days (taking into account leap year rules)
    // 400 years have 12 months === 4800
    return days * 4800 / 146097;
}

function monthsToDays (months) {
    // the reverse of daysToMonths
    return months * 146097 / 4800;
}

function as (units) {
    if (!this.isValid()) {
        return NaN;
    }
    var days;
    var months;
    var milliseconds = this._milliseconds;

    units = normalizeUnits(units);

    if (units === 'month' || units === 'year') {
        days   = this._days   + milliseconds / 864e5;
        months = this._months + daysToMonths(days);
        return units === 'month' ? months : months / 12;
    } else {
        // handle milliseconds separately because of floating point math errors (issue #1867)
        days = this._days + Math.round(monthsToDays(this._months));
        switch (units) {
            case 'week'   : return days / 7     + milliseconds / 6048e5;
            case 'day'    : return days         + milliseconds / 864e5;
            case 'hour'   : return days * 24    + milliseconds / 36e5;
            case 'minute' : return days * 1440  + milliseconds / 6e4;
            case 'second' : return days * 86400 + milliseconds / 1000;
            // Math.floor prevents floating point math errors here
            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
            default: throw new Error('Unknown unit ' + units);
        }
    }
}

// TODO: Use this.as('ms')?
function valueOf$1 () {
    if (!this.isValid()) {
        return NaN;
    }
    return (
        this._milliseconds +
        this._days * 864e5 +
        (this._months % 12) * 2592e6 +
        toInt(this._months / 12) * 31536e6
    );
}

function makeAs (alias) {
    return function () {
        return this.as(alias);
    };
}

var asMilliseconds = makeAs('ms');
var asSeconds      = makeAs('s');
var asMinutes      = makeAs('m');
var asHours        = makeAs('h');
var asDays         = makeAs('d');
var asWeeks        = makeAs('w');
var asMonths       = makeAs('M');
var asYears        = makeAs('y');

function clone$1 () {
    return createDuration(this);
}

function get$2 (units) {
    units = normalizeUnits(units);
    return this.isValid() ? this[units + 's']() : NaN;
}

function makeGetter(name) {
    return function () {
        return this.isValid() ? this._data[name] : NaN;
    };
}

var milliseconds = makeGetter('milliseconds');
var seconds      = makeGetter('seconds');
var minutes      = makeGetter('minutes');
var hours        = makeGetter('hours');
var days         = makeGetter('days');
var months       = makeGetter('months');
var years        = makeGetter('years');

function weeks () {
    return absFloor(this.days() / 7);
}

var round = Math.round;
var thresholds = {
    ss: 44,         // a few seconds to seconds
    s : 45,         // seconds to minute
    m : 45,         // minutes to hour
    h : 22,         // hours to day
    d : 26,         // days to month
    M : 11          // months to year
};

// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
}

function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
    var duration = createDuration(posNegDuration).abs();
    var seconds  = round(duration.as('s'));
    var minutes  = round(duration.as('m'));
    var hours    = round(duration.as('h'));
    var days     = round(duration.as('d'));
    var months   = round(duration.as('M'));
    var years    = round(duration.as('y'));

    var a = seconds <= thresholds.ss && ['s', seconds]  ||
            seconds < thresholds.s   && ['ss', seconds] ||
            minutes <= 1             && ['m']           ||
            minutes < thresholds.m   && ['mm', minutes] ||
            hours   <= 1             && ['h']           ||
            hours   < thresholds.h   && ['hh', hours]   ||
            days    <= 1             && ['d']           ||
            days    < thresholds.d   && ['dd', days]    ||
            months  <= 1             && ['M']           ||
            months  < thresholds.M   && ['MM', months]  ||
            years   <= 1             && ['y']           || ['yy', years];

    a[2] = withoutSuffix;
    a[3] = +posNegDuration > 0;
    a[4] = locale;
    return substituteTimeAgo.apply(null, a);
}

// This function allows you to set the rounding function for relative time strings
function getSetRelativeTimeRounding (roundingFunction) {
    if (roundingFunction === undefined) {
        return round;
    }
    if (typeof(roundingFunction) === 'function') {
        round = roundingFunction;
        return true;
    }
    return false;
}

// This function allows you to set a threshold for relative time strings
function getSetRelativeTimeThreshold (threshold, limit) {
    if (thresholds[threshold] === undefined) {
        return false;
    }
    if (limit === undefined) {
        return thresholds[threshold];
    }
    thresholds[threshold] = limit;
    if (threshold === 's') {
        thresholds.ss = limit - 1;
    }
    return true;
}

function humanize (withSuffix) {
    if (!this.isValid()) {
        return this.localeData().invalidDate();
    }

    var locale = this.localeData();
    var output = relativeTime$1(this, !withSuffix, locale);

    if (withSuffix) {
        output = locale.pastFuture(+this, output);
    }

    return locale.postformat(output);
}

var abs$1 = Math.abs;

function sign(x) {
    return ((x > 0) - (x < 0)) || +x;
}

function toISOString$1() {
    // for ISO strings we do not use the normal bubbling rules:
    //  * milliseconds bubble up until they become hours
    //  * days do not bubble at all
    //  * months bubble up until they become years
    // This is because there is no context-free conversion between hours and days
    // (think of clock changes)
    // and also not between days and months (28-31 days per month)
    if (!this.isValid()) {
        return this.localeData().invalidDate();
    }

    var seconds = abs$1(this._milliseconds) / 1000;
    var days         = abs$1(this._days);
    var months       = abs$1(this._months);
    var minutes, hours, years;

    // 3600 seconds -> 60 minutes -> 1 hour
    minutes           = absFloor(seconds / 60);
    hours             = absFloor(minutes / 60);
    seconds %= 60;
    minutes %= 60;

    // 12 months -> 1 year
    years  = absFloor(months / 12);
    months %= 12;


    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
    var Y = years;
    var M = months;
    var D = days;
    var h = hours;
    var m = minutes;
    var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
    var total = this.asSeconds();

    if (!total) {
        // this is the same as C#'s (Noda) and python (isodate)...
        // but not other JS (goog.date)
        return 'P0D';
    }

    var totalSign = total < 0 ? '-' : '';
    var ymSign = sign(this._months) !== sign(total) ? '-' : '';
    var daysSign = sign(this._days) !== sign(total) ? '-' : '';
    var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';

    return totalSign + 'P' +
        (Y ? ymSign + Y + 'Y' : '') +
        (M ? ymSign + M + 'M' : '') +
        (D ? daysSign + D + 'D' : '') +
        ((h || m || s) ? 'T' : '') +
        (h ? hmsSign + h + 'H' : '') +
        (m ? hmsSign + m + 'M' : '') +
        (s ? hmsSign + s + 'S' : '');
}

var proto$2 = Duration.prototype;

proto$2.isValid        = isValid$1;
proto$2.abs            = abs;
proto$2.add            = add$1;
proto$2.subtract       = subtract$1;
proto$2.as             = as;
proto$2.asMilliseconds = asMilliseconds;
proto$2.asSeconds      = asSeconds;
proto$2.asMinutes      = asMinutes;
proto$2.asHours        = asHours;
proto$2.asDays         = asDays;
proto$2.asWeeks        = asWeeks;
proto$2.asMonths       = asMonths;
proto$2.asYears        = asYears;
proto$2.valueOf        = valueOf$1;
proto$2._bubble        = bubble;
proto$2.clone          = clone$1;
proto$2.get            = get$2;
proto$2.milliseconds   = milliseconds;
proto$2.seconds        = seconds;
proto$2.minutes        = minutes;
proto$2.hours          = hours;
proto$2.days           = days;
proto$2.weeks          = weeks;
proto$2.months         = months;
proto$2.years          = years;
proto$2.humanize       = humanize;
proto$2.toISOString    = toISOString$1;
proto$2.toString       = toISOString$1;
proto$2.toJSON         = toISOString$1;
proto$2.locale         = locale;
proto$2.localeData     = localeData;

// Deprecations
proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
proto$2.lang = lang;

// Side effect imports

// FORMATTING

addFormatToken('X', 0, 0, 'unix');
addFormatToken('x', 0, 0, 'valueOf');

// PARSING

addRegexToken('x', matchSigned);
addRegexToken('X', matchTimestamp);
addParseToken('X', function (input, array, config) {
    config._d = new Date(parseFloat(input, 10) * 1000);
});
addParseToken('x', function (input, array, config) {
    config._d = new Date(toInt(input));
});

// Side effect imports


hooks.version = '2.20.1';

setHookCallback(createLocal);

hooks.fn                    = proto;
hooks.min                   = min;
hooks.max                   = max;
hooks.now                   = now;
hooks.utc                   = createUTC;
hooks.unix                  = createUnix;
hooks.months                = listMonths;
hooks.isDate                = isDate;
hooks.locale                = getSetGlobalLocale;
hooks.invalid               = createInvalid;
hooks.duration              = createDuration;
hooks.isMoment              = isMoment;
hooks.weekdays              = listWeekdays;
hooks.parseZone             = createInZone;
hooks.localeData            = getLocale;
hooks.isDuration            = isDuration;
hooks.monthsShort           = listMonthsShort;
hooks.weekdaysMin           = listWeekdaysMin;
hooks.defineLocale          = defineLocale;
hooks.updateLocale          = updateLocale;
hooks.locales               = listLocales;
hooks.weekdaysShort         = listWeekdaysShort;
hooks.normalizeUnits        = normalizeUnits;
hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
hooks.calendarFormat        = getCalendarFormat;
hooks.prototype             = proto;

// currently HTML5 input type only supports 24-hour formats
hooks.HTML5_FMT = {
    DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
    DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
    DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
    DATE: 'YYYY-MM-DD',                             // <input type="date" />
    TIME: 'HH:mm',                                  // <input type="time" />
    TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
    TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
    WEEK: 'YYYY-[W]WW',                             // <input type="week" />
    MONTH: 'YYYY-MM'                                // <input type="month" />
};

return hooks;

})));


/*** EXPORTS FROM exports-to-window-loader ***/
window['moment'] = __webpack_require__(63);
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(206)(module)))

/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var aFunction = __webpack_require__(150);
var toObject = __webpack_require__(62);
var fails = __webpack_require__(29);
var nativeSort = [].sort;
var test = [1, 2, 3];

// IE8-
var FAILS_ON_UNDEFINED = fails(function () {
  test.sort(undefined);
});
// V8 bug
var FAILS_ON_NULL = fails(function () {
  test.sort(null);
});
// Old WebKit
var SLOPPY_METHOD = __webpack_require__(126)('sort');

var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || SLOPPY_METHOD;

// `Array.prototype.sort` method
// https://tc39.github.io/ecma262/#sec-array.prototype.sort
__webpack_require__(22)({ target: 'Array', proto: true, forced: FORCED }, {
  sort: function sort(comparefn) {
    return comparefn === undefined
      ? nativeSort.call(toObject(this))
      : nativeSort.call(toObject(this), aFunction(comparefn));
  }
});


/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var hide = __webpack_require__(61);
var has = __webpack_require__(47);
var setGlobal = __webpack_require__(143);
var nativeFunctionToString = __webpack_require__(177);
var InternalStateModule = __webpack_require__(87);
var getInternalState = InternalStateModule.get;
var enforceInternalState = InternalStateModule.enforce;
var TEMPLATE = String(nativeFunctionToString).split('toString');

__webpack_require__(98)('inspectSource', function (it) {
  return nativeFunctionToString.call(it);
});

(module.exports = function (O, key, value, options) {
  var unsafe = options ? !!options.unsafe : false;
  var simple = options ? !!options.enumerable : false;
  var noTargetGet = options ? !!options.noTargetGet : false;
  if (typeof value == 'function') {
    if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key);
    enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
  }
  if (O === global) {
    if (simple) O[key] = value;
    else setGlobal(key, value);
    return;
  } else if (!unsafe) {
    delete O[key];
  } else if (!noTargetGet && O[key]) {
    simple = true;
  }
  if (simple) O[key] = value;
  else hide(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
  return typeof this == 'function' && getInternalState(this).source || nativeFunctionToString.call(this);
});


/***/ }),
/* 66 */
/***/ (function(module, exports) {

function _taggedTemplateLiteral(strings, raw) {
  if (!raw) {
    raw = strings.slice(0);
  }

  return Object.freeze(Object.defineProperties(strings, {
    raw: {
      value: Object.freeze(raw)
    }
  }));
}

module.exports = _taggedTemplateLiteral;

/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(37);

__webpack_require__(105);

exports.__esModule = true;
exports.toSingleLine = toSingleLine;

var _array = __webpack_require__(3);

/* eslint-disable import/prefer-default-export */

/**
 * Tags a multiline string and return new one without line break characters and following spaces.
 *
 * @param {Array} strings Parts of the entire string without expressions.
 * @param {...String} expressions Expressions converted to strings, which are added to the entire string.
 * @returns {String}
 */
function toSingleLine(strings) {
  for (var _len = arguments.length, expressions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    expressions[_key - 1] = arguments[_key];
  }

  var result = (0, _array.arrayReduce)(strings, function (previousValue, currentValue, index) {
    var valueWithoutWhiteSpaces = currentValue.replace(/(?:\r?\n\s+)/g, '');
    var expressionForIndex = expressions[index] ? expressions[index] : '';
    return previousValue + valueWithoutWhiteSpaces + expressionForIndex;
  }, '');
  return result.trim();
}

/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(12);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(37);

exports.__esModule = true;
exports.toUpperCaseFirst = toUpperCaseFirst;
exports.equalsIgnoreCase = equalsIgnoreCase;
exports.randomString = randomString;
exports.isPercentValue = isPercentValue;
exports.substitute = substitute;
exports.stripTags = stripTags;

var _mixed = __webpack_require__(27);

/**
 * Convert string to upper case first letter.
 *
 * @param {String} string String to convert.
 * @returns {String}
 */
function toUpperCaseFirst(string) {
  return string[0].toUpperCase() + string.substr(1);
}
/**
 * Compare strings case insensitively.
 *
 * @param {...String} strings Strings to compare.
 * @returns {Boolean}
 */


function equalsIgnoreCase() {
  var unique = [];

  for (var _len = arguments.length, strings = new Array(_len), _key = 0; _key < _len; _key++) {
    strings[_key] = arguments[_key];
  }

  var length = strings.length;

  while (length) {
    length -= 1;
    var string = (0, _mixed.stringify)(strings[length]).toLowerCase();

    if (unique.indexOf(string) === -1) {
      unique.push(string);
    }
  }

  return unique.length === 1;
}
/**
 * Generates a random hex string. Used as namespace for Handsontable instance events.
 *
 * @return {String} Returns 16-long character random string (eq. `'92b1bfc74ec4'`).
 */


function randomString() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  }

  return s4() + s4() + s4() + s4();
}
/**
 * Checks if value is valid percent.
 *
 * @param {String} value
 * @returns {Boolean}
 */


function isPercentValue(value) {
  return /^([0-9][0-9]?%$)|(^100%$)/.test(value);
}
/**
 * Substitute strings placed beetwen square brackets into value defined in `variables` object. String names defined in
 * square brackets must be the same as property name of `variables` object.
 *
 * @param {String} template Template string.
 * @param {Object} variables Object which contains all available values which can be injected into template.
 * @returns {String}
 */


function substitute(template) {
  var variables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  return "".concat(template).replace(/(?:\\)?\[([^[\]]+)]/g, function (match, name) {
    if (match.charAt(0) === '\\') {
      return match.substr(1, match.length - 1);
    }

    return variables[name] === void 0 ? '' : variables[name];
  });
}

var STRIP_TAGS_REGEX = /<\/?\w+\/?>|<\w+[\s|/][^>]*>/gi;
/**
 * Strip any HTML tag from the string.
 *
 * @param  {String} string String to cut HTML from.
 * @return {String}
 */

function stripTags(string) {
  return "".concat(string).replace(STRIP_TAGS_REGEX, '');
}

/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {

// toObject with fallback for non-array-like ES3 strings
var IndexedObject = __webpack_require__(113);
var requireObjectCoercible = __webpack_require__(58);

module.exports = function (it) {
  return IndexedObject(requireObjectCoercible(it));
};


/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// `Map` constructor
// https://tc39.github.io/ecma262/#sec-map-objects
module.exports = __webpack_require__(125)('Map', function (get) {
  return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, __webpack_require__(192), true);


/***/ }),
/* 71 */
/***/ (function(module, exports) {

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

module.exports = _defineProperty;

/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.setBrowserMeta = setBrowserMeta;
exports.isChrome = isChrome;
exports.isEdge = isEdge;
exports.isIE = isIE;
exports.isIE8 = isIE8;
exports.isIE9 = isIE9;
exports.isMSBrowser = isMSBrowser;
exports.isMobileBrowser = isMobileBrowser;
exports.isSafari = isSafari;

var _object = __webpack_require__(4);

var tester = function tester(testerFunc) {
  var result = {
    value: false
  };

  result.test = function (ua, vendor) {
    result.value = testerFunc(ua, vendor);
  };

  return result;
};

var browsers = {
  chrome: tester(function (ua, vendor) {
    return /Chrome/.test(ua) && /Google/.test(vendor);
  }),
  edge: tester(function (ua) {
    return /Edge/.test(ua);
  }),
  ie: tester(function (ua) {
    return /Trident/.test(ua);
  }),
  // eslint-disable-next-line no-restricted-globals
  ie8: tester(function () {
    return !document.createTextNode('test').textContent;
  }),
  // eslint-disable-next-line no-restricted-globals
  ie9: tester(function () {
    return !!document.documentMode;
  }),
  mobile: tester(function (ua) {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
  }),
  safari: tester(function (ua, vendor) {
    return /Safari/.test(ua) && /Apple Computer/.test(vendor);
  })
};

function setBrowserMeta() {
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
      _ref$userAgent = _ref.userAgent,
      userAgent = _ref$userAgent === void 0 ? navigator.userAgent : _ref$userAgent,
      _ref$vendor = _ref.vendor,
      vendor = _ref$vendor === void 0 ? navigator.vendor : _ref$vendor;

  (0, _object.objectEach)(browsers, function (_ref2) {
    var test = _ref2.test;
    return void test(userAgent, vendor);
  });
}

setBrowserMeta();

function isChrome() {
  return browsers.chrome.value;
}

function isEdge() {
  return browsers.edge.value;
}

function isIE() {
  return browsers.ie.value;
}

function isIE8() {
  return browsers.ie8.value;
}

function isIE9() {
  return browsers.ie9.value;
}

function isMSBrowser() {
  return browsers.ie.value || browsers.edge.value;
}

function isMobileBrowser() {
  return browsers.mobile.value;
}

function isSafari() {
  return browsers.safari.value;
}

/***/ }),
/* 73 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(131);

__webpack_require__(30);

exports.__esModule = true;
exports.requestAnimationFrame = requestAnimationFrame;
exports.isClassListSupported = isClassListSupported;
exports.isTextContentSupported = isTextContentSupported;
exports.isGetComputedStyleSupported = isGetComputedStyleSupported;
exports.cancelAnimationFrame = cancelAnimationFrame;
exports.isTouchSupported = isTouchSupported;
exports.isWebComponentSupportedNatively = isWebComponentSupportedNatively;
exports.hasCaptionProblem = hasCaptionProblem;
exports.getComparisonFunction = getComparisonFunction;
exports.isPassiveEventSupported = isPassiveEventSupported;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

// https://gist.github.com/paulirish/1579671

/* eslint-disable no-restricted-globals */
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
var _requestAnimationFrame = window.requestAnimationFrame;
var _cancelAnimationFrame = window.cancelAnimationFrame;

for (var x = 0; x < vendors.length && !_requestAnimationFrame; ++x) {
  _requestAnimationFrame = window["".concat(vendors[x], "RequestAnimationFrame")];
  _cancelAnimationFrame = window["".concat(vendors[x], "CancelAnimationFrame")] || window["".concat(vendors[x], "CancelRequestAnimationFrame")];
}

if (!_requestAnimationFrame) {
  _requestAnimationFrame = function _requestAnimationFrame(callback) {
    var currTime = new Date().getTime();
    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    var id = window.setTimeout(function () {
      callback(currTime + timeToCall);
    }, timeToCall);
    lastTime = currTime + timeToCall;
    return id;
  };
}

if (!_cancelAnimationFrame) {
  _cancelAnimationFrame = function _cancelAnimationFrame(id) {
    clearTimeout(id);
  };
}
/**
 * Polyfill for requestAnimationFrame
 *
 * @param {Function} callback
 * @returns {Number}
 */


function requestAnimationFrame(callback) {
  return _requestAnimationFrame.call(window, callback);
}

function isClassListSupported() {
  return !!document.documentElement.classList;
}

function isTextContentSupported() {
  return !!document.createTextNode('test').textContent;
}

function isGetComputedStyleSupported() {
  return !!window.getComputedStyle;
}
/**
 * Polyfill for cancelAnimationFrame
 *
 * @param {Number} id
 */


function cancelAnimationFrame(id) {
  _cancelAnimationFrame.call(window, id);
}

function isTouchSupported() {
  return 'ontouchstart' in window;
}
/**
 * Checks if browser is support web components natively
 *
 * @returns {Boolean}
 */


function isWebComponentSupportedNatively() {
  var test = document.createElement('div');
  return !!(test.createShadowRoot && test.createShadowRoot.toString().match(/\[native code\]/));
}

var _hasCaptionProblem;

function detectCaptionProblem() {
  var TABLE = document.createElement('TABLE');
  TABLE.style.borderSpacing = '0';
  TABLE.style.borderWidth = '0';
  TABLE.style.padding = '0';
  var TBODY = document.createElement('TBODY');
  TABLE.appendChild(TBODY);
  TBODY.appendChild(document.createElement('TR'));
  TBODY.firstChild.appendChild(document.createElement('TD'));
  TBODY.firstChild.firstChild.innerHTML = '<tr><td>t<br>t</td></tr>';
  var CAPTION = document.createElement('CAPTION');
  CAPTION.innerHTML = 'c<br>c<br>c<br>c';
  CAPTION.style.padding = '0';
  CAPTION.style.margin = '0';
  TABLE.insertBefore(CAPTION, TBODY);
  document.body.appendChild(TABLE);
  _hasCaptionProblem = TABLE.offsetHeight < 2 * TABLE.lastChild.offsetHeight; // boolean

  document.body.removeChild(TABLE);
}

function hasCaptionProblem() {
  if (_hasCaptionProblem === void 0) {
    detectCaptionProblem();
  }

  return _hasCaptionProblem;
}

var comparisonFunction;
/**
 * Get string comparison function for sorting purposes. It supports multilingual string comparison base on Internationalization API.
 *
 * @param {String} [language]
 * @param {Object} [options]
 * @returns {*}
 */

function getComparisonFunction(language) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  if (comparisonFunction) {
    return comparisonFunction;
  }

  if ((typeof Intl === "undefined" ? "undefined" : (0, _typeof2.default)(Intl)) === 'object') {
    comparisonFunction = new Intl.Collator(language, options).compare;
  } else if (typeof String.prototype.localeCompare === 'function') {
    comparisonFunction = function comparisonFunction(a, b) {
      return "".concat(a).localeCompare(b);
    };
  } else {
    comparisonFunction = function comparisonFunction(a, b) {
      if (a === b) {
        return 0;
      }

      return a > b ? -1 : 1;
    };
  }

  return comparisonFunction;
}

var passiveSupported;
/**
 * Checks if browser supports passive events.
 *
 * @returns {Boolean}
 */

function isPassiveEventSupported() {
  if (passiveSupported !== void 0) {
    return passiveSupported;
  }

  try {
    var options = {
      get passive() {
        passiveSupported = true;
      }

    }; // eslint-disable-next-line no-restricted-globals

    window.addEventListener('test', options, options); // eslint-disable-next-line no-restricted-globals

    window.removeEventListener('test', options, options);
  } catch (err) {
    passiveSupported = false;
  }

  return passiveSupported;
}

/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _console = __webpack_require__(55);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _core = _interopRequireDefault(__webpack_require__(326));

var registeredOverlays = {};
/**
 * Creates an overlay over the original Walkontable instance. The overlay renders the clone of the original Walkontable
 * and (optionally) implements behavior needed for native horizontal and vertical scrolling.
 *
 * @class Overlay
 */

var Overlay =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(Overlay, null, [{
    key: "registerOverlay",

    /**
     * Register overlay class.
     *
     * @param {String} type Overlay type, one of the CLONE_TYPES value
     * @param {Overlay} overlayClass Overlay class extended from base overlay class {@link Overlay}
     */
    value: function registerOverlay(type, overlayClass) {
      if (Overlay.CLONE_TYPES.indexOf(type) === -1) {
        throw new Error("Unsupported overlay (".concat(type, ")."));
      }

      registeredOverlays[type] = overlayClass;
    }
    /**
     * Create new instance of overlay type.
     *
     * @param {String} type Overlay type, one of the CLONE_TYPES value
     * @param {Walkontable} wot Walkontable instance
     */

  }, {
    key: "createOverlay",
    value: function createOverlay(type, wot) {
      return new registeredOverlays[type](wot);
    }
    /**
     * Check if specified overlay was registered.
     *
     * @param {String} type Overlay type, one of the CLONE_TYPES value
     * @returns {Boolean}
     */

  }, {
    key: "hasOverlay",
    value: function hasOverlay(type) {
      return registeredOverlays[type] !== void 0;
    }
    /**
     * Checks if overlay object (`overlay`) is instance of overlay type (`type`).
     *
     * @param {Overlay} overlay Overlay object
     * @param {String} type Overlay type, one of the CLONE_TYPES value
     * @returns {Boolean}
     */

  }, {
    key: "isOverlayTypeOf",
    value: function isOverlayTypeOf(overlay, type) {
      if (!overlay || !registeredOverlays[type]) {
        return false;
      }

      return overlay instanceof registeredOverlays[type];
    }
    /**
     * @param {Walkontable} wotInstance
     */

  }, {
    key: "CLONE_TOP",

    /**
     * @type {String}
     */
    get: function get() {
      return 'top';
    }
    /**
     * @type {String}
     */

  }, {
    key: "CLONE_BOTTOM",
    get: function get() {
      return 'bottom';
    }
    /**
     * @type {String}
     */

  }, {
    key: "CLONE_LEFT",
    get: function get() {
      return 'left';
    }
    /**
     * @type {String}
     */

  }, {
    key: "CLONE_TOP_LEFT_CORNER",
    get: function get() {
      return 'top_left_corner';
    }
    /**
     * @type {String}
     */

  }, {
    key: "CLONE_BOTTOM_LEFT_CORNER",
    get: function get() {
      return 'bottom_left_corner';
    }
    /**
     * @type {String}
     */

  }, {
    key: "CLONE_DEBUG",
    get: function get() {
      return 'debug';
    }
    /**
     * List of all availables clone types
     *
     * @type {Array}
     */

  }, {
    key: "CLONE_TYPES",
    get: function get() {
      return [Overlay.CLONE_TOP, Overlay.CLONE_BOTTOM, Overlay.CLONE_LEFT, Overlay.CLONE_TOP_LEFT_CORNER, Overlay.CLONE_BOTTOM_LEFT_CORNER, Overlay.CLONE_DEBUG];
    }
  }]);

  function Overlay(wotInstance) {
    (0, _classCallCheck2.default)(this, Overlay);
    (0, _object.defineGetter)(this, 'wot', wotInstance, {
      writable: false
    });
    var _this$wot$wtTable = this.wot.wtTable,
        TABLE = _this$wot$wtTable.TABLE,
        hider = _this$wot$wtTable.hider,
        spreader = _this$wot$wtTable.spreader,
        holder = _this$wot$wtTable.holder,
        wtRootElement = _this$wot$wtTable.wtRootElement; // legacy support, deprecated in the future

    this.instance = this.wot;
    this.type = '';
    this.mainTableScrollableElement = null;
    this.TABLE = TABLE;
    this.hider = hider;
    this.spreader = spreader;
    this.holder = holder;
    this.wtRootElement = wtRootElement;
    this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
    this.areElementSizesAdjusted = false;
    this.updateStateOfRendering();
  }
  /**
   * Update internal state of object with an information about the need of full rendering of the overlay.
   *
   * @returns {Boolean} Returns `true` if the state has changed since the last check.
   */


  (0, _createClass2.default)(Overlay, [{
    key: "updateStateOfRendering",
    value: function updateStateOfRendering() {
      var previousState = this.needFullRender;
      this.needFullRender = this.shouldBeRendered();
      var changed = previousState !== this.needFullRender;

      if (changed && !this.needFullRender) {
        this.reset();
      }

      return changed;
    }
    /**
     * Checks if overlay should be fully rendered
     *
     * @returns {Boolean}
     */

  }, {
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      return true;
    }
    /**
     * Update the trimming container.
     */

  }, {
    key: "updateTrimmingContainer",
    value: function updateTrimmingContainer() {
      this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
    }
    /**
     * Update the main scrollable element.
     */

  }, {
    key: "updateMainScrollableElement",
    value: function updateMainScrollableElement() {
      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootWindow = _this$wot.rootWindow;

      if (rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden') {
        this.mainTableScrollableElement = this.wot.wtTable.holder;
      } else {
        this.mainTableScrollableElement = (0, _element.getScrollableElement)(wtTable.TABLE);
      }
    }
    /**
     * Calculates coordinates of the provided element, relative to the root Handsontable element.
     * NOTE: The element needs to be a child of the overlay in order for the method to work correctly.
     *
     * @param {HTMLElement} element The cell element to calculate the position for.
     * @param {Number} rowIndex Visual row index.
     * @param {Number} columnIndex Visual column index.
     * @returns {{top: Number, left: Number}|undefined}
     */

  }, {
    key: "getRelativeCellPosition",
    value: function getRelativeCellPosition(element, rowIndex, columnIndex) {
      if (this.clone.wtTable.holder.contains(element) === false) {
        (0, _console.warn)("The provided element is not a child of the ".concat(this.type, " overlay"));
        return;
      }

      var windowScroll = this.mainTableScrollableElement === this.wot.rootWindow;
      var fixedColumn = columnIndex < this.wot.getSetting('fixedColumnsLeft');
      var fixedRowTop = rowIndex < this.wot.getSetting('fixedRowsTop');
      var fixedRowBottom = rowIndex >= this.wot.getSetting('totalRows') - this.wot.getSetting('fixedRowsBottom');
      var spreaderOffset = {
        left: this.clone.wtTable.spreader.offsetLeft,
        top: this.clone.wtTable.spreader.offsetTop
      };
      var elementOffset = {
        left: element.offsetLeft,
        top: element.offsetTop
      };
      var offsetObject = null;

      if (windowScroll) {
        offsetObject = this.getRelativeCellPositionWithinWindow(fixedRowTop, fixedColumn, elementOffset, spreaderOffset);
      } else {
        offsetObject = this.getRelativeCellPositionWithinHolder(fixedRowTop, fixedRowBottom, fixedColumn, elementOffset, spreaderOffset);
      }

      return offsetObject;
    }
    /**
     * Calculates coordinates of the provided element, relative to the root Handsontable element within a table with window
     * as a scrollable element.
     *
     * @private
     * @param {Boolean} onFixedRowTop `true` if the coordinates point to a place within the top fixed rows.
     * @param {Boolean} onFixedColumn `true` if the coordinates point to a place within the fixed columns.
     * @param {Number} elementOffset Offset position of the cell element.
     * @param {Number} spreaderOffset Offset position of the spreader element.
     * @returns {{top: Number, left: Number}}
     */

  }, {
    key: "getRelativeCellPositionWithinWindow",
    value: function getRelativeCellPositionWithinWindow(onFixedRowTop, onFixedColumn, elementOffset, spreaderOffset) {
      var absoluteRootElementPosition = this.wot.wtTable.wtRootElement.getBoundingClientRect();
      var horizontalOffset = 0;
      var verticalOffset = 0;

      if (!onFixedColumn) {
        horizontalOffset = spreaderOffset.left;
      } else {
        horizontalOffset = absoluteRootElementPosition.left <= 0 ? -1 * absoluteRootElementPosition.left : 0;
      }

      if (onFixedRowTop) {
        var absoluteOverlayPosition = this.clone.wtTable.TABLE.getBoundingClientRect();
        verticalOffset = absoluteOverlayPosition.top - absoluteRootElementPosition.top;
      } else {
        verticalOffset = spreaderOffset.top;
      }

      return {
        left: elementOffset.left + horizontalOffset,
        top: elementOffset.top + verticalOffset
      };
    }
    /**
     * Calculates coordinates of the provided element, relative to the root Handsontable element within a table with window
     * as a scrollable element.
     *
     * @private
     * @param {Boolean} onFixedRowTop `true` if the coordinates point to a place within the top fixed rows.
     * @param {Boolean} onFixedRowBottom `true` if the coordinates point to a place within the bottom fixed rows.
     * @param {Boolean} onFixedColumn `true` if the coordinates point to a place within the fixed columns.
     * @param {Number} elementOffset Offset position of the cell element.
     * @param {Number} spreaderOffset Offset position of the spreader element.
     * @returns {{top: Number, left: Number}}
     */

  }, {
    key: "getRelativeCellPositionWithinHolder",
    value: function getRelativeCellPositionWithinHolder(onFixedRowTop, onFixedRowBottom, onFixedColumn, elementOffset, spreaderOffset) {
      var tableScrollPosition = {
        horizontal: this.clone.cloneSource.wtOverlays.leftOverlay.getScrollPosition(),
        vertical: this.clone.cloneSource.wtOverlays.topOverlay.getScrollPosition()
      };
      var horizontalOffset = 0;
      var verticalOffset = 0;

      if (!onFixedColumn) {
        horizontalOffset = tableScrollPosition.horizontal - spreaderOffset.left;
      }

      if (onFixedRowBottom) {
        var absoluteRootElementPosition = this.wot.wtTable.wtRootElement.getBoundingClientRect();
        var absoluteOverlayPosition = this.clone.wtTable.TABLE.getBoundingClientRect();
        verticalOffset = absoluteOverlayPosition.top * -1 + absoluteRootElementPosition.top;
      } else if (!onFixedRowTop) {
        verticalOffset = tableScrollPosition.vertical - spreaderOffset.top;
      }

      return {
        left: elementOffset.left - horizontalOffset,
        top: elementOffset.top - verticalOffset
      };
    }
    /**
     * Make a clone of table for overlay
     *
     * @param {String} direction Can be `Overlay.CLONE_TOP`, `Overlay.CLONE_LEFT`,
     *                           `Overlay.CLONE_TOP_LEFT_CORNER`, `Overlay.CLONE_DEBUG`
     * @returns {Walkontable}
     */

  }, {
    key: "makeClone",
    value: function makeClone(direction) {
      if (Overlay.CLONE_TYPES.indexOf(direction) === -1) {
        throw new Error("Clone type \"".concat(direction, "\" is not supported."));
      }

      var _this$wot2 = this.wot,
          wtTable = _this$wot2.wtTable,
          rootDocument = _this$wot2.rootDocument,
          rootWindow = _this$wot2.rootWindow;
      var clone = rootDocument.createElement('DIV');
      var clonedTable = rootDocument.createElement('TABLE');
      clone.className = "ht_clone_".concat(direction, " handsontable");
      clone.style.position = 'absolute';
      clone.style.top = 0;
      clone.style.left = 0;
      clone.style.overflow = 'hidden';
      clonedTable.className = wtTable.TABLE.className;
      clone.appendChild(clonedTable);
      this.type = direction;
      wtTable.wtRootElement.parentNode.appendChild(clone);
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (preventOverflow === true || preventOverflow === 'horizontal' && this.type === Overlay.CLONE_TOP || preventOverflow === 'vertical' && this.type === Overlay.CLONE_LEFT) {
        this.mainTableScrollableElement = rootWindow;
      } else if (rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden') {
        this.mainTableScrollableElement = wtTable.holder;
      } else {
        this.mainTableScrollableElement = (0, _element.getScrollableElement)(wtTable.TABLE);
      }

      return new _core.default({
        cloneSource: this.wot,
        cloneOverlay: this,
        table: clonedTable
      });
    }
    /**
     * Refresh/Redraw overlay
     *
     * @param {Boolean} [fastDraw=false]
     */

  }, {
    key: "refresh",
    value: function refresh() {
      var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      // When hot settings are changed we allow to refresh overlay once before blocking
      var nextCycleRenderFlag = this.shouldBeRendered();

      if (this.clone && (this.needFullRender || nextCycleRenderFlag)) {
        this.clone.draw(fastDraw);
      }

      this.needFullRender = nextCycleRenderFlag;
    }
    /**
     * Reset overlay styles to initial values.
     */

  }, {
    key: "reset",
    value: function reset() {
      if (!this.clone) {
        return;
      }

      var holder = this.clone.wtTable.holder;
      var hider = this.clone.wtTable.hider;
      var holderStyle = holder.style;
      var hidderStyle = hider.style;
      var rootStyle = holder.parentNode.style;
      (0, _array.arrayEach)([holderStyle, hidderStyle, rootStyle], function (style) {
        style.width = '';
        style.height = '';
      });
    }
    /**
     * Destroy overlay instance
     */

  }, {
    key: "destroy",
    value: function destroy() {
      new _eventManager.default(this.clone).destroy();
    }
  }]);
  return Overlay;
}();

var _default = Overlay;
exports.default = _default;

/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(40);

__webpack_require__(30);

exports.__esModule = true;
exports.isFunction = isFunction;
exports.throttle = throttle;
exports.throttleAfterHits = throttleAfterHits;
exports.debounce = debounce;
exports.pipe = pipe;
exports.partial = partial;
exports.curry = curry;
exports.curryRight = curryRight;

var _array = __webpack_require__(3);

/**
 * Checks if given variable is function.
 *
 * @param {*} func Variable to check.
 * @returns {Boolean}
 */
function isFunction(func) {
  return typeof func === 'function';
}
/**
 * Creates throttle function that enforces a maximum number of times a function (`func`) can be called over time (`wait`).
 *
 * @param {Function} func Function to invoke.
 * @param {Number} wait Delay in miliseconds.
 * @returns {Function}
 */


function throttle(func) {
  var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
  var lastCalled = 0;
  var result = {
    lastCallThrottled: true
  };
  var lastTimer = null;

  function _throttle() {
    var _this = this;

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var stamp = Date.now();
    var needCall = false;
    result.lastCallThrottled = true;

    if (!lastCalled) {
      lastCalled = stamp;
      needCall = true;
    }

    var remaining = wait - (stamp - lastCalled);

    if (needCall) {
      result.lastCallThrottled = false;
      func.apply(this, args);
    } else {
      if (lastTimer) {
        clearTimeout(lastTimer);
      }

      lastTimer = setTimeout(function () {
        result.lastCallThrottled = false;
        func.apply(_this, args);
        lastCalled = 0;
        lastTimer = void 0;
      }, remaining);
    }

    return result;
  }

  return _throttle;
}
/**
 * Creates throttle function that enforces a maximum number of times a function (`func`) can be called over
 * time (`wait`) after specified hits.
 *
 * @param {Function} func Function to invoke.
 * @param {Number} wait Delay in miliseconds.
 * @param {Number} hits Number of hits after throttling will be applied.
 * @returns {Function}
 */


function throttleAfterHits(func) {
  var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
  var hits = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10;
  var funcThrottle = throttle(func, wait);
  var remainHits = hits;

  function _clearHits() {
    remainHits = hits;
  }

  function _throttleAfterHits() {
    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      args[_key2] = arguments[_key2];
    }

    if (remainHits) {
      remainHits -= 1;
      return func.apply(this, args);
    }

    return funcThrottle.apply(this, args);
  }

  _throttleAfterHits.clearHits = _clearHits;
  return _throttleAfterHits;
}
/**
 * Creates debounce function that enforces a function (`func`) not be called again until a certain amount of time (`wait`)
 * has passed without it being called.
 *
 * @param {Function} func Function to invoke.
 * @param {Number} wait Delay in milliseconds.
 * @returns {Function}
 */


function debounce(func) {
  var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
  var lastTimer = null;
  var result;

  function _debounce() {
    var _this2 = this;

    for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
      args[_key3] = arguments[_key3];
    }

    if (lastTimer) {
      clearTimeout(lastTimer);
    }

    lastTimer = setTimeout(function () {
      result = func.apply(_this2, args);
    }, wait);
    return result;
  }

  return _debounce;
}
/**
 * Creates the function that returns the result of calling the given functions. Result of the first function is passed to
 * the second as an argument and so on. Only first function in the chain can handle multiple arguments.
 *
 * @param {Function} functions Functions to compose.
 * @returns {Function}
 */


function pipe() {
  for (var _len4 = arguments.length, functions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
    functions[_key4] = arguments[_key4];
  }

  var firstFunc = functions[0],
      restFunc = functions.slice(1);
  return function _pipe() {
    for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
      args[_key5] = arguments[_key5];
    }

    return (0, _array.arrayReduce)(restFunc, function (acc, fn) {
      return fn(acc);
    }, firstFunc.apply(this, args));
  };
}
/**
 * Creates the function that returns the function with cached arguments.
 *
 * @param {Function} func Function to partialization.
 * @param {Array} params Function arguments to cache.
 * @returns {Function}
 */


function partial(func) {
  for (var _len6 = arguments.length, params = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
    params[_key6 - 1] = arguments[_key6];
  }

  return function _partial() {
    for (var _len7 = arguments.length, restParams = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
      restParams[_key7] = arguments[_key7];
    }

    return func.apply(this, params.concat(restParams));
  };
}
/**
 * Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
 * to the arguments defined in `func` then function will be invoked.
 * Arguments are added to the stack in direction from the left to the right.
 *
 * @example
 * ```
 * var replace = curry(function(find, replace, string) {
 *   return string.replace(find, replace);
 * });
 *
 * // returns function with bounded first argument
 * var replace = replace('foo')
 *
 * // returns replaced string - all arguments was passed so function was invoked
 * replace('bar', 'Some test with foo...');
 *
 * ```
 *
 * @param {Function} func Function to currying.
 * @returns {Function}
 */


function curry(func) {
  var argsLength = func.length;

  function given(argsSoFar) {
    return function _curry() {
      for (var _len8 = arguments.length, params = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
        params[_key8] = arguments[_key8];
      }

      var passedArgsSoFar = argsSoFar.concat(params);
      var result;

      if (passedArgsSoFar.length >= argsLength) {
        result = func.apply(this, passedArgsSoFar);
      } else {
        result = given(passedArgsSoFar);
      }

      return result;
    };
  }

  return given([]);
}
/**
 * Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
 * to the arguments defined in `func` then function will be invoked.
 * Arguments are added to the stack in direction from the right to the left.
 *
 * @example
 * ```
 * var replace = curry(function(find, replace, string) {
 *   return string.replace(find, replace);
 * });
 *
 * // returns function with bounded first argument
 * var replace = replace('Some test with foo...')
 *
 * // returns replaced string - all arguments was passed so function was invoked
 * replace('bar', 'foo');
 *
 * ```
 *
 * @param {Function} func Function to currying.
 * @returns {Function}
 */


function curryRight(func) {
  var argsLength = func.length;

  function given(argsSoFar) {
    return function _curry() {
      for (var _len9 = arguments.length, params = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
        params[_key9] = arguments[_key9];
      }

      var passedArgsSoFar = argsSoFar.concat(params.reverse());
      var result;

      if (passedArgsSoFar.length >= argsLength) {
        result = func.apply(this, passedArgsSoFar);
      } else {
        result = given(passedArgsSoFar);
      }

      return result;
    };
  }

  return given([]);
}

/***/ }),
/* 76 */
/***/ (function(module, exports, __webpack_require__) {

var toObject = __webpack_require__(62);
var nativeKeys = __webpack_require__(89);
var FAILS_ON_PRIMITIVES = __webpack_require__(29)(function () { nativeKeys(1); });

// `Object.keys` method
// https://tc39.github.io/ecma262/#sec-object.keys
__webpack_require__(22)({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {
  keys: function keys(it) {
    return nativeKeys(toObject(it));
  }
});


/***/ }),
/* 77 */
/***/ (function(module, exports) {

var toString = {}.toString;

module.exports = function (it) {
  return toString.call(it).slice(8, -1);
};


/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = staticRegister;
exports.collection = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var collection = new Map();
exports.collection = collection;

function staticRegister() {
  var namespace = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'common';

  if (!collection.has(namespace)) {
    collection.set(namespace, new Map());
  }

  var subCollection = collection.get(namespace);
  /**
   * Register an item to the collection. If the item under the same was exist earlier then this item will be replaced with new one.
   *
   * @param {String} name Identification of the item.
   * @param {*} item Item to save in the collection.
   */

  function register(name, item) {
    subCollection.set(name, item);
  }
  /**
   * Retrieve the item from the collection.
   *
   * @param {String} name Identification of the item.
   * @returns {*} Returns item which was saved in the collection.
   */


  function getItem(name) {
    return subCollection.get(name);
  }
  /**
   * Check if item under specyfied name is exists.
   *
   * @param {String} name Identification of the item.
   * @returns {Boolean} Returns `true` or `false` depends on if element exists in the collection.
   */


  function hasItem(name) {
    return subCollection.has(name);
  }
  /**
   * Retrieve list of names registered from the collection.
   *
   * @returns {Array} Returns an array of strings with all names under which objects are stored.
   */


  function getNames() {
    return (0, _toConsumableArray2.default)(subCollection.keys());
  }
  /**
   * Retrieve all registered values from the collection.
   *
   * @returns {Array} Returns an array with all values stored in the collection.
   */


  function getValues() {
    return (0, _toConsumableArray2.default)(subCollection.values());
  }

  return {
    register: register,
    getItem: getItem,
    hasItem: hasItem,
    getNames: getNames,
    getValues: getValues
  };
}

/***/ }),
/* 79 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.getValidator = _getItem;
exports.getRegisteredValidators = exports.getRegisteredValidatorNames = exports.hasValidator = exports.registerValidator = void 0;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _autocompleteValidator = _interopRequireDefault(__webpack_require__(554));

var _dateValidator = _interopRequireDefault(__webpack_require__(555));

var _numericValidator = _interopRequireDefault(__webpack_require__(557));

var _timeValidator = _interopRequireDefault(__webpack_require__(558));

var _staticRegister = (0, _staticRegister2.default)('validators'),
    register = _staticRegister.register,
    getItem = _staticRegister.getItem,
    hasItem = _staticRegister.hasItem,
    getNames = _staticRegister.getNames,
    getValues = _staticRegister.getValues;

exports.getRegisteredValidators = getValues;
exports.getRegisteredValidatorNames = getNames;
exports.hasValidator = hasItem;
exports.registerValidator = register;
register('autocomplete', _autocompleteValidator.default);
register('date', _dateValidator.default);
register('numeric', _numericValidator.default);
register('time', _timeValidator.default);
/**
 * Retrieve validator function.
 *
 * @param {String} name Validator identification.
 * @returns {Function} Returns validator function.
 */

function _getItem(name) {
  if (typeof name === 'function') {
    return name;
  }

  if (!hasItem(name)) {
    throw Error("No registered validator found under \"".concat(name, "\" name"));
  }

  return getItem(name);
}

/***/ }),
/* 80 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global = __webpack_require__(32);
var isForced = __webpack_require__(120);
var has = __webpack_require__(47);
var classof = __webpack_require__(77);
var inheritIfRequired = __webpack_require__(152);
var toPrimitive = __webpack_require__(97);
var fails = __webpack_require__(29);
var getOwnPropertyNames = __webpack_require__(93).f;
var getOwnPropertyDescriptor = __webpack_require__(115).f;
var defineProperty = __webpack_require__(49).f;
var internalStringTrim = __webpack_require__(196);
var NUMBER = 'Number';
var NativeNumber = global[NUMBER];
var NumberPrototype = NativeNumber.prototype;

// Opera ~12 has broken Object#toString
var BROKEN_CLASSOF = classof(__webpack_require__(99)(NumberPrototype)) == NUMBER;
var NATIVE_TRIM = 'trim' in String.prototype;

// `ToNumber` abstract operation
// https://tc39.github.io/ecma262/#sec-tonumber
var toNumber = function (argument) {
  var it = toPrimitive(argument, false);
  var first, third, radix, maxCode, digits, length, i, code;
  if (typeof it == 'string' && it.length > 2) {
    it = NATIVE_TRIM ? it.trim() : internalStringTrim(it, 3);
    first = it.charCodeAt(0);
    if (first === 43 || first === 45) {
      third = it.charCodeAt(2);
      if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
    } else if (first === 48) {
      switch (it.charCodeAt(1)) {
        case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i
        case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i
        default: return +it;
      }
      digits = it.slice(2);
      length = digits.length;
      for (i = 0; i < length; i++) {
        code = digits.charCodeAt(i);
        // parseInt parses a string to a first unavailable symbol
        // but ToNumber should return NaN if a string contains unavailable symbols
        if (code < 48 || code > maxCode) return NaN;
      } return parseInt(digits, radix);
    }
  } return +it;
};

// `Number` constructor
// https://tc39.github.io/ecma262/#sec-number-constructor
if (isForced(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {
  var NumberWrapper = function Number(value) {
    var it = arguments.length < 1 ? 0 : value;
    var that = this;
    return that instanceof NumberWrapper
      // check on 1..constructor(foo) case
      && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(that); }) : classof(that) != NUMBER)
        ? inheritIfRequired(new NativeNumber(toNumber(it)), that, NumberWrapper) : toNumber(it);
  };
  for (var keys = __webpack_require__(52) ? getOwnPropertyNames(NativeNumber) : (
    // ES3:
    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
    // ES2015 (in case, if modules with ES2015 Number statics required before):
    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
  ).split(','), j = 0, key; keys.length > j; j++) {
    if (has(NativeNumber, key = keys[j]) && !has(NumberWrapper, key)) {
      defineProperty(NumberWrapper, key, getOwnPropertyDescriptor(NativeNumber, key));
    }
  }
  NumberWrapper.prototype = NumberPrototype;
  NumberPrototype.constructor = NumberWrapper;
  __webpack_require__(65)(global, NUMBER, NumberWrapper);
}


/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {

// `Number.isInteger` method
// https://tc39.github.io/ecma262/#sec-number.isinteger
__webpack_require__(22)({ target: 'Number', stat: true }, {
  isInteger: __webpack_require__(568)
});


/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// `Set` constructor
// https://tc39.github.io/ecma262/#sec-set-objects
module.exports = __webpack_require__(125)('Set', function (get) {
  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, __webpack_require__(192));


/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

var _interopRequireWildcard = __webpack_require__(9);

__webpack_require__(12);

exports.__esModule = true;
exports.predefinedItems = predefinedItems;
exports.addItem = addItem;
exports.ITEMS = exports.UNDO = exports.NO_ITEMS = exports.SEPARATOR = exports.ROW_BELOW = exports.ROW_ABOVE = exports.REMOVE_ROW = exports.REMOVE_COLUMN = exports.REDO = exports.READ_ONLY = exports.COLUMN_RIGHT = exports.COLUMN_LEFT = exports.CLEAR_COLUMN = exports.ALIGNMENT = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _object = __webpack_require__(4);

var _alignment = _interopRequireWildcard(__webpack_require__(619));

exports.ALIGNMENT = _alignment.KEY;

var _clearColumn = _interopRequireWildcard(__webpack_require__(620));

exports.CLEAR_COLUMN = _clearColumn.KEY;

var _columnLeft = _interopRequireWildcard(__webpack_require__(621));

exports.COLUMN_LEFT = _columnLeft.KEY;

var _columnRight = _interopRequireWildcard(__webpack_require__(622));

exports.COLUMN_RIGHT = _columnRight.KEY;

var _readOnly = _interopRequireWildcard(__webpack_require__(623));

exports.READ_ONLY = _readOnly.KEY;

var _redo = _interopRequireWildcard(__webpack_require__(624));

exports.REDO = _redo.KEY;

var _removeColumn = _interopRequireWildcard(__webpack_require__(625));

exports.REMOVE_COLUMN = _removeColumn.KEY;

var _removeRow = _interopRequireWildcard(__webpack_require__(626));

exports.REMOVE_ROW = _removeRow.KEY;

var _rowAbove = _interopRequireWildcard(__webpack_require__(627));

exports.ROW_ABOVE = _rowAbove.KEY;

var _rowBelow = _interopRequireWildcard(__webpack_require__(628));

exports.ROW_BELOW = _rowBelow.KEY;

var _separator = _interopRequireWildcard(__webpack_require__(166));

exports.SEPARATOR = _separator.KEY;

var _noItems = _interopRequireWildcard(__webpack_require__(629));

exports.NO_ITEMS = _noItems.KEY;

var _undo = _interopRequireWildcard(__webpack_require__(630));

exports.UNDO = _undo.KEY;

var _predefinedItems2;

var ITEMS = [_rowAbove.KEY, _rowBelow.KEY, _columnLeft.KEY, _columnRight.KEY, _clearColumn.KEY, _removeRow.KEY, _removeColumn.KEY, _undo.KEY, _redo.KEY, _readOnly.KEY, _alignment.KEY, _separator.KEY, _noItems.KEY];
exports.ITEMS = ITEMS;

var _predefinedItems = (_predefinedItems2 = {}, (0, _defineProperty2.default)(_predefinedItems2, _separator.KEY, _separator.default), (0, _defineProperty2.default)(_predefinedItems2, _noItems.KEY, _noItems.default), (0, _defineProperty2.default)(_predefinedItems2, _rowAbove.KEY, _rowAbove.default), (0, _defineProperty2.default)(_predefinedItems2, _rowBelow.KEY, _rowBelow.default), (0, _defineProperty2.default)(_predefinedItems2, _columnLeft.KEY, _columnLeft.default), (0, _defineProperty2.default)(_predefinedItems2, _columnRight.KEY, _columnRight.default), (0, _defineProperty2.default)(_predefinedItems2, _clearColumn.KEY, _clearColumn.default), (0, _defineProperty2.default)(_predefinedItems2, _removeRow.KEY, _removeRow.default), (0, _defineProperty2.default)(_predefinedItems2, _removeColumn.KEY, _removeColumn.default), (0, _defineProperty2.default)(_predefinedItems2, _undo.KEY, _undo.default), (0, _defineProperty2.default)(_predefinedItems2, _redo.KEY, _redo.default), (0, _defineProperty2.default)(_predefinedItems2, _readOnly.KEY, _readOnly.default), (0, _defineProperty2.default)(_predefinedItems2, _alignment.KEY, _alignment.default), _predefinedItems2);
/**
 * Gets new object with all predefined menu items.
 *
 * @returns {Object}
 */


function predefinedItems() {
  var items = {};
  (0, _object.objectEach)(_predefinedItems, function (itemFactory, key) {
    items[key] = itemFactory();
  });
  return items;
}
/**
 * Add new predefined menu item to the collection.
 *
 * @param {String} key Menu command id.
 * @param {Object} item Object command descriptor.
 */


function addItem(key, item) {
  if (ITEMS.indexOf(key) === -1) {
    _predefinedItems[key] = item;
  }
}

/***/ }),
/* 84 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(131);

__webpack_require__(37);

exports.__esModule = true;
exports.isFormulaExpression = isFormulaExpression;
exports.isFormulaExpressionEscaped = isFormulaExpressionEscaped;
exports.unescapeFormulaExpression = unescapeFormulaExpression;
exports.toUpperCaseFormula = toUpperCaseFormula;
exports.cellCoordFactory = cellCoordFactory;

/**
 * Check if provided expression is valid formula expression.
 *
 * @param {*} expression Expression to check.
 * @returns {Boolean}
 */
function isFormulaExpression(expression) {
  return typeof expression === 'string' && expression.length >= 2 && expression.charAt(0) === '=';
}
/**
 * Check if provided formula expression is escaped.
 *
 * @param {*} expression Expression to check.
 * @returns {Boolean}
 */


function isFormulaExpressionEscaped(expression) {
  return typeof expression === 'string' && expression.charAt(0) === '\'' && expression.charAt(1) === '=';
}
/**
 * Replace escaped formula expression into valid string.
 *
 * @param {String} expression Expression to process.
 * @returns {String}
 */


function unescapeFormulaExpression(expression) {
  return isFormulaExpressionEscaped(expression) ? expression.substr(1) : expression;
}
/**
 * Upper case formula expression.
 *
 * @param {String} expression Formula expression.
 * @returns {String}
 */


function toUpperCaseFormula(expression) {
  var PATTERN = /(\\"|"(?:\\"|[^"])*"|(\+))|(\\'|'(?:\\'|[^'])*'|(\+))/g;
  var strings = expression.match(PATTERN) || [];
  var index = -1;
  return expression.toUpperCase().replace(PATTERN, function () {
    index += 1;
    return strings[index];
  });
}
/**
 * Cell coordinates function factory.
 *
 * @param {String} axis An axis name (`row` or `column`) which default index will be applied to.
 * @param {Number} defaultIndex Default index.
 * @returns {Function}
 */


function cellCoordFactory(axis, defaultIndex) {
  return function (cell) {
    return {
      row: axis === 'row' ? defaultIndex : cell.row,
      column: axis === 'column' ? defaultIndex : cell.column
    };
  };
}

/***/ }),
/* 85 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _hotFormulaParser = __webpack_require__(111);

var _array = __webpack_require__(3);

var _base = _interopRequireDefault(__webpack_require__(503));

var STATE_OUT_OFF_DATE = 1;
var STATE_COMPUTING = 2;
var STATE_UP_TO_DATE = 3;
var states = [STATE_OUT_OFF_DATE, STATE_COMPUTING, STATE_UP_TO_DATE];
/**
 * Class responsible for wrapping formula expression. It contains calculated value of
 * the formula, an error if it has happened and cell references which indicates a relationship with regular
 * cells. This object uses physical cell coordinates.
 *
 * @class CellValue
 * @util
 */

var CellValue =
/*#__PURE__*/
function (_BaseCell) {
  (0, _inherits2.default)(CellValue, _BaseCell);
  (0, _createClass2.default)(CellValue, null, [{
    key: "STATE_OUT_OFF_DATE",

    /**
     * Out of date state indicates cells ready for recomputing.
     *
     * @returns {Number}
     */
    get: function get() {
      return 1; // PhantomJS crashes when we want to use constant above
    }
    /**
     * Computing state indicates cells under processing.
     *
     * @returns {Number}
     */

  }, {
    key: "STATE_COMPUTING",
    get: function get() {
      return 2; // PhantomJS crashes when we want to use constant above
    }
    /**
     * Up to date state indicates cells with fresh computed value.
     *
     * @returns {Number}
     */

  }, {
    key: "STATE_UP_TO_DATE",
    get: function get() {
      return 3; // PhantomJS crashes when we want to use constant above
    }
  }]);

  function CellValue(row, column) {
    var _this;

    (0, _classCallCheck2.default)(this, CellValue);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CellValue).call(this, row, column));
    /**
     * List of precedents cells.
     *
     * @type {Array}
     */

    _this.precedents = [];
    /**
     * Computed value.
     *
     * @type {*}
     */

    _this.value = null;
    /**
     * Error name.
     *
     * @type {String|null}
     */

    _this.error = null;
    /**
     * Indicates cell state.
     *
     * @type {String}
     */

    _this.state = CellValue.STATE_UP_TO_DATE;
    return _this;
  }
  /**
   * Set computed value.
   *
   * @param {*} value
   */


  (0, _createClass2.default)(CellValue, [{
    key: "setValue",
    value: function setValue(value) {
      this.value = value;
    }
    /**
     * Get computed value.
     *
     * @returns {*}
     */

  }, {
    key: "getValue",
    value: function getValue() {
      return this.value;
    }
    /**
     * Set error message for this cell.
     *
     * @param {String} error Error name.
     */

  }, {
    key: "setError",
    value: function setError(error) {
      this.error = error;
    }
    /**
     * Get error name for this cell.
     *
     * @returns {String|null}
     */

  }, {
    key: "getError",
    value: function getError() {
      return this.error;
    }
    /**
     * Check if cell value is marked as error.
     *
     * @returns {Boolean}
     */

  }, {
    key: "hasError",
    value: function hasError() {
      return this.error !== null;
    }
    /**
     * Set cell state.
     *
     * @param {Number} state Cell state.
     */

  }, {
    key: "setState",
    value: function setState(state) {
      if (states.indexOf(state) === -1) {
        throw Error("Unrecognized state: ".concat(state));
      }

      this.state = state;
    }
    /**
     * Check cell state.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isState",
    value: function isState(state) {
      return this.state === state;
    }
    /**
     * Add precedent cell to the collection.
     *
     * @param {CellReference} cellReference Cell reference object.
     */

  }, {
    key: "addPrecedent",
    value: function addPrecedent(cellReference) {
      if (this.isEqual(cellReference)) {
        throw Error(_hotFormulaParser.ERROR_REF);
      }

      if (!this.hasPrecedent(cellReference)) {
        this.precedents.push(cellReference);
      }
    }
    /**
     * Remove precedent cell from the collection.
     *
     * @param {CellReference} cellReference Cell reference object.
     */

  }, {
    key: "removePrecedent",
    value: function removePrecedent(cellReference) {
      if (this.isEqual(cellReference)) {
        throw Error(_hotFormulaParser.ERROR_REF);
      }

      this.precedents = (0, _array.arrayFilter)(this.precedents, function (cell) {
        return !cell.isEqual(cellReference);
      });
    }
    /**
     * Clear all precedent cells.
     */

  }, {
    key: "clearPrecedents",
    value: function clearPrecedents() {
      this.precedents.length = 0;
    }
    /**
     * Get precedent cells.
     *
     * @returns {Array}
     */

  }, {
    key: "getPrecedents",
    value: function getPrecedents() {
      return this.precedents;
    }
    /**
     * Check if cell value has precedents cells.
     *
     * @returns {Boolean}
     */

  }, {
    key: "hasPrecedents",
    value: function hasPrecedents() {
      return this.precedents.length > 0;
    }
    /**
     * Check if cell reference is precedents this cell.
     *
     * @param {CellReference} cellReference Cell reference object.
     * @returns {Boolean}
     */

  }, {
    key: "hasPrecedent",
    value: function hasPrecedent(cellReference) {
      return (0, _array.arrayFilter)(this.precedents, function (cell) {
        return cell.isEqual(cellReference);
      }).length > 0;
    }
  }]);
  return CellValue;
}(_base.default);

var _default = CellValue;
exports.default = _default;

/***/ }),
/* 86 */
/***/ (function(module, exports) {

var ceil = Math.ceil;
var floor = Math.floor;

// `ToInteger` abstract operation
// https://tc39.github.io/ecma262/#sec-tointeger
module.exports = function (argument) {
  return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
};


/***/ }),
/* 87 */
/***/ (function(module, exports, __webpack_require__) {

var NATIVE_WEAK_MAP = __webpack_require__(178);
var isObject = __webpack_require__(42);
var hide = __webpack_require__(61);
var objectHas = __webpack_require__(47);
var sharedKey = __webpack_require__(117);
var hiddenKeys = __webpack_require__(94);
var WeakMap = __webpack_require__(32).WeakMap;
var set, get, has;

var enforce = function (it) {
  return has(it) ? get(it) : set(it, {});
};

var getterFor = function (TYPE) {
  return function (it) {
    var state;
    if (!isObject(it) || (state = get(it)).type !== TYPE) {
      throw TypeError('Incompatible receiver, ' + TYPE + ' required');
    } return state;
  };
};

if (NATIVE_WEAK_MAP) {
  var store = new WeakMap();
  var wmget = store.get;
  var wmhas = store.has;
  var wmset = store.set;
  set = function (it, metadata) {
    wmset.call(store, it, metadata);
    return metadata;
  };
  get = function (it) {
    return wmget.call(store, it) || {};
  };
  has = function (it) {
    return wmhas.call(store, it);
  };
} else {
  var STATE = sharedKey('state');
  hiddenKeys[STATE] = true;
  set = function (it, metadata) {
    hide(it, STATE, metadata);
    return metadata;
  };
  get = function (it) {
    return objectHas(it, STATE) ? it[STATE] : {};
  };
  has = function (it) {
    return objectHas(it, STATE);
  };
}

module.exports = {
  set: set,
  get: get,
  has: has,
  enforce: enforce,
  getterFor: getterFor
};


/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(64);

exports.__esModule = true;

var _registry = __webpack_require__(487);

exports.registerRootComparator = _registry.registerRootComparator;
exports.getRootComparator = _registry.getRootComparator;
exports.getCompareFunctionFactory = _registry.getCompareFunctionFactory;

var _engine = __webpack_require__(611);

exports.FIRST_AFTER_SECOND = _engine.FIRST_AFTER_SECOND;
exports.FIRST_BEFORE_SECOND = _engine.FIRST_BEFORE_SECOND;
exports.DO_NOT_SWAP = _engine.DO_NOT_SWAP;
exports.sort = _engine.sort;

/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var internalObjectKeys = __webpack_require__(175);
var enumBugKeys = __webpack_require__(141);

module.exports = Object.keys || function keys(O) {
  return internalObjectKeys(O, enumBugKeys);
};


/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.registerIdentity = registerIdentity;
exports.getTranslator = getTranslator;
exports.getIdentity = getIdentity;
exports.RecordTranslator = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _core = _interopRequireDefault(__webpack_require__(161));

var _object = __webpack_require__(4);

/**
 * @class RecordTranslator
 * @util
 */
var RecordTranslator =
/*#__PURE__*/
function () {
  function RecordTranslator(hot) {
    (0, _classCallCheck2.default)(this, RecordTranslator);
    this.hot = hot;
  }
  /**
   * Translate physical row index into visual.
   *
   * @param {Number} row Physical row index.
   * @returns {Number} Returns visual row index.
   */


  (0, _createClass2.default)(RecordTranslator, [{
    key: "toVisualRow",
    value: function toVisualRow(row) {
      return this.hot.runHooks('unmodifyRow', row);
    }
    /**
     * Translate physical column index into visual.
     *
     * @param {Number} column Physical column index.
     * @returns {Number} Returns visual column index.
     */

  }, {
    key: "toVisualColumn",
    value: function toVisualColumn(column) {
      return this.hot.runHooks('unmodifyCol', column);
    }
    /**
     * Translate physical coordinates into visual. Can be passed as separate 2 arguments (row, column) or as an object in first
     * argument with `row` and `column` keys.
     *
     * @param {Number|Object} row Physical coordinates or row index.
     * @param {Number} [column] Physical column index.
     * @returns {Object|Array} Returns an object with visual records or an array if coordinates passed as separate arguments.
     */

  }, {
    key: "toVisual",
    value: function toVisual(row, column) {
      var result;

      if ((0, _object.isObject)(row)) {
        result = {
          row: this.toVisualRow(row.row),
          column: this.toVisualColumn(row.column)
        };
      } else {
        result = [this.toVisualRow(row), this.toVisualColumn(column)];
      }

      return result;
    }
    /**
     * Translate visual row index into physical.
     *
     * @param {Number} row Visual row index.
     * @returns {Number} Returns physical row index.
     */

  }, {
    key: "toPhysicalRow",
    value: function toPhysicalRow(row) {
      return this.hot.runHooks('modifyRow', row);
    }
    /**
     * Translate visual column index into physical.
     *
     * @param {Number} column Visual column index.
     * @returns {Number} Returns physical column index.
     */

  }, {
    key: "toPhysicalColumn",
    value: function toPhysicalColumn(column) {
      return this.hot.runHooks('modifyCol', column);
    }
    /**
     * Translate visual coordinates into physical. Can be passed as separate 2 arguments (row, column) or as an object in first
     * argument with `row` and `column` keys.
     *
     * @param {Number|Object} row Visual coordinates or row index.
     * @param {Number} [column] Visual column index.
     * @returns {Object|Array} Returns an object with physical records or an array if coordinates passed as separate arguments.
     */

  }, {
    key: "toPhysical",
    value: function toPhysical(row, column) {
      var result;

      if ((0, _object.isObject)(row)) {
        result = {
          row: this.toPhysicalRow(row.row),
          column: this.toPhysicalColumn(row.column)
        };
      } else {
        result = [this.toPhysicalRow(row), this.toPhysicalColumn(column)];
      }

      return result;
    }
  }]);
  return RecordTranslator;
}();

exports.RecordTranslator = RecordTranslator;
var identities = new WeakMap();
var translatorSingletons = new WeakMap();
/**
 * Allows to register custom identity manually.
 *
 * @param {*} identity
 * @param {*} hot
 */

function registerIdentity(identity, hot) {
  identities.set(identity, hot);
}
/**
 * Returns a cached instance of RecordTranslator or create the new one for given identity.
 *
 * @param {*} identity
 * @returns {RecordTranslator}
 */


function getTranslator(identity) {
  var instance = identity instanceof _core.default ? identity : getIdentity(identity);
  var singleton;

  if (translatorSingletons.has(instance)) {
    singleton = translatorSingletons.get(instance);
  } else {
    singleton = new RecordTranslator(instance);
    translatorSingletons.set(instance, singleton);
  }

  return singleton;
}
/**
 * Returns mapped identity.
 *
 * @param {*} identity
 * @returns {*}
 */


function getIdentity(identity) {
  if (!identities.has(identity)) {
    throw Error('Record translator was not registered for this object identity');
  }

  return identities.get(identity);
}

/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

__webpack_require__(64);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var MIXIN_NAME = 'arrayMapper';
/**
 * @type {Object}
 */

var arrayMapper = {
  _arrayMap: [],

  /**
   * Get translated index by its physical index.
   *
   * @param {Number} physicalIndex Physical index.
   * @return {Number|null} Returns translated index mapped by passed physical index.
   */
  getValueByIndex: function getValueByIndex(physicalIndex) {
    var length = this._arrayMap.length;
    var translatedIndex = null;

    if (physicalIndex < length) {
      translatedIndex = this._arrayMap[physicalIndex];
    }

    return translatedIndex;
  },

  /**
   * Get physical index by its translated index.
   *
   * @param {*} translatedIndex Value to search.
   * @returns {Number|null} Returns a physical index of the array mapper.
   */
  getIndexByValue: function getIndexByValue(translatedIndex) {
    var physicalIndex; // eslint-disable-next-line no-cond-assign, no-return-assign

    return (physicalIndex = this._arrayMap.indexOf(translatedIndex)) === -1 ? null : physicalIndex;
  },

  /**
   * Insert new items to array mapper starting at passed index. New entries will be a continuation of last value in the array.
   *
   * @param {Number} physicalIndex Array index.
   * @param {Number} [amount=1] Defines how many items will be created to an array.
   * @returns {Array} Returns added items.
   */
  insertItems: function insertItems(physicalIndex) {
    var _this = this;

    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
    var newIndex = (0, _array.arrayMax)(this._arrayMap) + 1;
    var addedItems = [];
    (0, _number.rangeEach)(amount - 1, function (count) {
      addedItems.push(_this._arrayMap.splice(physicalIndex + count, 0, newIndex + count));
    });
    return addedItems;
  },

  /**
   * Remove items from array mapper.
   *
   * @param {Number} physicalIndex Array index.
   * @param {Number} [amount=1] Defines how many items will be created to an array.
   * @returns {Array} Returns removed items.
   */
  removeItems: function removeItems(physicalIndex) {
    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
    var removedItems = [];

    if (Array.isArray(physicalIndex)) {
      var mapCopy = [].concat(this._arrayMap); // Sort descending

      physicalIndex.sort(function (a, b) {
        return b - a;
      });

      for (var i = 0, length = physicalIndex.length; i < length; i++) {
        var indexToRemove = physicalIndex[i];

        this._arrayMap.splice(indexToRemove, 1);

        removedItems.push(mapCopy[indexToRemove]);
      }
    } else {
      removedItems = this._arrayMap.splice(physicalIndex, amount);
    }

    return removedItems;
  },

  /**
   * Unshift items (remove and shift chunk of array to the left).
   *
   * @param {Number|Array} physicalIndex Array index or Array of indexes to unshift.
   * @param {Number} [amount=1] Defines how many items will be removed from an array (when index is passed as number).
   */
  unshiftItems: function unshiftItems(physicalIndex) {
    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
    var removedItems = this.removeItems(physicalIndex, amount);

    function countRowShift(logicalRow) {
      // Todo: compare perf between reduce vs sort->each->brake
      return (0, _array.arrayReduce)(removedItems, function (count, removedLogicalRow) {
        var result = count;

        if (logicalRow > removedLogicalRow) {
          result += 1;
        }

        return result;
      }, 0);
    }

    this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (logicalRow) {
      var logicalRowIndex = logicalRow;
      var rowShift = countRowShift(logicalRowIndex);

      if (rowShift) {
        logicalRowIndex -= rowShift;
      }

      return logicalRowIndex;
    });
  },

  /**
   * Shift (right shifting) items starting at passed index.
   *
   * @param {Number} physicalIndex Array index.
   * @param {Number} [amount=1] Defines how many items will be created to an array.
   */
  shiftItems: function shiftItems(physicalIndex) {
    var _this2 = this;

    var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
    this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (row) {
      var physicalRowIndex = row;

      if (physicalRowIndex >= physicalIndex) {
        physicalRowIndex += amount;
      }

      return physicalRowIndex;
    });
    (0, _number.rangeEach)(amount - 1, function (count) {
      _this2._arrayMap.splice(physicalIndex + count, 0, physicalIndex + count);
    });
  },

  /**
   * Swap indexes in arrayMapper.
   *
   * @param {Number} physicalIndexFrom index to move.
   * @param {Number} physicalIndexTo index to.
   */
  swapIndexes: function swapIndexes(physicalIndexFrom, physicalIndexTo) {
    var _this$_arrayMap;

    (_this$_arrayMap = this._arrayMap).splice.apply(_this$_arrayMap, [physicalIndexTo, 0].concat((0, _toConsumableArray2.default)(this._arrayMap.splice(physicalIndexFrom, 1))));
  },

  /**
   * Clear all stored index<->value information from an array.
   */
  clearMap: function clearMap() {
    this._arrayMap.length = 0;
  }
};
(0, _object.defineGetter)(arrayMapper, 'MIXIN_NAME', MIXIN_NAME, {
  writable: false,
  enumerable: false
});
var _default = arrayMapper;
exports.default = _default;

/***/ }),
/* 92 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.createId = createId;
exports.createDefaultCustomBorder = createDefaultCustomBorder;
exports.createSingleEmptyBorder = createSingleEmptyBorder;
exports.createDefaultHtBorder = createDefaultHtBorder;
exports.createEmptyBorders = createEmptyBorders;
exports.extendDefaultBorder = extendDefaultBorder;
exports.checkSelectionBorders = checkSelectionBorders;
exports.markSelected = markSelected;

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

/**
 * Create separated id for borders for each cell.
 *
 * @param {Number} row Visual row index.
 * @param {Number} col Visual column index.
 * @returns {String}
 */
function createId(row, col) {
  return "border_row".concat(row, "col").concat(col);
}
/**
 * Create default single border for each position (top/right/bottom/left).
 *
 * @returns {Object} `{{width: number, color: string}}`
 */


function createDefaultCustomBorder() {
  return {
    width: 1,
    color: '#000'
  };
}
/**
 * Create default object for empty border.
 *
 * @returns {Object} `{{hide: boolean}}`
 */


function createSingleEmptyBorder() {
  return {
    hide: true
  };
}
/**
 * Create default Handsontable border object.
 *
 * @returns {Object} `{{width: number, color: string, cornerVisible: boolean}}`
 */


function createDefaultHtBorder() {
  return {
    width: 1,
    color: '#000',
    cornerVisible: false
  };
}
/**
 * Prepare empty border for each cell with all custom borders hidden.
 *
 * @param {Number} row Visual row index.
 * @param {Number} col Visual column index.
 * @returns {Object} `{{id: *, border: *, row: *, col: *, top: {hide: boolean}, right: {hide: boolean}, bottom: {hide: boolean}, left: {hide: boolean}}}`
 */


function createEmptyBorders(row, col) {
  return {
    id: createId(row, col),
    border: createDefaultHtBorder(),
    row: row,
    col: col,
    top: createSingleEmptyBorder(),
    right: createSingleEmptyBorder(),
    bottom: createSingleEmptyBorder(),
    left: createSingleEmptyBorder()
  };
}

function extendDefaultBorder(defaultBorder, customBorder) {
  if ((0, _object.hasOwnProperty)(customBorder, 'border')) {
    defaultBorder.border = customBorder.border;
  }

  if ((0, _object.hasOwnProperty)(customBorder, 'top')) {
    if (customBorder.top) {
      if (!(0, _object.isObject)(customBorder.top)) {
        customBorder.top = createDefaultCustomBorder();
      }

      defaultBorder.top = customBorder.top;
    } else {
      customBorder.top = createSingleEmptyBorder();
      defaultBorder.top = customBorder.top;
    }
  }

  if ((0, _object.hasOwnProperty)(customBorder, 'right')) {
    if (customBorder.right) {
      if (!(0, _object.isObject)(customBorder.right)) {
        customBorder.right = createDefaultCustomBorder();
      }

      defaultBorder.right = customBorder.right;
    } else {
      customBorder.right = createSingleEmptyBorder();
      defaultBorder.right = customBorder.right;
    }
  }

  if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) {
    if (customBorder.bottom) {
      if (!(0, _object.isObject)(customBorder.bottom)) {
        customBorder.bottom = createDefaultCustomBorder();
      }

      defaultBorder.bottom = customBorder.bottom;
    } else {
      customBorder.bottom = createSingleEmptyBorder();
      defaultBorder.bottom = customBorder.bottom;
    }
  }

  if ((0, _object.hasOwnProperty)(customBorder, 'left')) {
    if (customBorder.left) {
      if (!(0, _object.isObject)(customBorder.left)) {
        customBorder.left = createDefaultCustomBorder();
      }

      defaultBorder.left = customBorder.left;
    } else {
      customBorder.left = createSingleEmptyBorder();
      defaultBorder.left = customBorder.left;
    }
  }

  return defaultBorder;
}
/**
 * Check if selection has border.
 *
 * @param hot
 * @param direction
 */


function checkSelectionBorders(hot, direction) {
  var atLeastOneHasBorder = false;
  (0, _array.arrayEach)(hot.getSelectedRange(), function (range) {
    range.forAll(function (r, c) {
      var metaBorders = hot.getCellMeta(r, c).borders;

      if (metaBorders) {
        if (direction) {
          if (!(0, _object.hasOwnProperty)(metaBorders[direction], 'hide') || metaBorders[direction].hide === false) {
            atLeastOneHasBorder = true;
            return false; // breaks forAll
          }
        } else {
          atLeastOneHasBorder = true;
          return false; // breaks forAll
        }
      }
    });
  });
  return atLeastOneHasBorder;
}
/**
 * Mark label in contextMenu as selected.
 *
 * @param label
 * @returns {string}
 */


function markSelected(label) {
  return "<span class=\"selected\">".concat(String.fromCharCode(10003), "</span>").concat(label); // workaround for https://github.com/handsontable/handsontable/issues/1946
}

/***/ }),
/* 93 */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var internalObjectKeys = __webpack_require__(175);
var hiddenKeys = __webpack_require__(141).concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
  return internalObjectKeys(O, hiddenKeys);
};


/***/ }),
/* 94 */
/***/ (function(module, exports) {

module.exports = {};


/***/ }),
/* 95 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

// Nashorn ~ JDK8 bug
var NASHORN_BUG = nativeGetOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);

exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
  var descriptor = nativeGetOwnPropertyDescriptor(this, V);
  return !!descriptor && descriptor.enumerable;
} : nativePropertyIsEnumerable;


/***/ }),
/* 96 */
/***/ (function(module, exports) {

module.exports = function (bitmap, value) {
  return {
    enumerable: !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable: !(bitmap & 4),
    value: value
  };
};


/***/ }),
/* 97 */
/***/ (function(module, exports, __webpack_require__) {

// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = __webpack_require__(42);
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function (it, S) {
  if (!isObject(it)) return it;
  var fn, val;
  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  throw TypeError("Can't convert object to primitive value");
};


/***/ }),
/* 98 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var setGlobal = __webpack_require__(143);
var SHARED = '__core-js_shared__';
var store = global[SHARED] || setGlobal(SHARED, {});

(module.exports = function (key, value) {
  return store[key] || (store[key] = value !== undefined ? value : {});
})('versions', []).push({
  version: '3.0.0',
  mode: __webpack_require__(116) ? 'pure' : 'global',
  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
});


/***/ }),
/* 99 */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject = __webpack_require__(45);
var defineProperties = __webpack_require__(511);
var enumBugKeys = __webpack_require__(141);
var html = __webpack_require__(181);
var documentCreateElement = __webpack_require__(142);
var IE_PROTO = __webpack_require__(117)('IE_PROTO');
var PROTOTYPE = 'prototype';
var Empty = function () { /* empty */ };

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function () {
  // Thrash, waste and sodomy: IE GC bug
  var iframe = documentCreateElement('iframe');
  var length = enumBugKeys.length;
  var lt = '<';
  var script = 'script';
  var gt = '>';
  var js = 'java' + script + ':';
  var iframeDocument;
  iframe.style.display = 'none';
  html.appendChild(iframe);
  iframe.src = String(js);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(lt + script + gt + 'document.F=Object' + lt + '/' + script + gt);
  iframeDocument.close();
  createDict = iframeDocument.F;
  while (length--) delete createDict[PROTOTYPE][enumBugKeys[length]];
  return createDict();
};

module.exports = Object.create || function create(O, Properties) {
  var result;
  if (O !== null) {
    Empty[PROTOTYPE] = anObject(O);
    result = new Empty();
    Empty[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = createDict();
  return Properties === undefined ? result : defineProperties(result, Properties);
};

__webpack_require__(94)[IE_PROTO] = true;


/***/ }),
/* 100 */
/***/ (function(module, exports) {

module.exports = {};


/***/ }),
/* 101 */
/***/ (function(module, exports, __webpack_require__) {

var aFunction = __webpack_require__(150);

// optional / simple context binding
module.exports = function (fn, that, length) {
  aFunction(fn);
  if (that === undefined) return fn;
  switch (length) {
    case 0: return function () {
      return fn.call(that);
    };
    case 1: return function (a) {
      return fn.call(that, a);
    };
    case 2: return function (a, b) {
      return fn.call(that, a, b);
    };
    case 3: return function (a, b, c) {
      return fn.call(that, a, b, c);
    };
  }
  return function (/* ...args */) {
    return fn.apply(that, arguments);
  };
};


/***/ }),
/* 102 */
/***/ (function(module, exports, __webpack_require__) {

var bind = __webpack_require__(101);
var IndexedObject = __webpack_require__(113);
var toObject = __webpack_require__(62);
var toLength = __webpack_require__(48);
var arraySpeciesCreate = __webpack_require__(151);

// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex }` methods implementation
// 0 -> Array#forEach
// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
// 1 -> Array#map
// https://tc39.github.io/ecma262/#sec-array.prototype.map
// 2 -> Array#filter
// https://tc39.github.io/ecma262/#sec-array.prototype.filter
// 3 -> Array#some
// https://tc39.github.io/ecma262/#sec-array.prototype.some
// 4 -> Array#every
// https://tc39.github.io/ecma262/#sec-array.prototype.every
// 5 -> Array#find
// https://tc39.github.io/ecma262/#sec-array.prototype.find
// 6 -> Array#findIndex
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
module.exports = function (TYPE, specificCreate) {
  var IS_MAP = TYPE == 1;
  var IS_FILTER = TYPE == 2;
  var IS_SOME = TYPE == 3;
  var IS_EVERY = TYPE == 4;
  var IS_FIND_INDEX = TYPE == 6;
  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  var create = specificCreate || arraySpeciesCreate;
  return function ($this, callbackfn, that) {
    var O = toObject($this);
    var self = IndexedObject(O);
    var boundFunction = bind(callbackfn, that, 3);
    var length = toLength(self.length);
    var index = 0;
    var target = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
    var value, result;
    for (;length > index; index++) if (NO_HOLES || index in self) {
      value = self[index];
      result = boundFunction(value, index, O);
      if (TYPE) {
        if (IS_MAP) target[index] = result; // map
        else if (result) switch (TYPE) {
          case 3: return true;              // some
          case 5: return value;             // find
          case 6: return index;             // findIndex
          case 2: target.push(value);       // filter
        } else if (IS_EVERY) return false;  // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
  };
};


/***/ }),
/* 103 */
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__(29);
var SPECIES = __webpack_require__(35)('species');

module.exports = function (METHOD_NAME) {
  return !fails(function () {
    var array = [];
    var constructor = array.constructor = {};
    constructor[SPECIES] = function () {
      return { foo: 1 };
    };
    return array[METHOD_NAME](Boolean).foo !== 1;
  });
};


/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(105);

exports.__esModule = true;
exports.default = exports.EditorState = void 0;

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _src = __webpack_require__(25);

var _mixed = __webpack_require__(27);

var _object = __webpack_require__(4);

var _hooksRefRegisterer = _interopRequireDefault(__webpack_require__(534));

var EditorState = {
  VIRGIN: 'STATE_VIRGIN',
  // before editing
  EDITING: 'STATE_EDITING',
  WAITING: 'STATE_WAITING',
  // waiting for async validation
  FINISHED: 'STATE_FINISHED'
};
/**
 * @util
 * @class BaseEditor
 */

exports.EditorState = EditorState;

var BaseEditor =
/*#__PURE__*/
function () {
  function BaseEditor(instance) {
    (0, _classCallCheck2.default)(this, BaseEditor);

    /**
     * A reference to the source instance of the Handsontable.
     *
     * @type {Handsontable}
     */
    this.hot = instance;
    /**
     * A reference to the source instance of the Handsontable.
     * @deprecated
     *
     * @type {Handsontable}
     */

    this.instance = instance;
    /**
     * Editor's state.
     *
     * @type {String}
     */

    this.state = EditorState.VIRGIN;
    /**
     * Flag to store information about editor's opening status.
     * @private
     *
     * @type {Boolean}
     */

    this._opened = false;
    /**
     * Defines the editor's editing mode. When false, then an editor works in fast editing mode.
     * @private
     *
     * @type {Boolean}
     */

    this._fullEditMode = false;
    /**
     * Callback to call after closing editor.
     *
     * @type {Function}
     */

    this._closeCallback = null;
    /**
     * Currently rendered cell's TD element.
     *
     * @type {HTMLTableCellElement}
     */

    this.TD = null;
    /**
     * Visual row index.
     *
     * @type {Number}
     */

    this.row = null;
    /**
     * Visual column index.
     *
     * @type {Number}
     */

    this.col = null;
    /**
     * Column property name or a column index, if datasource is an array of arrays.
     *
     * @type {Number|String}
     */

    this.prop = null;
    /**
     * Original cell's value.
     *
     * @type {*}
     */

    this.originalValue = null;
    /**
     * Object containing the cell's properties.
     *
     * @type {Object}
     */

    this.cellProperties = null;
    this.init();
  }
  /**
   * Fires callback after closing editor.
   *
   * @private
   * @param {Boolean} result
   */


  (0, _createClass2.default)(BaseEditor, [{
    key: "_fireCallbacks",
    value: function _fireCallbacks(result) {
      if (this._closeCallback) {
        this._closeCallback(result);

        this._closeCallback = null;
      }
    }
    /**
     * Initializes an editor's intance.
     */

  }, {
    key: "init",
    value: function init() {}
    /**
     * Required method to get current value from editable element.
     */

  }, {
    key: "getValue",
    value: function getValue() {
      throw Error('Editor getValue() method unimplemented');
    }
    /**
     * Required method to set new value into editable element.
     */

  }, {
    key: "setValue",
    value: function setValue() {
      throw Error('Editor setValue() method unimplemented');
    }
    /**
     * Required method to open editor.
     */

  }, {
    key: "open",
    value: function open() {
      throw Error('Editor open() method unimplemented');
    }
    /**
     * Required method to close editor.
     */

  }, {
    key: "close",
    value: function close() {
      throw Error('Editor close() method unimplemented');
    }
    /**
     * Prepares editor's meta data.
     *
     * @param {Number} row
     * @param {Number} col
     * @param {Number|String} prop
     * @param {HTMLTableCellElement} td
     * @param {*} originalValue
     * @param {Object} cellProperties
     */

  }, {
    key: "prepare",
    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
      this.TD = td;
      this.row = row;
      this.col = col;
      this.prop = prop;
      this.originalValue = originalValue;
      this.cellProperties = cellProperties;
      this.state = EditorState.VIRGIN;
    }
    /**
     * Fallback method to provide extendable editors in ES5.
     */

  }, {
    key: "extend",
    value: function extend() {
      return (
        /*#__PURE__*/
        function (_this$constructor) {
          (0, _inherits2.default)(Editor, _this$constructor);

          function Editor() {
            (0, _classCallCheck2.default)(this, Editor);
            return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Editor).apply(this, arguments));
          }

          return Editor;
        }(this.constructor)
      );
    }
    /**
     * Saves value from editor into data storage.
     *
     * @param {*} value
     * @param {Boolean} ctrlDown If true, applies value to each cell in the last selected range.
     */

  }, {
    key: "saveValue",
    value: function saveValue(value, ctrlDown) {
      var selection;
      var tmp; // if ctrl+enter and multiple cells selected, behave like Excel (finish editing and apply to all cells)

      if (ctrlDown) {
        selection = this.hot.getSelectedLast();

        if (selection[0] > selection[2]) {
          tmp = selection[0];
          selection[0] = selection[2];
          selection[2] = tmp;
        }

        if (selection[1] > selection[3]) {
          tmp = selection[1];
          selection[1] = selection[3];
          selection[3] = tmp;
        }
      } else {
        selection = [this.row, this.col, null, null];
      }

      this.hot.populateFromArray(selection[0], selection[1], value, selection[2], selection[3], 'edit');
    }
    /**
     * Begins editing on a highlighted cell and hides fillHandle corner if was present.
     *
     * @param {*} newInitialValue
     * @param {*} event
     */

  }, {
    key: "beginEditing",
    value: function beginEditing(newInitialValue, event) {
      if (this.state !== EditorState.VIRGIN) {
        return;
      }

      this.hot.view.scrollViewport(new _src.CellCoords(this.row, this.col));
      this.state = EditorState.EDITING; // Set the editor value only in the full edit mode. In other mode the focusable element has to be empty,
      // otherwise IME (editor for Asia users) doesn't work.

      if (this.isInFullEditMode()) {
        var stringifiedInitialValue = typeof newInitialValue === 'string' ? newInitialValue : (0, _mixed.stringify)(this.originalValue);
        this.setValue(stringifiedInitialValue);
      }

      this.open(event);
      this._opened = true;
      this.focus(); // only rerender the selections (FillHandle should disappear when beginediting is triggered)

      this.hot.view.render();
      this.hot.runHooks('afterBeginEditing', this.row, this.col);
    }
    /**
     * Finishes editing and start saving or restoring process for editing cell or last selected range.
     *
     * @param {Boolean} restoreOriginalValue If true, then closes editor without saving value from the editor into a cell.
     * @param {Boolean} ctrlDown If true, then saveValue will save editor's value to each cell in the last selected range.
     * @param {Function} callback
     */

  }, {
    key: "finishEditing",
    value: function finishEditing(restoreOriginalValue, ctrlDown, callback) {
      var _this = this;

      var val;

      if (callback) {
        var previousCloseCallback = this._closeCallback;

        this._closeCallback = function (result) {
          if (previousCloseCallback) {
            previousCloseCallback(result);
          }

          callback(result);

          _this.hot.view.render();
        };
      }

      if (this.isWaiting()) {
        return;
      }

      if (this.state === EditorState.VIRGIN) {
        this.hot._registerTimeout(function () {
          _this._fireCallbacks(true);
        });

        return;
      }

      if (this.state === EditorState.EDITING) {
        if (restoreOriginalValue) {
          this.cancelChanges();
          this.hot.view.render();
          return;
        }

        var value = this.getValue();

        if (this.hot.getSettings().trimWhitespace) {
          // We trim only string values
          val = [[typeof value === 'string' ? String.prototype.trim.call(value || '') : value]];
        } else {
          val = [[value]];
        }

        this.state = EditorState.WAITING;
        this.saveValue(val, ctrlDown);

        if (this.hot.getCellValidator(this.cellProperties)) {
          this.hot.addHookOnce('postAfterValidate', function (result) {
            _this.state = EditorState.FINISHED;

            _this.discardEditor(result);
          });
        } else {
          this.state = EditorState.FINISHED;
          this.discardEditor(true);
        }
      }
    }
    /**
     * Finishes editing without singout saving value.
     */

  }, {
    key: "cancelChanges",
    value: function cancelChanges() {
      this.state = EditorState.FINISHED;
      this.discardEditor();
    }
    /**
     * Verifies result of validation or closes editor if user's cancelled changes.
     *
     * @param {Boolean|undefined} result
     */

  }, {
    key: "discardEditor",
    value: function discardEditor(result) {
      if (this.state !== EditorState.FINISHED) {
        return;
      } // validator was defined and failed


      if (result === false && this.cellProperties.allowInvalid !== true) {
        this.hot.selectCell(this.row, this.col);
        this.focus();
        this.state = EditorState.EDITING;

        this._fireCallbacks(false);
      } else {
        this.close();
        this._opened = false;
        this._fullEditMode = false;
        this.state = EditorState.VIRGIN;

        this._fireCallbacks(true);
      }
    }
    /**
     * Switch editor into full edit mode. In this state navigation keys don't close editor. This mode is activated
     * automatically after hit ENTER or F2 key on the cell or while editing cell press F2 key.
     */

  }, {
    key: "enableFullEditMode",
    value: function enableFullEditMode() {
      this._fullEditMode = true;
    }
    /**
     * Checks if editor is in full edit mode.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isInFullEditMode",
    value: function isInFullEditMode() {
      return this._fullEditMode;
    }
    /**
     * Returns information whether the editor is open.
     */

  }, {
    key: "isOpened",
    value: function isOpened() {
      return this._opened;
    }
    /**
     * Returns information whether the editor is waiting, eg.: for async validation.
     */

  }, {
    key: "isWaiting",
    value: function isWaiting() {
      return this.state === EditorState.WAITING;
    }
    /**
     * Returns name of the overlay, where editor is placed.
     *
     * @private
     */

  }, {
    key: "checkEditorSection",
    value: function checkEditorSection() {
      var totalRows = this.hot.countRows();
      var section = '';

      if (this.row < this.hot.getSettings().fixedRowsTop) {
        if (this.col < this.hot.getSettings().fixedColumnsLeft) {
          section = 'top-left-corner';
        } else {
          section = 'top';
        }
      } else if (this.hot.getSettings().fixedRowsBottom && this.row >= totalRows - this.hot.getSettings().fixedRowsBottom) {
        if (this.col < this.hot.getSettings().fixedColumnsLeft) {
          section = 'bottom-left-corner';
        } else {
          section = 'bottom';
        }
      } else if (this.col < this.hot.getSettings().fixedColumnsLeft) {
        section = 'left';
      }

      return section;
    }
  }]);
  return BaseEditor;
}();

(0, _object.mixin)(BaseEditor, _hooksRefRegisterer.default);
var _default = BaseEditor;
exports.default = _default;

/***/ }),
/* 105 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalStringTrim = __webpack_require__(196);
var FORCED = __webpack_require__(521)('trim');

// `String.prototype.trim` method
// https://tc39.github.io/ecma262/#sec-string.prototype.trim
__webpack_require__(22)({ target: 'String', proto: true, forced: FORCED }, {
  trim: function trim() {
    return internalStringTrim(this, 3);
  }
});


/***/ }),
/* 106 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

/**
 * CellCoords holds cell coordinates (row, column) and few method to validate them and retrieve as an array or an object.
 *
 * @util
 */
var CellCoords =
/*#__PURE__*/
function () {
  function CellCoords(row, column) {
    (0, _classCallCheck2.default)(this, CellCoords);

    /**
     * Row index.
     *
     * @type {Number}
     */
    this.row = null;
    /**
     * Column index.
     *
     * @type {Number}
     */

    this.col = null;

    if (typeof row !== 'undefined' && typeof column !== 'undefined') {
      this.row = row;
      this.col = column;
    }
  }
  /**
   * Checks if given set of coordinates is valid in context of a given Walkontable instance.
   *
   * @param {Walkontable} wot A Walkontable instance.
   * @returns {Boolean}
   */


  (0, _createClass2.default)(CellCoords, [{
    key: "isValid",
    value: function isValid(wot) {
      // is it a valid cell index (0 or higher)
      if (this.row < 0 || this.col < 0) {
        return false;
      } // is selection within total rows and columns


      if (this.row >= wot.getSetting('totalRows') || this.col >= wot.getSetting('totalColumns')) {
        return false;
      }

      return true;
    }
    /**
     * Checks if this cell coordinates are the same as cell coordinates given as an argument.
     *
     * @param {CellCoords} cellCoords Cell coordinates to equal.
     * @returns {Boolean}
     */

  }, {
    key: "isEqual",
    value: function isEqual(cellCoords) {
      if (cellCoords === this) {
        return true;
      }

      return this.row === cellCoords.row && this.col === cellCoords.col;
    }
    /**
     * Checks if tested coordinates are positioned in south-east from this cell coordinates.
     *
     * @param {Object} testedCoords Cell coordinates to check.
     * @returns {Boolean}
     */

  }, {
    key: "isSouthEastOf",
    value: function isSouthEastOf(testedCoords) {
      return this.row >= testedCoords.row && this.col >= testedCoords.col;
    }
    /**
     * Checks if tested coordinates are positioned in north-east from this cell coordinates.
     *
     * @param {Object} testedCoords Cell coordinates to check.
     * @returns {Boolean}
     */

  }, {
    key: "isNorthWestOf",
    value: function isNorthWestOf(testedCoords) {
      return this.row <= testedCoords.row && this.col <= testedCoords.col;
    }
    /**
     * Checks if tested coordinates are positioned in south-west from this cell coordinates.
     *
     * @param {Object} testedCoords Cell coordinates to check.
     * @returns {Boolean}
     */

  }, {
    key: "isSouthWestOf",
    value: function isSouthWestOf(testedCoords) {
      return this.row >= testedCoords.row && this.col <= testedCoords.col;
    }
    /**
     * Checks if tested coordinates are positioned in north-east from this cell coordinates.
     *
     * @param {Object} testedCoords Cell coordinates to check.
     * @returns {Boolean}
     */

  }, {
    key: "isNorthEastOf",
    value: function isNorthEastOf(testedCoords) {
      return this.row <= testedCoords.row && this.col >= testedCoords.col;
    }
    /**
     * Converts CellCoords to literal object with `row` and `col` properties.
     *
     * @return {Object} Returns a literal object with `row` and `col` properties.
     */

  }, {
    key: "toObject",
    value: function toObject() {
      return {
        row: this.row,
        col: this.col
      };
    }
  }]);
  return CellCoords;
}();

var _default = CellCoords;
exports.default = _default;

/***/ }),
/* 107 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(40);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _autoResize = _interopRequireDefault(__webpack_require__(536));

var _browser = __webpack_require__(72);

var _baseEditor = _interopRequireWildcard(__webpack_require__(104));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _unicode = __webpack_require__(50);

var _event = __webpack_require__(31);

/**
 * @private
 * @editor TextEditor
 * @class TextEditor
 * @dependencies autoResize
 */
var TextEditor =
/*#__PURE__*/
function (_BaseEditor) {
  (0, _inherits2.default)(TextEditor, _BaseEditor);

  /**
   * @param {Handsontable} instance
   */
  function TextEditor(instance) {
    var _this;

    (0, _classCallCheck2.default)(this, TextEditor);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TextEditor).call(this, instance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Autoresize instance. Automagically resizes editor after changes.
     *
     * @private
     * @type {autoResize}
     */

    _this.autoResize = (0, _autoResize.default)();
    /**
     * Contains  `z-index` of the editor. Helps display editor on overlays on correct elevation.
     *
     * @private
     * @type {Number}
     */

    _this.holderZIndex = -1;
    /**
     * An TEXTAREA element.
     *
     * @private
     * @type {HTMLTextAreaElement}
     */

    _this.TEXTAREA = void 0;
    /**
     * Style declaration object of the TEXTAREA element.
     *
     * @private
     * @type {CSSStyleDeclaration}
     */

    _this.textareaStyle = void 0;
    /**
     * Parent element of the TEXTAREA.
     *
     * @private
     * @type {HTMLDivElement}
     */

    _this.TEXTAREA_PARENT = void 0;
    /**
     * Style declaration object of the TEXTAREA_PARENT element.
     *
     * @private
     * @type {CSSStyleDeclaration}
     */

    _this.textareaParentStyle = void 0;

    _this.createElements();

    _this.bindEvents();

    _this.hot.addHookOnce('afterDestroy', function () {
      return _this.destroy();
    });

    return _this;
  }
  /**
   * Gets current value from editable element.
   *
   * @returns {Number}
   */


  (0, _createClass2.default)(TextEditor, [{
    key: "getValue",
    value: function getValue() {
      return this.TEXTAREA.value;
    }
    /**
     * Sets new value into editable element.
     *
     * @param {*} newValue
     */

  }, {
    key: "setValue",
    value: function setValue(newValue) {
      this.TEXTAREA.value = newValue;
    }
    /**
     * Opens the editor and adjust its size.
     */

  }, {
    key: "open",
    value: function open() {
      var _this2 = this;

      this.refreshDimensions(); // need it instantly, to prevent https://github.com/handsontable/handsontable/issues/348

      this.showEditableElement();
      this.addHook('beforeKeyDown', function (event) {
        return _this2.onBeforeKeyDown(event);
      });
    }
    /**
     * Closes the editor.
     */

  }, {
    key: "close",
    value: function close() {
      this.autoResize.unObserve();

      if (this.hot.rootDocument.activeElement === this.TEXTAREA) {
        this.hot.listen(); // don't refocus the table if user focused some cell outside of HT on purpose
      }

      this.hideEditableElement();
      this.removeHooksByKey('beforeKeyDown');
    }
    /**
     * Prepares editor's meta data.
     *
     * @param {Number} row
     * @param {Number} col
     * @param {Number|String} prop
     * @param {HTMLTableCellElement} td
     * @param {*} originalValue
     * @param {Object} cellProperties
     */

  }, {
    key: "prepare",
    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
      var _this3 = this;

      var previousState = this.state;
      (0, _get2.default)((0, _getPrototypeOf2.default)(TextEditor.prototype), "prepare", this).call(this, row, col, prop, td, originalValue, cellProperties);

      if (!cellProperties.readOnly) {
        this.refreshDimensions(true);
        var allowInvalid = cellProperties.allowInvalid,
            fragmentSelection = cellProperties.fragmentSelection;

        if (allowInvalid) {
          this.TEXTAREA.value = ''; // Remove an empty space from texarea (added by copyPaste plugin to make copy/paste functionality work with IME)
        }

        if (previousState !== _baseEditor.EditorState.FINISHED) {
          this.hideEditableElement();
        } // @TODO: The fragmentSelection functionality is conflicted with IME. For this feature refocus has to
        // be disabled (to make IME working).


        var restoreFocus = !fragmentSelection;

        if (restoreFocus && !(0, _browser.isMobileBrowser)()) {
          this.hot._registerImmediate(function () {
            return _this3.focus(true);
          });
        }
      }
    }
    /**
     * Begins editing on a highlighted cell and hides fillHandle corner if was present.
     *
     * @param {*} newInitialValue
     * @param {*} event
     */

  }, {
    key: "beginEditing",
    value: function beginEditing(newInitialValue, event) {
      if (this.state !== _baseEditor.EditorState.VIRGIN) {
        return;
      }

      this.TEXTAREA.value = ''; // Remove an empty space from texarea (added by copyPaste plugin to make copy/paste functionality work with IME).

      (0, _get2.default)((0, _getPrototypeOf2.default)(TextEditor.prototype), "beginEditing", this).call(this, newInitialValue, event);
    }
    /**
     * Sets focus state on the select element.
     *
     * @param {Boolean} [safeFocus=false] If `true` select element only when is handsontableInput. Otherwise sets focus on this element.
     * If focus is calling without param textarea need be select and set caret position.
     */

  }, {
    key: "focus",
    value: function focus() {
      var safeFocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      // For IME editor textarea element must be focused using ".select" method. Using ".focus" browser automatically scroll into
      // the focused element which is undesire effect.
      if (safeFocus) {
        (0, _element.selectElementIfAllowed)(this.TEXTAREA);
      } else {
        this.TEXTAREA.select();
        (0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length);
      }
    }
    /**
     * Creates an editor's elements and adds necessary CSS classnames.
     */

  }, {
    key: "createElements",
    value: function createElements() {
      var rootDocument = this.hot.rootDocument;
      this.TEXTAREA = rootDocument.createElement('TEXTAREA');
      this.TEXTAREA.tabIndex = -1;
      (0, _element.addClass)(this.TEXTAREA, 'handsontableInput');
      this.textareaStyle = this.TEXTAREA.style;
      this.textareaStyle.width = 0;
      this.textareaStyle.height = 0;
      this.textareaStyle.overflowY = 'visible';
      this.TEXTAREA_PARENT = rootDocument.createElement('DIV');
      (0, _element.addClass)(this.TEXTAREA_PARENT, 'handsontableInputHolder');
      this.textareaParentStyle = this.TEXTAREA_PARENT.style;
      this.textareaParentStyle.zIndex = '-1';
      this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
      this.hot.rootElement.appendChild(this.TEXTAREA_PARENT);
    }
    /**
     * Gets HTMLTableCellElement of the edited cell if exist.
     *
     * @private
     * @returns {HTMLTableCellElement|undefined}
     */

  }, {
    key: "getEditedCell",
    value: function getEditedCell() {
      var editorSection = this.checkEditorSection();
      var editedCell;

      switch (editorSection) {
        case 'top':
          editedCell = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.holderZIndex = 101;
          break;

        case 'top-left-corner':
          editedCell = this.hot.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.holderZIndex = 103;
          break;

        case 'bottom-left-corner':
          editedCell = this.hot.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.holderZIndex = 103;
          break;

        case 'left':
          editedCell = this.hot.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.holderZIndex = 102;
          break;

        case 'bottom':
          editedCell = this.hot.view.wt.wtOverlays.bottomOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.holderZIndex = 102;
          break;

        default:
          editedCell = this.hot.getCell(this.row, this.col);
          this.holderZIndex = -1;
          break;
      }

      return editedCell < 0 ? void 0 : editedCell;
    }
    /**
     * Moves an editable element out of the viewport, but element must be able to hold focus for IME support.
     *
     * @private
     */

  }, {
    key: "hideEditableElement",
    value: function hideEditableElement() {
      if ((0, _browser.isIE)() || (0, _browser.isEdge)()) {
        this.textareaStyle.textIndent = '-99999px';
      }

      this.textareaStyle.overflowY = 'visible';
      this.textareaParentStyle.opacity = '0';
      this.textareaParentStyle.height = '1px';
      this.textareaParentStyle.zIndex = '-1';
    }
    /**
     * Resets an editable element position.
     *
     * @private
     */

  }, {
    key: "showEditableElement",
    value: function showEditableElement() {
      this.textareaParentStyle.height = '';
      this.textareaParentStyle.overflow = '';
      this.textareaParentStyle.position = '';
      this.textareaParentStyle.right = 'auto';
      this.textareaParentStyle.zIndex = this.holderZIndex >= 0 ? this.holderZIndex : '';
      this.textareaParentStyle.opacity = '1';
      this.textareaStyle.textIndent = '';
      this.textareaStyle.overflowY = 'auto';
    }
    /**
     * Refreshes editor's value using source data.
     *
     * @private
     */

  }, {
    key: "refreshValue",
    value: function refreshValue() {
      var physicalRow = this.hot.toPhysicalRow(this.row);
      var sourceData = this.hot.getSourceDataAtCell(physicalRow, this.col);
      this.originalValue = sourceData;
      this.setValue(sourceData);
      this.refreshDimensions();
    }
    /**
     * Refreshes editor's size and position.
     *
     * @private
     * @param {Boolean} force
     */

  }, {
    key: "refreshDimensions",
    value: function refreshDimensions() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (this.state !== _baseEditor.EditorState.EDITING && !force) {
        return;
      }

      this.TD = this.getEditedCell(); // TD is outside of the viewport.

      if (!this.TD) {
        if (!force) {
          this.close();
        }

        return;
      }

      var _this$hot$view$wt = this.hot.view.wt,
          wtOverlays = _this$hot$view$wt.wtOverlays,
          wtViewport = _this$hot$view$wt.wtViewport;
      var currentOffset = (0, _element.offset)(this.TD);
      var containerOffset = (0, _element.offset)(this.hot.rootElement);
      var scrollableContainerTop = wtOverlays.topOverlay.holder;
      var scrollableContainerLeft = wtOverlays.leftOverlay.holder;
      var totalRowsCount = this.hot.countRows();
      var containerScrollTop = scrollableContainerTop !== this.hot.rootWindow ? scrollableContainerTop.scrollTop : 0;
      var containerScrollLeft = scrollableContainerLeft !== this.hot.rootWindow ? scrollableContainerLeft.scrollLeft : 0;
      var editorSection = this.checkEditorSection();
      var scrollTop = ['', 'left'].includes(editorSection) ? containerScrollTop : 0;
      var scrollLeft = ['', 'top', 'bottom'].includes(editorSection) ? containerScrollLeft : 0; // If colHeaders is disabled, cells in the first row have border-top

      var editTopModifier = currentOffset.top === containerOffset.top ? 0 : 1;
      var settings = this.hot.getSettings();
      var colHeadersCount = this.hot.hasColHeaders();
      var backgroundColor = this.TD.style.backgroundColor;
      var editTop = currentOffset.top - containerOffset.top - editTopModifier - scrollTop;
      var editLeft = currentOffset.left - containerOffset.left - 1 - scrollLeft;
      var cssTransformOffset; // TODO: Refactor this to the new instance.getCell method (from #ply-59), after 0.12.1 is released

      switch (editorSection) {
        case 'top':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'left':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'top-left-corner':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'bottom-left-corner':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'bottom':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
          break;

        default:
          break;
      }

      if (colHeadersCount && this.hot.getSelectedLast()[0] === 0 || settings.fixedRowsBottom && this.hot.getSelectedLast()[0] === totalRowsCount - settings.fixedRowsBottom) {
        editTop += 1;
      }

      if (this.hot.getSelectedLast()[1] === 0) {
        editLeft += 1;
      }

      if (cssTransformOffset && cssTransformOffset !== -1) {
        this.textareaParentStyle[cssTransformOffset[0]] = cssTransformOffset[1];
      } else {
        (0, _element.resetCssTransform)(this.TEXTAREA_PARENT);
      }

      this.textareaParentStyle.top = "".concat(editTop, "px");
      this.textareaParentStyle.left = "".concat(editLeft, "px");
      this.showEditableElement();
      var firstRowOffset = wtViewport.rowsRenderCalculator.startPosition;
      var firstColumnOffset = wtViewport.columnsRenderCalculator.startPosition;
      var horizontalScrollPosition = wtOverlays.leftOverlay.getScrollPosition();
      var verticalScrollPosition = wtOverlays.topOverlay.getScrollPosition();
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.hot.rootDocument);
      var cellTopOffset = this.TD.offsetTop + firstRowOffset - verticalScrollPosition;
      var cellLeftOffset = this.TD.offsetLeft + firstColumnOffset - horizontalScrollPosition;
      var width = (0, _element.innerWidth)(this.TD) - 8;
      var actualVerticalScrollbarWidth = (0, _element.hasVerticalScrollbar)(scrollableContainerTop) ? scrollbarWidth : 0;
      var actualHorizontalScrollbarWidth = (0, _element.hasHorizontalScrollbar)(scrollableContainerLeft) ? scrollbarWidth : 0;
      var maxWidth = this.hot.view.maximumVisibleElementWidth(cellLeftOffset) - 9 - actualVerticalScrollbarWidth;
      var height = this.TD.scrollHeight + 1;
      var maxHeight = Math.max(this.hot.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth, 23);
      var cellComputedStyle = (0, _element.getComputedStyle)(this.TD, this.hot.rootWindow);
      this.TEXTAREA.style.fontSize = cellComputedStyle.fontSize;
      this.TEXTAREA.style.fontFamily = cellComputedStyle.fontFamily;
      this.TEXTAREA.style.backgroundColor = backgroundColor;
      this.autoResize.init(this.TEXTAREA, {
        minHeight: Math.min(height, maxHeight),
        maxHeight: maxHeight,
        // TEXTAREA should never be higher than visible part of the viewport (should not cover the scrollbar)
        minWidth: Math.min(width, maxWidth),
        maxWidth: maxWidth // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)

      }, true);
    }
    /**
     * Binds events and hooks.
     *
     * @private
     */

  }, {
    key: "bindEvents",
    value: function bindEvents() {
      var _this4 = this;

      this.eventManager.addEventListener(this.TEXTAREA, 'cut', function (event) {
        return (0, _event.stopPropagation)(event);
      });
      this.eventManager.addEventListener(this.TEXTAREA, 'paste', function (event) {
        return (0, _event.stopPropagation)(event);
      });
      this.addHook('afterScrollHorizontally', function () {
        return _this4.refreshDimensions();
      });
      this.addHook('afterScrollVertically', function () {
        return _this4.refreshDimensions();
      });
      this.addHook('afterColumnResize', function () {
        _this4.refreshDimensions();

        _this4.focus();
      });
      this.addHook('afterRowResize', function () {
        _this4.refreshDimensions();

        _this4.focus();
      });
    }
    /**
     * Ugly hack for autocompleteEditor.
     *
     * @private
     */

  }, {
    key: "allowKeyEventPropagation",
    value: function allowKeyEventPropagation() {}
    /**
     * Destroys the internal event manager and clears attached hooks.
     *
     * @private
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.eventManager.destroy();
      this.clearHooks();
    }
    /**
     * onBeforeKeyDown callback.
     *
     * @param {Event} event
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown(event) {
      // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
      var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; // Process only events that have been fired in the editor

      if (event.target !== this.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) {
        return;
      }

      switch (event.keyCode) {
        case _unicode.KEY_CODES.ARROW_RIGHT:
          if (this.isInFullEditMode()) {
            if (!this.isWaiting() && !this.allowKeyEventPropagation(event.keyCode)) {
              (0, _event.stopImmediatePropagation)(event);
            }
          }

          break;

        case _unicode.KEY_CODES.ARROW_LEFT:
          if (this.isInFullEditMode()) {
            if (!this.isWaiting() && !this.allowKeyEventPropagation(event.keyCode)) {
              (0, _event.stopImmediatePropagation)(event);
            }
          }

          break;

        case _unicode.KEY_CODES.ARROW_UP:
        case _unicode.KEY_CODES.ARROW_DOWN:
          if (this.isInFullEditMode()) {
            if (!this.isWaiting() && !this.allowKeyEventPropagation(event.keyCode)) {
              (0, _event.stopImmediatePropagation)(event);
            }
          }

          break;

        case _unicode.KEY_CODES.ENTER:
          {
            var isMultipleSelection = this.hot.selection.isMultiple();

            if (ctrlDown && !isMultipleSelection || event.altKey) {
              // if ctrl+enter or alt+enter, add new line
              if (this.isOpened()) {
                var caretPosition = (0, _element.getCaretPosition)(this.TEXTAREA);
                var value = this.getValue();
                var newValue = "".concat(value.slice(0, caretPosition), "\n").concat(value.slice(caretPosition));
                this.setValue(newValue);
                (0, _element.setCaretPosition)(this.TEXTAREA, caretPosition + 1);
              } else {
                this.beginEditing("".concat(this.originalValue, "\n"));
              }

              (0, _event.stopImmediatePropagation)(event);
            }

            event.preventDefault(); // don't add newline to field

            break;
          }

        case _unicode.KEY_CODES.BACKSPACE:
        case _unicode.KEY_CODES.DELETE:
        case _unicode.KEY_CODES.HOME:
        case _unicode.KEY_CODES.END:
          (0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context)

          break;

        default:
          break;
      }

      if ([_unicode.KEY_CODES.ARROW_UP, _unicode.KEY_CODES.ARROW_RIGHT, _unicode.KEY_CODES.ARROW_DOWN, _unicode.KEY_CODES.ARROW_LEFT].indexOf(event.keyCode) === -1) {
        this.autoResize.resize(String.fromCharCode(event.keyCode));
      }
    }
  }]);
  return TextEditor;
}(_baseEditor.default);

var _default = TextEditor;
exports.default = _default;

/***/ }),
/* 108 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(59);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(64);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.sortComparison = sortComparison;
exports.toVisualValue = toVisualValue;
exports.createArrayAssertion = createArrayAssertion;
exports.toEmptyString = toEmptyString;
exports.unifyColumnValues = unifyColumnValues;
exports.intersectValues = intersectValues;

var _feature = __webpack_require__(73);

var _array = __webpack_require__(3);

var sortCompare = (0, _feature.getComparisonFunction)();
/**
 * Comparison function for sorting purposes.
 *
 * @param {*} a
 * @param {*} b
 * @returns {Number} Returns number from -1 to 1.
 */

function sortComparison(a, b) {
  if (typeof a === 'number' && typeof b === 'number') {
    return a - b;
  }

  return sortCompare(a, b);
}
/**
 * Convert raw value into visual value.
 *
 * @param {*} value
 * @param {String} defaultEmptyValue Default value for empty cells.
 * @returns {*}
 */


function toVisualValue(value, defaultEmptyValue) {
  var visualValue = value;

  if (visualValue === '') {
    visualValue = "(".concat(defaultEmptyValue, ")");
  }

  return visualValue;
}

var SUPPORT_SET_CONSTRUCTOR = new Set([1]).has(1);
var SUPPORT_FAST_DEDUPE = SUPPORT_SET_CONSTRUCTOR && typeof Array.from === 'function';
/**
 * Create an array assertion to compare if an element exists in that array (in a more efficient way than .indexOf).
 *
 * @param {Array} initialData Values to compare.
 * @returns {Function}
 */

function createArrayAssertion(initialData) {
  var dataset = initialData;

  if (SUPPORT_SET_CONSTRUCTOR) {
    dataset = new Set(dataset);
  }

  return function (value) {
    var result;

    if (SUPPORT_SET_CONSTRUCTOR) {
      result = dataset.has(value);
    } else {
      /* eslint-disable no-bitwise */
      result = !!~dataset.indexOf(value);
    }

    return result;
  };
}
/**
 * Convert empty-ish values like null and undefined to an empty string.
 *
 * @param value Value to check.
 * @returns {String}
 */


function toEmptyString(value) {
  return value === null || value === void 0 ? '' : value;
}
/**
 * Unify column values (replace `null` and `undefined` values into empty string, unique values and sort them).
 *
 * @param {Array} values An array of values.
 * @returns {Array}
 */


function unifyColumnValues(values) {
  var unifiedValues = values;

  if (SUPPORT_FAST_DEDUPE) {
    unifiedValues = Array.from(new Set(unifiedValues));
  } else {
    unifiedValues = (0, _array.arrayUnique)(unifiedValues);
  }

  unifiedValues = unifiedValues.sort(function (a, b) {
    if (typeof a === 'number' && typeof b === 'number') {
      return a - b;
    }

    if (a === b) {
      return 0;
    }

    return a > b ? 1 : -1;
  });
  return unifiedValues;
}
/**
 * Intersect 'base' values with 'selected' values and return an array of object.
 *
 * @param {Array} base An array of base values.
 * @param {Array} selected An array of selected values.
 * @param {String} defaultEmptyValue Default value for empty cells.
 * @param {Function} [callback] A callback function which is invoked for every item in an array.
 * @returns {Array}
 */


function intersectValues(base, selected, defaultEmptyValue, callback) {
  var result = [];
  var same = base === selected;
  var selectedItemsAssertion;

  if (!same) {
    selectedItemsAssertion = createArrayAssertion(selected);
  }

  (0, _array.arrayEach)(base, function (value) {
    var checked = false;

    if (same || selectedItemsAssertion(value)) {
      checked = true;
    }

    var item = {
      checked: checked,
      value: value,
      visualValue: toVisualValue(value, defaultEmptyValue)
    };

    if (callback) {
      callback(item);
    }

    result.push(item);
  });
  return result;
}

/***/ }),
/* 109 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(51);

exports.__esModule = true;
exports.getOperationFunc = getOperationFunc;
exports.getOperationName = getOperationName;
exports.registerOperation = registerOperation;
exports.operations = void 0;
var operations = {};
/**
 * Get operation closure with pre-bound arguments.
 *
 * @param {String} id Operator `id`.
 * @returns {Function}
 */

exports.operations = operations;

function getOperationFunc(id) {
  if (!operations[id]) {
    throw Error("Operation with id \"".concat(id, "\" does not exist."));
  }

  var func = operations[id].func;
  return function (conditions, value) {
    return func(conditions, value);
  };
}
/**
 * Return name of operation which is displayed inside UI component, basing on it's `id`.
 *
 * @param {String} id `Id` of operation.
 */


function getOperationName(id) {
  return operations[id].name;
}
/**
 * Operator registerer.
 *
 * @param {String} id Operation `id`.
 * @param {String} name Operation name which is displayed inside UI component.
 * @param {Function} func Operation function.
 */


function registerOperation(id, name, func) {
  operations[id] = {
    name: name,
    func: func
  };
}

/***/ }),
/* 110 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(138);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var C = _interopRequireWildcard(__webpack_require__(11));

var STATE_BUILT = 'built';
var STATE_BUILDING = 'building';
var EVENTS_TO_REGISTER = ['click', 'input', 'keydown', 'keypress', 'keyup', 'focus', 'blur', 'change'];
/**
 * @class
 * @private
 */

var BaseUI =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(BaseUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        className: '',
        value: '',
        tagName: 'div',
        children: [],
        wrapIt: true
      });
    }
  }]);

  function BaseUI(hotInstance, options) {
    (0, _classCallCheck2.default)(this, BaseUI);

    /**
     * Instance of Handsontable.
     *
     * @type {Core}
     */
    this.hot = hotInstance;
    /**
     * Instance of EventManager.
     *
     * @type {EventManager}
     */

    this.eventManager = new _eventManager.default(this);
    /**
     * List of element options.
     *
     * @type {Object}
     */

    this.options = (0, _object.extend)(BaseUI.DEFAULTS, options);
    /**
     * Build root DOM element.
     *
     * @type {Element}
     * @private
     */

    this._element = this.hot.rootDocument.createElement(this.options.wrapIt ? 'div' : this.options.tagName);
    /**
     * Flag which determines build state of element.
     *
     * @type {Boolean}
     */

    this.buildState = false;
  }
  /**
   * Set the element value.
   *
   * @returns {*}
   */


  (0, _createClass2.default)(BaseUI, [{
    key: "setValue",
    value: function setValue(value) {
      this.options.value = value;
      this.update();
    }
    /**
     * Get the element value.
     *
     * @returns {*}
     */

  }, {
    key: "getValue",
    value: function getValue() {
      return this.options.value;
    }
    /**
     * Get element as a DOM object.
     *
     * @returns {Element}
     */

  }, {
    key: "isBuilt",

    /**
     * Check if element was built (built whole DOM structure).
     *
     * @returns {Boolean}
     */
    value: function isBuilt() {
      return this.buildState === STATE_BUILT;
    }
    /**
     * Translate value if it is possible. It's checked if value belongs to namespace of translated phrases.
     *
     * @param {*} value Value which will may be translated.
     * @returns {*} Translated value if translation was possible, original value otherwise.
     */

  }, {
    key: "translateIfPossible",
    value: function translateIfPossible(value) {
      if (typeof value === 'string' && value.startsWith(C.FILTERS_NAMESPACE)) {
        return this.hot.getTranslatedPhrase(value);
      }

      return value;
    }
    /**
     * Build DOM structure.
     */

  }, {
    key: "build",
    value: function build() {
      var _this = this;

      var registerEvent = function registerEvent(element, eventName) {
        _this.eventManager.addEventListener(element, eventName, function (event) {
          return _this.runLocalHooks(eventName, event, _this);
        });
      };

      if (!this.buildState) {
        this.buildState = STATE_BUILDING;
      }

      if (this.options.className) {
        (0, _element.addClass)(this._element, this.options.className);
      }

      if (this.options.children.length) {
        (0, _array.arrayEach)(this.options.children, function (element) {
          return _this._element.appendChild(element.element);
        });
      } else if (this.options.wrapIt) {
        var element = this.hot.rootDocument.createElement(this.options.tagName);
        (0, _object.objectEach)(this.options, function (value, key) {
          if (element[key] !== void 0 && key !== 'className' && key !== 'tagName' && key !== 'children') {
            element[key] = _this.translateIfPossible(value);
          }
        });

        this._element.appendChild(element);

        (0, _array.arrayEach)(EVENTS_TO_REGISTER, function (eventName) {
          return registerEvent(element, eventName);
        });
      } else {
        (0, _array.arrayEach)(EVENTS_TO_REGISTER, function (eventName) {
          return registerEvent(_this._element, eventName);
        });
      }
    }
    /**
     * Update DOM structure.
     */

  }, {
    key: "update",
    value: function update() {}
    /**
     * Reset to initial state.
     */

  }, {
    key: "reset",
    value: function reset() {
      this.options.value = '';
      this.update();
    }
    /**
     * Show element.
     */

  }, {
    key: "show",
    value: function show() {
      this.element.style.display = '';
    }
    /**
     * Hide element.
     */

  }, {
    key: "hide",
    value: function hide() {
      this.element.style.display = 'none';
    }
    /**
     * Focus element.
     */

  }, {
    key: "focus",
    value: function focus() {}
  }, {
    key: "destroy",
    value: function destroy() {
      this.eventManager.destroy();
      this.eventManager = null;
      this.hot = null;

      if (this._element.parentNode) {
        this._element.parentNode.removeChild(this._element);
      }

      this._element = null;
    }
  }, {
    key: "element",
    get: function get() {
      if (this.buildState === STATE_BUILDING) {
        return this._element;
      }

      if (this.buildState === STATE_BUILT) {
        this.update();
        return this._element;
      }

      this.buildState = STATE_BUILDING;
      this.build();
      this.buildState = STATE_BUILT;
      return this._element;
    }
  }]);
  return BaseUI;
}();

(0, _object.mixin)(BaseUI, _localHooks.default);
var _default = BaseUI;
exports.default = _default;

/***/ }),
/* 111 */
/***/ (function(module, exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory();
	else {}
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 14);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

exports.nil = new Error('#NULL!');
exports.div0 = new Error('#DIV/0!');
exports.value = new Error('#VALUE!');
exports.ref = new Error('#REF!');
exports.name = new Error('#NAME?');
exports.num = new Error('#NUM!');
exports.na = new Error('#N/A');
exports.error = new Error('#ERROR!');
exports.data = new Error('#GETTING_DATA');


/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);

exports.flattenShallow = function(array) {
  if (!array || !array.reduce) {
    return array;
  }

  return array.reduce(function(a, b) {
    var aIsArray = Array.isArray(a);
    var bIsArray = Array.isArray(b);

    if (aIsArray && bIsArray ) {
      return a.concat(b);
    }
    if (aIsArray) {
      a.push(b);

      return a;
    }
    if (bIsArray) {
      return [a].concat(b);
    }

    return [a, b];
  });
};

exports.isFlat = function(array) {
  if (!array) {
    return false;
  }

  for (var i = 0; i < array.length; ++i) {
    if (Array.isArray(array[i])) {
      return false;
    }
  }

  return true;
};

exports.flatten = function() {
  var result = exports.argsToArray.apply(null, arguments);

  while (!exports.isFlat(result)) {
    result = exports.flattenShallow(result);
  }

  return result;
};

exports.argsToArray = function(args) {
  var result = [];

  exports.arrayEach(args, function(value) {
    result.push(value);
  });

  return result;
};

exports.numbers = function() {
  var possibleNumbers = this.flatten.apply(null, arguments);
  return possibleNumbers.filter(function(el) {
    return typeof el === 'number';
  });
};

exports.cleanFloat = function(number) {
  var power = 1e14;
  return Math.round(number * power) / power;
};

exports.parseBool = function(bool) {
  if (typeof bool === 'boolean') {
    return bool;
  }

  if (bool instanceof Error) {
    return bool;
  }

  if (typeof bool === 'number') {
    return bool !== 0;
  }

  if (typeof bool === 'string') {
    var up = bool.toUpperCase();
    if (up === 'TRUE') {
      return true;
    }

    if (up === 'FALSE') {
      return false;
    }
  }

  if (bool instanceof Date && !isNaN(bool)) {
    return true;
  }

  return error.value;
};

exports.parseNumber = function(string) {
  if (string === undefined || string === '') {
    return error.value;
  }
  if (!isNaN(string)) {
    return parseFloat(string);
  }

  return error.value;
};

exports.parseNumberArray = function(arr) {
  var len;

  if (!arr || (len = arr.length) === 0) {
    return error.value;
  }

  var parsed;

  while (len--) {
    parsed = exports.parseNumber(arr[len]);
    if (parsed === error.value) {
      return parsed;
    }
    arr[len] = parsed;
  }

  return arr;
};

exports.parseMatrix = function(matrix) {
  var n;

  if (!matrix || (n = matrix.length) === 0) {
    return error.value;
  }
  var pnarr;

  for (var i = 0; i < matrix.length; i++) {
    pnarr = exports.parseNumberArray(matrix[i]);
    matrix[i] = pnarr;

    if (pnarr instanceof Error) {
      return pnarr;
    }
  }

  return matrix;
};

var d1900 = new Date(Date.UTC(1900, 0, 1));
exports.parseDate = function(date) {
  if (!isNaN(date)) {
    if (date instanceof Date) {
      return new Date(date);
    }
    var d = parseInt(date, 10);
    if (d < 0) {
      return error.num;
    }
    if (d <= 60) {
      return new Date(d1900.getTime() + (d - 1) * 86400000);
    }
    return new Date(d1900.getTime() + (d - 2) * 86400000);
  }
  if (typeof date === 'string') {
    date = new Date(date);
    if (!isNaN(date)) {
      return date;
    }
  }
  return error.value;
};

exports.parseDateArray = function(arr) {
  var len = arr.length;
  var parsed;
  while (len--) {
    parsed = this.parseDate(arr[len]);
    if (parsed === error.value) {
      return parsed;
    }
    arr[len] = parsed;
  }
  return arr;
};

exports.anyIsError = function() {
  var n = arguments.length;
  while (n--) {
    if (arguments[n] instanceof Error) {
      return true;
    }
  }
  return false;
};

exports.arrayValuesToNumbers = function(arr) {
  var n = arr.length;
  var el;
  while (n--) {
    el = arr[n];
    if (typeof el === 'number') {
      continue;
    }
    if (el === true) {
      arr[n] = 1;
      continue;
    }
    if (el === false) {
      arr[n] = 0;
      continue;
    }
    if (typeof el === 'string') {
      var number = this.parseNumber(el);
      if (number instanceof Error) {
        arr[n] = 0;
      } else {
        arr[n] = number;
      }
    }
  }
  return arr;
};

exports.rest = function(array, idx) {
  idx = idx || 1;
  if (!array || typeof array.slice !== 'function') {
    return array;
  }
  return array.slice(idx);
};

exports.initial = function(array, idx) {
  idx = idx || 1;
  if (!array || typeof array.slice !== 'function') {
    return array;
  }
  return array.slice(0, array.length - idx);
};

exports.arrayEach = function(array, iteratee) {
  var index = -1, length = array.length;

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }

  return array;
};

exports.transpose = function(matrix) {
  if(!matrix) {
    return error.value;
  }

  return matrix[0].map(function(col, i) {
    return matrix.map(function(row) {
      return row[i];
    });
  });
};


/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;

var _errors;

exports['default'] = error;
exports.isValidStrict = isValidStrict;
var ERROR = exports.ERROR = 'ERROR';
var ERROR_DIV_ZERO = exports.ERROR_DIV_ZERO = 'DIV/0';
var ERROR_NAME = exports.ERROR_NAME = 'NAME';
var ERROR_NOT_AVAILABLE = exports.ERROR_NOT_AVAILABLE = 'N/A';
var ERROR_NULL = exports.ERROR_NULL = 'NULL';
var ERROR_NUM = exports.ERROR_NUM = 'NUM';
var ERROR_REF = exports.ERROR_REF = 'REF';
var ERROR_VALUE = exports.ERROR_VALUE = 'VALUE';

var errors = (_errors = {}, _errors[ERROR] = '#ERROR!', _errors[ERROR_DIV_ZERO] = '#DIV/0!', _errors[ERROR_NAME] = '#NAME?', _errors[ERROR_NOT_AVAILABLE] = '#N/A', _errors[ERROR_NULL] = '#NULL!', _errors[ERROR_NUM] = '#NUM!', _errors[ERROR_REF] = '#REF!', _errors[ERROR_VALUE] = '#VALUE!', _errors);

/**
 * Return error type based on provided error id.
 *
 * @param {String} type Error type.
 * @returns {String|null} Returns error id.
 */
function error(type) {
  var result = void 0;

  type = (type + '').replace(/#|!|\?/g, '');

  if (errors[type]) {
    result = errors[type];
  }

  return result ? result : null;
}

/**
 * Check if error type is strict valid with knows errors.
 *
 * @param {String} Error type.
 * @return {Boolean}
 */
function isValidStrict(type) {
  var valid = false;

  for (var i in errors) {
    if (Object.prototype.hasOwnProperty.call(errors, i) && errors[i] === type) {
      valid = true;
      break;
    }
  }

  return valid;
}

/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.toNumber = toNumber;
exports.invertNumber = invertNumber;
/**
 * Convert value into number.
 *
 * @param {String|Number} number
 * @returns {*}
 */
function toNumber(number) {
  var result = void 0;

  if (typeof number === 'number') {
    result = number;
  } else if (typeof number === 'string') {
    result = number.indexOf('.') > -1 ? parseFloat(number) : parseInt(number, 10);
  }

  return result;
}

/**
 * Invert provided number.
 *
 * @param {Number} number
 * @returns {Number} Returns inverted number.
 */
function invertNumber(number) {
  return -1 * toNumber(number);
}

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

var utils = __webpack_require__(1);
var error = __webpack_require__(0);
var statistical = __webpack_require__(5);
var information = __webpack_require__(7);

exports.ABS = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.abs(number);

  return result;
};

exports.ACOS = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.acos(number);

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.ACOSH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.log(number + Math.sqrt(number * number - 1));

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.ACOT = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.atan(1 / number);

  return result;
};

exports.ACOTH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = 0.5 * Math.log((number + 1) / (number - 1));

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

//TODO: use options
exports.AGGREGATE = function(function_num, options, ref1, ref2) {
  function_num = utils.parseNumber(function_num);
  options = utils.parseNumber(function_num);
  if (utils.anyIsError(function_num, options)) {
    return error.value;
  }
  switch (function_num) {
    case 1:
      return statistical.AVERAGE(ref1);
    case 2:
      return statistical.COUNT(ref1);
    case 3:
      return statistical.COUNTA(ref1);
    case 4:
      return statistical.MAX(ref1);
    case 5:
      return statistical.MIN(ref1);
    case 6:
      return exports.PRODUCT(ref1);
    case 7:
      return statistical.STDEV.S(ref1);
    case 8:
      return statistical.STDEV.P(ref1);
    case 9:
      return exports.SUM(ref1);
    case 10:
      return statistical.VAR.S(ref1);
    case 11:
      return statistical.VAR.P(ref1);
    case 12:
      return statistical.MEDIAN(ref1);
    case 13:
      return statistical.MODE.SNGL(ref1);
    case 14:
      return statistical.LARGE(ref1, ref2);
    case 15:
      return statistical.SMALL(ref1, ref2);
    case 16:
      return statistical.PERCENTILE.INC(ref1, ref2);
    case 17:
      return statistical.QUARTILE.INC(ref1, ref2);
    case 18:
      return statistical.PERCENTILE.EXC(ref1, ref2);
    case 19:
      return statistical.QUARTILE.EXC(ref1, ref2);
  }
};

exports.ARABIC = function(text) {
  // Credits: Rafa? Kukawski
  if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(text)) {
    return error.value;
  }
  var r = 0;
  text.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
    r += {
      M: 1000,
      CM: 900,
      D: 500,
      CD: 400,
      C: 100,
      XC: 90,
      L: 50,
      XL: 40,
      X: 10,
      IX: 9,
      V: 5,
      IV: 4,
      I: 1
    }[i];
  });
  return r;
};

exports.ASIN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.asin(number);

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.ASINH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.log(number + Math.sqrt(number * number + 1));
};

exports.ATAN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.atan(number);
};

exports.ATAN2 = function(number_x, number_y) {
  number_x = utils.parseNumber(number_x);
  number_y = utils.parseNumber(number_y);
  if (utils.anyIsError(number_x, number_y)) {
    return error.value;
  }
  return Math.atan2(number_x, number_y);
};

exports.ATANH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var result = Math.log((1 + number) / (1 - number)) / 2;

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.BASE = function(number, radix, min_length) {
  min_length = min_length || 0;

  number = utils.parseNumber(number);
  radix = utils.parseNumber(radix);
  min_length = utils.parseNumber(min_length);
  if (utils.anyIsError(number, radix, min_length)) {
    return error.value;
  }
  min_length = (min_length === undefined) ? 0 : min_length;
  var result = number.toString(radix);
  return new Array(Math.max(min_length + 1 - result.length, 0)).join('0') + result;
};

exports.CEILING = function(number, significance, mode) {
  significance = (significance === undefined) ? 1 : Math.abs(significance);
  mode = mode || 0;

  number = utils.parseNumber(number);
  significance = utils.parseNumber(significance);
  mode = utils.parseNumber(mode);
  if (utils.anyIsError(number, significance, mode)) {
    return error.value;
  }
  if (significance === 0) {
    return 0;
  }
  var precision = -Math.floor(Math.log(significance) / Math.log(10));
  if (number >= 0) {
    return exports.ROUND(Math.ceil(number / significance) * significance, precision);
  } else {
    if (mode === 0) {
      return -exports.ROUND(Math.floor(Math.abs(number) / significance) * significance, precision);
    } else {
      return -exports.ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision);
    }
  }
};

exports.CEILING.MATH = exports.CEILING;

exports.CEILING.PRECISE = exports.CEILING;

exports.COMBIN = function(number, number_chosen) {
  number = utils.parseNumber(number);
  number_chosen = utils.parseNumber(number_chosen);
  if (utils.anyIsError(number, number_chosen)) {
    return error.value;
  }
  return exports.FACT(number) / (exports.FACT(number_chosen) * exports.FACT(number - number_chosen));
};

exports.COMBINA = function(number, number_chosen) {
  number = utils.parseNumber(number);
  number_chosen = utils.parseNumber(number_chosen);
  if (utils.anyIsError(number, number_chosen)) {
    return error.value;
  }
  return (number === 0 && number_chosen === 0) ? 1 : exports.COMBIN(number + number_chosen - 1, number - 1);
};

exports.COS = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.cos(number);
};

exports.COSH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return (Math.exp(number) + Math.exp(-number)) / 2;
};

exports.COT = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return 1 / Math.tan(number);
};

exports.COTH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var e2 = Math.exp(2 * number);
  return (e2 + 1) / (e2 - 1);
};

exports.CSC = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return 1 / Math.sin(number);
};

exports.CSCH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return 2 / (Math.exp(number) - Math.exp(-number));
};

exports.DECIMAL = function(number, radix) {
  if (arguments.length < 1) {
    return error.value;
  }

  return parseInt(number, radix);
};

exports.DEGREES = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return number * 180 / Math.PI;
};

exports.EVEN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return exports.CEILING(number, -2, -1);
};

exports.EXP = function(number) {
  if (arguments.length < 1) {
    return error.na;
  }
  if (typeof number !== 'number' || arguments.length > 1) {
    return error.error;
  }

  number = Math.exp(number);

  return number;
};

var MEMOIZED_FACT = [];
exports.FACT = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var n = Math.floor(number);
  if (n === 0 || n === 1) {
    return 1;
  } else if (MEMOIZED_FACT[n] > 0) {
    return MEMOIZED_FACT[n];
  } else {
    MEMOIZED_FACT[n] = exports.FACT(n - 1) * n;
    return MEMOIZED_FACT[n];
  }
};

exports.FACTDOUBLE = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var n = Math.floor(number);
  if (n <= 0) {
    return 1;
  } else {
    return n * exports.FACTDOUBLE(n - 2);
  }
};

exports.FLOOR = function(number, significance) {
  number = utils.parseNumber(number);
  significance = utils.parseNumber(significance);
  if (utils.anyIsError(number, significance)) {
    return error.value;
  }
  if (significance === 0) {
    return 0;
  }

  if (!(number > 0 && significance > 0) && !(number < 0 && significance < 0)) {
    return error.num;
  }

  significance = Math.abs(significance);
  var precision = -Math.floor(Math.log(significance) / Math.log(10));
  if (number >= 0) {
    return exports.ROUND(Math.floor(number / significance) * significance, precision);
  } else {
    return -exports.ROUND(Math.ceil(Math.abs(number) / significance), precision);
  }
};

//TODO: Verify
exports.FLOOR.MATH = function(number, significance, mode) {
  significance = (significance === undefined) ? 1 : significance;
  mode = (mode === undefined) ? 0 : mode;

  number = utils.parseNumber(number);
  significance = utils.parseNumber(significance);
  mode = utils.parseNumber(mode);
  if (utils.anyIsError(number, significance, mode)) {
    return error.value;
  }
  if (significance === 0) {
    return 0;
  }

  significance = significance ? Math.abs(significance) : 1;
  var precision = -Math.floor(Math.log(significance) / Math.log(10));
  if (number >= 0) {
    return exports.ROUND(Math.floor(number / significance) * significance, precision);
  } else if (mode === 0 || mode === undefined) {
    return -exports.ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision);
  }
  return -exports.ROUND(Math.floor(Math.abs(number) / significance) * significance, precision);
};

// Deprecated
exports.FLOOR.PRECISE = exports.FLOOR.MATH;

// adapted http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript
exports.GCD = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var n = range.length;
  var r0 = range[0];
  var x = r0 < 0 ? -r0 : r0;
  for (var i = 1; i < n; i++) {
    var ri = range[i];
    var y = ri < 0 ? -ri : ri;
    while (x && y) {
      if (x > y) {
        x %= y;
      } else {
        y %= x;
      }
    }
    x += y;
  }
  return x;
};


exports.INT = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.floor(number);
};

//TODO: verify
exports.ISO = {
  CEILING: exports.CEILING
};

exports.LCM = function() {
  // Credits: Jonas Raoni Soares Silva
  var o = utils.parseNumberArray(utils.flatten(arguments));
  if (o instanceof Error) {
    return o;
  }
  for (var i, j, n, d, r = 1;
       (n = o.pop()) !== undefined;) {
    while (n > 1) {
      if (n % 2) {
        for (i = 3, j = Math.floor(Math.sqrt(n)); i <= j && n % i; i += 2) {
          //empty
        }
        d = (i <= j) ? i : n;
      } else {
        d = 2;
      }
      for (n /= d, r *= d, i = o.length; i;
           (o[--i] % d) === 0 && (o[i] /= d) === 1 && o.splice(i, 1)) {
        //empty
      }
    }
  }
  return r;
};

exports.LN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.log(number);
};

exports.LN10 = function() {
  return Math.log(10);
};

exports.LN2 = function() {
  return Math.log(2);
};

exports.LOG10E = function() {
  return Math.LOG10E;
};

exports.LOG2E = function() {
  return Math.LOG2E;
};

exports.LOG = function(number, base) {
  number = utils.parseNumber(number);
  base = utils.parseNumber(base);
  if (utils.anyIsError(number, base)) {
    return error.value;
  }
  base = (base === undefined) ? 10 : base;
  return Math.log(number) / Math.log(base);
};

exports.LOG10 = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.log(number) / Math.log(10);
};

exports.MOD = function(dividend, divisor) {
  dividend = utils.parseNumber(dividend);
  divisor = utils.parseNumber(divisor);
  if (utils.anyIsError(dividend, divisor)) {
    return error.value;
  }
  if (divisor === 0) {
    return error.div0;
  }
  var modulus = Math.abs(dividend % divisor);
  return (divisor > 0) ? modulus : -modulus;
};

exports.MROUND = function(number, multiple) {
  number = utils.parseNumber(number);
  multiple = utils.parseNumber(multiple);
  if (utils.anyIsError(number, multiple)) {
    return error.value;
  }
  if (number * multiple < 0) {
    return error.num;
  }

  return Math.round(number / multiple) * multiple;
};

exports.MULTINOMIAL = function() {
  var args = utils.parseNumberArray(utils.flatten(arguments));
  if (args instanceof Error) {
    return args;
  }
  var sum = 0;
  var divisor = 1;
  for (var i = 0; i < args.length; i++) {
    sum += args[i];
    divisor *= exports.FACT(args[i]);
  }
  return exports.FACT(sum) / divisor;
};

exports.ODD = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var temp = Math.ceil(Math.abs(number));
  temp = (temp & 1) ? temp : temp + 1;
  return (number > 0) ? temp : -temp;
};

exports.PI = function() {
  return Math.PI;
};

exports.E = function() {
  return Math.E;
};

exports.POWER = function(number, power) {
  number = utils.parseNumber(number);
  power = utils.parseNumber(power);
  if (utils.anyIsError(number, power)) {
    return error.value;
  }
  var result = Math.pow(number, power);
  if (isNaN(result)) {
    return error.num;
  }

  return result;
};

exports.PRODUCT = function() {
  var args = utils.parseNumberArray(utils.flatten(arguments));
  if (args instanceof Error) {
    return args;
  }
  var result = 1;
  for (var i = 0; i < args.length; i++) {
    result *= args[i];
  }
  return result;
};

exports.QUOTIENT = function(numerator, denominator) {
  numerator = utils.parseNumber(numerator);
  denominator = utils.parseNumber(denominator);
  if (utils.anyIsError(numerator, denominator)) {
    return error.value;
  }
  return parseInt(numerator / denominator, 10);
};

exports.RADIANS = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return number * Math.PI / 180;
};

exports.RAND = function() {
  return Math.random();
};

exports.RANDBETWEEN = function(bottom, top) {
  bottom = utils.parseNumber(bottom);
  top = utils.parseNumber(top);
  if (utils.anyIsError(bottom, top)) {
    return error.value;
  }
  // Creative Commons Attribution 3.0 License
  // Copyright (c) 2012 eqcode
  return bottom + Math.ceil((top - bottom + 1) * Math.random()) - 1;
};

// TODO
exports.ROMAN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  // The MIT License
  // Copyright (c) 2008 Steven Levithan
  var digits = String(number).split('');
  var key = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
  var roman = '';
  var i = 3;
  while (i--) {
    roman = (key[+digits.pop() + (i * 10)] || '') + roman;
  }
  return new Array(+digits.join('') + 1).join('M') + roman;
};

exports.ROUND = function(number, digits) {
  number = utils.parseNumber(number);
  digits = utils.parseNumber(digits);
  if (utils.anyIsError(number, digits)) {
    return error.value;
  }
  return Math.round(number * Math.pow(10, digits)) / Math.pow(10, digits);
};

exports.ROUNDDOWN = function(number, digits) {
  number = utils.parseNumber(number);
  digits = utils.parseNumber(digits);
  if (utils.anyIsError(number, digits)) {
    return error.value;
  }
  var sign = (number > 0) ? 1 : -1;
  return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits);
};

exports.ROUNDUP = function(number, digits) {
  number = utils.parseNumber(number);
  digits = utils.parseNumber(digits);
  if (utils.anyIsError(number, digits)) {
    return error.value;
  }
  var sign = (number > 0) ? 1 : -1;
  return sign * (Math.ceil(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits);
};

exports.SEC = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return 1 / Math.cos(number);
};

exports.SECH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return 2 / (Math.exp(number) + Math.exp(-number));
};

exports.SERIESSUM = function(x, n, m, coefficients) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  m = utils.parseNumber(m);
  coefficients = utils.parseNumberArray(coefficients);
  if (utils.anyIsError(x, n, m, coefficients)) {
    return error.value;
  }
  var result = coefficients[0] * Math.pow(x, n);
  for (var i = 1; i < coefficients.length; i++) {
    result += coefficients[i] * Math.pow(x, n + i * m);
  }
  return result;
};

exports.SIGN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  if (number < 0) {
    return -1;
  } else if (number === 0) {
    return 0;
  } else {
    return 1;
  }
};

exports.SIN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.sin(number);
};

exports.SINH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return (Math.exp(number) - Math.exp(-number)) / 2;
};

exports.SQRT = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  if (number < 0) {
    return error.num;
  }
  return Math.sqrt(number);
};

exports.SQRTPI = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.sqrt(number * Math.PI);
};

exports.SQRT1_2 = function() {
  return 1 / Math.sqrt(2);
};

exports.SQRT2 = function() {
  return Math.sqrt(2);
};

exports.SUBTOTAL = function(function_code, ref1) {
  function_code = utils.parseNumber(function_code);
  if (function_code instanceof Error) {
    return function_code;
  }
  switch (function_code) {
    case 1:
      return statistical.AVERAGE(ref1);
    case 2:
      return statistical.COUNT(ref1);
    case 3:
      return statistical.COUNTA(ref1);
    case 4:
      return statistical.MAX(ref1);
    case 5:
      return statistical.MIN(ref1);
    case 6:
      return exports.PRODUCT(ref1);
    case 7:
      return statistical.STDEV.S(ref1);
    case 8:
      return statistical.STDEV.P(ref1);
    case 9:
      return exports.SUM(ref1);
    case 10:
      return statistical.VAR.S(ref1);
    case 11:
      return statistical.VAR.P(ref1);
    // no hidden values for us
    case 101:
      return statistical.AVERAGE(ref1);
    case 102:
      return statistical.COUNT(ref1);
    case 103:
      return statistical.COUNTA(ref1);
    case 104:
      return statistical.MAX(ref1);
    case 105:
      return statistical.MIN(ref1);
    case 106:
      return exports.PRODUCT(ref1);
    case 107:
      return statistical.STDEV.S(ref1);
    case 108:
      return statistical.STDEV.P(ref1);
    case 109:
      return exports.SUM(ref1);
    case 110:
      return statistical.VAR.S(ref1);
    case 111:
      return statistical.VAR.P(ref1);

  }
};

exports.ADD = function (num1, num2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  num1 = utils.parseNumber(num1);
  num2 = utils.parseNumber(num2);
  if (utils.anyIsError(num1, num2)) {
    return error.value;
  }

  return num1 + num2;
};

exports.MINUS = function (num1, num2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  num1 = utils.parseNumber(num1);
  num2 = utils.parseNumber(num2);
  if (utils.anyIsError(num1, num2)) {
    return error.value;
  }

  return num1 - num2;
};

exports.DIVIDE = function (dividend, divisor) {
  if (arguments.length !== 2) {
    return error.na;
  }

  dividend = utils.parseNumber(dividend);
  divisor = utils.parseNumber(divisor);
  if (utils.anyIsError(dividend, divisor)) {
    return error.value;
  }

  if (divisor === 0) {
    return error.div0;
  }

  return dividend / divisor;
};

exports.MULTIPLY = function (factor1, factor2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  factor1 = utils.parseNumber(factor1);
  factor2 = utils.parseNumber(factor2);
  if (utils.anyIsError(factor1, factor2)) {
    return error.value;
  }

  return factor1 * factor2;
};

exports.GTE = function (num1, num2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  num1 = utils.parseNumber(num1);
  num2 = utils.parseNumber(num2);
  if (utils.anyIsError(num1, num2)) {
    return error.error;
  }

  return num1 >= num2;
};

exports.LT = function (num1, num2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  num1 = utils.parseNumber(num1);
  num2 = utils.parseNumber(num2);
  if (utils.anyIsError(num1, num2)) {
    return error.error;
  }

  return num1 < num2;
};


exports.LTE = function (num1, num2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  num1 = utils.parseNumber(num1);
  num2 = utils.parseNumber(num2);
  if (utils.anyIsError(num1, num2)) {
    return error.error;
  }

  return num1 <= num2;
};

exports.EQ = function (value1, value2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  return value1 === value2;
};

exports.NE = function (value1, value2) {
  if (arguments.length !== 2) {
    return error.na;
  }

  return value1 !== value2;
};

exports.POW = function (base, exponent) {
  if (arguments.length !== 2) {
    return error.na;
  }

  base = utils.parseNumber(base);
  exponent = utils.parseNumber(exponent);
  if (utils.anyIsError(base, exponent)) {
    return error.error;
  }

  return exports.POWER(base, exponent);
};

exports.SUM = function() {
  var result = 0;

  utils.arrayEach(utils.argsToArray(arguments), function(value) {
    if (typeof value === 'number') {
      result += value;

    } else if (typeof value === 'string') {
      var parsed = parseFloat(value);

      !isNaN(parsed) && (result += parsed);

    } else if (Array.isArray(value)) {
      result += exports.SUM.apply(null, value);
    }
  });

  return result;
};

exports.SUMIF = function(range, criteria) {
  range = utils.parseNumberArray(utils.flatten(range));
  if (range instanceof Error) {
    return range;
  }
  var result = 0;
  for (var i = 0; i < range.length; i++) {
    result += (eval(range[i] + criteria)) ? range[i] : 0; // jshint ignore:line
  }
  return result;
};

exports.SUMIFS = function() {
  var args = utils.argsToArray(arguments);
  var range = utils.parseNumberArray(utils.flatten(args.shift()));
  if (range instanceof Error) {
    return range;
  }
  var criteria = args;

  var n_range_elements = range.length;
  var n_criterias = criteria.length;

  var result = 0;
  for (var i = 0; i < n_range_elements; i++) {
    var el = range[i];
    var condition = '';
    for (var c = 0; c < n_criterias; c++) {
      condition += el + criteria[c];
      if (c !== n_criterias - 1) {
        condition += '&&';
      }
    }
    if (eval(condition)) { // jshint ignore:line
      result += el;
    }
  }
  return result;
};

exports.SUMPRODUCT = function() {
  if (!arguments || arguments.length === 0) {
    return error.value;
  }
  var arrays = arguments.length + 1;
  var result = 0;
  var product;
  var k;
  var _i;
  var _ij;
  for (var i = 0; i < arguments[0].length; i++) {
    if (!(arguments[0][i] instanceof Array)) {
      product = 1;
      for (k = 1; k < arrays; k++) {
        _i = utils.parseNumber(arguments[k - 1][i]);
        if (_i instanceof Error) {
          return _i;
        }
        product *= _i;
      }
      result += product;
    } else {
      for (var j = 0; j < arguments[0][i].length; j++) {
        product = 1;
        for (k = 1; k < arrays; k++) {
          _ij = utils.parseNumber(arguments[k - 1][i][j]);
          if (_ij instanceof Error) {
            return _ij;
          }
          product *= _ij;
        }
        result += product;
      }
    }
  }
  return result;
};

exports.SUMSQ = function() {
  var numbers = utils.parseNumberArray(utils.flatten(arguments));
  if (numbers instanceof Error) {
    return numbers;
  }
  var result = 0;
  var length = numbers.length;
  for (var i = 0; i < length; i++) {
    result += (information.ISNUMBER(numbers[i])) ? numbers[i] * numbers[i] : 0;
  }
  return result;
};

exports.SUMX2MY2 = function(array_x, array_y) {
  array_x = utils.parseNumberArray(utils.flatten(array_x));
  array_y = utils.parseNumberArray(utils.flatten(array_y));
  if (utils.anyIsError(array_x, array_y)) {
    return error.value;
  }
  var result = 0;
  for (var i = 0; i < array_x.length; i++) {
    result += array_x[i] * array_x[i] - array_y[i] * array_y[i];
  }
  return result;
};

exports.SUMX2PY2 = function(array_x, array_y) {
  array_x = utils.parseNumberArray(utils.flatten(array_x));
  array_y = utils.parseNumberArray(utils.flatten(array_y));
  if (utils.anyIsError(array_x, array_y)) {
    return error.value;
  }
  var result = 0;
  array_x = utils.parseNumberArray(utils.flatten(array_x));
  array_y = utils.parseNumberArray(utils.flatten(array_y));
  for (var i = 0; i < array_x.length; i++) {
    result += array_x[i] * array_x[i] + array_y[i] * array_y[i];
  }
  return result;
};

exports.SUMXMY2 = function(array_x, array_y) {
  array_x = utils.parseNumberArray(utils.flatten(array_x));
  array_y = utils.parseNumberArray(utils.flatten(array_y));
  if (utils.anyIsError(array_x, array_y)) {
    return error.value;
  }
  var result = 0;
  array_x = utils.flatten(array_x);
  array_y = utils.flatten(array_y);
  for (var i = 0; i < array_x.length; i++) {
    result += Math.pow(array_x[i] - array_y[i], 2);
  }
  return result;
};

exports.TAN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return Math.tan(number);
};

exports.TANH = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  var e2 = Math.exp(2 * number);
  return (e2 - 1) / (e2 + 1);
};

exports.TRUNC = function(number, digits) {
  digits = (digits === undefined) ? 0 : digits;
  number = utils.parseNumber(number);
  digits = utils.parseNumber(digits);
  if (utils.anyIsError(number, digits)) {
    return error.value;
  }
  var sign = (number > 0) ? 1 : -1;
  return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits);
};


/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {

var mathTrig = __webpack_require__(4);
var text = __webpack_require__(6);
var jStat = __webpack_require__(9).jStat;
var utils = __webpack_require__(1);
var error = __webpack_require__(0);
var misc = __webpack_require__(10);

var SQRT2PI = 2.5066282746310002;

exports.AVEDEV = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  return jStat.sum(jStat(range).subtract(jStat.mean(range)).abs()[0]) / range.length;
};

exports.AVERAGE = function() {
  var range = utils.numbers(utils.flatten(arguments));
  var n = range.length;
  var sum = 0;
  var count = 0;
  var result;

  for (var i = 0; i < n; i++) {
    sum += range[i];
    count += 1;
  }
  result = sum / count;

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.AVERAGEA = function() {
  var range = utils.flatten(arguments);
  var n = range.length;
  var sum = 0;
  var count = 0;
  var result;
  for (var i = 0; i < n; i++) {
    var el = range[i];
    if (typeof el === 'number') {
      sum += el;
    }
    if (el === true) {
      sum++;
    }
    if (el !== null) {
      count++;
    }
  }
  result = sum / count;

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.AVERAGEIF = function(range, criteria, average_range) {
  if (arguments.length <= 1) {
    return error.na;
  }
  average_range = average_range || range;
  range = utils.flatten(range);
  average_range = utils.parseNumberArray(utils.flatten(average_range));
  if (average_range instanceof Error) {
    return average_range;
  }
  var average_count = 0;
  var result = 0;
  for (var i = 0; i < range.length; i++) {
    if (eval(range[i] + criteria)) { // jshint ignore:line
      result += average_range[i];
      average_count++;
    }
  }
  return result / average_count;
};

exports.AVERAGEIFS = function() {
  // Does not work with multi dimensional ranges yet!
  //http://office.microsoft.com/en-001/excel-help/averageifs-function-HA010047493.aspx
  var args = utils.argsToArray(arguments);
  var criteria = (args.length - 1) / 2;
  var range = utils.flatten(args[0]);
  var count = 0;
  var result = 0;
  for (var i = 0; i < range.length; i++) {
    var condition = '';
    for (var j = 0; j < criteria; j++) {
      condition += args[2 * j + 1][i] + args[2 * j + 2];
      if (j !== criteria - 1) {
        condition += '&&';
      }
    }
    if (eval(condition)) { // jshint ignore:line
      result += range[i];
      count++;
    }
  }

  var average = result / count;
  if (isNaN(average)) {
    return 0;
  } else {
    return average;
  }
};

exports.BETA = {};

exports.BETA.DIST = function(x, alpha, beta, cumulative, A, B) {
  if (arguments.length < 4) {
    return error.value;
  }

  A = (A === undefined) ? 0 : A;
  B = (B === undefined) ? 1 : B;

  x = utils.parseNumber(x);
  alpha = utils.parseNumber(alpha);
  beta = utils.parseNumber(beta);
  A = utils.parseNumber(A);
  B = utils.parseNumber(B);
  if (utils.anyIsError(x, alpha, beta, A, B)) {
    return error.value;
  }

  x = (x - A) / (B - A);
  return (cumulative) ? jStat.beta.cdf(x, alpha, beta) : jStat.beta.pdf(x, alpha, beta);
};

exports.BETA.INV = function(probability, alpha, beta, A, B) {
  A = (A === undefined) ? 0 : A;
  B = (B === undefined) ? 1 : B;

  probability = utils.parseNumber(probability);
  alpha = utils.parseNumber(alpha);
  beta = utils.parseNumber(beta);
  A = utils.parseNumber(A);
  B = utils.parseNumber(B);
  if (utils.anyIsError(probability, alpha, beta, A, B)) {
    return error.value;
  }

  return jStat.beta.inv(probability, alpha, beta) * (B - A) + A;
};

exports.BINOM = {};

exports.BINOM.DIST = function(successes, trials, probability, cumulative) {
  successes = utils.parseNumber(successes);
  trials = utils.parseNumber(trials);
  probability = utils.parseNumber(probability);
  cumulative = utils.parseNumber(cumulative);
  if (utils.anyIsError(successes, trials, probability, cumulative)) {
    return error.value;
  }
  return (cumulative) ? jStat.binomial.cdf(successes, trials, probability) : jStat.binomial.pdf(successes, trials, probability);
};

exports.BINOM.DIST.RANGE = function(trials, probability, successes, successes2) {
  successes2 = (successes2 === undefined) ? successes : successes2;

  trials = utils.parseNumber(trials);
  probability = utils.parseNumber(probability);
  successes = utils.parseNumber(successes);
  successes2 = utils.parseNumber(successes2);
  if (utils.anyIsError(trials, probability, successes, successes2)) {
    return error.value;
  }

  var result = 0;
  for (var i = successes; i <= successes2; i++) {
    result += mathTrig.COMBIN(trials, i) * Math.pow(probability, i) * Math.pow(1 - probability, trials - i);
  }
  return result;
};

exports.BINOM.INV = function(trials, probability, alpha) {
  trials = utils.parseNumber(trials);
  probability = utils.parseNumber(probability);
  alpha = utils.parseNumber(alpha);
  if (utils.anyIsError(trials, probability, alpha)) {
    return error.value;
  }

  var x = 0;
  while (x <= trials) {
    if (jStat.binomial.cdf(x, trials, probability) >= alpha) {
      return x;
    }
    x++;
  }
};

exports.CHISQ = {};

exports.CHISQ.DIST = function(x, k, cumulative) {
  x = utils.parseNumber(x);
  k = utils.parseNumber(k);
  if (utils.anyIsError(x, k)) {
    return error.value;
  }

  return (cumulative) ? jStat.chisquare.cdf(x, k) : jStat.chisquare.pdf(x, k);
};

exports.CHISQ.DIST.RT = function(x, k) {
  if (!x | !k) {
    return error.na;
  }

  if (x < 1 || k > Math.pow(10, 10)) {
    return error.num;
  }

  if ((typeof x !== 'number') || (typeof k !== 'number')) {
    return error.value;
  }

  return 1 -  jStat.chisquare.cdf(x, k);
};

exports.CHISQ.INV = function(probability, k) {
  probability = utils.parseNumber(probability);
  k = utils.parseNumber(k);
  if (utils.anyIsError(probability, k)) {
    return error.value;
  }
  return jStat.chisquare.inv(probability, k);
};

exports.CHISQ.INV.RT = function(p, k) {
  if (!p | !k) {
    return error.na;
  }

  if (p < 0 || p > 1 || k < 1 || k > Math.pow(10, 10)) {
    return error.num;
  }

  if ((typeof p !== 'number') || (typeof k !== 'number')) {
    return error.value;
  }

  return jStat.chisquare.inv(1.0 - p, k);
};

exports.CHISQ.TEST = function(observed, expected) {
  if (arguments.length !== 2) {
    return error.na;
  }

  if ((!(observed instanceof Array)) || (!(expected instanceof Array))) {
    return error.value;
  }

  if (observed.length !== expected.length) {
    return error.value;
  }

  if (observed[0] && expected[0] &&
    observed[0].length !== expected[0].length) {
    return error.value;
  }

  var row = observed.length;
  var tmp, i, j;

  // Convert single-dimension array into two-dimension array
  for (i = 0; i < row; i ++) {
    if (!(observed[i] instanceof Array)) {
      tmp = observed[i];
      observed[i] = [];
      observed[i].push(tmp);
    }
    if (!(expected[i] instanceof Array)) {
      tmp = expected[i];
      expected[i] = [];
      expected[i].push(tmp);
    }
  }

  var col = observed[0].length;
  var dof = (col === 1) ? row-1 : (row-1)*(col-1);
  var xsqr = 0;
  var Pi =Math.PI;

  for (i = 0; i < row; i ++) {
    for (j = 0; j < col; j ++) {
      xsqr += Math.pow((observed[i][j] - expected[i][j]), 2) / expected[i][j];
    }
  }

  // Get independency by X square and its degree of freedom
  function ChiSq(xsqr, dof) {
    var p = Math.exp(-0.5 * xsqr);
    if((dof%2) === 1) {
      p = p * Math.sqrt(2 * xsqr/Pi);
    }
    var k = dof;
    while(k >= 2) {
      p = p * xsqr/k;
      k = k - 2;
    }
    var t = p;
    var a = dof;
    while (t > 0.0000000001*p) {
      a = a + 2;
      t = t * xsqr/a;
      p = p + t;
    }
    return 1-p;
  }

  return Math.round(ChiSq(xsqr, dof) * 1000000) / 1000000;
};

exports.COLUMN = function(matrix, index) {
  if (arguments.length !== 2) {
    return error.na;
  }

  if (index < 0) {
    return error.num;
  }

  if (!(matrix instanceof Array) || (typeof index !== 'number')) {
    return error.value;
  }

  if (matrix.length === 0) {
    return undefined;
  }

  return jStat.col(matrix, index);
};

exports.COLUMNS = function(matrix) {
  if (arguments.length !== 1) {
    return error.na;
  }

  if (!(matrix instanceof Array)) {
    return error.value;
  }

  if (matrix.length === 0) {
    return 0;
  }

  return jStat.cols(matrix);
};

exports.CONFIDENCE = {};

exports.CONFIDENCE.NORM = function(alpha, sd, n) {
  alpha = utils.parseNumber(alpha);
  sd = utils.parseNumber(sd);
  n = utils.parseNumber(n);
  if (utils.anyIsError(alpha, sd, n)) {
    return error.value;
  }
  return jStat.normalci(1, alpha, sd, n)[1] - 1;
};

exports.CONFIDENCE.T = function(alpha, sd, n) {
  alpha = utils.parseNumber(alpha);
  sd = utils.parseNumber(sd);
  n = utils.parseNumber(n);
  if (utils.anyIsError(alpha, sd, n)) {
    return error.value;
  }
  return jStat.tci(1, alpha, sd, n)[1] - 1;
};

exports.CORREL = function(array1, array2) {
  array1 = utils.parseNumberArray(utils.flatten(array1));
  array2 = utils.parseNumberArray(utils.flatten(array2));
  if (utils.anyIsError(array1, array2)) {
    return error.value;
  }
  return jStat.corrcoeff(array1, array2);
};

exports.COUNT = function() {
  return utils.numbers(utils.flatten(arguments)).length;
};

exports.COUNTA = function() {
  var range = utils.flatten(arguments);
  return range.length - exports.COUNTBLANK(range);
};

exports.COUNTIN = function (range, value) {
  var result = 0;

  range = utils.flatten(range);

  for (var i = 0; i < range.length; i++) {
    if (range[i] === value) {
      result++;
    }
  }
  return result;
};


exports.COUNTBLANK = function() {
  var range = utils.flatten(arguments);
  var blanks = 0;
  var element;
  for (var i = 0; i < range.length; i++) {
    element = range[i];
    if (element === null || element === '') {
      blanks++;
    }
  }
  return blanks;
};

exports.COUNTIF = function(range, criteria) {
  range = utils.flatten(range);
  if (!/[<>=!]/.test(criteria)) {
    criteria = '=="' + criteria + '"';
  }
  var matches = 0;
  for (var i = 0; i < range.length; i++) {
    if (typeof range[i] !== 'string') {
      if (eval(range[i] + criteria)) { // jshint ignore:line
        matches++;
      }
    } else {
      if (eval('"' + range[i] + '"' + criteria)) { // jshint ignore:line
        matches++;
      }
    }
  }
  return matches;
};

exports.COUNTIFS = function() {
  var args = utils.argsToArray(arguments);
  var results = new Array(utils.flatten(args[0]).length);
  for (var i = 0; i < results.length; i++) {
    results[i] = true;
  }
  for (i = 0; i < args.length; i += 2) {
    var range = utils.flatten(args[i]);
    var criteria = args[i + 1];
    if (!/[<>=!]/.test(criteria)) {
      criteria = '=="' + criteria + '"';
    }
    for (var j = 0; j < range.length; j++) {
      if (typeof range[j] !== 'string') {
        results[j] = results[j] && eval(range[j] + criteria); // jshint ignore:line
      } else {
        results[j] = results[j] && eval('"' + range[j] + '"' + criteria); // jshint ignore:line
      }
    }
  }
  var result = 0;
  for (i = 0; i < results.length; i++) {
    if (results[i]) {
      result++;
    }
  }
  return result;
};

exports.COUNTUNIQUE = function () {
  return misc.UNIQUE.apply(null, utils.flatten(arguments)).length;
};

exports.COVARIANCE = {};

exports.COVARIANCE.P = function(array1, array2) {
  array1 = utils.parseNumberArray(utils.flatten(array1));
  array2 = utils.parseNumberArray(utils.flatten(array2));
  if (utils.anyIsError(array1, array2)) {
    return error.value;
  }
  var mean1 = jStat.mean(array1);
  var mean2 = jStat.mean(array2);
  var result = 0;
  var n = array1.length;
  for (var i = 0; i < n; i++) {
    result += (array1[i] - mean1) * (array2[i] - mean2);
  }
  return result / n;
};

exports.COVARIANCE.S = function(array1, array2) {
  array1 = utils.parseNumberArray(utils.flatten(array1));
  array2 = utils.parseNumberArray(utils.flatten(array2));
  if (utils.anyIsError(array1, array2)) {
    return error.value;
  }
  return jStat.covariance(array1, array2);
};

exports.DEVSQ = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var mean = jStat.mean(range);
  var result = 0;
  for (var i = 0; i < range.length; i++) {
    result += Math.pow((range[i] - mean), 2);
  }
  return result;
};

exports.EXPON = {};

exports.EXPON.DIST = function(x, lambda, cumulative) {
  x = utils.parseNumber(x);
  lambda = utils.parseNumber(lambda);
  if (utils.anyIsError(x, lambda)) {
    return error.value;
  }
  return (cumulative) ? jStat.exponential.cdf(x, lambda) : jStat.exponential.pdf(x, lambda);
};

exports.F = {};

exports.F.DIST = function(x, d1, d2, cumulative) {
  x = utils.parseNumber(x);
  d1 = utils.parseNumber(d1);
  d2 = utils.parseNumber(d2);
  if (utils.anyIsError(x, d1, d2)) {
    return error.value;
  }
  return (cumulative) ? jStat.centralF.cdf(x, d1, d2) : jStat.centralF.pdf(x, d1, d2);
};

exports.F.DIST.RT = function(x, d1, d2) {
  if (arguments.length !== 3) {
    return error.na;
  }

  if (x < 0 || d1 < 1 || d2 < 1) {
    return error.num;
  }

  if ((typeof x !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) {
    return error.value;
  }

  return 1 - jStat.centralF.cdf(x, d1, d2);
};

exports.F.INV = function(probability, d1, d2) {
  probability = utils.parseNumber(probability);
  d1 = utils.parseNumber(d1);
  d2 = utils.parseNumber(d2);
  if (utils.anyIsError(probability, d1, d2)) {
    return error.value;
  }
  if (probability <= 0.0 || probability > 1.0) {
    return error.num;
  }

  return jStat.centralF.inv(probability, d1, d2);
};

exports.F.INV.RT = function(p, d1, d2) {
  if (arguments.length !== 3) {
    return error.na;
  }

  if (p < 0 || p > 1 || d1 < 1 || d1 > Math.pow(10, 10) || d2 < 1 || d2 > Math.pow(10, 10)) {
    return error.num;
  }

  if ((typeof p !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) {
    return error.value;
  }

  return jStat.centralF.inv(1.0 - p, d1, d2);
};

exports.F.TEST = function(array1, array2) {
  if (!array1 || !array2) {
    return error.na;
  }

  if (!(array1 instanceof Array) || !(array2 instanceof Array)) {
    return error.na;
  }

  if (array1.length < 2 || array2.length < 2) {
    return error.div0;
  }

  var sumOfSquares = function(values, x1) {
    var sum = 0;
    for (var i = 0; i < values.length; i++) {
      sum +=Math.pow((values[i] - x1), 2);
    }
    return sum;
  };

  var x1 = mathTrig.SUM(array1) / array1.length;
  var x2 = mathTrig.SUM(array2) / array2.length;
  var sum1 = sumOfSquares(array1, x1) / (array1.length - 1);
  var sum2 = sumOfSquares(array2, x2) / (array2.length - 1);

  return sum1 / sum2;
};

exports.FISHER = function(x) {
  x = utils.parseNumber(x);
  if (x instanceof Error) {
    return x;
  }
  return Math.log((1 + x) / (1 - x)) / 2;
};

exports.FISHERINV = function(y) {
  y = utils.parseNumber(y);
  if (y instanceof Error) {
    return y;
  }
  var e2y = Math.exp(2 * y);
  return (e2y - 1) / (e2y + 1);
};

exports.FORECAST = function(x, data_y, data_x) {
  x = utils.parseNumber(x);
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(x, data_y, data_x)) {
    return error.value;
  }
  var xmean = jStat.mean(data_x);
  var ymean = jStat.mean(data_y);
  var n = data_x.length;
  var num = 0;
  var den = 0;
  for (var i = 0; i < n; i++) {
    num += (data_x[i] - xmean) * (data_y[i] - ymean);
    den += Math.pow(data_x[i] - xmean, 2);
  }
  var b = num / den;
  var a = ymean - b * xmean;
  return a + b * x;
};

exports.FREQUENCY = function(data, bins) {
  data = utils.parseNumberArray(utils.flatten(data));
  bins = utils.parseNumberArray(utils.flatten(bins));
  if (utils.anyIsError(data, bins)) {
    return error.value;
  }
  var n = data.length;
  var b = bins.length;
  var r = [];
  for (var i = 0; i <= b; i++) {
    r[i] = 0;
    for (var j = 0; j < n; j++) {
      if (i === 0) {
        if (data[j] <= bins[0]) {
          r[0] += 1;
        }
      } else if (i < b) {
        if (data[j] > bins[i - 1] && data[j] <= bins[i]) {
          r[i] += 1;
        }
      } else if (i === b) {
        if (data[j] > bins[b - 1]) {
          r[b] += 1;
        }
      }
    }
  }
  return r;
};


exports.GAMMA = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }

  if (number === 0) {
    return error.num;
  }

  if (parseInt(number, 10) === number && number < 0) {
    return error.num;
  }

  return jStat.gammafn(number);
};

exports.GAMMA.DIST = function(value, alpha, beta, cumulative) {
  if (arguments.length !== 4) {
    return error.na;
  }

  if (value < 0 || alpha <= 0 || beta <= 0) {
    return error.value;
  }

  if ((typeof value !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) {
    return error.value;
  }

  return cumulative ? jStat.gamma.cdf(value, alpha, beta, true) : jStat.gamma.pdf(value, alpha, beta, false);
};

exports.GAMMA.INV = function(probability, alpha, beta) {
  if (arguments.length !== 3) {
    return error.na;
  }

  if (probability < 0 || probability > 1 || alpha <= 0 || beta <= 0) {
    return error.num;
  }

  if ((typeof probability !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) {
    return error.value;
  }

  return jStat.gamma.inv(probability, alpha, beta);
};

exports.GAMMALN = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return jStat.gammaln(number);
};

exports.GAMMALN.PRECISE = function(x) {
  if (arguments.length !== 1) {
    return error.na;
  }

  if (x <= 0) {
    return error.num;
  }

  if (typeof x !== 'number') {
    return error.value;
  }

  return jStat.gammaln(x);
};

exports.GAUSS = function(z) {
  z = utils.parseNumber(z);
  if (z instanceof Error) {
    return z;
  }
  return jStat.normal.cdf(z, 0, 1) - 0.5;
};

exports.GEOMEAN = function() {
  var args = utils.parseNumberArray(utils.flatten(arguments));
  if (args instanceof Error) {
    return args;
  }
  return jStat.geomean(args);
};

exports.GROWTH = function(known_y, known_x, new_x, use_const) {
  // Credits: Ilmari Karonen (http://stackoverflow.com/questions/14161990/how-to-implement-growth-function-in-javascript)

  known_y = utils.parseNumberArray(known_y);
  if (known_y instanceof Error) {
    return known_y;
  }

  // Default values for optional parameters:
  var i;
  if (known_x === undefined) {
    known_x = [];
    for (i = 1; i <= known_y.length; i++) {
      known_x.push(i);
    }
  }
  if (new_x === undefined) {
    new_x = [];
    for (i = 1; i <= known_y.length; i++) {
      new_x.push(i);
    }
  }

  known_x = utils.parseNumberArray(known_x);
  new_x = utils.parseNumberArray(new_x);
  if (utils.anyIsError(known_x, new_x)) {
    return error.value;
  }


  if (use_const === undefined) {
    use_const = true;
  }

  // Calculate sums over the data:
  var n = known_y.length;
  var avg_x = 0;
  var avg_y = 0;
  var avg_xy = 0;
  var avg_xx = 0;
  for (i = 0; i < n; i++) {
    var x = known_x[i];
    var y = Math.log(known_y[i]);
    avg_x += x;
    avg_y += y;
    avg_xy += x * y;
    avg_xx += x * x;
  }
  avg_x /= n;
  avg_y /= n;
  avg_xy /= n;
  avg_xx /= n;

  // Compute linear regression coefficients:
  var beta;
  var alpha;
  if (use_const) {
    beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x);
    alpha = avg_y - beta * avg_x;
  } else {
    beta = avg_xy / avg_xx;
    alpha = 0;
  }

  // Compute and return result array:
  var new_y = [];
  for (i = 0; i < new_x.length; i++) {
    new_y.push(Math.exp(alpha + beta * new_x[i]));
  }
  return new_y;
};

exports.HARMEAN = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var n = range.length;
  var den = 0;
  for (var i = 0; i < n; i++) {
    den += 1 / range[i];
  }
  return n / den;
};

exports.HYPGEOM = {};

exports.HYPGEOM.DIST = function(x, n, M, N, cumulative) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  M = utils.parseNumber(M);
  N = utils.parseNumber(N);
  if (utils.anyIsError(x, n, M, N)) {
    return error.value;
  }

  function pdf(x, n, M, N) {
    return mathTrig.COMBIN(M, x) * mathTrig.COMBIN(N - M, n - x) / mathTrig.COMBIN(N, n);
  }

  function cdf(x, n, M, N) {
    var result = 0;
    for (var i = 0; i <= x; i++) {
      result += pdf(i, n, M, N);
    }
    return result;
  }

  return (cumulative) ? cdf(x, n, M, N) : pdf(x, n, M, N);
};

exports.INTERCEPT = function(known_y, known_x) {
  known_y = utils.parseNumberArray(known_y);
  known_x = utils.parseNumberArray(known_x);
  if (utils.anyIsError(known_y, known_x)) {
    return error.value;
  }
  if (known_y.length !== known_x.length) {
    return error.na;
  }
  return exports.FORECAST(0, known_y, known_x);
};

exports.KURT = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var mean = jStat.mean(range);
  var n = range.length;
  var sigma = 0;
  for (var i = 0; i < n; i++) {
    sigma += Math.pow(range[i] - mean, 4);
  }
  sigma = sigma / Math.pow(jStat.stdev(range, true), 4);
  return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sigma - 3 * (n - 1) * (n - 1) / ((n - 2) * (n - 3));
};

exports.LARGE = function(range, k) {
  range = utils.parseNumberArray(utils.flatten(range));
  k = utils.parseNumber(k);
  if (utils.anyIsError(range, k)) {
    return range;
  }
  return range.sort(function(a, b) {
    return b - a;
  })[k - 1];
};

exports.LINEST = function(data_y, data_x) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(data_y, data_x)) {
    return error.value;
  }
  var ymean = jStat.mean(data_y);
  var xmean = jStat.mean(data_x);
  var n = data_x.length;
  var num = 0;
  var den = 0;
  for (var i = 0; i < n; i++) {
    num += (data_x[i] - xmean) * (data_y[i] - ymean);
    den += Math.pow(data_x[i] - xmean, 2);
  }
  var m = num / den;
  var b = ymean - m * xmean;
  return [m, b];
};

// According to Microsoft:
// http://office.microsoft.com/en-us/starter-help/logest-function-HP010342665.aspx
// LOGEST returns are based on the following linear model:
// ln y = x1 ln m1 + ... + xn ln mn + ln b
exports.LOGEST = function(data_y, data_x) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(data_y, data_x)) {
    return error.value;
  }
  for (var i = 0; i < data_y.length; i ++) {
    data_y[i] = Math.log(data_y[i]);
  }

  var result = exports.LINEST(data_y, data_x);
  result[0] = Math.round(Math.exp(result[0])*1000000)/1000000;
  result[1] = Math.round(Math.exp(result[1])*1000000)/1000000;
  return result;
};

exports.LOGNORM = {};

exports.LOGNORM.DIST = function(x, mean, sd, cumulative) {
  x = utils.parseNumber(x);
  mean = utils.parseNumber(mean);
  sd = utils.parseNumber(sd);
  if (utils.anyIsError(x, mean, sd)) {
    return error.value;
  }
  return (cumulative) ? jStat.lognormal.cdf(x, mean, sd) : jStat.lognormal.pdf(x, mean, sd);
};

exports.LOGNORM.INV = function(probability, mean, sd) {
  probability = utils.parseNumber(probability);
  mean = utils.parseNumber(mean);
  sd = utils.parseNumber(sd);
  if (utils.anyIsError(probability, mean, sd)) {
    return error.value;
  }
  return jStat.lognormal.inv(probability, mean, sd);
};

exports.MAX = function() {
  var range = utils.numbers(utils.flatten(arguments));
  return (range.length === 0) ? 0 : Math.max.apply(Math, range);
};

exports.MAXA = function() {
  var range = utils.arrayValuesToNumbers(utils.flatten(arguments));
  return (range.length === 0) ? 0 : Math.max.apply(Math, range);
};

exports.MEDIAN = function() {
  var range = utils.arrayValuesToNumbers(utils.flatten(arguments));
  var result = jStat.median(range);

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.MIN = function() {
  var range = utils.numbers(utils.flatten(arguments));
  return (range.length === 0) ? 0 : Math.min.apply(Math, range);
};

exports.MINA = function() {
  var range = utils.arrayValuesToNumbers(utils.flatten(arguments));
  return (range.length === 0) ? 0 : Math.min.apply(Math, range);
};

exports.MODE = {};

exports.MODE.MULT = function() {
  // Credits: Roönaän
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var n = range.length;
  var count = {};
  var maxItems = [];
  var max = 0;
  var currentItem;

  for (var i = 0; i < n; i++) {
    currentItem = range[i];
    count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1;
    if (count[currentItem] > max) {
      max = count[currentItem];
      maxItems = [];
    }
    if (count[currentItem] === max) {
      maxItems[maxItems.length] = currentItem;
    }
  }
  return maxItems;
};

exports.MODE.SNGL = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  return exports.MODE.MULT(range).sort(function(a, b) {
    return a - b;
  })[0];
};

exports.NEGBINOM = {};

exports.NEGBINOM.DIST = function(k, r, p, cumulative) {
  k = utils.parseNumber(k);
  r = utils.parseNumber(r);
  p = utils.parseNumber(p);
  if (utils.anyIsError(k, r, p)) {
    return error.value;
  }
  return (cumulative) ? jStat.negbin.cdf(k, r, p) : jStat.negbin.pdf(k, r, p);
};

exports.NORM = {};

exports.NORM.DIST = function(x, mean, sd, cumulative) {
  x = utils.parseNumber(x);
  mean = utils.parseNumber(mean);
  sd = utils.parseNumber(sd);
  if (utils.anyIsError(x, mean, sd)) {
    return error.value;
  }
  if (sd <= 0) {
    return error.num;
  }

  // Return normal distribution computed by jStat [http://jstat.org]
  return (cumulative) ? jStat.normal.cdf(x, mean, sd) : jStat.normal.pdf(x, mean, sd);
};

exports.NORM.INV = function(probability, mean, sd) {
  probability = utils.parseNumber(probability);
  mean = utils.parseNumber(mean);
  sd = utils.parseNumber(sd);
  if (utils.anyIsError(probability, mean, sd)) {
    return error.value;
  }
  return jStat.normal.inv(probability, mean, sd);
};

exports.NORM.S = {};

exports.NORM.S.DIST = function(z, cumulative) {
  z = utils.parseNumber(z);
  if (z instanceof Error) {
    return error.value;
  }
  return (cumulative) ? jStat.normal.cdf(z, 0, 1) : jStat.normal.pdf(z, 0, 1);
};

exports.NORM.S.INV = function(probability) {
  probability = utils.parseNumber(probability);
  if (probability instanceof Error) {
    return error.value;
  }
  return jStat.normal.inv(probability, 0, 1);
};

exports.PEARSON = function(data_x, data_y) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(data_y, data_x)) {
    return error.value;
  }
  var xmean = jStat.mean(data_x);
  var ymean = jStat.mean(data_y);
  var n = data_x.length;
  var num = 0;
  var den1 = 0;
  var den2 = 0;
  for (var i = 0; i < n; i++) {
    num += (data_x[i] - xmean) * (data_y[i] - ymean);
    den1 += Math.pow(data_x[i] - xmean, 2);
    den2 += Math.pow(data_y[i] - ymean, 2);
  }
  return num / Math.sqrt(den1 * den2);
};

exports.PERCENTILE = {};

exports.PERCENTILE.EXC = function(array, k) {
  array = utils.parseNumberArray(utils.flatten(array));
  k = utils.parseNumber(k);
  if (utils.anyIsError(array, k)) {
    return error.value;
  }
  array = array.sort(function(a, b) {
    {
      return a - b;
    }
  });
  var n = array.length;
  if (k < 1 / (n + 1) || k > 1 - 1 / (n + 1)) {
    return error.num;
  }
  var l = k * (n + 1) - 1;
  var fl = Math.floor(l);
  return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl]));
};

exports.PERCENTILE.INC = function(array, k) {
  array = utils.parseNumberArray(utils.flatten(array));
  k = utils.parseNumber(k);
  if (utils.anyIsError(array, k)) {
    return error.value;
  }
  array = array.sort(function(a, b) {
    return a - b;
  });
  var n = array.length;
  var l = k * (n - 1);
  var fl = Math.floor(l);
  return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl]));
};

exports.PERCENTRANK = {};

exports.PERCENTRANK.EXC = function(array, x, significance) {
  significance = (significance === undefined) ? 3 : significance;
  array = utils.parseNumberArray(utils.flatten(array));
  x = utils.parseNumber(x);
  significance = utils.parseNumber(significance);
  if (utils.anyIsError(array, x, significance)) {
    return error.value;
  }
  array = array.sort(function(a, b) {
    return a - b;
  });
  var uniques = misc.UNIQUE.apply(null, array);
  var n = array.length;
  var m = uniques.length;
  var power = Math.pow(10, significance);
  var result = 0;
  var match = false;
  var i = 0;
  while (!match && i < m) {
    if (x === uniques[i]) {
      result = (array.indexOf(uniques[i]) + 1) / (n + 1);
      match = true;
    } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {
      result = (array.indexOf(uniques[i]) + 1 + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n + 1);
      match = true;
    }
    i++;
  }
  return Math.floor(result * power) / power;
};

exports.PERCENTRANK.INC = function(array, x, significance) {
  significance = (significance === undefined) ? 3 : significance;
  array = utils.parseNumberArray(utils.flatten(array));
  x = utils.parseNumber(x);
  significance = utils.parseNumber(significance);
  if (utils.anyIsError(array, x, significance)) {
    return error.value;
  }
  array = array.sort(function(a, b) {
    return a - b;
  });
  var uniques = misc.UNIQUE.apply(null, array);
  var n = array.length;
  var m = uniques.length;
  var power = Math.pow(10, significance);
  var result = 0;
  var match = false;
  var i = 0;
  while (!match && i < m) {
    if (x === uniques[i]) {
      result = array.indexOf(uniques[i]) / (n - 1);
      match = true;
    } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {
      result = (array.indexOf(uniques[i]) + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n - 1);
      match = true;
    }
    i++;
  }
  return Math.floor(result * power) / power;
};

exports.PERMUT = function(number, number_chosen) {
  number = utils.parseNumber(number);
  number_chosen = utils.parseNumber(number_chosen);
  if (utils.anyIsError(number, number_chosen)) {
    return error.value;
  }
  return mathTrig.FACT(number) / mathTrig.FACT(number - number_chosen);
};

exports.PERMUTATIONA = function(number, number_chosen) {
  number = utils.parseNumber(number);
  number_chosen = utils.parseNumber(number_chosen);
  if (utils.anyIsError(number, number_chosen)) {
    return error.value;
  }
  return Math.pow(number, number_chosen);
};

exports.PHI = function(x) {
  x = utils.parseNumber(x);
  if (x instanceof Error) {
    return error.value;
  }
  return Math.exp(-0.5 * x * x) / SQRT2PI;
};

exports.POISSON = {};

exports.POISSON.DIST = function(x, mean, cumulative) {
  x = utils.parseNumber(x);
  mean = utils.parseNumber(mean);
  if (utils.anyIsError(x, mean)) {
    return error.value;
  }
  return (cumulative) ? jStat.poisson.cdf(x, mean) : jStat.poisson.pdf(x, mean);
};

exports.PROB = function(range, probability, lower, upper) {
  if (lower === undefined) {
    return 0;
  }
  upper = (upper === undefined) ? lower : upper;

  range = utils.parseNumberArray(utils.flatten(range));
  probability = utils.parseNumberArray(utils.flatten(probability));
  lower = utils.parseNumber(lower);
  upper = utils.parseNumber(upper);
  if (utils.anyIsError(range, probability, lower, upper)) {
    return error.value;
  }

  if (lower === upper) {
    return (range.indexOf(lower) >= 0) ? probability[range.indexOf(lower)] : 0;
  }

  var sorted = range.sort(function(a, b) {
    return a - b;
  });
  var n = sorted.length;
  var result = 0;
  for (var i = 0; i < n; i++) {
    if (sorted[i] >= lower && sorted[i] <= upper) {
      result += probability[range.indexOf(sorted[i])];
    }
  }
  return result;
};

exports.QUARTILE = {};

exports.QUARTILE.EXC = function(range, quart) {
  range = utils.parseNumberArray(utils.flatten(range));
  quart = utils.parseNumber(quart);
  if (utils.anyIsError(range, quart)) {
    return error.value;
  }
  switch (quart) {
    case 1:
      return exports.PERCENTILE.EXC(range, 0.25);
    case 2:
      return exports.PERCENTILE.EXC(range, 0.5);
    case 3:
      return exports.PERCENTILE.EXC(range, 0.75);
    default:
      return error.num;
  }
};

exports.QUARTILE.INC = function(range, quart) {
  range = utils.parseNumberArray(utils.flatten(range));
  quart = utils.parseNumber(quart);
  if (utils.anyIsError(range, quart)) {
    return error.value;
  }
  switch (quart) {
    case 1:
      return exports.PERCENTILE.INC(range, 0.25);
    case 2:
      return exports.PERCENTILE.INC(range, 0.5);
    case 3:
      return exports.PERCENTILE.INC(range, 0.75);
    default:
      return error.num;
  }
};

exports.RANK = {};

exports.RANK.AVG = function(number, range, order) {
  number = utils.parseNumber(number);
  range = utils.parseNumberArray(utils.flatten(range));
  if (utils.anyIsError(number, range)) {
    return error.value;
  }
  range = utils.flatten(range);
  order = order || false;
  var sort = (order) ? function(a, b) {
    return a - b;
  } : function(a, b) {
    return b - a;
  };
  range = range.sort(sort);

  var length = range.length;
  var count = 0;
  for (var i = 0; i < length; i++) {
    if (range[i] === number) {
      count++;
    }
  }

  return (count > 1) ? (2 * range.indexOf(number) + count + 1) / 2 : range.indexOf(number) + 1;
};

exports.RANK.EQ = function(number, range, order) {
  number = utils.parseNumber(number);
  range = utils.parseNumberArray(utils.flatten(range));
  if (utils.anyIsError(number, range)) {
    return error.value;
  }
  order = order || false;
  var sort = (order) ? function(a, b) {
    return a - b;
  } : function(a, b) {
    return b - a;
  };
  range = range.sort(sort);
  return range.indexOf(number) + 1;
};

exports.ROW = function(matrix, index) {
  if (arguments.length !== 2) {
    return error.na;
  }

  if (index < 0) {
    return error.num;
  }

  if (!(matrix instanceof Array) || (typeof index !== 'number')) {
    return error.value;
  }

  if (matrix.length === 0) {
    return undefined;
  }

  return jStat.row(matrix, index);
};

exports.ROWS = function(matrix) {
  if (arguments.length !== 1) {
    return error.na;
  }

  if (!(matrix instanceof Array)) {
    return error.value;
  }

  if (matrix.length === 0) {
    return 0;
  }

  return jStat.rows(matrix);
};

exports.RSQ = function(data_x, data_y) { // no need to flatten here, PEARSON will take care of that
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  if (utils.anyIsError(data_x, data_y)) {
    return error.value;
  }
  return Math.pow(exports.PEARSON(data_x, data_y), 2);
};

exports.SKEW = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var mean = jStat.mean(range);
  var n = range.length;
  var sigma = 0;
  for (var i = 0; i < n; i++) {
    sigma += Math.pow(range[i] - mean, 3);
  }
  return n * sigma / ((n - 1) * (n - 2) * Math.pow(jStat.stdev(range, true), 3));
};

exports.SKEW.P = function() {
  var range = utils.parseNumberArray(utils.flatten(arguments));
  if (range instanceof Error) {
    return range;
  }
  var mean = jStat.mean(range);
  var n = range.length;
  var m2 = 0;
  var m3 = 0;
  for (var i = 0; i < n; i++) {
    m3 += Math.pow(range[i] - mean, 3);
    m2 += Math.pow(range[i] - mean, 2);
  }
  m3 = m3 / n;
  m2 = m2 / n;
  return m3 / Math.pow(m2, 3 / 2);
};

exports.SLOPE = function(data_y, data_x) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(data_y, data_x)) {
    return error.value;
  }
  var xmean = jStat.mean(data_x);
  var ymean = jStat.mean(data_y);
  var n = data_x.length;
  var num = 0;
  var den = 0;
  for (var i = 0; i < n; i++) {
    num += (data_x[i] - xmean) * (data_y[i] - ymean);
    den += Math.pow(data_x[i] - xmean, 2);
  }
  return num / den;
};

exports.SMALL = function(range, k) {
  range = utils.parseNumberArray(utils.flatten(range));
  k = utils.parseNumber(k);
  if (utils.anyIsError(range, k)) {
    return range;
  }
  return range.sort(function(a, b) {
    return a - b;
  })[k - 1];
};

exports.STANDARDIZE = function(x, mean, sd) {
  x = utils.parseNumber(x);
  mean = utils.parseNumber(mean);
  sd = utils.parseNumber(sd);
  if (utils.anyIsError(x, mean, sd)) {
    return error.value;
  }
  return (x - mean) / sd;
};

exports.STDEV = {};

exports.STDEV.P = function() {
  var v = exports.VAR.P.apply(this, arguments);
  var result = Math.sqrt(v);

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.STDEV.S = function() {
  var v = exports.VAR.S.apply(this, arguments);
  var result = Math.sqrt(v);

  return result;
};

exports.STDEVA = function() {
  var v = exports.VARA.apply(this, arguments);
  var result = Math.sqrt(v);

  return result;
};

exports.STDEVPA = function() {
  var v = exports.VARPA.apply(this, arguments);
  var result = Math.sqrt(v);

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};


exports.STEYX = function(data_y, data_x) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  if (utils.anyIsError(data_y, data_x)) {
    return error.value;
  }
  var xmean = jStat.mean(data_x);
  var ymean = jStat.mean(data_y);
  var n = data_x.length;
  var lft = 0;
  var num = 0;
  var den = 0;
  for (var i = 0; i < n; i++) {
    lft += Math.pow(data_y[i] - ymean, 2);
    num += (data_x[i] - xmean) * (data_y[i] - ymean);
    den += Math.pow(data_x[i] - xmean, 2);
  }
  return Math.sqrt((lft - num * num / den) / (n - 2));
};

exports.TRANSPOSE = function(matrix) {
  if (!matrix) {
    return error.na;
  }
  return jStat.transpose(matrix);
};

exports.T = text.T;

exports.T.DIST = function(x, df, cumulative) {
  x = utils.parseNumber(x);
  df = utils.parseNumber(df);
  if (utils.anyIsError(x, df)) {
    return error.value;
  }
  return (cumulative) ? jStat.studentt.cdf(x, df) : jStat.studentt.pdf(x, df);
};

exports.T.DIST['2T'] = function(x, df) {
  if (arguments.length !== 2) {
    return error.na;
  }

  if (x < 0 || df < 1) {
    return error.num;
  }

  if ((typeof x !== 'number') || (typeof df !== 'number')) {
    return error.value;
  }

  return (1 - jStat.studentt.cdf(x , df)) * 2;
};

exports.T.DIST.RT = function(x, df) {
  if (arguments.length !== 2) {
    return error.na;
  }

  if (x < 0 || df < 1) {
    return error.num;
  }

  if ((typeof x !== 'number') || (typeof df !== 'number')) {
    return error.value;
  }

  return 1 - jStat.studentt.cdf(x , df);
};

exports.T.INV = function(probability, df) {
  probability = utils.parseNumber(probability);
  df = utils.parseNumber(df);
  if (utils.anyIsError(probability, df)) {
    return error.value;
  }
  return jStat.studentt.inv(probability, df);
};

exports.T.INV['2T'] = function(probability, df) {
  probability = utils.parseNumber(probability);
  df = utils.parseNumber(df);
  if (probability <= 0 || probability > 1 || df < 1) {
    return error.num;
  }
  if (utils.anyIsError(probability, df)) {
    return error.value;
  }
  return Math.abs(jStat.studentt.inv(probability/2, df));
};

// The algorithm can be found here:
// http://www.chem.uoa.gr/applets/AppletTtest/Appl_Ttest2.html
exports.T.TEST = function(data_x, data_y) {
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  if (utils.anyIsError(data_x, data_y)) {
    return error.value;
  }

  var mean_x = jStat.mean(data_x);
  var mean_y = jStat.mean(data_y);
  var s_x = 0;
  var s_y = 0;
  var i;

  for (i = 0; i < data_x.length; i++) {
    s_x += Math.pow(data_x[i] - mean_x, 2);
  }
  for (i = 0; i < data_y.length; i++) {
    s_y += Math.pow(data_y[i] - mean_y, 2);
  }

  s_x = s_x / (data_x.length-1);
  s_y = s_y / (data_y.length-1);

  var t = Math.abs(mean_x - mean_y) / Math.sqrt(s_x/data_x.length + s_y/data_y.length);

  return exports.T.DIST['2T'](t, data_x.length+data_y.length-2);
};

exports.TREND = function(data_y, data_x, new_data_x) {
  data_y = utils.parseNumberArray(utils.flatten(data_y));
  data_x = utils.parseNumberArray(utils.flatten(data_x));
  new_data_x = utils.parseNumberArray(utils.flatten(new_data_x));
  if (utils.anyIsError(data_y, data_x, new_data_x)) {
    return error.value;
  }
  var linest = exports.LINEST(data_y, data_x);
  var m = linest[0];
  var b = linest[1];
  var result = [];

  new_data_x.forEach(function(x) {
    result.push(m * x + b);
  });

  return result;
};

exports.TRIMMEAN = function(range, percent) {
  range = utils.parseNumberArray(utils.flatten(range));
  percent = utils.parseNumber(percent);
  if (utils.anyIsError(range, percent)) {
    return error.value;
  }
  var trim = mathTrig.FLOOR(range.length * percent, 2) / 2;
  return jStat.mean(utils.initial(utils.rest(range.sort(function(a, b) {
    return a - b;
  }), trim), trim));
};

exports.VAR = {};

exports.VAR.P = function() {
  var range = utils.numbers(utils.flatten(arguments));
  var n = range.length;
  var sigma = 0;
  var mean = exports.AVERAGE(range);
  var result;
  for (var i = 0; i < n; i++) {
    sigma += Math.pow(range[i] - mean, 2);
  }
  result = sigma / n;

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.VAR.S = function() {
  var range = utils.numbers(utils.flatten(arguments));
  var n = range.length;
  var sigma = 0;
  var mean = exports.AVERAGE(range);
  for (var i = 0; i < n; i++) {
    sigma += Math.pow(range[i] - mean, 2);
  }
  return sigma / (n - 1);
};

exports.VARA = function() {
  var range = utils.flatten(arguments);
  var n = range.length;
  var sigma = 0;
  var count = 0;
  var mean = exports.AVERAGEA(range);
  for (var i = 0; i < n; i++) {
    var el = range[i];
    if (typeof el === 'number') {
      sigma += Math.pow(el - mean, 2);
    } else if (el === true) {
      sigma += Math.pow(1 - mean, 2);
    } else {
      sigma += Math.pow(0 - mean, 2);
    }

    if (el !== null) {
      count++;
    }
  }
  return sigma / (count - 1);
};

exports.VARPA = function() {
  var range = utils.flatten(arguments);
  var n = range.length;
  var sigma = 0;
  var count = 0;
  var mean = exports.AVERAGEA(range);
  var result;
  for (var i = 0; i < n; i++) {
    var el = range[i];
    if (typeof el === 'number') {
      sigma += Math.pow(el - mean, 2);
    } else if (el === true) {
      sigma += Math.pow(1 - mean, 2);
    } else {
      sigma += Math.pow(0 - mean, 2);
    }

    if (el !== null) {
      count++;
    }
  }
  result = sigma / count;

  if (isNaN(result)) {
    result = error.num;
  }

  return result;
};

exports.WEIBULL = {};

exports.WEIBULL.DIST = function(x, alpha, beta, cumulative) {
  x = utils.parseNumber(x);
  alpha = utils.parseNumber(alpha);
  beta = utils.parseNumber(beta);
  if (utils.anyIsError(x, alpha, beta)) {
    return error.value;
  }
  return (cumulative) ? 1 - Math.exp(-Math.pow(x / beta, alpha)) : Math.pow(x, alpha - 1) * Math.exp(-Math.pow(x / beta, alpha)) * alpha / Math.pow(beta, alpha);
};

exports.Z = {};

exports.Z.TEST = function(range, x, sd) {
  range = utils.parseNumberArray(utils.flatten(range));
  x = utils.parseNumber(x);
  if (utils.anyIsError(range, x)) {
    return error.value;
  }

  sd = sd || exports.STDEV.S(range);
  var n = range.length;
  return 1 - exports.NORM.S.DIST((exports.AVERAGE(range) - x) / (sd / Math.sqrt(n)), true);
};


/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {

var utils = __webpack_require__(1);
var error = __webpack_require__(0);

//TODO
exports.ASC = function() {
  throw new Error('ASC is not implemented');
};

//TODO
exports.BAHTTEXT = function() {
  throw new Error('BAHTTEXT is not implemented');
};

exports.CHAR = function(number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return String.fromCharCode(number);
};

exports.CLEAN = function(text) {
  text = text || '';
  var re = /[\0-\x1F]/g;
  return text.replace(re, "");
};

exports.CODE = function(text) {
  text = text || '';
  var result = text.charCodeAt(0);

  if (isNaN(result)) {
    result = error.na;
  }
  return result;
};

exports.CONCATENATE = function() {
  var args = utils.flatten(arguments);

  var trueFound = 0;
  while ((trueFound = args.indexOf(true)) > -1) {
    args[trueFound] = 'TRUE';
  }

  var falseFound = 0;
  while ((falseFound = args.indexOf(false)) > -1) {
    args[falseFound] = 'FALSE';
  }

  return args.join('');
};

//TODO
exports.DBCS = function() {
  throw new Error('DBCS is not implemented');
};

//TODO
exports.DOLLAR = function() {
  throw new Error('DOLLAR is not implemented');
};

exports.EXACT = function(text1, text2) {
  if (arguments.length !== 2) {
    return error.na;
  }
  return text1 === text2;
};

exports.FIND = function(find_text, within_text, position) {
  if (arguments.length < 2) {
    return error.na;
  }
  position = (position === undefined) ? 0 : position;
  return within_text ? within_text.indexOf(find_text, position - 1) + 1 : null;
};

//TODO
exports.FIXED = function() {
  throw new Error('FIXED is not implemented');
};

exports.HTML2TEXT = function (value) {
  var result = '';

  if (value) {
    if (value instanceof Array) {
      value.forEach(function (line) {
        if (result !== '') {
          result += '\n';
        }
        result += (line.replace(/<(?:.|\n)*?>/gm, ''));
      });
    } else {
      result = value.replace(/<(?:.|\n)*?>/gm, '');
    }
  }

  return result;
};

exports.LEFT = function(text, number) {
  number = (number === undefined) ? 1 : number;
  number = utils.parseNumber(number);
  if (number instanceof Error || typeof text !== 'string') {
    return error.value;
  }
  return text ? text.substring(0, number) : null;
};

exports.LEN = function(text) {
  if (arguments.length === 0) {
    return error.error;
  }

  if (typeof text === 'string') {
    return text ? text.length : 0;
  }

  if (text.length) {
    return text.length;
  }

  return error.value;
};

exports.LOWER = function(text) {
  if (typeof text !== 'string') {
    return error.value;
  }
  return text ? text.toLowerCase() : text;
};

exports.MID = function(text, start, number) {
  start = utils.parseNumber(start);
  number = utils.parseNumber(number);
  if (utils.anyIsError(start, number) || typeof text !== 'string') {
    return number;
  }

  var begin = start - 1;
  var end = begin + number;

  return text.substring(begin, end);
};

// TODO
exports.NUMBERVALUE = function (text, decimal_separator, group_separator)  {
  decimal_separator = (typeof decimal_separator === 'undefined') ? '.' : decimal_separator;
  group_separator = (typeof group_separator === 'undefined') ? ',' : group_separator;
  return Number(text.replace(decimal_separator, '.').replace(group_separator, ''));
};

// TODO
exports.PRONETIC = function() {
  throw new Error('PRONETIC is not implemented');
};

exports.PROPER = function(text) {
  if (text === undefined || text.length === 0) {
    return error.value;
  }
  if (text === true) {
    text = 'TRUE';
  }
  if (text === false) {
    text = 'FALSE';
  }
  if (isNaN(text) && typeof text === 'number') {
    return error.value;
  }
  if (typeof text === 'number') {
    text = '' + text;
  }

  return text.replace(/\w\S*/g, function(txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });
};

exports.REGEXEXTRACT = function (text, regular_expression) {
  if (arguments.length < 2) {
    return error.na;
  }
  var match = text.match(new RegExp(regular_expression));
  return match ? (match[match.length > 1 ? match.length - 1 : 0]) : null;
};

exports.REGEXMATCH = function (text, regular_expression, full) {
  if (arguments.length < 2) {
    return error.na;
  }
  var match = text.match(new RegExp(regular_expression));
  return full ? match : !!match;
};

exports.REGEXREPLACE = function (text, regular_expression, replacement) {
  if (arguments.length < 3) {
    return error.na;
  }
  return text.replace(new RegExp(regular_expression), replacement);
};

exports.REPLACE = function(text, position, length, new_text) {
  position = utils.parseNumber(position);
  length = utils.parseNumber(length);
  if (utils.anyIsError(position, length) ||
    typeof text !== 'string' ||
    typeof new_text !== 'string') {
    return error.value;
  }
  return text.substr(0, position - 1) + new_text + text.substr(position - 1 + length);
};

exports.REPT = function(text, number) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return new Array(number + 1).join(text);
};

exports.RIGHT = function(text, number) {
  number = (number === undefined) ? 1 : number;
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }
  return text ? text.substring(text.length - number) : error.na;
};

exports.SEARCH = function(find_text, within_text, position) {
  var foundAt;
  if (typeof find_text !== 'string' || typeof within_text !== 'string') {
    return error.value;
  }
  position = (position === undefined) ? 0 : position;
  foundAt = within_text.toLowerCase().indexOf(find_text.toLowerCase(), position - 1)+1;
  return (foundAt === 0)?error.value:foundAt;
};

exports.SPLIT = function (text, separator) {
  return text.split(separator);
};

exports.SUBSTITUTE = function(text, old_text, new_text, occurrence) {
  if (arguments.length < 2) {
    return error.na;
  }
  if (!text || !old_text || !new_text) {
    return text;
  } else if (occurrence === undefined) {
    return text.replace(new RegExp(old_text, 'g'), new_text);
  } else {
    var index = 0;
    var i = 0;
    while (text.indexOf(old_text, index) > 0) {
      index = text.indexOf(old_text, index + 1);
      i++;
      if (i === occurrence) {
        return text.substring(0, index) + new_text + text.substring(index + old_text.length);
      }
    }
  }
};

exports.T = function(value) {
  return (typeof value === "string") ? value : '';
};

// TODO incomplete implementation
exports.TEXT = function() {
  throw new Error('TEXT is not implemented');
};

exports.TRIM = function(text) {
  if (typeof text !== 'string') {
    return error.value;
  }
  return text.replace(/ +/g, ' ').trim();
};

exports.UNICHAR = exports.CHAR;

exports.UNICODE = exports.CODE;

exports.UPPER = function(text) {
  if (typeof text !== 'string') {
    return error.value;
  }
  return text.toUpperCase();
};

//TODO
exports.VALUE = function() {
  throw new Error('VALUE is not implemented');
};


/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);

// TODO
exports.CELL = function() {
  throw new Error('CELL is not implemented');
};

exports.ERROR = {};
exports.ERROR.TYPE = function(error_val) {
  switch (error_val) {
    case error.nil: return 1;
    case error.div0: return 2;
    case error.value: return 3;
    case error.ref: return 4;
    case error.name: return 5;
    case error.num: return 6;
    case error.na: return 7;
    case error.data: return 8;
  }
  return error.na;
};

// TODO
exports.INFO = function() {
  throw new Error('INFO is not implemented');
};

exports.ISBLANK = function(value) {
  return value === null;
};

exports.ISBINARY = function (number) {
  return (/^[01]{1,10}$/).test(number);
};

exports.ISERR = function(value) {
  return ([error.value, error.ref, error.div0, error.num, error.name, error.nil]).indexOf(value) >= 0 ||
    (typeof value === 'number' && (isNaN(value) || !isFinite(value)));
};

exports.ISERROR = function(value) {
  return exports.ISERR(value) || value === error.na;
};

exports.ISEVEN = function(number) {
  return (Math.floor(Math.abs(number)) & 1) ? false : true;
};

// TODO
exports.ISFORMULA = function() {
  throw new Error('ISFORMULA is not implemented');
};

exports.ISLOGICAL = function(value) {
  return value === true || value === false;
};

exports.ISNA = function(value) {
  return value === error.na;
};

exports.ISNONTEXT = function(value) {
  return typeof(value) !== 'string';
};

exports.ISNUMBER = function(value) {
  return typeof(value) === 'number' && !isNaN(value) && isFinite(value);
};

exports.ISODD = function(number) {
  return (Math.floor(Math.abs(number)) & 1) ? true : false;
};

// TODO
exports.ISREF = function() {
  throw new Error('ISREF is not implemented');
};

exports.ISTEXT = function(value) {
  return typeof(value) === 'string';
};

exports.N = function(value) {
  if (this.ISNUMBER(value)) {
    return value;
  }
  if (value instanceof Date) {
    return value.getTime();
  }
  if (value === true) {
    return 1;
  }
  if (value === false) {
    return 0;
  }
  if (this.ISERROR(value)) {
    return value;
  }
  return 0;
};

exports.NA = function() {
  return error.na;
};


// TODO
exports.SHEET = function() {
  throw new Error('SHEET is not implemented');
};

// TODO
exports.SHEETS = function() {
  throw new Error('SHEETS is not implemented');
};

exports.TYPE = function(value) {
  if (this.ISNUMBER(value)) {
    return 1;
  }
  if (this.ISTEXT(value)) {
    return 2;
  }
  if (this.ISLOGICAL(value)) {
    return 4;
  }
  if (this.ISERROR(value)) {
    return 16;
  }
  if (Array.isArray(value)) {
    return 64;
  }
};


/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var utils = __webpack_require__(1);

var d1900 = new Date(Date.UTC(1900, 0, 1));
var WEEK_STARTS = [
  undefined,
  0,
  1,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  1,
  2,
  3,
  4,
  5,
  6,
  0
];
var WEEK_TYPES = [
  [],
  [1, 2, 3, 4, 5, 6, 7],
  [7, 1, 2, 3, 4, 5, 6],
  [6, 0, 1, 2, 3, 4, 5],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [7, 1, 2, 3, 4, 5, 6],
  [6, 7, 1, 2, 3, 4, 5],
  [5, 6, 7, 1, 2, 3, 4],
  [4, 5, 6, 7, 1, 2, 3],
  [3, 4, 5, 6, 7, 1, 2],
  [2, 3, 4, 5, 6, 7, 1],
  [1, 2, 3, 4, 5, 6, 7]
];
var WEEKEND_TYPES = [
  [],
  [6, 0],
  [0, 1],
  [1, 2],
  [2, 3],
  [3, 4],
  [4, 5],
  [5, 6],
  undefined,
  undefined,
  undefined, [0, 0],
  [1, 1],
  [2, 2],
  [3, 3],
  [4, 4],
  [5, 5],
  [6, 6]
];

exports.DATE = function(year, month, day) {
  var result;

  year = utils.parseNumber(year);
  month = utils.parseNumber(month);
  day = utils.parseNumber(day);

  if (utils.anyIsError(year, month, day)) {
    result = error.value;

  } else if (year < 0 || month < 0 || day < 0) {
    result = error.num;

  } else {
    result = new Date(year, month - 1, day);
  }

  return result;
};

exports.DATEVALUE = function(date_text) {
  var modifier = 2;
  var date;

  if (typeof date_text !== 'string') {
    return error.value;
  }

  date = Date.parse(date_text);

  if (isNaN(date)) {
    return error.value;
  }

  if (date <= -2203891200000) {
    modifier = 1;
  }

  return Math.ceil((date - d1900) / 86400000) + modifier;
};

exports.DAY = function(serial_number) {
  var date = utils.parseDate(serial_number);
  if (date instanceof Error) {
    return date;
  }

  return date.getDate();
};

exports.DAYS = function(end_date, start_date) {
  end_date = utils.parseDate(end_date);
  start_date = utils.parseDate(start_date);

  if (end_date instanceof Error) {
    return end_date;
  }
  if (start_date instanceof Error) {
    return start_date;
  }

  return serial(end_date) - serial(start_date);
};

exports.DAYS360 = function(start_date, end_date, method) {
  method = utils.parseBool(method);
  start_date = utils.parseDate(start_date);
  end_date = utils.parseDate(end_date);

  if (start_date instanceof Error) {
    return start_date;
  }
  if (end_date instanceof Error) {
    return end_date;
  }
  if (method instanceof Error) {
    return method;
  }
  var sm = start_date.getMonth();
  var em = end_date.getMonth();
  var sd, ed;

  if (method) {
    sd = start_date.getDate() === 31 ? 30 : start_date.getDate();
    ed = end_date.getDate() === 31 ? 30 : end_date.getDate();
  } else {
    var smd = new Date(start_date.getFullYear(), sm + 1, 0).getDate();
    var emd = new Date(end_date.getFullYear(), em + 1, 0).getDate();
    sd = start_date.getDate() === smd ? 30 : start_date.getDate();
    if (end_date.getDate() === emd) {
      if (sd < 30) {
        em++;
        ed = 1;
      } else {
        ed = 30;
      }
    } else {
      ed = end_date.getDate();
    }
  }

  return 360 * (end_date.getFullYear() - start_date.getFullYear()) +
    30 * (em - sm) + (ed - sd);
};

exports.EDATE = function(start_date, months) {
  start_date = utils.parseDate(start_date);

  if (start_date instanceof Error) {
    return start_date;
  }
  if (isNaN(months)) {
    return error.value;
  }
  months = parseInt(months, 10);
  start_date.setMonth(start_date.getMonth() + months);

  return serial(start_date);
};

exports.EOMONTH = function(start_date, months) {
  start_date = utils.parseDate(start_date);

  if (start_date instanceof Error) {
    return start_date;
  }
  if (isNaN(months)) {
    return error.value;
  }
  months = parseInt(months, 10);

  return serial(new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0));
};

exports.HOUR = function(serial_number) {
  serial_number = utils.parseDate(serial_number);

  if (serial_number instanceof Error) {
    return serial_number;
  }

  return serial_number.getHours();
};

exports.INTERVAL = function (second) {
  if (typeof second !== 'number' && typeof second !== 'string') {
    return error.value;
  } else {
    second = parseInt(second, 10);
  }

  var year  = Math.floor(second/946080000);
  second    = second%946080000;
  var month = Math.floor(second/2592000);
  second    = second%2592000;
  var day   = Math.floor(second/86400);
  second    = second%86400;

  var hour  = Math.floor(second/3600);
  second    = second%3600;
  var min   = Math.floor(second/60);
  second    = second%60;
  var sec   = second;

  year  = (year  > 0) ? year  + 'Y' : '';
  month = (month > 0) ? month + 'M' : '';
  day   = (day   > 0) ? day   + 'D' : '';
  hour  = (hour  > 0) ? hour  + 'H' : '';
  min   = (min   > 0) ? min   + 'M' : '';
  sec   = (sec   > 0) ? sec   + 'S' : '';

  return 'P' + year + month + day + 'T' + hour + min + sec;
};

exports.ISOWEEKNUM = function(date) {
  date = utils.parseDate(date);

  if (date instanceof Error) {
    return date;
  }

  date.setHours(0, 0, 0);
  date.setDate(date.getDate() + 4 - (date.getDay() || 7));
  var yearStart = new Date(date.getFullYear(), 0, 1);

  return Math.ceil((((date - yearStart) / 86400000) + 1) / 7);
};

exports.MINUTE = function(serial_number) {
  serial_number = utils.parseDate(serial_number);

  if (serial_number instanceof Error) {
    return serial_number;
  }

  return serial_number.getMinutes();
};

exports.MONTH = function(serial_number) {
  serial_number = utils.parseDate(serial_number);

  if (serial_number instanceof Error) {
    return serial_number;
  }

  return serial_number.getMonth() + 1;
};

exports.NETWORKDAYS = function(start_date, end_date, holidays) {
  return this.NETWORKDAYS.INTL(start_date, end_date, 1, holidays);
};

exports.NETWORKDAYS.INTL = function(start_date, end_date, weekend, holidays) {
  start_date = utils.parseDate(start_date);

  if (start_date instanceof Error) {
    return start_date;
  }
  end_date = utils.parseDate(end_date);

  if (end_date instanceof Error) {
    return end_date;
  }
  if (weekend === undefined) {
    weekend = WEEKEND_TYPES[1];
  } else {
    weekend = WEEKEND_TYPES[weekend];
  }
  if (!(weekend instanceof Array)) {
    return error.value;
  }
  if (holidays === undefined) {
    holidays = [];
  } else if (!(holidays instanceof Array)) {
    holidays = [holidays];
  }

  for (var i = 0; i < holidays.length; i++) {
    var h = utils.parseDate(holidays[i]);
    if (h instanceof Error) {
      return h;
    }
    holidays[i] = h;
  }
  var days = (end_date - start_date) / (1000 * 60 * 60 * 24) + 1;
  var total = days;
  var day = start_date;
  for (i = 0; i < days; i++) {
    var d = (new Date().getTimezoneOffset() > 0) ? day.getUTCDay() : day.getDay();
    var dec = false;
    if (d === weekend[0] || d === weekend[1]) {
      dec = true;
    }
    for (var j = 0; j < holidays.length; j++) {
      var holiday = holidays[j];
      if (holiday.getDate() === day.getDate() &&
        holiday.getMonth() === day.getMonth() &&
        holiday.getFullYear() === day.getFullYear()) {
        dec = true;
        break;
      }
    }
    if (dec) {
      total--;
    }
    day.setDate(day.getDate() + 1);
  }

  return total;
};

exports.NOW = function() {
  return new Date();
};

exports.SECOND = function(serial_number) {
  serial_number = utils.parseDate(serial_number);
  if (serial_number instanceof Error) {
    return serial_number;
  }

  return serial_number.getSeconds();
};

exports.TIME = function(hour, minute, second) {
  hour = utils.parseNumber(hour);
  minute = utils.parseNumber(minute);
  second = utils.parseNumber(second);
  if (utils.anyIsError(hour, minute, second)) {
    return error.value;
  }
  if (hour < 0 || minute < 0 || second < 0) {
    return error.num;
  }

  return (3600 * hour + 60 * minute + second) / 86400;
};

exports.TIMEVALUE = function(time_text) {
  time_text = utils.parseDate(time_text);

  if (time_text instanceof Error) {
    return time_text;
  }

  return (3600 * time_text.getHours() + 60 * time_text.getMinutes() + time_text.getSeconds()) / 86400;
};

exports.TODAY = function() {
  return new Date();
};

exports.WEEKDAY = function(serial_number, return_type) {
  serial_number = utils.parseDate(serial_number);
  if (serial_number instanceof Error) {
    return serial_number;
  }
  if (return_type === undefined) {
    return_type = 1;
  }
  var day = serial_number.getDay();

  return WEEK_TYPES[return_type][day];
};

exports.WEEKNUM = function(serial_number, return_type) {
  serial_number = utils.parseDate(serial_number);
  if (serial_number instanceof Error) {
    return serial_number;
  }
  if (return_type === undefined) {
    return_type = 1;
  }
  if (return_type === 21) {
    return this.ISOWEEKNUM(serial_number);
  }
  var week_start = WEEK_STARTS[return_type];
  var jan = new Date(serial_number.getFullYear(), 0, 1);
  var inc = jan.getDay() < week_start ? 1 : 0;
  jan -= Math.abs(jan.getDay() - week_start) * 24 * 60 * 60 * 1000;

  return Math.floor(((serial_number - jan) / (1000 * 60 * 60 * 24)) / 7 + 1) + inc;
};

exports.WORKDAY = function(start_date, days, holidays) {
  return this.WORKDAY.INTL(start_date, days, 1, holidays);
};

exports.WORKDAY.INTL = function(start_date, days, weekend, holidays) {
  start_date = utils.parseDate(start_date);
  if (start_date instanceof Error) {
    return start_date;
  }
  days = utils.parseNumber(days);
  if (days instanceof Error) {
    return days;
  }
  if (days < 0) {
    return error.num;
  }
  if (weekend === undefined) {
    weekend = WEEKEND_TYPES[1];
  } else {
    weekend = WEEKEND_TYPES[weekend];
  }
  if (!(weekend instanceof Array)) {
    return error.value;
  }
  if (holidays === undefined) {
    holidays = [];
  } else if (!(holidays instanceof Array)) {
    holidays = [holidays];
  }
  for (var i = 0; i < holidays.length; i++) {
    var h = utils.parseDate(holidays[i]);
    if (h instanceof Error) {
      return h;
    }
    holidays[i] = h;
  }
  var d = 0;
  while (d < days) {
    start_date.setDate(start_date.getDate() + 1);
    var day = start_date.getDay();
    if (day === weekend[0] || day === weekend[1]) {
      continue;
    }
    for (var j = 0; j < holidays.length; j++) {
      var holiday = holidays[j];
      if (holiday.getDate() === start_date.getDate() &&
        holiday.getMonth() === start_date.getMonth() &&
        holiday.getFullYear() === start_date.getFullYear()) {
        d--;
        break;
      }
    }
    d++;
  }

  return start_date;
};

exports.YEAR = function(serial_number) {
  serial_number = utils.parseDate(serial_number);

  if (serial_number instanceof Error) {
    return serial_number;
  }

  return serial_number.getFullYear();
};

function isLeapYear(year) {
  return new Date(year, 1, 29).getMonth() === 1;
}

// TODO : Use DAYS ?
function daysBetween(start_date, end_date) {
  return Math.ceil((end_date - start_date) / 1000 / 60 / 60 / 24);
}

exports.YEARFRAC = function(start_date, end_date, basis) {
  start_date = utils.parseDate(start_date);
  if (start_date instanceof Error) {
    return start_date;
  }
  end_date = utils.parseDate(end_date);
  if (end_date instanceof Error) {
    return end_date;
  }

  basis = basis || 0;
  var sd = start_date.getDate();
  var sm = start_date.getMonth() + 1;
  var sy = start_date.getFullYear();
  var ed = end_date.getDate();
  var em = end_date.getMonth() + 1;
  var ey = end_date.getFullYear();

  switch (basis) {
    case 0:
      // US (NASD) 30/360
      if (sd === 31 && ed === 31) {
        sd = 30;
        ed = 30;
      } else if (sd === 31) {
        sd = 30;
      } else if (sd === 30 && ed === 31) {
        ed = 30;
      }
      return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360;
    case 1:
      // Actual/actual
      var feb29Between = function(date1, date2) {
        var year1 = date1.getFullYear();
        var mar1year1 = new Date(year1, 2, 1);
        if (isLeapYear(year1) && date1 < mar1year1 && date2 >= mar1year1) {
          return true;
        }
        var year2 = date2.getFullYear();
        var mar1year2 = new Date(year2, 2, 1);
        return (isLeapYear(year2) && date2 >= mar1year2 && date1 < mar1year2);
      };
      var ylength = 365;
      if (sy === ey || ((sy + 1) === ey) && ((sm > em) || ((sm === em) && (sd >= ed)))) {
        if ((sy === ey && isLeapYear(sy)) ||
          feb29Between(start_date, end_date) ||
          (em === 1 && ed === 29)) {
          ylength = 366;
        }
        return daysBetween(start_date, end_date) / ylength;
      }
      var years = (ey - sy) + 1;
      var days = (new Date(ey + 1, 0, 1) - new Date(sy, 0, 1)) / 1000 / 60 / 60 / 24;
      var average = days / years;
      return daysBetween(start_date, end_date) / average;
    case 2:
      // Actual/360
      return daysBetween(start_date, end_date) / 360;
    case 3:
      // Actual/365
      return daysBetween(start_date, end_date) / 365;
    case 4:
      // European 30/360
      return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360;
  }
};

function serial(date) {
  var addOn = (date > -2203891200000) ? 2 : 1;

  return Math.ceil((date - d1900) / 86400000) + addOn;
}


/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {

(function (window, factory) {
    if (true) {
        module.exports = factory();
    } else {}
})(this, function () {
var jStat = (function(Math, undefined) {

// For quick reference.
var concat = Array.prototype.concat;
var slice = Array.prototype.slice;
var toString = Object.prototype.toString;

// Calculate correction for IEEE error
// TODO: This calculation can be improved.
function calcRdx(n, m) {
  var val = n > m ? n : m;
  return Math.pow(10,
                  17 - ~~(Math.log(((val > 0) ? val : -val)) * Math.LOG10E));
}


var isArray = Array.isArray || function isArray(arg) {
  return toString.call(arg) === '[object Array]';
};


function isFunction(arg) {
  return toString.call(arg) === '[object Function]';
}


function isNumber(arg) {
  return typeof arg === 'number' && arg === arg;
}


// Converts the jStat matrix to vector.
function toVector(arr) {
  return concat.apply([], arr);
}


// The one and only jStat constructor.
function jStat() {
  return new jStat._init(arguments);
}


// TODO: Remove after all references in src files have been removed.
jStat.fn = jStat.prototype;


// By separating the initializer from the constructor it's easier to handle
// always returning a new instance whether "new" was used or not.
jStat._init = function _init(args) {
  var i;

  // If first argument is an array, must be vector or matrix.
  if (isArray(args[0])) {
    // Check if matrix.
    if (isArray(args[0][0])) {
      // See if a mapping function was also passed.
      if (isFunction(args[1]))
        args[0] = jStat.map(args[0], args[1]);
      // Iterate over each is faster than this.push.apply(this, args[0].
      for (var i = 0; i < args[0].length; i++)
        this[i] = args[0][i];
      this.length = args[0].length;

    // Otherwise must be a vector.
    } else {
      this[0] = isFunction(args[1]) ? jStat.map(args[0], args[1]) : args[0];
      this.length = 1;
    }

  // If first argument is number, assume creation of sequence.
  } else if (isNumber(args[0])) {
    this[0] = jStat.seq.apply(null, args);
    this.length = 1;

  // Handle case when jStat object is passed to jStat.
  } else if (args[0] instanceof jStat) {
    // Duplicate the object and pass it back.
    return jStat(args[0].toArray());

  // Unexpected argument value, return empty jStat object.
  // TODO: This is strange behavior. Shouldn't this throw or some such to let
  // the user know they had bad arguments?
  } else {
    this[0] = [];
    this.length = 1;
  }

  return this;
};
jStat._init.prototype = jStat.prototype;
jStat._init.constructor = jStat;


// Utility functions.
// TODO: for internal use only?
jStat.utils = {
  calcRdx: calcRdx,
  isArray: isArray,
  isFunction: isFunction,
  isNumber: isNumber,
  toVector: toVector
};


// Easily extend the jStat object.
// TODO: is this seriously necessary?
jStat.extend = function extend(obj) {
  var i, j;

  if (arguments.length === 1) {
    for (j in obj)
      jStat[j] = obj[j];
    return this;
  }

  for (var i = 1; i < arguments.length; i++) {
    for (j in arguments[i])
      obj[j] = arguments[i][j];
  }

  return obj;
};


// Returns the number of rows in the matrix.
jStat.rows = function rows(arr) {
  return arr.length || 1;
};


// Returns the number of columns in the matrix.
jStat.cols = function cols(arr) {
  return arr[0].length || 1;
};


// Returns the dimensions of the object { rows: i, cols: j }
jStat.dimensions = function dimensions(arr) {
  return {
    rows: jStat.rows(arr),
    cols: jStat.cols(arr)
  };
};


// Returns a specified row as a vector or return a sub matrix by pick some rows
jStat.row = function row(arr, index) {
  if (isArray(index)) {
    return index.map(function(i) {
      return jStat.row(arr, i);
    })
  }
  return arr[index];
};


// return row as array
// rowa([[1,2],[3,4]],0) -> [1,2]
jStat.rowa = function rowa(arr, i) {
  return jStat.row(arr, i);
};


// Returns the specified column as a vector or return a sub matrix by pick some
// columns
jStat.col = function col(arr, index) {
  if (isArray(index)) {
    var submat = jStat.arange(arr.length).map(function(i) {
      return new Array(index.length);
    });
    index.forEach(function(ind, i){
      jStat.arange(arr.length).forEach(function(j) {
        submat[j][i] = arr[j][ind];
      });
    });
    return submat;
  }
  var column = new Array(arr.length);
  for (var i = 0; i < arr.length; i++)
    column[i] = [arr[i][index]];
  return column;
};


// return column as array
// cola([[1,2],[3,4]],0) -> [1,3]
jStat.cola = function cola(arr, i) {
  return jStat.col(arr, i).map(function(a){ return a[0] });
};


// Returns the diagonal of the matrix
jStat.diag = function diag(arr) {
  var nrow = jStat.rows(arr);
  var res = new Array(nrow);
  for (var row = 0; row < nrow; row++)
    res[row] = [arr[row][row]];
  return res;
};


// Returns the anti-diagonal of the matrix
jStat.antidiag = function antidiag(arr) {
  var nrow = jStat.rows(arr) - 1;
  var res = new Array(nrow);
  for (var i = 0; nrow >= 0; nrow--, i++)
    res[i] = [arr[i][nrow]];
  return res;
};

// Transpose a matrix or array.
jStat.transpose = function transpose(arr) {
  var obj = [];
  var objArr, rows, cols, j, i;

  // Make sure arr is in matrix format.
  if (!isArray(arr[0]))
    arr = [arr];

  rows = arr.length;
  cols = arr[0].length;

  for (var i = 0; i < cols; i++) {
    objArr = new Array(rows);
    for (j = 0; j < rows; j++)
      objArr[j] = arr[j][i];
    obj.push(objArr);
  }

  // If obj is vector, return only single array.
  return obj.length === 1 ? obj[0] : obj;
};


// Map a function to an array or array of arrays.
// "toAlter" is an internal variable.
jStat.map = function map(arr, func, toAlter) {
  var row, nrow, ncol, res, col;

  if (!isArray(arr[0]))
    arr = [arr];

  nrow = arr.length;
  ncol = arr[0].length;
  res = toAlter ? arr : new Array(nrow);

  for (row = 0; row < nrow; row++) {
    // if the row doesn't exist, create it
    if (!res[row])
      res[row] = new Array(ncol);
    for (col = 0; col < ncol; col++)
      res[row][col] = func(arr[row][col], row, col);
  }

  return res.length === 1 ? res[0] : res;
};


// Cumulatively combine the elements of an array or array of arrays using a function.
jStat.cumreduce = function cumreduce(arr, func, toAlter) {
  var row, nrow, ncol, res, col;

  if (!isArray(arr[0]))
    arr = [arr];

  nrow = arr.length;
  ncol = arr[0].length;
  res = toAlter ? arr : new Array(nrow);

  for (row = 0; row < nrow; row++) {
    // if the row doesn't exist, create it
    if (!res[row])
      res[row] = new Array(ncol);
    if (ncol > 0)
      res[row][0] = arr[row][0];
    for (col = 1; col < ncol; col++)
      res[row][col] = func(res[row][col-1], arr[row][col]);
  }
  return res.length === 1 ? res[0] : res;
};


// Destructively alter an array.
jStat.alter = function alter(arr, func) {
  return jStat.map(arr, func, true);
};


// Generate a rows x cols matrix according to the supplied function.
jStat.create = function  create(rows, cols, func) {
  var res = new Array(rows);
  var i, j;

  if (isFunction(cols)) {
    func = cols;
    cols = rows;
  }

  for (var i = 0; i < rows; i++) {
    res[i] = new Array(cols);
    for (j = 0; j < cols; j++)
      res[i][j] = func(i, j);
  }

  return res;
};


function retZero() { return 0; }


// Generate a rows x cols matrix of zeros.
jStat.zeros = function zeros(rows, cols) {
  if (!isNumber(cols))
    cols = rows;
  return jStat.create(rows, cols, retZero);
};


function retOne() { return 1; }


// Generate a rows x cols matrix of ones.
jStat.ones = function ones(rows, cols) {
  if (!isNumber(cols))
    cols = rows;
  return jStat.create(rows, cols, retOne);
};


// Generate a rows x cols matrix of uniformly random numbers.
jStat.rand = function rand(rows, cols) {
  if (!isNumber(cols))
    cols = rows;
  return jStat.create(rows, cols, Math.random);
};


function retIdent(i, j) { return i === j ? 1 : 0; }


// Generate an identity matrix of size row x cols.
jStat.identity = function identity(rows, cols) {
  if (!isNumber(cols))
    cols = rows;
  return jStat.create(rows, cols, retIdent);
};


// Tests whether a matrix is symmetric
jStat.symmetric = function symmetric(arr) {
  var issymmetric = true;
  var size = arr.length;
  var row, col;

  if (arr.length !== arr[0].length)
    return false;

  for (row = 0; row < size; row++) {
    for (col = 0; col < size; col++)
      if (arr[col][row] !== arr[row][col])
        return false;
  }

  return true;
};


// Set all values to zero.
jStat.clear = function clear(arr) {
  return jStat.alter(arr, retZero);
};


// Generate sequence.
jStat.seq = function seq(min, max, length, func) {
  if (!isFunction(func))
    func = false;

  var arr = [];
  var hival = calcRdx(min, max);
  var step = (max * hival - min * hival) / ((length - 1) * hival);
  var current = min;
  var cnt;

  // Current is assigned using a technique to compensate for IEEE error.
  // TODO: Needs better implementation.
  for (cnt = 0;
       current <= max && cnt < length;
       cnt++, current = (min * hival + step * hival * cnt) / hival) {
    arr.push((func ? func(current, cnt) : current));
  }

  return arr;
};


// arange(5) -> [0,1,2,3,4]
// arange(1,5) -> [1,2,3,4]
// arange(5,1,-1) -> [5,4,3,2]
jStat.arange = function arange(start, end, step) {
  var rl = [];
  step = step || 1;
  if (end === undefined) {
    end = start;
    start = 0;
  }
  if (start === end || step === 0) {
    return [];
  }
  if (start < end && step < 0) {
    return [];
  }
  if (start > end && step > 0) {
    return [];
  }
  if (step > 0) {
    for (i = start; i < end; i += step) {
      rl.push(i);
    }
  } else {
    for (i = start; i > end; i += step) {
      rl.push(i);
    }
  }
  return rl;
};


// A=[[1,2,3],[4,5,6],[7,8,9]]
// slice(A,{row:{end:2},col:{start:1}}) -> [[2,3],[5,6]]
// slice(A,1,{start:1}) -> [5,6]
// as numpy code A[:2,1:]
jStat.slice = (function(){
  function _slice(list, start, end, step) {
    // note it's not equal to range.map mode it's a bug
    var i;
    var rl = [];
    var length = list.length;
    if (start === undefined && end === undefined && step === undefined) {
      return jStat.copy(list);
    }

    start = start || 0;
    end = end || list.length;
    start = start >= 0 ? start : length + start;
    end = end >= 0 ? end : length + end;
    step = step || 1;
    if (start === end || step === 0) {
      return [];
    }
    if (start < end && step < 0) {
      return [];
    }
    if (start > end && step > 0) {
      return [];
    }
    if (step > 0) {
      for (i = start; i < end; i += step) {
        rl.push(list[i]);
      }
    } else {
      for (i = start; i > end;i += step) {
        rl.push(list[i]);
      }
    }
    return rl;
  }

  function slice(list, rcSlice) {
    rcSlice = rcSlice || {};
    if (isNumber(rcSlice.row)) {
      if (isNumber(rcSlice.col))
        return list[rcSlice.row][rcSlice.col];
      var row = jStat.rowa(list, rcSlice.row);
      var colSlice = rcSlice.col || {};
      return _slice(row, colSlice.start, colSlice.end, colSlice.step);
    }

    if (isNumber(rcSlice.col)) {
      var col = jStat.cola(list, rcSlice.col);
      var rowSlice = rcSlice.row || {};
      return _slice(col, rowSlice.start, rowSlice.end, rowSlice.step);
    }

    var rowSlice = rcSlice.row || {};
    var colSlice = rcSlice.col || {};
    var rows = _slice(list, rowSlice.start, rowSlice.end, rowSlice.step);
    return rows.map(function(row) {
      return _slice(row, colSlice.start, colSlice.end, colSlice.step);
    });
  }

  return slice;
}());


// A=[[1,2,3],[4,5,6],[7,8,9]]
// sliceAssign(A,{row:{start:1},col:{start:1}},[[0,0],[0,0]])
// A=[[1,2,3],[4,0,0],[7,0,0]]
jStat.sliceAssign = function sliceAssign(A, rcSlice, B) {
  if (isNumber(rcSlice.row)) {
    if (isNumber(rcSlice.col))
      return A[rcSlice.row][rcSlice.col] = B;
    rcSlice.col = rcSlice.col || {};
    rcSlice.col.start = rcSlice.col.start || 0;
    rcSlice.col.end = rcSlice.col.end || A[0].length;
    rcSlice.col.step = rcSlice.col.step || 1;
    var nl = jStat.arange(rcSlice.col.start,
                          Math.min(A.length, rcSlice.col.end),
                          rcSlice.col.step);
    var m = rcSlice.row;
    nl.forEach(function(n, i) {
      A[m][n] = B[i];
    });
    return A;
  }

  if (isNumber(rcSlice.col)) {
    rcSlice.row = rcSlice.row || {};
    rcSlice.row.start = rcSlice.row.start || 0;
    rcSlice.row.end = rcSlice.row.end || A.length;
    rcSlice.row.step = rcSlice.row.step || 1;
    var ml = jStat.arange(rcSlice.row.start,
                          Math.min(A[0].length, rcSlice.row.end),
                          rcSlice.row.step);
    var n = rcSlice.col;
    ml.forEach(function(m, j) {
      A[m][n] = B[j];
    });
    return A;
  }

  if (B[0].length === undefined) {
    B = [B];
  }
  rcSlice.row.start = rcSlice.row.start || 0;
  rcSlice.row.end = rcSlice.row.end || A.length;
  rcSlice.row.step = rcSlice.row.step || 1;
  rcSlice.col.start = rcSlice.col.start || 0;
  rcSlice.col.end = rcSlice.col.end || A[0].length;
  rcSlice.col.step = rcSlice.col.step || 1;
  var ml = jStat.arange(rcSlice.row.start,
                        Math.min(A.length, rcSlice.row.end),
                        rcSlice.row.step);
  var nl = jStat.arange(rcSlice.col.start,
                        Math.min(A[0].length, rcSlice.col.end),
                        rcSlice.col.step);
  ml.forEach(function(m, i) {
    nl.forEach(function(n, j) {
      A[m][n] = B[i][j];
    });
  });
  return A;
};


// [1,2,3] ->
// [[1,0,0],[0,2,0],[0,0,3]]
jStat.diagonal = function diagonal(diagArray) {
  var mat = jStat.zeros(diagArray.length, diagArray.length);
  diagArray.forEach(function(t, i) {
    mat[i][i] = t;
  });
  return mat;
};


// return copy of A
jStat.copy = function copy(A) {
  return A.map(function(row) {
    if (isNumber(row))
      return row;
    return row.map(function(t) {
      return t;
    });
  });
};


// TODO: Go over this entire implementation. Seems a tragic waste of resources
// doing all this work. Instead, and while ugly, use new Function() to generate
// a custom function for each static method.

// Quick reference.
var jProto = jStat.prototype;

// Default length.
jProto.length = 0;

// For internal use only.
// TODO: Check if they're actually used, and if they are then rename them
// to _*
jProto.push = Array.prototype.push;
jProto.sort = Array.prototype.sort;
jProto.splice = Array.prototype.splice;
jProto.slice = Array.prototype.slice;


// Return a clean array.
jProto.toArray = function toArray() {
  return this.length > 1 ? slice.call(this) : slice.call(this)[0];
};


// Map a function to a matrix or vector.
jProto.map = function map(func, toAlter) {
  return jStat(jStat.map(this, func, toAlter));
};


// Cumulatively combine the elements of a matrix or vector using a function.
jProto.cumreduce = function cumreduce(func, toAlter) {
  return jStat(jStat.cumreduce(this, func, toAlter));
};


// Destructively alter an array.
jProto.alter = function alter(func) {
  jStat.alter(this, func);
  return this;
};


// Extend prototype with methods that have no argument.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jProto[passfunc] = function(func) {
      var self = this,
      results;
      // Check for callback.
      if (func) {
        setTimeout(function() {
          func.call(self, jProto[passfunc].call(self));
        });
        return this;
      }
      results = jStat[passfunc](this);
      return isArray(results) ? jStat(results) : results;
    };
  })(funcs[i]);
})('transpose clear symmetric rows cols dimensions diag antidiag'.split(' '));


// Extend prototype with methods that have one argument.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jProto[passfunc] = function(index, func) {
      var self = this;
      // check for callback
      if (func) {
        setTimeout(function() {
          func.call(self, jProto[passfunc].call(self, index));
        });
        return this;
      }
      return jStat(jStat[passfunc](this, index));
    };
  })(funcs[i]);
})('row col'.split(' '));


// Extend prototype with simple shortcut methods.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jProto[passfunc] = new Function(
        'return jStat(jStat.' + passfunc + '.apply(null, arguments));');
  })(funcs[i]);
})('create zeros ones rand identity'.split(' '));


// Exposing jStat.
return jStat;

}(Math));
(function(jStat, Math) {

var isFunction = jStat.utils.isFunction;

// Ascending functions for sort
function ascNum(a, b) { return a - b; }

function clip(arg, min, max) {
  return Math.max(min, Math.min(arg, max));
}


// sum of an array
jStat.sum = function sum(arr) {
  var sum = 0;
  var i = arr.length;
  while (--i >= 0)
    sum += arr[i];
  return sum;
};


// sum squared
jStat.sumsqrd = function sumsqrd(arr) {
  var sum = 0;
  var i = arr.length;
  while (--i >= 0)
    sum += arr[i] * arr[i];
  return sum;
};


// sum of squared errors of prediction (SSE)
jStat.sumsqerr = function sumsqerr(arr) {
  var mean = jStat.mean(arr);
  var sum = 0;
  var i = arr.length;
  var tmp;
  while (--i >= 0) {
    tmp = arr[i] - mean;
    sum += tmp * tmp;
  }
  return sum;
};

// sum of an array in each row
jStat.sumrow = function sumrow(arr) {
  var sum = 0;
  var i = arr.length;
  while (--i >= 0)
    sum += arr[i];
  return sum;
};

// product of an array
jStat.product = function product(arr) {
  var prod = 1;
  var i = arr.length;
  while (--i >= 0)
    prod *= arr[i];
  return prod;
};


// minimum value of an array
jStat.min = function min(arr) {
  var low = arr[0];
  var i = 0;
  while (++i < arr.length)
    if (arr[i] < low)
      low = arr[i];
  return low;
};


// maximum value of an array
jStat.max = function max(arr) {
  var high = arr[0];
  var i = 0;
  while (++i < arr.length)
    if (arr[i] > high)
      high = arr[i];
  return high;
};


// unique values of an array
jStat.unique = function unique(arr) {
  var hash = {}, _arr = [];
  for(var i = 0; i < arr.length; i++) {
    if (!hash[arr[i]]) {
      hash[arr[i]] = true;
      _arr.push(arr[i]);
    }
  }
  return _arr;
};


// mean value of an array
jStat.mean = function mean(arr) {
  return jStat.sum(arr) / arr.length;
};


// mean squared error (MSE)
jStat.meansqerr = function meansqerr(arr) {
  return jStat.sumsqerr(arr) / arr.length;
};


// geometric mean of an array
jStat.geomean = function geomean(arr) {
  return Math.pow(jStat.product(arr), 1 / arr.length);
};


// median of an array
jStat.median = function median(arr) {
  var arrlen = arr.length;
  var _arr = arr.slice().sort(ascNum);
  // check if array is even or odd, then return the appropriate
  return !(arrlen & 1)
    ? (_arr[(arrlen / 2) - 1 ] + _arr[(arrlen / 2)]) / 2
    : _arr[(arrlen / 2) | 0 ];
};


// cumulative sum of an array
jStat.cumsum = function cumsum(arr) {
  return jStat.cumreduce(arr, function (a, b) { return a + b; });
};


// cumulative product of an array
jStat.cumprod = function cumprod(arr) {
  return jStat.cumreduce(arr, function (a, b) { return a * b; });
};


// successive differences of a sequence
jStat.diff = function diff(arr) {
  var diffs = [];
  var arrLen = arr.length;
  var i;
  for (var i = 1; i < arrLen; i++)
    diffs.push(arr[i] - arr[i - 1]);
  return diffs;
};


// ranks of an array
jStat.rank = function (arr) {
  var arrlen = arr.length;
  var sorted = arr.slice().sort(ascNum);
  var ranks = new Array(arrlen);
  for (var i = 0; i < arrlen; i++) {
    var first = sorted.indexOf(arr[i]);
    var last = sorted.lastIndexOf(arr[i]);
    if (first === last) {
      var val = first;
    } else {
      var val = (first + last) / 2;
    }
    ranks[i] = val + 1;
  }
  return ranks;
};


// mode of an array
// if there are multiple modes of an array, return all of them
// is this the appropriate way of handling it?
jStat.mode = function mode(arr) {
  var arrLen = arr.length;
  var _arr = arr.slice().sort(ascNum);
  var count = 1;
  var maxCount = 0;
  var numMaxCount = 0;
  var mode_arr = [];
  var i;

  for (var i = 0; i < arrLen; i++) {
    if (_arr[i] === _arr[i + 1]) {
      count++;
    } else {
      if (count > maxCount) {
        mode_arr = [_arr[i]];
        maxCount = count;
        numMaxCount = 0;
      }
      // are there multiple max counts
      else if (count === maxCount) {
        mode_arr.push(_arr[i]);
        numMaxCount++;
      }
      // resetting count for new value in array
      count = 1;
    }
  }

  return numMaxCount === 0 ? mode_arr[0] : mode_arr;
};


// range of an array
jStat.range = function range(arr) {
  return jStat.max(arr) - jStat.min(arr);
};

// variance of an array
// flag = true indicates sample instead of population
jStat.variance = function variance(arr, flag) {
  return jStat.sumsqerr(arr) / (arr.length - (flag ? 1 : 0));
};

// pooled variance of an array of arrays
jStat.pooledvariance = function pooledvariance(arr) {
  var sumsqerr = arr.reduce(function (a, samples) {return a + jStat.sumsqerr(samples);}, 0);
  var count = arr.reduce(function (a, samples) {return a + samples.length;}, 0);
  return sumsqerr / (count - arr.length);
};

// deviation of an array
jStat.deviation = function (arr) {
  var mean = jStat.mean(arr);
  var arrlen = arr.length;
  var dev = new Array(arrlen);
  for (var i = 0; i < arrlen; i++) {
    dev[i] = arr[i] - mean;
  }
  return dev;
};

// standard deviation of an array
// flag = true indicates sample instead of population
jStat.stdev = function stdev(arr, flag) {
  return Math.sqrt(jStat.variance(arr, flag));
};

// pooled standard deviation of an array of arrays
jStat.pooledstdev = function pooledstdev(arr) {
  return Math.sqrt(jStat.pooledvariance(arr));
};

// mean deviation (mean absolute deviation) of an array
jStat.meandev = function meandev(arr) {
  var mean = jStat.mean(arr);
  var a = [];
  for (var i = arr.length - 1; i >= 0; i--) {
    a.push(Math.abs(arr[i] - mean));
  }
  return jStat.mean(a);
};


// median deviation (median absolute deviation) of an array
jStat.meddev = function meddev(arr) {
  var median = jStat.median(arr);
  var a = [];
  for (var i = arr.length - 1; i >= 0; i--) {
    a.push(Math.abs(arr[i] - median));
  }
  return jStat.median(a);
};


// coefficient of variation
jStat.coeffvar = function coeffvar(arr) {
  return jStat.stdev(arr) / jStat.mean(arr);
};


// quartiles of an array
jStat.quartiles = function quartiles(arr) {
  var arrlen = arr.length;
  var _arr = arr.slice().sort(ascNum);
  return [
    _arr[ Math.round((arrlen) / 4) - 1 ],
    _arr[ Math.round((arrlen) / 2) - 1 ],
    _arr[ Math.round((arrlen) * 3 / 4) - 1 ]
  ];
};


// Arbitary quantiles of an array. Direct port of the scipy.stats
// implementation by Pierre GF Gerard-Marchant.
jStat.quantiles = function quantiles(arr, quantilesArray, alphap, betap) {
  var sortedArray = arr.slice().sort(ascNum);
  var quantileVals = [quantilesArray.length];
  var n = arr.length;
  var i, p, m, aleph, k, gamma;

  if (typeof alphap === 'undefined')
    alphap = 3 / 8;
  if (typeof betap === 'undefined')
    betap = 3 / 8;

  for (var i = 0; i < quantilesArray.length; i++) {
    p = quantilesArray[i];
    m = alphap + p * (1 - alphap - betap);
    aleph = n * p + m;
    k = Math.floor(clip(aleph, 1, n - 1));
    gamma = clip(aleph - k, 0, 1);
    quantileVals[i] = (1 - gamma) * sortedArray[k - 1] + gamma * sortedArray[k];
  }

  return quantileVals;
};

// Returns the k-th percentile of values in a range, where k is in the
// range 0..1, exclusive.
jStat.percentile = function percentile(arr, k) {
  var _arr = arr.slice().sort(ascNum);
  var realIndex = k * (_arr.length - 1);
  var index = parseInt(realIndex);
  var frac = realIndex - index;

  if (index + 1 < _arr.length) {
    return _arr[index] * (1 - frac) + _arr[index + 1] * frac;
  } else {
    return _arr[index];
  }
}


// The percentile rank of score in a given array. Returns the percentage
// of all values in the input array that are less than (kind='strict') or
// less or equal than (kind='weak') score. Default is weak.
jStat.percentileOfScore = function percentileOfScore(arr, score, kind) {
  var counter = 0;
  var len = arr.length;
  var strict = false;
  var value, i;

  if (kind === 'strict')
    strict = true;

  for (var i = 0; i < len; i++) {
    value = arr[i];
    if ((strict && value < score) ||
        (!strict && value <= score)) {
      counter++;
    }
  }

  return counter / len;
};


// Histogram (bin count) data
jStat.histogram = function histogram(arr, bins) {
  var first = jStat.min(arr);
  var binCnt = bins || 4;
  var binWidth = (jStat.max(arr) - first) / binCnt;
  var len = arr.length;
  var bins = [];
  var i;

  for (var i = 0; i < binCnt; i++)
    bins[i] = 0;
  for (var i = 0; i < len; i++)
    bins[Math.min(Math.floor(((arr[i] - first) / binWidth)), binCnt - 1)] += 1;

  return bins;
};


// covariance of two arrays
jStat.covariance = function covariance(arr1, arr2) {
  var u = jStat.mean(arr1);
  var v = jStat.mean(arr2);
  var arr1Len = arr1.length;
  var sq_dev = new Array(arr1Len);
  var i;

  for (var i = 0; i < arr1Len; i++)
    sq_dev[i] = (arr1[i] - u) * (arr2[i] - v);

  return jStat.sum(sq_dev) / (arr1Len - 1);
};


// (pearson's) population correlation coefficient, rho
jStat.corrcoeff = function corrcoeff(arr1, arr2) {
  return jStat.covariance(arr1, arr2) /
      jStat.stdev(arr1, 1) /
      jStat.stdev(arr2, 1);
};

  // (spearman's) rank correlation coefficient, sp
jStat.spearmancoeff =  function (arr1, arr2) {
  arr1 = jStat.rank(arr1);
  arr2 = jStat.rank(arr2);
  //return pearson's correlation of the ranks:
  return jStat.corrcoeff(arr1, arr2);
}


// statistical standardized moments (general form of skew/kurt)
jStat.stanMoment = function stanMoment(arr, n) {
  var mu = jStat.mean(arr);
  var sigma = jStat.stdev(arr);
  var len = arr.length;
  var skewSum = 0;

  for (var i = 0; i < len; i++)
    skewSum += Math.pow((arr[i] - mu) / sigma, n);

  return skewSum / arr.length;
};

// (pearson's) moment coefficient of skewness
jStat.skewness = function skewness(arr) {
  return jStat.stanMoment(arr, 3);
};

// (pearson's) (excess) kurtosis
jStat.kurtosis = function kurtosis(arr) {
  return jStat.stanMoment(arr, 4) - 3;
};


var jProto = jStat.prototype;


// Extend jProto with method for calculating cumulative sums and products.
// This differs from the similar extension below as cumsum and cumprod should
// not be run again in the case fullbool === true.
// If a matrix is passed, automatically assume operation should be done on the
// columns.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    // If a matrix is passed, automatically assume operation should be done on
    // the columns.
    jProto[passfunc] = function(fullbool, func) {
      var arr = [];
      var i = 0;
      var tmpthis = this;
      // Assignment reassignation depending on how parameters were passed in.
      if (isFunction(fullbool)) {
        func = fullbool;
        fullbool = false;
      }
      // Check if a callback was passed with the function.
      if (func) {
        setTimeout(function() {
          func.call(tmpthis, jProto[passfunc].call(tmpthis, fullbool));
        });
        return this;
      }
      // Check if matrix and run calculations.
      if (this.length > 1) {
        tmpthis = fullbool === true ? this : this.transpose();
        for (; i < tmpthis.length; i++)
          arr[i] = jStat[passfunc](tmpthis[i]);
        return arr;
      }
      // Pass fullbool if only vector, not a matrix. for variance and stdev.
      return jStat[passfunc](this[0], fullbool);
    };
  })(funcs[i]);
})(('cumsum cumprod').split(' '));


// Extend jProto with methods which don't require arguments and work on columns.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    // If a matrix is passed, automatically assume operation should be done on
    // the columns.
    jProto[passfunc] = function(fullbool, func) {
      var arr = [];
      var i = 0;
      var tmpthis = this;
      // Assignment reassignation depending on how parameters were passed in.
      if (isFunction(fullbool)) {
        func = fullbool;
        fullbool = false;
      }
      // Check if a callback was passed with the function.
      if (func) {
        setTimeout(function() {
          func.call(tmpthis, jProto[passfunc].call(tmpthis, fullbool));
        });
        return this;
      }
      // Check if matrix and run calculations.
      if (this.length > 1) {
        if (passfunc !== 'sumrow')
          tmpthis = fullbool === true ? this : this.transpose();
        for (; i < tmpthis.length; i++)
          arr[i] = jStat[passfunc](tmpthis[i]);
        return fullbool === true
            ? jStat[passfunc](jStat.utils.toVector(arr))
            : arr;
      }
      // Pass fullbool if only vector, not a matrix. for variance and stdev.
      return jStat[passfunc](this[0], fullbool);
    };
  })(funcs[i]);
})(('sum sumsqrd sumsqerr sumrow product min max unique mean meansqerr ' +
    'geomean median diff rank mode range variance deviation stdev meandev ' +
    'meddev coeffvar quartiles histogram skewness kurtosis').split(' '));


// Extend jProto with functions that take arguments. Operations on matrices are
// done on columns.
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jProto[passfunc] = function() {
      var arr = [];
      var i = 0;
      var tmpthis = this;
      var args = Array.prototype.slice.call(arguments);

      // If the last argument is a function, we assume it's a callback; we
      // strip the callback out and call the function again.
      if (isFunction(args[args.length - 1])) {
        var callbackFunction = args[args.length - 1];
        var argsToPass = args.slice(0, args.length - 1);

        setTimeout(function() {
          callbackFunction.call(tmpthis,
                                jProto[passfunc].apply(tmpthis, argsToPass));
        });
        return this;

      // Otherwise we curry the function args and call normally.
      } else {
        var callbackFunction = undefined;
        var curriedFunction = function curriedFunction(vector) {
          return jStat[passfunc].apply(tmpthis, [vector].concat(args));
        }
      }

      // If this is a matrix, run column-by-column.
      if (this.length > 1) {
        tmpthis = tmpthis.transpose();
        for (; i < tmpthis.length; i++)
          arr[i] = curriedFunction(tmpthis[i]);
        return arr;
      }

      // Otherwise run on the vector.
      return curriedFunction(this[0]);
    };
  })(funcs[i]);
})('quantiles percentileOfScore'.split(' '));

}(jStat, Math));
// Special functions //
(function(jStat, Math) {

// Log-gamma function
jStat.gammaln = function gammaln(x) {
  var j = 0;
  var cof = [
    76.18009172947146, -86.50532032941677, 24.01409824083091,
    -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5
  ];
  var ser = 1.000000000190015;
  var xx, y, tmp;
  tmp = (y = xx = x) + 5.5;
  tmp -= (xx + 0.5) * Math.log(tmp);
  for (; j < 6; j++)
    ser += cof[j] / ++y;
  return Math.log(2.5066282746310005 * ser / xx) - tmp;
};


// gamma of x
jStat.gammafn = function gammafn(x) {
  var p = [-1.716185138865495, 24.76565080557592, -379.80425647094563,
           629.3311553128184, 866.9662027904133, -31451.272968848367,
           -36144.413418691176, 66456.14382024054
  ];
  var q = [-30.8402300119739, 315.35062697960416, -1015.1563674902192,
           -3107.771671572311, 22538.118420980151, 4755.8462775278811,
           -134659.9598649693, -115132.2596755535];
  var fact = false;
  var n = 0;
  var xden = 0;
  var xnum = 0;
  var y = x;
  var i, z, yi, res, sum, ysq;
  if (y <= 0) {
    res = y % 1 + 3.6e-16;
    if (res) {
      fact = (!(y & 1) ? 1 : -1) * Math.PI / Math.sin(Math.PI * res);
      y = 1 - y;
    } else {
      return Infinity;
    }
  }
  yi = y;
  if (y < 1) {
    z = y++;
  } else {
    z = (y -= n = (y | 0) - 1) - 1;
  }
  for (var i = 0; i < 8; ++i) {
    xnum = (xnum + p[i]) * z;
    xden = xden * z + q[i];
  }
  res = xnum / xden + 1;
  if (yi < y) {
    res /= yi;
  } else if (yi > y) {
    for (var i = 0; i < n; ++i) {
      res *= y;
      y++;
    }
  }
  if (fact) {
    res = fact / res;
  }
  return res;
};


// lower incomplete gamma function, which is usually typeset with a
// lower-case greek gamma as the function symbol
jStat.gammap = function gammap(a, x) {
  return jStat.lowRegGamma(a, x) * jStat.gammafn(a);
};


// The lower regularized incomplete gamma function, usually written P(a,x)
jStat.lowRegGamma = function lowRegGamma(a, x) {
  var aln = jStat.gammaln(a);
  var ap = a;
  var sum = 1 / a;
  var del = sum;
  var b = x + 1 - a;
  var c = 1 / 1.0e-30;
  var d = 1 / b;
  var h = d;
  var i = 1;
  // calculate maximum number of itterations required for a
  var ITMAX = -~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17);
  var an, endval;

  if (x < 0 || a <= 0) {
    return NaN;
  } else if (x < a + 1) {
    for (; i <= ITMAX; i++) {
      sum += del *= x / ++ap;
    }
    return (sum * Math.exp(-x + a * Math.log(x) - (aln)));
  }

  for (; i <= ITMAX; i++) {
    an = -i * (i - a);
    b += 2;
    d = an * d + b;
    c = b + an / c;
    d = 1 / d;
    h *= d * c;
  }

  return (1 - h * Math.exp(-x + a * Math.log(x) - (aln)));
};

// natural log factorial of n
jStat.factorialln = function factorialln(n) {
  return n < 0 ? NaN : jStat.gammaln(n + 1);
};

// factorial of n
jStat.factorial = function factorial(n) {
  return n < 0 ? NaN : jStat.gammafn(n + 1);
};

// combinations of n, m
jStat.combination = function combination(n, m) {
  // make sure n or m don't exceed the upper limit of usable values
  return (n > 170 || m > 170)
      ? Math.exp(jStat.combinationln(n, m))
      : (jStat.factorial(n) / jStat.factorial(m)) / jStat.factorial(n - m);
};


jStat.combinationln = function combinationln(n, m){
  return jStat.factorialln(n) - jStat.factorialln(m) - jStat.factorialln(n - m);
};


// permutations of n, m
jStat.permutation = function permutation(n, m) {
  return jStat.factorial(n) / jStat.factorial(n - m);
};


// beta function
jStat.betafn = function betafn(x, y) {
  // ensure arguments are positive
  if (x <= 0 || y <= 0)
    return undefined;
  // make sure x + y doesn't exceed the upper limit of usable values
  return (x + y > 170)
      ? Math.exp(jStat.betaln(x, y))
      : jStat.gammafn(x) * jStat.gammafn(y) / jStat.gammafn(x + y);
};


// natural logarithm of beta function
jStat.betaln = function betaln(x, y) {
  return jStat.gammaln(x) + jStat.gammaln(y) - jStat.gammaln(x + y);
};


// Evaluates the continued fraction for incomplete beta function by modified
// Lentz's method.
jStat.betacf = function betacf(x, a, b) {
  var fpmin = 1e-30;
  var m = 1;
  var qab = a + b;
  var qap = a + 1;
  var qam = a - 1;
  var c = 1;
  var d = 1 - qab * x / qap;
  var m2, aa, del, h;

  // These q's will be used in factors that occur in the coefficients
  if (Math.abs(d) < fpmin)
    d = fpmin;
  d = 1 / d;
  h = d;

  for (; m <= 100; m++) {
    m2 = 2 * m;
    aa = m * (b - m) * x / ((qam + m2) * (a + m2));
    // One step (the even one) of the recurrence
    d = 1 + aa * d;
    if (Math.abs(d) < fpmin)
      d = fpmin;
    c = 1 + aa / c;
    if (Math.abs(c) < fpmin)
      c = fpmin;
    d = 1 / d;
    h *= d * c;
    aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
    // Next step of the recurrence (the odd one)
    d = 1 + aa * d;
    if (Math.abs(d) < fpmin)
      d = fpmin;
    c = 1 + aa / c;
    if (Math.abs(c) < fpmin)
      c = fpmin;
    d = 1 / d;
    del = d * c;
    h *= del;
    if (Math.abs(del - 1.0) < 3e-7)
      break;
  }

  return h;
};


// Returns the inverse of the lower regularized inomplete gamma function
jStat.gammapinv = function gammapinv(p, a) {
  var j = 0;
  var a1 = a - 1;
  var EPS = 1e-8;
  var gln = jStat.gammaln(a);
  var x, err, t, u, pp, lna1, afac;

  if (p >= 1)
    return Math.max(100, a + 100 * Math.sqrt(a));
  if (p <= 0)
    return 0;
  if (a > 1) {
    lna1 = Math.log(a1);
    afac = Math.exp(a1 * (lna1 - 1) - gln);
    pp = (p < 0.5) ? p : 1 - p;
    t = Math.sqrt(-2 * Math.log(pp));
    x = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;
    if (p < 0.5)
      x = -x;
    x = Math.max(1e-3,
                 a * Math.pow(1 - 1 / (9 * a) - x / (3 * Math.sqrt(a)), 3));
  } else {
    t = 1 - a * (0.253 + a * 0.12);
    if (p < t)
      x = Math.pow(p / t, 1 / a);
    else
      x = 1 - Math.log(1 - (p - t) / (1 - t));
  }

  for(; j < 12; j++) {
    if (x <= 0)
      return 0;
    err = jStat.lowRegGamma(a, x) - p;
    if (a > 1)
      t = afac * Math.exp(-(x - a1) + a1 * (Math.log(x) - lna1));
    else
      t = Math.exp(-x + a1 * Math.log(x) - gln);
    u = err / t;
    x -= (t = u / (1 - 0.5 * Math.min(1, u * ((a - 1) / x - 1))));
    if (x <= 0)
      x = 0.5 * (x + t);
    if (Math.abs(t) < EPS * x)
      break;
  }

  return x;
};


// Returns the error function erf(x)
jStat.erf = function erf(x) {
  var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
             -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
             4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
             1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
             6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
             -2.27365122e-10, 9.6467911e-11, 2.394038e-12,
             -6.886027e-12, 8.94487e-13, 3.13092e-13,
             -1.12708e-13, 3.81e-16, 7.106e-15,
             -1.523e-15, -9.4e-17, 1.21e-16,
             -2.8e-17];
  var j = cof.length - 1;
  var isneg = false;
  var d = 0;
  var dd = 0;
  var t, ty, tmp, res;

  if (x < 0) {
    x = -x;
    isneg = true;
  }

  t = 2 / (2 + x);
  ty = 4 * t - 2;

  for(; j > 0; j--) {
    tmp = d;
    d = ty * d - dd + cof[j];
    dd = tmp;
  }

  res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
  return isneg ? res - 1 : 1 - res;
};


// Returns the complmentary error function erfc(x)
jStat.erfc = function erfc(x) {
  return 1 - jStat.erf(x);
};


// Returns the inverse of the complementary error function
jStat.erfcinv = function erfcinv(p) {
  var j = 0;
  var x, err, t, pp;
  if (p >= 2)
    return -100;
  if (p <= 0)
    return 100;
  pp = (p < 1) ? p : 2 - p;
  t = Math.sqrt(-2 * Math.log(pp / 2));
  x = -0.70711 * ((2.30753 + t * 0.27061) /
                  (1 + t * (0.99229 + t * 0.04481)) - t);
  for (; j < 2; j++) {
    err = jStat.erfc(x) - pp;
    x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
  }
  return (p < 1) ? x : -x;
};


// Returns the inverse of the incomplete beta function
jStat.ibetainv = function ibetainv(p, a, b) {
  var EPS = 1e-8;
  var a1 = a - 1;
  var b1 = b - 1;
  var j = 0;
  var lna, lnb, pp, t, u, err, x, al, h, w, afac;
  if (p <= 0)
    return 0;
  if (p >= 1)
    return 1;
  if (a >= 1 && b >= 1) {
    pp = (p < 0.5) ? p : 1 - p;
    t = Math.sqrt(-2 * Math.log(pp));
    x = (2.30753 + t * 0.27061) / (1 + t* (0.99229 + t * 0.04481)) - t;
    if (p < 0.5)
      x = -x;
    al = (x * x - 3) / 6;
    h = 2 / (1 / (2 * a - 1)  + 1 / (2 * b - 1));
    w = (x * Math.sqrt(al + h) / h) - (1 / (2 * b - 1) - 1 / (2 * a - 1)) *
        (al + 5 / 6 - 2 / (3 * h));
    x = a / (a + b * Math.exp(2 * w));
  } else {
    lna = Math.log(a / (a + b));
    lnb = Math.log(b / (a + b));
    t = Math.exp(a * lna) / a;
    u = Math.exp(b * lnb) / b;
    w = t + u;
    if (p < t / w)
      x = Math.pow(a * w * p, 1 / a);
    else
      x = 1 - Math.pow(b * w * (1 - p), 1 / b);
  }
  afac = -jStat.gammaln(a) - jStat.gammaln(b) + jStat.gammaln(a + b);
  for(; j < 10; j++) {
    if (x === 0 || x === 1)
      return x;
    err = jStat.ibeta(x, a, b) - p;
    t = Math.exp(a1 * Math.log(x) + b1 * Math.log(1 - x) + afac);
    u = err / t;
    x -= (t = u / (1 - 0.5 * Math.min(1, u * (a1 / x - b1 / (1 - x)))));
    if (x <= 0)
      x = 0.5 * (x + t);
    if (x >= 1)
      x = 0.5 * (x + t + 1);
    if (Math.abs(t) < EPS * x && j > 0)
      break;
  }
  return x;
};


// Returns the incomplete beta function I_x(a,b)
jStat.ibeta = function ibeta(x, a, b) {
  // Factors in front of the continued fraction.
  var bt = (x === 0 || x === 1) ?  0 :
    Math.exp(jStat.gammaln(a + b) - jStat.gammaln(a) -
             jStat.gammaln(b) + a * Math.log(x) + b *
             Math.log(1 - x));
  if (x < 0 || x > 1)
    return false;
  if (x < (a + 1) / (a + b + 2))
    // Use continued fraction directly.
    return bt * jStat.betacf(x, a, b) / a;
  // else use continued fraction after making the symmetry transformation.
  return 1 - bt * jStat.betacf(1 - x, b, a) / b;
};


// Returns a normal deviate (mu=0, sigma=1).
// If n and m are specified it returns a object of normal deviates.
jStat.randn = function randn(n, m) {
  var u, v, x, y, q, mat;
  if (!m)
    m = n;
  if (n)
    return jStat.create(n, m, function() { return jStat.randn(); });
  do {
    u = Math.random();
    v = 1.7156 * (Math.random() - 0.5);
    x = u - 0.449871;
    y = Math.abs(v) + 0.386595;
    q = x * x + y * (0.19600 * y - 0.25472 * x);
  } while (q > 0.27597 && (q > 0.27846 || v * v > -4 * Math.log(u) * u * u));
  return v / u;
};


// Returns a gamma deviate by the method of Marsaglia and Tsang.
jStat.randg = function randg(shape, n, m) {
  var oalph = shape;
  var a1, a2, u, v, x, mat;
  if (!m)
    m = n;
  if (!shape)
    shape = 1;
  if (n) {
    mat = jStat.zeros(n,m);
    mat.alter(function() { return jStat.randg(shape); });
    return mat;
  }
  if (shape < 1)
    shape += 1;
  a1 = shape - 1 / 3;
  a2 = 1 / Math.sqrt(9 * a1);
  do {
    do {
      x = jStat.randn();
      v = 1 + a2 * x;
    } while(v <= 0);
    v = v * v * v;
    u = Math.random();
  } while(u > 1 - 0.331 * Math.pow(x, 4) &&
          Math.log(u) > 0.5 * x*x + a1 * (1 - v + Math.log(v)));
  // alpha > 1
  if (shape == oalph)
    return a1 * v;
  // alpha < 1
  do {
    u = Math.random();
  } while(u === 0);
  return Math.pow(u, 1 / oalph) * a1 * v;
};


// making use of static methods on the instance
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jStat.fn[passfunc] = function() {
      return jStat(
          jStat.map(this, function(value) { return jStat[passfunc](value); }));
    }
  })(funcs[i]);
})('gammaln gammafn factorial factorialln'.split(' '));


(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jStat.fn[passfunc] = function() {
      return jStat(jStat[passfunc].apply(null, arguments));
    };
  })(funcs[i]);
})('randn'.split(' '));

}(jStat, Math));
(function(jStat, Math) {

// generate all distribution instance methods
(function(list) {
  for (var i = 0; i < list.length; i++) (function(func) {
    // distribution instance method
    jStat[func] = function(a, b, c) {
      if (!(this instanceof arguments.callee))
        return new arguments.callee(a, b, c);
      this._a = a;
      this._b = b;
      this._c = c;
      return this;
    };
    // distribution method to be used on a jStat instance
    jStat.fn[func] = function(a, b, c) {
      var newthis = jStat[func](a, b, c);
      newthis.data = this;
      return newthis;
    };
    // sample instance method
    jStat[func].prototype.sample = function(arr) {
      var a = this._a;
      var b = this._b;
      var c = this._c;
      if (arr)
        return jStat.alter(arr, function() {
          return jStat[func].sample(a, b, c);
        });
      else
        return jStat[func].sample(a, b, c);
    };
    // generate the pdf, cdf and inv instance methods
    (function(vals) {
      for (var i = 0; i < vals.length; i++) (function(fnfunc) {
        jStat[func].prototype[fnfunc] = function(x) {
          var a = this._a;
          var b = this._b;
          var c = this._c;
          if (!x && x !== 0)
            x = this.data;
          if (typeof x !== 'number') {
            return jStat.fn.map.call(x, function(x) {
              return jStat[func][fnfunc](x, a, b, c);
            });
          }
          return jStat[func][fnfunc](x, a, b, c);
        };
      })(vals[i]);
    })('pdf cdf inv'.split(' '));
    // generate the mean, median, mode and variance instance methods
    (function(vals) {
      for (var i = 0; i < vals.length; i++) (function(fnfunc) {
        jStat[func].prototype[fnfunc] = function() {
          return jStat[func][fnfunc](this._a, this._b, this._c);
        };
      })(vals[i]);
    })('mean median mode variance'.split(' '));
  })(list[i]);
})((
  'beta centralF cauchy chisquare exponential gamma invgamma kumaraswamy ' +
  'laplace lognormal noncentralt normal pareto studentt weibull uniform ' +
  'binomial negbin hypgeom poisson triangular tukey arcsine'
).split(' '));



// extend beta function with static methods
jStat.extend(jStat.beta, {
  pdf: function pdf(x, alpha, beta) {
    // PDF is zero outside the support
    if (x > 1 || x < 0)
      return 0;
    // PDF is one for the uniform case
    if (alpha == 1 && beta == 1)
      return 1;

    if (alpha < 512 && beta < 512) {
      return (Math.pow(x, alpha - 1) * Math.pow(1 - x, beta - 1)) /
          jStat.betafn(alpha, beta);
    } else {
      return Math.exp((alpha - 1) * Math.log(x) +
                      (beta - 1) * Math.log(1 - x) -
                      jStat.betaln(alpha, beta));
    }
  },

  cdf: function cdf(x, alpha, beta) {
    return (x > 1 || x < 0) ? (x > 1) * 1 : jStat.ibeta(x, alpha, beta);
  },

  inv: function inv(x, alpha, beta) {
    return jStat.ibetainv(x, alpha, beta);
  },

  mean: function mean(alpha, beta) {
    return alpha / (alpha + beta);
  },

  median: function median(alpha, beta) {
    return jStat.ibetainv(0.5, alpha, beta);
  },

  mode: function mode(alpha, beta) {
    return (alpha - 1 ) / ( alpha + beta - 2);
  },

  // return a random sample
  sample: function sample(alpha, beta) {
    var u = jStat.randg(alpha);
    return u / (u + jStat.randg(beta));
  },

  variance: function variance(alpha, beta) {
    return (alpha * beta) / (Math.pow(alpha + beta, 2) * (alpha + beta + 1));
  }
});

// extend F function with static methods
jStat.extend(jStat.centralF, {
  // This implementation of the pdf function avoids float overflow
  // See the way that R calculates this value:
  // https://svn.r-project.org/R/trunk/src/nmath/df.c
  pdf: function pdf(x, df1, df2) {
    var p, q, f;

    if (x < 0)
      return 0;

    if (df1 <= 2) {
      if (x === 0 && df1 < 2) {
        return Infinity;
      }
      if (x === 0 && df1 === 2) {
        return 1;
      }
      return (1 / jStat.betafn(df1 / 2, df2 / 2)) *
              Math.pow(df1 / df2, df1 / 2) *
              Math.pow(x, (df1/2) - 1) *
              Math.pow((1 + (df1 / df2) * x), -(df1 + df2) / 2);
    }

    p = (df1 * x) / (df2 + x * df1);
    q = df2 / (df2 + x * df1);
    f = df1 * q / 2.0;
    return f * jStat.binomial.pdf((df1 - 2) / 2, (df1 + df2 - 2) / 2, p);
  },

  cdf: function cdf(x, df1, df2) {
    if (x < 0)
      return 0;
    return jStat.ibeta((df1 * x) / (df1 * x + df2), df1 / 2, df2 / 2);
  },

  inv: function inv(x, df1, df2) {
    return df2 / (df1 * (1 / jStat.ibetainv(x, df1 / 2, df2 / 2) - 1));
  },

  mean: function mean(df1, df2) {
    return (df2 > 2) ? df2 / (df2 - 2) : undefined;
  },

  mode: function mode(df1, df2) {
    return (df1 > 2) ? (df2 * (df1 - 2)) / (df1 * (df2 + 2)) : undefined;
  },

  // return a random sample
  sample: function sample(df1, df2) {
    var x1 = jStat.randg(df1 / 2) * 2;
    var x2 = jStat.randg(df2 / 2) * 2;
    return (x1 / df1) / (x2 / df2);
  },

  variance: function variance(df1, df2) {
    if (df2 <= 4)
      return undefined;
    return 2 * df2 * df2 * (df1 + df2 - 2) /
        (df1 * (df2 - 2) * (df2 - 2) * (df2 - 4));
  }
});


// extend cauchy function with static methods
jStat.extend(jStat.cauchy, {
  pdf: function pdf(x, local, scale) {
    if (scale < 0) { return 0; }

    return (scale / (Math.pow(x - local, 2) + Math.pow(scale, 2))) / Math.PI;
  },

  cdf: function cdf(x, local, scale) {
    return Math.atan((x - local) / scale) / Math.PI + 0.5;
  },

  inv: function(p, local, scale) {
    return local + scale * Math.tan(Math.PI * (p - 0.5));
  },

  median: function median(local, scale) {
    return local;
  },

  mode: function mode(local, scale) {
    return local;
  },

  sample: function sample(local, scale) {
    return jStat.randn() *
        Math.sqrt(1 / (2 * jStat.randg(0.5))) * scale + local;
  }
});



// extend chisquare function with static methods
jStat.extend(jStat.chisquare, {
  pdf: function pdf(x, dof) {
    if (x < 0)
      return 0;
    return (x === 0 && dof === 2) ? 0.5 :
        Math.exp((dof / 2 - 1) * Math.log(x) - x / 2 - (dof / 2) *
                 Math.log(2) - jStat.gammaln(dof / 2));
  },

  cdf: function cdf(x, dof) {
    if (x < 0)
      return 0;
    return jStat.lowRegGamma(dof / 2, x / 2);
  },

  inv: function(p, dof) {
    return 2 * jStat.gammapinv(p, 0.5 * dof);
  },

  mean : function(dof) {
    return dof;
  },

  // TODO: this is an approximation (is there a better way?)
  median: function median(dof) {
    return dof * Math.pow(1 - (2 / (9 * dof)), 3);
  },

  mode: function mode(dof) {
    return (dof - 2 > 0) ? dof - 2 : 0;
  },

  sample: function sample(dof) {
    return jStat.randg(dof / 2) * 2;
  },

  variance: function variance(dof) {
    return 2 * dof;
  }
});



// extend exponential function with static methods
jStat.extend(jStat.exponential, {
  pdf: function pdf(x, rate) {
    return x < 0 ? 0 : rate * Math.exp(-rate * x);
  },

  cdf: function cdf(x, rate) {
    return x < 0 ? 0 : 1 - Math.exp(-rate * x);
  },

  inv: function(p, rate) {
    return -Math.log(1 - p) / rate;
  },

  mean : function(rate) {
    return 1 / rate;
  },

  median: function (rate) {
    return (1 / rate) * Math.log(2);
  },

  mode: function mode(rate) {
    return 0;
  },

  sample: function sample(rate) {
    return -1 / rate * Math.log(Math.random());
  },

  variance : function(rate) {
    return Math.pow(rate, -2);
  }
});



// extend gamma function with static methods
jStat.extend(jStat.gamma, {
  pdf: function pdf(x, shape, scale) {
    if (x < 0)
      return 0;
    return (x === 0 && shape === 1) ? 1 / scale :
            Math.exp((shape - 1) * Math.log(x) - x / scale -
                    jStat.gammaln(shape) - shape * Math.log(scale));
  },

  cdf: function cdf(x, shape, scale) {
    if (x < 0)
      return 0;
    return jStat.lowRegGamma(shape, x / scale);
  },

  inv: function(p, shape, scale) {
    return jStat.gammapinv(p, shape) * scale;
  },

  mean : function(shape, scale) {
    return shape * scale;
  },

  mode: function mode(shape, scale) {
    if(shape > 1) return (shape - 1) * scale;
    return undefined;
  },

  sample: function sample(shape, scale) {
    return jStat.randg(shape) * scale;
  },

  variance: function variance(shape, scale) {
    return shape * scale * scale;
  }
});

// extend inverse gamma function with static methods
jStat.extend(jStat.invgamma, {
  pdf: function pdf(x, shape, scale) {
    if (x <= 0)
      return 0;
    return Math.exp(-(shape + 1) * Math.log(x) - scale / x -
                    jStat.gammaln(shape) + shape * Math.log(scale));
  },

  cdf: function cdf(x, shape, scale) {
    if (x <= 0)
      return 0;
    return 1 - jStat.lowRegGamma(shape, scale / x);
  },

  inv: function(p, shape, scale) {
    return scale / jStat.gammapinv(1 - p, shape);
  },

  mean : function(shape, scale) {
    return (shape > 1) ? scale / (shape - 1) : undefined;
  },

  mode: function mode(shape, scale) {
    return scale / (shape + 1);
  },

  sample: function sample(shape, scale) {
    return scale / jStat.randg(shape);
  },

  variance: function variance(shape, scale) {
    if (shape <= 2)
      return undefined;
    return scale * scale / ((shape - 1) * (shape - 1) * (shape - 2));
  }
});


// extend kumaraswamy function with static methods
jStat.extend(jStat.kumaraswamy, {
  pdf: function pdf(x, alpha, beta) {
    if (x === 0 && alpha === 1)
      return beta;
    else if (x === 1 && beta === 1)
      return alpha;
    return Math.exp(Math.log(alpha) + Math.log(beta) + (alpha - 1) *
                    Math.log(x) + (beta - 1) *
                    Math.log(1 - Math.pow(x, alpha)));
  },

  cdf: function cdf(x, alpha, beta) {
    if (x < 0)
      return 0;
    else if (x > 1)
      return 1;
    return (1 - Math.pow(1 - Math.pow(x, alpha), beta));
  },

  inv: function inv(p, alpha, beta) {
    return Math.pow(1 - Math.pow(1 - p, 1 / beta), 1 / alpha);
  },

  mean : function(alpha, beta) {
    return (beta * jStat.gammafn(1 + 1 / alpha) *
            jStat.gammafn(beta)) / (jStat.gammafn(1 + 1 / alpha + beta));
  },

  median: function median(alpha, beta) {
    return Math.pow(1 - Math.pow(2, -1 / beta), 1 / alpha);
  },

  mode: function mode(alpha, beta) {
    if (!(alpha >= 1 && beta >= 1 && (alpha !== 1 && beta !== 1)))
      return undefined;
    return Math.pow((alpha - 1) / (alpha * beta - 1), 1 / alpha);
  },

  variance: function variance(alpha, beta) {
    throw new Error('variance not yet implemented');
    // TODO: complete this
  }
});



// extend lognormal function with static methods
jStat.extend(jStat.lognormal, {
  pdf: function pdf(x, mu, sigma) {
    if (x <= 0)
      return 0;
    return Math.exp(-Math.log(x) - 0.5 * Math.log(2 * Math.PI) -
                    Math.log(sigma) - Math.pow(Math.log(x) - mu, 2) /
                    (2 * sigma * sigma));
  },

  cdf: function cdf(x, mu, sigma) {
    if (x < 0)
      return 0;
    return 0.5 +
        (0.5 * jStat.erf((Math.log(x) - mu) / Math.sqrt(2 * sigma * sigma)));
  },

  inv: function(p, mu, sigma) {
    return Math.exp(-1.41421356237309505 * sigma * jStat.erfcinv(2 * p) + mu);
  },

  mean: function mean(mu, sigma) {
    return Math.exp(mu + sigma * sigma / 2);
  },

  median: function median(mu, sigma) {
    return Math.exp(mu);
  },

  mode: function mode(mu, sigma) {
    return Math.exp(mu - sigma * sigma);
  },

  sample: function sample(mu, sigma) {
    return Math.exp(jStat.randn() * sigma + mu);
  },

  variance: function variance(mu, sigma) {
    return (Math.exp(sigma * sigma) - 1) * Math.exp(2 * mu + sigma * sigma);
  }
});



// extend noncentralt function with static methods
jStat.extend(jStat.noncentralt, {
  pdf: function pdf(x, dof, ncp) {
    var tol = 1e-14;
    if (Math.abs(ncp) < tol)  // ncp approx 0; use student-t
      return jStat.studentt.pdf(x, dof)

    if (Math.abs(x) < tol) {  // different formula for x == 0
      return Math.exp(jStat.gammaln((dof + 1) / 2) - ncp * ncp / 2 -
                      0.5 * Math.log(Math.PI * dof) - jStat.gammaln(dof / 2));
    }

    // formula for x != 0
    return dof / x *
        (jStat.noncentralt.cdf(x * Math.sqrt(1 + 2 / dof), dof+2, ncp) -
         jStat.noncentralt.cdf(x, dof, ncp));
  },

  cdf: function cdf(x, dof, ncp) {
    var tol = 1e-14;
    var min_iterations = 200;

    if (Math.abs(ncp) < tol)  // ncp approx 0; use student-t
      return jStat.studentt.cdf(x, dof);

    // turn negative x into positive and flip result afterwards
    var flip = false;
    if (x < 0) {
      flip = true;
      ncp = -ncp;
    }

    var prob = jStat.normal.cdf(-ncp, 0, 1);
    var value = tol + 1;
    // use value at last two steps to determine convergence
    var lastvalue = value;
    var y = x * x / (x * x + dof);
    var j = 0;
    var p = Math.exp(-ncp * ncp / 2);
    var q = Math.exp(-ncp * ncp / 2 - 0.5 * Math.log(2) -
                     jStat.gammaln(3 / 2)) * ncp;
    while (j < min_iterations || lastvalue > tol || value > tol) {
      lastvalue = value;
      if (j > 0) {
        p *= (ncp * ncp) / (2 * j);
        q *= (ncp * ncp) / (2 * (j + 1 / 2));
      }
      value = p * jStat.beta.cdf(y, j + 0.5, dof / 2) +
          q * jStat.beta.cdf(y, j+1, dof/2);
      prob += 0.5 * value;
      j++;
    }

    return flip ? (1 - prob) : prob;
  }
});


// extend normal function with static methods
jStat.extend(jStat.normal, {
  pdf: function pdf(x, mean, std) {
    return Math.exp(-0.5 * Math.log(2 * Math.PI) -
                    Math.log(std) - Math.pow(x - mean, 2) / (2 * std * std));
  },

  cdf: function cdf(x, mean, std) {
    return 0.5 * (1 + jStat.erf((x - mean) / Math.sqrt(2 * std * std)));
  },

  inv: function(p, mean, std) {
    return -1.41421356237309505 * std * jStat.erfcinv(2 * p) + mean;
  },

  mean : function(mean, std) {
    return mean;
  },

  median: function median(mean, std) {
    return mean;
  },

  mode: function (mean, std) {
    return mean;
  },

  sample: function sample(mean, std) {
    return jStat.randn() * std + mean;
  },

  variance : function(mean, std) {
    return std * std;
  }
});



// extend pareto function with static methods
jStat.extend(jStat.pareto, {
  pdf: function pdf(x, scale, shape) {
    if (x < scale)
      return 0;
    return (shape * Math.pow(scale, shape)) / Math.pow(x, shape + 1);
  },

  cdf: function cdf(x, scale, shape) {
    if (x < scale)
      return 0;
    return 1 - Math.pow(scale / x, shape);
  },

  inv: function inv(p, scale, shape) {
    return scale / Math.pow(1 - p, 1 / shape);
  },

  mean: function mean(scale, shape) {
    if (shape <= 1)
      return undefined;
    return (shape * Math.pow(scale, shape)) / (shape - 1);
  },

  median: function median(scale, shape) {
    return scale * (shape * Math.SQRT2);
  },

  mode: function mode(scale, shape) {
    return scale;
  },

  variance : function(scale, shape) {
    if (shape <= 2)
      return undefined;
    return (scale*scale * shape) / (Math.pow(shape - 1, 2) * (shape - 2));
  }
});



// extend studentt function with static methods
jStat.extend(jStat.studentt, {
  pdf: function pdf(x, dof) {
    dof = dof > 1e100 ? 1e100 : dof;
    return (1/(Math.sqrt(dof) * jStat.betafn(0.5, dof/2))) *
        Math.pow(1 + ((x * x) / dof), -((dof + 1) / 2));
  },

  cdf: function cdf(x, dof) {
    var dof2 = dof / 2;
    return jStat.ibeta((x + Math.sqrt(x * x + dof)) /
                       (2 * Math.sqrt(x * x + dof)), dof2, dof2);
  },

  inv: function(p, dof) {
    var x = jStat.ibetainv(2 * Math.min(p, 1 - p), 0.5 * dof, 0.5);
    x = Math.sqrt(dof * (1 - x) / x);
    return (p > 0.5) ? x : -x;
  },

  mean: function mean(dof) {
    return (dof > 1) ? 0 : undefined;
  },

  median: function median(dof) {
    return 0;
  },

  mode: function mode(dof) {
    return 0;
  },

  sample: function sample(dof) {
    return jStat.randn() * Math.sqrt(dof / (2 * jStat.randg(dof / 2)));
  },

  variance: function variance(dof) {
    return (dof  > 2) ? dof / (dof - 2) : (dof > 1) ? Infinity : undefined;
  }
});



// extend weibull function with static methods
jStat.extend(jStat.weibull, {
  pdf: function pdf(x, scale, shape) {
    if (x < 0 || scale < 0 || shape < 0)
      return 0;
    return (shape / scale) * Math.pow((x / scale), (shape - 1)) *
        Math.exp(-(Math.pow((x / scale), shape)));
  },

  cdf: function cdf(x, scale, shape) {
    return x < 0 ? 0 : 1 - Math.exp(-Math.pow((x / scale), shape));
  },

  inv: function(p, scale, shape) {
    return scale * Math.pow(-Math.log(1 - p), 1 / shape);
  },

  mean : function(scale, shape) {
    return scale * jStat.gammafn(1 + 1 / shape);
  },

  median: function median(scale, shape) {
    return scale * Math.pow(Math.log(2), 1 / shape);
  },

  mode: function mode(scale, shape) {
    if (shape <= 1)
      return 0;
    return scale * Math.pow((shape - 1) / shape, 1 / shape);
  },

  sample: function sample(scale, shape) {
    return scale * Math.pow(-Math.log(Math.random()), 1 / shape);
  },

  variance: function variance(scale, shape) {
    return scale * scale * jStat.gammafn(1 + 2 / shape) -
        Math.pow(jStat.weibull.mean(scale, shape), 2);
  }
});



// extend uniform function with static methods
jStat.extend(jStat.uniform, {
  pdf: function pdf(x, a, b) {
    return (x < a || x > b) ? 0 : 1 / (b - a);
  },

  cdf: function cdf(x, a, b) {
    if (x < a)
      return 0;
    else if (x < b)
      return (x - a) / (b - a);
    return 1;
  },

  inv: function(p, a, b) {
    return a + (p * (b - a));
  },

  mean: function mean(a, b) {
    return 0.5 * (a + b);
  },

  median: function median(a, b) {
    return jStat.mean(a, b);
  },

  mode: function mode(a, b) {
    throw new Error('mode is not yet implemented');
  },

  sample: function sample(a, b) {
    return (a / 2 + b / 2) + (b / 2 - a / 2) * (2 * Math.random() - 1);
  },

  variance: function variance(a, b) {
    return Math.pow(b - a, 2) / 12;
  }
});



// extend uniform function with static methods
jStat.extend(jStat.binomial, {
  pdf: function pdf(k, n, p) {
    return (p === 0 || p === 1) ?
      ((n * p) === k ? 1 : 0) :
      jStat.combination(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
  },

  cdf: function cdf(x, n, p) {
    var binomarr = [],
    k = 0;
    if (x < 0) {
      return 0;
    }
    if (x < n) {
      for (; k <= x; k++) {
        binomarr[ k ] = jStat.binomial.pdf(k, n, p);
      }
      return jStat.sum(binomarr);
    }
    return 1;
  }
});



// extend uniform function with static methods
jStat.extend(jStat.negbin, {
  pdf: function pdf(k, r, p) {
    if (k !== k >>> 0)
      return false;
    if (k < 0)
      return 0;
    return jStat.combination(k + r - 1, r - 1) *
        Math.pow(1 - p, k) * Math.pow(p, r);
  },

  cdf: function cdf(x, r, p) {
    var sum = 0,
    k = 0;
    if (x < 0) return 0;
    for (; k <= x; k++) {
      sum += jStat.negbin.pdf(k, r, p);
    }
    return sum;
  }
});



// extend uniform function with static methods
jStat.extend(jStat.hypgeom, {
  pdf: function pdf(k, N, m, n) {
    // Hypergeometric PDF.

    // A simplification of the CDF algorithm below.

    // k = number of successes drawn
    // N = population size
    // m = number of successes in population
    // n = number of items drawn from population

    if(k !== k | 0) {
      return false;
    } else if(k < 0 || k < m - (N - n)) {
      // It's impossible to have this few successes drawn.
      return 0;
    } else if(k > n || k > m) {
      // It's impossible to have this many successes drawn.
      return 0;
    } else if (m * 2 > N) {
      // More than half the population is successes.

      if(n * 2 > N) {
        // More than half the population is sampled.

        return jStat.hypgeom.pdf(N - m - n + k, N, N - m, N - n)
      } else {
        // Half or less of the population is sampled.

        return jStat.hypgeom.pdf(n - k, N, N - m, n);
      }

    } else if(n * 2 > N) {
      // Half or less is successes.

      return jStat.hypgeom.pdf(m - k, N, m, N - n);

    } else if(m < n) {
      // We want to have the number of things sampled to be less than the
      // successes available. So swap the definitions of successful and sampled.
      return jStat.hypgeom.pdf(k, N, n, m);
    } else {
      // If we get here, half or less of the population was sampled, half or
      // less of it was successes, and we had fewer sampled things than
      // successes. Now we can do this complicated iterative algorithm in an
      // efficient way.

      // The basic premise of the algorithm is that we partially normalize our
      // intermediate product to keep it in a numerically good region, and then
      // finish the normalization at the end.

      // This variable holds the scaled probability of the current number of
      // successes.
      var scaledPDF = 1;

      // This keeps track of how much we have normalized.
      var samplesDone = 0;

      for(var i = 0; i < k; i++) {
        // For every possible number of successes up to that observed...

        while(scaledPDF > 1 && samplesDone < n) {
          // Intermediate result is growing too big. Apply some of the
          // normalization to shrink everything.

          scaledPDF *= 1 - (m / (N - samplesDone));

          // Say we've normalized by this sample already.
          samplesDone++;
        }

        // Work out the partially-normalized hypergeometric PDF for the next
        // number of successes
        scaledPDF *= (n - i) * (m - i) / ((i + 1) * (N - m - n + i + 1));
      }

      for(; samplesDone < n; samplesDone++) {
        // Apply all the rest of the normalization
        scaledPDF *= 1 - (m / (N - samplesDone));
      }

      // Bound answer sanely before returning.
      return Math.min(1, Math.max(0, scaledPDF));
    }
  },

  cdf: function cdf(x, N, m, n) {
    // Hypergeometric CDF.

    // This algorithm is due to Prof. Thomas S. Ferguson, <tom@math.ucla.edu>,
    // and comes from his hypergeometric test calculator at
    // <http://www.math.ucla.edu/~tom/distributions/Hypergeometric.html>.

    // x = number of successes drawn
    // N = population size
    // m = number of successes in population
    // n = number of items drawn from population

    if(x < 0 || x < m - (N - n)) {
      // It's impossible to have this few successes drawn or fewer.
      return 0;
    } else if(x >= n || x >= m) {
      // We will always have this many successes or fewer.
      return 1;
    } else if (m * 2 > N) {
      // More than half the population is successes.

      if(n * 2 > N) {
        // More than half the population is sampled.

        return jStat.hypgeom.cdf(N - m - n + x, N, N - m, N - n)
      } else {
        // Half or less of the population is sampled.

        return 1 - jStat.hypgeom.cdf(n - x - 1, N, N - m, n);
      }

    } else if(n * 2 > N) {
      // Half or less is successes.

      return 1 - jStat.hypgeom.cdf(m - x - 1, N, m, N - n);

    } else if(m < n) {
      // We want to have the number of things sampled to be less than the
      // successes available. So swap the definitions of successful and sampled.
      return jStat.hypgeom.cdf(x, N, n, m);
    } else {
      // If we get here, half or less of the population was sampled, half or
      // less of it was successes, and we had fewer sampled things than
      // successes. Now we can do this complicated iterative algorithm in an
      // efficient way.

      // The basic premise of the algorithm is that we partially normalize our
      // intermediate sum to keep it in a numerically good region, and then
      // finish the normalization at the end.

      // Holds the intermediate, scaled total CDF.
      var scaledCDF = 1;

      // This variable holds the scaled probability of the current number of
      // successes.
      var scaledPDF = 1;

      // This keeps track of how much we have normalized.
      var samplesDone = 0;

      for(var i = 0; i < x; i++) {
        // For every possible number of successes up to that observed...

        while(scaledCDF > 1 && samplesDone < n) {
          // Intermediate result is growing too big. Apply some of the
          // normalization to shrink everything.

          var factor = 1 - (m / (N - samplesDone));

          scaledPDF *= factor;
          scaledCDF *= factor;

          // Say we've normalized by this sample already.
          samplesDone++;
        }

        // Work out the partially-normalized hypergeometric PDF for the next
        // number of successes
        scaledPDF *= (n - i) * (m - i) / ((i + 1) * (N - m - n + i + 1));

        // Add to the CDF answer.
        scaledCDF += scaledPDF;
      }

      for(; samplesDone < n; samplesDone++) {
        // Apply all the rest of the normalization
        scaledCDF *= 1 - (m / (N - samplesDone));
      }

      // Bound answer sanely before returning.
      return Math.min(1, Math.max(0, scaledCDF));
    }
  }
});



// extend uniform function with static methods
jStat.extend(jStat.poisson, {
  pdf: function pdf(k, l) {
    if (l < 0 || (k % 1) !== 0 || k < 0) {
      return 0;
    }

    return Math.pow(l, k) * Math.exp(-l) / jStat.factorial(k);
  },

  cdf: function cdf(x, l) {
    var sumarr = [],
    k = 0;
    if (x < 0) return 0;
    for (; k <= x; k++) {
      sumarr.push(jStat.poisson.pdf(k, l));
    }
    return jStat.sum(sumarr);
  },

  mean : function(l) {
    return l;
  },

  variance : function(l) {
    return l;
  },

  sample: function sample(l) {
    var p = 1, k = 0, L = Math.exp(-l);
    do {
      k++;
      p *= Math.random();
    } while (p > L);
    return k - 1;
  }
});

// extend triangular function with static methods
jStat.extend(jStat.triangular, {
  pdf: function pdf(x, a, b, c) {
    if (b <= a || c < a || c > b) {
      return NaN;
    } else {
      if (x < a || x > b) {
        return 0;
      } else if (x < c) {
          return (2 * (x - a)) / ((b - a) * (c - a));
      } else if (x === c) {
          return (2 / (b - a));
      } else { // x > c
          return (2 * (b - x)) / ((b - a) * (b - c));
      }
    }
  },

  cdf: function cdf(x, a, b, c) {
    if (b <= a || c < a || c > b)
      return NaN;
    if (x <= a)
      return 0;
    else if (x >= b)
      return 1;
    if (x <= c)
      return Math.pow(x - a, 2) / ((b - a) * (c - a));
    else // x > c
      return 1 - Math.pow(b - x, 2) / ((b - a) * (b - c));
  },

  inv: function inv(p, a, b, c) {
    if (b <= a || c < a || c > b) {
      return NaN;
    } else {
      if (p <= ((c - a) / (b - a))) {
        return a + (b - a) * Math.sqrt(p * ((c - a) / (b - a)));
      } else { // p > ((c - a) / (b - a))
        return a + (b - a) * (1 - Math.sqrt((1 - p) * (1 - ((c - a) / (b - a)))));
      }
    }
  },

  mean: function mean(a, b, c) {
    return (a + b + c) / 3;
  },

  median: function median(a, b, c) {
    if (c <= (a + b) / 2) {
      return b - Math.sqrt((b - a) * (b - c)) / Math.sqrt(2);
    } else if (c > (a + b) / 2) {
      return a + Math.sqrt((b - a) * (c - a)) / Math.sqrt(2);
    }
  },

  mode: function mode(a, b, c) {
    return c;
  },

  sample: function sample(a, b, c) {
    var u = Math.random();
    if (u < ((c - a) / (b - a)))
      return a + Math.sqrt(u * (b - a) * (c - a))
    return b - Math.sqrt((1 - u) * (b - a) * (b - c));
  },

  variance: function variance(a, b, c) {
    return (a * a + b * b + c * c - a * b - a * c - b * c) / 18;
  }
});


// extend arcsine function with static methods
jStat.extend(jStat.arcsine, {
  pdf: function pdf(x, a, b) {
    if (b <= a) return NaN;

    return (x <= a || x >= b) ? 0 :
      (2 / Math.PI) *
        Math.pow(Math.pow(b - a, 2) -
                  Math.pow(2 * x - a - b, 2), -0.5);
  },

  cdf: function cdf(x, a, b) {
    if (x < a)
      return 0;
    else if (x < b)
      return (2 / Math.PI) * Math.asin(Math.sqrt((x - a)/(b - a)));
    return 1;
  },

  inv: function(p, a, b) {
    return a + (0.5 - 0.5 * Math.cos(Math.PI * p)) * (b - a);
  },

  mean: function mean(a, b) {
    if (b <= a) return NaN;
    return (a + b) / 2;
  },

  median: function median(a, b) {
    if (b <= a) return NaN;
    return (a + b) / 2;
  },

  mode: function mode(a, b) {
    throw new Error('mode is not yet implemented');
  },

  sample: function sample(a, b) {
    return ((a + b) / 2) + ((b - a) / 2) *
      Math.sin(2 * Math.PI * jStat.uniform.sample(0, 1));
  },

  variance: function variance(a, b) {
    if (b <= a) return NaN;
    return Math.pow(b - a, 2) / 8;
  }
});


function laplaceSign(x) { return x / Math.abs(x); }

jStat.extend(jStat.laplace, {
  pdf: function pdf(x, mu, b) {
    return (b <= 0) ? 0 : (Math.exp(-Math.abs(x - mu) / b)) / (2 * b);
  },

  cdf: function cdf(x, mu, b) {
    if (b <= 0) { return 0; }

    if(x < mu) {
      return 0.5 * Math.exp((x - mu) / b);
    } else {
      return 1 - 0.5 * Math.exp(- (x - mu) / b);
    }
  },

  mean: function(mu, b) {
    return mu;
  },

  median: function(mu, b) {
    return mu;
  },

  mode: function(mu, b) {
    return mu;
  },

  variance: function(mu, b) {
    return 2 * b * b;
  },

  sample: function sample(mu, b) {
    var u = Math.random() - 0.5;

    return mu - (b * laplaceSign(u) * Math.log(1 - (2 * Math.abs(u))));
  }
});

function tukeyWprob(w, rr, cc) {
  var nleg = 12;
  var ihalf = 6;

  var C1 = -30;
  var C2 = -50;
  var C3 = 60;
  var bb   = 8;
  var wlar = 3;
  var wincr1 = 2;
  var wincr2 = 3;
  var xleg = [
    0.981560634246719250690549090149,
    0.904117256370474856678465866119,
    0.769902674194304687036893833213,
    0.587317954286617447296702418941,
    0.367831498998180193752691536644,
    0.125233408511468915472441369464
  ];
  var aleg = [
    0.047175336386511827194615961485,
    0.106939325995318430960254718194,
    0.160078328543346226334652529543,
    0.203167426723065921749064455810,
    0.233492536538354808760849898925,
    0.249147045813402785000562436043
  ];

  var qsqz = w * 0.5;

  // if w >= 16 then the integral lower bound (occurs for c=20)
  // is 0.99999999999995 so return a value of 1.

  if (qsqz >= bb)
    return 1.0;

  // find (f(w/2) - 1) ^ cc
  // (first term in integral of hartley's form).

  var pr_w = 2 * jStat.normal.cdf(qsqz, 0, 1, 1, 0) - 1; // erf(qsqz / M_SQRT2)
  // if pr_w ^ cc < 2e-22 then set pr_w = 0
  if (pr_w >= Math.exp(C2 / cc))
    pr_w = Math.pow(pr_w, cc);
  else
    pr_w = 0.0;

  // if w is large then the second component of the
  // integral is small, so fewer intervals are needed.

  var wincr;
  if (w > wlar)
    wincr = wincr1;
  else
    wincr = wincr2;

  // find the integral of second term of hartley's form
  // for the integral of the range for equal-length
  // intervals using legendre quadrature.  limits of
  // integration are from (w/2, 8).  two or three
  // equal-length intervals are used.

  // blb and bub are lower and upper limits of integration.

  var blb = qsqz;
  var binc = (bb - qsqz) / wincr;
  var bub = blb + binc;
  var einsum = 0.0;

  // integrate over each interval

  var cc1 = cc - 1.0;
  for (var wi = 1; wi <= wincr; wi++) {
    var elsum = 0.0;
    var a = 0.5 * (bub + blb);

    // legendre quadrature with order = nleg

    var b = 0.5 * (bub - blb);

    for (var jj = 1; jj <= nleg; jj++) {
      var j, xx;
      if (ihalf < jj) {
        j = (nleg - jj) + 1;
        xx = xleg[j-1];
      } else {
        j = jj;
        xx = -xleg[j-1];
      }
      var c = b * xx;
      var ac = a + c;

      // if exp(-qexpo/2) < 9e-14,
      // then doesn't contribute to integral

      var qexpo = ac * ac;
      if (qexpo > C3)
        break;

      var pplus = 2 * jStat.normal.cdf(ac, 0, 1, 1, 0);
      var pminus= 2 * jStat.normal.cdf(ac, w, 1, 1, 0);

      // if rinsum ^ (cc-1) < 9e-14,
      // then doesn't contribute to integral

      var rinsum = (pplus * 0.5) - (pminus * 0.5);
      if (rinsum >= Math.exp(C1 / cc1)) {
        rinsum = (aleg[j-1] * Math.exp(-(0.5 * qexpo))) * Math.pow(rinsum, cc1);
        elsum += rinsum;
      }
    }
    elsum *= (((2.0 * b) * cc) / Math.sqrt(2 * Math.PI));
    einsum += elsum;
    blb = bub;
    bub += binc;
  }

  // if pr_w ^ rr < 9e-14, then return 0
  pr_w += einsum;
  if (pr_w <= Math.exp(C1 / rr))
    return 0;

  pr_w = Math.pow(pr_w, rr);
  if (pr_w >= 1) // 1 was iMax was eps
    return 1;
  return pr_w;
}

function tukeyQinv(p, c, v) {
  var p0 = 0.322232421088;
  var q0 = 0.993484626060e-01;
  var p1 = -1.0;
  var q1 = 0.588581570495;
  var p2 = -0.342242088547;
  var q2 = 0.531103462366;
  var p3 = -0.204231210125;
  var q3 = 0.103537752850;
  var p4 = -0.453642210148e-04;
  var q4 = 0.38560700634e-02;
  var c1 = 0.8832;
  var c2 = 0.2368;
  var c3 = 1.214;
  var c4 = 1.208;
  var c5 = 1.4142;
  var vmax = 120.0;

  var ps = 0.5 - 0.5 * p;
  var yi = Math.sqrt(Math.log(1.0 / (ps * ps)));
  var t = yi + (((( yi * p4 + p3) * yi + p2) * yi + p1) * yi + p0)
     / (((( yi * q4 + q3) * yi + q2) * yi + q1) * yi + q0);
  if (v < vmax) t += (t * t * t + t) / v / 4.0;
  var q = c1 - c2 * t;
  if (v < vmax) q += -c3 / v + c4 * t / v;
  return t * (q * Math.log(c - 1.0) + c5);
}

jStat.extend(jStat.tukey, {
  cdf: function cdf(q, nmeans, df) {
    // Identical implementation as the R ptukey() function as of commit 68947
    var rr = 1;
    var cc = nmeans;

    var nlegq = 16;
    var ihalfq = 8;

    var eps1 = -30.0;
    var eps2 = 1.0e-14;
    var dhaf  = 100.0;
    var dquar = 800.0;
    var deigh = 5000.0;
    var dlarg = 25000.0;
    var ulen1 = 1.0;
    var ulen2 = 0.5;
    var ulen3 = 0.25;
    var ulen4 = 0.125;
    var xlegq = [
      0.989400934991649932596154173450,
      0.944575023073232576077988415535,
      0.865631202387831743880467897712,
      0.755404408355003033895101194847,
      0.617876244402643748446671764049,
      0.458016777657227386342419442984,
      0.281603550779258913230460501460,
      0.950125098376374401853193354250e-1
    ];
    var alegq = [
      0.271524594117540948517805724560e-1,
      0.622535239386478928628438369944e-1,
      0.951585116824927848099251076022e-1,
      0.124628971255533872052476282192,
      0.149595988816576732081501730547,
      0.169156519395002538189312079030,
      0.182603415044923588866763667969,
      0.189450610455068496285396723208
    ];

    if (q <= 0)
      return 0;

    // df must be > 1
    // there must be at least two values

    if (df < 2 || rr < 1 || cc < 2) return NaN;

    if (!Number.isFinite(q))
      return 1;

    if (df > dlarg)
      return tukeyWprob(q, rr, cc);

    // calculate leading constant

    var f2 = df * 0.5;
    var f2lf = ((f2 * Math.log(df)) - (df * Math.log(2))) - jStat.gammaln(f2);
    var f21 = f2 - 1.0;

    // integral is divided into unit, half-unit, quarter-unit, or
    // eighth-unit length intervals depending on the value of the
    // degrees of freedom.

    var ff4 = df * 0.25;
    var ulen;
    if      (df <= dhaf)  ulen = ulen1;
    else if (df <= dquar) ulen = ulen2;
    else if (df <= deigh) ulen = ulen3;
    else                  ulen = ulen4;

    f2lf += Math.log(ulen);

    // integrate over each subinterval

    var ans = 0.0;

    for (var i = 1; i <= 50; i++) {
      var otsum = 0.0;

      // legendre quadrature with order = nlegq
      // nodes (stored in xlegq) are symmetric around zero.

      var twa1 = (2 * i - 1) * ulen;

      for (var jj = 1; jj <= nlegq; jj++) {
        var j, t1;
        if (ihalfq < jj) {
          j = jj - ihalfq - 1;
          t1 = (f2lf + (f21 * Math.log(twa1 + (xlegq[j] * ulen))))
              - (((xlegq[j] * ulen) + twa1) * ff4);
        } else {
          j = jj - 1;
          t1 = (f2lf + (f21 * Math.log(twa1 - (xlegq[j] * ulen))))
              + (((xlegq[j] * ulen) - twa1) * ff4);
        }

        // if exp(t1) < 9e-14, then doesn't contribute to integral
        var qsqz;
        if (t1 >= eps1) {
          if (ihalfq < jj) {
            qsqz = q * Math.sqrt(((xlegq[j] * ulen) + twa1) * 0.5);
          } else {
            qsqz = q * Math.sqrt(((-(xlegq[j] * ulen)) + twa1) * 0.5);
          }

          // call wprob to find integral of range portion

          var wprb = tukeyWprob(qsqz, rr, cc);
          var rotsum = (wprb * alegq[j]) * Math.exp(t1);
          otsum += rotsum;
        }
        // end legendre integral for interval i
        // L200:
      }

      // if integral for interval i < 1e-14, then stop.
      // However, in order to avoid small area under left tail,
      // at least  1 / ulen  intervals are calculated.
      if (i * ulen >= 1.0 && otsum <= eps2)
        break;

      // end of interval i
      // L330:

      ans += otsum;
    }

    if (otsum > eps2) { // not converged
      throw new Error('tukey.cdf failed to converge');
    }
    if (ans > 1)
      ans = 1;
    return ans;
  },

  inv: function(p, nmeans, df) {
    // Identical implementation as the R qtukey() function as of commit 68947
    var rr = 1;
    var cc = nmeans;

    var eps = 0.0001;
    var maxiter = 50;

    // df must be > 1 ; there must be at least two values
    if (df < 2 || rr < 1 || cc < 2) return NaN;

    if (p < 0 || p > 1) return NaN;
    if (p === 0) return 0;
    if (p === 1) return Infinity;

    // Initial value

    var x0 = tukeyQinv(p, cc, df);

    // Find prob(value < x0)

    var valx0 = jStat.tukey.cdf(x0, nmeans, df) - p;

    // Find the second iterate and prob(value < x1).
    // If the first iterate has probability value
    // exceeding p then second iterate is 1 less than
    // first iterate; otherwise it is 1 greater.

    var x1;
    if (valx0 > 0.0)
      x1 = Math.max(0.0, x0 - 1.0);
    else
      x1 = x0 + 1.0;
    var valx1 = jStat.tukey.cdf(x1, nmeans, df) - p;

    // Find new iterate

    var ans;
    for(var iter = 1; iter < maxiter; iter++) {
      ans = x1 - ((valx1 * (x1 - x0)) / (valx1 - valx0));
      valx0 = valx1;

      // New iterate must be >= 0

      x0 = x1;
      if (ans < 0.0) {
        ans = 0.0;
        valx1 = -p;
      }
      // Find prob(value < new iterate)

      valx1 = jStat.tukey.cdf(ans, nmeans, df) - p;
      x1 = ans;

      // If the difference between two successive
      // iterates is less than eps, stop

      var xabs = Math.abs(x1 - x0);
      if (xabs < eps)
        return ans;
    }

    throw new Error('tukey.inv failed to converge');
  }
});

}(jStat, Math));
/* Provides functions for the solution of linear system of equations, integration, extrapolation,
 * interpolation, eigenvalue problems, differential equations and PCA analysis. */

(function(jStat, Math) {

var push = Array.prototype.push;
var isArray = jStat.utils.isArray;

function isUsable(arg) {
  return isArray(arg) || arg instanceof jStat;
}

jStat.extend({

  // add a vector/matrix to a vector/matrix or scalar
  add: function add(arr, arg) {
    // check if arg is a vector or scalar
    if (isUsable(arg)) {
      if (!isUsable(arg[0])) arg = [ arg ];
      return jStat.map(arr, function(value, row, col) {
        return value + arg[row][col];
      });
    }
    return jStat.map(arr, function(value) { return value + arg; });
  },

  // subtract a vector or scalar from the vector
  subtract: function subtract(arr, arg) {
    // check if arg is a vector or scalar
    if (isUsable(arg)) {
      if (!isUsable(arg[0])) arg = [ arg ];
      return jStat.map(arr, function(value, row, col) {
        return value - arg[row][col] || 0;
      });
    }
    return jStat.map(arr, function(value) { return value - arg; });
  },

  // matrix division
  divide: function divide(arr, arg) {
    if (isUsable(arg)) {
      if (!isUsable(arg[0])) arg = [ arg ];
      return jStat.multiply(arr, jStat.inv(arg));
    }
    return jStat.map(arr, function(value) { return value / arg; });
  },

  // matrix multiplication
  multiply: function multiply(arr, arg) {
    var row, col, nrescols, sum, nrow, ncol, res, rescols;
    // eg: arr = 2 arg = 3 -> 6 for res[0][0] statement closure
    if (arr.length === undefined && arg.length === undefined) {
      return arr * arg;
    }
    nrow = arr.length,
    ncol = arr[0].length,
    res = jStat.zeros(nrow, nrescols = (isUsable(arg)) ? arg[0].length : ncol),
    rescols = 0;
    if (isUsable(arg)) {
      for (; rescols < nrescols; rescols++) {
        for (row = 0; row < nrow; row++) {
          sum = 0;
          for (col = 0; col < ncol; col++)
          sum += arr[row][col] * arg[col][rescols];
          res[row][rescols] = sum;
        }
      }
      return (nrow === 1 && rescols === 1) ? res[0][0] : res;
    }
    return jStat.map(arr, function(value) { return value * arg; });
  },

  // outer([1,2,3],[4,5,6])
  // ===
  // [[1],[2],[3]] times [[4,5,6]]
  // ->
  // [[4,5,6],[8,10,12],[12,15,18]]
  outer:function outer(A, B) {
    return jStat.multiply(A.map(function(t){ return [t] }), [B]);
  },


  // Returns the dot product of two matricies
  dot: function dot(arr, arg) {
    if (!isUsable(arr[0])) arr = [ arr ];
    if (!isUsable(arg[0])) arg = [ arg ];
    // convert column to row vector
    var left = (arr[0].length === 1 && arr.length !== 1) ? jStat.transpose(arr) : arr,
    right = (arg[0].length === 1 && arg.length !== 1) ? jStat.transpose(arg) : arg,
    res = [],
    row = 0,
    nrow = left.length,
    ncol = left[0].length,
    sum, col;
    for (; row < nrow; row++) {
      res[row] = [];
      sum = 0;
      for (col = 0; col < ncol; col++)
      sum += left[row][col] * right[row][col];
      res[row] = sum;
    }
    return (res.length === 1) ? res[0] : res;
  },

  // raise every element by a scalar
  pow: function pow(arr, arg) {
    return jStat.map(arr, function(value) { return Math.pow(value, arg); });
  },

  // exponentiate every element
  exp: function exp(arr) {
    return jStat.map(arr, function(value) { return Math.exp(value); });
  },

  // generate the natural log of every element
  log: function exp(arr) {
    return jStat.map(arr, function(value) { return Math.log(value); });
  },

  // generate the absolute values of the vector
  abs: function abs(arr) {
    return jStat.map(arr, function(value) { return Math.abs(value); });
  },

  // computes the p-norm of the vector
  // In the case that a matrix is passed, uses the first row as the vector
  norm: function norm(arr, p) {
    var nnorm = 0,
    i = 0;
    // check the p-value of the norm, and set for most common case
    if (isNaN(p)) p = 2;
    // check if multi-dimensional array, and make vector correction
    if (isUsable(arr[0])) arr = arr[0];
    // vector norm
    for (; i < arr.length; i++) {
      nnorm += Math.pow(Math.abs(arr[i]), p);
    }
    return Math.pow(nnorm, 1 / p);
  },

  // computes the angle between two vectors in rads
  // In case a matrix is passed, this uses the first row as the vector
  angle: function angle(arr, arg) {
    return Math.acos(jStat.dot(arr, arg) / (jStat.norm(arr) * jStat.norm(arg)));
  },

  // augment one matrix by another
  // Note: this function returns a matrix, not a jStat object
  aug: function aug(a, b) {
    var newarr = [];
    for (var i = 0; i < a.length; i++) {
      newarr.push(a[i].slice());
    }
    for (var i = 0; i < newarr.length; i++) {
      push.apply(newarr[i], b[i]);
    }
    return newarr;
  },

  // The inv() function calculates the inverse of a matrix
  // Create the inverse by augmenting the matrix by the identity matrix of the
  // appropriate size, and then use G-J elimination on the augmented matrix.
  inv: function inv(a) {
    var rows = a.length;
    var cols = a[0].length;
    var b = jStat.identity(rows, cols);
    var c = jStat.gauss_jordan(a, b);
    var result = [];
    var i = 0;
    var j;

    //We need to copy the inverse portion to a new matrix to rid G-J artifacts
    for (; i < rows; i++) {
      result[i] = [];
      for (j = cols; j < c[0].length; j++)
        result[i][j - cols] = c[i][j];
    }
    return result;
  },

  // calculate the determinant of a matrix
  det: function det(a) {
    var alen = a.length,
    alend = alen * 2,
    vals = new Array(alend),
    rowshift = alen - 1,
    colshift = alend - 1,
    mrow = rowshift - alen + 1,
    mcol = colshift,
    i = 0,
    result = 0,
    j;
    // check for special 2x2 case
    if (alen === 2) {
      return a[0][0] * a[1][1] - a[0][1] * a[1][0];
    }
    for (; i < alend; i++) {
      vals[i] = 1;
    }
    for (var i = 0; i < alen; i++) {
      for (j = 0; j < alen; j++) {
        vals[(mrow < 0) ? mrow + alen : mrow ] *= a[i][j];
        vals[(mcol < alen) ? mcol + alen : mcol ] *= a[i][j];
        mrow++;
        mcol--;
      }
      mrow = --rowshift - alen + 1;
      mcol = --colshift;
    }
    for (var i = 0; i < alen; i++) {
      result += vals[i];
    }
    for (; i < alend; i++) {
      result -= vals[i];
    }
    return result;
  },

  gauss_elimination: function gauss_elimination(a, b) {
    var i = 0,
    j = 0,
    n = a.length,
    m = a[0].length,
    factor = 1,
    sum = 0,
    x = [],
    maug, pivot, temp, k;
    a = jStat.aug(a, b);
    maug = a[0].length;
    for(var i = 0; i < n; i++) {
      pivot = a[i][i];
      j = i;
      for (k = i + 1; k < m; k++) {
        if (pivot < Math.abs(a[k][i])) {
          pivot = a[k][i];
          j = k;
        }
      }
      if (j != i) {
        for(k = 0; k < maug; k++) {
          temp = a[i][k];
          a[i][k] = a[j][k];
          a[j][k] = temp;
        }
      }
      for (j = i + 1; j < n; j++) {
        factor = a[j][i] / a[i][i];
        for(k = i; k < maug; k++) {
          a[j][k] = a[j][k] - factor * a[i][k];
        }
      }
    }
    for (var i = n - 1; i >= 0; i--) {
      sum = 0;
      for (j = i + 1; j<= n - 1; j++) {
        sum = sum + x[j] * a[i][j];
      }
      x[i] =(a[i][maug - 1] - sum) / a[i][i];
    }
    return x;
  },

  gauss_jordan: function gauss_jordan(a, b) {
    var m = jStat.aug(a, b),
    h = m.length,
    w = m[0].length;
    var c = 0;
    // find max pivot
    for (var y = 0; y < h; y++) {
      var maxrow = y;
      for (var y2 = y+1; y2 < h; y2++) {
        if (Math.abs(m[y2][y]) > Math.abs(m[maxrow][y]))
          maxrow = y2;
      }
      var tmp = m[y];
      m[y] = m[maxrow];
      m[maxrow] = tmp
      for (var y2 = y+1; y2 < h; y2++) {
        c = m[y2][y] / m[y][y];
        for (var x = y; x < w; x++) {
          m[y2][x] -= m[y][x] * c;
        }
      }
    }
    // backsubstitute
    for (var y = h-1; y >= 0; y--) {
      c = m[y][y];
      for (var y2 = 0; y2 < y; y2++) {
        for (var x = w-1; x > y-1; x--) {
          m[y2][x] -= m[y][x] * m[y2][y] / c;
        }
      }
      m[y][y] /= c;
      for (var x = h; x < w; x++) {
        m[y][x] /= c;
      }
    }
    return m;
  },

  // solve equation
  // Ax=b
  // A is upper triangular matrix
  // A=[[1,2,3],[0,4,5],[0,6,7]]
  // b=[1,2,3]
  // triaUpSolve(A,b) // -> [2.666,0.1666,1.666]
  // if you use matrix style
  // A=[[1,2,3],[0,4,5],[0,6,7]]
  // b=[[1],[2],[3]]
  // will return [[2.666],[0.1666],[1.666]]
  triaUpSolve: function triaUpSolve(A, b) {
    var size = A[0].length;
    var x = jStat.zeros(1, size)[0];
    var parts;
    var matrix_mode = false;

    if (b[0].length != undefined) {
      b = b.map(function(i){ return i[0] });
      matrix_mode = true;
    }

    jStat.arange(size - 1, -1, -1).forEach(function(i) {
      parts = jStat.arange(i + 1, size).map(function(j) {
        return x[j] * A[i][j];
      });
      x[i] = (b[i] - jStat.sum(parts)) / A[i][i];
    });

    if (matrix_mode)
      return x.map(function(i){ return [i] });
    return x;
  },

  triaLowSolve: function triaLowSolve(A, b) {
    // like to triaUpSolve but A is lower triangular matrix
    var size = A[0].length;
    var x = jStat.zeros(1, size)[0];
    var parts;

    var matrix_mode=false;
    if (b[0].length != undefined) {
      b = b.map(function(i){ return i[0] });
      matrix_mode = true;
    }

    jStat.arange(size).forEach(function(i) {
      parts = jStat.arange(i).map(function(j) {
        return A[i][j] * x[j];
      });
      x[i] = (b[i] - jStat.sum(parts)) / A[i][i];
    })

    if (matrix_mode)
      return x.map(function(i){ return [i] });
    return x;
  },


  // A -> [L,U]
  // A=LU
  // L is lower triangular matrix
  // U is upper triangular matrix
  lu: function lu(A) {
    var size = A.length;
    //var L=jStat.diagonal(jStat.ones(1,size)[0]);
    var L = jStat.identity(size);
    var R = jStat.zeros(A.length, A[0].length);
    var parts;
    jStat.arange(size).forEach(function(t) {
      R[0][t] = A[0][t];
    });
    jStat.arange(1, size).forEach(function(l) {
      jStat.arange(l).forEach(function(i) {
        parts = jStat.arange(i).map(function(jj) {
          return L[l][jj] * R[jj][i];
        });
        L[l][i] = (A[l][i] - jStat.sum(parts)) / R[i][i];
      });
      jStat.arange(l, size).forEach(function(j) {
        parts = jStat.arange(l).map(function(jj) {
          return L[l][jj] * R[jj][j];
        });
        R[l][j] = A[i][j] - jStat.sum(parts);
      });
    });
    return [L, R];
  },

  // A -> T
  // A=TT'
  // T is lower triangular matrix
  cholesky: function cholesky(A) {
    var size = A.length;
    var T = jStat.zeros(A.length, A[0].length);
    var parts;
    jStat.arange(size).forEach(function(i) {
      parts = jStat.arange(i).map(function(t) {
        return Math.pow(T[i][t],2);
      });
      T[i][i] = Math.sqrt(A[i][i] - jStat.sum(parts));
      jStat.arange(i + 1, size).forEach(function(j) {
        parts = jStat.arange(i).map(function(t) {
          return T[i][t] * T[j][t];
        });
        T[j][i] = (A[i][j] - jStat.sum(parts)) / T[i][i];
      });
    });
    return T;
  },


  gauss_jacobi: function gauss_jacobi(a, b, x, r) {
    var i = 0;
    var j = 0;
    var n = a.length;
    var l = [];
    var u = [];
    var d = [];
    var xv, c, h, xk;
    for (; i < n; i++) {
      l[i] = [];
      u[i] = [];
      d[i] = [];
      for (j = 0; j < n; j++) {
        if (i > j) {
          l[i][j] = a[i][j];
          u[i][j] = d[i][j] = 0;
        } else if (i < j) {
          u[i][j] = a[i][j];
          l[i][j] = d[i][j] = 0;
        } else {
          d[i][j] = a[i][j];
          l[i][j] = u[i][j] = 0;
        }
      }
    }
    h = jStat.multiply(jStat.multiply(jStat.inv(d), jStat.add(l, u)), -1);
    c = jStat.multiply(jStat.inv(d), b);
    xv = x;
    xk = jStat.add(jStat.multiply(h, x), c);
    i = 2;
    while (Math.abs(jStat.norm(jStat.subtract(xk,xv))) > r) {
      xv = xk;
      xk = jStat.add(jStat.multiply(h, xv), c);
      i++;
    }
    return xk;
  },

  gauss_seidel: function gauss_seidel(a, b, x, r) {
    var i = 0;
    var n = a.length;
    var l = [];
    var u = [];
    var d = [];
    var j, xv, c, h, xk;
    for (; i < n; i++) {
      l[i] = [];
      u[i] = [];
      d[i] = [];
      for (j = 0; j < n; j++) {
        if (i > j) {
          l[i][j] = a[i][j];
          u[i][j] = d[i][j] = 0;
        } else if (i < j) {
          u[i][j] = a[i][j];
          l[i][j] = d[i][j] = 0;
        } else {
          d[i][j] = a[i][j];
          l[i][j] = u[i][j] = 0;
        }
      }
    }
    h = jStat.multiply(jStat.multiply(jStat.inv(jStat.add(d, l)), u), -1);
    c = jStat.multiply(jStat.inv(jStat.add(d, l)), b);
    xv = x;
    xk = jStat.add(jStat.multiply(h, x), c);
    i = 2;
    while (Math.abs(jStat.norm(jStat.subtract(xk, xv))) > r) {
      xv = xk;
      xk = jStat.add(jStat.multiply(h, xv), c);
      i = i + 1;
    }
    return xk;
  },

  SOR: function SOR(a, b, x, r, w) {
    var i = 0;
    var n = a.length;
    var l = [];
    var u = [];
    var d = [];
    var j, xv, c, h, xk;
    for (; i < n; i++) {
      l[i] = [];
      u[i] = [];
      d[i] = [];
      for (j = 0; j < n; j++) {
        if (i > j) {
          l[i][j] = a[i][j];
          u[i][j] = d[i][j] = 0;
        } else if (i < j) {
          u[i][j] = a[i][j];
          l[i][j] = d[i][j] = 0;
        } else {
          d[i][j] = a[i][j];
          l[i][j] = u[i][j] = 0;
        }
      }
    }
    h = jStat.multiply(jStat.inv(jStat.add(d, jStat.multiply(l, w))),
                       jStat.subtract(jStat.multiply(d, 1 - w),
                                      jStat.multiply(u, w)));
    c = jStat.multiply(jStat.multiply(jStat.inv(jStat.add(d,
        jStat.multiply(l, w))), b), w);
    xv = x;
    xk = jStat.add(jStat.multiply(h, x), c);
    i = 2;
    while (Math.abs(jStat.norm(jStat.subtract(xk, xv))) > r) {
      xv = xk;
      xk = jStat.add(jStat.multiply(h, xv), c);
      i++;
    }
    return xk;
  },

  householder: function householder(a) {
    var m = a.length;
    var n = a[0].length;
    var i = 0;
    var w = [];
    var p = [];
    var alpha, r, k, j, factor;
    for (; i < m - 1; i++) {
      alpha = 0;
      for (j = i + 1; j < n; j++)
      alpha += (a[j][i] * a[j][i]);
      factor = (a[i + 1][i] > 0) ? -1 : 1;
      alpha = factor * Math.sqrt(alpha);
      r = Math.sqrt((((alpha * alpha) - a[i + 1][i] * alpha) / 2));
      w = jStat.zeros(m, 1);
      w[i + 1][0] = (a[i + 1][i] - alpha) / (2 * r);
      for (k = i + 2; k < m; k++) w[k][0] = a[k][i] / (2 * r);
      p = jStat.subtract(jStat.identity(m, n),
          jStat.multiply(jStat.multiply(w, jStat.transpose(w)), 2));
      a = jStat.multiply(p, jStat.multiply(a, p));
    }
    return a;
  },

  // A -> [Q,R]
  // Q is orthogonal matrix
  // R is upper triangular
  QR: (function() {
    // x -> Q
    // find a orthogonal matrix Q st.
    // Qx=y
    // y is [||x||,0,0,...]

    // quick ref
    var sum   = jStat.sum;
    var range = jStat.arange;

    function get_Q1(x) {
      var size = x.length;
      var norm_x = jStat.norm(x, 2);
      var e1 = jStat.zeros(1, size)[0];
      e1[0] = 1;
      var u = jStat.add(jStat.multiply(jStat.multiply(e1, norm_x), -1), x);
      var norm_u = jStat.norm(u, 2);
      var v = jStat.divide(u, norm_u);
      var Q = jStat.subtract(jStat.identity(size),
                             jStat.multiply(jStat.outer(v, v), 2));
      return Q;
    }

    function qr(A) {
      var size = A[0].length;
      var QList = [];
      jStat.arange(size).forEach(function(i) {
        var x = jStat.slice(A, { row: { start: i }, col: i });
        var Q = get_Q1(x);
        var Qn = jStat.identity(A.length);
        Qn = jStat.sliceAssign(Qn, { row: { start: i }, col: { start: i }}, Q);
        A = jStat.multiply(Qn, A);
        QList.push(Qn);
      });
      var Q = QList.reduce(function(x, y){ return jStat.multiply(x,y) });
      var R = A;
      return [Q, R];
    }

    function qr2(x) {
      // quick impletation
      // https://www.stat.wisc.edu/~larget/math496/qr.html

      var n = x.length;
      var p = x[0].length;

      x = jStat.copy(x);
      r = jStat.zeros(p, p);

      var i,j,k;
      for(j = 0; j < p; j++){
        r[j][j] = Math.sqrt(sum(range(n).map(function(i){
          return x[i][j] * x[i][j];
        })));
        for(i = 0; i < n; i++){
          x[i][j] = x[i][j] / r[j][j];
        }
        for(k = j+1; k < p; k++){
          r[j][k] = sum(range(n).map(function(i){
            return x[i][j] * x[i][k];
          }));
          for(i = 0; i < n; i++){
            x[i][k] = x[i][k] - x[i][j]*r[j][k];
          }
        }
      }
      return [x, r];
    }

    return qr2;
  }()),

  lstsq: (function(A, b) {
    // solve least squard problem for Ax=b as QR decomposition way if b is
    // [[b1],[b2],[b3]] form will return [[x1],[x2],[x3]] array form solution
    // else b is [b1,b2,b3] form will return [x1,x2,x3] array form solution
    function R_I(A) {
      A = jStat.copy(A);
      var size = A.length;
      var I = jStat.identity(size);
      jStat.arange(size - 1, -1, -1).forEach(function(i) {
        jStat.sliceAssign(
            I, { row: i }, jStat.divide(jStat.slice(I, { row: i }), A[i][i]));
        jStat.sliceAssign(
            A, { row: i }, jStat.divide(jStat.slice(A, { row: i }), A[i][i]));
        jStat.arange(i).forEach(function(j) {
          var c = jStat.multiply(A[j][i], -1);
          var Aj = jStat.slice(A, { row: j });
          var cAi = jStat.multiply(jStat.slice(A, { row: i }), c);
          jStat.sliceAssign(A, { row: j }, jStat.add(Aj, cAi));
          var Ij = jStat.slice(I, { row: j });
          var cIi = jStat.multiply(jStat.slice(I, { row: i }), c);
          jStat.sliceAssign(I, { row: j }, jStat.add(Ij, cIi));
        })
      });
      return I;
    }

    function qr_solve(A, b){
      var array_mode = false;
      if (b[0].length === undefined) {
        // [c1,c2,c3] mode
        b = b.map(function(x){ return [x] });
        array_mode = true;
      }
      var QR = jStat.QR(A);
      var Q = QR[0];
      var R = QR[1];
      var attrs = A[0].length;
      var Q1 = jStat.slice(Q,{col:{end:attrs}});
      var R1 = jStat.slice(R,{row:{end:attrs}});
      var RI = R_I(R1);
	  var Q2 = jStat.transpose(Q1);

	  if(Q2[0].length === undefined){
		  Q2 = [Q2]; // The confusing jStat.multifly implementation threat nature process again.
	  }

      var x = jStat.multiply(jStat.multiply(RI, Q2), b);

	  if(x.length === undefined){
		  x = [[x]]; // The confusing jStat.multifly implementation threat nature process again.
	  }


      if (array_mode)
        return x.map(function(i){ return i[0] });
      return x;
    }

    return qr_solve;
  }()),

  jacobi: function jacobi(a) {
    var condition = 1;
    var count = 0;
    var n = a.length;
    var e = jStat.identity(n, n);
    var ev = [];
    var b, i, j, p, q, maxim, theta, s;
    // condition === 1 only if tolerance is not reached
    while (condition === 1) {
      count++;
      maxim = a[0][1];
      p = 0;
      q = 1;
      for (var i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
          if (i != j) {
            if (maxim < Math.abs(a[i][j])) {
              maxim = Math.abs(a[i][j]);
              p = i;
              q = j;
            }
          }
        }
      }
      if (a[p][p] === a[q][q])
        theta = (a[p][q] > 0) ? Math.PI / 4 : -Math.PI / 4;
      else
        theta = Math.atan(2 * a[p][q] / (a[p][p] - a[q][q])) / 2;
      s = jStat.identity(n, n);
      s[p][p] = Math.cos(theta);
      s[p][q] = -Math.sin(theta);
      s[q][p] = Math.sin(theta);
      s[q][q] = Math.cos(theta);
      // eigen vector matrix
      e = jStat.multiply(e, s);
      b = jStat.multiply(jStat.multiply(jStat.inv(s), a), s);
      a = b;
      condition = 0;
      for (var i = 1; i < n; i++) {
        for (j = 1; j < n; j++) {
          if (i != j && Math.abs(a[i][j]) > 0.001) {
            condition = 1;
          }
        }
      }
    }
    for (var i = 0; i < n; i++) ev.push(a[i][i]);
    //returns both the eigenvalue and eigenmatrix
    return [e, ev];
  },

  rungekutta: function rungekutta(f, h, p, t_j, u_j, order) {
    var k1, k2, u_j1, k3, k4;
    if (order === 2) {
      while (t_j <= p) {
        k1 = h * f(t_j, u_j);
        k2 = h * f(t_j + h, u_j + k1);
        u_j1 = u_j + (k1 + k2) / 2;
        u_j = u_j1;
        t_j = t_j + h;
      }
    }
    if (order === 4) {
      while (t_j <= p) {
        k1 = h * f(t_j, u_j);
        k2 = h * f(t_j + h / 2, u_j + k1 / 2);
        k3 = h * f(t_j + h / 2, u_j + k2 / 2);
        k4 = h * f(t_j +h, u_j + k3);
        u_j1 = u_j + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
        u_j = u_j1;
        t_j = t_j + h;
      }
    }
    return u_j;
  },

  romberg: function romberg(f, a, b, order) {
    var i = 0;
    var h = (b - a) / 2;
    var x = [];
    var h1 = [];
    var g = [];
    var m, a1, j, k, I, d;
    while (i < order / 2) {
      I = f(a);
      for (j = a, k = 0; j <= b; j = j + h, k++) x[k] = j;
      m = x.length;
      for (j = 1; j < m - 1; j++) {
        I += (((j % 2) !== 0) ? 4 : 2) * f(x[j]);
      }
      I = (h / 3) * (I + f(b));
      g[i] = I;
      h /= 2;
      i++;
    }
    a1 = g.length;
    m = 1;
    while (a1 !== 1) {
      for (j = 0; j < a1 - 1; j++)
      h1[j] = ((Math.pow(4, m)) * g[j + 1] - g[j]) / (Math.pow(4, m) - 1);
      a1 = h1.length;
      g = h1;
      h1 = [];
      m++;
    }
    return g;
  },

  richardson: function richardson(X, f, x, h) {
    function pos(X, x) {
      var i = 0;
      var n = X.length;
      var p;
      for (; i < n; i++)
        if (X[i] === x) p = i;
      return p;
    }
    var n = X.length,
    h_min = Math.abs(x - X[pos(X, x) + 1]),
    i = 0,
    g = [],
    h1 = [],
    y1, y2, m, a, j;
    while (h >= h_min) {
      y1 = pos(X, x + h);
      y2 = pos(X, x);
      g[i] = (f[y1] - 2 * f[y2] + f[2 * y2 - y1]) / (h * h);
      h /= 2;
      i++;
    }
    a = g.length;
    m = 1;
    while (a != 1) {
      for (j = 0; j < a - 1; j++)
      h1[j] = ((Math.pow(4, m)) * g[j + 1] - g[j]) / (Math.pow(4, m) - 1);
      a = h1.length;
      g = h1;
      h1 = [];
      m++;
    }
    return g;
  },

  simpson: function simpson(f, a, b, n) {
    var h = (b - a) / n;
    var I = f(a);
    var x = [];
    var j = a;
    var k = 0;
    var i = 1;
    var m;
    for (; j <= b; j = j + h, k++)
      x[k] = j;
    m = x.length;
    for (; i < m - 1; i++) {
      I += ((i % 2 !== 0) ? 4 : 2) * f(x[i]);
    }
    return (h / 3) * (I + f(b));
  },

  hermite: function hermite(X, F, dF, value) {
    var n = X.length;
    var p = 0;
    var i = 0;
    var l = [];
    var dl = [];
    var A = [];
    var B = [];
    var j;
    for (; i < n; i++) {
      l[i] = 1;
      for (j = 0; j < n; j++) {
        if (i != j) l[i] *= (value - X[j]) / (X[i] - X[j]);
      }
      dl[i] = 0;
      for (j = 0; j < n; j++) {
        if (i != j) dl[i] += 1 / (X [i] - X[j]);
      }
      A[i] = (1 - 2 * (value - X[i]) * dl[i]) * (l[i] * l[i]);
      B[i] = (value - X[i]) * (l[i] * l[i]);
      p += (A[i] * F[i] + B[i] * dF[i]);
    }
    return p;
  },

  lagrange: function lagrange(X, F, value) {
    var p = 0;
    var i = 0;
    var j, l;
    var n = X.length;
    for (; i < n; i++) {
      l = F[i];
      for (j = 0; j < n; j++) {
        // calculating the lagrange polynomial L_i
        if (i != j) l *= (value - X[j]) / (X[i] - X[j]);
      }
      // adding the lagrange polynomials found above
      p += l;
    }
    return p;
  },

  cubic_spline: function cubic_spline(X, F, value) {
    var n = X.length;
    var i = 0, j;
    var A = [];
    var B = [];
    var alpha = [];
    var c = [];
    var h = [];
    var b = [];
    var d = [];
    for (; i < n - 1; i++)
      h[i] = X[i + 1] - X[i];
    alpha[0] = 0;
    for (var i = 1; i < n - 1; i++) {
      alpha[i] = (3 / h[i]) * (F[i + 1] - F[i]) -
          (3 / h[i-1]) * (F[i] - F[i-1]);
    }
    for (var i = 1; i < n - 1; i++) {
      A[i] = [];
      B[i] = [];
      A[i][i-1] = h[i-1];
      A[i][i] = 2 * (h[i - 1] + h[i]);
      A[i][i+1] = h[i];
      B[i][0] = alpha[i];
    }
    c = jStat.multiply(jStat.inv(A), B);
    for (j = 0; j < n - 1; j++) {
      b[j] = (F[j + 1] - F[j]) / h[j] - h[j] * (c[j + 1][0] + 2 * c[j][0]) / 3;
      d[j] = (c[j + 1][0] - c[j][0]) / (3 * h[j]);
    }
    for (j = 0; j < n; j++) {
      if (X[j] > value) break;
    }
    j -= 1;
    return F[j] + (value - X[j]) * b[j] + jStat.sq(value-X[j]) *
        c[j] + (value - X[j]) * jStat.sq(value - X[j]) * d[j];
  },

  gauss_quadrature: function gauss_quadrature() {
    throw new Error('gauss_quadrature not yet implemented');
  },

  PCA: function PCA(X) {
    var m = X.length;
    var n = X[0].length;
    var flag = false;
    var i = 0;
    var j, temp1;
    var u = [];
    var D = [];
    var result = [];
    var temp2 = [];
    var Y = [];
    var Bt = [];
    var B = [];
    var C = [];
    var V = [];
    var Vt = [];
    for (var i = 0; i < m; i++) {
      u[i] = jStat.sum(X[i]) / n;
    }
    for (var i = 0; i < n; i++) {
      B[i] = [];
      for(j = 0; j < m; j++) {
        B[i][j] = X[j][i] - u[j];
      }
    }
    B = jStat.transpose(B);
    for (var i = 0; i < m; i++) {
      C[i] = [];
      for (j = 0; j < m; j++) {
        C[i][j] = (jStat.dot([B[i]], [B[j]])) / (n - 1);
      }
    }
    result = jStat.jacobi(C);
    V = result[0];
    D = result[1];
    Vt = jStat.transpose(V);
    for (var i = 0; i < D.length; i++) {
      for (j = i; j < D.length; j++) {
        if(D[i] < D[j])  {
          temp1 = D[i];
          D[i] = D[j];
          D[j] = temp1;
          temp2 = Vt[i];
          Vt[i] = Vt[j];
          Vt[j] = temp2;
        }
      }
    }
    Bt = jStat.transpose(B);
    for (var i = 0; i < m; i++) {
      Y[i] = [];
      for (j = 0; j < Bt.length; j++) {
        Y[i][j] = jStat.dot([Vt[i]], [Bt[j]]);
      }
    }
    return [X, D, Vt, Y];
  }
});

// extend jStat.fn with methods that require one argument
(function(funcs) {
  for (var i = 0; i < funcs.length; i++) (function(passfunc) {
    jStat.fn[passfunc] = function(arg, func) {
      var tmpthis = this;
      // check for callback
      if (func) {
        setTimeout(function() {
          func.call(tmpthis, jStat.fn[passfunc].call(tmpthis, arg));
        }, 15);
        return this;
      }
      if (typeof jStat[passfunc](this, arg) === 'number')
        return jStat[passfunc](this, arg);
      else
        return jStat(jStat[passfunc](this, arg));
    };
  }(funcs[i]));
}('add divide multiply subtract dot pow exp log abs norm angle'.split(' ')));

}(jStat, Math));
(function(jStat, Math) {

var slice = [].slice;
var isNumber = jStat.utils.isNumber;
var isArray = jStat.utils.isArray;

// flag==true denotes use of sample standard deviation
// Z Statistics
jStat.extend({
  // 2 different parameter lists:
  // (value, mean, sd)
  // (value, array, flag)
  zscore: function zscore() {
    var args = slice.call(arguments);
    if (isNumber(args[1])) {
      return (args[0] - args[1]) / args[2];
    }
    return (args[0] - jStat.mean(args[1])) / jStat.stdev(args[1], args[2]);
  },

  // 3 different paramter lists:
  // (value, mean, sd, sides)
  // (zscore, sides)
  // (value, array, sides, flag)
  ztest: function ztest() {
    var args = slice.call(arguments);
    var z;
    if (isArray(args[1])) {
      // (value, array, sides, flag)
      z = jStat.zscore(args[0],args[1],args[3]);
      return (args[2] === 1) ?
        (jStat.normal.cdf(-Math.abs(z), 0, 1)) :
        (jStat.normal.cdf(-Math.abs(z), 0, 1)*2);
    } else {
      if (args.length > 2) {
        // (value, mean, sd, sides)
        z = jStat.zscore(args[0],args[1],args[2]);
        return (args[3] === 1) ?
          (jStat.normal.cdf(-Math.abs(z),0,1)) :
          (jStat.normal.cdf(-Math.abs(z),0,1)* 2);
      } else {
        // (zscore, sides)
        z = args[0];
        return (args[1] === 1) ?
          (jStat.normal.cdf(-Math.abs(z),0,1)) :
          (jStat.normal.cdf(-Math.abs(z),0,1)*2);
      }
    }
  }
});

jStat.extend(jStat.fn, {
  zscore: function zscore(value, flag) {
    return (value - this.mean()) / this.stdev(flag);
  },

  ztest: function ztest(value, sides, flag) {
    var zscore = Math.abs(this.zscore(value, flag));
    return (sides === 1) ?
      (jStat.normal.cdf(-zscore, 0, 1)) :
      (jStat.normal.cdf(-zscore, 0, 1) * 2);
  }
});

// T Statistics
jStat.extend({
  // 2 parameter lists
  // (value, mean, sd, n)
  // (value, array)
  tscore: function tscore() {
    var args = slice.call(arguments);
    return (args.length === 4) ?
      ((args[0] - args[1]) / (args[2] / Math.sqrt(args[3]))) :
      ((args[0] - jStat.mean(args[1])) /
       (jStat.stdev(args[1], true) / Math.sqrt(args[1].length)));
  },

  // 3 different paramter lists:
  // (value, mean, sd, n, sides)
  // (tscore, n, sides)
  // (value, array, sides)
  ttest: function ttest() {
    var args = slice.call(arguments);
    var tscore;
    if (args.length === 5) {
      tscore = Math.abs(jStat.tscore(args[0], args[1], args[2], args[3]));
      return (args[4] === 1) ?
        (jStat.studentt.cdf(-tscore, args[3]-1)) :
        (jStat.studentt.cdf(-tscore, args[3]-1)*2);
    }
    if (isNumber(args[1])) {
      tscore = Math.abs(args[0])
      return (args[2] == 1) ?
        (jStat.studentt.cdf(-tscore, args[1]-1)) :
        (jStat.studentt.cdf(-tscore, args[1]-1) * 2);
    }
    tscore = Math.abs(jStat.tscore(args[0], args[1]))
    return (args[2] == 1) ?
      (jStat.studentt.cdf(-tscore, args[1].length-1)) :
      (jStat.studentt.cdf(-tscore, args[1].length-1) * 2);
  }
});

jStat.extend(jStat.fn, {
  tscore: function tscore(value) {
    return (value - this.mean()) / (this.stdev(true) / Math.sqrt(this.cols()));
  },

  ttest: function ttest(value, sides) {
    return (sides === 1) ?
      (1 - jStat.studentt.cdf(Math.abs(this.tscore(value)), this.cols()-1)) :
      (jStat.studentt.cdf(-Math.abs(this.tscore(value)), this.cols()-1)*2);
  }
});

// F Statistics
jStat.extend({
  // Paramter list is as follows:
  // (array1, array2, array3, ...)
  // or it is an array of arrays
  // array of arrays conversion
  anovafscore: function anovafscore() {
    var args = slice.call(arguments),
    expVar, sample, sampMean, sampSampMean, tmpargs, unexpVar, i, j;
    if (args.length === 1) {
      tmpargs = new Array(args[0].length);
      for (var i = 0; i < args[0].length; i++) {
        tmpargs[i] = args[0][i];
      }
      args = tmpargs;
    }
    // 2 sample case
    if (args.length === 2) {
      return jStat.variance(args[0]) / jStat.variance(args[1]);
    }
    // Builds sample array
    sample = new Array();
    for (var i = 0; i < args.length; i++) {
      sample = sample.concat(args[i]);
    }
    sampMean = jStat.mean(sample);
    // Computes the explained variance
    expVar = 0;
    for (var i = 0; i < args.length; i++) {
      expVar = expVar + args[i].length * Math.pow(jStat.mean(args[i]) - sampMean, 2);
    }
    expVar /= (args.length - 1);
    // Computes unexplained variance
    unexpVar = 0;
    for (var i = 0; i < args.length; i++) {
      sampSampMean = jStat.mean(args[i]);
      for (j = 0; j < args[i].length; j++) {
        unexpVar += Math.pow(args[i][j] - sampSampMean, 2);
      }
    }
    unexpVar /= (sample.length - args.length);
    return expVar / unexpVar;
  },

  // 2 different paramter setups
  // (array1, array2, array3, ...)
  // (anovafscore, df1, df2)
  anovaftest: function anovaftest() {
    var args = slice.call(arguments),
    df1, df2, n, i;
    if (isNumber(args[0])) {
      return 1 - jStat.centralF.cdf(args[0], args[1], args[2]);
    }
    anovafscore = jStat.anovafscore(args);
    df1 = args.length - 1;
    n = 0;
    for (var i = 0; i < args.length; i++) {
      n = n + args[i].length;
    }
    df2 = n - df1 - 1;
    return 1 - jStat.centralF.cdf(anovafscore, df1, df2);
  },

  ftest: function ftest(fscore, df1, df2) {
    return 1 - jStat.centralF.cdf(fscore, df1, df2);
  }
});

jStat.extend(jStat.fn, {
  anovafscore: function anovafscore() {
    return jStat.anovafscore(this.toArray());
  },

  anovaftes: function anovaftes() {
    var n = 0;
    var i;
    for (var i = 0; i < this.length; i++) {
      n = n + this[i].length;
    }
    return jStat.ftest(this.anovafscore(), this.length - 1, n - this.length);
  }
});

// Tukey's range test
jStat.extend({
  // 2 parameter lists
  // (mean1, mean2, n1, n2, sd)
  // (array1, array2, sd)
  qscore: function qscore() {
    var args = slice.call(arguments);
    var mean1, mean2, n1, n2, sd;
    if (isNumber(args[0])) {
        mean1 = args[0];
        mean2 = args[1];
        n1 = args[2];
        n2 = args[3];
        sd = args[4];
    } else {
        mean1 = jStat.mean(args[0]);
        mean2 = jStat.mean(args[1]);
        n1 = args[0].length;
        n2 = args[1].length;
        sd = args[2];
    }
    return Math.abs(mean1 - mean2) / (sd * Math.sqrt((1 / n1 + 1 / n2) / 2));
  },

  // 3 different parameter lists:
  // (qscore, n, k)
  // (mean1, mean2, n1, n2, sd, n, k)
  // (array1, array2, sd, n, k)
  qtest: function qtest() {
    var args = slice.call(arguments);

    var qscore;
    if (args.length === 3) {
      qscore = args[0];
      args = args.slice(1);
    } else if (args.length === 7) {
      qscore = jStat.qscore(args[0], args[1], args[2], args[3], args[4]);
      args = args.slice(5);
    } else {
      qscore = jStat.qscore(args[0], args[1], args[2]);
      args = args.slice(3);
    }

    var n = args[0];
    var k = args[1];

    return 1 - jStat.tukey.cdf(qscore, k, n - k);
  },

  tukeyhsd: function tukeyhsd(arrays) {
    var sd = jStat.pooledstdev(arrays);
    var means = arrays.map(function (arr) {return jStat.mean(arr);});
    var n = arrays.reduce(function (n, arr) {return n + arr.length;}, 0);

    var results = [];
    for (var i = 0; i < arrays.length; ++i) {
        for (var j = i + 1; j < arrays.length; ++j) {
            var p = jStat.qtest(means[i], means[j], arrays[i].length, arrays[j].length, sd, n, arrays.length);
            results.push([[i, j], p]);
        }
    }

    return results;
  }
});

// Error Bounds
jStat.extend({
  // 2 different parameter setups
  // (value, alpha, sd, n)
  // (value, alpha, array)
  normalci: function normalci() {
    var args = slice.call(arguments),
    ans = new Array(2),
    change;
    if (args.length === 4) {
      change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *
                        args[2] / Math.sqrt(args[3]));
    } else {
      change = Math.abs(jStat.normal.inv(args[1] / 2, 0, 1) *
                        jStat.stdev(args[2]) / Math.sqrt(args[2].length));
    }
    ans[0] = args[0] - change;
    ans[1] = args[0] + change;
    return ans;
  },

  // 2 different parameter setups
  // (value, alpha, sd, n)
  // (value, alpha, array)
  tci: function tci() {
    var args = slice.call(arguments),
    ans = new Array(2),
    change;
    if (args.length === 4) {
      change = Math.abs(jStat.studentt.inv(args[1] / 2, args[3] - 1) *
                        args[2] / Math.sqrt(args[3]));
    } else {
      change = Math.abs(jStat.studentt.inv(args[1] / 2, args[2].length - 1) *
                        jStat.stdev(args[2], true) / Math.sqrt(args[2].length));
    }
    ans[0] = args[0] - change;
    ans[1] = args[0] + change;
    return ans;
  },

  significant: function significant(pvalue, alpha) {
    return pvalue < alpha;
  }
});

jStat.extend(jStat.fn, {
  normalci: function normalci(value, alpha) {
    return jStat.normalci(value, alpha, this.toArray());
  },

  tci: function tci(value, alpha) {
    return jStat.tci(value, alpha, this.toArray());
  }
});

// internal method for calculating the z-score for a difference of proportions test
function differenceOfProportions(p1, n1, p2, n2) {
  if (p1 > 1 || p2 > 1 || p1 <= 0 || p2 <= 0) {
    throw new Error("Proportions should be greater than 0 and less than 1")
  }
  var pooled = (p1 * n1 + p2 * n2) / (n1 + n2);
  var se = Math.sqrt(pooled * (1 - pooled) * ((1/n1) + (1/n2)));
  return (p1 - p2) / se;
}

// Difference of Proportions
jStat.extend(jStat.fn, {
  oneSidedDifferenceOfProportions: function oneSidedDifferenceOfProportions(p1, n1, p2, n2) {
    var z = differenceOfProportions(p1, n1, p2, n2);
    return jStat.ztest(z, 1);
  },

  twoSidedDifferenceOfProportions: function twoSidedDifferenceOfProportions(p1, n1, p2, n2) {
    var z = differenceOfProportions(p1, n1, p2, n2);
    return jStat.ztest(z, 2);
  }
});

}(jStat, Math));
jStat.models = (function(){

  function sub_regress(endog, exog) {
    return ols(endog, exog);
  }

  function sub_regress(exog) {
    var var_count = exog[0].length;
    var modelList = jStat.arange(var_count).map(function(endog_index) {
      var exog_index =
          jStat.arange(var_count).filter(function(i){return i!==endog_index});
      return ols(jStat.col(exog, endog_index).map(function(x){ return x[0] }),
                 jStat.col(exog, exog_index))
    });
    return modelList;
  }

  // do OLS model regress
  // exog have include const columns ,it will not generate it .In fact, exog is
  // "design matrix" look at
  //https://en.wikipedia.org/wiki/Design_matrix
  function ols(endog, exog) {
    var nobs = endog.length;
    var df_model = exog[0].length - 1;
    var df_resid = nobs-df_model - 1;
    var coef = jStat.lstsq(exog, endog);
    var predict =
        jStat.multiply(exog, coef.map(function(x) { return [x] }))
            .map(function(p) { return p[0] });
    var resid = jStat.subtract(endog, predict);
    var ybar = jStat.mean(endog);
    // constant cause problem
    // var SST = jStat.sum(endog.map(function(y) {
    //   return Math.pow(y-ybar,2);
    // }));
    var SSE = jStat.sum(predict.map(function(f) {
      return Math.pow(f - ybar, 2);
    }));
    var SSR = jStat.sum(endog.map(function(y, i) {
      return Math.pow(y - predict[i], 2);
    }));
    var SST = SSE + SSR;
    var R2 = (SSE / SST);
    return {
        exog:exog,
        endog:endog,
        nobs:nobs,
        df_model:df_model,
        df_resid:df_resid,
        coef:coef,
        predict:predict,
        resid:resid,
        ybar:ybar,
        SST:SST,
        SSE:SSE,
        SSR:SSR,
        R2:R2
    };
  }

  // H0: b_I=0
  // H1: b_I!=0
  function t_test(model) {
    var subModelList = sub_regress(model.exog);
    //var sigmaHat=jStat.stdev(model.resid);
    var sigmaHat = Math.sqrt(model.SSR / (model.df_resid));
    var seBetaHat = subModelList.map(function(mod) {
      var SST = mod.SST;
      var R2 = mod.R2;
      return sigmaHat / Math.sqrt(SST * (1 - R2));
    });
    var tStatistic = model.coef.map(function(coef, i) {
      return (coef - 0) / seBetaHat[i];
    });
    var pValue = tStatistic.map(function(t) {
      var leftppf = jStat.studentt.cdf(t, model.df_resid);
      return (leftppf > 0.5 ? 1 - leftppf : leftppf) * 2;
    });
    var c = jStat.studentt.inv(0.975, model.df_resid);
    var interval95 = model.coef.map(function(coef, i) {
      var d = c * seBetaHat[i];
      return [coef - d, coef + d];
    })
    return {
        se: seBetaHat,
        t: tStatistic,
        p: pValue,
        sigmaHat: sigmaHat,
        interval95: interval95
    };
  }

  function F_test(model) {
    var F_statistic =
        (model.R2 / model.df_model) / ((1 - model.R2) / model.df_resid);
    var fcdf = function(x, n1, n2) {
      return jStat.beta.cdf(x / (n2 / n1 + x), n1 / 2, n2 / 2)
    }
    var pvalue = 1 - fcdf(F_statistic, model.df_model, model.df_resid);
    return { F_statistic: F_statistic, pvalue: pvalue };
  }

  function ols_wrap(endog, exog) {
    var model = ols(endog,exog);
    var ttest = t_test(model);
    var ftest = F_test(model);
    // Provide the Wherry / Ezekiel / McNemar / Cohen Adjusted R^2
    // Which matches the 'adjusted R^2' provided by R's lm package
    var adjust_R2 =
        1 - (1 - model.R2) * ((model.nobs - 1) / (model.df_resid));
    model.t = ttest;
    model.f = ftest;
    model.adjust_R2 = adjust_R2;
    return model;
  }

  return { ols: ols_wrap };
})();
  // Make it compatible with previous version.
  jStat.jStat = jStat;

  return jStat;
});


/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

var utils = __webpack_require__(1);
var error = __webpack_require__(0);

exports.UNIQUE = function () {
  var result = [];
  for (var i = 0; i < arguments.length; ++i) {
    var hasElement = false;
    var element    = arguments[i];

    // Check if we've already seen this element.
    for (var j = 0; j < result.length; ++j) {
      hasElement = result[j] === element;
      if (hasElement) { break; }
    }

    // If we did not find it, add it to the result.
    if (!hasElement) {
      result.push(element);
    }
  }
  return result;
};

exports.FLATTEN = utils.flatten;

exports.ARGS2ARRAY = function () {
  return Array.prototype.slice.call(arguments, 0);
};

exports.REFERENCE = function (context, reference) {
  if (!arguments.length) {
    return error.error;
  }
  try {
    var path = reference.split('.');
    var result = context;
    for (var i = 0; i < path.length; ++i) {
      var step = path[i];
      if (step[step.length - 1] === ']') {
        var opening = step.indexOf('[');
        var index = step.substring(opening + 1, step.length - 1);
        result = result[step.substring(0, opening)][index];
      } else {
        result = result[step];
      }
    }
    return result;
  } catch (error) {}
};

exports.JOIN = function (array, separator) {
  return array.join(separator);
};

exports.NUMBERS = function () {
  var possibleNumbers = utils.flatten(arguments);
  return possibleNumbers.filter(function (el) {
    return typeof el === 'number';
  });
};

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var jStat = __webpack_require__(9).jStat;
var text = __webpack_require__(6);
var utils = __webpack_require__(1);
var bessel = __webpack_require__(25);

function isValidBinaryNumber(number) {
  return (/^[01]{1,10}$/).test(number);
}

exports.BESSELI = function(x, n) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  if (utils.anyIsError(x, n)) {
    return error.value;
  }

  return bessel.besseli(x, n);
};

exports.BESSELJ = function(x, n) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  if (utils.anyIsError(x, n)) {
    return error.value;
  }

  return bessel.besselj(x, n);
};

exports.BESSELK = function(x, n) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  if (utils.anyIsError(x, n)) {
    return error.value;
  }

  return bessel.besselk(x, n);
};

exports.BESSELY = function(x, n) {
  x = utils.parseNumber(x);
  n = utils.parseNumber(n);
  if (utils.anyIsError(x, n)) {
    return error.value;
  }

  return bessel.bessely(x, n);
};

exports.BIN2DEC = function(number) {
  // Return error if number is not binary or contains more than 10 characters (10 digits)
  if (!isValidBinaryNumber(number)) {
    return error.num;
  }

  // Convert binary number to decimal
  var result = parseInt(number, 2);

  // Handle negative numbers
  var stringified = number.toString();
  if (stringified.length === 10 && stringified.substring(0, 1) === '1') {
    return parseInt(stringified.substring(1), 2) - 512;
  } else {
    return result;
  }
};


exports.BIN2HEX = function(number, places) {
  // Return error if number is not binary or contains more than 10 characters (10 digits)
  if (!isValidBinaryNumber(number)) {
    return error.num;
  }

  // Ignore places and return a 10-character hexadecimal number if number is negative
  var stringified = number.toString();
  if (stringified.length === 10 && stringified.substring(0, 1) === '1') {
    return (1099511627264 + parseInt(stringified.substring(1), 2)).toString(16);
  }

  // Convert binary number to hexadecimal
  var result = parseInt(number, 2).toString(16);

  // Return hexadecimal number using the minimum number of characters necessary if places is undefined
  if (places === undefined) {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.BIN2OCT = function(number, places) {
  // Return error if number is not binary or contains more than 10 characters (10 digits)
  if (!isValidBinaryNumber(number)) {
    return error.num;
  }

  // Ignore places and return a 10-character octal number if number is negative
  var stringified = number.toString();
  if (stringified.length === 10 && stringified.substring(0, 1) === '1') {
    return (1073741312 + parseInt(stringified.substring(1), 2)).toString(8);
  }

  // Convert binary number to octal
  var result = parseInt(number, 2).toString(8);

  // Return octal number using the minimum number of characters necessary if places is undefined
  if (places === undefined) {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.BITAND = function(number1, number2) {
  // Return error if either number is a non-numeric value
  number1 = utils.parseNumber(number1);
  number2 = utils.parseNumber(number2);
  if (utils.anyIsError(number1, number2)) {
    return error.value;
  }

  // Return error if either number is less than 0
  if (number1 < 0 || number2 < 0) {
    return error.num;
  }

  // Return error if either number is a non-integer
  if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {
    return error.num;
  }

  // Return error if either number is greater than (2^48)-1
  if (number1 > 281474976710655 || number2 > 281474976710655) {
    return error.num;
  }

  // Return bitwise AND of two numbers
  return number1 & number2;
};

exports.BITLSHIFT = function(number, shift) {
  number = utils.parseNumber(number);
  shift = utils.parseNumber(shift);
  if (utils.anyIsError(number, shift)) {
    return error.value;
  }

  // Return error if number is less than 0
  if (number < 0) {
    return error.num;
  }

  // Return error if number is a non-integer
  if (Math.floor(number) !== number) {
    return error.num;
  }

  // Return error if number is greater than (2^48)-1
  if (number > 281474976710655) {
    return error.num;
  }

  // Return error if the absolute value of shift is greater than 53
  if (Math.abs(shift) > 53) {
    return error.num;
  }

  // Return number shifted by shift bits to the left or to the right if shift is negative
  return (shift >= 0) ? number << shift : number >> -shift;
};

exports.BITOR = function(number1, number2) {
  number1 = utils.parseNumber(number1);
  number2 = utils.parseNumber(number2);
  if (utils.anyIsError(number1, number2)) {
    return error.value;
  }

  // Return error if either number is less than 0
  if (number1 < 0 || number2 < 0) {
    return error.num;
  }

  // Return error if either number is a non-integer
  if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {
    return error.num;
  }

  // Return error if either number is greater than (2^48)-1
  if (number1 > 281474976710655 || number2 > 281474976710655) {
    return error.num;
  }

  // Return bitwise OR of two numbers
  return number1 | number2;
};

exports.BITRSHIFT = function(number, shift) {
  number = utils.parseNumber(number);
  shift = utils.parseNumber(shift);
  if (utils.anyIsError(number, shift)) {
    return error.value;
  }

  // Return error if number is less than 0
  if (number < 0) {
    return error.num;
  }

  // Return error if number is a non-integer
  if (Math.floor(number) !== number) {
    return error.num;
  }

  // Return error if number is greater than (2^48)-1
  if (number > 281474976710655) {
    return error.num;
  }

  // Return error if the absolute value of shift is greater than 53
  if (Math.abs(shift) > 53) {
    return error.num;
  }

  // Return number shifted by shift bits to the right or to the left if shift is negative
  return (shift >= 0) ? number >> shift : number << -shift;
};

exports.BITXOR = function(number1, number2) {
  number1 = utils.parseNumber(number1);
  number2 = utils.parseNumber(number2);
  if (utils.anyIsError(number1, number2)) {
    return error.value;
  }

  // Return error if either number is less than 0
  if (number1 < 0 || number2 < 0) {
    return error.num;
  }

  // Return error if either number is a non-integer
  if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) {
    return error.num;
  }

  // Return error if either number is greater than (2^48)-1
  if (number1 > 281474976710655 || number2 > 281474976710655) {
    return error.num;
  }

  // Return bitwise XOR of two numbers
  return number1 ^ number2;
};

exports.COMPLEX = function(real, imaginary, suffix) {
  real = utils.parseNumber(real);
  imaginary = utils.parseNumber(imaginary);
  if (utils.anyIsError(real, imaginary)) {
    return real;
  }

  // Set suffix
  suffix = (suffix === undefined) ? 'i' : suffix;

  // Return error if suffix is neither "i" nor "j"
  if (suffix !== 'i' && suffix !== 'j') {
    return error.value;
  }

  // Return complex number
  if (real === 0 && imaginary === 0) {
    return 0;
  } else if (real === 0) {
    return (imaginary === 1) ? suffix : imaginary.toString() + suffix;
  } else if (imaginary === 0) {
    return real.toString();
  } else {
    var sign = (imaginary > 0) ? '+' : '';
    return real.toString() + sign + ((imaginary === 1) ? suffix : imaginary.toString() + suffix);
  }
};

exports.CONVERT = function(number, from_unit, to_unit) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }

  // List of units supported by CONVERT and units defined by the International System of Units
  // [Name, Symbol, Alternate symbols, Quantity, ISU, CONVERT, Conversion ratio]
  var units = [
    ["a.u. of action", "?", null, "action", false, false, 1.05457168181818e-34],
    ["a.u. of charge", "e", null, "electric_charge", false, false, 1.60217653141414e-19],
    ["a.u. of energy", "Eh", null, "energy", false, false, 4.35974417757576e-18],
    ["a.u. of length", "a?", null, "length", false, false, 5.29177210818182e-11],
    ["a.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31],
    ["a.u. of time", "?/Eh", null, "time", false, false, 2.41888432650516e-17],
    ["admiralty knot", "admkn", null, "speed", false, true, 0.514773333],
    ["ampere", "A", null, "electric_current", true, false, 1],
    ["ampere per meter", "A/m", null, "magnetic_field_intensity", true, false, 1],
    ["ångström", "Å", ["ang"], "length", false, true, 1e-10],
    ["are", "ar", null, "area", false, true, 100],
    ["astronomical unit", "ua", null, "length", false, false, 1.49597870691667e-11],
    ["bar", "bar", null, "pressure", false, false, 100000],
    ["barn", "b", null, "area", false, false, 1e-28],
    ["becquerel", "Bq", null, "radioactivity", true, false, 1],
    ["bit", "bit", ["b"], "information", false, true, 1],
    ["btu", "BTU", ["btu"], "energy", false, true, 1055.05585262],
    ["byte", "byte", null, "information", false, true, 8],
    ["candela", "cd", null, "luminous_intensity", true, false, 1],
    ["candela per square metre", "cd/m?", null, "luminance", true, false, 1],
    ["coulomb", "C", null, "electric_charge", true, false, 1],
    ["cubic ångström", "ang3", ["ang^3"], "volume", false, true, 1e-30],
    ["cubic foot", "ft3", ["ft^3"], "volume", false, true, 0.028316846592],
    ["cubic inch", "in3", ["in^3"], "volume", false, true, 0.000016387064],
    ["cubic light-year", "ly3", ["ly^3"], "volume", false, true, 8.46786664623715e-47],
    ["cubic metre", "m?", null, "volume", true, true, 1],
    ["cubic mile", "mi3", ["mi^3"], "volume", false, true, 4168181825.44058],
    ["cubic nautical mile", "Nmi3", ["Nmi^3"], "volume", false, true, 6352182208],
    ["cubic Pica", "Pica3", ["Picapt3", "Pica^3", "Picapt^3"], "volume", false, true, 7.58660370370369e-8],
    ["cubic yard", "yd3", ["yd^3"], "volume", false, true, 0.764554857984],
    ["cup", "cup", null, "volume", false, true, 0.0002365882365],
    ["dalton", "Da", ["u"], "mass", false, false, 1.66053886282828e-27],
    ["day", "d", ["day"], "time", false, true, 86400],
    ["degree", "°", null, "angle", false, false, 0.0174532925199433],
    ["degrees Rankine", "Rank", null, "temperature", false, true, 0.555555555555556],
    ["dyne", "dyn", ["dy"], "force", false, true, 0.00001],
    ["electronvolt", "eV", ["ev"], "energy", false, true, 1.60217656514141],
    ["ell", "ell", null, "length", false, true, 1.143],
    ["erg", "erg", ["e"], "energy", false, true, 1e-7],
    ["farad", "F", null, "electric_capacitance", true, false, 1],
    ["fluid ounce", "oz", null, "volume", false, true, 0.0000295735295625],
    ["foot", "ft", null, "length", false, true, 0.3048],
    ["foot-pound", "flb", null, "energy", false, true, 1.3558179483314],
    ["gal", "Gal", null, "acceleration", false, false, 0.01],
    ["gallon", "gal", null, "volume", false, true, 0.003785411784],
    ["gauss", "G", ["ga"], "magnetic_flux_density", false, true, 1],
    ["grain", "grain", null, "mass", false, true, 0.0000647989],
    ["gram", "g", null, "mass", false, true, 0.001],
    ["gray", "Gy", null, "absorbed_dose", true, false, 1],
    ["gross registered ton", "GRT", ["regton"], "volume", false, true, 2.8316846592],
    ["hectare", "ha", null, "area", false, true, 10000],
    ["henry", "H", null, "inductance", true, false, 1],
    ["hertz", "Hz", null, "frequency", true, false, 1],
    ["horsepower", "HP", ["h"], "power", false, true, 745.69987158227],
    ["horsepower-hour", "HPh", ["hh", "hph"], "energy", false, true, 2684519.538],
    ["hour", "h", ["hr"], "time", false, true, 3600],
    ["imperial gallon (U.K.)", "uk_gal", null, "volume", false, true, 0.00454609],
    ["imperial hundredweight", "lcwt", ["uk_cwt", "hweight"], "mass", false, true, 50.802345],
    ["imperial quart (U.K)", "uk_qt", null, "volume", false, true, 0.0011365225],
    ["imperial ton", "brton", ["uk_ton", "LTON"], "mass", false, true, 1016.046909],
    ["inch", "in", null, "length", false, true, 0.0254],
    ["international acre", "uk_acre", null, "area", false, true, 4046.8564224],
    ["IT calorie", "cal", null, "energy", false, true, 4.1868],
    ["joule", "J", null, "energy", true, true, 1],
    ["katal", "kat", null, "catalytic_activity", true, false, 1],
    ["kelvin", "K", ["kel"], "temperature", true, true, 1],
    ["kilogram", "kg", null, "mass", true, true, 1],
    ["knot", "kn", null, "speed", false, true, 0.514444444444444],
    ["light-year", "ly", null, "length", false, true, 9460730472580800],
    ["litre", "L", ["l", "lt"], "volume", false, true, 0.001],
    ["lumen", "lm", null, "luminous_flux", true, false, 1],
    ["lux", "lx", null, "illuminance", true, false, 1],
    ["maxwell", "Mx", null, "magnetic_flux", false, false, 1e-18],
    ["measurement ton", "MTON", null, "volume", false, true, 1.13267386368],
    ["meter per hour", "m/h", ["m/hr"], "speed", false, true, 0.00027777777777778],
    ["meter per second", "m/s", ["m/sec"], "speed", true, true, 1],
    ["meter per second squared", "m?s??", null, "acceleration", true, false, 1],
    ["parsec", "pc", ["parsec"], "length", false, true, 30856775814671900],
    ["meter squared per second", "m?/s", null, "kinematic_viscosity", true, false, 1],
    ["metre", "m", null, "length", true, true, 1],
    ["miles per hour", "mph", null, "speed", false, true, 0.44704],
    ["millimetre of mercury", "mmHg", null, "pressure", false, false, 133.322],
    ["minute", "?", null, "angle", false, false, 0.000290888208665722],
    ["minute", "min", ["mn"], "time", false, true, 60],
    ["modern teaspoon", "tspm", null, "volume", false, true, 0.000005],
    ["mole", "mol", null, "amount_of_substance", true, false, 1],
    ["morgen", "Morgen", null, "area", false, true, 2500],
    ["n.u. of action", "?", null, "action", false, false, 1.05457168181818e-34],
    ["n.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31],
    ["n.u. of speed", "c?", null, "speed", false, false, 299792458],
    ["n.u. of time", "?/(me?c??)", null, "time", false, false, 1.28808866778687e-21],
    ["nautical mile", "M", ["Nmi"], "length", false, true, 1852],
    ["newton", "N", null, "force", true, true, 1],
    ["œrsted", "Oe ", null, "magnetic_field_intensity", false, false, 79.5774715459477],
    ["ohm", "Ω", null, "electric_resistance", true, false, 1],
    ["ounce mass", "ozm", null, "mass", false, true, 0.028349523125],
    ["pascal", "Pa", null, "pressure", true, false, 1],
    ["pascal second", "Pa?s", null, "dynamic_viscosity", true, false, 1],
    ["pferdestärke", "PS", null, "power", false, true, 735.49875],
    ["phot", "ph", null, "illuminance", false, false, 0.0001],
    ["pica (1/6 inch)", "pica", null, "length", false, true, 0.00035277777777778],
    ["pica (1/72 inch)", "Pica", ["Picapt"], "length", false, true, 0.00423333333333333],
    ["poise", "P", null, "dynamic_viscosity", false, false, 0.1],
    ["pond", "pond", null, "force", false, true, 0.00980665],
    ["pound force", "lbf", null, "force", false, true, 4.4482216152605],
    ["pound mass", "lbm", null, "mass", false, true, 0.45359237],
    ["quart", "qt", null, "volume", false, true, 0.000946352946],
    ["radian", "rad", null, "angle", true, false, 1],
    ["second", "?", null, "angle", false, false, 0.00000484813681109536],
    ["second", "s", ["sec"], "time", true, true, 1],
    ["short hundredweight", "cwt", ["shweight"], "mass", false, true, 45.359237],
    ["siemens", "S", null, "electrical_conductance", true, false, 1],
    ["sievert", "Sv", null, "equivalent_dose", true, false, 1],
    ["slug", "sg", null, "mass", false, true, 14.59390294],
    ["square ångström", "ang2", ["ang^2"], "area", false, true, 1e-20],
    ["square foot", "ft2", ["ft^2"], "area", false, true, 0.09290304],
    ["square inch", "in2", ["in^2"], "area", false, true, 0.00064516],
    ["square light-year", "ly2", ["ly^2"], "area", false, true, 8.95054210748189e+31],
    ["square meter", "m?", null, "area", true, true, 1],
    ["square mile", "mi2", ["mi^2"], "area", false, true, 2589988.110336],
    ["square nautical mile", "Nmi2", ["Nmi^2"], "area", false, true, 3429904],
    ["square Pica", "Pica2", ["Picapt2", "Pica^2", "Picapt^2"], "area", false, true, 0.00001792111111111],
    ["square yard", "yd2", ["yd^2"], "area", false, true, 0.83612736],
    ["statute mile", "mi", null, "length", false, true, 1609.344],
    ["steradian", "sr", null, "solid_angle", true, false, 1],
    ["stilb", "sb", null, "luminance", false, false, 0.0001],
    ["stokes", "St", null, "kinematic_viscosity", false, false, 0.0001],
    ["stone", "stone", null, "mass", false, true, 6.35029318],
    ["tablespoon", "tbs", null, "volume", false, true, 0.0000147868],
    ["teaspoon", "tsp", null, "volume", false, true, 0.00000492892],
    ["tesla", "T", null, "magnetic_flux_density", true, true, 1],
    ["thermodynamic calorie", "c", null, "energy", false, true, 4.184],
    ["ton", "ton", null, "mass", false, true, 907.18474],
    ["tonne", "t", null, "mass", false, false, 1000],
    ["U.K. pint", "uk_pt", null, "volume", false, true, 0.00056826125],
    ["U.S. bushel", "bushel", null, "volume", false, true, 0.03523907],
    ["U.S. oil barrel", "barrel", null, "volume", false, true, 0.158987295],
    ["U.S. pint", "pt", ["us_pt"], "volume", false, true, 0.000473176473],
    ["U.S. survey mile", "survey_mi", null, "length", false, true, 1609.347219],
    ["U.S. survey/statute acre", "us_acre", null, "area", false, true, 4046.87261],
    ["volt", "V", null, "voltage", true, false, 1],
    ["watt", "W", null, "power", true, true, 1],
    ["watt-hour", "Wh", ["wh"], "energy", false, true, 3600],
    ["weber", "Wb", null, "magnetic_flux", true, false, 1],
    ["yard", "yd", null, "length", false, true, 0.9144],
    ["year", "yr", null, "time", false, true, 31557600]
  ];

  // Binary prefixes
  // [Name, Prefix power of 2 value, Previx value, Abbreviation, Derived from]
  var binary_prefixes = {
    Yi: ["yobi", 80, 1208925819614629174706176, "Yi", "yotta"],
    Zi: ["zebi", 70, 1180591620717411303424, "Zi", "zetta"],
    Ei: ["exbi", 60, 1152921504606846976, "Ei", "exa"],
    Pi: ["pebi", 50, 1125899906842624, "Pi", "peta"],
    Ti: ["tebi", 40, 1099511627776, "Ti", "tera"],
    Gi: ["gibi", 30, 1073741824, "Gi", "giga"],
    Mi: ["mebi", 20, 1048576, "Mi", "mega"],
    ki: ["kibi", 10, 1024, "ki", "kilo"]
  };

  // Unit prefixes
  // [Name, Multiplier, Abbreviation]
  var unit_prefixes = {
    Y: ["yotta", 1e+24, "Y"],
    Z: ["zetta", 1e+21, "Z"],
    E: ["exa", 1e+18, "E"],
    P: ["peta", 1e+15, "P"],
    T: ["tera", 1e+12, "T"],
    G: ["giga", 1e+09, "G"],
    M: ["mega", 1e+06, "M"],
    k: ["kilo", 1e+03, "k"],
    h: ["hecto", 1e+02, "h"],
    e: ["dekao", 1e+01, "e"],
    d: ["deci", 1e-01, "d"],
    c: ["centi", 1e-02, "c"],
    m: ["milli", 1e-03, "m"],
    u: ["micro", 1e-06, "u"],
    n: ["nano", 1e-09, "n"],
    p: ["pico", 1e-12, "p"],
    f: ["femto", 1e-15, "f"],
    a: ["atto", 1e-18, "a"],
    z: ["zepto", 1e-21, "z"],
    y: ["yocto", 1e-24, "y"]
  };

  // Initialize units and multipliers
  var from = null;
  var to = null;
  var base_from_unit = from_unit;
  var base_to_unit = to_unit;
  var from_multiplier = 1;
  var to_multiplier = 1;
  var alt;

  // Lookup from and to units
  for (var i = 0; i < units.length; i++) {
    alt = (units[i][2] === null) ? [] : units[i][2];
    if (units[i][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) {
      from = units[i];
    }
    if (units[i][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) {
      to = units[i];
    }
  }

  // Lookup from prefix
  if (from === null) {
    var from_binary_prefix = binary_prefixes[from_unit.substring(0, 2)];
    var from_unit_prefix = unit_prefixes[from_unit.substring(0, 1)];

    // Handle dekao unit prefix (only unit prefix with two characters)
    if (from_unit.substring(0, 2) === 'da') {
      from_unit_prefix = ["dekao", 1e+01, "da"];
    }

    // Handle binary prefixes first (so that 'Yi' is processed before 'Y')
    if (from_binary_prefix) {
      from_multiplier = from_binary_prefix[2];
      base_from_unit = from_unit.substring(2);
    } else if (from_unit_prefix) {
      from_multiplier = from_unit_prefix[1];
      base_from_unit = from_unit.substring(from_unit_prefix[2].length);
    }

    // Lookup from unit
    for (var j = 0; j < units.length; j++) {
      alt = (units[j][2] === null) ? [] : units[j][2];
      if (units[j][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) {
        from = units[j];
      }
    }
  }

  // Lookup to prefix
  if (to === null) {
    var to_binary_prefix = binary_prefixes[to_unit.substring(0, 2)];
    var to_unit_prefix = unit_prefixes[to_unit.substring(0, 1)];

    // Handle dekao unit prefix (only unit prefix with two characters)
    if (to_unit.substring(0, 2) === 'da') {
      to_unit_prefix = ["dekao", 1e+01, "da"];
    }

    // Handle binary prefixes first (so that 'Yi' is processed before 'Y')
    if (to_binary_prefix) {
      to_multiplier = to_binary_prefix[2];
      base_to_unit = to_unit.substring(2);
    } else if (to_unit_prefix) {
      to_multiplier = to_unit_prefix[1];
      base_to_unit = to_unit.substring(to_unit_prefix[2].length);
    }

    // Lookup to unit
    for (var k = 0; k < units.length; k++) {
      alt = (units[k][2] === null) ? [] : units[k][2];
      if (units[k][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) {
        to = units[k];
      }
    }
  }

  // Return error if a unit does not exist
  if (from === null || to === null) {
    return error.na;
  }

  // Return error if units represent different quantities
  if (from[3] !== to[3]) {
    return error.na;
  }

  // Return converted number
  return number * from[6] * from_multiplier / (to[6] * to_multiplier);
};

exports.DEC2BIN = function(number, places) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }

  // Return error if number is not decimal, is lower than -512, or is greater than 511
  if (!/^-?[0-9]{1,3}$/.test(number) || number < -512 || number > 511) {
    return error.num;
  }

  // Ignore places and return a 10-character binary number if number is negative
  if (number < 0) {
    return '1' + text.REPT('0', 9 - (512 + number).toString(2).length) + (512 + number).toString(2);
  }

  // Convert decimal number to binary
  var result = parseInt(number, 10).toString(2);

  // Return binary number using the minimum number of characters necessary if places is undefined
  if (typeof places === 'undefined') {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.DEC2HEX = function(number, places) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }

  // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887
  if (!/^-?[0-9]{1,12}$/.test(number) || number < -549755813888 || number > 549755813887) {
    return error.num;
  }

  // Ignore places and return a 10-character hexadecimal number if number is negative
  if (number < 0) {
    return (1099511627776 + number).toString(16);
  }

  // Convert decimal number to hexadecimal
  var result = parseInt(number, 10).toString(16);

  // Return hexadecimal number using the minimum number of characters necessary if places is undefined
  if (typeof places === 'undefined') {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.DEC2OCT = function(number, places) {
  number = utils.parseNumber(number);
  if (number instanceof Error) {
    return number;
  }

  // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887
  if (!/^-?[0-9]{1,9}$/.test(number) || number < -536870912 || number > 536870911) {
    return error.num;
  }

  // Ignore places and return a 10-character octal number if number is negative
  if (number < 0) {
    return (1073741824 + number).toString(8);
  }

  // Convert decimal number to octal
  var result = parseInt(number, 10).toString(8);

  // Return octal number using the minimum number of characters necessary if places is undefined
  if (typeof places === 'undefined') {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.DELTA = function(number1, number2) {
  // Set number2 to zero if undefined
  number2 = (number2 === undefined) ? 0 : number2;
  number1 = utils.parseNumber(number1);
  number2 = utils.parseNumber(number2);
  if (utils.anyIsError(number1, number2)) {
    return error.value;
  }

  // Return delta
  return (number1 === number2) ? 1 : 0;
};

// TODO: why is upper_bound not used ? The excel documentation has no examples with upper_bound
exports.ERF = function(lower_bound, upper_bound) {
  // Set number2 to zero if undefined
  upper_bound = (upper_bound === undefined) ? 0 : upper_bound;

  lower_bound = utils.parseNumber(lower_bound);
  upper_bound = utils.parseNumber(upper_bound);
  if (utils.anyIsError(lower_bound, upper_bound)) {
    return error.value;
  }

  return jStat.erf(lower_bound);
};

// TODO
exports.ERF.PRECISE = function() {
  throw new Error('ERF.PRECISE is not implemented');
};

exports.ERFC = function(x) {
  // Return error if x is not a number
  if (isNaN(x)) {
    return error.value;
  }

  return jStat.erfc(x);
};

// TODO
exports.ERFC.PRECISE = function() {
  throw new Error('ERFC.PRECISE is not implemented');
};

exports.GESTEP = function(number, step) {
  step = step || 0;
  number = utils.parseNumber(number);
  if (utils.anyIsError(step, number)) {
    return number;
  }

  // Return delta
  return (number >= step) ? 1 : 0;
};

exports.HEX2BIN = function(number, places) {
  // Return error if number is not hexadecimal or contains more than ten characters (10 digits)
  if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {
    return error.num;
  }

  // Check if number is negative
  var negative = (number.length === 10 && number.substring(0, 1).toLowerCase() === 'f') ? true : false;

  // Convert hexadecimal number to decimal
  var decimal = (negative) ? parseInt(number, 16) - 1099511627776 : parseInt(number, 16);

  // Return error if number is lower than -512 or greater than 511
  if (decimal < -512 || decimal > 511) {
    return error.num;
  }

  // Ignore places and return a 10-character binary number if number is negative
  if (negative) {
    return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2);
  }

  // Convert decimal number to binary
  var result = decimal.toString(2);

  // Return binary number using the minimum number of characters necessary if places is undefined
  if (places === undefined) {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.HEX2DEC = function(number) {
  // Return error if number is not hexadecimal or contains more than ten characters (10 digits)
  if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {
    return error.num;
  }

  // Convert hexadecimal number to decimal
  var decimal = parseInt(number, 16);

  // Return decimal number
  return (decimal >= 549755813888) ? decimal - 1099511627776 : decimal;
};

exports.HEX2OCT = function(number, places) {
  // Return error if number is not hexadecimal or contains more than ten characters (10 digits)
  if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) {
    return error.num;
  }

  // Convert hexadecimal number to decimal
  var decimal = parseInt(number, 16);

  // Return error if number is positive and greater than 0x1fffffff (536870911)
  if (decimal > 536870911 && decimal < 1098974756864) {
    return error.num;
  }

  // Ignore places and return a 10-character octal number if number is negative
  if (decimal >= 1098974756864) {
    return (decimal - 1098437885952).toString(8);
  }

  // Convert decimal number to octal
  var result = decimal.toString(8);

  // Return octal number using the minimum number of characters necessary if places is undefined
  if (places === undefined) {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.IMABS = function(inumber) {
  // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  // Return error if either coefficient is not a number
  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return absolute value of complex number
  return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
};

exports.IMAGINARY = function(inumber) {
  if (inumber === undefined || inumber === true || inumber === false) {
    return error.value;
  }

  // Return 0 if inumber is equal to 0
  if (inumber === 0 || inumber === '0') {
    return 0;
  }

  // Handle special cases
  if (['i', 'j'].indexOf(inumber) >= 0) {
    return 1;
  }

  // Normalize imaginary coefficient
  inumber = inumber.replace('+i', '+1i').replace('-i', '-1i').replace('+j', '+1j').replace('-j', '-1j');

  // Lookup sign
  var plus = inumber.indexOf('+');
  var minus = inumber.indexOf('-');
  if (plus === 0) {
    plus = inumber.indexOf('+', 1);
  }

  if (minus === 0) {
    minus = inumber.indexOf('-', 1);
  }

  // Lookup imaginary unit
  var last = inumber.substring(inumber.length - 1, inumber.length);
  var unit = (last === 'i' || last === 'j');

  if (plus >= 0 || minus >= 0) {
    // Return error if imaginary unit is neither i nor j
    if (!unit) {
      return error.num;
    }

    // Return imaginary coefficient of complex number
    if (plus >= 0) {
      return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ?
        error.num :
        Number(inumber.substring(plus + 1, inumber.length - 1));
    } else {
      return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ?
        error.num :
        -Number(inumber.substring(minus + 1, inumber.length - 1));
    }
  } else {
    if (unit) {
      return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : inumber.substring(0, inumber.length - 1);
    } else {
      return (isNaN(inumber)) ? error.num : 0;
    }
  }
};

exports.IMARGUMENT = function(inumber) {
  // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  // Return error if either coefficient is not a number
  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return error if inumber is equal to zero
  if (x === 0 && y === 0) {
    return error.div0;
  }

  // Return PI/2 if x is equal to zero and y is positive
  if (x === 0 && y > 0) {
    return Math.PI / 2;
  }

  // Return -PI/2 if x is equal to zero and y is negative
  if (x === 0 && y < 0) {
    return -Math.PI / 2;
  }

  // Return zero if x is negative and y is equal to zero
  if (y === 0 && x > 0) {
    return 0;
  }

  // Return zero if x is negative and y is equal to zero
  if (y === 0 && x < 0) {
    return -Math.PI;
  }

  // Return argument of complex number
  if (x > 0) {
    return Math.atan(y / x);
  } else if (x < 0 && y >= 0) {
    return Math.atan(y / x) + Math.PI;
  } else {
    return Math.atan(y / x) - Math.PI;
  }
};

exports.IMCONJUGATE = function(inumber) {
  // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return conjugate of complex number
  return (y !== 0) ? exports.COMPLEX(x, -y, unit) : inumber;
};

exports.IMCOS = function(inumber) {
  // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return cosine of complex number
  return exports.COMPLEX(Math.cos(x) * (Math.exp(y) + Math.exp(-y)) / 2, -Math.sin(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit);
};

exports.IMCOSH = function(inumber) {
  // Lookup real and imaginary coefficients using exports.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return hyperbolic cosine of complex number
  return exports.COMPLEX(Math.cos(y) * (Math.exp(x) + Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) - Math.exp(-x)) / 2, unit);
};

exports.IMCOT = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return cotangent of complex number
  return exports.IMDIV(exports.IMCOS(inumber), exports.IMSIN(inumber));
};

exports.IMDIV = function(inumber1, inumber2) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var a = exports.IMREAL(inumber1);
  var b = exports.IMAGINARY(inumber1);
  var c = exports.IMREAL(inumber2);
  var d = exports.IMAGINARY(inumber2);

  if (utils.anyIsError(a, b, c, d)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit1 = inumber1.substring(inumber1.length - 1);
  var unit2 = inumber2.substring(inumber2.length - 1);
  var unit = 'i';
  if (unit1 === 'j') {
    unit = 'j';
  } else if (unit2 === 'j') {
    unit = 'j';
  }

  // Return error if inumber2 is null
  if (c === 0 && d === 0) {
    return error.num;
  }

  // Return exponential of complex number
  var den = c * c + d * d;
  return exports.COMPLEX((a * c + b * d) / den, (b * c - a * d) / den, unit);
};

exports.IMEXP = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return exponential of complex number
  var e = Math.exp(x);
  return exports.COMPLEX(e * Math.cos(y), e * Math.sin(y), unit);
};

exports.IMLN = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return exponential of complex number
  return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)), Math.atan(y / x), unit);
};

exports.IMLOG10 = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return exponential of complex number
  return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(10), Math.atan(y / x) / Math.log(10), unit);
};

exports.IMLOG2 = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return exponential of complex number
  return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(2), Math.atan(y / x) / Math.log(2), unit);
};

exports.IMPOWER = function(inumber, number) {
  number = utils.parseNumber(number);
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);
  if (utils.anyIsError(number, x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Calculate power of modulus
  var p = Math.pow(exports.IMABS(inumber), number);

  // Calculate argument
  var t = exports.IMARGUMENT(inumber);

  // Return exponential of complex number
  return exports.COMPLEX(p * Math.cos(number * t), p * Math.sin(number * t), unit);
};

exports.IMPRODUCT = function() {
  // Initialize result
  var result = arguments[0];

  if (!arguments.length) {
    return error.value;
  }

  // Loop on all numbers
  for (var i = 1; i < arguments.length; i++) {
    // Lookup coefficients of two complex numbers
    var a = exports.IMREAL(result);
    var b = exports.IMAGINARY(result);
    var c = exports.IMREAL(arguments[i]);
    var d = exports.IMAGINARY(arguments[i]);

    if (utils.anyIsError(a, b, c, d)) {
      return error.value;
    }

    // Complute product of two complex numbers
    result = exports.COMPLEX(a * c - b * d, a * d + b * c);
  }

  // Return product of complex numbers
  return result;
};

exports.IMREAL = function(inumber) {
  if (inumber === undefined || inumber === true || inumber === false) {
    return error.value;
  }

  // Return 0 if inumber is equal to 0
  if (inumber === 0 || inumber === '0') {
    return 0;
  }

  // Handle special cases
  if (['i', '+i', '1i', '+1i', '-i', '-1i', 'j', '+j', '1j', '+1j', '-j', '-1j'].indexOf(inumber) >= 0) {
    return 0;
  }

  // Lookup sign
  var plus = inumber.indexOf('+');
  var minus = inumber.indexOf('-');
  if (plus === 0) {
    plus = inumber.indexOf('+', 1);
  }
  if (minus === 0) {
    minus = inumber.indexOf('-', 1);
  }

  // Lookup imaginary unit
  var last = inumber.substring(inumber.length - 1, inumber.length);
  var unit = (last === 'i' || last === 'j');

  if (plus >= 0 || minus >= 0) {
    // Return error if imaginary unit is neither i nor j
    if (!unit) {
      return error.num;
    }

    // Return real coefficient of complex number
    if (plus >= 0) {
      return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ?
        error.num :
        Number(inumber.substring(0, plus));
    } else {
      return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ?
        error.num :
        Number(inumber.substring(0, minus));
    }
  } else {
    if (unit) {
      return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : 0;
    } else {
      return (isNaN(inumber)) ? error.num : inumber;
    }
  }
};

exports.IMSEC = function(inumber) {
  // Return error if inumber is a logical value
  if (inumber === true || inumber === false) {
    return error.value;
  }

  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return secant of complex number
  return exports.IMDIV('1', exports.IMCOS(inumber));
};

exports.IMSECH = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return hyperbolic secant of complex number
  return exports.IMDIV('1', exports.IMCOSH(inumber));
};

exports.IMSIN = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return sine of complex number
  return exports.COMPLEX(Math.sin(x) * (Math.exp(y) + Math.exp(-y)) / 2, Math.cos(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit);
};

exports.IMSINH = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Return hyperbolic sine of complex number
  return exports.COMPLEX(Math.cos(y) * (Math.exp(x) - Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) + Math.exp(-x)) / 2, unit);
};

exports.IMSQRT = function(inumber) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit = inumber.substring(inumber.length - 1);
  unit = (unit === 'i' || unit === 'j') ? unit : 'i';

  // Calculate power of modulus
  var s = Math.sqrt(exports.IMABS(inumber));

  // Calculate argument
  var t = exports.IMARGUMENT(inumber);

  // Return exponential of complex number
  return exports.COMPLEX(s * Math.cos(t / 2), s * Math.sin(t / 2), unit);
};

exports.IMCSC = function (inumber) {
  // Return error if inumber is a logical value
  if (inumber === true || inumber === false) {
    return error.value;
  }

  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  // Return error if either coefficient is not a number
  if (utils.anyIsError(x, y)) {
    return error.num;
  }

  // Return cosecant of complex number
  return exports.IMDIV('1', exports.IMSIN(inumber));
};

exports.IMCSCH = function (inumber) {
  // Return error if inumber is a logical value
  if (inumber === true || inumber === false) {
    return error.value;
  }

  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  // Return error if either coefficient is not a number
  if (utils.anyIsError(x, y)) {
    return error.num;
  }

  // Return hyperbolic cosecant of complex number
  return exports.IMDIV('1', exports.IMSINH(inumber));
};

exports.IMSUB = function(inumber1, inumber2) {
  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var a = this.IMREAL(inumber1);
  var b = this.IMAGINARY(inumber1);
  var c = this.IMREAL(inumber2);
  var d = this.IMAGINARY(inumber2);

  if (utils.anyIsError(a, b, c, d)) {
    return error.value;
  }

  // Lookup imaginary unit
  var unit1 = inumber1.substring(inumber1.length - 1);
  var unit2 = inumber2.substring(inumber2.length - 1);
  var unit = 'i';
  if (unit1 === 'j') {
    unit = 'j';
  } else if (unit2 === 'j') {
    unit = 'j';
  }

  // Return _ of two complex numbers
  return this.COMPLEX(a - c, b - d, unit);
};

exports.IMSUM = function() {
  if (!arguments.length) {
    return error.value;
  }
  var args = utils.flatten(arguments);

  // Initialize result
  var result = args[0];

  // Loop on all numbers
  for (var i = 1; i < args.length; i++) {
    // Lookup coefficients of two complex numbers
    var a = this.IMREAL(result);
    var b = this.IMAGINARY(result);
    var c = this.IMREAL(args[i]);
    var d = this.IMAGINARY(args[i]);

    if (utils.anyIsError(a, b, c, d)) {
      return error.value;
    }

    // Complute product of two complex numbers
    result = this.COMPLEX(a + c, b + d);
  }

  // Return sum of complex numbers
  return result;
};

exports.IMTAN = function(inumber) {
  // Return error if inumber is a logical value
  if (inumber === true || inumber === false) {
    return error.value;
  }

  // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org]
  var x = exports.IMREAL(inumber);
  var y = exports.IMAGINARY(inumber);

  if (utils.anyIsError(x, y)) {
    return error.value;
  }

  // Return tangent of complex number
  return this.IMDIV(this.IMSIN(inumber), this.IMCOS(inumber));
};

exports.OCT2BIN = function(number, places) {
  // Return error if number is not hexadecimal or contains more than ten characters (10 digits)
  if (!/^[0-7]{1,10}$/.test(number)) {
    return error.num;
  }

  // Check if number is negative
  var negative = (number.length === 10 && number.substring(0, 1) === '7') ? true : false;

  // Convert octal number to decimal
  var decimal = (negative) ? parseInt(number, 8) - 1073741824 : parseInt(number, 8);

  // Return error if number is lower than -512 or greater than 511
  if (decimal < -512 || decimal > 511) {
    return error.num;
  }

  // Ignore places and return a 10-character binary number if number is negative
  if (negative) {
    return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2);
  }

  // Convert decimal number to binary
  var result = decimal.toString(2);

  // Return binary number using the minimum number of characters necessary if places is undefined
  if (typeof places === 'undefined') {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};

exports.OCT2DEC = function(number) {
  // Return error if number is not octal or contains more than ten characters (10 digits)
  if (!/^[0-7]{1,10}$/.test(number)) {
    return error.num;
  }

  // Convert octal number to decimal
  var decimal = parseInt(number, 8);

  // Return decimal number
  return (decimal >= 536870912) ? decimal - 1073741824 : decimal;
};

exports.OCT2HEX = function(number, places) {
  // Return error if number is not octal or contains more than ten characters (10 digits)
  if (!/^[0-7]{1,10}$/.test(number)) {
    return error.num;
  }

  // Convert octal number to decimal
  var decimal = parseInt(number, 8);

  // Ignore places and return a 10-character octal number if number is negative
  if (decimal >= 536870912) {
    return 'ff' + (decimal + 3221225472).toString(16);
  }

  // Convert decimal number to hexadecimal
  var result = decimal.toString(16);

  // Return hexadecimal number using the minimum number of characters necessary if places is undefined
  if (places === undefined) {
    return result;
  } else {
    // Return error if places is nonnumeric
    if (isNaN(places)) {
      return error.value;
    }

    // Return error if places is negative
    if (places < 0) {
      return error.num;
    }

    // Truncate places in case it is not an integer
    places = Math.floor(places);

    // Pad return value with leading 0s (zeros) if necessary (using Underscore.string)
    return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num;
  }
};


/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
var SUPPORTED_FORMULAS = ['ABS', 'ACCRINT', 'ACOS', 'ACOSH', 'ACOT', 'ACOTH', 'ADD', 'AGGREGATE', 'AND', 'ARABIC', 'ARGS2ARRAY', 'ASIN', 'ASINH', 'ATAN', 'ATAN2', 'ATANH', 'AVEDEV', 'AVERAGE', 'AVERAGEA', 'AVERAGEIF', 'AVERAGEIFS', 'BASE', 'BESSELI', 'BESSELJ', 'BESSELK', 'BESSELY', 'BETA.DIST', 'BETA.INV', 'BETADIST', 'BETAINV', 'BIN2DEC', 'BIN2HEX', 'BIN2OCT', 'BINOM.DIST', 'BINOM.DIST.RANGE', 'BINOM.INV', 'BINOMDIST', 'BITAND', 'BITLSHIFT', 'BITOR', 'BITRSHIFT', 'BITXOR', 'CEILING', 'CEILINGMATH', 'CEILINGPRECISE', 'CHAR', 'CHISQ.DIST', 'CHISQ.DIST.RT', 'CHISQ.INV', 'CHISQ.INV.RT', 'CHOOSE', 'CHOOSE', 'CLEAN', 'CODE', 'COLUMN', 'COLUMNS', 'COMBIN', 'COMBINA', 'COMPLEX', 'CONCATENATE', 'CONFIDENCE', 'CONFIDENCE.NORM', 'CONFIDENCE.T', 'CONVERT', 'CORREL', 'COS', 'COSH', 'COT', 'COTH', 'COUNT', 'COUNTA', 'COUNTBLANK', 'COUNTIF', 'COUNTIFS', 'COUNTIN', 'COUNTUNIQUE', 'COVARIANCE.P', 'COVARIANCE.S', 'CSC', 'CSCH', 'CUMIPMT', 'CUMPRINC', 'DATE', 'DATEVALUE', 'DAY', 'DAYS', 'DAYS360', 'DB', 'DDB', 'DEC2BIN', 'DEC2HEX', 'DEC2OCT', 'DECIMAL', 'DEGREES', 'DELTA', 'DEVSQ', 'DIVIDE', 'DOLLARDE', 'DOLLARFR', 'E', 'EDATE', 'EFFECT', 'EOMONTH', 'EQ', 'ERF', 'ERFC', 'EVEN', 'EXACT', 'EXP', 'EXPON.DIST', 'EXPONDIST', 'F.DIST', 'F.DIST.RT', 'F.INV', 'F.INV.RT', 'FACT', 'FACTDOUBLE', 'FALSE', 'FDIST', 'FDISTRT', 'FIND', 'FINV', 'FINVRT', 'FISHER', 'FISHERINV', 'FLATTEN', 'FLOOR', 'FORECAST', 'FREQUENCY', 'FV', 'FVSCHEDULE', 'GAMMA', 'GAMMA.DIST', 'GAMMA.INV', 'GAMMADIST', 'GAMMAINV', 'GAMMALN', 'GAMMALN.PRECISE', 'GAUSS', 'GCD', 'GEOMEAN', 'GESTEP', 'GROWTH', 'GTE', 'HARMEAN', 'HEX2BIN', 'HEX2DEC', 'HEX2OCT', 'HOUR', 'HTML2TEXT', 'HYPGEOM.DIST', 'HYPGEOMDIST', 'IF', 'IMABS', 'IMAGINARY', 'IMARGUMENT', 'IMCONJUGATE', 'IMCOS', 'IMCOSH', 'IMCOT', 'IMCSC', 'IMCSCH', 'IMDIV', 'IMEXP', 'IMLN', 'IMLOG10', 'IMLOG2', 'IMPOWER', 'IMPRODUCT', 'IMREAL', 'IMSEC', 'IMSECH', 'IMSIN', 'IMSINH', 'IMSQRT', 'IMSUB', 'IMSUM', 'IMTAN', 'INT', 'INTERCEPT', 'INTERVAL', 'IPMT', 'IRR', 'ISBINARY', 'ISBLANK', 'ISEVEN', 'ISLOGICAL', 'ISNONTEXT', 'ISNUMBER', 'ISODD', 'ISODD', 'ISOWEEKNUM', 'ISPMT', 'ISTEXT', 'JOIN', 'KURT', 'LARGE', 'LCM', 'LEFT', 'LEN', 'LINEST', 'LN', 'LOG', 'LOG10', 'LOGEST', 'LOGNORM.DIST', 'LOGNORM.INV', 'LOGNORMDIST', 'LOGNORMINV', 'LOWER', 'LT', 'LTE', 'MATCH', 'MAX', 'MAXA', 'MEDIAN', 'MID', 'MIN', 'MINA', 'MINUS', 'MINUTE', 'MIRR', 'MOD', 'MODE.MULT', 'MODE.SNGL', 'MODEMULT', 'MODESNGL', 'MONTH', 'MROUND', 'MULTINOMIAL', 'MULTIPLY', 'NE', 'NEGBINOM.DIST', 'NEGBINOMDIST', 'NETWORKDAYS', 'NOMINAL', 'NORM.DIST', 'NORM.INV', 'NORM.S.DIST', 'NORM.S.INV', 'NORMDIST', 'NORMINV', 'NORMSDIST', 'NORMSINV', 'NOT', 'NOW', 'NPER', 'NPV', 'NUMBERS', 'OCT2BIN', 'OCT2DEC', 'OCT2HEX', 'ODD', 'OR', 'PDURATION', 'PEARSON', 'PERCENTILEEXC', 'PERCENTILEINC', 'PERCENTRANKEXC', 'PERCENTRANKINC', 'PERMUT', 'PERMUTATIONA', 'PHI', 'PI', 'PMT', 'POISSON.DIST', 'POISSONDIST', 'POW', 'POWER', 'PPMT', 'PROB', 'PRODUCT', 'PROPER', 'PV', 'QUARTILE.EXC', 'QUARTILE.INC', 'QUARTILEEXC', 'QUARTILEINC', 'QUOTIENT', 'RADIANS', 'RAND', 'RANDBETWEEN', 'RANK.AVG', 'RANK.EQ', 'RANKAVG', 'RANKEQ', 'RATE', 'REFERENCE', 'REGEXEXTRACT', 'REGEXMATCH', 'REGEXREPLACE', 'REPLACE', 'REPT', 'RIGHT', 'ROMAN', 'ROUND', 'ROUNDDOWN', 'ROUNDUP', 'ROW', 'ROWS', 'RRI', 'RSQ', 'SEARCH', 'SEC', 'SECH', 'SECOND', 'SERIESSUM', 'SIGN', 'SIN', 'SINH', 'SKEW', 'SKEW.P', 'SKEWP', 'SLN', 'SLOPE', 'SMALL', 'SPLIT', 'SPLIT', 'SQRT', 'SQRTPI', 'STANDARDIZE', 'STDEV.P', 'STDEV.S', 'STDEVA', 'STDEVP', 'STDEVPA', 'STDEVS', 'STEYX', 'SUBSTITUTE', 'SUBTOTAL', 'SUM', 'SUMIF', 'SUMIFS', 'SUMPRODUCT', 'SUMSQ', 'SUMX2MY2', 'SUMX2PY2', 'SUMXMY2', 'SWITCH', 'SYD', 'T', 'T.DIST', 'T.DIST.2T', 'T.DIST.RT', 'T.INV', 'T.INV.2T', 'TAN', 'TANH', 'TBILLEQ', 'TBILLPRICE', 'TBILLYIELD', 'TDIST', 'TDIST2T', 'TDISTRT', 'TIME', 'TIMEVALUE', 'TINV', 'TINV2T', 'TODAY', 'TRANSPOSE', 'TREND', 'TRIM', 'TRIMMEAN', 'TRUE', 'TRUNC', 'UNICHAR', 'UNICODE', 'UNIQUE', 'UPPER', 'VAR.P', 'VAR.S', 'VARA', 'VARP', 'VARPA', 'VARS', 'WEEKDAY', 'WEEKNUM', 'WEIBULL.DIST', 'WEIBULLDIST', 'WORKDAY', 'XIRR', 'XNPV', 'XOR', 'YEAR', 'YEARFRAC'];

exports['default'] = SUPPORTED_FORMULAS;

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.rowLabelToIndex = rowLabelToIndex;
exports.rowIndexToLabel = rowIndexToLabel;
exports.columnLabelToIndex = columnLabelToIndex;
exports.columnIndexToLabel = columnIndexToLabel;
exports.extractLabel = extractLabel;
exports.toLabel = toLabel;
/**
 * Convert row label to index.
 *
 * @param {String} label Row label (eq. '1', '5')
 * @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
 */
function rowLabelToIndex(label) {
  var result = parseInt(label, 10);

  if (isNaN(result)) {
    result = -1;
  } else {
    result = Math.max(result - 1, -1);
  }

  return result;
}

/**
 * Convert row index to label.
 *
 * @param {Number} row Row index.
 * @returns {String} Returns row label (eq. '1', '7').
 */
function rowIndexToLabel(row) {
  var result = '';

  if (row >= 0) {
    result = '' + (row + 1);
  }

  return result;
}

var COLUMN_LABEL_BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;

/**
 * Convert column label to index.
 *
 * @param {String} label Column label (eq. 'ABB', 'CNQ')
 * @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
 */
function columnLabelToIndex(label) {
  var result = 0;

  if (typeof label === 'string') {
    label = label.toUpperCase();

    for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
      result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
    }
  }
  --result;

  return result;
}

/**
 * Convert column index to label.
 *
 * @param {Number} column Column index.
 * @returns {String} Returns column label (eq. 'ABB', 'CNQ').
 */
function columnIndexToLabel(column) {
  var result = '';

  while (column >= 0) {
    result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
    column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
  }

  return result.toUpperCase();
}

var LABEL_EXTRACT_REGEXP = /^([$])?([A-Za-z]+)([$])?([0-9]+)$/;

/**
 * Extract cell coordinates.
 *
 * @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
 * @returns {Array} Returns an array of objects.
 */
function extractLabel(label) {
  if (typeof label !== 'string' || !LABEL_EXTRACT_REGEXP.test(label)) {
    return [];
  }

  var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
      columnAbs = _label$toUpperCase$ma[1],
      column = _label$toUpperCase$ma[2],
      rowAbs = _label$toUpperCase$ma[3],
      row = _label$toUpperCase$ma[4];

  return [{
    index: rowLabelToIndex(row),
    label: row,
    isAbsolute: rowAbs === '$'
  }, {
    index: columnLabelToIndex(column),
    label: column,
    isAbsolute: columnAbs === '$'
  }];
}

/**
 * Convert row and column indexes into cell label.
 *
 * @param {Object} row Object with `index` and `isAbsolute` properties.
 * @param {Object} column Object with `index` and `isAbsolute` properties.
 * @returns {String} Returns cell label.
 */
function toLabel(row, column) {
  var rowLabel = (row.isAbsolute ? '$' : '') + rowIndexToLabel(row.index);
  var columnLabel = (column.isAbsolute ? '$' : '') + columnIndexToLabel(column.index);

  return columnLabel + rowLabel;
}

/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.rowLabelToIndex = exports.rowIndexToLabel = exports.columnLabelToIndex = exports.columnIndexToLabel = exports.toLabel = exports.extractLabel = exports.error = exports.Parser = exports.ERROR_VALUE = exports.ERROR_REF = exports.ERROR_NUM = exports.ERROR_NULL = exports.ERROR_NOT_AVAILABLE = exports.ERROR_NAME = exports.ERROR_DIV_ZERO = exports.ERROR = exports.SUPPORTED_FORMULAS = undefined;

var _parser = __webpack_require__(15);

var _parser2 = _interopRequireDefault(_parser);

var _supportedFormulas = __webpack_require__(12);

var _supportedFormulas2 = _interopRequireDefault(_supportedFormulas);

var _error = __webpack_require__(2);

var _error2 = _interopRequireDefault(_error);

var _cell = __webpack_require__(13);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

exports.SUPPORTED_FORMULAS = _supportedFormulas2['default'];
exports.ERROR = _error.ERROR;
exports.ERROR_DIV_ZERO = _error.ERROR_DIV_ZERO;
exports.ERROR_NAME = _error.ERROR_NAME;
exports.ERROR_NOT_AVAILABLE = _error.ERROR_NOT_AVAILABLE;
exports.ERROR_NULL = _error.ERROR_NULL;
exports.ERROR_NUM = _error.ERROR_NUM;
exports.ERROR_REF = _error.ERROR_REF;
exports.ERROR_VALUE = _error.ERROR_VALUE;
exports.Parser = _parser2['default'];
exports.error = _error2['default'];
exports.extractLabel = _cell.extractLabel;
exports.toLabel = _cell.toLabel;
exports.columnIndexToLabel = _cell.columnIndexToLabel;
exports.columnLabelToIndex = _cell.columnLabelToIndex;
exports.rowIndexToLabel = _cell.rowIndexToLabel;
exports.rowLabelToIndex = _cell.rowLabelToIndex;

/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;

var _tinyEmitter = __webpack_require__(16);

var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);

var _evaluateByOperator = __webpack_require__(17);

var _evaluateByOperator2 = _interopRequireDefault(_evaluateByOperator);

var _grammarParser = __webpack_require__(38);

var _string = __webpack_require__(41);

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var _error2 = _interopRequireDefault(_error);

var _cell = __webpack_require__(13);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * @class Parser
 */
var Parser = function (_Emitter) {
  _inherits(Parser, _Emitter);

  function Parser() {
    _classCallCheck(this, Parser);

    var _this = _possibleConstructorReturn(this, _Emitter.call(this));

    _this.parser = new _grammarParser.Parser();
    _this.parser.yy = {
      toNumber: _number.toNumber,
      trimEdges: _string.trimEdges,
      invertNumber: _number.invertNumber,
      throwError: function throwError(errorName) {
        return _this._throwError(errorName);
      },
      callVariable: function callVariable(variable) {
        return _this._callVariable(variable);
      },
      evaluateByOperator: _evaluateByOperator2['default'],
      callFunction: function callFunction(name, params) {
        return _this._callFunction(name, params);
      },
      cellValue: function cellValue(value) {
        return _this._callCellValue(value);
      },
      rangeValue: function rangeValue(start, end) {
        return _this._callRangeValue(start, end);
      }
    };
    _this.variables = Object.create(null);
    _this.functions = Object.create(null);

    _this.setVariable('TRUE', true).setVariable('FALSE', false).setVariable('NULL', null);
    return _this;
  }

  /**
   * Parse formula expression.
   *
   * @param {String} expression to parse.
   * @return {*} Returns an object with tow properties `error` and `result`.
   */


  Parser.prototype.parse = function parse(expression) {
    var result = null;
    var error = null;

    try {
      if (expression === '') {
        result = '';
      } else {
        result = this.parser.parse(expression);
      }
    } catch (ex) {
      var message = (0, _error2['default'])(ex.message);

      if (message) {
        error = message;
      } else {
        error = (0, _error2['default'])(_error.ERROR);
      }
    }

    if (result instanceof Error) {
      error = (0, _error2['default'])(result.message) || (0, _error2['default'])(_error.ERROR);
      result = null;
    }

    return {
      error: error,
      result: result
    };
  };

  /**
   * Set predefined variable name which can be visible while parsing formula expression.
   *
   * @param {String} name Variable name.
   * @param {*} value Variable value.
   * @returns {Parser}
   */


  Parser.prototype.setVariable = function setVariable(name, value) {
    this.variables[name] = value;

    return this;
  };

  /**
   * Get variable name.
   *
   * @param {String} name Variable name.
   * @returns {*}
   */


  Parser.prototype.getVariable = function getVariable(name) {
    return this.variables[name];
  };

  /**
   * Retrieve variable value by its name.
   *
   * @param name Variable name.
   * @returns {*}
   * @private
   */


  Parser.prototype._callVariable = function _callVariable(name) {
    var value = this.getVariable(name);

    this.emit('callVariable', name, function (newValue) {
      if (newValue !== void 0) {
        value = newValue;
      }
    });

    if (value === void 0) {
      throw Error(_error.ERROR_NAME);
    }

    return value;
  };

  /**
   * Set custom function which can be visible while parsing formula expression.
   *
   * @param {String} name Custom function name.
   * @param {Function} fn Custom function.
   * @returns {Parser}
   */


  Parser.prototype.setFunction = function setFunction(name, fn) {
    this.functions[name] = fn;

    return this;
  };

  /**
   * Get custom function.
   *
   * @param {String} name Custom function name.
   * @returns {*}
   */


  Parser.prototype.getFunction = function getFunction(name) {
    return this.functions[name];
  };

  /**
   * Call function with provided params.
   *
   * @param name Function name.
   * @param params Function params.
   * @returns {*}
   * @private
   */


  Parser.prototype._callFunction = function _callFunction(name) {
    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

    var fn = this.getFunction(name);
    var value = void 0;

    if (fn) {
      value = fn(params);
    }

    this.emit('callFunction', name, params, function (newValue) {
      if (newValue !== void 0) {
        value = newValue;
      }
    });

    return value === void 0 ? (0, _evaluateByOperator2['default'])(name, params) : value;
  };

  /**
   * Retrieve value by its label (`B3`, `B$3`, `B$3`, `$B$3`).
   *
   * @param {String} label Coordinates.
   * @returns {*}
   * @private
   */


  Parser.prototype._callCellValue = function _callCellValue(label) {
    label = label.toUpperCase();

    var _extractLabel = (0, _cell.extractLabel)(label),
        row = _extractLabel[0],
        column = _extractLabel[1];

    var value = void 0;

    this.emit('callCellValue', { label: label, row: row, column: column }, function (_value) {
      value = _value;
    });

    return value;
  };

  /**
   * Retrieve value by its label (`B3:A1`, `B$3:A1`, `B$3:$A1`, `$B$3:A$1`).
   *
   * @param {String} startLabel Coordinates of the first cell.
   * @param {String} endLabel Coordinates of the last cell.
   * @returns {Array} Returns an array of mixed values.
   * @private
   */


  Parser.prototype._callRangeValue = function _callRangeValue(startLabel, endLabel) {
    startLabel = startLabel.toUpperCase();
    endLabel = endLabel.toUpperCase();

    var _extractLabel2 = (0, _cell.extractLabel)(startLabel),
        startRow = _extractLabel2[0],
        startColumn = _extractLabel2[1];

    var _extractLabel3 = (0, _cell.extractLabel)(endLabel),
        endRow = _extractLabel3[0],
        endColumn = _extractLabel3[1];

    var startCell = {};
    var endCell = {};

    if (startRow.index <= endRow.index) {
      startCell.row = startRow;
      endCell.row = endRow;
    } else {
      startCell.row = endRow;
      endCell.row = startRow;
    }

    if (startColumn.index <= endColumn.index) {
      startCell.column = startColumn;
      endCell.column = endColumn;
    } else {
      startCell.column = endColumn;
      endCell.column = startColumn;
    }

    startCell.label = (0, _cell.toLabel)(startCell.row, startCell.column);
    endCell.label = (0, _cell.toLabel)(endCell.row, endCell.column);

    var value = [];

    this.emit('callRangeValue', startCell, endCell, function () {
      var _value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

      value = _value;
    });

    return value;
  };

  /**
   * Try to throw error by its name.
   *
   * @param {String} errorName Error name.
   * @returns {String}
   * @private
   */


  Parser.prototype._throwError = function _throwError(errorName) {
    if ((0, _error.isValidStrict)(errorName)) {
      throw Error(errorName);
    }

    throw Error(_error.ERROR);
  };

  return Parser;
}(_tinyEmitter2['default']);

exports['default'] = Parser;

/***/ }),
/* 16 */
/***/ (function(module, exports) {

function E () {
  // Keep this empty so it's easier to inherit from
  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
}

E.prototype = {
  on: function (name, callback, ctx) {
    var e = this.e || (this.e = {});

    (e[name] || (e[name] = [])).push({
      fn: callback,
      ctx: ctx
    });

    return this;
  },

  once: function (name, callback, ctx) {
    var self = this;
    function listener () {
      self.off(name, listener);
      callback.apply(ctx, arguments);
    };

    listener._ = callback
    return this.on(name, listener, ctx);
  },

  emit: function (name) {
    var data = [].slice.call(arguments, 1);
    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
    var i = 0;
    var len = evtArr.length;

    for (i; i < len; i++) {
      evtArr[i].fn.apply(evtArr[i].ctx, data);
    }

    return this;
  },

  off: function (name, callback) {
    var e = this.e || (this.e = {});
    var evts = e[name];
    var liveEvents = [];

    if (evts && callback) {
      for (var i = 0, len = evts.length; i < len; i++) {
        if (evts[i].fn !== callback && evts[i].fn._ !== callback)
          liveEvents.push(evts[i]);
      }
    }

    // Remove event from queue to prevent memory leak
    // Suggested by https://github.com/lazd
    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910

    (liveEvents.length)
      ? e[name] = liveEvents
      : delete e[name];

    return this;
  }
};

module.exports = E;


/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = evaluateByOperator;
exports.registerOperation = registerOperation;

var _add = __webpack_require__(18);

var _add2 = _interopRequireDefault(_add);

var _ampersand = __webpack_require__(19);

var _ampersand2 = _interopRequireDefault(_ampersand);

var _divide = __webpack_require__(20);

var _divide2 = _interopRequireDefault(_divide);

var _equal = __webpack_require__(21);

var _equal2 = _interopRequireDefault(_equal);

var _formulaFunction = __webpack_require__(22);

var _formulaFunction2 = _interopRequireDefault(_formulaFunction);

var _greaterThan = __webpack_require__(30);

var _greaterThan2 = _interopRequireDefault(_greaterThan);

var _greaterThanOrEqual = __webpack_require__(31);

var _greaterThanOrEqual2 = _interopRequireDefault(_greaterThanOrEqual);

var _lessThan = __webpack_require__(32);

var _lessThan2 = _interopRequireDefault(_lessThan);

var _lessThanOrEqual = __webpack_require__(33);

var _lessThanOrEqual2 = _interopRequireDefault(_lessThanOrEqual);

var _minus = __webpack_require__(34);

var _minus2 = _interopRequireDefault(_minus);

var _multiply = __webpack_require__(35);

var _multiply2 = _interopRequireDefault(_multiply);

var _notEqual = __webpack_require__(36);

var _notEqual2 = _interopRequireDefault(_notEqual);

var _power = __webpack_require__(37);

var _power2 = _interopRequireDefault(_power);

var _error = __webpack_require__(2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

/* eslint-disable import/no-named-as-default-member */
var availableOperators = Object.create(null);

/**
 * Evaluate values by operator id.git
 *
 * @param {String} operator Operator id.
 * @param {Array} [params=[]] Arguments to evaluate.
 * @returns {*}
 */
function evaluateByOperator(operator) {
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

  operator = operator.toUpperCase();

  if (!availableOperators[operator]) {
    throw Error(_error.ERROR_NAME);
  }

  return availableOperators[operator].apply(availableOperators, params);
}

/**
 * Register operator.
 *
 * @param {String|Array} symbol Symbol to register.
 * @param {Function} func Logic to register for this symbol.
 */
function registerOperation(symbol, func) {
  if (!Array.isArray(symbol)) {
    symbol = [symbol.toUpperCase()];
  }
  symbol.forEach(function (s) {
    if (func.isFactory) {
      availableOperators[s] = func(s);
    } else {
      availableOperators[s] = func;
    }
  });
}

registerOperation(_add2['default'].SYMBOL, _add2['default']);
registerOperation(_ampersand2['default'].SYMBOL, _ampersand2['default']);
registerOperation(_divide2['default'].SYMBOL, _divide2['default']);
registerOperation(_equal2['default'].SYMBOL, _equal2['default']);
registerOperation(_power2['default'].SYMBOL, _power2['default']);
registerOperation(_formulaFunction2['default'].SYMBOL, _formulaFunction2['default']);
registerOperation(_greaterThan2['default'].SYMBOL, _greaterThan2['default']);
registerOperation(_greaterThanOrEqual2['default'].SYMBOL, _greaterThanOrEqual2['default']);
registerOperation(_lessThan2['default'].SYMBOL, _lessThan2['default']);
registerOperation(_lessThanOrEqual2['default'].SYMBOL, _lessThanOrEqual2['default']);
registerOperation(_multiply2['default'].SYMBOL, _multiply2['default']);
registerOperation(_notEqual2['default'].SYMBOL, _notEqual2['default']);
registerOperation(_minus2['default'].SYMBOL, _minus2['default']);

/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var SYMBOL = exports.SYMBOL = '+';

function func(first) {
  for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    rest[_key - 1] = arguments[_key];
  }

  var result = rest.reduce(function (acc, value) {
    return acc + (0, _number.toNumber)(value);
  }, (0, _number.toNumber)(first));

  if (isNaN(result)) {
    throw Error(_error.ERROR_VALUE);
  }

  return result;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '&';

function func() {
  for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
    params[_key] = arguments[_key];
  }

  return params.reduce(function (acc, value) {
    return acc + value.toString();
  }, '');
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var SYMBOL = exports.SYMBOL = '/';

function func(first) {
  for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    rest[_key - 1] = arguments[_key];
  }

  var result = rest.reduce(function (acc, value) {
    return acc / (0, _number.toNumber)(value);
  }, (0, _number.toNumber)(first));

  if (result === Infinity) {
    throw Error(_error.ERROR_DIV_ZERO);
  }
  if (isNaN(result)) {
    throw Error(_error.ERROR_VALUE);
  }

  return result;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '=';

function func(exp1, exp2) {
  return exp1 === exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _formulajs = __webpack_require__(23);

var formulajs = _interopRequireWildcard(_formulajs);

var _supportedFormulas = __webpack_require__(12);

var _supportedFormulas2 = _interopRequireDefault(_supportedFormulas);

var _error = __webpack_require__(2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

var SYMBOL = exports.SYMBOL = _supportedFormulas2['default'];

function func(symbol) {
  return function __formulaFunction() {
    symbol = symbol.toUpperCase();

    var symbolParts = symbol.split('.');
    var foundFormula = false;
    var result = void 0;

    if (symbolParts.length === 1) {
      if (formulajs[symbolParts[0]]) {
        foundFormula = true;
        result = formulajs[symbolParts[0]].apply(formulajs, arguments);
      }
    } else {
      var length = symbolParts.length;
      var index = 0;
      var nestedFormula = formulajs;

      while (index < length) {
        nestedFormula = nestedFormula[symbolParts[index]];
        index++;

        if (!nestedFormula) {
          nestedFormula = null;
          break;
        }
      }
      if (nestedFormula) {
        foundFormula = true;
        result = nestedFormula.apply(undefined, arguments);
      }
    }

    if (!foundFormula) {
      throw Error(_error.ERROR_NAME);
    }

    return result;
  };
}

func.isFactory = true;
func.SYMBOL = SYMBOL;

/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {

var categories = [
  __webpack_require__(24),
  __webpack_require__(26),
  __webpack_require__(11),
  __webpack_require__(27),
  __webpack_require__(4),
  __webpack_require__(6),
  __webpack_require__(8),
  __webpack_require__(28),
  __webpack_require__(7),
  __webpack_require__(29),
  __webpack_require__(5),
  __webpack_require__(10)
];

for (var c in categories) {
  var category = categories[c];
  for (var f in category) {
    exports[f] = exports[f] || category[f];
  }
}


/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {

var mathTrig = __webpack_require__(4);
var statistical = __webpack_require__(5);
var engineering = __webpack_require__(11);
var dateTime = __webpack_require__(8);

function set(fn, root) {
  if (root) {
    for (var i in root) {
      fn[i] = root[i];
    }
  }

  return fn;
}

exports.BETADIST = statistical.BETA.DIST;
exports.BETAINV = statistical.BETA.INV;
exports.BINOMDIST = statistical.BINOM.DIST;
exports.CEILING = exports.ISOCEILING = set(mathTrig.CEILING.MATH, mathTrig.CEILING);
exports.CEILINGMATH = mathTrig.CEILING.MATH;
exports.CEILINGPRECISE = mathTrig.CEILING.PRECISE;
exports.CHIDIST = statistical.CHISQ.DIST;
exports.CHIDISTRT = statistical.CHISQ.DIST.RT;
exports.CHIINV = statistical.CHISQ.INV;
exports.CHIINVRT = statistical.CHISQ.INV.RT;
exports.CHITEST = statistical.CHISQ.TEST;
exports.CONFIDENCE = set(statistical.CONFIDENCE.NORM, statistical.CONFIDENCE);
exports.COVAR = statistical.COVARIANCE.P;
exports.COVARIANCEP = statistical.COVARIANCE.P;
exports.COVARIANCES = statistical.COVARIANCE.S;
exports.CRITBINOM = statistical.BINOM.INV;
exports.EXPONDIST = statistical.EXPON.DIST;
exports.ERFCPRECISE = engineering.ERFC.PRECISE;
exports.ERFPRECISE = engineering.ERF.PRECISE;
exports.FDIST = statistical.F.DIST;
exports.FDISTRT = statistical.F.DIST.RT;
exports.FINVRT = statistical.F.INV.RT;
exports.FINV = statistical.F.INV;
exports.FLOOR = set(mathTrig.FLOOR.MATH, mathTrig.FLOOR);
exports.FLOORMATH = mathTrig.FLOOR.MATH;
exports.FLOORPRECISE = mathTrig.FLOOR.PRECISE;
exports.FTEST = statistical.F.TEST;
exports.GAMMADIST = statistical.GAMMA.DIST;
exports.GAMMAINV = statistical.GAMMA.INV;
exports.GAMMALNPRECISE = statistical.GAMMALN.PRECISE;
exports.HYPGEOMDIST = statistical.HYPGEOM.DIST;
exports.LOGINV = statistical.LOGNORM.INV;
exports.LOGNORMINV = statistical.LOGNORM.INV;
exports.LOGNORMDIST = statistical.LOGNORM.DIST;
exports.MODE = set(statistical.MODE.SNGL, statistical.MODE);
exports.MODEMULT = statistical.MODE.MULT;
exports.MODESNGL = statistical.MODE.SNGL;
exports.NEGBINOMDIST = statistical.NEGBINOM.DIST;
exports.NETWORKDAYSINTL = dateTime.NETWORKDAYS.INTL;
exports.NORMDIST = statistical.NORM.DIST;
exports.NORMINV = statistical.NORM.INV;
exports.NORMSDIST = statistical.NORM.S.DIST;
exports.NORMSINV = statistical.NORM.S.INV;
exports.PERCENTILE = set(statistical.PERCENTILE.EXC, statistical.PERCENTILE);
exports.PERCENTILEEXC = statistical.PERCENTILE.EXC;
exports.PERCENTILEINC = statistical.PERCENTILE.INC;
exports.PERCENTRANK = set(statistical.PERCENTRANK.INC, statistical.PERCENTRANK);
exports.PERCENTRANKEXC = statistical.PERCENTRANK.EXC;
exports.PERCENTRANKINC = statistical.PERCENTRANK.INC;
exports.POISSON = set(statistical.POISSON.DIST, statistical.POISSON);
exports.POISSONDIST = statistical.POISSON.DIST;
exports.QUARTILE = set(statistical.QUARTILE.INC, statistical.QUARTILE);
exports.QUARTILEEXC = statistical.QUARTILE.EXC;
exports.QUARTILEINC = statistical.QUARTILE.INC;
exports.RANK = set(statistical.RANK.EQ, statistical.RANK);
exports.RANKAVG = statistical.RANK.AVG;
exports.RANKEQ = statistical.RANK.EQ;
exports.SKEWP = statistical.SKEW.P;
exports.STDEV = set(statistical.STDEV.S, statistical.STDEV);
exports.STDEVP = statistical.STDEV.P;
exports.STDEVS = statistical.STDEV.S;
exports.TDIST = statistical.T.DIST;
exports.TDISTRT = statistical.T.DIST.RT;
exports.TINV = statistical.T.INV;
exports.TTEST = statistical.T.TEST;
exports.VAR = set(statistical.VAR.S, statistical.VAR);
exports.VARP = statistical.VAR.P;
exports.VARS = statistical.VAR.S;
exports.WEIBULL = set(statistical.WEIBULL.DIST, statistical.WEIBULL);
exports.WEIBULLDIST = statistical.WEIBULL.DIST;
exports.WORKDAYINTL = dateTime.WORKDAY.INTL;
exports.ZTEST = statistical.Z.TEST;


/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {

var M = Math;
function _horner(arr, v) { return arr.reduce(function(z,w){return v * z + w;},0); };
function _bessel_iter(x, n, f0, f1, sign) {
  if(!sign) sign = -1;
  var tdx = 2 / x, f2;
  if(n === 0) return f0;
  if(n === 1) return f1;
  for(var o = 1; o != n; ++o) {
    f2 = f1 * o * tdx + sign * f0;
    f0 = f1; f1 = f2;
  }
  return f1;
}
function _bessel_wrap(bessel0, bessel1, name, nonzero, sign) {
  return function bessel(x,n) {
    if(n === 0) return bessel0(x);
    if(n === 1) return bessel1(x);
    if(n < 0) throw name + ': Order (' + n + ') must be nonnegative';
    if(nonzero == 1 && x === 0) throw name + ': Undefined when x == 0';
    if(nonzero == 2 && x <= 0) throw name + ': Undefined when x <= 0';
    var b0 = bessel0(x), b1 = bessel1(x);
    return _bessel_iter(x, n, b0, b1, sign);
  };
}
var besselj = (function() {
  var b0_a1a = [57568490574.0,-13362590354.0,651619640.7,-11214424.18,77392.33017,-184.9052456].reverse();
  var b0_a2a = [57568490411.0,1029532985.0,9494680.718,59272.64853,267.8532712,1.0].reverse();
  var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse();
  var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934935152e-7].reverse();
  var W = 0.636619772; // 2 / Math.PI

  function bessel0(x) {
    var a, a1, a2, y = x * x, xx = M.abs(x) - 0.785398164;
    if(M.abs(x) < 8) {
      a1 = _horner(b0_a1a, y);
      a2 = _horner(b0_a2a, y);
      a = a1/a2;
    }
    else {
      y = 64 / y;
      a1 = _horner(b0_a1b, y);
      a2 = _horner(b0_a2b, y);
      a = M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x));
    }
    return a;
  }
  var b1_a1a = [72362614232.0,-7895059235.0,242396853.1,-2972611.439, 15704.48260, -30.16036606].reverse();
  var b1_a2a = [144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0].reverse();
  var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse();
  var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse();
  function bessel1(x) {
    var a, a1, a2, y = x*x, xx = M.abs(x) - 2.356194491;
    if(Math.abs(x)< 8) {
      a1 = x*_horner(b1_a1a, y);
      a2 = _horner(b1_a2a, y);
      a = a1 / a2;
    } else {
      y = 64 / y;
      a1=_horner(b1_a1b, y);
      a2=_horner(b1_a2b, y);
      a=M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x));
      if(x < 0) a = -a;
    }
    return a;
  }
  return function besselj(x, n) {
    n = Math.round(n);
    if(n === 0) return bessel0(M.abs(x));
    if(n === 1) return bessel1(M.abs(x));
    if(n < 0) throw 'BESSELJ: Order (' + n + ') must be nonnegative';
    if(M.abs(x) === 0) return 0;

    var ret, j, tox = 2 / M.abs(x), m, jsum, sum, bjp, bj, bjm;
    if(M.abs(x) > n) {
      ret = _bessel_iter(x, n, bessel0(M.abs(x)), bessel1(M.abs(x)),-1);
    } else {
      m=2*M.floor((n+M.floor(M.sqrt(40*n)))/2);
      jsum=0;
      bjp=ret=sum=0.0;
      bj=1.0;
      for (j=m;j>0;j--) {
        bjm=j*tox*bj-bjp;
        bjp=bj;
        bj=bjm;
        if (M.abs(bj) > 1E10) {
          bj *= 1E-10;
          bjp *= 1E-10;
          ret *= 1E-10;
          sum *= 1E-10;
        }
        if (jsum) sum += bj;
        jsum=!jsum;
        if (j == n) ret=bjp;
      }
      sum=2.0*sum-bj;
      ret /= sum;
    }
    return x < 0 && (n%2) ? -ret : ret;
  };
})();
var bessely = (function() {
  var b0_a1a = [-2957821389.0, 7062834065.0, -512359803.6, 10879881.29, -86327.92757, 228.4622733].reverse();
  var b0_a2a = [40076544269.0, 745249964.8, 7189466.438, 47447.26470, 226.1030244, 1.0].reverse();
  var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse();
  var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934945152e-7].reverse();

  var W = 0.636619772;
  function bessel0(x) {
    var a, a1, a2, y = x * x, xx = x - 0.785398164;
    if(x < 8) {
      a1 = _horner(b0_a1a, y);
      a2 = _horner(b0_a2a, y);
      a = a1/a2 + W * besselj(x,0) * M.log(x);
    } else {
      y = 64 / y;
      a1 = _horner(b0_a1b, y);
      a2 = _horner(b0_a2b, y);
      a = M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);
    }
    return a;
  }

  var b1_a1a = [-0.4900604943e13, 0.1275274390e13, -0.5153438139e11, 0.7349264551e9, -0.4237922726e7, 0.8511937935e4].reverse();
  var b1_a2a = [0.2499580570e14, 0.4244419664e12, 0.3733650367e10, 0.2245904002e8, 0.1020426050e6, 0.3549632885e3, 1].reverse();
  var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse();
  var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse();
  function bessel1(x) {
    var a, a1, a2, y = x*x, xx = x - 2.356194491;
    if(x < 8) {
      a1 = x*_horner(b1_a1a, y);
      a2 = _horner(b1_a2a, y);
      a = a1/a2 + W * (besselj(x,1) * M.log(x) - 1 / x);
    } else {
      y = 64 / y;
      a1=_horner(b1_a1b, y);
      a2=_horner(b1_a2b, y);
      a=M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x);
    }
    return a;
  }

  return _bessel_wrap(bessel0, bessel1, 'BESSELY', 1, -1);
})();
var besseli = (function() {
  var b0_a = [1.0, 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2].reverse();
  var b0_b = [0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2].reverse();
  function bessel0(x) {
    if(x <= 3.75) return _horner(b0_a, x*x/(3.75*3.75));
    return M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b0_b, 3.75/M.abs(x));
  }

  var b1_a = [0.5, 0.87890594, 0.51498869, 0.15084934, 0.2658733e-1, 0.301532e-2, 0.32411e-3].reverse();
  var b1_b = [0.39894228, -0.3988024e-1, -0.362018e-2, 0.163801e-2, -0.1031555e-1, 0.2282967e-1, -0.2895312e-1, 0.1787654e-1, -0.420059e-2].reverse();
  function bessel1(x) {
    if(x < 3.75) return x * _horner(b1_a, x*x/(3.75*3.75));
    return (x < 0 ? -1 : 1) * M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b1_b, 3.75/M.abs(x));
  }

  return function besseli(x, n) {
    n = Math.round(n);
    if(n === 0) return bessel0(x);
    if(n == 1) return bessel1(x);
    if(n < 0) throw 'BESSELI Order (' + n + ') must be nonnegative';
    if(M.abs(x) === 0) return 0;

    var ret, j, tox = 2 / M.abs(x), m, bip, bi, bim;
    m=2*M.round((n+M.round(M.sqrt(40*n)))/2);
    bip=ret=0.0;
    bi=1.0;
    for (j=m;j>0;j--) {
      bim=j*tox*bi + bip;
      bip=bi; bi=bim;
      if (M.abs(bi) > 1E10) {
        bi *= 1E-10;
        bip *= 1E-10;
        ret *= 1E-10;
      }
      if(j == n) ret = bip;
    }
    ret *= besseli(x, 0) / bi;
    return x < 0 && (n%2) ? -ret : ret;
  };

})();

var besselk = (function() {
  var b0_a = [-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1, 0.262698e-2, 0.10750e-3, 0.74e-5].reverse();
  var b0_b = [1.25331414, -0.7832358e-1, 0.2189568e-1, -0.1062446e-1, 0.587872e-2, -0.251540e-2, 0.53208e-3].reverse();
  function bessel0(x) {
    if(x <= 2) return -M.log(x/2)*besseli(x,0) + _horner(b0_a, x*x/4);
    return M.exp(-x)/M.sqrt(x)*_horner(b0_b, 2/x);
  }

  var b1_a = [1.0, 0.15443144, -0.67278579, -0.18156897, -0.1919402e-1, -0.110404e-2, -0.4686e-4].reverse();
  var b1_b = [1.25331414, 0.23498619, -0.3655620e-1, 0.1504268e-1, -0.780353e-2, 0.325614e-2, -0.68245e-3].reverse();
  function bessel1(x) {
    if(x <= 2) return M.log(x/2)*besseli(x,1) + (1/x)*_horner(b1_a, x*x/4);
    return M.exp(-x)/M.sqrt(x)*_horner(b1_b, 2/x);
  }

  return _bessel_wrap(bessel0, bessel1, 'BESSELK', 2, 1);
})();
if(true) {
  exports.besselj = besselj;
  exports.bessely = bessely;
  exports.besseli = besseli;
  exports.besselk = besselk;
}



/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var stats = __webpack_require__(5);
var maths = __webpack_require__(4);
var utils = __webpack_require__(1);

function compact(array) {
  var result = [];

  utils.arrayEach(array, function(value) {
    if (value) {
      result.push(value);
    }
  });

  return result;
}

exports.FINDFIELD = function(database, title) {
  var index = null;

  utils.arrayEach(database, function(value, i) {
    if (value[0] === title) {
      index = i;
      return false;
    }
  });

  // Return error if the input field title is incorrect
  if (index == null) {
    return error.value;
  }

  return index;
};

function findResultIndex(database, criterias) {
  var matches = {};
  for (var i = 1; i < database[0].length; ++i) {
    matches[i] = true;
  }
  var maxCriteriaLength = criterias[0].length;
  for (i = 1; i < criterias.length; ++i) {
    if (criterias[i].length > maxCriteriaLength) {
      maxCriteriaLength = criterias[i].length;
    }
  }

  for (var k = 1; k < database.length; ++k) {
    for (var l = 1; l < database[k].length; ++l) {
      var currentCriteriaResult = false;
      var hasMatchingCriteria   = false;
      for (var j = 0; j < criterias.length; ++j) {
        var criteria = criterias[j];
        if (criteria.length < maxCriteriaLength) {
          continue;
        }

        var criteriaField = criteria[0];
        if (database[k][0] !== criteriaField) {
          continue;
        }
        hasMatchingCriteria = true;
        for (var p = 1; p < criteria.length; ++p) {
          currentCriteriaResult = currentCriteriaResult || eval(database[k][l] + criteria[p]);  // jshint ignore:line
        }
      }
      if (hasMatchingCriteria) {
        matches[l] = matches[l] && currentCriteriaResult;
      }
    }
  }

  var result = [];
  for (var n = 0; n < database[0].length; ++n) {
    if (matches[n]) {
      result.push(n - 1);
    }
  }

  return result;
}

// Database functions
exports.DAVERAGE = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }
  var sum = 0;

  utils.arrayEach(resultIndexes, function(value) {
    sum += targetFields[value];
  });

  return resultIndexes.length === 0 ? error.div0 : sum / resultIndexes.length;
};

exports.DCOUNT = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });

  return stats.COUNT(targetValues);
};

exports.DCOUNTA = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }

  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });

  return stats.COUNTA(targetValues);
};

exports.DGET = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }

  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  // Return error if no record meets the criteria
  if (resultIndexes.length === 0) {
    return error.value;
  }
  // Returns the #NUM! error value because more than one record meets the
  // criteria
  if (resultIndexes.length > 1) {
    return error.num;
  }

  return targetFields[resultIndexes[0]];
};

exports.DMAX = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var maxValue = targetFields[resultIndexes[0]];

  utils.arrayEach(resultIndexes, function(value) {
    if (maxValue < targetFields[value]) {
      maxValue = targetFields[value];
    }
  });

  return maxValue;
};

exports.DMIN = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }

  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var minValue = targetFields[resultIndexes[0]];

  utils.arrayEach(resultIndexes, function(value) {
    if (minValue > targetFields[value]) {
      minValue = targetFields[value];
    }
  });

  return minValue;
};

exports.DPRODUCT = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }

  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });
  targetValues = compact(targetValues);

  var result = 1;

  utils.arrayEach(targetValues, function(value) {
    result *= value;
  });

  return result;
};

exports.DSTDEV = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }
  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });
  targetValues = compact(targetValues);

  return stats.STDEV.S(targetValues);
};

exports.DSTDEVP = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });
  targetValues = compact(targetValues);

  return stats.STDEV.P(targetValues);
};

exports.DSUM = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }

  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });

  return maths.SUM(targetValues);
};

exports.DVAR = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }
  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });

  return stats.VAR.S(targetValues);
};

exports.DVARP = function(database, field, criteria) {
  // Return error if field is not a number and not a string
  if (isNaN(field) && (typeof field !== "string")) {
    return error.value;
  }
  var resultIndexes = findResultIndex(database, criteria);
  var targetFields = [];

  if (typeof field === "string") {
    var index = exports.FINDFIELD(database, field);
    targetFields = utils.rest(database[index]);
  } else {
    targetFields = utils.rest(database[field]);
  }
  var targetValues = [];

  utils.arrayEach(resultIndexes, function(value) {
    targetValues.push(targetFields[value]);
  });

  return stats.VAR.P(targetValues);
};


/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var utils = __webpack_require__(1);
var information = __webpack_require__(7);

exports.AND = function() {
  var args = utils.flatten(arguments);
  var result = true;
  for (var i = 0; i < args.length; i++) {
    if (!args[i]) {
      result = false;
    }
  }
  return result;
};

exports.CHOOSE = function() {
  if (arguments.length < 2) {
    return error.na;
  }

  var index = arguments[0];
  if (index < 1 || index > 254) {
    return error.value;
  }

  if (arguments.length < index + 1) {
    return error.value;
  }

  return arguments[index];
};

exports.FALSE = function() {
  return false;
};

exports.IF = function(test, then_value, otherwise_value) {
  return test ? then_value : otherwise_value;
};

exports.IFERROR = function(value, valueIfError) {
  if (information.ISERROR(value)) {
    return valueIfError;
  }
  return value;
};

exports.IFNA = function(value, value_if_na) {
  return value === error.na ? value_if_na : value;
};

exports.NOT = function(logical) {
  return !logical;
};

exports.OR = function() {
  var args = utils.flatten(arguments);
  var result = false;
  for (var i = 0; i < args.length; i++) {
    if (args[i]) {
      result = true;
    }
  }
  return result;
};

exports.TRUE = function() {
  return true;
};

exports.XOR = function() {
  var args = utils.flatten(arguments);
  var result = 0;
  for (var i = 0; i < args.length; i++) {
    if (args[i]) {
      result++;
    }
  }
  return (Math.floor(Math.abs(result)) & 1) ? true : false;
};

exports.SWITCH = function () {
  var result;

  if (arguments.length > 0)  {
    var targetValue = arguments[0];
    var argc = arguments.length - 1;
    var switchCount = Math.floor(argc / 2);
    var switchSatisfied = false;
    var hasDefaultClause = argc % 2 !== 0;
    var defaultClause = argc % 2 === 0 ? null : arguments[arguments.length - 1];

    if (switchCount) {
      for (var index = 0; index < switchCount; index++) {
        if (targetValue === arguments[index * 2 + 1]) {
          result = arguments[index * 2 + 2];
          switchSatisfied = true;
          break;
        }
      }
    }

    if (!switchSatisfied) {
      result = hasDefaultClause ? defaultClause : error.na;
    }
  } else {
    result = error.value;
  }

  return result;
};


/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var dateTime = __webpack_require__(8);
var utils = __webpack_require__(1);

function validDate(d) {
  return d && d.getTime && !isNaN(d.getTime());
}

function ensureDate(d) {
  return (d instanceof Date)?d:new Date(d);
}

exports.ACCRINT = function(issue, first, settlement, rate, par, frequency, basis) {
  // Return error if either date is invalid
  issue      = ensureDate(issue);
  first      = ensureDate(first);
  settlement = ensureDate(settlement);
  if (!validDate(issue) || !validDate(first) || !validDate(settlement)) {
    return error.value;
  }

  // Return error if either rate or par are lower than or equal to zero
  if (rate <= 0 || par <= 0) {
    return error.num;
  }

  // Return error if frequency is neither 1, 2, or 4
  if ([1, 2, 4].indexOf(frequency) === -1) {
    return error.num;
  }

  // Return error if basis is neither 0, 1, 2, 3, or 4
  if ([0, 1, 2, 3, 4].indexOf(basis) === -1) {
    return error.num;
  }

  // Return error if settlement is before or equal to issue
  if (settlement <= issue) {
    return error.num;
  }

  // Set default values
  par   = par   || 0;
  basis = basis || 0;

  // Compute accrued interest
  return par * rate * dateTime.YEARFRAC(issue, settlement, basis);
};

// TODO
exports.ACCRINTM = function() {
  throw new Error('ACCRINTM is not implemented');
};

// TODO
exports.AMORDEGRC = function() {
  throw new Error('AMORDEGRC is not implemented');
};

// TODO
exports.AMORLINC = function() {
  throw new Error('AMORLINC is not implemented');
};

// TODO
exports.COUPDAYBS = function() {
  throw new Error('COUPDAYBS is not implemented');
};

// TODO
exports.COUPDAYS = function() {
  throw new Error('COUPDAYS is not implemented');
};

// TODO
exports.COUPDAYSNC = function() {
  throw new Error('COUPDAYSNC is not implemented');
};

// TODO
exports.COUPNCD = function() {
  throw new Error('COUPNCD is not implemented');
};

// TODO
exports.COUPNUM = function() {
  throw new Error('COUPNUM is not implemented');
};

// TODO
exports.COUPPCD = function() {
  throw new Error('COUPPCD is not implemented');
};

exports.CUMIPMT = function(rate, periods, value, start, end, type) {
  // Credits: algorithm inspired by Apache OpenOffice
  // Credits: Hannes Stiebitzhofer for the translations of function and variable names
  // Requires exports.FV() and exports.PMT() from exports.js [http://stoic.com/exports/]

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  value = utils.parseNumber(value);
  if (utils.anyIsError(rate, periods, value)) {
    return error.value;
  }

  // Return error if either rate, periods, or value are lower than or equal to zero
  if (rate <= 0 || periods <= 0 || value <= 0) {
    return error.num;
  }

  // Return error if start < 1, end < 1, or start > end
  if (start < 1 || end < 1 || start > end) {
    return error.num;
  }

  // Return error if type is neither 0 nor 1
  if (type !== 0 && type !== 1) {
    return error.num;
  }

  // Compute cumulative interest
  var payment = exports.PMT(rate, periods, value, 0, type);
  var interest = 0;

  if (start === 1) {
    if (type === 0) {
      interest = -value;
      start++;
    }
  }

  for (var i = start; i <= end; i++) {
    if (type === 1) {
      interest += exports.FV(rate, i - 2, payment, value, 1) - payment;
    } else {
      interest += exports.FV(rate, i - 1, payment, value, 0);
    }
  }
  interest *= rate;

  // Return cumulative interest
  return interest;
};

exports.CUMPRINC = function(rate, periods, value, start, end, type) {
  // Credits: algorithm inspired by Apache OpenOffice
  // Credits: Hannes Stiebitzhofer for the translations of function and variable names

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  value = utils.parseNumber(value);
  if (utils.anyIsError(rate, periods, value)) {
    return error.value;
  }

  // Return error if either rate, periods, or value are lower than or equal to zero
  if (rate <= 0 || periods <= 0 || value <= 0) {
    return error.num;
  }

  // Return error if start < 1, end < 1, or start > end
  if (start < 1 || end < 1 || start > end) {
    return error.num;
  }

  // Return error if type is neither 0 nor 1
  if (type !== 0 && type !== 1) {
    return error.num;
  }

  // Compute cumulative principal
  var payment = exports.PMT(rate, periods, value, 0, type);
  var principal = 0;
  if (start === 1) {
    if (type === 0) {
      principal = payment + value * rate;
    } else {
      principal = payment;
    }
    start++;
  }
  for (var i = start; i <= end; i++) {
    if (type > 0) {
      principal += payment - (exports.FV(rate, i - 2, payment, value, 1) - payment) * rate;
    } else {
      principal += payment - exports.FV(rate, i - 1, payment, value, 0) * rate;
    }
  }

  // Return cumulative principal
  return principal;
};

exports.DB = function(cost, salvage, life, period, month) {
  // Initialize month
  month = (month === undefined) ? 12 : month;

  cost = utils.parseNumber(cost);
  salvage = utils.parseNumber(salvage);
  life = utils.parseNumber(life);
  period = utils.parseNumber(period);
  month = utils.parseNumber(month);
  if (utils.anyIsError(cost, salvage, life, period, month)) {
    return error.value;
  }

  // Return error if any of the parameters is negative
  if (cost < 0 || salvage < 0 || life < 0 || period < 0) {
    return error.num;
  }

  // Return error if month is not an integer between 1 and 12
  if ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].indexOf(month) === -1) {
    return error.num;
  }

  // Return error if period is greater than life
  if (period > life) {
    return error.num;
  }

  // Return 0 (zero) if salvage is greater than or equal to cost
  if (salvage >= cost) {
    return 0;
  }

  // Rate is rounded to three decimals places
  var rate = (1 - Math.pow(salvage / cost, 1 / life)).toFixed(3);

  // Compute initial depreciation
  var initial = cost * rate * month / 12;

  // Compute total depreciation
  var total = initial;
  var current = 0;
  var ceiling = (period === life) ? life - 1 : period;
  for (var i = 2; i <= ceiling; i++) {
    current = (cost - total) * rate;
    total += current;
  }

  // Depreciation for the first and last periods are special cases
  if (period === 1) {
    // First period
    return initial;
  } else if (period === life) {
    // Last period
    return (cost - total) * rate;
  } else {
    return current;
  }
};

exports.DDB = function(cost, salvage, life, period, factor) {
  // Initialize factor
  factor = (factor === undefined) ? 2 : factor;

  cost = utils.parseNumber(cost);
  salvage = utils.parseNumber(salvage);
  life = utils.parseNumber(life);
  period = utils.parseNumber(period);
  factor = utils.parseNumber(factor);
  if (utils.anyIsError(cost, salvage, life, period, factor)) {
    return error.value;
  }

  // Return error if any of the parameters is negative or if factor is null
  if (cost < 0 || salvage < 0 || life < 0 || period < 0 || factor <= 0) {
    return error.num;
  }

  // Return error if period is greater than life
  if (period > life) {
    return error.num;
  }

  // Return 0 (zero) if salvage is greater than or equal to cost
  if (salvage >= cost) {
    return 0;
  }

  // Compute depreciation
  var total = 0;
  var current = 0;
  for (var i = 1; i <= period; i++) {
    current = Math.min((cost - total) * (factor / life), (cost - salvage - total));
    total += current;
  }

  // Return depreciation
  return current;
};

// TODO
exports.DISC = function() {
  throw new Error('DISC is not implemented');
};

exports.DOLLARDE = function(dollar, fraction) {
  // Credits: algorithm inspired by Apache OpenOffice

  dollar = utils.parseNumber(dollar);
  fraction = utils.parseNumber(fraction);
  if (utils.anyIsError(dollar, fraction)) {
    return error.value;
  }

  // Return error if fraction is negative
  if (fraction < 0) {
    return error.num;
  }

  // Return error if fraction is greater than or equal to 0 and less than 1
  if (fraction >= 0 && fraction < 1) {
    return error.div0;
  }

  // Truncate fraction if it is not an integer
  fraction = parseInt(fraction, 10);

  // Compute integer part
  var result = parseInt(dollar, 10);

  // Add decimal part
  result += (dollar % 1) * Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN10)) / fraction;

  // Round result
  var power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1);
  result = Math.round(result * power) / power;

  // Return converted dollar price
  return result;
};

exports.DOLLARFR = function(dollar, fraction) {
  // Credits: algorithm inspired by Apache OpenOffice

  dollar = utils.parseNumber(dollar);
  fraction = utils.parseNumber(fraction);
  if (utils.anyIsError(dollar, fraction)) {
    return error.value;
  }

  // Return error if fraction is negative
  if (fraction < 0) {
    return error.num;
  }

  // Return error if fraction is greater than or equal to 0 and less than 1
  if (fraction >= 0 && fraction < 1) {
    return error.div0;
  }

  // Truncate fraction if it is not an integer
  fraction = parseInt(fraction, 10);

  // Compute integer part
  var result = parseInt(dollar, 10);

  // Add decimal part
  result += (dollar % 1) * Math.pow(10, -Math.ceil(Math.log(fraction) / Math.LN10)) * fraction;

  // Return converted dollar price
  return result;
};

// TODO
exports.DURATION = function() {
  throw new Error('DURATION is not implemented');
};

exports.EFFECT = function(rate, periods) {
  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  if (utils.anyIsError(rate, periods)) {
    return error.value;
  }

  // Return error if rate <=0 or periods < 1
  if (rate <= 0 || periods < 1) {
    return error.num;
  }

  // Truncate periods if it is not an integer
  periods = parseInt(periods, 10);

  // Return effective annual interest rate
  return Math.pow(1 + rate / periods, periods) - 1;
};

exports.FV = function(rate, periods, payment, value, type) {
  // Credits: algorithm inspired by Apache OpenOffice

  value = value || 0;
  type = type || 0;

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  payment = utils.parseNumber(payment);
  value = utils.parseNumber(value);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, periods, payment, value, type)) {
    return error.value;
  }

  // Return future value
  var result;
  if (rate === 0) {
    result = value + payment * periods;
  } else {
    var term = Math.pow(1 + rate, periods);
    if (type === 1) {
      result = value * term + payment * (1 + rate) * (term - 1) / rate;
    } else {
      result = value * term + payment * (term - 1) / rate;
    }
  }
  return -result;
};

exports.FVSCHEDULE = function(principal, schedule) {
  principal = utils.parseNumber(principal);
  schedule = utils.parseNumberArray(utils.flatten(schedule));
  if (utils.anyIsError(principal, schedule)) {
    return error.value;
  }

  var n = schedule.length;
  var future = principal;

  // Apply all interests in schedule
  for (var i = 0; i < n; i++) {
    // Apply scheduled interest
    future *= 1 + schedule[i];
  }

  // Return future value
  return future;
};

// TODO
exports.INTRATE = function() {
  throw new Error('INTRATE is not implemented');
};

exports.IPMT = function(rate, period, periods, present, future, type) {
  // Credits: algorithm inspired by Apache OpenOffice

  future = future || 0;
  type = type || 0;

  rate = utils.parseNumber(rate);
  period = utils.parseNumber(period);
  periods = utils.parseNumber(periods);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, period, periods, present, future, type)) {
    return error.value;
  }

  // Compute payment
  var payment = exports.PMT(rate, periods, present, future, type);

  // Compute interest
  var interest;
  if (period === 1) {
    if (type === 1) {
      interest = 0;
    } else {
      interest = -present;
    }
  } else {
    if (type === 1) {
      interest = exports.FV(rate, period - 2, payment, present, 1) - payment;
    } else {
      interest = exports.FV(rate, period - 1, payment, present, 0);
    }
  }

  // Return interest
  return interest * rate;
};

exports.IRR = function(values, guess) {
  // Credits: algorithm inspired by Apache OpenOffice

  guess = guess || 0;

  values = utils.parseNumberArray(utils.flatten(values));
  guess = utils.parseNumber(guess);
  if (utils.anyIsError(values, guess)) {
    return error.value;
  }

  // Calculates the resulting amount
  var irrResult = function(values, dates, rate) {
    var r = rate + 1;
    var result = values[0];
    for (var i = 1; i < values.length; i++) {
      result += values[i] / Math.pow(r, (dates[i] - dates[0]) / 365);
    }
    return result;
  };

  // Calculates the first derivation
  var irrResultDeriv = function(values, dates, rate) {
    var r = rate + 1;
    var result = 0;
    for (var i = 1; i < values.length; i++) {
      var frac = (dates[i] - dates[0]) / 365;
      result -= frac * values[i] / Math.pow(r, frac + 1);
    }
    return result;
  };

  // Initialize dates and check that values contains at least one positive value and one negative value
  var dates = [];
  var positive = false;
  var negative = false;
  for (var i = 0; i < values.length; i++) {
    dates[i] = (i === 0) ? 0 : dates[i - 1] + 365;
    if (values[i] > 0) {
      positive = true;
    }
    if (values[i] < 0) {
      negative = true;
    }
  }

  // Return error if values does not contain at least one positive value and one negative value
  if (!positive || !negative) {
    return error.num;
  }

  // Initialize guess and resultRate
  guess = (guess === undefined) ? 0.1 : guess;
  var resultRate = guess;

  // Set maximum epsilon for end of iteration
  var epsMax = 1e-10;

  // Implement Newton's method
  var newRate, epsRate, resultValue;
  var contLoop = true;
  do {
    resultValue = irrResult(values, dates, resultRate);
    newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);
    epsRate = Math.abs(newRate - resultRate);
    resultRate = newRate;
    contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax);
  } while (contLoop);

  // Return internal rate of return
  return resultRate;
};

exports.ISPMT = function(rate, period, periods, value) {
  rate = utils.parseNumber(rate);
  period = utils.parseNumber(period);
  periods = utils.parseNumber(periods);
  value = utils.parseNumber(value);
  if (utils.anyIsError(rate, period, periods, value)) {
    return error.value;
  }

  // Return interest
  return value * rate * (period / periods - 1);
};

// TODO
exports.MDURATION = function() {
  throw new Error('MDURATION is not implemented');
};

exports.MIRR = function(values, finance_rate, reinvest_rate) {
  values = utils.parseNumberArray(utils.flatten(values));
  finance_rate = utils.parseNumber(finance_rate);
  reinvest_rate = utils.parseNumber(reinvest_rate);
  if (utils.anyIsError(values, finance_rate, reinvest_rate)) {
    return error.value;
  }

  // Initialize number of values
  var n = values.length;

  // Lookup payments (negative values) and incomes (positive values)
  var payments = [];
  var incomes = [];
  for (var i = 0; i < n; i++) {
    if (values[i] < 0) {
      payments.push(values[i]);
    } else {
      incomes.push(values[i]);
    }
  }

  // Return modified internal rate of return
  var num = -exports.NPV(reinvest_rate, incomes) * Math.pow(1 + reinvest_rate, n - 1);
  var den = exports.NPV(finance_rate, payments) * (1 + finance_rate);
  return Math.pow(num / den, 1 / (n - 1)) - 1;
};

exports.NOMINAL = function(rate, periods) {
  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  if (utils.anyIsError(rate, periods)) {
    return error.value;
  }

  // Return error if rate <=0 or periods < 1
  if (rate <= 0 || periods < 1) {
    return error.num;
  }

  // Truncate periods if it is not an integer
  periods = parseInt(periods, 10);

  // Return nominal annual interest rate
  return (Math.pow(rate + 1, 1 / periods) - 1) * periods;
};

exports.NPER = function(rate, payment, present, future, type) {
  type = (type === undefined) ? 0 : type;
  future = (future === undefined) ? 0 : future;

  rate = utils.parseNumber(rate);
  payment = utils.parseNumber(payment);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, payment, present, future, type)) {
    return error.value;
  }

  // Return number of periods
  var num = payment * (1 + rate * type) - future * rate;
  var den = (present * rate + payment * (1 + rate * type));
  return Math.log(num / den) / Math.log(1 + rate);
};

exports.NPV = function() {
  var args = utils.parseNumberArray(utils.flatten(arguments));
  if (args instanceof Error) {
    return args;
  }

  // Lookup rate
  var rate = args[0];

  // Initialize net present value
  var value = 0;

  // Loop on all values
  for (var j = 1; j < args.length; j++) {
    value += args[j] / Math.pow(1 + rate, j);
  }

  // Return net present value
  return value;
};

// TODO
exports.ODDFPRICE = function() {
  throw new Error('ODDFPRICE is not implemented');
};

// TODO
exports.ODDFYIELD = function() {
  throw new Error('ODDFYIELD is not implemented');
};

// TODO
exports.ODDLPRICE = function() {
  throw new Error('ODDLPRICE is not implemented');
};

// TODO
exports.ODDLYIELD = function() {
  throw new Error('ODDLYIELD is not implemented');
};

exports.PDURATION = function(rate, present, future) {
  rate = utils.parseNumber(rate);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  if (utils.anyIsError(rate, present, future)) {
    return error.value;
  }

  // Return error if rate <=0
  if (rate <= 0) {
    return error.num;
  }

  // Return number of periods
  return (Math.log(future) - Math.log(present)) / Math.log(1 + rate);
};

exports.PMT = function(rate, periods, present, future, type) {
  // Credits: algorithm inspired by Apache OpenOffice

  future = future || 0;
  type = type || 0;

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, periods, present, future, type)) {
    return error.value;
  }

  // Return payment
  var result;
  if (rate === 0) {
    result = (present + future) / periods;
  } else {
    var term = Math.pow(1 + rate, periods);
    if (type === 1) {
      result = (future * rate / (term - 1) + present * rate / (1 - 1 / term)) / (1 + rate);
    } else {
      result = future * rate / (term - 1) + present * rate / (1 - 1 / term);
    }
  }
  return -result;
};

exports.PPMT = function(rate, period, periods, present, future, type) {
  future = future || 0;
  type = type || 0;

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, periods, present, future, type)) {
    return error.value;
  }

  return exports.PMT(rate, periods, present, future, type) - exports.IPMT(rate, period, periods, present, future, type);
};

// TODO
exports.PRICE = function() {
  throw new Error('PRICE is not implemented');
};

// TODO
exports.PRICEDISC = function() {
  throw new Error('PRICEDISC is not implemented');
};

// TODO
exports.PRICEMAT = function() {
  throw new Error('PRICEMAT is not implemented');
};

exports.PV = function(rate, periods, payment, future, type) {
  future = future || 0;
  type = type || 0;

  rate = utils.parseNumber(rate);
  periods = utils.parseNumber(periods);
  payment = utils.parseNumber(payment);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  if (utils.anyIsError(rate, periods, payment, future, type)) {
    return error.value;
  }

  // Return present value
  if (rate === 0) {
    return -payment * periods - future;
  } else {
    return (((1 - Math.pow(1 + rate, periods)) / rate) * payment * (1 + rate * type) - future) / Math.pow(1 + rate, periods);
  }
};

exports.RATE = function(periods, payment, present, future, type, guess) {
  // Credits: rabugento

  guess = (guess === undefined) ? 0.01 : guess;
  future = (future === undefined) ? 0 : future;
  type = (type === undefined) ? 0 : type;

  periods = utils.parseNumber(periods);
  payment = utils.parseNumber(payment);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  type = utils.parseNumber(type);
  guess = utils.parseNumber(guess);
  if (utils.anyIsError(periods, payment, present, future, type, guess)) {
    return error.value;
  }

  // Set maximum epsilon for end of iteration
  var epsMax = 1e-10;

  // Set maximum number of iterations
  var iterMax = 50;

  // Implement Newton's method
  var y, y0, y1, x0, x1 = 0,
    f = 0,
    i = 0;
  var rate = guess;
  if (Math.abs(rate) < epsMax) {
    y = present * (1 + periods * rate) + payment * (1 + rate * type) * periods + future;
  } else {
    f = Math.exp(periods * Math.log(1 + rate));
    y = present * f + payment * (1 / rate + type) * (f - 1) + future;
  }
  y0 = present + payment * periods + future;
  y1 = present * f + payment * (1 / rate + type) * (f - 1) + future;
  i = x0 = 0;
  x1 = rate;
  while ((Math.abs(y0 - y1) > epsMax) && (i < iterMax)) {
    rate = (y1 * x0 - y0 * x1) / (y1 - y0);
    x0 = x1;
    x1 = rate;
    if (Math.abs(rate) < epsMax) {
      y = present * (1 + periods * rate) + payment * (1 + rate * type) * periods + future;
    } else {
      f = Math.exp(periods * Math.log(1 + rate));
      y = present * f + payment * (1 / rate + type) * (f - 1) + future;
    }
    y0 = y1;
    y1 = y;
    ++i;
  }
  return rate;
};

// TODO
exports.RECEIVED = function() {
  throw new Error('RECEIVED is not implemented');
};

exports.RRI = function(periods, present, future) {
  periods = utils.parseNumber(periods);
  present = utils.parseNumber(present);
  future = utils.parseNumber(future);
  if (utils.anyIsError(periods, present, future)) {
    return error.value;
  }

  // Return error if periods or present is equal to 0 (zero)
  if (periods === 0 || present === 0) {
    return error.num;
  }

  // Return equivalent interest rate
  return Math.pow(future / present, 1 / periods) - 1;
};

exports.SLN = function(cost, salvage, life) {
  cost = utils.parseNumber(cost);
  salvage = utils.parseNumber(salvage);
  life = utils.parseNumber(life);
  if (utils.anyIsError(cost, salvage, life)) {
    return error.value;
  }

  // Return error if life equal to 0 (zero)
  if (life === 0) {
    return error.num;
  }

  // Return straight-line depreciation
  return (cost - salvage) / life;
};

exports.SYD = function(cost, salvage, life, period) {
  // Return error if any of the parameters is not a number
  cost = utils.parseNumber(cost);
  salvage = utils.parseNumber(salvage);
  life = utils.parseNumber(life);
  period = utils.parseNumber(period);
  if (utils.anyIsError(cost, salvage, life, period)) {
    return error.value;
  }

  // Return error if life equal to 0 (zero)
  if (life === 0) {
    return error.num;
  }

  // Return error if period is lower than 1 or greater than life
  if (period < 1 || period > life) {
    return error.num;
  }

  // Truncate period if it is not an integer
  period = parseInt(period, 10);

  // Return straight-line depreciation
  return ((cost - salvage) * (life - period + 1) * 2) / (life * (life + 1));
};

exports.TBILLEQ = function(settlement, maturity, discount) {
  settlement = utils.parseDate(settlement);
  maturity = utils.parseDate(maturity);
  discount = utils.parseNumber(discount);
  if (utils.anyIsError(settlement, maturity, discount)) {
    return error.value;
  }

  // Return error if discount is lower than or equal to zero
  if (discount <= 0) {
    return error.num;
  }

  // Return error if settlement is greater than maturity
  if (settlement > maturity) {
    return error.num;
  }

  // Return error if maturity is more than one year after settlement
  if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {
    return error.num;
  }

  // Return bond-equivalent yield
  return (365 * discount) / (360 - discount * dateTime.DAYS360(settlement, maturity, false));
};

exports.TBILLPRICE = function(settlement, maturity, discount) {
  settlement = utils.parseDate(settlement);
  maturity = utils.parseDate(maturity);
  discount = utils.parseNumber(discount);
  if (utils.anyIsError(settlement, maturity, discount)) {
    return error.value;
  }

  // Return error if discount is lower than or equal to zero
  if (discount <= 0) {
    return error.num;
  }

  // Return error if settlement is greater than maturity
  if (settlement > maturity) {
    return error.num;
  }

  // Return error if maturity is more than one year after settlement
  if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {
    return error.num;
  }

  // Return bond-equivalent yield
  return 100 * (1 - discount * dateTime.DAYS360(settlement, maturity, false) / 360);
};

exports.TBILLYIELD = function(settlement, maturity, price) {
  settlement = utils.parseDate(settlement);
  maturity = utils.parseDate(maturity);
  price = utils.parseNumber(price);
  if (utils.anyIsError(settlement, maturity, price)) {
    return error.value;
  }

  // Return error if price is lower than or equal to zero
  if (price <= 0) {
    return error.num;
  }

  // Return error if settlement is greater than maturity
  if (settlement > maturity) {
    return error.num;
  }

  // Return error if maturity is more than one year after settlement
  if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) {
    return error.num;
  }

  // Return bond-equivalent yield
  return (100 - price) * 360 / (price * dateTime.DAYS360(settlement, maturity, false));
};

// TODO
exports.VDB = function() {
  throw new Error('VDB is not implemented');
};

// TODO needs better support for date
// exports.XIRR = function(values, dates, guess) {
//   // Credits: algorithm inspired by Apache OpenOffice
//
//   values = utils.parseNumberArray(utils.flatten(values));
//   dates = utils.parseDateArray(utils.flatten(dates));
//   guess = utils.parseNumber(guess);
//
//   if (utils.anyIsError(values, dates, guess)) {
//     return error.value;
//   }
//
//   // Calculates the resulting amount
//   var irrResult = function(values, dates, rate) {
//     var r = rate + 1;
//     var result = values[0];
//     for (var i = 1; i < values.length; i++) {
//       result += values[i] / Math.pow(r, dateTime.DAYS(dates[i], dates[0]) / 365);
//     }
//     return result;
//   };
//
//   // Calculates the first derivation
//   var irrResultDeriv = function(values, dates, rate) {
//     var r = rate + 1;
//     var result = 0;
//     for (var i = 1; i < values.length; i++) {
//       var frac = dateTime.DAYS(dates[i], dates[0]) / 365;
//       result -= frac * values[i] / Math.pow(r, frac + 1);
//     }
//     return result;
//   };
//
//   // Check that values contains at least one positive value and one negative value
//   var positive = false;
//   var negative = false;
//   for (var i = 0; i < values.length; i++) {
//     if (values[i] > 0) {
//       positive = true;
//     }
//     if (values[i] < 0) {
//       negative = true;
//     }
//   }
//
//   // Return error if values does not contain at least one positive value and one negative value
//   if (!positive || !negative) {
//     return error.num;
//   }
//
//   // Initialize guess and resultRate
//   guess = guess || 0.1;
//   var resultRate = guess;
//
//   // Set maximum epsilon for end of iteration
//   var epsMax = 1e-10;
//
//   // Implement Newton's method
//   var newRate, epsRate, resultValue;
//   var contLoop = true;
//   do {
//     resultValue = irrResult(values, dates, resultRate);
//     newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate);
//     epsRate = Math.abs(newRate - resultRate);
//     resultRate = newRate;
//     contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax);
//   } while (contLoop);
//
//   // Return internal rate of return
//   return resultRate;
// };

exports.XNPV = function(rate, values, dates) {
  rate = utils.parseNumber(rate);
  values = utils.parseNumberArray(utils.flatten(values));
  dates = utils.parseDateArray(utils.flatten(dates));
  if (utils.anyIsError(rate, values, dates)) {
    return error.value;
  }

  var result = 0;
  for (var i = 0; i < values.length; i++) {
    result += values[i] / Math.pow(1 + rate, dateTime.DAYS(dates[i], dates[0]) / 365);
  }
  return result;
};

// TODO
exports.YIELD = function() {
  throw new Error('YIELD is not implemented');
};

// TODO
exports.YIELDDISC = function() {
  throw new Error('YIELDDISC is not implemented');
};

// TODO
exports.YIELDMAT = function() {
  throw new Error('YIELDMAT is not implemented');
};


/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {

var error = __webpack_require__(0);
var utils = __webpack_require__(1);

exports.MATCH = function(lookupValue, lookupArray, matchType) {
  if (!lookupValue && !lookupArray) {
    return error.na;
  }

  if (arguments.length === 2) {
    matchType = 1;
  }
  if (!(lookupArray instanceof Array)) {
    return error.na;
  }

  if (matchType !== -1 && matchType !== 0 && matchType !== 1) {
    return error.na;
  }
  var index;
  var indexValue;
  for (var idx = 0; idx < lookupArray.length; idx++) {
    if (matchType === 1) {
      if (lookupArray[idx] === lookupValue) {
        return idx + 1;
      } else if (lookupArray[idx] < lookupValue) {
        if (!indexValue) {
          index = idx + 1;
          indexValue = lookupArray[idx];
        } else if (lookupArray[idx] > indexValue) {
          index = idx + 1;
          indexValue = lookupArray[idx];
        }
      }
    } else if (matchType === 0) {
      if (typeof lookupValue === 'string') {
        lookupValue = lookupValue.replace(/\?/g, '.');
        if (lookupArray[idx].toLowerCase().match(lookupValue.toLowerCase())) {
          return idx + 1;
        }
      } else {
        if (lookupArray[idx] === lookupValue) {
          return idx + 1;
        }
      }
    } else if (matchType === -1) {
      if (lookupArray[idx] === lookupValue) {
        return idx + 1;
      } else if (lookupArray[idx] > lookupValue) {
        if (!indexValue) {
          index = idx + 1;
          indexValue = lookupArray[idx];
        } else if (lookupArray[idx] < indexValue) {
          index = idx + 1;
          indexValue = lookupArray[idx];
        }
      }
    }
  }

  return index ? index : error.na;
};

exports.VLOOKUP = function (needle, table, index, rangeLookup) {
  if (!needle || !table || !index) {
    return error.na;
  }

  rangeLookup = rangeLookup || false;
  for (var i = 0; i < table.length; i++) {
    var row = table[i];
    if ((!rangeLookup && row[0] === needle) ||
      ((row[0] === needle) ||
        (rangeLookup && typeof row[0] === "string" && row[0].toLowerCase().indexOf(needle.toLowerCase()) !== -1))) {
      return (index < (row.length + 1) ? row[index - 1] : error.ref);
    }
  }

  return error.na;
};

exports.HLOOKUP = function (needle, table, index, rangeLookup) {
  if (!needle || !table || !index) {
    return error.na;
  }

  rangeLookup = rangeLookup || false;

  var transposedTable = utils.transpose(table);

  for (var i = 0; i < transposedTable.length; i++) {
    var row = transposedTable[i];
    if ((!rangeLookup && row[0] === needle) ||
      ((row[0] === needle) ||
        (rangeLookup && typeof row[0] === "string" && row[0].toLowerCase().indexOf(needle.toLowerCase()) !== -1))) {
      return (index < (row.length + 1) ? row[index - 1] : error.ref);
    }
  }

  return error.na;
};


/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '>';

function func(exp1, exp2) {
  return exp1 > exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '>=';

function func(exp1, exp2) {
  return exp1 >= exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '<';

function func(exp1, exp2) {
  return exp1 < exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '<=';

function func(exp1, exp2) {
  return exp1 <= exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var SYMBOL = exports.SYMBOL = '-';

function func(first) {
  for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    rest[_key - 1] = arguments[_key];
  }

  var result = rest.reduce(function (acc, value) {
    return acc - (0, _number.toNumber)(value);
  }, (0, _number.toNumber)(first));

  if (isNaN(result)) {
    throw Error(_error.ERROR_VALUE);
  }

  return result;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var SYMBOL = exports.SYMBOL = '*';

function func(first) {
  for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    rest[_key - 1] = arguments[_key];
  }

  var result = rest.reduce(function (acc, value) {
    return acc * (0, _number.toNumber)(value);
  }, (0, _number.toNumber)(first));

  if (isNaN(result)) {
    throw Error(_error.ERROR_VALUE);
  }

  return result;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports['default'] = func;
var SYMBOL = exports.SYMBOL = '<>';

function func(exp1, exp2) {
  return exp1 !== exp2;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.SYMBOL = undefined;
exports['default'] = func;

var _number = __webpack_require__(3);

var _error = __webpack_require__(2);

var SYMBOL = exports.SYMBOL = '^';

function func(exp1, exp2) {
  var result = Math.pow((0, _number.toNumber)(exp1), (0, _number.toNumber)(exp2));

  if (isNaN(result)) {
    throw Error(_error.ERROR_VALUE);
  }

  return result;
}

func.SYMBOL = SYMBOL;

/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(module, process) {/* parser generated by jison 0.4.17 */
/*
  Returns a Parser object of the following structure:

  Parser: {
    yy: {}
  }

  Parser.prototype: {
    yy: {},
    trace: function(),
    symbols_: {associative list: name ==> number},
    terminals_: {associative list: number ==> name},
    productions_: [...],
    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
    table: [...],
    defaultActions: {...},
    parseError: function(str, hash),
    parse: function(input),

    lexer: {
        EOF: 1,
        parseError: function(str, hash),
        setInput: function(input),
        input: function(),
        unput: function(str),
        more: function(),
        less: function(n),
        pastInput: function(),
        upcomingInput: function(),
        showPosition: function(),
        test_match: function(regex_match_array, rule_index),
        next: function(),
        lex: function(),
        begin: function(condition),
        popState: function(),
        _currentRules: function(),
        topState: function(),
        pushState: function(condition),

        options: {
            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
        },

        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
        rules: [...],
        conditions: {associative list: name ==> set},
    }
  }


  token location info (@$, _$, etc.): {
    first_line: n,
    last_line: n,
    first_column: n,
    last_column: n,
    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
  }


  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
    text:        (matched text)
    token:       (the produced terminal token, if any)
    line:        (yylineno)
  }
  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
    loc:         (yylloc)
    expected:    (string describing the set of expected tokens)
    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
  }
*/
var grammarParser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,8],$V2=[1,6],$V3=[1,7],$V4=[1,9],$V5=[1,14],$V6=[1,15],$V7=[1,16],$V8=[1,12],$V9=[1,13],$Va=[1,17],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,22],$Vf=[1,23],$Vg=[1,24],$Vh=[1,25],$Vi=[1,26],$Vj=[1,27],$Vk=[1,28],$Vl=[5,9,10,11,13,14,15,16,17,18,19,20,29,30],$Vm=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,32],$Vn=[5,9,10,11,13,14,15,16,17,18,19,20,29,30,34],$Vo=[5,10,11,13,14,15,16,17,29,30],$Vp=[5,10,13,14,15,16,29,30],$Vq=[5,10,11,13,14,15,16,17,18,19,29,30],$Vr=[13,29,30];
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"expressions":3,"expression":4,"EOF":5,"variableSequence":6,"number":7,"STRING":8,"&":9,"=":10,"+":11,"(":12,")":13,"<":14,">":15,"NOT":16,"-":17,"*":18,"/":19,"^":20,"FUNCTION":21,"expseq":22,"cell":23,"ABSOLUTE_CELL":24,"RELATIVE_CELL":25,"MIXED_CELL":26,":":27,"ARRAY":28,";":29,",":30,"VARIABLE":31,"DECIMAL":32,"NUMBER":33,"%":34,"ERROR":35,"$accept":0,"$end":1},
terminals_: {5:"EOF",8:"STRING",9:"&",10:"=",11:"+",12:"(",13:")",14:"<",15:">",16:"NOT",17:"-",18:"*",19:"/",20:"^",21:"FUNCTION",24:"ABSOLUTE_CELL",25:"RELATIVE_CELL",26:"MIXED_CELL",27:":",28:"ARRAY",29:";",30:",",31:"VARIABLE",32:"DECIMAL",33:"NUMBER",34:"%",35:"ERROR"},
productions_: [0,[3,2],[4,1],[4,1],[4,1],[4,3],[4,3],[4,3],[4,3],[4,4],[4,4],[4,4],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,2],[4,2],[4,3],[4,4],[4,1],[4,1],[4,2],[23,1],[23,1],[23,1],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[23,3],[22,1],[22,1],[22,3],[22,3],[6,1],[6,3],[7,1],[7,3],[7,2],[2,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */

var $0 = $$.length - 1;
switch (yystate) {
case 1:

      return $$[$0-1];

break;
case 2:

      this.$ = yy.callVariable($$[$0][0]);

break;
case 3:

      this.$ = yy.toNumber($$[$0]);

break;
case 4:

      this.$ = yy.trimEdges($$[$0]);

break;
case 5:

      this.$ = yy.evaluateByOperator('&', [$$[$0-2], $$[$0]]);

break;
case 6:

      this.$ = yy.evaluateByOperator('=', [$$[$0-2], $$[$0]]);

break;
case 7:

      this.$ = yy.evaluateByOperator('+', [$$[$0-2], $$[$0]]);

break;
case 8:

      this.$ = $$[$0-1];

break;
case 9:

      this.$ = yy.evaluateByOperator('<=', [$$[$0-3], $$[$0]]);

break;
case 10:

      this.$ = yy.evaluateByOperator('>=', [$$[$0-3], $$[$0]]);

break;
case 11:

      this.$ = yy.evaluateByOperator('<>', [$$[$0-3], $$[$0]]);

break;
case 12:

      this.$ = yy.evaluateByOperator('NOT', [$$[$0-2], $$[$0]]);

break;
case 13:

      this.$ = yy.evaluateByOperator('>', [$$[$0-2], $$[$0]]);

break;
case 14:

      this.$ = yy.evaluateByOperator('<', [$$[$0-2], $$[$0]]);

break;
case 15:

      this.$ = yy.evaluateByOperator('-', [$$[$0-2], $$[$0]]);

break;
case 16:

      this.$ = yy.evaluateByOperator('*', [$$[$0-2], $$[$0]]);

break;
case 17:

      this.$ = yy.evaluateByOperator('/', [$$[$0-2], $$[$0]]);

break;
case 18:

      this.$ = yy.evaluateByOperator('^', [$$[$0-2], $$[$0]]);

break;
case 19:

      var n1 = yy.invertNumber($$[$0]);

      this.$ = n1;

      if (isNaN(this.$)) {
          this.$ = 0;
      }

break;
case 20:

      var n1 = yy.toNumber($$[$0]);

      this.$ = n1;

      if (isNaN(this.$)) {
          this.$ = 0;
      }

break;
case 21:

      this.$ = yy.callFunction($$[$0-2]);

break;
case 22:

      this.$ = yy.callFunction($$[$0-3], $$[$0-1]);

break;
case 26: case 27: case 28:

      this.$ = yy.cellValue($$[$0]);

break;
case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37:

      this.$ = yy.rangeValue($$[$0-2], $$[$0]);

break;
case 38: case 42:

      this.$ = [$$[$0]];

break;
case 39:

      var result = [];
      var arr = eval("[" + yytext + "]");

      arr.forEach(function(item) {
        result.push(item);
      });

      this.$ = result;

break;
case 40: case 41:

      $$[$0-2].push($$[$0]);
      this.$ = $$[$0-2];

break;
case 43:

      this.$ = (Array.isArray($$[$0-2]) ? $$[$0-2] : [$$[$0-2]]);
      this.$.push($$[$0]);

break;
case 44:

      this.$ = $$[$0];

break;
case 45:

      this.$ = ($$[$0-2] + '.' + $$[$0]) * 1;

break;
case 46:

      this.$ = $$[$0-1] * 0.01;

break;
case 47:

      this.$ = yy.throwError($$[$0]);

break;
}
},
table: [{2:11,3:1,4:2,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{1:[3]},{5:[1,18],9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vl,[2,2],{32:[1,29]}),o($Vl,[2,3],{34:[1,30]}),o($Vl,[2,4]),{2:11,4:31,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:32,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:33,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{12:[1,34]},o($Vl,[2,23]),o($Vl,[2,24],{2:35,35:$Va}),o($Vm,[2,42]),o($Vn,[2,44],{32:[1,36]}),o($Vl,[2,26],{27:[1,37]}),o($Vl,[2,27],{27:[1,38]}),o($Vl,[2,28],{27:[1,39]}),o([5,9,10,11,13,14,15,16,17,18,19,20,29,30,35],[2,47]),{1:[2,1]},{2:11,4:40,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:41,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:42,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:45,6:3,7:4,8:$V0,10:[1,43],11:$V1,12:$V2,15:[1,44],17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:47,6:3,7:4,8:$V0,10:[1,46],11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:48,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:49,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:50,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:51,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:52,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{31:[1,53]},o($Vn,[2,46]),{9:$Vb,10:$Vc,11:$Vd,13:[1,54],14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk},o($Vo,[2,19],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,20],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:57,6:3,7:4,8:$V0,11:$V1,12:$V2,13:[1,55],17:$V3,21:$V4,22:56,23:10,24:$V5,25:$V6,26:$V7,28:[1,58],31:$V8,33:$V9,35:$Va},o($Vl,[2,25]),{33:[1,59]},{24:[1,60],25:[1,61],26:[1,62]},{24:[1,63],25:[1,64],26:[1,65]},{24:[1,66],25:[1,67],26:[1,68]},o($Vl,[2,5]),o([5,10,13,29,30],[2,6],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,7],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:69,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:70,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,14],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),{2:11,4:71,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vp,[2,13],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o([5,10,13,16,29,30],[2,12],{9:$Vb,11:$Vd,14:$Ve,15:$Vf,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vo,[2,15],{9:$Vb,18:$Vi,19:$Vj,20:$Vk}),o($Vq,[2,16],{9:$Vb,20:$Vk}),o($Vq,[2,17],{9:$Vb,20:$Vk}),o([5,10,11,13,14,15,16,17,18,19,20,29,30],[2,18],{9:$Vb}),o($Vm,[2,43]),o($Vl,[2,8]),o($Vl,[2,21]),{13:[1,72],29:[1,73],30:[1,74]},o($Vr,[2,38],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,39]),o($Vn,[2,45]),o($Vl,[2,29]),o($Vl,[2,30]),o($Vl,[2,31]),o($Vl,[2,32]),o($Vl,[2,33]),o($Vl,[2,34]),o($Vl,[2,35]),o($Vl,[2,36]),o($Vl,[2,37]),o($Vp,[2,9],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,11],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vp,[2,10],{9:$Vb,11:$Vd,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vl,[2,22]),{2:11,4:75,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},{2:11,4:76,6:3,7:4,8:$V0,11:$V1,12:$V2,17:$V3,21:$V4,23:10,24:$V5,25:$V6,26:$V7,31:$V8,33:$V9,35:$Va},o($Vr,[2,40],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk}),o($Vr,[2,41],{9:$Vb,10:$Vc,11:$Vd,14:$Ve,15:$Vf,16:$Vg,17:$Vh,18:$Vi,19:$Vj,20:$Vk})],
defaultActions: {18:[2,1]},
parseError: function parseError(str, hash) {
    if (hash.recoverable) {
        this.trace(str);
    } else {
        function _parseError (msg, hash) {
            this.message = msg;
            this.hash = hash;
        }
        _parseError.prototype = Error;

        throw new _parseError(str, hash);
    }
},
parse: function parse(input) {
    var self = this,
        stack = [0],
        tstack = [], // token stack
        vstack = [null], // semantic value stack
        lstack = [], // location stack
        table = this.table,
        yytext = '',
        yylineno = 0,
        yyleng = 0,
        recovering = 0,
        TERROR = 2,
        EOF = 1;

    var args = lstack.slice.call(arguments, 1);

    //this.reductionCount = this.shiftCount = 0;

    var lexer = Object.create(this.lexer);
    var sharedState = { yy: {} };
    // copy state
    for (var k in this.yy) {
      if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
        sharedState.yy[k] = this.yy[k];
      }
    }

    lexer.setInput(input, sharedState.yy);
    sharedState.yy.lexer = lexer;
    sharedState.yy.parser = this;
    if (typeof lexer.yylloc == 'undefined') {
        lexer.yylloc = {};
    }
    var yyloc = lexer.yylloc;
    lstack.push(yyloc);

    var ranges = lexer.options && lexer.options.ranges;

    if (typeof sharedState.yy.parseError === 'function') {
        this.parseError = sharedState.yy.parseError;
    } else {
        this.parseError = Object.getPrototypeOf(this).parseError;
    }

    function popStack (n) {
        stack.length = stack.length - 2 * n;
        vstack.length = vstack.length - n;
        lstack.length = lstack.length - n;
    }

    var lex = function () {
        var token;
        token = lexer.lex() || EOF;
        // if token isn't its numeric value, convert
        if (typeof token !== 'number') {
            token = self.symbols_[token] || token;
        }
        return token;
    }

    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
    while (true) {
        // retreive state number from top of stack
        state = stack[stack.length - 1];

        // use default actions if available
        if (this.defaultActions[state]) {
            action = this.defaultActions[state];
        } else {
            if (symbol === null || typeof symbol == 'undefined') {
                symbol = lex();
            }
            // read action for current state and first input
            action = table[state] && table[state][symbol];
        }

        // handle parse error
        if (typeof action === 'undefined' || !action.length || !action[0]) {
            var error_rule_depth;
            var errStr = '';

            // Return the rule stack depth where the nearest error rule can be found.
            // Return FALSE when no error recovery rule was found.
            function locateNearestErrorRecoveryRule(state) {
                var stack_probe = stack.length - 1;
                var depth = 0;

                // try to recover from error
                for(;;) {
                    // check for error recovery rule in this state
                    if ((TERROR.toString()) in table[state]) {
                        return depth;
                    }
                    if (state === 0 || stack_probe < 2) {
                        return false; // No suitable error recovery rule available.
                    }
                    stack_probe -= 2; // popStack(1): [symbol, action]
                    state = stack[stack_probe];
                    ++depth;
                }
            }

            if (!recovering) {
                // first see if there's any chance at hitting an error recovery rule:
                error_rule_depth = locateNearestErrorRecoveryRule(state);

                // Report error
                expected = [];
                for (p in table[state]) {
                    if (this.terminals_[p] && p > TERROR) {
                        expected.push("'"+this.terminals_[p]+"'");
                    }
                }
                if (lexer.showPosition) {
                    errStr = 'Parse error on line '+(yylineno+1)+":\n"+lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol)+ "'";
                } else {
                    errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
                                  (symbol == EOF ? "end of input" :
                                              ("'"+(this.terminals_[symbol] || symbol)+"'"));
                }
                this.parseError(errStr, {
                    text: lexer.match,
                    token: this.terminals_[symbol] || symbol,
                    line: lexer.yylineno,
                    loc: yyloc,
                    expected: expected,
                    recoverable: (error_rule_depth !== false)
                });
            } else if (preErrorSymbol !== EOF) {
                error_rule_depth = locateNearestErrorRecoveryRule(state);
            }

            // just recovered from another error
            if (recovering == 3) {
                if (symbol === EOF || preErrorSymbol === EOF) {
                    throw new Error(errStr || 'Parsing halted while starting to recover from another error.');
                }

                // discard current lookahead and grab another
                yyleng = lexer.yyleng;
                yytext = lexer.yytext;
                yylineno = lexer.yylineno;
                yyloc = lexer.yylloc;
                symbol = lex();
            }

            // try to recover from error
            if (error_rule_depth === false) {
                throw new Error(errStr || 'Parsing halted. No suitable error recovery rule available.');
            }
            popStack(error_rule_depth);

            preErrorSymbol = (symbol == TERROR ? null : symbol); // save the lookahead token
            symbol = TERROR;         // insert generic error symbol as new lookahead
            state = stack[stack.length-1];
            action = table[state] && table[state][TERROR];
            recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
        }

        // this shouldn't happen, unless resolve defaults are off
        if (action[0] instanceof Array && action.length > 1) {
            throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
        }

        switch (action[0]) {
            case 1: // shift
                //this.shiftCount++;

                stack.push(symbol);
                vstack.push(lexer.yytext);
                lstack.push(lexer.yylloc);
                stack.push(action[1]); // push state
                symbol = null;
                if (!preErrorSymbol) { // normal execution/no error
                    yyleng = lexer.yyleng;
                    yytext = lexer.yytext;
                    yylineno = lexer.yylineno;
                    yyloc = lexer.yylloc;
                    if (recovering > 0) {
                        recovering--;
                    }
                } else {
                    // error just occurred, resume old lookahead f/ before error
                    symbol = preErrorSymbol;
                    preErrorSymbol = null;
                }
                break;

            case 2:
                // reduce
                //this.reductionCount++;

                len = this.productions_[action[1]][1];

                // perform semantic action
                yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
                // default location, uses first token for firsts, last for lasts
                yyval._$ = {
                    first_line: lstack[lstack.length-(len||1)].first_line,
                    last_line: lstack[lstack.length-1].last_line,
                    first_column: lstack[lstack.length-(len||1)].first_column,
                    last_column: lstack[lstack.length-1].last_column
                };
                if (ranges) {
                  yyval._$.range = [lstack[lstack.length-(len||1)].range[0], lstack[lstack.length-1].range[1]];
                }
                r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));

                if (typeof r !== 'undefined') {
                    return r;
                }

                // pop off stack
                if (len) {
                    stack = stack.slice(0,-1*len*2);
                    vstack = vstack.slice(0, -1*len);
                    lstack = lstack.slice(0, -1*len);
                }

                stack.push(this.productions_[action[1]][0]);    // push nonterminal (reduce)
                vstack.push(yyval.$);
                lstack.push(yyval._$);
                // goto new state = table[STATE][NONTERMINAL]
                newState = table[stack[stack.length-2]][stack[stack.length-1]];
                stack.push(newState);
                break;

            case 3:
                // accept
                return true;
        }

    }

    return true;
}};

/* generated by jison-lex 0.3.4 */
var lexer = (function(){
var lexer = ({

EOF:1,

parseError:function parseError(str, hash) {
        if (this.yy.parser) {
            this.yy.parser.parseError(str, hash);
        } else {
            throw new Error(str);
        }
    },

// resets the lexer, sets new input
setInput:function (input, yy) {
        this.yy = yy || this.yy || {};
        this._input = input;
        this._more = this._backtrack = this.done = false;
        this.yylineno = this.yyleng = 0;
        this.yytext = this.matched = this.match = '';
        this.conditionStack = ['INITIAL'];
        this.yylloc = {
            first_line: 1,
            first_column: 0,
            last_line: 1,
            last_column: 0
        };
        if (this.options.ranges) {
            this.yylloc.range = [0,0];
        }
        this.offset = 0;
        return this;
    },

// consumes and returns one char from the input
input:function () {
        var ch = this._input[0];
        this.yytext += ch;
        this.yyleng++;
        this.offset++;
        this.match += ch;
        this.matched += ch;
        var lines = ch.match(/(?:\r\n?|\n).*/g);
        if (lines) {
            this.yylineno++;
            this.yylloc.last_line++;
        } else {
            this.yylloc.last_column++;
        }
        if (this.options.ranges) {
            this.yylloc.range[1]++;
        }

        this._input = this._input.slice(1);
        return ch;
    },

// unshifts one char (or a string) into the input
unput:function (ch) {
        var len = ch.length;
        var lines = ch.split(/(?:\r\n?|\n)/g);

        this._input = ch + this._input;
        this.yytext = this.yytext.substr(0, this.yytext.length - len);
        //this.yyleng -= len;
        this.offset -= len;
        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
        this.match = this.match.substr(0, this.match.length - 1);
        this.matched = this.matched.substr(0, this.matched.length - 1);

        if (lines.length - 1) {
            this.yylineno -= lines.length - 1;
        }
        var r = this.yylloc.range;

        this.yylloc = {
            first_line: this.yylloc.first_line,
            last_line: this.yylineno + 1,
            first_column: this.yylloc.first_column,
            last_column: lines ?
                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
              this.yylloc.first_column - len
        };

        if (this.options.ranges) {
            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
        }
        this.yyleng = this.yytext.length;
        return this;
    },

// When called from action, caches matched text and appends it on next action
more:function () {
        this._more = true;
        return this;
    },

// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject:function () {
        if (this.options.backtrack_lexer) {
            this._backtrack = true;
        } else {
            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
                text: "",
                token: null,
                line: this.yylineno
            });

        }
        return this;
    },

// retain first n characters of the match
less:function (n) {
        this.unput(this.match.slice(n));
    },

// displays already matched input, i.e. for error messages
pastInput:function () {
        var past = this.matched.substr(0, this.matched.length - this.match.length);
        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
    },

// displays upcoming input, i.e. for error messages
upcomingInput:function () {
        var next = this.match;
        if (next.length < 20) {
            next += this._input.substr(0, 20-next.length);
        }
        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
    },

// displays the character position where the lexing error occurred, i.e. for error messages
showPosition:function () {
        var pre = this.pastInput();
        var c = new Array(pre.length + 1).join("-");
        return pre + this.upcomingInput() + "\n" + c + "^";
    },

// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function (match, indexed_rule) {
        var token,
            lines,
            backup;

        if (this.options.backtrack_lexer) {
            // save context
            backup = {
                yylineno: this.yylineno,
                yylloc: {
                    first_line: this.yylloc.first_line,
                    last_line: this.last_line,
                    first_column: this.yylloc.first_column,
                    last_column: this.yylloc.last_column
                },
                yytext: this.yytext,
                match: this.match,
                matches: this.matches,
                matched: this.matched,
                yyleng: this.yyleng,
                offset: this.offset,
                _more: this._more,
                _input: this._input,
                yy: this.yy,
                conditionStack: this.conditionStack.slice(0),
                done: this.done
            };
            if (this.options.ranges) {
                backup.yylloc.range = this.yylloc.range.slice(0);
            }
        }

        lines = match[0].match(/(?:\r\n?|\n).*/g);
        if (lines) {
            this.yylineno += lines.length;
        }
        this.yylloc = {
            first_line: this.yylloc.last_line,
            last_line: this.yylineno + 1,
            first_column: this.yylloc.last_column,
            last_column: lines ?
                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
                         this.yylloc.last_column + match[0].length
        };
        this.yytext += match[0];
        this.match += match[0];
        this.matches = match;
        this.yyleng = this.yytext.length;
        if (this.options.ranges) {
            this.yylloc.range = [this.offset, this.offset += this.yyleng];
        }
        this._more = false;
        this._backtrack = false;
        this._input = this._input.slice(match[0].length);
        this.matched += match[0];
        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
        if (this.done && this._input) {
            this.done = false;
        }
        if (token) {
            return token;
        } else if (this._backtrack) {
            // recover context
            for (var k in backup) {
                this[k] = backup[k];
            }
            return false; // rule action called reject() implying the next rule should be tested instead.
        }
        return false;
    },

// return next match in input
next:function () {
        if (this.done) {
            return this.EOF;
        }
        if (!this._input) {
            this.done = true;
        }

        var token,
            match,
            tempMatch,
            index;
        if (!this._more) {
            this.yytext = '';
            this.match = '';
        }
        var rules = this._currentRules();
        for (var i = 0; i < rules.length; i++) {
            tempMatch = this._input.match(this.rules[rules[i]]);
            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
                match = tempMatch;
                index = i;
                if (this.options.backtrack_lexer) {
                    token = this.test_match(tempMatch, rules[i]);
                    if (token !== false) {
                        return token;
                    } else if (this._backtrack) {
                        match = false;
                        continue; // rule action called reject() implying a rule MISmatch.
                    } else {
                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
                        return false;
                    }
                } else if (!this.options.flex) {
                    break;
                }
            }
        }
        if (match) {
            token = this.test_match(match, rules[index]);
            if (token !== false) {
                return token;
            }
            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
            return false;
        }
        if (this._input === "") {
            return this.EOF;
        } else {
            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
                text: "",
                token: null,
                line: this.yylineno
            });
        }
    },

// return next match that has a token
lex:function lex() {
        var r = this.next();
        if (r) {
            return r;
        } else {
            return this.lex();
        }
    },

// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin(condition) {
        this.conditionStack.push(condition);
    },

// pop the previously active lexer condition state off the condition stack
popState:function popState() {
        var n = this.conditionStack.length - 1;
        if (n > 0) {
            return this.conditionStack.pop();
        } else {
            return this.conditionStack[0];
        }
    },

// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules() {
        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
        } else {
            return this.conditions["INITIAL"].rules;
        }
    },

// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState(n) {
        n = this.conditionStack.length - 1 - Math.abs(n || 0);
        if (n >= 0) {
            return this.conditionStack[n];
        } else {
            return "INITIAL";
        }
    },

// alias for begin(condition)
pushState:function pushState(condition) {
        this.begin(condition);
    },

// return the number of states currently on the stack
stateStackSize:function stateStackSize() {
        return this.conditionStack.length;
    },
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 8;
break;
case 2:return 8;
break;
case 3:return 21;
break;
case 4:return 35;
break;
case 5:return 24;
break;
case 6:return 26;
break;
case 7:return 26;
break;
case 8:return 25;
break;
case 9:return 21;
break;
case 10:return 31;
break;
case 11:return 31;
break;
case 12:return 33;
break;
case 13:return 28;
break;
case 14:return 9;
break;
case 15:return ' ';
break;
case 16:return 32;
break;
case 17:return 27;
break;
case 18:return 29;
break;
case 19:return 30;
break;
case 20:return 18;
break;
case 21:return 19;
break;
case 22:return 17;
break;
case 23:return 11;
break;
case 24:return 20;
break;
case 25:return 12;
break;
case 26:return 13;
break;
case 27:return 15;
break;
case 28:return 14;
break;
case 29:return 16;
break;
case 30:return '"';
break;
case 31:return "'";
break;
case 32:return "!";
break;
case 33:return 10;
break;
case 34:return 34;
break;
case 35:return '#';
break;
case 36:return 5;
break;
}
},
rules: [/^(?:\s+)/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9\.]+(?=[(]))/,/^(?:#[A-Z0-9\/]+(!|\?)?)/,/^(?:\$[A-Za-z]+\$[0-9]+)/,/^(?:\$[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z]+\$[0-9]+)/,/^(?:[A-Za-z]+[0-9]+)/,/^(?:[A-Za-z\.]+(?=[(]))/,/^(?:[A-Za-z]{1,}[A-Za-z_0-9]+)/,/^(?:[A-Za-z_]+)/,/^(?:[0-9]+)/,/^(?:\[(.*)?\])/,/^(?:&)/,/^(?: )/,/^(?:[.])/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\/)/,/^(?:-)/,/^(?:\+)/,/^(?:\^)/,/^(?:\()/,/^(?:\))/,/^(?:>)/,/^(?:<)/,/^(?:NOT\b)/,/^(?:")/,/^(?:')/,/^(?:!)/,/^(?:=)/,/^(?:%)/,/^(?:[#])/,/^(?:$)/],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"inclusive":true}}
});
return lexer;
})();
parser.lexer = lexer;
function Parser () {
  this.yy = {};
}
Parser.prototype = parser;parser.Parser = Parser;
return new Parser;
})();


if (true) {
exports.parser = grammarParser;
exports.Parser = grammarParser.Parser;
exports.parse = function () { return grammarParser.parse.apply(grammarParser, arguments); };
if (typeof module !== 'undefined' && __webpack_require__.c[__webpack_require__.s] === module) {
  exports.main(process.argv.slice(1));
}
}

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(39)(module), __webpack_require__(40)))

/***/ }),
/* 39 */
/***/ (function(module, exports) {

module.exports = function(module) {
	if(!module.webpackPolyfill) {
		module.deprecate = function() {};
		module.paths = [];
		// module.parent = undefined by default
		if(!module.children) module.children = [];
		Object.defineProperty(module, "loaded", {
			enumerable: true,
			get: function() {
				return module.l;
			}
		});
		Object.defineProperty(module, "id", {
			enumerable: true,
			get: function() {
				return module.i;
			}
		});
		module.webpackPolyfill = 1;
	}
	return module;
};


/***/ }),
/* 40 */
/***/ (function(module, exports) {

// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };


/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.trimEdges = trimEdges;
/* eslint-disable import/prefer-default-export */
/**
 * Trim value by cutting character starting from the beginning and ending at the same time.
 *
 * @param {String} string String to trimming.
 * @param {Number} [margin=1] Number of character to cut.
 * @returns {String}
 */
function trimEdges(string) {
  var margin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;

  string = string.substring(margin, string.length - margin);

  return string;
}

/***/ })
/******/ ]);
});

/***/ }),
/* 112 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(131);

__webpack_require__(37);

__webpack_require__(46);

__webpack_require__(138);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _hotFormulaParser = __webpack_require__(111);

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _utils = __webpack_require__(84);

var BARE_CELL_STRICT_REGEX = /^\$?[A-Z]+\$?\d+$/;
var BARE_CELL_REGEX = /\$?[A-Z]+\$?\d+/;
var CELL_REGEX = /(?:[^0-9A-Z$: ]|^)\s*(\$?[A-Z]+\$?\d+)\s*(?![0-9A-Z_: ])/g;
var RANGE_REGEX = /\$?[A-Z]+\$?\d+\s*:\s*\$?[A-Z]+\$?\d+/g;
var CELL_AND_RANGE_REGEX = /((?:[^0-9A-Z$: ]|^)\s*(\$?[A-Z]+\$?\d+)\s*(?![0-9A-Z_: ]))|(\$?[A-Z]+\$?\d+\s*:\s*\$?[A-Z]+\$?\d+)/g;
/**
 * Component adds an ability to parse and modify formula expressions. It is designed for translating cell
 * coordinates and cell ranges in any direction. By default, component translates only relative coordinates but this
 * behavior can be overwritten by passing custom modifier which controls translating process.
 *
 * @class ExpressionModifier
 * @util
 */

var ExpressionModifier =
/*#__PURE__*/
function () {
  function ExpressionModifier(expression) {
    (0, _classCallCheck2.default)(this, ExpressionModifier);

    /**
     * Formula expression to modify.
     *
     * @type {String}
     */
    this.expression = '';
    /**
     * Extracted cells and cells ranges.
     *
     * @type {Array}
     */

    this.cells = [];
    /**
     * Function which can modify default behaviour of how cells and cell ranges will be translated.
     *
     * @type {null|Function}
     */

    this.customModifier = null;

    if (typeof expression === 'string') {
      this.setExpression(expression);
    }
  }
  /**
   * Set formula expression to modify.
   *
   * @param {String} expression Formula expression to process.
   * @returns {ExpressionModifier}
   */


  (0, _createClass2.default)(ExpressionModifier, [{
    key: "setExpression",
    value: function setExpression(expression) {
      this.cells.length = 0;
      this.expression = (0, _utils.toUpperCaseFormula)(expression);

      this._extractCells();

      this._extractCellsRange();

      return this;
    }
    /**
     * Set function which can modify default behavior of how cells and cell ranges will be translated.
     * The passed function will be called with 4 arguments:
     *  - cell, A cell object with structure
     *            like this: {start: {row, column}, end: {row, column}, origLabel, type: 'cell|range', refError, toLabel: () => {}}
     *  - axis, Type of currently processing axis ('row' or 'column')
     *  - delta, Number as distance to translate. Can be positive or negative.
     *  - startFromIndex, Base index which translation will be applied from.
     *
     * the function must return an array with 3 items, where:
     *  [
     *    deltaStart, Number as a delta to translate first part of coordinates.
     *    deltaEnd,   Number as a delta to translate second part of coordinates (if cell range is modified).
     *    refError,   Defines an error which refers to the situation when translated cell overcrossed the data boundary.
     *  ]
     *
     *
     * @param {Function} customModifier Function with custom logic.
     */

  }, {
    key: "useCustomModifier",
    value: function useCustomModifier(customModifier) {
      this.customModifier = customModifier;
    }
    /**
     * Translate formula expression cells.
     *
     * @param {Object} delta Distance to move in proper direction.
     * @param {Object} [startFrom] Coordinates which translation will be applied from.
     * @returns {ExpressionModifier}
     */

  }, {
    key: "translate",
    value: function translate(_ref) {
      var _this = this;

      var deltaRow = _ref.row,
          deltaColumn = _ref.column;
      var startFrom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      (0, _array.arrayEach)(this.cells, function (cell) {
        if (deltaRow !== null && deltaRow !== void 0) {
          _this._translateCell(cell, 'row', deltaRow, startFrom.row);
        }

        if (deltaColumn !== null && deltaColumn !== void 0) {
          _this._translateCell(cell, 'column', deltaColumn, startFrom.column);
        }
      });
      return this;
    }
    /**
     * Translate object into string representation.
     *
     * @returns {String}
     */

  }, {
    key: "toString",
    value: function toString() {
      var _this2 = this;

      var expression = this.expression.replace(CELL_AND_RANGE_REGEX, function (match, p1, p2) {
        var isSingleCell = match.indexOf(':') === -1;
        var result = match;
        var cellLabel = match;
        var translatedCellLabel = null;

        if (isSingleCell) {
          cellLabel = BARE_CELL_STRICT_REGEX.test(p1) ? p1 : p2;
        }

        var cell = _this2._searchCell(cellLabel);

        if (cell) {
          translatedCellLabel = cell.refError ? (0, _hotFormulaParser.error)(_hotFormulaParser.ERROR_REF) : cell.toLabel();

          if (isSingleCell) {
            result = match.replace(cellLabel, translatedCellLabel);
          } else {
            result = translatedCellLabel;
          }
        }

        return result;
      });

      if (!expression.startsWith('=')) {
        expression = "=".concat(expression);
      }

      return expression;
    }
    /**
     * Translate single cell.
     *
     * @param {Object} cell Cell object.
     * @param {String} axis Axis to modify.
     * @param {Number} delta Distance to move.
     * @param {Number} [startFromIndex] Base index which translation will be applied from.
     * @private
     */

  }, {
    key: "_translateCell",
    value: function _translateCell(cell, axis, delta, startFromIndex) {
      var start = cell.start,
          end = cell.end;
      var startIndex = start[axis].index;
      var endIndex = end[axis].index;
      var deltaStart = delta;
      var deltaEnd = delta;
      var refError = false;

      if (this.customModifier) {
        var _this$customModifier = this.customModifier(cell, axis, delta, startFromIndex);

        var _this$customModifier2 = (0, _slicedToArray2.default)(_this$customModifier, 3);

        deltaStart = _this$customModifier2[0];
        deltaEnd = _this$customModifier2[1];
        refError = _this$customModifier2[2];
      } else {
        // By default only relative cells are translated, if meets absolute reset deltas to 0
        if (start[axis].isAbsolute) {
          deltaStart = 0;
        }

        if (end[axis].isAbsolute) {
          deltaEnd = 0;
        }
      }

      if (deltaStart && !refError) {
        if (startIndex + deltaStart < 0) {
          refError = true;
        }

        start[axis].index = Math.max(startIndex + deltaStart, 0);
      }

      if (deltaEnd && !refError) {
        if (endIndex + deltaEnd < 0) {
          refError = true;
        }

        end[axis].index = Math.max(endIndex + deltaEnd, 0);
      }

      if (refError) {
        cell.refError = true;
      }
    }
    /**
     * Extract all cells from the formula expression.
     *
     * @private
     */

  }, {
    key: "_extractCells",
    value: function _extractCells() {
      var _this3 = this;

      var matches = this.expression.match(CELL_REGEX);

      if (!matches) {
        return;
      }

      (0, _array.arrayEach)(matches, function (coord) {
        var cellCoords = coord.match(BARE_CELL_REGEX);

        if (!cellCoords) {
          return;
        }

        var _extractLabel = (0, _hotFormulaParser.extractLabel)(cellCoords[0]),
            _extractLabel2 = (0, _slicedToArray2.default)(_extractLabel, 2),
            row = _extractLabel2[0],
            column = _extractLabel2[1];

        _this3.cells.push(_this3._createCell({
          row: row,
          column: column
        }, {
          row: row,
          column: column
        }, cellCoords[0]));
      });
    }
    /**
     * Extract all cells range from the formula expression.
     *
     * @private
     */

  }, {
    key: "_extractCellsRange",
    value: function _extractCellsRange() {
      var _this4 = this;

      var matches = this.expression.match(RANGE_REGEX);

      if (!matches) {
        return;
      }

      (0, _array.arrayEach)(matches, function (match) {
        var _match$split = match.split(':'),
            _match$split2 = (0, _slicedToArray2.default)(_match$split, 2),
            start = _match$split2[0],
            end = _match$split2[1];

        var _extractLabel3 = (0, _hotFormulaParser.extractLabel)(start),
            _extractLabel4 = (0, _slicedToArray2.default)(_extractLabel3, 2),
            startRow = _extractLabel4[0],
            startColumn = _extractLabel4[1];

        var _extractLabel5 = (0, _hotFormulaParser.extractLabel)(end),
            _extractLabel6 = (0, _slicedToArray2.default)(_extractLabel5, 2),
            endRow = _extractLabel6[0],
            endColumn = _extractLabel6[1];

        var startCell = {
          row: startRow,
          column: startColumn
        };
        var endCell = {
          row: endRow,
          column: endColumn
        };

        _this4.cells.push(_this4._createCell(startCell, endCell, match));
      });
    }
    /**
     * Search cell by its label.
     *
     * @param {String} label Cell label eq. `B4` or `$B$6`.
     * @returns {Object|null}
     * @private
     */

  }, {
    key: "_searchCell",
    value: function _searchCell(label) {
      var _arrayFilter = (0, _array.arrayFilter)(this.cells, function (cellMeta) {
        return cellMeta.origLabel === label;
      }),
          _arrayFilter2 = (0, _slicedToArray2.default)(_arrayFilter, 1),
          cell = _arrayFilter2[0];

      return cell || null;
    }
    /**
     * Create object cell.
     *
     * @param {Object} start Start coordinates (top-left).
     * @param {Object} end End coordinates (bottom-right).
     * @param {String} label Original label name.
     * @returns {Object}
     * @private
     */

  }, {
    key: "_createCell",
    value: function _createCell(start, end, label) {
      return {
        start: start,
        end: end,
        origLabel: label,
        type: label.indexOf(':') === -1 ? 'cell' : 'range',
        refError: false,
        toLabel: function toLabel() {
          var newLabel = (0, _hotFormulaParser.toLabel)(this.start.row, this.start.column);

          if (this.type === 'range') {
            newLabel += ":".concat((0, _hotFormulaParser.toLabel)(this.end.row, this.end.column));
          }

          return newLabel;
        }
      };
    }
  }]);
  return ExpressionModifier;
}();

(0, _object.mixin)(ExpressionModifier, _localHooks.default);
var _default = ExpressionModifier;
exports.default = _default;

/***/ }),
/* 113 */
/***/ (function(module, exports, __webpack_require__) {

// fallback for non-array-like ES3 and non-enumerable old V8 strings
var fails = __webpack_require__(29);
var classof = __webpack_require__(77);
var split = ''.split;

module.exports = fails(function () {
  // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
  // eslint-disable-next-line no-prototype-builtins
  return !Object('z').propertyIsEnumerable(0);
}) ? function (it) {
  return classof(it) == 'String' ? split.call(it, '') : Object(it);
} : Object;


/***/ }),
/* 114 */
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__(86);
var max = Math.max;
var min = Math.min;

// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(length, length).
module.exports = function (index, length) {
  var integer = toInteger(index);
  return integer < 0 ? max(integer + length, 0) : min(integer, length);
};


/***/ }),
/* 115 */
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__(52);
var propertyIsEnumerableModule = __webpack_require__(95);
var createPropertyDescriptor = __webpack_require__(96);
var toIndexedObject = __webpack_require__(69);
var toPrimitive = __webpack_require__(97);
var has = __webpack_require__(47);
var IE8_DOM_DEFINE = __webpack_require__(176);
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

exports.f = DESCRIPTORS ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
  O = toIndexedObject(O);
  P = toPrimitive(P, true);
  if (IE8_DOM_DEFINE) try {
    return nativeGetOwnPropertyDescriptor(O, P);
  } catch (e) { /* empty */ }
  if (has(O, P)) return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]);
};


/***/ }),
/* 116 */
/***/ (function(module, exports) {

module.exports = false;


/***/ }),
/* 117 */
/***/ (function(module, exports, __webpack_require__) {

var shared = __webpack_require__(98)('keys');
var uid = __webpack_require__(118);

module.exports = function (key) {
  return shared[key] || (shared[key] = uid(key));
};


/***/ }),
/* 118 */
/***/ (function(module, exports) {

var id = 0;
var postfix = Math.random();

module.exports = function (key) {
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + postfix).toString(36));
};


/***/ }),
/* 119 */
/***/ (function(module, exports) {

exports.f = Object.getOwnPropertySymbols;


/***/ }),
/* 120 */
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__(29);
var replacement = /#|\.prototype\./;

var isForced = function (feature, detection) {
  var value = data[normalize(feature)];
  return value == POLYFILL ? true
    : value == NATIVE ? false
    : typeof detection == 'function' ? fails(detection)
    : !!detection;
};

var normalize = isForced.normalize = function (string) {
  return String(string).replace(replacement, '.').toLowerCase();
};

var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';

module.exports = isForced;


/***/ }),
/* 121 */
/***/ (function(module, exports, __webpack_require__) {

var UNSCOPABLES = __webpack_require__(35)('unscopables');
var create = __webpack_require__(99);
var hide = __webpack_require__(61);
var ArrayPrototype = Array.prototype;

// Array.prototype[@@unscopables]
// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
if (ArrayPrototype[UNSCOPABLES] == undefined) {
  hide(ArrayPrototype, UNSCOPABLES, create(null));
}

// add a key to Array.prototype[@@unscopables]
module.exports = function (key) {
  ArrayPrototype[UNSCOPABLES][key] = true;
};


/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {

var defineProperty = __webpack_require__(49).f;
var has = __webpack_require__(47);
var TO_STRING_TAG = __webpack_require__(35)('toStringTag');

module.exports = function (it, TAG, STATIC) {
  if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
    defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG });
  }
};


/***/ }),
/* 123 */
/***/ (function(module, exports, __webpack_require__) {

var METADATA = __webpack_require__(118)('meta');
var FREEZING = __webpack_require__(515);
var isObject = __webpack_require__(42);
var has = __webpack_require__(47);
var defineProperty = __webpack_require__(49).f;
var id = 0;

var isExtensible = Object.isExtensible || function () {
  return true;
};

var setMetadata = function (it) {
  defineProperty(it, METADATA, { value: {
    objectID: 'O' + ++id, // object ID
    weakData: {}          // weak collections IDs
  } });
};

var fastKey = function (it, create) {
  // return a primitive with prefix
  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  if (!has(it, METADATA)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return 'F';
    // not necessary to add metadata
    if (!create) return 'E';
    // add missing metadata
    setMetadata(it);
  // return object ID
  } return it[METADATA].objectID;
};

var getWeakData = function (it, create) {
  if (!has(it, METADATA)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return true;
    // not necessary to add metadata
    if (!create) return false;
    // add missing metadata
    setMetadata(it);
  // return the store of weak collections IDs
  } return it[METADATA].weakData;
};

// add metadata on freeze-family methods calling
var onFreeze = function (it) {
  if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
  return it;
};

var meta = module.exports = {
  REQUIRED: false,
  fastKey: fastKey,
  getWeakData: getWeakData,
  onFreeze: onFreeze
};

__webpack_require__(94)[METADATA] = true;


/***/ }),
/* 124 */
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__(77);

// `IsArray` abstract operation
// https://tc39.github.io/ecma262/#sec-isarray
module.exports = Array.isArray || function isArray(arg) {
  return classof(arg) == 'Array';
};


/***/ }),
/* 125 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global = __webpack_require__(32);
var isForced = __webpack_require__(120);
var $export = __webpack_require__(22);
var redefine = __webpack_require__(65);
var InternalMetadataModule = __webpack_require__(123);
var iterate = __webpack_require__(149);
var anInstance = __webpack_require__(148);
var isObject = __webpack_require__(42);
var fails = __webpack_require__(29);
var checkCorrectnessOfIteration = __webpack_require__(190);
var setToStringTag = __webpack_require__(122);
var inheritIfRequired = __webpack_require__(152);

module.exports = function (CONSTRUCTOR_NAME, wrapper, common, IS_MAP, IS_WEAK) {
  var NativeConstructor = global[CONSTRUCTOR_NAME];
  var NativePrototype = NativeConstructor && NativeConstructor.prototype;
  var Constructor = NativeConstructor;
  var ADDER = IS_MAP ? 'set' : 'add';
  var exported = {};

  var fixMethod = function (KEY) {
    var nativeMethod = NativePrototype[KEY];
    redefine(NativePrototype, KEY,
      KEY == 'add' ? function add(a) {
        nativeMethod.call(this, a === 0 ? 0 : a);
        return this;
      } : KEY == 'delete' ? function (a) {
        return IS_WEAK && !isObject(a) ? false : nativeMethod.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a) {
        return IS_WEAK && !isObject(a) ? undefined : nativeMethod.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a) {
        return IS_WEAK && !isObject(a) ? false : nativeMethod.call(this, a === 0 ? 0 : a);
      } : function set(a, b) {
        nativeMethod.call(this, a === 0 ? 0 : a, b);
        return this;
      }
    );
  };

  // eslint-disable-next-line max-len
  if (isForced(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {
    new NativeConstructor().entries().next();
  })))) {
    // create collection constructor
    Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);
    InternalMetadataModule.REQUIRED = true;
  } else if (isForced(CONSTRUCTOR_NAME, true)) {
    var instance = new Constructor();
    // early implementations not supports chaining
    var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
    // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
    var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
    // most early implementations doesn't supports iterables, most modern - not close it correctly
    // eslint-disable-next-line no-new
    var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });
    // for early implementations -0 and +0 not the same
    var BUGGY_ZERO = !IS_WEAK && fails(function () {
      // V8 ~ Chromium 42- fails only with 5+ elements
      var $instance = new NativeConstructor();
      var index = 5;
      while (index--) $instance[ADDER](index, index);
      return !$instance.has(-0);
    });

    if (!ACCEPT_ITERABLES) {
      Constructor = wrapper(function (target, iterable) {
        anInstance(target, Constructor, CONSTRUCTOR_NAME);
        var that = inheritIfRequired(new NativeConstructor(), target, Constructor);
        if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);
        return that;
      });
      Constructor.prototype = NativePrototype;
      NativePrototype.constructor = Constructor;
    }

    if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }

    if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);

    // weak collections should not contains .clear method
    if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;
  }

  exported[CONSTRUCTOR_NAME] = Constructor;
  $export({ global: true, forced: Constructor != NativeConstructor }, exported);

  setToStringTag(Constructor, CONSTRUCTOR_NAME);

  if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);

  return Constructor;
};


/***/ }),
/* 126 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var fails = __webpack_require__(29);

module.exports = function (METHOD_NAME, argument) {
  var method = [][METHOD_NAME];
  return !method || !fails(function () {
    // eslint-disable-next-line no-useless-call
    method.call(null, argument || function () { throw Error(); }, 1);
  });
};


/***/ }),
/* 127 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toPrimitive = __webpack_require__(97);
var definePropertyModule = __webpack_require__(49);
var createPropertyDescriptor = __webpack_require__(96);

module.exports = function (object, key, value) {
  var propertyKey = toPrimitive(key);
  if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value));
  else object[propertyKey] = value;
};


/***/ }),
/* 128 */
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__(77);
var regexpExec = __webpack_require__(156);

// `RegExpExec` abstract operation
// https://tc39.github.io/ecma262/#sec-regexpexec
module.exports = function (R, S) {
  var exec = R.exec;
  if (typeof exec === 'function') {
    var result = exec.call(R, S);
    if (typeof result !== 'object') {
      throw TypeError('RegExp exec method returned something other than an Object or null');
    }
    return result;
  }

  if (classof(R) !== 'RegExp') {
    throw TypeError('RegExp#exec called on incompatible receiver');
  }

  return regexpExec.call(R, S);
};



/***/ }),
/* 129 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var hide = __webpack_require__(61);
var redefine = __webpack_require__(65);
var fails = __webpack_require__(29);
var wellKnownSymbol = __webpack_require__(35);
var regexpExec = __webpack_require__(156);

var SPECIES = wellKnownSymbol('species');

var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
  // #replace needs built-in support for named groups.
  // #match works fine because it just return the exec results, even if it has
  // a "grops" property.
  var re = /./;
  re.exec = function () {
    var result = [];
    result.groups = { a: '7' };
    return result;
  };
  return ''.replace(re, '$<a>') !== '7';
});

// Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
// Weex JS has frozen built-in prototypes, so use try / catch wrapper
var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
  var re = /(?:)/;
  var originalExec = re.exec;
  re.exec = function () { return originalExec.apply(this, arguments); };
  var result = 'ab'.split(re);
  return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
});

module.exports = function (KEY, length, exec, sham) {
  var SYMBOL = wellKnownSymbol(KEY);

  var DELEGATES_TO_SYMBOL = !fails(function () {
    // String methods call symbol-named RegEp methods
    var O = {};
    O[SYMBOL] = function () { return 7; };
    return ''[KEY](O) != 7;
  });

  var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
    // Symbol-named RegExp methods call .exec
    var execCalled = false;
    var re = /a/;
    re.exec = function () { execCalled = true; return null; };

    if (KEY === 'split') {
      // RegExp[@@split] doesn't call the regex's exec method, but first creates
      // a new one. We need to return the patched regex when creating the new one.
      re.constructor = {};
      re.constructor[SPECIES] = function () { return re; };
    }

    re[SYMBOL]('');
    return !execCalled;
  });

  if (
    !DELEGATES_TO_SYMBOL ||
    !DELEGATES_TO_EXEC ||
    (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
    (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
  ) {
    var nativeRegExpMethod = /./[SYMBOL];
    var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
      if (regexp.exec === regexpExec) {
        if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
          // The native String method already delegates to @@method (this
          // polyfilled function), leasing to infinite recursion.
          // We avoid it by directly calling the native @@method method.
          return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
        }
        return { done: true, value: nativeMethod.call(str, regexp, arg2) };
      }
      return { done: false };
    });
    var stringMethod = methods[0];
    var regexMethod = methods[1];

    redefine(String.prototype, KEY, stringMethod);
    redefine(RegExp.prototype, SYMBOL, length == 2
      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
      ? function (string, arg) { return regexMethod.call(string, this, arg); }
      // 21.2.5.6 RegExp.prototype[@@match](string)
      // 21.2.5.9 RegExp.prototype[@@search](string)
      : function (string) { return regexMethod.call(string, this); }
    );
    if (sham) hide(RegExp.prototype[SYMBOL], 'sham', true);
  }
};


/***/ }),
/* 130 */
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__(52);
var MATCH = __webpack_require__(35)('match');
var global = __webpack_require__(32);
var isForced = __webpack_require__(120);
var inheritIfRequired = __webpack_require__(152);
var defineProperty = __webpack_require__(49).f;
var getOwnPropertyNames = __webpack_require__(93).f;
var isRegExp = __webpack_require__(154);
var getFlags = __webpack_require__(153);
var redefine = __webpack_require__(65);
var fails = __webpack_require__(29);
var NativeRegExp = global.RegExp;
var RegExpPrototype = NativeRegExp.prototype;
var re1 = /a/g;
var re2 = /a/g;

// "new" should create a new object, old webkit bug
var CORRECT_NEW = new NativeRegExp(re1) !== re1;

var FORCED = isForced('RegExp', DESCRIPTORS && (!CORRECT_NEW || fails(function () {
  re2[MATCH] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';
})));

// `RegExp` constructor
// https://tc39.github.io/ecma262/#sec-regexp-constructor
if (FORCED) {
  var RegExpWrapper = function RegExp(pattern, flags) {
    var thisIsRegExp = this instanceof RegExpWrapper;
    var patternIsRegExp = isRegExp(pattern);
    var flagsAreUndefined = flags === undefined;
    return !thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined ? pattern
      : inheritIfRequired(CORRECT_NEW
        ? new NativeRegExp(patternIsRegExp && !flagsAreUndefined ? pattern.source : pattern, flags)
        : NativeRegExp((patternIsRegExp = pattern instanceof RegExpWrapper)
          ? pattern.source
          : pattern, patternIsRegExp && flagsAreUndefined ? getFlags.call(pattern) : flags)
      , thisIsRegExp ? this : RegExpPrototype, RegExpWrapper);
  };
  var proxy = function (key) {
    key in RegExpWrapper || defineProperty(RegExpWrapper, key, {
      configurable: true,
      get: function () { return NativeRegExp[key]; },
      set: function (it) { NativeRegExp[key] = it; }
    });
  };
  var keys = getOwnPropertyNames(NativeRegExp);
  var i = 0;
  while (i < keys.length) proxy(keys[i++]);
  RegExpPrototype.constructor = RegExpWrapper;
  RegExpWrapper.prototype = RegExpPrototype;
  redefine(global, 'RegExp', RegExpWrapper);
}

// https://tc39.github.io/ecma262/#sec-get-regexp-@@species
__webpack_require__(193)('RegExp');


/***/ }),
/* 131 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var anObject = __webpack_require__(45);
var toLength = __webpack_require__(48);
var requireObjectCoercible = __webpack_require__(58);
var advanceStringIndex = __webpack_require__(155);
var regExpExec = __webpack_require__(128);

// @@match logic
__webpack_require__(129)(
  'match',
  1,
  function (MATCH, nativeMatch, maybeCallNative) {
    return [
      // `String.prototype.match` method
      // https://tc39.github.io/ecma262/#sec-string.prototype.match
      function match(regexp) {
        var O = requireObjectCoercible(this);
        var matcher = regexp == undefined ? undefined : regexp[MATCH];
        return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
      },
      // `RegExp.prototype[@@match]` method
      // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match
      function (regexp) {
        var res = maybeCallNative(nativeMatch, regexp, this);
        if (res.done) return res.value;

        var rx = anObject(regexp);
        var S = String(this);

        if (!rx.global) return regExpExec(rx, S);

        var fullUnicode = rx.unicode;
        rx.lastIndex = 0;
        var A = [];
        var n = 0;
        var result;
        while ((result = regExpExec(rx, S)) !== null) {
          var matchStr = String(result[0]);
          A[n] = matchStr;
          if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
          n++;
        }
        return n === 0 ? null : A;
      }
    ];
  }
);


/***/ }),
/* 132 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(470);

exports.__esModule = true;
exports.spreadsheetColumnLabel = spreadsheetColumnLabel;
exports.spreadsheetColumnIndex = spreadsheetColumnIndex;
exports.createSpreadsheetData = createSpreadsheetData;
exports.createSpreadsheetObjectData = createSpreadsheetObjectData;
exports.createEmptySpreadsheetData = createEmptySpreadsheetData;
exports.translateRowsToColumns = translateRowsToColumns;
exports.cellMethodLookupFactory = cellMethodLookupFactory;

var _cellTypes = __webpack_require__(160);

var _object = __webpack_require__(4);

var COLUMN_LABEL_BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
/**
 * Generates spreadsheet-like column names: A, B, C, ..., Z, AA, AB, etc.
 *
 * @param {Number} index Column index.
 * @returns {String}
 */

function spreadsheetColumnLabel(index) {
  var dividend = index + 1;
  var columnLabel = '';
  var modulo;

  while (dividend > 0) {
    modulo = (dividend - 1) % COLUMN_LABEL_BASE_LENGTH;
    columnLabel = String.fromCharCode(65 + modulo) + columnLabel;
    dividend = parseInt((dividend - modulo) / COLUMN_LABEL_BASE_LENGTH, 10);
  }

  return columnLabel;
}
/**
 * Generates spreadsheet-like column index from theirs labels: A, B, C ...., Z, AA, AB, etc.
 *
 * @param {String} label Column label.
 * @returns {Number}
 */


function spreadsheetColumnIndex(label) {
  var result = 0;

  if (label) {
    for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
      result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
    }
  }

  result -= 1;
  return result;
}
/**
 * Creates 2D array of Excel-like values "A1", "A2", ...
 *
 * @param {Number} rows Number of rows to generate.
 * @param {Number} columns Number of columns to generate.
 * @returns {Array}
 */


function createSpreadsheetData() {
  var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
  var columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
  var _rows = [];
  var i;
  var j;

  for (i = 0; i < rows; i++) {
    var row = [];

    for (j = 0; j < columns; j++) {
      row.push(spreadsheetColumnLabel(j) + (i + 1));
    }

    _rows.push(row);
  }

  return _rows;
}
/**
 * Creates 2D array of Excel-like values "A1", "A2", as an array of objects.
 *
 * @param {Number} rows Number of rows to generate.
 * @param {Number} colCount Number of columns to generate.
 * @returns {Array}
 */


function createSpreadsheetObjectData() {
  var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
  var colCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
  var _rows = [];
  var i;
  var j;

  for (i = 0; i < rows; i++) {
    var row = {};

    for (j = 0; j < colCount; j++) {
      row["prop".concat(j)] = spreadsheetColumnLabel(j) + (i + 1);
    }

    _rows.push(row);
  }

  return _rows;
}
/**
 * Generates an empty data object.
 *
 * @param {Number} rows Number of rows to generate.
 * @param {Number} columns Number of columns to generate
 * @returns {Array}
 */


function createEmptySpreadsheetData(rows, columns) {
  var data = [];
  var row;

  for (var i = 0; i < rows; i++) {
    row = [];

    for (var j = 0; j < columns; j++) {
      row.push('');
    }

    data.push(row);
  }

  return data;
}

function translateRowsToColumns(input) {
  var output = [];
  var i;
  var ilen;
  var j;
  var jlen;
  var olen = 0;

  for (i = 0, ilen = input.length; i < ilen; i++) {
    for (j = 0, jlen = input[i].length; j < jlen; j++) {
      if (j === olen) {
        output.push([]);
        olen += 1;
      }

      output[j].push(input[i][j]);
    }
  }

  return output;
}
/**
 * Factory that produces a function for searching methods (or any properties) which could be defined directly in
 * table configuration or implicitly, within cell type definition.
 *
 * For example: renderer can be defined explicitly using "renderer" property in column configuration or it can be
 * defined implicitly using "type" property.
 *
 * Methods/properties defined explicitly always takes precedence over those defined through "type".
 *
 * If the method/property is not found in an object, searching is continued recursively through prototype chain, until
 * it reaches the Object.prototype.
 *
 *
 * @param methodName {String} name of the method/property to search (i.e. 'renderer', 'validator', 'copyable')
 * @param allowUndefined {Boolean} [optional] if false, the search is continued if methodName has not been found in cell "type"
 * @returns {Function}
 */


function cellMethodLookupFactory(methodName, allowUndefined) {
  var isUndefinedAllowed = typeof allowUndefined === 'undefined' ? true : allowUndefined;
  return function cellMethodLookup(row, col) {
    return function getMethodFromProperties(properties) {
      if (!properties) {
        return; // method not found
      } else if ((0, _object.hasOwnProperty)(properties, methodName) && properties[methodName] !== void 0) {
        // check if it is own and is not empty
        return properties[methodName]; // method defined directly
      } else if ((0, _object.hasOwnProperty)(properties, 'type') && properties.type) {
        // check if it is own and is not empty
        if (typeof properties.type !== 'string') {
          throw new Error('Cell type must be a string ');
        }

        var type = (0, _cellTypes.getCellType)(properties.type);

        if ((0, _object.hasOwnProperty)(type, methodName)) {
          return type[methodName]; // method defined in type.
        } else if (isUndefinedAllowed) {
          return; // method does not defined in type (eg. validator), returns undefined
        }
      }

      return getMethodFromProperties(Object.getPrototypeOf(properties));
    }(typeof row === 'number' ? this.getCellMeta(row, col) : row);
  };
}

/***/ }),
/* 133 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// ECMAScript 6 symbols shim
var global = __webpack_require__(32);
var has = __webpack_require__(47);
var DESCRIPTORS = __webpack_require__(52);
var IS_PURE = __webpack_require__(116);
var $export = __webpack_require__(22);
var redefine = __webpack_require__(65);
var hiddenKeys = __webpack_require__(94);
var fails = __webpack_require__(29);
var shared = __webpack_require__(98);
var setToStringTag = __webpack_require__(122);
var uid = __webpack_require__(118);
var wellKnownSymbol = __webpack_require__(35);
var wrappedWellKnownSymbolModule = __webpack_require__(473);
var defineWellKnownSymbol = __webpack_require__(474);
var enumKeys = __webpack_require__(576);
var isArray = __webpack_require__(124);
var anObject = __webpack_require__(45);
var isObject = __webpack_require__(42);
var toIndexedObject = __webpack_require__(69);
var toPrimitive = __webpack_require__(97);
var createPropertyDescriptor = __webpack_require__(96);
var nativeObjectCreate = __webpack_require__(99);
var getOwnPropertyNamesExternal = __webpack_require__(174);
var getOwnPropertyDescriptorModule = __webpack_require__(115);
var definePropertyModule = __webpack_require__(49);
var propertyIsEnumerableModule = __webpack_require__(95);
var hide = __webpack_require__(61);
var objectKeys = __webpack_require__(89);
var HIDDEN = __webpack_require__(117)('hidden');
var InternalStateModule = __webpack_require__(87);
var SYMBOL = 'Symbol';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(SYMBOL);
var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
var nativeDefineProperty = definePropertyModule.f;
var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;
var $Symbol = global.Symbol;
var JSON = global.JSON;
var nativeJSONStringify = JSON && JSON.stringify;
var PROTOTYPE = 'prototype';
var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
var nativePropertyIsEnumerable = propertyIsEnumerableModule.f;
var SymbolRegistry = shared('symbol-registry');
var AllSymbols = shared('symbols');
var ObjectPrototypeSymbols = shared('op-symbols');
var WellKnownSymbolsStore = shared('wks');
var ObjectPrototype = Object[PROTOTYPE];
var QObject = global.QObject;
var NATIVE_SYMBOL = __webpack_require__(180);
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDescriptor = DESCRIPTORS && fails(function () {
  return nativeObjectCreate(nativeDefineProperty({}, 'a', {
    get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }
  })).a != 7;
}) ? function (it, key, D) {
  var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, key);
  if (ObjectPrototypeDescriptor) delete ObjectPrototype[key];
  nativeDefineProperty(it, key, D);
  if (ObjectPrototypeDescriptor && it !== ObjectPrototype) {
    nativeDefineProperty(ObjectPrototype, key, ObjectPrototypeDescriptor);
  }
} : nativeDefineProperty;

var wrap = function (tag, description) {
  var symbol = AllSymbols[tag] = nativeObjectCreate($Symbol[PROTOTYPE]);
  setInternalState(symbol, {
    type: SYMBOL,
    tag: tag,
    description: description
  });
  if (!DESCRIPTORS) symbol.description = description;
  return symbol;
};

var isSymbol = NATIVE_SYMBOL && typeof $Symbol.iterator == 'symbol' ? function (it) {
  return typeof it == 'symbol';
} : function (it) {
  return Object(it) instanceof $Symbol;
};

var $defineProperty = function defineProperty(it, key, D) {
  if (it === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, key, D);
  anObject(it);
  key = toPrimitive(key, true);
  anObject(D);
  if (has(AllSymbols, key)) {
    if (!D.enumerable) {
      if (!has(it, HIDDEN)) nativeDefineProperty(it, HIDDEN, createPropertyDescriptor(1, {}));
      it[HIDDEN][key] = true;
    } else {
      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
      D = nativeObjectCreate(D, { enumerable: createPropertyDescriptor(0, false) });
    } return setSymbolDescriptor(it, key, D);
  } return nativeDefineProperty(it, key, D);
};

var $defineProperties = function defineProperties(it, P) {
  anObject(it);
  var keys = enumKeys(P = toIndexedObject(P));
  var i = 0;
  var l = keys.length;
  var key;
  while (l > i) $defineProperty(it, key = keys[i++], P[key]);
  return it;
};

var $create = function create(it, P) {
  return P === undefined ? nativeObjectCreate(it) : $defineProperties(nativeObjectCreate(it), P);
};

var $propertyIsEnumerable = function propertyIsEnumerable(key) {
  var E = nativePropertyIsEnumerable.call(this, key = toPrimitive(key, true));
  if (this === ObjectPrototype && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return false;
  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};

var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {
  it = toIndexedObject(it);
  key = toPrimitive(key, true);
  if (it === ObjectPrototype && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
  var D = nativeGetOwnPropertyDescriptor(it, key);
  if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;
  return D;
};

var $getOwnPropertyNames = function getOwnPropertyNames(it) {
  var names = nativeGetOwnPropertyNames(toIndexedObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (!has(AllSymbols, key = names[i++]) && !has(hiddenKeys, key)) result.push(key);
  } return result;
};

var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
  var IS_OP = it === ObjectPrototype;
  var names = nativeGetOwnPropertyNames(IS_OP ? ObjectPrototypeSymbols : toIndexedObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectPrototype, key) : true)) result.push(AllSymbols[key]);
  } return result;
};

// `Symbol` constructor
// https://tc39.github.io/ecma262/#sec-symbol-constructor
if (!NATIVE_SYMBOL) {
  $Symbol = function Symbol() {
    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
    var description = arguments[0] === undefined ? undefined : String(arguments[0]);
    var tag = uid(description);
    var setter = function (value) {
      if (this === ObjectPrototype) setter.call(ObjectPrototypeSymbols, value);
      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
      setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
    };
    if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
    return wrap(tag, description);
  };
  redefine($Symbol[PROTOTYPE], 'toString', function toString() {
    return getInternalState(this).tag;
  });

  propertyIsEnumerableModule.f = $propertyIsEnumerable;
  definePropertyModule.f = $defineProperty;
  getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;
  __webpack_require__(93).f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;
  __webpack_require__(119).f = $getOwnPropertySymbols;

  if (DESCRIPTORS) {
    // https://github.com/tc39/proposal-Symbol-description
    nativeDefineProperty($Symbol[PROTOTYPE], 'description', {
      configurable: true,
      get: function description() {
        return getInternalState(this).description;
      }
    });
    if (!IS_PURE) {
      redefine(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
    }
  }

  wrappedWellKnownSymbolModule.f = function (name) {
    return wrap(wellKnownSymbol(name), name);
  };
}

$export({ global: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, { Symbol: $Symbol });

for (var wellKnownSymbols = objectKeys(WellKnownSymbolsStore), k = 0; wellKnownSymbols.length > k;) {
  defineWellKnownSymbol(wellKnownSymbols[k++]);
}

$export({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {
  // `Symbol.for` method
  // https://tc39.github.io/ecma262/#sec-symbol.for
  'for': function (key) {
    return has(SymbolRegistry, key += '')
      ? SymbolRegistry[key]
      : SymbolRegistry[key] = $Symbol(key);
  },
  // `Symbol.keyFor` method
  // https://tc39.github.io/ecma262/#sec-symbol.keyfor
  keyFor: function keyFor(sym) {
    if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
    for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;
  },
  useSetter: function () { USE_SETTER = true; },
  useSimple: function () { USE_SETTER = false; }
});

$export({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {
  // `Object.create` method
  // https://tc39.github.io/ecma262/#sec-object.create
  create: $create,
  // `Object.defineProperty` method
  // https://tc39.github.io/ecma262/#sec-object.defineproperty
  defineProperty: $defineProperty,
  // `Object.defineProperties` method
  // https://tc39.github.io/ecma262/#sec-object.defineproperties
  defineProperties: $defineProperties,
  // `Object.getOwnPropertyDescriptor` method
  // https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor
});

$export({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {
  // `Object.getOwnPropertyNames` method
  // https://tc39.github.io/ecma262/#sec-object.getownpropertynames
  getOwnPropertyNames: $getOwnPropertyNames,
  // `Object.getOwnPropertySymbols` method
  // https://tc39.github.io/ecma262/#sec-object.getownpropertysymbols
  getOwnPropertySymbols: $getOwnPropertySymbols
});

// `JSON.stringify` method behavior with symbols
// https://tc39.github.io/ecma262/#sec-json.stringify
JSON && $export({ target: 'JSON', stat: true, forced: !NATIVE_SYMBOL || fails(function () {
  var symbol = $Symbol();
  // MS Edge converts symbol values to JSON as {}
  return nativeJSONStringify([symbol]) != '[null]'
    // WebKit converts symbol values to JSON as null
    || nativeJSONStringify({ a: symbol }) != '{}'
    // V8 throws on boxed symbols
    || nativeJSONStringify(Object(symbol)) != '{}';
}) }, {
  stringify: function stringify(it) {
    var args = [it];
    var i = 1;
    var replacer, $replacer;
    while (arguments.length > i) args.push(arguments[i++]);
    $replacer = replacer = args[1];
    if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
    if (!isArray(replacer)) replacer = function (key, value) {
      if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
      if (!isSymbol(value)) return value;
    };
    args[1] = replacer;
    return nativeJSONStringify.apply(JSON, args);
  }
});

// `Symbol.prototype[@@toPrimitive]` method
// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@toprimitive
if (!$Symbol[PROTOTYPE][TO_PRIMITIVE]) hide($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// `Symbol.prototype[@@toStringTag]` property
// https://tc39.github.io/ecma262/#sec-symbol.prototype-@@tostringtag
setToStringTag($Symbol, SYMBOL);

hiddenKeys[HIDDEN] = true;


/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// `Symbol.prototype.description` getter
// https://tc39.github.io/ecma262/#sec-symbol.prototype.description

var DESCRIPTORS = __webpack_require__(52);
var has = __webpack_require__(47);
var isObject = __webpack_require__(42);
var defineProperty = __webpack_require__(49).f;
var copyConstructorProperties = __webpack_require__(179);
var NativeSymbol = __webpack_require__(32).Symbol;

if (DESCRIPTORS && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) ||
  // Safari 12 bug
  NativeSymbol().description !== undefined
)) {
  var EmptyStringDescriptionStore = {};
  // wrap Symbol constructor for correct work with undefined description
  var SymbolWrapper = function Symbol() {
    var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]);
    var result = this instanceof SymbolWrapper
      ? new NativeSymbol(description)
      // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
      : description === undefined ? NativeSymbol() : NativeSymbol(description);
    if (description === '') EmptyStringDescriptionStore[result] = true;
    return result;
  };
  copyConstructorProperties(SymbolWrapper, NativeSymbol);
  var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype;
  symbolPrototype.constructor = SymbolWrapper;

  var symbolToString = symbolPrototype.toString;
  var native = String(NativeSymbol('test')) == 'Symbol(test)';
  var regexp = /^Symbol\((.*)\)[^)]+$/;
  defineProperty(symbolPrototype, 'description', {
    configurable: true,
    get: function description() {
      var symbol = isObject(this) ? this.valueOf() : this;
      var string = symbolToString.call(symbol);
      if (has(EmptyStringDescriptionStore, symbol)) return '';
      var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1');
      return desc === '' ? undefined : desc;
    }
  });

  __webpack_require__(22)({ global: true, forced: true }, { Symbol: SymbolWrapper });
}


/***/ }),
/* 135 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.registerLanguageDictionary = registerLanguage;
exports.getLanguageDictionary = getLanguage;
exports.hasLanguageDictionary = hasLanguage;
exports.getDefaultLanguageDictionary = getDefaultLanguage;
exports.getLanguagesDictionaries = getLanguages;
exports.DEFAULT_LANGUAGE_CODE = void 0;

var _object = __webpack_require__(4);

var _utils = __webpack_require__(477);

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _enUS = _interopRequireDefault(__webpack_require__(577));

var DEFAULT_LANGUAGE_CODE = _enUS.default.languageCode;
exports.DEFAULT_LANGUAGE_CODE = DEFAULT_LANGUAGE_CODE;

var _staticRegister = (0, _staticRegister2.default)('languagesDictionaries'),
    registerGloballyLanguageDictionary = _staticRegister.register,
    getGlobalLanguageDictionary = _staticRegister.getItem,
    hasGlobalLanguageDictionary = _staticRegister.hasItem,
    getGlobalLanguagesDictionaries = _staticRegister.getValues;
/**
 * Register language dictionary for specific language code.
 *
 * @param {String|Object} languageCodeOrDictionary Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE' or object representing dictionary.
 * @param {Object} dictionary Dictionary for specific language (optional if first parameter has already dictionary).
 */


function registerLanguage(languageCodeOrDictionary, dictionary) {
  var languageCode = languageCodeOrDictionary;
  var dictionaryObject = dictionary; // Dictionary passed as first argument.

  if ((0, _object.isObject)(languageCodeOrDictionary)) {
    dictionaryObject = languageCodeOrDictionary;
    languageCode = dictionaryObject.languageCode;
  }

  extendLanguageDictionary(languageCode, dictionaryObject);
  registerGloballyLanguageDictionary(languageCode, (0, _object.deepClone)(dictionaryObject)); // We do not allow user to work with dictionary by reference, it can cause lot of bugs.

  return (0, _object.deepClone)(dictionaryObject);
}
/**
 * Get language dictionary for specific language code.
 *
 * @param {String} languageCode Language code.
 * @returns {Object} Object with constants representing identifiers for translation (as keys) and corresponding translation phrases (as values).
 */


function getLanguage(languageCode) {
  if (!hasLanguage(languageCode)) {
    return null;
  }

  return (0, _object.deepClone)(getGlobalLanguageDictionary(languageCode));
}
/**
 *
 * Get if language with specified language code was registered.
 *
 * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'.
 * @returns {Boolean}
 */


function hasLanguage(languageCode) {
  return hasGlobalLanguageDictionary(languageCode);
}
/**
 * Get default language dictionary.
 *
 * @returns {Object} Object with constants representing identifiers for translation (as keys) and corresponding translation phrases (as values).
 */


function getDefaultLanguage() {
  return _enUS.default;
}
/**
 * Extend handled dictionary by default language dictionary. As result, if any dictionary key isn't defined for specific language, it will be filled with default language value ("dictionary gaps" are supplemented).
 *
 * @private
 * @param {String} languageCode Language code.
 * @param {Object} dictionary Dictionary which is extended.
 */


function extendLanguageDictionary(languageCode, dictionary) {
  if (languageCode !== DEFAULT_LANGUAGE_CODE) {
    (0, _utils.extendNotExistingKeys)(dictionary, getGlobalLanguageDictionary(DEFAULT_LANGUAGE_CODE));
  }
}
/**
 * Get registered language dictionaries.
 *
 * @returns {Array}
 */


function getLanguages() {
  return getGlobalLanguagesDictionaries();
}

/**
 * Automatically registers default dictionary.
 */
registerLanguage(_enUS.default);

/***/ }),
/* 136 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(59);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports._getRefCount = _getRefCount;
exports._resetState = _resetState;
exports.isPressed = isPressed;
exports.isPressedCtrlKey = isPressedCtrlKey;
exports.startObserving = startObserving;
exports.stopObserving = stopObserving;

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _unicode = __webpack_require__(50);

var eventManager = new _eventManager.default();
var pressedKeys = new Set();
var refCount = 0;
/**
 * Begins observing keyboard keys states.
 */

function startObserving(rootDocument) {
  if (refCount === 0) {
    eventManager.addEventListener(rootDocument, 'keydown', function (event) {
      if (!pressedKeys.has(event.keyCode)) {
        pressedKeys.add(event.keyCode);
      }
    });
    eventManager.addEventListener(rootDocument, 'keyup', function (event) {
      if (pressedKeys.has(event.keyCode)) {
        pressedKeys.delete(event.keyCode);
      }
    });
    eventManager.addEventListener(rootDocument, 'visibilitychange', function () {
      if (rootDocument.hidden) {
        pressedKeys.clear();
      }
    });
    eventManager.addEventListener(rootDocument.defaultView, 'blur', function () {
      pressedKeys.clear();
    });
  }

  refCount += 1;
}
/**
 * Stops observing keyboard keys states and clear all previously saved states.
 */


function stopObserving() {
  if (refCount > 0) {
    refCount -= 1;
  }

  if (refCount === 0) {
    _resetState();
  }
}
/**
 * Remove all listeners attached to the DOM and clear all previously saved states.
 */


function _resetState() {
  eventManager.clearEvents();
  pressedKeys.clear();
  refCount = 0;
}
/**
 * Checks if provided keyCode or keyCodes are pressed.
 *
 * @param {String} keyCodes The key codes passed as a string defined in helpers/unicode.js file delimited with '|'.
 * @return {Boolean}
 */


function isPressed(keyCodes) {
  return Array.from(pressedKeys.values()).some(function (_keyCode) {
    return (0, _unicode.isKey)(_keyCode, keyCodes);
  });
}
/**
 * Checks if ctrl keys are pressed.
 *
 * @return {Boolean}
 */


function isPressedCtrlKey() {
  var values = Array.from(pressedKeys.values());
  return values.some(function (_keyCode) {
    return (0, _unicode.isCtrlMetaKey)(_keyCode);
  });
}
/**
 * Returns reference count. Useful for debugging and testing purposes.
 *
 * @return {Number}
 */


function _getRefCount() {
  return refCount;
}

/***/ }),
/* 137 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(133);

__webpack_require__(134);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(64);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.detectSelectionType = detectSelectionType;
exports.normalizeSelectionFactory = normalizeSelectionFactory;
exports.transformSelectionToColumnDistance = transformSelectionToColumnDistance;
exports.transformSelectionToRowDistance = transformSelectionToRowDistance;
exports.isValidCoord = isValidCoord;
exports.SELECTION_TYPES = exports.SELECTION_TYPE_OBJECT = exports.SELECTION_TYPE_ARRAY = exports.SELECTION_TYPE_EMPTY = exports.SELECTION_TYPE_UNRECOGNIZED = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _src = __webpack_require__(25);

var _array = __webpack_require__(3);

var _mixed = __webpack_require__(27);

var SELECTION_TYPE_UNRECOGNIZED = 0;
exports.SELECTION_TYPE_UNRECOGNIZED = SELECTION_TYPE_UNRECOGNIZED;
var SELECTION_TYPE_EMPTY = 1;
exports.SELECTION_TYPE_EMPTY = SELECTION_TYPE_EMPTY;
var SELECTION_TYPE_ARRAY = 2;
exports.SELECTION_TYPE_ARRAY = SELECTION_TYPE_ARRAY;
var SELECTION_TYPE_OBJECT = 3;
exports.SELECTION_TYPE_OBJECT = SELECTION_TYPE_OBJECT;
var SELECTION_TYPES = [SELECTION_TYPE_OBJECT, SELECTION_TYPE_ARRAY];
exports.SELECTION_TYPES = SELECTION_TYPES;
var ARRAY_TYPE_PATTERN = [['number'], ['number', 'string'], ['number', 'undefined'], ['number', 'string', 'undefined']];
var rootCall = Symbol('root');
var childCall = Symbol('child');
/**
 * Detect selection schema structure.
 *
 * @param {*} selectionRanges The selected range or and array of selected ranges. This type of data is produced by
 *                            `hot.getSelected()`, `hot.getSelectedLast()`, `hot.getSelectedRange()`
 *                            and `hot.getSelectedRangeLast()` methods.
 * @returns {Number} Returns a number that specifies the type of detected selection schema. If selection schema type
 *                   is unrecognized than it returns `0`.
 */

function detectSelectionType(selectionRanges) {
  var _callSymbol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : rootCall;

  if (_callSymbol !== rootCall && _callSymbol !== childCall) {
    throw new Error('The second argument is used internally only and cannot be overwritten.');
  }

  var isArray = Array.isArray(selectionRanges);
  var isRootCall = _callSymbol === rootCall;
  var result = SELECTION_TYPE_UNRECOGNIZED;

  if (isArray) {
    var firstItem = selectionRanges[0];

    if (selectionRanges.length === 0) {
      result = SELECTION_TYPE_EMPTY;
    } else if (isRootCall && firstItem instanceof _src.CellRange) {
      result = SELECTION_TYPE_OBJECT;
    } else if (isRootCall && Array.isArray(firstItem)) {
      result = detectSelectionType(firstItem, childCall);
    } else if (selectionRanges.length >= 2 && selectionRanges.length <= 4) {
      var isArrayType = !selectionRanges.some(function (value, index) {
        return !ARRAY_TYPE_PATTERN[index].includes((0, _typeof2.default)(value));
      });

      if (isArrayType) {
        result = SELECTION_TYPE_ARRAY;
      }
    }
  }

  return result;
}
/**
 * Factory function designed for normalization data schema from different data structures of the selection ranges.
 *
 * @param {String} type Selection type which will be processed.
 * @param {Object} [options]
 * @param {Boolean} [options.keepDirection=false] If `true`, the coordinates which contain the direction of the
 *                                                selected cells won't be changed. Otherwise, the selection will be
 *                                                normalized to values starting from top-left to bottom-right.
 * @param {Function} [options.propToCol] Pass the converting function (usually `datamap.propToCol`) if the column
 *                                       defined as props should be normalized to the numeric values.
 * @returns {Number[]} Returns normalized data about selected range as an array (`[rowStart, columnStart, rowEnd, columnEnd]`).
 */


function normalizeSelectionFactory(type) {
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
      _ref$keepDirection = _ref.keepDirection,
      keepDirection = _ref$keepDirection === void 0 ? false : _ref$keepDirection,
      propToCol = _ref.propToCol;

  if (!SELECTION_TYPES.includes(type)) {
    throw new Error('Unsupported selection ranges schema type was provided.');
  }

  return function (selection) {
    var isObjectType = type === SELECTION_TYPE_OBJECT;
    var rowStart = isObjectType ? selection.from.row : selection[0];
    var columnStart = isObjectType ? selection.from.col : selection[1];
    var rowEnd = isObjectType ? selection.to.row : selection[2];
    var columnEnd = isObjectType ? selection.to.col : selection[3];

    if (typeof propToCol === 'function') {
      if (typeof columnStart === 'string') {
        columnStart = propToCol(columnStart);
      }

      if (typeof columnEnd === 'string') {
        columnEnd = propToCol(columnEnd);
      }
    }

    if ((0, _mixed.isUndefined)(rowEnd)) {
      rowEnd = rowStart;
    }

    if ((0, _mixed.isUndefined)(columnEnd)) {
      columnEnd = columnStart;
    }

    if (!keepDirection) {
      var origRowStart = rowStart;
      var origColumnStart = columnStart;
      var origRowEnd = rowEnd;
      var origColumnEnd = columnEnd;
      rowStart = Math.min(origRowStart, origRowEnd);
      columnStart = Math.min(origColumnStart, origColumnEnd);
      rowEnd = Math.max(origRowStart, origRowEnd);
      columnEnd = Math.max(origColumnStart, origColumnEnd);
    }

    return [rowStart, columnStart, rowEnd, columnEnd];
  };
}
/**
 * Function transform selection ranges (produced by `hot.getSelected()` and `hot.getSelectedRange()`) to normalized
 * data structure. It merges repeated ranges into consecutive coordinates. The returned structure
 * contains an array of arrays. The single item contains at index 0 visual column index from the selection was
 * started and at index 1 distance as a count of selected columns.
 *
 * @param {Array[]|CellRange[]} selectionRanges Selection ranges produced by Handsontable.
 * @return {Array[]} Returns an array of arrays with ranges defines in that schema:
 *                   `[[visualColumnStart, distance], [visualColumnStart, distance], ...]`.
 *                   The column distances are always created starting from the left (zero index) to the
 *                   right (the latest column index).
 */


function transformSelectionToColumnDistance(selectionRanges) {
  var selectionType = detectSelectionType(selectionRanges);

  if (selectionType === SELECTION_TYPE_UNRECOGNIZED || selectionType === SELECTION_TYPE_EMPTY) {
    return [];
  }

  var selectionSchemaNormalizer = normalizeSelectionFactory(selectionType);
  var unorderedIndexes = new Set(); // Iterate through all ranges and collect all column indexes which are not saved yet.

  (0, _array.arrayEach)(selectionRanges, function (selection) {
    var _selectionSchemaNorma = selectionSchemaNormalizer(selection),
        _selectionSchemaNorma2 = (0, _slicedToArray2.default)(_selectionSchemaNorma, 4),
        columnStart = _selectionSchemaNorma2[1],
        columnEnd = _selectionSchemaNorma2[3];

    var amount = columnEnd - columnStart + 1;
    (0, _array.arrayEach)(Array.from(new Array(amount), function (_, i) {
      return columnStart + i;
    }), function (index) {
      if (!unorderedIndexes.has(index)) {
        unorderedIndexes.add(index);
      }
    });
  }); // Sort indexes in ascending order to easily detecting non-consecutive columns.

  var orderedIndexes = Array.from(unorderedIndexes).sort(function (a, b) {
    return a - b;
  });
  var normalizedColumnRanges = (0, _array.arrayReduce)(orderedIndexes, function (acc, visualColumnIndex, index, array) {
    if (index !== 0 && visualColumnIndex === array[index - 1] + 1) {
      acc[acc.length - 1][1] += 1;
    } else {
      acc.push([visualColumnIndex, 1]);
    }

    return acc;
  }, []);
  return normalizedColumnRanges;
}
/**
 * Function transform selection ranges (produced by `hot.getSelected()` and `hot.getSelectedRange()`) to normalized
 * data structure. It merges repeated ranges into consecutive coordinates. The returned structure
 * contains an array of arrays. The single item contains at index 0 visual column index from the selection was
 * started and at index 1 distance as a count of selected columns.
 *
 * @param {Array[]|CellRange[]} selectionRanges Selection ranges produced by Handsontable.
 * @return {Array[]} Returns an array of arrays with ranges defines in that schema:
 *                   `[[visualColumnStart, distance], [visualColumnStart, distance], ...]`.
 *                   The column distances are always created starting from the left (zero index) to the
 *                   right (the latest column index).
 */


function transformSelectionToRowDistance(selectionRanges) {
  var selectionType = detectSelectionType(selectionRanges);

  if (selectionType === SELECTION_TYPE_UNRECOGNIZED || selectionType === SELECTION_TYPE_EMPTY) {
    return [];
  }

  var selectionSchemaNormalizer = normalizeSelectionFactory(selectionType);
  var unorderedIndexes = new Set(); // Iterate through all ranges and collect all column indexes which are not saved yet.

  (0, _array.arrayEach)(selectionRanges, function (selection) {
    var _selectionSchemaNorma3 = selectionSchemaNormalizer(selection),
        _selectionSchemaNorma4 = (0, _slicedToArray2.default)(_selectionSchemaNorma3, 3),
        rowStart = _selectionSchemaNorma4[0],
        rowEnd = _selectionSchemaNorma4[2];

    var amount = rowEnd - rowStart + 1;
    (0, _array.arrayEach)(Array.from(new Array(amount), function (_, i) {
      return rowStart + i;
    }), function (index) {
      if (!unorderedIndexes.has(index)) {
        unorderedIndexes.add(index);
      }
    });
  }); // Sort indexes in ascending order to easily detecting non-consecutive columns.

  var orderedIndexes = Array.from(unorderedIndexes).sort(function (a, b) {
    return a - b;
  });
  var normalizedRowRanges = (0, _array.arrayReduce)(orderedIndexes, function (acc, rowIndex, index, array) {
    if (index !== 0 && rowIndex === array[index - 1] + 1) {
      acc[acc.length - 1][1] += 1;
    } else {
      acc.push([rowIndex, 1]);
    }

    return acc;
  }, []);
  return normalizedRowRanges;
}
/**
 * Check if passed value can be treated as valid cell coordinate. The second argument is
 * used to check if the value doesn't exceed the defined max table rows/columns count.
 *
 * @param {*} coord
 * @param {Number} maxTableItemsCount The value that declares the maximum coordinate that is still validatable.
 * @return {Boolean}
 */


function isValidCoord(coord) {
  var maxTableItemsCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Infinity;
  return typeof coord === 'number' && coord >= 0 && coord < maxTableItemsCount;
}

/***/ }),
/* 138 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toLength = __webpack_require__(48);
var validateArguments = __webpack_require__(157);
var STARTS_WITH = 'startsWith';
var CORRECT_IS_REGEXP_LOGIC = __webpack_require__(158)(STARTS_WITH);
var nativeStartsWith = ''[STARTS_WITH];

// `String.prototype.startsWith` method
// https://tc39.github.io/ecma262/#sec-string.prototype.startswith
__webpack_require__(22)({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, {
  startsWith: function startsWith(searchString /* , position = 0 */) {
    var that = validateArguments(this, searchString, STARTS_WITH);
    var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));
    var search = String(searchString);
    return nativeStartsWith
      ? nativeStartsWith.call(that, search, index)
      : that.slice(index, index + search.length) === search;
  }
});


/***/ }),
/* 139 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _stateSaver = _interopRequireDefault(__webpack_require__(706));

/**
 * @plugin Filters
 * @class BaseComponent
 */
var BaseComponent =
/*#__PURE__*/
function () {
  function BaseComponent(hotInstance) {
    (0, _classCallCheck2.default)(this, BaseComponent);
    this.hot = hotInstance;
    /**
     * List of registered component UI elements.
     *
     * @type {Array}
     */

    this.elements = [];
    /**
     * Flag which determines if element is hidden.
     *
     * @type {Boolean}
     */

    this.hidden = false;
  }
  /**
   * Reset elements to their initial state.
   */


  (0, _createClass2.default)(BaseComponent, [{
    key: "reset",
    value: function reset() {
      (0, _array.arrayEach)(this.elements, function (ui) {
        return ui.reset();
      });
    }
    /**
     * Hide component.
     */

  }, {
    key: "hide",
    value: function hide() {
      this.hidden = true;
    }
    /**
     * Show component.
     */

  }, {
    key: "show",
    value: function show() {
      this.hidden = false;
    }
    /**
     * Check if component is hidden.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isHidden",
    value: function isHidden() {
      return this.hidden;
    }
    /**
     * Destroy element.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.clearLocalHooks();
      (0, _array.arrayEach)(this.elements, function (ui) {
        return ui.destroy();
      });
      this.elements = null;
      this.hot = null;
    }
  }]);
  return BaseComponent;
}();

(0, _object.mixin)(BaseComponent, _localHooks.default);
(0, _object.mixin)(BaseComponent, _stateSaver.default);
var _default = BaseComponent;
exports.default = _default;

/***/ }),
/* 140 */
/***/ (function(module, exports, __webpack_require__) {

var toIndexedObject = __webpack_require__(69);
var toLength = __webpack_require__(48);
var toAbsoluteIndex = __webpack_require__(114);

// `Array.prototype.{ indexOf, includes }` methods implementation
// false -> Array#indexOf
// https://tc39.github.io/ecma262/#sec-array.prototype.indexof
// true  -> Array#includes
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
module.exports = function (IS_INCLUDES) {
  return function ($this, el, fromIndex) {
    var O = toIndexedObject($this);
    var length = toLength(O.length);
    var index = toAbsoluteIndex(fromIndex, length);
    var value;
    // Array#includes uses SameValueZero equality algorithm
    // eslint-disable-next-line no-self-compare
    if (IS_INCLUDES && el != el) while (length > index) {
      value = O[index++];
      // eslint-disable-next-line no-self-compare
      if (value != value) return true;
    // Array#indexOf ignores holes, Array#includes - not
    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {
      if (O[index] === el) return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};


/***/ }),
/* 141 */
/***/ (function(module, exports) {

// IE8- don't enum bug keys
module.exports = [
  'constructor',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'toLocaleString',
  'toString',
  'valueOf'
];


/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var document = __webpack_require__(32).document;
// typeof document.createElement is 'object' in old IE
var exist = isObject(document) && isObject(document.createElement);

module.exports = function (it) {
  return exist ? document.createElement(it) : {};
};


/***/ }),
/* 143 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var hide = __webpack_require__(61);

module.exports = function (key, value) {
  try {
    hide(global, key, value);
  } catch (e) {
    global[key] = value;
  } return value;
};


/***/ }),
/* 144 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(22);
var createIteratorConstructor = __webpack_require__(512);
var getPrototypeOf = __webpack_require__(145);
var setPrototypeOf = __webpack_require__(184);
var setToStringTag = __webpack_require__(122);
var hide = __webpack_require__(61);
var redefine = __webpack_require__(65);
var IS_PURE = __webpack_require__(116);
var ITERATOR = __webpack_require__(35)('iterator');
var Iterators = __webpack_require__(100);
var IteratorsCore = __webpack_require__(182);
var IteratorPrototype = IteratorsCore.IteratorPrototype;
var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
var KEYS = 'keys';
var VALUES = 'values';
var ENTRIES = 'entries';

var returnThis = function () { return this; };

module.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
  createIteratorConstructor(IteratorConstructor, NAME, next);

  var getIterationMethod = function (KIND) {
    if (KIND === DEFAULT && defaultIterator) return defaultIterator;
    if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];
    switch (KIND) {
      case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
      case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
      case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
    } return function () { return new IteratorConstructor(this); };
  };

  var TO_STRING_TAG = NAME + ' Iterator';
  var INCORRECT_VALUES_NAME = false;
  var IterablePrototype = Iterable.prototype;
  var nativeIterator = IterablePrototype[ITERATOR]
    || IterablePrototype['@@iterator']
    || DEFAULT && IterablePrototype[DEFAULT];
  var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
  var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
  var CurrentIteratorPrototype, methods, KEY;

  // fix native
  if (anyNativeIterator) {
    CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));
    if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
      if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {
        if (setPrototypeOf) {
          setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);
        } else if (typeof CurrentIteratorPrototype[ITERATOR] != 'function') {
          hide(CurrentIteratorPrototype, ITERATOR, returnThis);
        }
      }
      // Set @@toStringTag to native iterators
      setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
      if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;
    }
  }

  // fix Array#{values, @@iterator}.name in V8 / FF
  if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
    INCORRECT_VALUES_NAME = true;
    defaultIterator = function values() { return nativeIterator.call(this); };
  }

  // define iterator
  if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {
    hide(IterablePrototype, ITERATOR, defaultIterator);
  }
  Iterators[NAME] = defaultIterator;

  // export additional methods
  if (DEFAULT) {
    methods = {
      values: getIterationMethod(VALUES),
      keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
      entries: getIterationMethod(ENTRIES)
    };
    if (FORCED) for (KEY in methods) {
      if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
        redefine(IterablePrototype, KEY, methods[KEY]);
      }
    } else $export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
  }

  return methods;
};


/***/ }),
/* 145 */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has = __webpack_require__(47);
var toObject = __webpack_require__(62);
var IE_PROTO = __webpack_require__(117)('IE_PROTO');
var CORRECT_PROTOTYPE_GETTER = __webpack_require__(183);
var ObjectPrototype = Object.prototype;

module.exports = CORRECT_PROTOTYPE_GETTER ? Object.getPrototypeOf : function (O) {
  O = toObject(O);
  if (has(O, IE_PROTO)) return O[IE_PROTO];
  if (typeof O.constructor == 'function' && O instanceof O.constructor) {
    return O.constructor.prototype;
  } return O instanceof Object ? ObjectPrototype : null;
};


/***/ }),
/* 146 */
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__(86);
var requireObjectCoercible = __webpack_require__(58);
// CONVERT_TO_STRING: true  -> String#at
// CONVERT_TO_STRING: false -> String#codePointAt
module.exports = function (that, pos, CONVERT_TO_STRING) {
  var S = String(requireObjectCoercible(that));
  var position = toInteger(pos);
  var size = S.length;
  var first, second;
  if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
  first = S.charCodeAt(position);
  return first < 0xd800 || first > 0xdbff || position + 1 === size
    || (second = S.charCodeAt(position + 1)) < 0xdc00 || second > 0xdfff
      ? CONVERT_TO_STRING ? S.charAt(position) : first
      : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xd800 << 10) + (second - 0xdc00) + 0x10000;
};


/***/ }),
/* 147 */
/***/ (function(module, exports, __webpack_require__) {

var redefine = __webpack_require__(65);

module.exports = function (target, src, options) {
  for (var key in src) redefine(target, key, src[key], options);
  return target;
};


/***/ }),
/* 148 */
/***/ (function(module, exports) {

module.exports = function (it, Constructor, name) {
  if (!(it instanceof Constructor)) {
    throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
  } return it;
};


/***/ }),
/* 149 */
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__(45);
var isArrayIteratorMethod = __webpack_require__(187);
var toLength = __webpack_require__(48);
var bind = __webpack_require__(101);
var getIteratorMethod = __webpack_require__(188);
var callWithSafeIterationClosing = __webpack_require__(189);
var BREAK = {};

var exports = module.exports = function (iterable, fn, that, ENTRIES, ITERATOR) {
  var boundFunction = bind(fn, that, ENTRIES ? 2 : 1);
  var iterator, iterFn, index, length, result, step;

  if (ITERATOR) {
    iterator = iterable;
  } else {
    iterFn = getIteratorMethod(iterable);
    if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
    // optimisation for array iterators
    if (isArrayIteratorMethod(iterFn)) {
      for (index = 0, length = toLength(iterable.length); length > index; index++) {
        result = ENTRIES ? boundFunction(anObject(step = iterable[index])[0], step[1]) : boundFunction(iterable[index]);
        if (result === BREAK) return BREAK;
      } return;
    }
    iterator = iterFn.call(iterable);
  }

  while (!(step = iterator.next()).done) {
    if (callWithSafeIterationClosing(iterator, boundFunction, step.value, ENTRIES) === BREAK) return BREAK;
  }
};

exports.BREAK = BREAK;


/***/ }),
/* 150 */
/***/ (function(module, exports) {

module.exports = function (it) {
  if (typeof it != 'function') {
    throw TypeError(String(it) + ' is not a function');
  } return it;
};


/***/ }),
/* 151 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var isArray = __webpack_require__(124);
var SPECIES = __webpack_require__(35)('species');

// `ArraySpeciesCreate` abstract operation
// https://tc39.github.io/ecma262/#sec-arrayspeciescreate
module.exports = function (originalArray, length) {
  var C;
  if (isArray(originalArray)) {
    C = originalArray.constructor;
    // cross-realm fallback
    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
    else if (isObject(C)) {
      C = C[SPECIES];
      if (C === null) C = undefined;
    }
  } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
};


/***/ }),
/* 152 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var setPrototypeOf = __webpack_require__(184);

module.exports = function (that, target, C) {
  var S = target.constructor;
  var P;
  if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {
    setPrototypeOf(that, P);
  } return that;
};


/***/ }),
/* 153 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var anObject = __webpack_require__(45);

// `RegExp.prototype.flags` getter implementation
// https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags
module.exports = function () {
  var that = anObject(this);
  var result = '';
  if (that.global) result += 'g';
  if (that.ignoreCase) result += 'i';
  if (that.multiline) result += 'm';
  if (that.unicode) result += 'u';
  if (that.sticky) result += 'y';
  return result;
};


/***/ }),
/* 154 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var classof = __webpack_require__(77);
var MATCH = __webpack_require__(35)('match');

// `IsRegExp` abstract operation
// https://tc39.github.io/ecma262/#sec-isregexp
module.exports = function (it) {
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classof(it) == 'RegExp');
};


/***/ }),
/* 155 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var codePointAt = __webpack_require__(146);

// `AdvanceStringIndex` abstract operation
// https://tc39.github.io/ecma262/#sec-advancestringindex
module.exports = function (S, index, unicode) {
  return index + (unicode ? codePointAt(S, index, true).length : 1);
};


/***/ }),
/* 156 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var regexpFlags = __webpack_require__(153);

var nativeExec = RegExp.prototype.exec;
// This always refers to the native implementation, because the
// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
// which loads this file before patching the method.
var nativeReplace = String.prototype.replace;

var patchedExec = nativeExec;

var UPDATES_LAST_INDEX_WRONG = (function () {
  var re1 = /a/;
  var re2 = /b*/g;
  nativeExec.call(re1, 'a');
  nativeExec.call(re2, 'a');
  return re1.lastIndex !== 0 || re2.lastIndex !== 0;
})();

// nonparticipating capturing group, copied from es5-shim's String#split patch.
var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;

var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;

if (PATCH) {
  patchedExec = function exec(str) {
    var re = this;
    var lastIndex, reCopy, match, i;

    if (NPCG_INCLUDED) {
      reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
    }
    if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;

    match = nativeExec.call(re, str);

    if (UPDATES_LAST_INDEX_WRONG && match) {
      re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
    }
    if (NPCG_INCLUDED && match && match.length > 1) {
      // Fix browsers whose `exec` methods don't consistently return `undefined`
      // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
      nativeReplace.call(match[0], reCopy, function () {
        for (i = 1; i < arguments.length - 2; i++) {
          if (arguments[i] === undefined) match[i] = undefined;
        }
      });
    }

    return match;
  };
}

module.exports = patchedExec;


/***/ }),
/* 157 */
/***/ (function(module, exports, __webpack_require__) {

// helper for String#{startsWith, endsWith, includes}
var isRegExp = __webpack_require__(154);
var requireObjectCoercible = __webpack_require__(58);

module.exports = function (that, searchString, NAME) {
  if (isRegExp(searchString)) {
    throw TypeError('String.prototype.' + NAME + " doesn't accept regex");
  } return String(requireObjectCoercible(that));
};


/***/ }),
/* 158 */
/***/ (function(module, exports, __webpack_require__) {

var MATCH = __webpack_require__(35)('match');

module.exports = function (METHOD_NAME) {
  var regexp = /./;
  try {
    '/./'[METHOD_NAME](regexp);
  } catch (e) {
    try {
      regexp[MATCH] = false;
      return '/./'[METHOD_NAME](regexp);
    } catch (f) { /* empty */ }
  } return false;
};


/***/ }),
/* 159 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalFind = __webpack_require__(102)(5);
var FIND = 'find';
var SKIPS_HOLES = true;

// Shouldn't skip holes
if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });

// `Array.prototype.find` method
// https://tc39.github.io/ecma262/#sec-array.prototype.find
__webpack_require__(22)({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {
  find: function find(callbackfn /* , that = undefined */) {
    return internalFind(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});

// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
__webpack_require__(121)(FIND);


/***/ }),
/* 160 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.registerCellType = _register;
exports.getCellType = _getItem;
exports.getRegisteredCellTypes = exports.getRegisteredCellTypeNames = exports.hasCellType = void 0;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var _autocompleteType = _interopRequireDefault(__webpack_require__(559));

var _checkboxType = _interopRequireDefault(__webpack_require__(560));

var _dateType = _interopRequireDefault(__webpack_require__(561));

var _dropdownType = _interopRequireDefault(__webpack_require__(562));

var _handsontableType = _interopRequireDefault(__webpack_require__(563));

var _numericType = _interopRequireDefault(__webpack_require__(564));

var _passwordType = _interopRequireDefault(__webpack_require__(565));

var _textType = _interopRequireDefault(__webpack_require__(566));

var _timeType = _interopRequireDefault(__webpack_require__(567));

var _staticRegister = (0, _staticRegister2.default)('cellTypes'),
    register = _staticRegister.register,
    getItem = _staticRegister.getItem,
    hasItem = _staticRegister.hasItem,
    getNames = _staticRegister.getNames,
    getValues = _staticRegister.getValues;

exports.getRegisteredCellTypes = getValues;
exports.getRegisteredCellTypeNames = getNames;
exports.hasCellType = hasItem;

_register('autocomplete', _autocompleteType.default);

_register('checkbox', _checkboxType.default);

_register('date', _dateType.default);

_register('dropdown', _dropdownType.default);

_register('handsontable', _handsontableType.default);

_register('numeric', _numericType.default);

_register('password', _passwordType.default);

_register('text', _textType.default);

_register('time', _timeType.default);
/**
 * Retrieve cell type object.
 *
 * @param {String} name Cell type identification.
 * @returns {Object} Returns cell type object.
 */


function _getItem(name) {
  if (!hasItem(name)) {
    throw Error("You declared cell type \"".concat(name, "\" as a string that is not mapped to a known object.\n                 Cell type must be an object or a string mapped to an object registered by \"Handsontable.cellTypes.registerCellType\" method"));
  }

  return getItem(name);
}
/**
 * Register cell type under specified name.
 *
 * @param {String} name Cell type identification.
 * @param {Object} type An object with contains keys (eq: `editor`, `renderer`, `validator`) which describes specified behaviour of the cell.
 */


function _register(name, type) {
  var editor = type.editor,
      renderer = type.renderer,
      validator = type.validator;

  if (editor) {
    (0, _editors.registerEditor)(name, editor);
  }

  if (renderer) {
    (0, _renderers.registerRenderer)(name, renderer);
  }

  if (validator) {
    (0, _validators.registerValidator)(name, validator);
  }

  register(name, type);
}

/***/ }),
/* 161 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(59);

__webpack_require__(12);

__webpack_require__(64);

__webpack_require__(33);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(14);

__webpack_require__(37);

__webpack_require__(569);

__webpack_require__(30);

exports.__esModule = true;
exports.default = Core;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _element = __webpack_require__(5);

var _setting = __webpack_require__(162);

var _function = __webpack_require__(75);

var _console = __webpack_require__(55);

var _mixed = __webpack_require__(27);

var _browser = __webpack_require__(72);

var _dataMap = _interopRequireDefault(__webpack_require__(571));

var _editorManager = _interopRequireDefault(__webpack_require__(573));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _plugins = __webpack_require__(20);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var _string = __webpack_require__(68);

var _number = __webpack_require__(15);

var _tableView = _interopRequireDefault(__webpack_require__(574));

var _dataSource = _interopRequireDefault(__webpack_require__(575));

var _data = __webpack_require__(132);

var _recordTranslator = __webpack_require__(90);

var _rootInstance = __webpack_require__(472);

var _src = __webpack_require__(25);

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _defaultSettings = _interopRequireDefault(__webpack_require__(475));

var _cellTypes = __webpack_require__(160);

var _i18n = __webpack_require__(476);

var _dictionariesManager = __webpack_require__(135);

var _utils = __webpack_require__(477);

var _keyStateObserver = __webpack_require__(136);

var _selection = __webpack_require__(478);

var activeGuid = null;
/**
 * Handsontable constructor
 *
 * @core
 * @constructor Core
 * @description
 *
 * After Handsontable is constructed, you can modify the grid behavior using the available public methods.
 *
 * ---
 * ## How to call methods
 *
 * These are 2 equal ways to call a Handsontable method:
 *
 * ```js
 * // all following examples assume that you constructed Handsontable like this
 * const hot = new Handsontable(document.getElementById('example1'), options);
 *
 * // now, to use setDataAtCell method, you can either:
 * ht.setDataAtCell(0, 0, 'new value');
 * ```
 *
 * Alternatively, you can call the method using jQuery wrapper (__obsolete__, requires initialization using our jQuery guide
 * ```js
 *   $('#example1').handsontable('setDataAtCell', 0, 0, 'new value');
 * ```
 * ---
 */

function Core(rootElement, userSettings) {
  var _this = this;

  var rootInstanceSymbol = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  var preventScrollingToCell = false;
  var instance = this;

  var GridSettings = function GridSettings() {};

  var eventManager = new _eventManager.default(instance);
  var priv;
  var datamap;
  var dataSource;
  var grid;
  var editorManager;
  (0, _object.extend)(GridSettings.prototype, _defaultSettings.default.prototype); // create grid settings as a copy of default settings

  (0, _object.extend)(GridSettings.prototype, userSettings); // overwrite defaults with user settings

  (0, _object.extend)(GridSettings.prototype, expandType(userSettings));
  (0, _utils.applyLanguageSetting)(GridSettings.prototype, userSettings.language);

  if ((0, _rootInstance.hasValidParameter)(rootInstanceSymbol)) {
    (0, _rootInstance.registerAsRootInstance)(this);
  } // TODO: check if references to DOM elements should be move to UI layer (Walkontable)

  /**
   * Reference to the container element.
   *
   * @private
   * @type {HTMLElement}
   */


  this.rootElement = rootElement;
  /**
   * The nearest document over container.
   *
   * @private
   * @type {Document}
   */

  this.rootDocument = rootElement.ownerDocument;
  /**
   * Window object over container's document.
   *
   * @private
   * @type {Window}
   */

  this.rootWindow = this.rootDocument.defaultView;
  (0, _keyStateObserver.startObserving)(this.rootDocument);
  this.isDestroyed = false;
  this.isHotTableEnv = (0, _element.isChildOfWebComponentTable)(this.rootElement);
  _eventManager.default.isHotTableEnv = this.isHotTableEnv;
  this.container = this.rootDocument.createElement('div');
  this.renderCall = false;
  rootElement.insertBefore(this.container, rootElement.firstChild);

  if ((0, _rootInstance.isRootInstance)(this)) {
    (0, _mixed._injectProductInfo)(userSettings.licenseKey, rootElement);
  }

  this.guid = "ht_".concat((0, _string.randomString)()); // this is the namespace for global events

  var recordTranslator = (0, _recordTranslator.getTranslator)(instance);
  dataSource = new _dataSource.default(instance);

  if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
    this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
  }

  priv = {
    cellSettings: [],
    columnSettings: [],
    columnsSettingConflicts: ['data', 'width', 'language'],
    settings: new GridSettings(),
    // current settings instance
    selRange: null,
    // exposed by public method `getSelectedRange`
    isPopulated: null,
    scrollable: null,
    firstRun: true
  };
  var selection = new _selection.Selection(priv.settings, {
    countCols: function countCols() {
      return instance.countCols();
    },
    countRows: function countRows() {
      return instance.countRows();
    },
    propToCol: function propToCol(prop) {
      return datamap.propToCol(prop);
    },
    isEditorOpened: function isEditorOpened() {
      return instance.getActiveEditor() ? instance.getActiveEditor().isOpened() : false;
    }
  });
  this.selection = selection;
  this.selection.addLocalHook('beforeSetRangeStart', function (cellCoords) {
    _this.runHooks('beforeSetRangeStart', cellCoords);
  });
  this.selection.addLocalHook('beforeSetRangeStartOnly', function (cellCoords) {
    _this.runHooks('beforeSetRangeStartOnly', cellCoords);
  });
  this.selection.addLocalHook('beforeSetRangeEnd', function (cellCoords) {
    _this.runHooks('beforeSetRangeEnd', cellCoords);

    if (cellCoords.row < 0) {
      cellCoords.row = _this.view.wt.wtTable.getFirstVisibleRow();
    }

    if (cellCoords.col < 0) {
      cellCoords.col = _this.view.wt.wtTable.getFirstVisibleColumn();
    }
  });
  this.selection.addLocalHook('afterSetRangeEnd', function (cellCoords) {
    var preventScrolling = (0, _object.createObjectPropListener)(false);

    var selectionRange = _this.selection.getSelectedRange();

    var _selectionRange$curre = selectionRange.current(),
        from = _selectionRange$curre.from,
        to = _selectionRange$curre.to;

    var selectionLayerLevel = selectionRange.size() - 1;

    _this.runHooks('afterSelection', from.row, from.col, to.row, to.col, preventScrolling, selectionLayerLevel);

    _this.runHooks('afterSelectionByProp', from.row, instance.colToProp(from.col), to.row, instance.colToProp(to.col), preventScrolling, selectionLayerLevel);

    var isSelectedByAnyHeader = _this.selection.isSelectedByAnyHeader();

    var currentSelectedRange = _this.selection.selectedRange.current();

    var scrollToCell = true;

    if (preventScrollingToCell) {
      scrollToCell = false;
    }

    if (preventScrolling.isTouched()) {
      scrollToCell = !preventScrolling.value;
    }

    var isSelectedByRowHeader = _this.selection.isSelectedByRowHeader();

    var isSelectedByColumnHeader = _this.selection.isSelectedByColumnHeader();

    if (scrollToCell !== false) {
      if (!isSelectedByAnyHeader) {
        if (currentSelectedRange && !_this.selection.isMultiple()) {
          _this.view.scrollViewport(currentSelectedRange.from);
        } else {
          _this.view.scrollViewport(cellCoords);
        }
      } else if (isSelectedByRowHeader) {
        _this.view.scrollViewportVertically(cellCoords.row);
      } else if (isSelectedByColumnHeader) {
        _this.view.scrollViewportHorizontally(cellCoords.col);
      }
    } // @TODO: These CSS classes are no longer needed anymore. They are used only as a indicator of the selected
    // rows/columns in the MergedCells plugin (via border.js#L520 in the walkontable module). After fixing
    // the Border class this should be removed.


    if (isSelectedByRowHeader && isSelectedByColumnHeader) {
      (0, _element.addClass)(_this.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
    } else if (isSelectedByRowHeader) {
      (0, _element.removeClass)(_this.rootElement, 'ht__selection--columns');
      (0, _element.addClass)(_this.rootElement, 'ht__selection--rows');
    } else if (isSelectedByColumnHeader) {
      (0, _element.removeClass)(_this.rootElement, 'ht__selection--rows');
      (0, _element.addClass)(_this.rootElement, 'ht__selection--columns');
    } else {
      (0, _element.removeClass)(_this.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
    }

    _this._refreshBorders(null);
  });
  this.selection.addLocalHook('afterSelectionFinished', function (cellRanges) {
    var selectionLayerLevel = cellRanges.length - 1;
    var _cellRanges$selection = cellRanges[selectionLayerLevel],
        from = _cellRanges$selection.from,
        to = _cellRanges$selection.to;

    _this.runHooks('afterSelectionEnd', from.row, from.col, to.row, to.col, selectionLayerLevel);

    _this.runHooks('afterSelectionEndByProp', from.row, instance.colToProp(from.col), to.row, instance.colToProp(to.col), selectionLayerLevel);
  });
  this.selection.addLocalHook('afterIsMultipleSelection', function (isMultiple) {
    var changedIsMultiple = _this.runHooks('afterIsMultipleSelection', isMultiple.value);

    if (isMultiple.value) {
      isMultiple.value = changedIsMultiple;
    }
  });
  this.selection.addLocalHook('beforeModifyTransformStart', function (cellCoordsDelta) {
    _this.runHooks('modifyTransformStart', cellCoordsDelta);
  });
  this.selection.addLocalHook('afterModifyTransformStart', function (coords, rowTransformDir, colTransformDir) {
    _this.runHooks('afterModifyTransformStart', coords, rowTransformDir, colTransformDir);
  });
  this.selection.addLocalHook('beforeModifyTransformEnd', function (cellCoordsDelta) {
    _this.runHooks('modifyTransformEnd', cellCoordsDelta);
  });
  this.selection.addLocalHook('afterModifyTransformEnd', function (coords, rowTransformDir, colTransformDir) {
    _this.runHooks('afterModifyTransformEnd', coords, rowTransformDir, colTransformDir);
  });
  this.selection.addLocalHook('afterDeselect', function () {
    editorManager.destroyEditor();

    _this._refreshBorders();

    (0, _element.removeClass)(_this.rootElement, ['ht__selection--rows', 'ht__selection--columns']);

    _this.runHooks('afterDeselect');
  });
  this.selection.addLocalHook('insertRowRequire', function (totalRows) {
    _this.alter('insert_row', totalRows, 1, 'auto');
  });
  this.selection.addLocalHook('insertColRequire', function (totalCols) {
    _this.alter('insert_col', totalCols, 1, 'auto');
  });
  grid = {
    /**
     * Inserts or removes rows and columns.
     *
     * @memberof Core#
     * @function alter
     * @private
     * @param {String} action Possible values: "insert_row", "insert_col", "remove_row", "remove_col".
     * @param {Number|Array} index Row or column visual index which from the alter action will be triggered.
     *                             Alter actions such as "remove_row" and "remove_col" support array indexes in the
     *                             format `[[index, amount], [index, amount]...]` this can be used to remove
     *                             non-consecutive columns or rows in one call.
     * @param {Number} [amount=1] Ammount rows or columns to remove.
     * @param {String} [source] Optional. Source of hook runner.
     * @param {Boolean} [keepEmptyRows] Optional. Flag for preventing deletion of empty rows.
     */
    alter: function alter(action, index) {
      var amount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
      var source = arguments.length > 3 ? arguments[3] : undefined;
      var keepEmptyRows = arguments.length > 4 ? arguments[4] : undefined;
      var delta;

      function spliceWith(data, startIndex, count, toInject) {
        var valueFactory = function valueFactory() {
          var result;

          if (toInject === 'array') {
            result = [];
          } else if (toInject === 'object') {
            result = {};
          }

          return result;
        };

        var spliceArgs = (0, _array.arrayMap)(new Array(count), function () {
          return valueFactory();
        });
        spliceArgs.unshift(startIndex, 0);
        data.splice.apply(data, (0, _toConsumableArray2.default)(spliceArgs));
      }

      var normalizeIndexesGroup = function normalizeIndexesGroup(indexes) {
        if (indexes.length === 0) {
          return [];
        }

        var sortedIndexes = (0, _toConsumableArray2.default)(indexes); // Sort the indexes in ascending order.

        sortedIndexes.sort(function (_ref, _ref2) {
          var _ref3 = (0, _slicedToArray2.default)(_ref, 1),
              indexA = _ref3[0];

          var _ref4 = (0, _slicedToArray2.default)(_ref2, 1),
              indexB = _ref4[0];

          if (indexA === indexB) {
            return 0;
          }

          return indexA > indexB ? 1 : -1;
        }); // Normalize the {index, amount} groups into bigger groups.

        var normalizedIndexes = (0, _array.arrayReduce)(sortedIndexes, function (acc, _ref5) {
          var _ref6 = (0, _slicedToArray2.default)(_ref5, 2),
              groupIndex = _ref6[0],
              groupAmount = _ref6[1];

          var previousItem = acc[acc.length - 1];

          var _previousItem = (0, _slicedToArray2.default)(previousItem, 2),
              prevIndex = _previousItem[0],
              prevAmount = _previousItem[1];

          var prevLastIndex = prevIndex + prevAmount;

          if (groupIndex <= prevLastIndex) {
            var amountToAdd = Math.max(groupAmount - (prevLastIndex - groupIndex), 0);
            previousItem[1] += amountToAdd;
          } else {
            acc.push([groupIndex, groupAmount]);
          }

          return acc;
        }, [sortedIndexes[0]]);
        return normalizedIndexes;
      };
      /* eslint-disable no-case-declarations */


      switch (action) {
        case 'insert_row':
          var numberOfSourceRows = instance.countSourceRows();

          if (instance.getSettings().maxRows === numberOfSourceRows) {
            return;
          } // eslint-disable-next-line no-param-reassign


          index = (0, _mixed.isDefined)(index) ? index : numberOfSourceRows;
          delta = datamap.createRow(index, amount, source);
          spliceWith(priv.cellSettings, index, amount, 'array');

          if (delta) {
            if (selection.isSelected() && selection.selectedRange.current().from.row >= index) {
              selection.selectedRange.current().from.row += delta;
              selection.transformEnd(delta, 0); // will call render() internally
            } else {
              instance._refreshBorders(); // it will call render and prepare methods

            }
          }

          break;

        case 'insert_col':
          delta = datamap.createCol(index, amount, source);

          for (var row = 0, len = instance.countSourceRows(); row < len; row++) {
            if (priv.cellSettings[row]) {
              spliceWith(priv.cellSettings[row], index, amount);
            }
          }

          if (delta) {
            if (Array.isArray(instance.getSettings().colHeaders)) {
              var spliceArray = [index, 0];
              spliceArray.length += delta; // inserts empty (undefined) elements at the end of an array

              Array.prototype.splice.apply(instance.getSettings().colHeaders, spliceArray); // inserts empty (undefined) elements into the colHeader array
            }

            if (selection.isSelected() && selection.selectedRange.current().from.col >= index) {
              selection.selectedRange.current().from.col += delta;
              selection.transformEnd(0, delta); // will call render() internally
            } else {
              instance._refreshBorders(); // it will call render and prepare methods

            }
          }

          break;

        case 'remove_row':
          var removeRow = function removeRow(indexes) {
            var offset = 0; // Normalize the {index, amount} groups into bigger groups.

            (0, _array.arrayEach)(indexes, function (_ref7) {
              var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
                  groupIndex = _ref8[0],
                  groupAmount = _ref8[1];

              var calcIndex = (0, _mixed.isEmpty)(groupIndex) ? instance.countRows() - 1 : Math.max(groupIndex - offset, 0); // If the 'index' is an integer decrease it by 'offset' otherwise pass it through to make the value
              // compatible with datamap.removeCol method.

              if (Number.isInteger(groupIndex)) {
                // eslint-disable-next-line no-param-reassign
                groupIndex = Math.max(groupIndex - offset, 0);
              } // TODO: for datamap.removeRow index should be passed as it is (with undefined and null values). If not, the logic
              // inside the datamap.removeRow breaks the removing functionality.


              datamap.removeRow(groupIndex, groupAmount, source);
              priv.cellSettings.splice(calcIndex, amount);
              var totalRows = instance.countRows();
              var fixedRowsTop = instance.getSettings().fixedRowsTop;

              if (fixedRowsTop >= calcIndex + 1) {
                instance.getSettings().fixedRowsTop -= Math.min(groupAmount, fixedRowsTop - calcIndex);
              }

              var fixedRowsBottom = instance.getSettings().fixedRowsBottom;

              if (fixedRowsBottom && calcIndex >= totalRows - fixedRowsBottom) {
                instance.getSettings().fixedRowsBottom -= Math.min(groupAmount, fixedRowsBottom);
              }

              offset += groupAmount;
            });
          };

          if (Array.isArray(index)) {
            removeRow(normalizeIndexesGroup(index));
          } else {
            removeRow([[index, amount]]);
          }

          grid.adjustRowsAndCols();

          instance._refreshBorders(); // it will call render and prepare methods


          break;

        case 'remove_col':
          var removeCol = function removeCol(indexes) {
            var offset = 0; // Normalize the {index, amount} groups into bigger groups.

            (0, _array.arrayEach)(indexes, function (_ref9) {
              var _ref10 = (0, _slicedToArray2.default)(_ref9, 2),
                  groupIndex = _ref10[0],
                  groupAmount = _ref10[1];

              var calcIndex = (0, _mixed.isEmpty)(groupIndex) ? instance.countCols() - 1 : Math.max(groupIndex - offset, 0);
              var visualColumnIndex = recordTranslator.toPhysicalColumn(calcIndex); // If the 'index' is an integer decrease it by 'offset' otherwise pass it through to make the value
              // compatible with datamap.removeCol method.

              if (Number.isInteger(groupIndex)) {
                // eslint-disable-next-line no-param-reassign
                groupIndex = Math.max(groupIndex - offset, 0);
              } // TODO: for datamap.removeCol index should be passed as it is (with undefined and null values). If not, the logic
              // inside the datamap.removeCol breaks the removing functionality.


              datamap.removeCol(groupIndex, groupAmount, source);

              for (var _row = 0, _len = instance.countSourceRows(); _row < _len; _row++) {
                if (priv.cellSettings[_row]) {
                  // if row hasn't been rendered it wouldn't have cellSettings
                  priv.cellSettings[_row].splice(visualColumnIndex, groupAmount);
                }
              }

              var fixedColumnsLeft = instance.getSettings().fixedColumnsLeft;

              if (fixedColumnsLeft >= calcIndex + 1) {
                instance.getSettings().fixedColumnsLeft -= Math.min(groupAmount, fixedColumnsLeft - calcIndex);
              }

              if (Array.isArray(instance.getSettings().colHeaders)) {
                if (typeof visualColumnIndex === 'undefined') {
                  visualColumnIndex = -1;
                }

                instance.getSettings().colHeaders.splice(visualColumnIndex, groupAmount);
              }

              offset += groupAmount;
            });
          };

          if (Array.isArray(index)) {
            removeCol(normalizeIndexesGroup(index));
          } else {
            removeCol([[index, amount]]);
          }

          grid.adjustRowsAndCols();

          instance._refreshBorders(); // it will call render and prepare methods


          break;

        default:
          throw new Error("There is no such action \"".concat(action, "\""));
      }

      if (!keepEmptyRows) {
        grid.adjustRowsAndCols(); // makes sure that we did not add rows that will be removed in next refresh
      }
    },

    /**
     * Makes sure there are empty rows at the bottom of the table
     */
    adjustRowsAndCols: function adjustRowsAndCols() {
      if (priv.settings.minRows) {
        // should I add empty rows to data source to meet minRows?
        var rows = instance.countRows();

        if (rows < priv.settings.minRows) {
          for (var r = 0, minRows = priv.settings.minRows; r < minRows - rows; r++) {
            datamap.createRow(instance.countRows(), 1, 'auto');
          }
        }
      }

      if (priv.settings.minSpareRows) {
        var emptyRows = instance.countEmptyRows(true); // should I add empty rows to meet minSpareRows?

        if (emptyRows < priv.settings.minSpareRows) {
          for (; emptyRows < priv.settings.minSpareRows && instance.countSourceRows() < priv.settings.maxRows; emptyRows++) {
            datamap.createRow(instance.countRows(), 1, 'auto');
          }
        }
      }

      {
        var emptyCols; // count currently empty cols

        if (priv.settings.minCols || priv.settings.minSpareCols) {
          emptyCols = instance.countEmptyCols(true);
        } // should I add empty cols to meet minCols?


        if (priv.settings.minCols && !priv.settings.columns && instance.countCols() < priv.settings.minCols) {
          for (; instance.countCols() < priv.settings.minCols; emptyCols++) {
            datamap.createCol(instance.countCols(), 1, 'auto');
          }
        } // should I add empty cols to meet minSpareCols?


        if (priv.settings.minSpareCols && !priv.settings.columns && instance.dataType === 'array' && emptyCols < priv.settings.minSpareCols) {
          for (; emptyCols < priv.settings.minSpareCols && instance.countCols() < priv.settings.maxCols; emptyCols++) {
            datamap.createCol(instance.countCols(), 1, 'auto');
          }
        }
      }
      var rowCount = instance.countRows();
      var colCount = instance.countCols();

      if (rowCount === 0 || colCount === 0) {
        selection.deselect();
      }

      if (selection.isSelected()) {
        (0, _array.arrayEach)(selection.selectedRange, function (range) {
          var selectionChanged = false;
          var fromRow = range.from.row;
          var fromCol = range.from.col;
          var toRow = range.to.row;
          var toCol = range.to.col; // if selection is outside, move selection to last row

          if (fromRow > rowCount - 1) {
            fromRow = rowCount - 1;
            selectionChanged = true;

            if (toRow > fromRow) {
              toRow = fromRow;
            }
          } else if (toRow > rowCount - 1) {
            toRow = rowCount - 1;
            selectionChanged = true;

            if (fromRow > toRow) {
              fromRow = toRow;
            }
          } // if selection is outside, move selection to last row


          if (fromCol > colCount - 1) {
            fromCol = colCount - 1;
            selectionChanged = true;

            if (toCol > fromCol) {
              toCol = fromCol;
            }
          } else if (toCol > colCount - 1) {
            toCol = colCount - 1;
            selectionChanged = true;

            if (fromCol > toCol) {
              fromCol = toCol;
            }
          }

          if (selectionChanged) {
            instance.selectCell(fromRow, fromCol, toRow, toCol);
          }
        });
      }

      if (instance.view) {
        instance.view.wt.wtOverlays.adjustElementsSize();
      }
    },

    /**
     * Populate the data from the provided 2d array from the given cell coordinates.
     *
     * @private
     * @param {Object} start Start selection position. Visual indexes.
     * @param {Array} input 2d data array.
     * @param {Object} [end] End selection position (only for drag-down mode). Visual indexes.
     * @param {String} [source="populateFromArray"] Source information string.
     * @param {String} [method="overwrite"] Populate method. Possible options: `shift_down`, `shift_right`, `overwrite`.
     * @param {String} direction (left|right|up|down) String specifying the direction.
     * @param {Array} deltas The deltas array. A difference between values of adjacent cells.
     *                       Useful **only** when the type of handled cells is `numeric`.
     * @returns {Object|undefined} ending td in pasted area (only if any cell was changed).
     */
    populateFromArray: function populateFromArray(start, input, end, source, method, direction, deltas) {
      // TODO: either remove or implement the `direction` argument. Currently it's not working at all.
      var r;
      var rlen;
      var c;
      var clen;
      var setData = [];
      var current = {};
      rlen = input.length;

      if (rlen === 0) {
        return false;
      }

      var repeatCol;
      var repeatRow;
      var cmax;
      var rmax;
      /* eslint-disable no-case-declarations */
      // insert data with specified pasteMode method

      switch (method) {
        case 'shift_down':
          repeatCol = end ? end.col - start.col + 1 : 0;
          repeatRow = end ? end.row - start.row + 1 : 0; // eslint-disable-next-line no-param-reassign

          input = (0, _data.translateRowsToColumns)(input);

          for (c = 0, clen = input.length, cmax = Math.max(clen, repeatCol); c < cmax; c++) {
            if (c < clen) {
              var _instance;

              for (r = 0, rlen = input[c].length; r < repeatRow - rlen; r++) {
                input[c].push(input[c][r % rlen]);
              }

              input[c].unshift(start.col + c, start.row, 0);

              (_instance = instance).spliceCol.apply(_instance, (0, _toConsumableArray2.default)(input[c]));
            } else {
              var _instance2;

              input[c % clen][0] = start.col + c;

              (_instance2 = instance).spliceCol.apply(_instance2, (0, _toConsumableArray2.default)(input[c % clen]));
            }
          }

          break;

        case 'shift_right':
          repeatCol = end ? end.col - start.col + 1 : 0;
          repeatRow = end ? end.row - start.row + 1 : 0;

          for (r = 0, rlen = input.length, rmax = Math.max(rlen, repeatRow); r < rmax; r++) {
            if (r < rlen) {
              var _instance3;

              for (c = 0, clen = input[r].length; c < repeatCol - clen; c++) {
                input[r].push(input[r][c % clen]);
              }

              input[r].unshift(start.row + r, start.col, 0);

              (_instance3 = instance).spliceRow.apply(_instance3, (0, _toConsumableArray2.default)(input[r]));
            } else {
              var _instance4;

              input[r % rlen][0] = start.row + r;

              (_instance4 = instance).spliceRow.apply(_instance4, (0, _toConsumableArray2.default)(input[r % rlen]));
            }
          }

          break;

        case 'overwrite':
        default:
          // overwrite and other not specified options
          current.row = start.row;
          current.col = start.col;
          var selected = {
            // selected range
            row: end && start ? end.row - start.row + 1 : 1,
            col: end && start ? end.col - start.col + 1 : 1
          };
          var skippedRow = 0;
          var skippedColumn = 0;
          var pushData = true;
          var cellMeta;

          var getInputValue = function getInputValue(row) {
            var col = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
            var rowValue = input[row % input.length];

            if (col !== null) {
              return rowValue[col % rowValue.length];
            }

            return rowValue;
          };

          var rowInputLength = input.length;
          var rowSelectionLength = end ? end.row - start.row + 1 : 0;

          if (end) {
            rlen = rowSelectionLength;
          } else {
            rlen = Math.max(rowInputLength, rowSelectionLength);
          }

          for (r = 0; r < rlen; r++) {
            if (end && current.row > end.row && rowSelectionLength > rowInputLength || !priv.settings.allowInsertRow && current.row > instance.countRows() - 1 || current.row >= priv.settings.maxRows) {
              break;
            }

            var visualRow = r - skippedRow;
            var colInputLength = getInputValue(visualRow).length;
            var colSelectionLength = end ? end.col - start.col + 1 : 0;

            if (end) {
              clen = colSelectionLength;
            } else {
              clen = Math.max(colInputLength, colSelectionLength);
            }

            current.col = start.col;
            cellMeta = instance.getCellMeta(current.row, current.col);

            if ((source === 'CopyPaste.paste' || source === 'Autofill.autofill') && cellMeta.skipRowOnPaste) {
              skippedRow += 1;
              current.row += 1;
              rlen += 1;
              /* eslint-disable no-continue */

              continue;
            }

            skippedColumn = 0;

            for (c = 0; c < clen; c++) {
              if (end && current.col > end.col && colSelectionLength > colInputLength || !priv.settings.allowInsertColumn && current.col > instance.countCols() - 1 || current.col >= priv.settings.maxCols) {
                break;
              }

              cellMeta = instance.getCellMeta(current.row, current.col);

              if ((source === 'CopyPaste.paste' || source === 'Autofill.fill') && cellMeta.skipColumnOnPaste) {
                skippedColumn += 1;
                current.col += 1;
                clen += 1;
                continue;
              }

              if (cellMeta.readOnly) {
                current.col += 1;
                /* eslint-disable no-continue */

                continue;
              }

              var visualColumn = c - skippedColumn;
              var value = getInputValue(visualRow, visualColumn);
              var orgValue = instance.getDataAtCell(current.row, current.col);
              var index = {
                row: visualRow,
                col: visualColumn
              };

              if (source === 'Autofill.fill') {
                var result = instance.runHooks('beforeAutofillInsidePopulate', index, direction, input, deltas, {}, selected);

                if (result) {
                  value = (0, _mixed.isUndefined)(result.value) ? value : result.value;
                }
              }

              if (value !== null && (0, _typeof2.default)(value) === 'object') {
                // when 'value' is array and 'orgValue' is null, set 'orgValue' to
                // an empty array so that the null value can be compared to 'value'
                // as an empty value for the array context
                if (Array.isArray(value) && orgValue === null) orgValue = [];

                if (orgValue === null || (0, _typeof2.default)(orgValue) !== 'object') {
                  pushData = false;
                } else {
                  var orgValueSchema = (0, _object.duckSchema)(Array.isArray(orgValue) ? orgValue : orgValue[0] || orgValue);
                  var valueSchema = (0, _object.duckSchema)(Array.isArray(value) ? value : value[0] || value);
                  /* eslint-disable max-depth */

                  if ((0, _object.isObjectEqual)(orgValueSchema, valueSchema)) {
                    value = (0, _object.deepClone)(value);
                  } else {
                    pushData = false;
                  }
                }
              } else if (orgValue !== null && (0, _typeof2.default)(orgValue) === 'object') {
                pushData = false;
              }

              if (pushData) {
                setData.push([current.row, current.col, value]);
              }

              pushData = true;
              current.col += 1;
            }

            current.row += 1;
          }

          instance.setDataAtCell(setData, null, null, source || 'populateFromArray');
          break;
      }
    }
  };
  /**
   * Internal function to set `language` key of settings.
   *
   * @private
   * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'
   * @fires Hooks#afterLanguageChange
   */

  function setLanguage(languageCode) {
    var normalizedLanguageCode = (0, _utils.normalizeLanguageCode)(languageCode);

    if ((0, _dictionariesManager.hasLanguageDictionary)(normalizedLanguageCode)) {
      instance.runHooks('beforeLanguageChange', normalizedLanguageCode);
      GridSettings.prototype.language = normalizedLanguageCode;
      instance.runHooks('afterLanguageChange', normalizedLanguageCode);
    } else {
      (0, _utils.warnUserAboutLanguageRegistration)(languageCode);
    }
  }

  this.init = function () {
    dataSource.setData(priv.settings.data);
    instance.runHooks('beforeInit');

    if ((0, _browser.isMobileBrowser)()) {
      (0, _element.addClass)(instance.rootElement, 'mobile');
    }

    this.updateSettings(priv.settings, true);
    this.view = new _tableView.default(this);
    editorManager = _editorManager.default.getInstance(instance, priv, selection, datamap);
    this.forceFullRender = true; // used when data was changed

    instance.runHooks('init');
    this.view.render();

    if ((0, _typeof2.default)(priv.firstRun) === 'object') {
      instance.runHooks('afterChange', priv.firstRun[0], priv.firstRun[1]);
      priv.firstRun = false;
    }

    instance.runHooks('afterInit');
  };

  function ValidatorsQueue() {
    // moved this one level up so it can be used in any function here. Probably this should be moved to a separate file
    var resolved = false;
    return {
      validatorsInQueue: 0,
      valid: true,
      addValidatorToQueue: function addValidatorToQueue() {
        this.validatorsInQueue += 1;
        resolved = false;
      },
      removeValidatorFormQueue: function removeValidatorFormQueue() {
        this.validatorsInQueue = this.validatorsInQueue - 1 < 0 ? 0 : this.validatorsInQueue - 1;
        this.checkIfQueueIsEmpty();
      },
      onQueueEmpty: function onQueueEmpty() {},
      checkIfQueueIsEmpty: function checkIfQueueIsEmpty() {
        if (this.validatorsInQueue === 0 && resolved === false) {
          resolved = true;
          this.onQueueEmpty(this.valid);
        }
      }
    };
  }
  /**
   * Get parsed number from numeric string.
   *
   * @private
   * @param {String} numericData Float (separated by a dot or a comma) or integer.
   * @returns {Number} Number if we get data in parsable format, not changed value otherwise.
   */


  function getParsedNumber(numericData) {
    // Unifying "float like" string. Change from value with comma determiner to value with dot determiner,
    // for example from `450,65` to `450.65`.
    var unifiedNumericData = numericData.replace(',', '.');

    if (isNaN(parseFloat(unifiedNumericData)) === false) {
      return parseFloat(unifiedNumericData);
    }

    return numericData;
  }

  function validateChanges(changes, source, callback) {
    if (!changes.length) {
      return;
    }

    var beforeChangeResult = instance.runHooks('beforeChange', changes, source || 'edit');

    if ((0, _function.isFunction)(beforeChangeResult)) {
      (0, _console.warn)('Your beforeChange callback returns a function. It\'s not supported since Handsontable 0.12.1 (and the returned function will not be executed).');
    } else if (beforeChangeResult === false) {
      var activeEditor = instance.getActiveEditor();

      if (activeEditor) {
        activeEditor.cancelChanges();
      }

      return;
    }

    var waitingForValidator = new ValidatorsQueue();

    var isNumericData = function isNumericData(value) {
      return value.length > 0 && /^\s*[+-.]?\s*(?:(?:\d+(?:(\.|,)\d+)?(?:e[+-]?\d+)?)|(?:0x[a-f\d]+))\s*$/.test(value);
    };

    waitingForValidator.onQueueEmpty = callback; // called when async validators are resolved and beforeChange was not async

    for (var i = changes.length - 1; i >= 0; i--) {
      if (changes[i] === null) {
        changes.splice(i, 1);
      } else {
        var _changes$i = (0, _slicedToArray2.default)(changes[i], 4),
            row = _changes$i[0],
            prop = _changes$i[1],
            newValue = _changes$i[3];

        var col = datamap.propToCol(prop);
        var cellProperties = instance.getCellMeta(row, col);

        if (cellProperties.type === 'numeric' && typeof newValue === 'string' && isNumericData(newValue)) {
          changes[i][3] = getParsedNumber(newValue);
        }
        /* eslint-disable no-loop-func */


        if (instance.getCellValidator(cellProperties)) {
          waitingForValidator.addValidatorToQueue();
          instance.validateCell(changes[i][3], cellProperties, function (index, cellPropertiesReference) {
            return function (result) {
              if (typeof result !== 'boolean') {
                throw new Error('Validation error: result is not boolean');
              }

              if (result === false && cellPropertiesReference.allowInvalid === false) {
                changes.splice(index, 1); // cancel the change

                cellPropertiesReference.valid = true; // we cancelled the change, so cell value is still valid

                var cell = instance.getCell(cellPropertiesReference.visualRow, cellPropertiesReference.visualCol);

                if (cell !== null) {
                  (0, _element.removeClass)(cell, instance.getSettings().invalidCellClassName);
                } // index -= 1;

              }

              waitingForValidator.removeValidatorFormQueue();
            };
          }(i, cellProperties), source);
        }
      }
    }

    waitingForValidator.checkIfQueueIsEmpty();
  }
  /**
   * Internal function to apply changes. Called after validateChanges
   *
   * @private
   * @param {Array} changes Array in form of [row, prop, oldValue, newValue]
   * @param {String} source String that identifies how this change will be described in changes array (useful in onChange callback)
   * @fires Hooks#beforeChangeRender
   * @fires Hooks#afterChange
   */


  function applyChanges(changes, source) {
    var i = changes.length - 1;

    if (i < 0) {
      return;
    }

    for (; i >= 0; i--) {
      var skipThisChange = false;

      if (changes[i] === null) {
        changes.splice(i, 1);
        /* eslint-disable no-continue */

        continue;
      }

      if ((changes[i][2] === null || changes[i][2] === void 0) && (changes[i][3] === null || changes[i][3] === void 0)) {
        /* eslint-disable no-continue */
        continue;
      }

      if (priv.settings.allowInsertRow) {
        while (changes[i][0] > instance.countRows() - 1) {
          var numberOfCreatedRows = datamap.createRow(void 0, void 0, source);

          if (numberOfCreatedRows === 0) {
            skipThisChange = true;
            break;
          }
        }
      }

      if (skipThisChange) {
        /* eslint-disable no-continue */
        continue;
      }

      if (instance.dataType === 'array' && (!priv.settings.columns || priv.settings.columns.length === 0) && priv.settings.allowInsertColumn) {
        while (datamap.propToCol(changes[i][1]) > instance.countCols() - 1) {
          datamap.createCol(void 0, void 0, source);
        }
      }

      datamap.set(changes[i][0], changes[i][1], changes[i][3]);
    }

    instance.forceFullRender = true; // used when data was changed

    grid.adjustRowsAndCols();
    instance.runHooks('beforeChangeRender', changes, source);
    editorManager.lockEditor();

    instance._refreshBorders(null);

    editorManager.unlockEditor();
    instance.view.wt.wtOverlays.adjustElementsSize();
    instance.runHooks('afterChange', changes, source || 'edit');
    var activeEditor = instance.getActiveEditor();

    if (activeEditor && (0, _mixed.isDefined)(activeEditor.refreshValue)) {
      activeEditor.refreshValue();
    }
  }
  /**
   * Validate a single cell.
   *
   * @param {String|Number} value
   * @param cellProperties
   * @param callback
   * @param source
   */


  this.validateCell = function (value, cellProperties, callback, source) {
    var validator = instance.getCellValidator(cellProperties); // the `canBeValidated = false` argument suggests, that the cell passes validation by default.

    function done(valid) {
      var canBeValidated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

      // Fixes GH#3903
      if (!canBeValidated || cellProperties.hidden === true) {
        callback(valid);
        return;
      }

      var col = cellProperties.visualCol;
      var row = cellProperties.visualRow;
      var td = instance.getCell(row, col, true);

      if (td && td.nodeName !== 'TH') {
        instance.view.wt.wtSettings.settings.cellRenderer(row, col, td);
      }

      callback(valid);
    }

    if ((0, _mixed.isRegExp)(validator)) {
      validator = function (expression) {
        return function (cellValue, validatorCallback) {
          validatorCallback(expression.test(cellValue));
        };
      }(validator);
    }

    if ((0, _function.isFunction)(validator)) {
      // eslint-disable-next-line no-param-reassign
      value = instance.runHooks('beforeValidate', value, cellProperties.visualRow, cellProperties.prop, source); // To provide consistent behaviour, validation should be always asynchronous

      instance._registerImmediate(function () {
        validator.call(cellProperties, value, function (valid) {
          if (!instance) {
            return;
          } // eslint-disable-next-line no-param-reassign


          valid = instance.runHooks('afterValidate', valid, value, cellProperties.visualRow, cellProperties.prop, source);
          cellProperties.valid = valid;
          done(valid);
          instance.runHooks('postAfterValidate', valid, value, cellProperties.visualRow, cellProperties.prop, source);
        });
      });
    } else {
      // resolve callback even if validator function was not found
      instance._registerImmediate(function () {
        cellProperties.valid = true;
        done(cellProperties.valid, false);
      });
    }
  };

  function setDataInputToArray(row, propOrCol, value) {
    if ((0, _typeof2.default)(row) === 'object') {
      // is it an array of changes
      return row;
    }

    return [[row, propOrCol, value]];
  }
  /**
   * @description
   * Set new value to a cell. To change many cells at once (recommended way), pass an array of `changes` in format
   * `[[row, col, value],...]` as the first argument.
   *
   * @memberof Core#
   * @function setDataAtCell
   * @param {Number|Array} row Visual row index or array of changes in format `[[row, col, value],...]`.
   * @param {Number} [column] Visual column index.
   * @param {String} [value] New value.
   * @param {String} [source] String that identifies how this change will be described in the changes array (useful in onAfterChange or onBeforeChange callback).
   */


  this.setDataAtCell = function (row, column, value, source) {
    var input = setDataInputToArray(row, column, value);
    var changes = [];
    var changeSource = source;
    var i;
    var ilen;
    var prop;

    for (i = 0, ilen = input.length; i < ilen; i++) {
      if ((0, _typeof2.default)(input[i]) !== 'object') {
        throw new Error('Method `setDataAtCell` accepts row number or changes array of arrays as its first parameter');
      }

      if (typeof input[i][1] !== 'number') {
        throw new Error('Method `setDataAtCell` accepts row and column number as its parameters. If you want to use object property name, use method `setDataAtRowProp`');
      }

      prop = datamap.colToProp(input[i][1]);
      changes.push([input[i][0], prop, dataSource.getAtCell(recordTranslator.toPhysicalRow(input[i][0]), input[i][1]), input[i][2]]);
    }

    if (!changeSource && (0, _typeof2.default)(row) === 'object') {
      changeSource = column;
    }

    instance.runHooks('afterSetDataAtCell', changes, changeSource);
    validateChanges(changes, changeSource, function () {
      applyChanges(changes, changeSource);
    });
  };
  /**
   * @description
   * Set new value to a cell. To change many cells at once (recommended way), pass an array of `changes` in format
   * `[[row, prop, value],...]` as the first argument.
   *
   * @memberof Core#
   * @function setDataAtRowProp
   * @param {Number|Array} row Visual row index or array of changes in format `[[row, prop, value], ...]`.
   * @param {String} prop Property name or the source string (e.g. `'first.name'` or `'0'`).
   * @param {String} value Value to be set.
   * @param {String} [source] String that identifies how this change will be described in changes array (useful in onChange callback).
   */


  this.setDataAtRowProp = function (row, prop, value, source) {
    var input = setDataInputToArray(row, prop, value);
    var changes = [];
    var changeSource = source;
    var i;
    var ilen;

    for (i = 0, ilen = input.length; i < ilen; i++) {
      changes.push([input[i][0], input[i][1], dataSource.getAtCell(recordTranslator.toPhysicalRow(input[i][0]), input[i][1]), input[i][2]]);
    }

    if (!changeSource && (0, _typeof2.default)(row) === 'object') {
      changeSource = prop;
    }

    instance.runHooks('afterSetDataAtRowProp', changes, changeSource);
    validateChanges(changes, changeSource, function () {
      applyChanges(changes, changeSource);
    });
  };
  /**
   * Listen to the keyboard input on document body. This allows Handsontable to capture keyboard events and respond
   * in the right way.
   *
   * @memberof Core#
   * @function listen
   * @param {Boolean} [modifyDocumentFocus=true] If `true`, currently focused element will be blured (which returns focus
   *                                             to the document.body). Otherwise the active element does not lose its focus.
   * @fires Hooks#afterListen
   */


  this.listen = function () {
    var modifyDocumentFocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
    var _instance5 = instance,
        rootDocument = _instance5.rootDocument;

    if (modifyDocumentFocus) {
      var invalidActiveElement = !rootDocument.activeElement || rootDocument.activeElement && rootDocument.activeElement.nodeName === void 0;

      if (rootDocument.activeElement && rootDocument.activeElement !== rootDocument.body && !invalidActiveElement) {
        rootDocument.activeElement.blur();
      } else if (invalidActiveElement) {
        // IE
        rootDocument.body.focus();
      }
    }

    if (instance && !instance.isListening()) {
      activeGuid = instance.guid;
      instance.runHooks('afterListen');
    }
  };
  /**
   * Stop listening to keyboard input on the document body. Calling this method makes the Handsontable inactive for
   * any keyboard events.
   *
   * @memberof Core#
   * @function unlisten
   */


  this.unlisten = function () {
    if (this.isListening()) {
      activeGuid = null;
      instance.runHooks('afterUnlisten');
    }
  };
  /**
   * Returns `true` if the current Handsontable instance is listening to keyboard input on document body.
   *
   * @memberof Core#
   * @function isListening
   * @returns {Boolean} `true` if the instance is listening, `false` otherwise.
   */


  this.isListening = function () {
    return activeGuid === instance.guid;
  };
  /**
   * Destroys the current editor, render the table and prepares the editor of the newly selected cell.
   *
   * @memberof Core#
   * @function destroyEditor
   * @param {Boolean} [revertOriginal=false] If `true`, the previous value will be restored. Otherwise, the edited value will be saved.
   * @param {Boolean} [prepareEditorIfNeeded=true] If `true` the editor under the selected cell will be prepared to open.
   */


  this.destroyEditor = function () {
    var revertOriginal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var prepareEditorIfNeeded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

    instance._refreshBorders(revertOriginal, prepareEditorIfNeeded);
  };
  /**
   * Populate cells at position with 2D input array (e.g. `[[1, 2], [3, 4]]`). Use `endRow`, `endCol` when you
   * want to cut input when a certain row is reached.
   *
   * Optional `method` argument has the same effect as pasteMode option (see {@link Options#pasteMode}).
   *
   * @memberof Core#
   * @function populateFromArray
   * @param {Number} row Start visual row index.
   * @param {Number} column Start visual column index.
   * @param {Array} input 2d array
   * @param {Number} [endRow] End visual row index (use when you want to cut input when certain row is reached).
   * @param {Number} [endCol] End visual column index (use when you want to cut input when certain column is reached).
   * @param {String} [source=populateFromArray] Used to identify this call in the resulting events (beforeChange, afterChange).
   * @param {String} [method=overwrite] Populate method, possible values: `'shift_down'`, `'shift_right'`, `'overwrite'`.
   * @param {String} direction Populate direction, possible values: `'left'`, `'right'`, `'up'`, `'down'`.
   * @param {Array} deltas The deltas array. A difference between values of adjacent cells.
   *                       Useful **only** when the type of handled cells is `numeric`.
   */


  this.populateFromArray = function (row, column, input, endRow, endCol, source, method, direction, deltas) {
    if (!((0, _typeof2.default)(input) === 'object' && (0, _typeof2.default)(input[0]) === 'object')) {
      throw new Error('populateFromArray parameter `input` must be an array of arrays'); // API changed in 0.9-beta2, let's check if you use it correctly
    }

    var c = typeof endRow === 'number' ? new _src.CellCoords(endRow, endCol) : null;
    return grid.populateFromArray(new _src.CellCoords(row, column), input, c, source, method, direction, deltas);
  };
  /**
   * Adds/removes data from the column. This method works the same as Array.splice for arrays (see {@link DataMap#spliceCol}).
   *
   * @memberof Core#
   * @function spliceCol
   * @param {Number} column Index of the column in which do you want to do splice.
   * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
   * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
   * @param {...Number} [elements] The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array.
   */


  this.spliceCol = function (column, index, amount) {
    var _datamap;

    for (var _len2 = arguments.length, elements = new Array(_len2 > 3 ? _len2 - 3 : 0), _key = 3; _key < _len2; _key++) {
      elements[_key - 3] = arguments[_key];
    }

    return (_datamap = datamap).spliceCol.apply(_datamap, [column, index, amount].concat(elements));
  };
  /**
   * Adds/removes data from the row. This method works the same as Array.splice for arrays (see {@link DataMap#spliceRow}).
   *
   * @memberof Core#
   * @function spliceRow
   * @param {Number} row Index of column in which do you want to do splice.
   * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
   * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
   * @param {...Number} [elements] The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array.
   */


  this.spliceRow = function (row, index, amount) {
    var _datamap2;

    for (var _len3 = arguments.length, elements = new Array(_len3 > 3 ? _len3 - 3 : 0), _key2 = 3; _key2 < _len3; _key2++) {
      elements[_key2 - 3] = arguments[_key2];
    }

    return (_datamap2 = datamap).spliceRow.apply(_datamap2, [row, index, amount].concat(elements));
  };
  /**
   * Returns indexes of the currently selected cells as an array of arrays `[[startRow, startCol, endRow, endCol],...]`.
   *
   * Start row and start column are the coordinates of the active cell (where the selection was started).
   *
   * The version 0.36.0 adds a non-consecutive selection feature. Since this version, the method returns an array of arrays.
   * Additionally to collect the coordinates of the currently selected area (as it was previously done by the method)
   * you need to use `getSelectedLast` method.
   *
   * @memberof Core#
   * @function getSelected
   * @returns {Array[]|undefined} An array of arrays of the selection's coordinates.
   */


  this.getSelected = function () {
    // https://github.com/handsontable/handsontable/issues/44  //cjl
    if (selection.isSelected()) {
      return (0, _array.arrayMap)(selection.getSelectedRange(), function (_ref11) {
        var from = _ref11.from,
            to = _ref11.to;
        return [from.row, from.col, to.row, to.col];
      });
    }
  };
  /**
   * Returns the last coordinates applied to the table as a an array `[startRow, startCol, endRow, endCol]`.
   *
   * @since 0.36.0
   * @memberof Core#
   * @function getSelectedLast
   * @returns {Array|undefined} An array of the selection's coordinates.
   */


  this.getSelectedLast = function () {
    var selected = this.getSelected();
    var result;

    if (selected && selected.length > 0) {
      result = selected[selected.length - 1];
    }

    return result;
  };
  /**
   * Returns the current selection as an array of CellRange objects.
   *
   * The version 0.36.0 adds a non-consecutive selection feature. Since this version, the method returns an array of arrays.
   * Additionally to collect the coordinates of the currently selected area (as it was previously done by the method)
   * you need to use `getSelectedRangeLast` method.
   *
   * @memberof Core#
   * @function getSelectedRange
   * @returns {CellRange[]|undefined} Selected range object or undefined if there is no selection.
   */


  this.getSelectedRange = function () {
    // https://github.com/handsontable/handsontable/issues/44  //cjl
    if (selection.isSelected()) {
      return Array.from(selection.getSelectedRange());
    }
  };
  /**
  * Returns the last coordinates applied to the table as a CellRange object.
  *
  * @memberof Core#
  * @function getSelectedRangeLast
  * @since 0.36.0
  * @returns {CellRange|undefined} Selected range object or undefined` if there is no selection.
   */


  this.getSelectedRangeLast = function () {
    var selectedRange = this.getSelectedRange();
    var result;

    if (selectedRange && selectedRange.length > 0) {
      result = selectedRange[selectedRange.length - 1];
    }

    return result;
  };
  /**
   * Erases content from cells that have been selected in the table.
   *
   * @memberof Core#
   * @function emptySelectedCells
   * @since 0.36.0
   */


  this.emptySelectedCells = function () {
    var _this2 = this;

    if (!selection.isSelected()) {
      return;
    }

    var changes = [];
    (0, _array.arrayEach)(selection.getSelectedRange(), function (cellRange) {
      var topLeft = cellRange.getTopLeftCorner();
      var bottomRight = cellRange.getBottomRightCorner();
      (0, _number.rangeEach)(topLeft.row, bottomRight.row, function (row) {
        (0, _number.rangeEach)(topLeft.col, bottomRight.col, function (column) {
          if (!_this2.getCellMeta(row, column).readOnly) {
            changes.push([row, column, '']);
          }
        });
      });
    });

    if (changes.length > 0) {
      this.setDataAtCell(changes);
    }
  };
  /**
   * Rerender the table. Calling this method starts the process of recalculating, redrawing and applying the changes
   * to the DOM. While rendering the table all cell renderers are recalled.
   *
   * Calling this method manually is not recommended. Handsontable tries to render itself by choosing the most
   * optimal moments in its lifecycle.
   *
   * @memberof Core#
   * @function render
   */


  this.render = function () {
    if (instance.view) {
      instance.renderCall = true;
      instance.forceFullRender = true; // used when data was changed

      editorManager.lockEditor();

      instance._refreshBorders(null);

      editorManager.unlockEditor();
    }
  };

  this.refreshDimensions = function () {
    if (!instance.view) {
      return;
    }

    var _instance$view$getLas = instance.view.getLastSize(),
        lastWidth = _instance$view$getLas.width,
        lastHeight = _instance$view$getLas.height;

    var _instance$rootElement = instance.rootElement.getBoundingClientRect(),
        width = _instance$rootElement.width,
        height = _instance$rootElement.height;

    var isSizeChanged = width !== lastWidth || height !== lastHeight;
    var isResizeBlocked = instance.runHooks('beforeRefreshDimensions', {
      width: lastWidth,
      height: lastHeight
    }, {
      width: width,
      height: height
    }, isSizeChanged) === false;

    if (isResizeBlocked) {
      return;
    }

    if (isSizeChanged || instance.view.wt.wtOverlays.scrollableElement === instance.rootWindow) {
      instance.view.setLastSize(width, height);
      instance.render();
    }

    instance.runHooks('afterRefreshDimensions', {
      width: lastWidth,
      height: lastHeight
    }, {
      width: width,
      height: height
    }, isSizeChanged);
  };
  /**
   * Loads new data to Handsontable. Loading new data resets the cell meta.
   *
   * @memberof Core#
   * @function loadData
   * @param {Array} data Array of arrays or array of objects containing data.
   * @fires Hooks#afterLoadData
   * @fires Hooks#afterChange
   */


  this.loadData = function (data) {
    if (Array.isArray(priv.settings.dataSchema)) {
      instance.dataType = 'array';
    } else if ((0, _function.isFunction)(priv.settings.dataSchema)) {
      instance.dataType = 'function';
    } else {
      instance.dataType = 'object';
    }

    if (datamap) {
      datamap.destroy();
    }

    datamap = new _dataMap.default(instance, priv, GridSettings);

    if ((0, _typeof2.default)(data) === 'object' && data !== null) {
      if (!(data.push && data.splice)) {
        // check if data is array. Must use duck-type check so Backbone Collections also pass it
        // when data is not an array, attempt to make a single-row array of it
        // eslint-disable-next-line no-param-reassign
        data = [data];
      }
    } else if (data === null) {
      var dataSchema = datamap.getSchema(); // eslint-disable-next-line no-param-reassign

      data = [];
      var row;
      var r = 0;
      var rlen = 0;

      for (r = 0, rlen = priv.settings.startRows; r < rlen; r++) {
        if ((instance.dataType === 'object' || instance.dataType === 'function') && priv.settings.dataSchema) {
          row = (0, _object.deepClone)(dataSchema);
          data.push(row);
        } else if (instance.dataType === 'array') {
          row = (0, _object.deepClone)(dataSchema[0]);
          data.push(row);
        } else {
          row = [];

          for (var c = 0, clen = priv.settings.startCols; c < clen; c++) {
            row.push(null);
          }

          data.push(row);
        }
      }
    } else {
      throw new Error("loadData only accepts array of objects or array of arrays (".concat((0, _typeof2.default)(data), " given)"));
    }

    priv.isPopulated = false;
    GridSettings.prototype.data = data;

    if (Array.isArray(data[0])) {
      instance.dataType = 'array';
    }

    datamap.dataSource = data;
    dataSource.data = data;
    dataSource.dataType = instance.dataType;
    dataSource.colToProp = datamap.colToProp.bind(datamap);
    dataSource.propToCol = datamap.propToCol.bind(datamap);
    clearCellSettingCache();
    grid.adjustRowsAndCols();
    instance.runHooks('afterLoadData', priv.firstRun);

    if (priv.firstRun) {
      priv.firstRun = [null, 'loadData'];
    } else {
      instance.runHooks('afterChange', null, 'loadData');
      instance.render();
    }

    priv.isPopulated = true;

    function clearCellSettingCache() {
      priv.cellSettings.length = 0;
    }
  };
  /**
   * Returns the current data object (the same one that was passed by `data` configuration option or `loadData` method,
   * unless the `modifyRow` hook was used to trim some of the rows. If that's the case - use the {@link Core#getSourceData} method.).
   *
   * Optionally you can provide cell range by defining `row`, `column`, `row2`, `column2` to get only a fragment of table data.
   *
   * @memberof Core#
   * @function getData
   * @param {Number} [row] From visual row index.
   * @param {Number} [column] From visual column index.
   * @param {Number} [row2] To visual row index.
   * @param {Number} [column2] To visual column index.
   * @returns {Array[]} Array with the data.
   * @example
   * ```js
   * // Get all data (in order how it is rendered in the table).
   * hot.getData();
   * // Get data fragment (from top-left 0, 0 to bottom-right 3, 3).
   * hot.getData(3, 3);
   * // Get data fragment (from top-left 2, 1 to bottom-right 3, 3).
   * hot.getData(2, 1, 3, 3);
   * ```
   */


  this.getData = function (row, column, row2, column2) {
    if ((0, _mixed.isUndefined)(row)) {
      return datamap.getAll();
    }

    return datamap.getRange(new _src.CellCoords(row, column), new _src.CellCoords(row2, column2), datamap.DESTINATION_RENDERER);
  };
  /**
   * Returns a string value of the selected range. Each column is separated by tab, each row is separated by a new
   * line character (see {@link DataMap#getCopyableText}).
   *
   * @memberof Core#
   * @function getCopyableText
   * @param {Number} startRow From visual row index.
   * @param {Number} startCol From visual column index.
   * @param {Number} endRow To visual row index.
   * @param {Number} endCol To visual column index.
   * @returns {String}
   */


  this.getCopyableText = function (startRow, startCol, endRow, endCol) {
    return datamap.getCopyableText(new _src.CellCoords(startRow, startCol), new _src.CellCoords(endRow, endCol));
  };
  /**
   * Returns the data's copyable value at specified `row` and `column` index (see {@link DataMap#getCopyable}).
   *
   * @memberof Core#
   * @function getCopyableData
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @returns {String}
   */


  this.getCopyableData = function (row, column) {
    return datamap.getCopyable(row, datamap.colToProp(column));
  };
  /**
   * Returns schema provided by constructor settings. If it doesn't exist then it returns the schema based on the data
   * structure in the first row.
   *
   * @memberof Core#
   * @function getSchema
   * @returns {Object} Schema object.
   */


  this.getSchema = function () {
    return datamap.getSchema();
  };
  /**
   * Use it if you need to change configuration after initialization. The `settings` argument is an object containing the new
   * settings, declared the same way as in the initial settings object.
   *
   * __Note__, that although the `updateSettings` method doesn't overwrite the previously declared settings, it might reset
   * the settings made post-initialization. (for example - ignore changes made using the columnResize feature).
   *
   * @memberof Core#
   * @function updateSettings
   * @param {Object} settings New settings object (see {@link Options}).
   * @param {Boolean} [init=false] Internally used for in initialization mode.
   * @example
   * ```js
   * hot.updateSettings({
   *    contextMenu: true,
   *    colHeaders: true,
   *    fixedRowsTop: 2
   * });
   * ```
   * @fires Hooks#afterCellMetaReset
   * @fires Hooks#afterUpdateSettings
   */


  this.updateSettings = function (settings) {
    var init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
    var columnsAsFunc = false;
    var i;
    var j;
    var clen;

    if ((0, _mixed.isDefined)(settings.rows)) {
      throw new Error('"rows" setting is no longer supported. do you mean startRows, minRows or maxRows?');
    }

    if ((0, _mixed.isDefined)(settings.cols)) {
      throw new Error('"cols" setting is no longer supported. do you mean startCols, minCols or maxCols?');
    } // eslint-disable-next-line no-restricted-syntax


    for (i in settings) {
      if (i === 'data') {
        /* eslint-disable-next-line no-continue */
        continue; // loadData will be triggered later
      } else if (i === 'language') {
        setLanguage(settings.language);
        /* eslint-disable-next-line no-continue */

        continue;
      } else if (_pluginHooks.default.getSingleton().getRegistered().indexOf(i) > -1) {
        if ((0, _function.isFunction)(settings[i]) || Array.isArray(settings[i])) {
          settings[i].initialHook = true;
          instance.addHook(i, settings[i]);
        }
      } else if (!init && (0, _object.hasOwnProperty)(settings, i)) {
        // Update settings
        GridSettings.prototype[i] = settings[i];
      }
    } // Load data or create data map


    if (settings.data === void 0 && priv.settings.data === void 0) {
      instance.loadData(null); // data source created just now
    } else if (settings.data !== void 0) {
      instance.loadData(settings.data); // data source given as option
    } else if (settings.columns !== void 0) {
      datamap.createMap();
    }

    clen = instance.countCols();
    var columnSetting = settings.columns || GridSettings.prototype.columns; // Init columns constructors configuration

    if (columnSetting && (0, _function.isFunction)(columnSetting)) {
      clen = instance.countSourceCols();
      columnsAsFunc = true;
    } // Clear cellSettings cache


    if (settings.cell !== void 0 || settings.cells !== void 0 || settings.columns !== void 0) {
      priv.cellSettings.length = 0;
    }

    if (clen > 0) {
      var proto;
      var column;

      for (i = 0, j = 0; i < clen; i++) {
        if (columnsAsFunc && !columnSetting(i)) {
          /* eslint-disable no-continue */
          continue;
        }

        priv.columnSettings[j] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts); // shortcut for prototype

        proto = priv.columnSettings[j].prototype; // Use settings provided by user

        if (columnSetting) {
          if (columnsAsFunc) {
            column = columnSetting(i);
          } else {
            column = columnSetting[j];
          }

          if (column) {
            (0, _object.extend)(proto, column);
            (0, _object.extend)(proto, expandType(column));
          }
        }

        j += 1;
      }
    }

    if ((0, _mixed.isDefined)(settings.cell)) {
      (0, _object.objectEach)(settings.cell, function (cell) {
        instance.setCellMetaObject(cell.row, cell.col, cell);
      });
    }

    instance.runHooks('afterCellMetaReset');

    if ((0, _mixed.isDefined)(settings.className)) {
      if (GridSettings.prototype.className) {
        (0, _element.removeClass)(instance.rootElement, GridSettings.prototype.className);
      }

      if (settings.className) {
        (0, _element.addClass)(instance.rootElement, settings.className);
      }
    }

    var currentHeight = instance.rootElement.style.height;

    if (currentHeight !== '') {
      currentHeight = parseInt(instance.rootElement.style.height, 10);
    }

    var height = settings.height;

    if ((0, _function.isFunction)(height)) {
      height = height();
    }

    if (init) {
      var initialStyle = instance.rootElement.getAttribute('style');

      if (initialStyle) {
        instance.rootElement.setAttribute('data-initialstyle', instance.rootElement.getAttribute('style'));
      }
    }

    if (height === null) {
      var _initialStyle = instance.rootElement.getAttribute('data-initialstyle');

      if (_initialStyle && (_initialStyle.indexOf('height') > -1 || _initialStyle.indexOf('overflow') > -1)) {
        instance.rootElement.setAttribute('style', _initialStyle);
      } else {
        instance.rootElement.style.height = '';
        instance.rootElement.style.overflow = '';
      }
    } else if (height !== void 0) {
      instance.rootElement.style.height = isNaN(height) ? "".concat(height) : "".concat(height, "px");
      instance.rootElement.style.overflow = 'hidden';
    }

    if (typeof settings.width !== 'undefined') {
      var width = settings.width;

      if ((0, _function.isFunction)(width)) {
        width = width();
      }

      instance.rootElement.style.width = isNaN(width) ? "".concat(width) : "".concat(width, "px");
    }

    if (!init) {
      datamap.clearLengthCache(); // force clear cache length on updateSettings() #3416

      if (instance.view) {
        instance.view.wt.wtViewport.resetHasOversizedColumnHeadersMarked();
      }

      instance.runHooks('afterUpdateSettings', settings);
    }

    grid.adjustRowsAndCols();

    if (instance.view && !priv.firstRun) {
      instance.forceFullRender = true; // used when data was changed

      editorManager.lockEditor();

      instance._refreshBorders(null);

      editorManager.unlockEditor();
    }

    if (!init && instance.view && (currentHeight === '' || height === '' || height === void 0) && currentHeight !== height) {
      instance.view.wt.wtOverlays.updateMainScrollableElements();
    }
  };
  /**
   * Get value from the selected cell.
   *
   * @memberof Core#
   * @function getValue
   * @returns {*} Value of selected cell.
   */


  this.getValue = function () {
    var sel = instance.getSelectedLast();

    if (GridSettings.prototype.getValue) {
      if ((0, _function.isFunction)(GridSettings.prototype.getValue)) {
        return GridSettings.prototype.getValue.call(instance);
      } else if (sel) {
        return instance.getData()[sel[0][0]][GridSettings.prototype.getValue];
      }
    } else if (sel) {
      return instance.getDataAtCell(sel[0], sel[1]);
    }
  };

  function expandType(obj) {
    if (!(0, _object.hasOwnProperty)(obj, 'type')) {
      // ignore obj.prototype.type
      return;
    }

    var expandedType = {};
    var type;

    if ((0, _typeof2.default)(obj.type) === 'object') {
      type = obj.type;
    } else if (typeof obj.type === 'string') {
      type = (0, _cellTypes.getCellType)(obj.type);
    } // eslint-disable-next-line no-restricted-syntax


    for (var i in type) {
      if ((0, _object.hasOwnProperty)(type, i) && !(0, _object.hasOwnProperty)(obj, i)) {
        expandedType[i] = type[i];
      }
    }

    return expandedType;
  }
  /**
   * Returns the object settings.
   *
   * @memberof Core#
   * @function getSettings
   * @returns {Object} Object containing the current table settings.
   */


  this.getSettings = function () {
    return priv.settings;
  };
  /**
   * Clears the data from the table (the table settings remain intact).
   *
   * @memberof Core#
   * @function clear
   */


  this.clear = function () {
    this.selectAll();
    this.emptySelectedCells();
  };
  /**
   * Allows altering the table structure by either inserting/removing rows or columns.
   *
   * @memberof Core#
   * @function alter
   * @param {String} action Possible alter operations:
   *  * `'insert_row'`
   *  * `'insert_col'`
   *  * `'remove_row'`
   *  * `'remove_col'`
   * @param {Number|Number[]} index Visual index of the row/column before which the new row/column will be
   *                                inserted/removed or an array of arrays in format `[[index, amount],...]`.
   * @param {Number} [amount=1] Amount of rows/columns to be inserted or removed.
   * @param {String} [source] Source indicator.
   * @param {Boolean} [keepEmptyRows] Flag for preventing deletion of empty rows.
   * @example
   * ```js
   * // Insert new row above the row at given visual index.
   * hot.alter('insert_row', 10);
   * // Insert 3 new columns before 10th column.
   * hot.alter('insert_col', 10, 3);
   * // Remove 2 rows starting from 10th row.
   * hot.alter('remove_row', 10, 2);
   * // Remove 5 non-contiquous rows (it removes 3 rows from visual index 1 and 2 rows from visual index 5).
   * hot.alter('remove_row', [[1, 3], [5, 2]]);
   * ```
   */


  this.alter = function (action, index, amount, source, keepEmptyRows) {
    grid.alter(action, index, amount, source, keepEmptyRows);
  };
  /**
   * Returns a TD element for the given `row` and `column` arguments, if it is rendered on screen.
   * Returns `null` if the TD is not rendered on screen (probably because that part of the table is not visible).
   *
   * @memberof Core#
   * @function getCell
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @param {Boolean} [topmost=false] If set to `true`, it returns the TD element from the topmost overlay. For example,
   * if the wanted cell is in the range of fixed rows, it will return a TD element from the `top` overlay.
   * @returns {HTMLTableCellElement|null} The cell's TD element.
   */


  this.getCell = function (row, column) {
    var topmost = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
    return instance.view.getCellAtCoords(new _src.CellCoords(row, column), topmost);
  };
  /**
   * Returns the coordinates of the cell, provided as a HTML table cell element.
   *
   * @memberof Core#
   * @function getCoords
   * @param {HTMLTableCellElement} element The HTML Element representing the cell.
   * @returns {CellCoords} Visual coordinates object.
   * @example
   * ```js
   * hot.getCoords(hot.getCell(1, 1));
   * // it returns CellCoords object instance with props row: 1 and col: 1.
   * ```
   */


  this.getCoords = function (element) {
    return this.view.wt.wtTable.getCoords.call(this.view.wt.wtTable, element);
  };
  /**
   * Returns the property name that corresponds with the given column index (see {@link DataMap#colToProp}).
   * If the data source is an array of arrays, it returns the columns index.
   *
   * @memberof Core#
   * @function colToProp
   * @param {Number} column Visual column index.
   * @returns {String|Number} Column property or physical column index.
   */


  this.colToProp = function (column) {
    return datamap.colToProp(column);
  };
  /**
   * Returns column index that corresponds with the given property (see {@link DataMap#propToCol}).
   *
   * @memberof Core#
   * @function propToCol
   * @param {String|Number} prop Property name or physical column index.
   * @returns {Number} Visual column index.
   */


  this.propToCol = function (prop) {
    return datamap.propToCol(prop);
  };
  /**
   * Translate physical row index into visual.
   *
   * This method is useful when you want to retrieve visual row index which can be reordered, moved or trimmed
   * based on a physical index
   *
   * @memberof Core#
   * @function toVisualRow
   * @param {Number} row Physical row index.
   * @returns {Number} Returns visual row index.
   */


  this.toVisualRow = function (row) {
    return recordTranslator.toVisualRow(row);
  };
  /**
   * Translate physical column index into visual.
   *
   * This method is useful when you want to retrieve visual column index which can be reordered, moved or trimmed
   * based on a physical index
   *
   * @memberof Core#
   * @function toVisualColumn
   * @param {Number} column Physical column index.
   * @returns {Number} Returns visual column index.
   */


  this.toVisualColumn = function (column) {
    return recordTranslator.toVisualColumn(column);
  };
  /**
   * Translate visual row index into physical.
   *
   * This method is useful when you want to retrieve physical row index based on a visual index which can be
   * reordered, moved or trimmed.
   *
   * @memberof Core#
   * @function toPhysicalRow
   * @param {Number} row Visual row index.
   * @returns {Number} Returns physical row index.
   */


  this.toPhysicalRow = function (row) {
    return recordTranslator.toPhysicalRow(row);
  };
  /**
   * Translate visual column index into physical.
   *
   * This method is useful when you want to retrieve physical column index based on a visual index which can be
   * reordered, moved or trimmed.
   *
   * @memberof Core#
   * @function toPhysicalColumn
   * @param {Number} column Visual column index.
   * @returns {Number} Returns physical column index.
   */


  this.toPhysicalColumn = function (column) {
    return recordTranslator.toPhysicalColumn(column);
  };
  /**
   * @description
   * Returns the cell value at `row`, `column`.
   *
   * __Note__: If data is reordered, sorted or trimmed, the currently visible order will be used.
   *
   * @memberof Core#
   * @function getDataAtCell
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @returns {*} Data at cell.
   */


  this.getDataAtCell = function (row, column) {
    return datamap.get(row, datamap.colToProp(column));
  };
  /**
   * Returns value at visual `row` and `prop` indexes (see {@link DataMap#get}).
   *
   * __Note__: If data is reordered, sorted or trimmed, the currently visible order will be used.
   *
   * @memberof Core#
   * @function getDataAtRowProp
   * @param {Number} row Visual row index.
   * @param {String} prop Property name.
   * @returns {*} Cell value.
   */


  this.getDataAtRowProp = function (row, prop) {
    return datamap.get(row, prop);
  };
  /**
   * @description
   * Returns array of column values from the data source.
   *
   * __Note__: If columns were reordered or sorted, the currently visible order will be used.
   *
   * @memberof Core#
   * @function getDataAtCol
   * @param {Number} column Visual column index.
   * @returns {Array} Array of cell values.
   */


  this.getDataAtCol = function (column) {
    var _ref12;

    return (_ref12 = []).concat.apply(_ref12, (0, _toConsumableArray2.default)(datamap.getRange(new _src.CellCoords(0, column), new _src.CellCoords(priv.settings.data.length - 1, column), datamap.DESTINATION_RENDERER)));
  };
  /**
   * Given the object property name (e.g. `'first.name'` or `'0'`), returns an array of column's values from the table data.
   * You can also provide a column index as the first argument.
   *
   * @memberof Core#
   * @function getDataAtProp
   * @param {String|Number} prop Property name or physical column index.
   * @returns {Array} Array of cell values.
   */
  // TODO: Getting data from `datamap` should work on visual indexes.


  this.getDataAtProp = function (prop) {
    var _ref13;

    var range = datamap.getRange(new _src.CellCoords(0, datamap.propToCol(prop)), new _src.CellCoords(priv.settings.data.length - 1, datamap.propToCol(prop)), datamap.DESTINATION_RENDERER);
    return (_ref13 = []).concat.apply(_ref13, (0, _toConsumableArray2.default)(range));
  };
  /**
   * Returns the source data object (the same that was passed by `data` configuration option or `loadData` method).
   * Optionally you can provide a cell range by using the `row`, `column`, `row2`, `column2` arguments, to get only a
   * fragment of the table data.
   *
   * __Note__: This method does not participate in data transformation. If the visual data of the table is reordered,
   * sorted or trimmed only physical indexes are correct.
   *
   * @memberof Core#
   * @function getSourceData
   * @param {Number} [row] From physical row index.
   * @param {Number} [column] From physical column index (or visual index, if data type is an array of objects).
   * @param {Number} [row2] To physical row index.
   * @param {Number} [column2] To physical column index (or visual index, if data type is an array of objects).
   * @returns {Array[]|Object[]} The table data.
   */


  this.getSourceData = function (row, column, row2, column2) {
    var data;

    if (row === void 0) {
      data = dataSource.getData();
    } else {
      data = dataSource.getByRange(new _src.CellCoords(row, column), new _src.CellCoords(row2, column2));
    }

    return data;
  };
  /**
   * Returns the source data object as an arrays of arrays format even when source data was provided in another format.
   * Optionally you can provide a cell range by using the `row`, `column`, `row2`, `column2` arguments, to get only a
   * fragment of the table data.
   *
   * __Note__: This method does not participate in data transformation. If the visual data of the table is reordered,
   * sorted or trimmed only physical indexes are correct.
   *
   * @memberof Core#
   * @function getSourceDataArray
   * @param {Number} [row] From physical row index.
   * @param {Number} [column] From physical column index (or visual index, if data type is an array of objects).
   * @param {Number} [row2] To physical row index.
   * @param {Number} [column2] To physical column index (or visual index, if data type is an array of objects).
   * @returns {Array} An array of arrays.
   */


  this.getSourceDataArray = function (row, column, row2, column2) {
    var data;

    if (row === void 0) {
      data = dataSource.getData(true);
    } else {
      data = dataSource.getByRange(new _src.CellCoords(row, column), new _src.CellCoords(row2, column2), true);
    }

    return data;
  };
  /**
   * Returns an array of column values from the data source.
   *
   * @memberof Core#
   * @function getSourceDataAtCol
   * @param {Number} column Visual column index.
   * @returns {Array} Array of the column's cell values.
   */
  // TODO: Getting data from `sourceData` should work always on physical indexes.


  this.getSourceDataAtCol = function (column) {
    return dataSource.getAtColumn(column);
  };
  /**
   * Returns a single row of the data (array or object, depending on what data format you use).
   *
   * __Note__: This method does not participate in data transformation. If the visual data of the table is reordered,
   * sorted or trimmed only physical indexes are correct.
   *
   * @memberof Core#
   * @function getSourceDataAtRow
   * @param {Number} row Physical row index.
   * @returns {Array|Object} Single row of data.
   */


  this.getSourceDataAtRow = function (row) {
    return dataSource.getAtRow(row);
  };
  /**
   * Returns a single value from the data source.
   *
   * @memberof Core#
   * @function getSourceDataAtCell
   * @param {Number} row Physical row index.
   * @param {Number} column Visual column index.
   * @returns {*} Cell data.
   */
  // TODO: Getting data from `sourceData` should work always on physical indexes.


  this.getSourceDataAtCell = function (row, column) {
    return dataSource.getAtCell(row, column);
  };
  /**
   * @description
   * Returns a single row of the data.
   *
   * __Note__: If rows were reordered, sorted or trimmed, the currently visible order will be used.
   *
   * @memberof Core#
   * @function getDataAtRow
   * @param {Number} row Visual row index.
   * @returns {Array} Array of row's cell data.
   */


  this.getDataAtRow = function (row) {
    var data = datamap.getRange(new _src.CellCoords(row, 0), new _src.CellCoords(row, this.countCols() - 1), datamap.DESTINATION_RENDERER);
    return data[0] || [];
  };
  /**
   * @description
   * Returns a data type defined in the Handsontable settings under the `type` key ([Options#type](http://docs.handsontable.com/Options.html#type)).
   * If there are cells with different types in the selected range, it returns `'mixed'`.
   *
   * __Note__: If data is reordered, sorted or trimmed, the currently visible order will be used.
   *
   * @memberof Core#
   * @function getDataType
   * @param {Number} rowFrom From visual row index.
   * @param {Number} columnFrom From visual column index.
   * @param {Number} rowTo To visual row index.
   * @param {Number} columnTo To visual column index.
   * @returns {String} Cell type (e.q: `'mixed'`, `'text'`, `'numeric'`, `'autocomplete'`).
   */


  this.getDataType = function (rowFrom, columnFrom, rowTo, columnTo) {
    var _this3 = this;

    var coords = rowFrom === void 0 ? [0, 0, this.countRows(), this.countCols()] : [rowFrom, columnFrom, rowTo, columnTo];
    var rowStart = coords[0],
        columnStart = coords[1];
    var rowEnd = coords[2],
        columnEnd = coords[3];
    var previousType = null;
    var currentType = null;

    if (rowEnd === void 0) {
      rowEnd = rowStart;
    }

    if (columnEnd === void 0) {
      columnEnd = columnStart;
    }

    var type = 'mixed';
    (0, _number.rangeEach)(Math.min(rowStart, rowEnd), Math.max(rowStart, rowEnd), function (row) {
      var isTypeEqual = true;
      (0, _number.rangeEach)(Math.min(columnStart, columnEnd), Math.max(columnStart, columnEnd), function (column) {
        var cellType = _this3.getCellMeta(row, column);

        currentType = cellType.type;

        if (previousType) {
          isTypeEqual = previousType === currentType;
        } else {
          previousType = currentType;
        }

        return isTypeEqual;
      });
      type = isTypeEqual ? currentType : 'mixed';
      return isTypeEqual;
    });
    return type;
  };
  /**
   * Remove a property defined by the `key` argument from the cell meta object for the provided `row` and `column` coordinates.
   *
   * @memberof Core#
   * @function removeCellMeta
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @param {String} key Property name.
   * @fires Hooks#beforeRemoveCellMeta
   * @fires Hooks#afterRemoveCellMeta
   */


  this.removeCellMeta = function (row, column, key) {
    var _recordTranslator$toP = recordTranslator.toPhysical(row, column),
        _recordTranslator$toP2 = (0, _slicedToArray2.default)(_recordTranslator$toP, 2),
        physicalRow = _recordTranslator$toP2[0],
        physicalColumn = _recordTranslator$toP2[1];

    var cachedValue = priv.cellSettings[physicalRow][physicalColumn][key];
    var hookResult = instance.runHooks('beforeRemoveCellMeta', row, column, key, cachedValue);

    if (hookResult !== false) {
      delete priv.cellSettings[physicalRow][physicalColumn][key];
      instance.runHooks('afterRemoveCellMeta', row, column, key, cachedValue);
    }

    cachedValue = null;
  };
  /**
   * Remove one or more rows from the cell meta object.
   *
   * @since 0.30.0
   * @param {Number} index An integer that specifies at what position to add/remove items, Use negative values to specify the position from the end of the array.
   * @param {Number} deleteAmount The number of items to be removed. If set to 0, no items will be removed.
   * @param {Array} items The new items to be added to the array.
   */


  this.spliceCellsMeta = function (index, deleteAmount) {
    var _priv$cellSettings;

    for (var _len4 = arguments.length, items = new Array(_len4 > 2 ? _len4 - 2 : 0), _key3 = 2; _key3 < _len4; _key3++) {
      items[_key3 - 2] = arguments[_key3];
    }

    (_priv$cellSettings = priv.cellSettings).splice.apply(_priv$cellSettings, [index, deleteAmount].concat(items));
  };
  /**
   * Set cell meta data object defined by `prop` to the corresponding params `row` and `column`.
   *
   * @memberof Core#
   * @function setCellMetaObject
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @param {Object} prop Meta object.
   */


  this.setCellMetaObject = function (row, column, prop) {
    var _this4 = this;

    if ((0, _typeof2.default)(prop) === 'object') {
      (0, _object.objectEach)(prop, function (value, key) {
        _this4.setCellMeta(row, column, key, value);
      });
    }
  };
  /**
   * Sets a property defined by the `key` property to the meta object of a cell corresponding to params `row` and `column`.
   *
   * @memberof Core#
   * @function setCellMeta
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @param {String} key Property name.
   * @param {String} value Property value.
   * @fires Hooks#afterSetCellMeta
   */


  this.setCellMeta = function (row, column, key, value) {
    var _recordTranslator$toP3 = recordTranslator.toPhysical(row, column),
        _recordTranslator$toP4 = (0, _slicedToArray2.default)(_recordTranslator$toP3, 2),
        physicalRow = _recordTranslator$toP4[0],
        physicalColumn = _recordTranslator$toP4[1];

    if (!priv.columnSettings[physicalColumn]) {
      priv.columnSettings[physicalColumn] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts);
    }

    if (!priv.cellSettings[physicalRow]) {
      priv.cellSettings[physicalRow] = [];
    }

    if (!priv.cellSettings[physicalRow][physicalColumn]) {
      priv.cellSettings[physicalRow][physicalColumn] = new priv.columnSettings[physicalColumn]();
    }

    priv.cellSettings[physicalRow][physicalColumn][key] = value;
    instance.runHooks('afterSetCellMeta', row, column, key, value);
  };
  /**
   * Get all the cells meta settings at least once generated in the table (in order of cell initialization).
   *
   * @memberof Core#
   * @function getCellsMeta
   * @returns {Array} Returns an array of ColumnSettings object instances.
   */


  this.getCellsMeta = function () {
    return (0, _array.arrayFlatten)(priv.cellSettings);
  };
  /**
   * Returns the cell properties object for the given `row` and `column` coordinates.
   *
   * @memberof Core#
   * @function getCellMeta
   * @param {Number} row Visual row index.
   * @param {Number} column Visual column index.
   * @returns {Object} The cell properties object.
   * @fires Hooks#beforeGetCellMeta
   * @fires Hooks#afterGetCellMeta
   */


  this.getCellMeta = function (row, column) {
    var prop = datamap.colToProp(column);

    var _recordTranslator$toP5 = recordTranslator.toPhysical(row, column),
        _recordTranslator$toP6 = (0, _slicedToArray2.default)(_recordTranslator$toP5, 2),
        potentialPhysicalRow = _recordTranslator$toP6[0],
        physicalColumn = _recordTranslator$toP6[1];

    var physicalRow = potentialPhysicalRow; // Workaround for #11. Connected also with #3849. It should be fixed within #4497.

    if (physicalRow === null) {
      physicalRow = row;
    }

    if (!priv.columnSettings[physicalColumn]) {
      priv.columnSettings[physicalColumn] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts);
    }

    if (!priv.cellSettings[physicalRow]) {
      priv.cellSettings[physicalRow] = [];
    }

    if (!priv.cellSettings[physicalRow][physicalColumn]) {
      priv.cellSettings[physicalRow][physicalColumn] = new priv.columnSettings[physicalColumn]();
    }

    var cellProperties = priv.cellSettings[physicalRow][physicalColumn]; // retrieve cellProperties from cache

    cellProperties.row = physicalRow;
    cellProperties.col = physicalColumn;
    cellProperties.visualRow = row;
    cellProperties.visualCol = column;
    cellProperties.prop = prop;
    cellProperties.instance = instance;
    instance.runHooks('beforeGetCellMeta', row, column, cellProperties);
    (0, _object.extend)(cellProperties, expandType(cellProperties)); // for `type` added in beforeGetCellMeta

    if (cellProperties.cells) {
      var settings = cellProperties.cells.call(cellProperties, physicalRow, physicalColumn, prop);

      if (settings) {
        (0, _object.extend)(cellProperties, settings);
        (0, _object.extend)(cellProperties, expandType(settings)); // for `type` added in cells
      }
    }

    instance.runHooks('afterGetCellMeta', row, column, cellProperties);
    return cellProperties;
  };
  /**
   * Returns an array of cell meta objects for specyfied physical row index.
   *
   * @memberof Core#
   * @function getCellMetaAtRow
   * @param {Number} row Physical row index.
   * @returns {Array}
   */


  this.getCellMetaAtRow = function (row) {
    return priv.cellSettings[row];
  };
  /**
   * Checks if the data format and config allows user to modify the column structure.
   *
   * @memberof Core#
   * @function isColumnModificationAllowed
   * @returns {Boolean}
   */


  this.isColumnModificationAllowed = function () {
    return !(instance.dataType === 'object' || instance.getSettings().columns);
  };

  var rendererLookup = (0, _data.cellMethodLookupFactory)('renderer');
  /**
   * Returns the cell renderer function by given `row` and `column` arguments.
   *
   * @memberof Core#
   * @function getCellRenderer
   * @param {Number|Object} row Visual row index or cell meta object (see {@link Core#getCellMeta}).
   * @param {Number} column Visual column index.
   * @returns {Function} The renderer function.
   * @example
   * ```js
   * // Get cell renderer using `row` and `column` coordinates.
   * hot.getCellRenderer(1, 1);
   * // Get cell renderer using cell meta object.
   * hot.getCellRenderer(hot.getCellMeta(1, 1));
   * ```
   */

  this.getCellRenderer = function (row, column) {
    return (0, _renderers.getRenderer)(rendererLookup.call(this, row, column));
  };
  /**
   * Returns the cell editor class by the provided `row` and `column` arguments.
   *
   * @memberof Core#
   * @function getCellEditor
   * @param {Number} row Visual row index or cell meta object (see {@link Core#getCellMeta}).
   * @param {Number} column Visual column index.
   * @returns {Function} The editor class.
   * @example
   * ```js
   * // Get cell editor class using `row` and `column` coordinates.
   * hot.getCellEditor(1, 1);
   * // Get cell editor class using cell meta object.
   * hot.getCellEditor(hot.getCellMeta(1, 1));
   * ```
   */


  this.getCellEditor = (0, _data.cellMethodLookupFactory)('editor');
  var validatorLookup = (0, _data.cellMethodLookupFactory)('validator');
  /**
   * Returns the cell validator by `row` and `column`.
   *
   * @memberof Core#
   * @function getCellValidator
   * @param {Number|Object} row Visual row index or cell meta object (see {@link Core#getCellMeta}).
   * @param {Number} column Visual column index.
   * @returns {Function|RegExp|undefined} The validator function.
   * @example
   * ```js
   * // Get cell valiator using `row` and `column` coordinates.
   * hot.getCellValidator(1, 1);
   * // Get cell valiator using cell meta object.
   * hot.getCellValidator(hot.getCellMeta(1, 1));
   * ```
   */

  this.getCellValidator = function (row, column) {
    var validator = validatorLookup.call(this, row, column);

    if (typeof validator === 'string') {
      validator = (0, _validators.getValidator)(validator);
    }

    return validator;
  };
  /**
   * Validates all cells using their validator functions and calls callback when finished.
   *
   * If one of the cells is invalid, the callback will be fired with `'valid'` arguments as `false` - otherwise it
   * would equal `true`.
   *
   * @memberof Core#
   * @function validateCells
   * @param {Function} [callback] The callback function.
   * @example
   * ```js
   * hot.validateCells((valid) => {
   *   if (valid) {
   *     // ... code for validated cells
   *   }
   * })
   * ```
   */


  this.validateCells = function (callback) {
    this._validateCells(callback);
  };
  /**
   * Validates rows using their validator functions and calls callback when finished.
   *
   * If one of the cells is invalid, the callback will be fired with `'valid'` arguments as `false` - otherwise it
   *  would equal `true`.
   *
   * @memberof Core#
   * @function validateRows
   * @param {Array} [rows] Array of validation target visual row indexes.
   * @param {Function} [callback] The callback function.
   * @example
   * ```js
   * hot.validateRows([3, 4, 5], (valid) => {
   *   if (valid) {
   *     // ... code for validated rows
   *   }
   * })
   * ```
   */


  this.validateRows = function (rows, callback) {
    if (!Array.isArray(rows)) {
      throw new Error('validateRows parameter `rows` must be an array');
    }

    this._validateCells(callback, rows);
  };
  /**
   * Validates columns using their validator functions and calls callback when finished.
   *
   * If one of the cells is invalid, the callback will be fired with `'valid'` arguments as `false` - otherwise it
   *  would equal `true`.
   *
   * @memberof Core#
   * @function validateColumns
   * @param {Array} [columns] Array of validation target visual columns indexes.
   * @param {Function} [callback] The callback function.
   * @example
   * ```js
   * hot.validateColumns([3, 4, 5], (valid) => {
   *   if (valid) {
   *     // ... code for validated columns
   *   }
   * })
   * ```
   */


  this.validateColumns = function (columns, callback) {
    if (!Array.isArray(columns)) {
      throw new Error('validateColumns parameter `columns` must be an array');
    }

    this._validateCells(callback, undefined, columns);
  };
  /**
   * Validates all cells using their validator functions and calls callback when finished.
   *
   * If one of the cells is invalid, the callback will be fired with `'valid'` arguments as `false` - otherwise it would equal `true`.
   *
   * Private use intended.
   *
   * @private
   * @memberof Core#
   * @function _validateCells
   * @param {Function} [callback] The callback function.
   * @param {Array} [rows] An array of validation target visual row indexes.
   * @param {Array} [columns] An array of validation target visual column indexes.
   */


  this._validateCells = function (callback, rows, columns) {
    var waitingForValidator = new ValidatorsQueue();

    if (callback) {
      waitingForValidator.onQueueEmpty = callback;
    }

    var i = instance.countRows() - 1;

    while (i >= 0) {
      if (rows !== undefined && rows.indexOf(i) === -1) {
        i -= 1;
        continue;
      }

      var j = instance.countCols() - 1;

      while (j >= 0) {
        if (columns !== undefined && columns.indexOf(j) === -1) {
          j -= 1;
          continue;
        }

        waitingForValidator.addValidatorToQueue();
        instance.validateCell(instance.getDataAtCell(i, j), instance.getCellMeta(i, j), function (result) {
          if (typeof result !== 'boolean') {
            throw new Error('Validation error: result is not boolean');
          }

          if (result === false) {
            waitingForValidator.valid = false;
          }

          waitingForValidator.removeValidatorFormQueue();
        }, 'validateCells');
        j -= 1;
      }

      i -= 1;
    }

    waitingForValidator.checkIfQueueIsEmpty();
  };
  /**
   * Returns an array of row headers' values (if they are enabled). If param `row` was given, it returns the header of the given row as a string.
   *
   * @memberof Core#
   * @function getRowHeader
   * @param {Number} [row] Visual row index.
   * @fires Hooks#modifyRowHeader
   * @returns {Array|String|Number} Array of header values / single header value.
   */


  this.getRowHeader = function (row) {
    var rowHeader = priv.settings.rowHeaders;
    var physicalRow = row;

    if (physicalRow !== void 0) {
      physicalRow = instance.runHooks('modifyRowHeader', physicalRow);
    }

    if (physicalRow === void 0) {
      rowHeader = [];
      (0, _number.rangeEach)(instance.countRows() - 1, function (i) {
        rowHeader.push(instance.getRowHeader(i));
      });
    } else if (Array.isArray(rowHeader) && rowHeader[physicalRow] !== void 0) {
      rowHeader = rowHeader[physicalRow];
    } else if ((0, _function.isFunction)(rowHeader)) {
      rowHeader = rowHeader(physicalRow);
    } else if (rowHeader && typeof rowHeader !== 'string' && typeof rowHeader !== 'number') {
      rowHeader = physicalRow + 1;
    }

    return rowHeader;
  };
  /**
   * Returns information about if this table is configured to display row headers.
   *
   * @memberof Core#
   * @function hasRowHeaders
   * @returns {Boolean} `true` if the instance has the row headers enabled, `false` otherwise.
   */


  this.hasRowHeaders = function () {
    return !!priv.settings.rowHeaders;
  };
  /**
   * Returns information about if this table is configured to display column headers.
   *
   * @memberof Core#
   * @function hasColHeaders
   * @returns {Boolean} `true` if the instance has the column headers enabled, `false` otherwise.
   */


  this.hasColHeaders = function () {
    if (priv.settings.colHeaders !== void 0 && priv.settings.colHeaders !== null) {
      // Polymer has empty value = null
      return !!priv.settings.colHeaders;
    }

    for (var i = 0, ilen = instance.countCols(); i < ilen; i++) {
      if (instance.getColHeader(i)) {
        return true;
      }
    }

    return false;
  };
  /**
   * Returns an array of column headers (in string format, if they are enabled). If param `column` is given, it
   * returns the header at the given column.
   *
   * @memberof Core#
   * @function getColHeader
   * @param {Number} [column] Visual column index.
   * @fires Hooks#modifyColHeader
   * @returns {Array|String|Number} The column header(s).
   */


  this.getColHeader = function (column) {
    var columnsAsFunc = priv.settings.columns && (0, _function.isFunction)(priv.settings.columns);
    var columnIndex = instance.runHooks('modifyColHeader', column);
    var result = priv.settings.colHeaders;

    if (columnIndex === void 0) {
      var out = [];
      var ilen = columnsAsFunc ? instance.countSourceCols() : instance.countCols();

      for (var i = 0; i < ilen; i++) {
        out.push(instance.getColHeader(i));
      }

      result = out;
    } else {
      var translateVisualIndexToColumns = function translateVisualIndexToColumns(visualColumnIndex) {
        var arr = [];
        var columnsLen = instance.countSourceCols();
        var index = 0;

        for (; index < columnsLen; index++) {
          if ((0, _function.isFunction)(instance.getSettings().columns) && instance.getSettings().columns(index)) {
            arr.push(index);
          }
        }

        return arr[visualColumnIndex];
      };

      var baseCol = columnIndex;
      var physicalColumn = instance.runHooks('modifyCol', baseCol);
      var prop = translateVisualIndexToColumns(physicalColumn);

      if (priv.settings.colHeaders === false) {
        result = null;
      } else if (priv.settings.columns && (0, _function.isFunction)(priv.settings.columns) && priv.settings.columns(prop) && priv.settings.columns(prop).title) {
        result = priv.settings.columns(prop).title;
      } else if (priv.settings.columns && priv.settings.columns[physicalColumn] && priv.settings.columns[physicalColumn].title) {
        result = priv.settings.columns[physicalColumn].title;
      } else if (Array.isArray(priv.settings.colHeaders) && priv.settings.colHeaders[physicalColumn] !== void 0) {
        result = priv.settings.colHeaders[physicalColumn];
      } else if ((0, _function.isFunction)(priv.settings.colHeaders)) {
        result = priv.settings.colHeaders(physicalColumn);
      } else if (priv.settings.colHeaders && typeof priv.settings.colHeaders !== 'string' && typeof priv.settings.colHeaders !== 'number') {
        result = (0, _data.spreadsheetColumnLabel)(baseCol); // see #1458
      }
    }

    return result;
  };
  /**
   * Return column width from settings (no guessing). Private use intended.
   *
   * @private
   * @memberof Core#
   * @function _getColWidthFromSettings
   * @param {Number} col Visual col index.
   * @returns {Number}
   */


  this._getColWidthFromSettings = function (col) {
    var cellProperties = instance.getCellMeta(0, col);
    var width = cellProperties.width;

    if (width === void 0 || width === priv.settings.width) {
      width = cellProperties.colWidths;
    }

    if (width !== void 0 && width !== null) {
      switch ((0, _typeof2.default)(width)) {
        case 'object':
          // array
          width = width[col];
          break;

        case 'function':
          width = width(col);
          break;

        default:
          break;
      }

      if (typeof width === 'string') {
        width = parseInt(width, 10);
      }
    }

    return width;
  };
  /**
   * Returns the width of the requested column.
   *
   * @memberof Core#
   * @function getColWidth
   * @param {Number} column Visual column index.
   * @returns {Number} Column width.
   * @fires Hooks#modifyColWidth
   */


  this.getColWidth = function (column) {
    var width = instance._getColWidthFromSettings(column);

    width = instance.runHooks('modifyColWidth', width, column);

    if (width === void 0) {
      width = _src.ViewportColumnsCalculator.DEFAULT_WIDTH;
    }

    return width;
  };
  /**
   * Return row height from settings (no guessing). Private use intended.
   *
   * @private
   * @memberof Core#
   * @function _getRowHeightFromSettings
   * @param {Number} row Visual row index.
   * @returns {Number}
   */


  this._getRowHeightFromSettings = function (row) {
    // let cellProperties = instance.getCellMeta(row, 0);
    // let height = cellProperties.height;
    //
    // if (height === void 0 || height === priv.settings.height) {
    //  height = cellProperties.rowHeights;
    // }
    var height = priv.settings.rowHeights;

    if (height !== void 0 && height !== null) {
      switch ((0, _typeof2.default)(height)) {
        case 'object':
          // array
          height = height[row];
          break;

        case 'function':
          height = height(row);
          break;

        default:
          break;
      }

      if (typeof height === 'string') {
        height = parseInt(height, 10);
      }
    }

    return height;
  };
  /**
   * Returns the row height.
   *
   * @memberof Core#
   * @function getRowHeight
   * @param {Number} row Visual row index.
   * @returns {Number} The given row's height.
   * @fires Hooks#modifyRowHeight
   */


  this.getRowHeight = function (row) {
    var height = instance._getRowHeightFromSettings(row);

    height = instance.runHooks('modifyRowHeight', height, row);
    return height;
  };
  /**
   * Returns the total number of rows in the data source.
   *
   * @memberof Core#
   * @function countSourceRows
   * @returns {Number} Total number of rows.
   */


  this.countSourceRows = function () {
    var sourceLength = instance.runHooks('modifySourceLength');
    return sourceLength || (instance.getSourceData() ? instance.getSourceData().length : 0);
  };
  /**
   * Returns the total number of columns in the data source.
   *
   * @memberof Core#
   * @function countSourceCols
   * @returns {Number} Total number of columns.
   */


  this.countSourceCols = function () {
    var len = 0;
    var obj = instance.getSourceData() && instance.getSourceData()[0] ? instance.getSourceData()[0] : [];

    if ((0, _object.isObject)(obj)) {
      len = (0, _object.deepObjectSize)(obj);
    } else {
      len = obj.length || 0;
    }

    return len;
  };
  /**
   * Returns the total number of visual rows in the table.
   *
   * @memberof Core#
   * @function countRows
   * @returns {Number} Total number of rows.
   */


  this.countRows = function () {
    return datamap.getLength();
  };
  /**
   * Returns the total number of visible columns in the table.
   *
   * @memberof Core#
   * @function countCols
   * @returns {Number} Total number of columns.
   */


  this.countCols = function () {
    var maxCols = this.getSettings().maxCols;
    var dataHasLength = false;
    var dataLen = 0;

    if (instance.dataType === 'array') {
      dataHasLength = priv.settings.data && priv.settings.data[0] && priv.settings.data[0].length;
    }

    if (dataHasLength) {
      dataLen = priv.settings.data[0].length;
    }

    if (priv.settings.columns) {
      var columnsIsFunction = (0, _function.isFunction)(priv.settings.columns);

      if (columnsIsFunction) {
        if (instance.dataType === 'array') {
          var columnLen = 0;

          for (var i = 0; i < dataLen; i++) {
            if (priv.settings.columns(i)) {
              columnLen += 1;
            }
          }

          dataLen = columnLen;
        } else if (instance.dataType === 'object' || instance.dataType === 'function') {
          dataLen = datamap.colToPropCache.length;
        }
      } else {
        dataLen = priv.settings.columns.length;
      }
    } else if (instance.dataType === 'object' || instance.dataType === 'function') {
      dataLen = datamap.colToPropCache.length;
    }

    return Math.min(maxCols, dataLen);
  };
  /**
   * Returns an visual index of the first rendered row.
   *
   * @memberof Core#
   * @function rowOffset
   * @returns {Number} Visual index of first rendered row.
   */


  this.rowOffset = function () {
    return instance.view.wt.wtTable.getFirstRenderedRow();
  };
  /**
   * Returns the visual index of the first rendered column.
   *
   * @memberof Core#
   * @function colOffset
   * @returns {Number} Visual index of the first visible column.
   */


  this.colOffset = function () {
    return instance.view.wt.wtTable.getFirstRenderedColumn();
  };
  /**
   * Returns the number of rendered rows (including rows partially or fully rendered outside viewport).
   *
   * @memberof Core#
   * @function countRenderedRows
   * @returns {Number} Returns -1 if table is not visible.
   */


  this.countRenderedRows = function () {
    return instance.view.wt.drawn ? instance.view.wt.wtTable.getRenderedRowsCount() : -1;
  };
  /**
   * Returns the number of visible rows (rendered rows that fully fit inside viewport).
   *
   * @memberof Core#
   * @function countVisibleRows
   * @returns {Number} Number of visible rows or -1.
   */


  this.countVisibleRows = function () {
    return instance.view.wt.drawn ? instance.view.wt.wtTable.getVisibleRowsCount() : -1;
  };
  /**
   * Returns the number of rendered columns (including columns partially or fully rendered outside viewport).
   *
   * @memberof Core#
   * @function countRenderedCols
   * @returns {Number} Returns -1 if table is not visible.
   */


  this.countRenderedCols = function () {
    return instance.view.wt.drawn ? instance.view.wt.wtTable.getRenderedColumnsCount() : -1;
  };
  /**
   * Returns the number of visible columns. Returns -1 if table is not visible
   *
   * @memberof Core#
   * @function countVisibleCols
   * @return {Number} Number of visible columns or -1.
   */


  this.countVisibleCols = function () {
    return instance.view.wt.drawn ? instance.view.wt.wtTable.getVisibleColumnsCount() : -1;
  };
  /**
   * Returns the number of empty rows. If the optional ending parameter is `true`, returns the
   * number of empty rows at the bottom of the table.
   *
   * @memberof Core#
   * @function countEmptyRows
   * @param {Boolean} [ending=false] If `true`, will only count empty rows at the end of the data source.
   * @returns {Number} Count empty rows.
   */


  this.countEmptyRows = function () {
    var ending = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var emptyRows = 0;
    (0, _number.rangeEachReverse)(instance.countRows() - 1, function (visualIndex) {
      if (instance.isEmptyRow(visualIndex)) {
        emptyRows += 1;
      } else if (ending === true) {
        return false;
      }
    });
    return emptyRows;
  };
  /**
   * Returns the number of empty columns. If the optional ending parameter is `true`, returns the number of empty
   * columns at right hand edge of the table.
   *
   * @memberof Core#
   * @function countEmptyCols
   * @param {Boolean} [ending=false] If `true`, will only count empty columns at the end of the data source row.
   * @returns {Number} Count empty cols.
   */


  this.countEmptyCols = function () {
    var ending = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

    if (instance.countRows() < 1) {
      return 0;
    }

    var emptyColumns = 0;
    (0, _number.rangeEachReverse)(instance.countCols() - 1, function (visualIndex) {
      if (instance.isEmptyCol(visualIndex)) {
        emptyColumns += 1;
      } else if (ending === true) {
        return false;
      }
    });
    return emptyColumns;
  };
  /**
   * Check if all cells in the row declared by the `row` argument are empty.
   *
   * @memberof Core#
   * @function isEmptyRow
   * @param {Number} row Visual row index.
   * @returns {Boolean} `true` if the row at the given `row` is empty, `false` otherwise.
   */


  this.isEmptyRow = function (row) {
    return priv.settings.isEmptyRow.call(instance, row);
  };
  /**
   * Check if all cells in the the column declared by the `column` argument are empty.
   *
   * @memberof Core#
   * @function isEmptyCol
   * @param {Number} column Column index.
   * @returns {Boolean} `true` if the column at the given `col` is empty, `false` otherwise.
   */


  this.isEmptyCol = function (column) {
    return priv.settings.isEmptyCol.call(instance, column);
  };
  /**
   * Select cell specified by `row` and `column` values or a range of cells finishing at `endRow`, `endCol`. If the table
   * was configured to support data column properties that properties can be used to making a selection.
   *
   * By default, viewport will be scrolled to the selection. After the `selectCell` method had finished, the instance
   * will be listening to keyboard input on the document.
   *
   * @example
   * ```js
   * // select a single cell
   * hot.selectCell(2, 4);
   * // select a single cell using column property
   * hot.selectCell(2, 'address');
   * // select a range of cells
   * hot.selectCell(2, 4, 3, 5);
   * // select a range of cells using column properties
   * hot.selectCell(2, 'address', 3, 'phone_number');
   * // select a range of cells without scrolling to them
   * hot.selectCell(2, 'address', 3, 'phone_number', false);
   * ```
   *
   * @memberof Core#
   * @function selectCell
   * @param {Number} row Visual row index.
   * @param {Number|String} column Visual column index or column property.
   * @param {Number} [endRow] Visual end row index (if selecting a range).
   * @param {Number|String} [endColumn] Visual end column index or column property (if selecting a range).
   * @param {Boolean} [scrollToCell=true] If `true`, the viewport will be scrolled to the selection.
   * @param {Boolean} [changeListener=true] If `false`, Handsontable will not change keyboard events listener to himself.
   * @returns {Boolean} `true` if selection was successful, `false` otherwise.
   */


  this.selectCell = function (row, column, endRow, endColumn) {
    var scrollToCell = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var changeListener = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;

    if ((0, _mixed.isUndefined)(row) || (0, _mixed.isUndefined)(column)) {
      return false;
    }

    return this.selectCells([[row, column, endRow, endColumn]], scrollToCell, changeListener);
  };
  /**
   * Make multiple, non-contiguous selection specified by `row` and `column` values or a range of cells
   * finishing at `endRow`, `endColumn`. The method supports two input formats which are the same as that
   * produces by `getSelected` and `getSelectedRange` methods.
   *
   * By default, viewport will be scrolled to selection. After the `selectCells` method had finished, the instance
   * will be listening to keyboard input on the document.
   *
   * @example
   * ```js
   * // Using an array of arrays.
   * hot.selectCells([[1, 1, 2, 2], [3, 3], [6, 2, 0, 2]]);
   * // Using an array of arrays with defined columns as props.
   * hot.selectCells([[1, 'id', 2, 'first_name'], [3, 'full_name'], [6, 'last_name', 0, 'first_name']]);
   * // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
   * const selected = hot.getSelectedRange();
   *
   * selected[0].from.row = 0;
   * selected[0].from.col = 0;
   *
   * hot.selectCells(selected);
   * ```
   *
   * @memberof Core#
   * @since 0.38.0
   * @function selectCells
   * @param {Array[]|CellRange[]} coords Visual coords passed as an array of array (`[[rowStart, columnStart, rowEnd, columnEnd], ...]`)
   *                                     the same format as `getSelected` method returns or as an CellRange objects
   *                                     which is the same format what `getSelectedRange` method returns.
   * @param {Boolean} [scrollToCell=true] If `true`, the viewport will be scrolled to the selection.
   * @param {Boolean} [changeListener=true] If `false`, Handsontable will not change keyboard events listener to himself.
   * @returns {Boolean} `true` if selection was successful, `false` otherwise.
   */


  this.selectCells = function () {
    var coords = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [[]];
    var scrollToCell = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var changeListener = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;

    if (scrollToCell === false) {
      preventScrollingToCell = true;
    }

    var wasSelected = selection.selectCells(coords);

    if (wasSelected && changeListener) {
      instance.listen();
    }

    preventScrollingToCell = false;
    return wasSelected;
  };
  /**
   * Select column specified by `startColumn` visual index, column property or a range of columns finishing at `endColumn`.
   *
   * @example
   * ```js
   * // Select column using visual index.
   * hot.selectColumns(1);
   * // Select column using column property.
   * hot.selectColumns('id');
   * // Select range of columns using visual indexes.
   * hot.selectColumns(1, 4);
   * // Select range of columns using column properties.
   * hot.selectColumns('id', 'last_name');
   * ```
   *
   * @memberof Core#
   * @since 0.38.0
   * @function selectColumns
   * @param {Number} startColumn The visual column index from which the selection starts.
   * @param {Number} [endColumn=startColumn] The visual column index to which the selection finishes. If `endColumn`
   *                                         is not defined the column defined by `startColumn` will be selected.
   * @returns {Boolean} `true` if selection was successful, `false` otherwise.
   */


  this.selectColumns = function (startColumn) {
    var endColumn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : startColumn;
    return selection.selectColumns(startColumn, endColumn);
  };
  /**
   * Select row specified by `startRow` visual index or a range of rows finishing at `endRow`.
   *
   * @example
   * ```js
   * // Select row using visual index.
   * hot.selectRows(1);
   * // Select range of rows using visual indexes.
   * hot.selectRows(1, 4);
   * ```
   *
   * @memberof Core#
   * @since 0.38.0
   * @function selectRows
   * @param {Number} startRow The visual row index from which the selection starts.
   * @param {Number} [endRow=startRow] The visual row index to which the selection finishes. If `endRow`
   *                                   is not defined the row defined by `startRow` will be selected.
   * @returns {Boolean} `true` if selection was successful, `false` otherwise.
   */


  this.selectRows = function (startRow) {
    var endRow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : startRow;
    return selection.selectRows(startRow, endRow);
  };
  /**
   * Deselects the current cell selection on the table.
   *
   * @memberof Core#
   * @function deselectCell
   */


  this.deselectCell = function () {
    selection.deselect();
  };
  /**
   * Select the whole table. The previous selection will be overwritten.
   *
   * @since 0.38.2
   * @memberof Core#
   * @function selectAll
   */


  this.selectAll = function () {
    preventScrollingToCell = true;
    selection.selectAll();
    preventScrollingToCell = false;
  };
  /**
   * Scroll viewport to coordinates specified by the `row` and `column` arguments.
   *
   * @memberof Core#
   * @function scrollViewportTo
   * @param {Number} [row] Visual row index.
   * @param {Number} [column] Visual column index.
   * @param {Boolean} [snapToBottom = false] If `true`, viewport is scrolled to show the cell on the bottom of the table.
   * @param {Boolean} [snapToRight = false] If `true`, viewport is scrolled to show the cell on the right side of the table.
   * @returns {Boolean} `true` if scroll was successful, `false` otherwise.
   */


  this.scrollViewportTo = function (row, column) {
    var snapToBottom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
    var snapToRight = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    var snapToTop = !snapToBottom;
    var snapToLeft = !snapToRight;
    var result = false;

    if (row !== void 0 && column !== void 0) {
      result = instance.view.scrollViewport(new _src.CellCoords(row, column), snapToTop, snapToRight, snapToBottom, snapToLeft);
    }

    if (typeof row === 'number' && typeof column !== 'number') {
      result = instance.view.scrollViewportVertically(row, snapToTop, snapToBottom);
    }

    if (typeof column === 'number' && typeof row !== 'number') {
      result = instance.view.scrollViewportHorizontally(column, snapToRight, snapToLeft);
    }

    return result;
  };
  /**
   * Removes the table from the DOM and destroys the instance of the Handsontable.
   *
   * @memberof Core#
   * @function destroy
   * @fires Hooks#afterDestroy
   */


  this.destroy = function () {
    instance._clearTimeouts();

    instance._clearImmediates();

    if (instance.view) {
      // in case HT is destroyed before initialization has finished
      instance.view.destroy();
    }

    if (dataSource) {
      dataSource.destroy();
    }

    dataSource = null;
    (0, _keyStateObserver.stopObserving)();

    if ((0, _rootInstance.isRootInstance)(instance)) {
      var licenseInfo = this.rootDocument.querySelector('#hot-display-license-info');

      if (licenseInfo) {
        licenseInfo.parentNode.removeChild(licenseInfo);
      }
    }

    (0, _element.empty)(instance.rootElement);
    eventManager.destroy();

    if (editorManager) {
      editorManager.destroy();
    }

    instance.runHooks('afterDestroy');

    _pluginHooks.default.getSingleton().destroy(instance);

    (0, _object.objectEach)(instance, function (property, key, obj) {
      // replace instance methods with post mortem
      if ((0, _function.isFunction)(property)) {
        obj[key] = postMortem(key);
      } else if (key !== 'guid') {
        // replace instance properties with null (restores memory)
        // it should not be necessary but this prevents a memory leak side effects that show itself in Jasmine tests
        obj[key] = null;
      }
    });
    instance.isDestroyed = true; // replace private properties with null (restores memory)
    // it should not be necessary but this prevents a memory leak side effects that show itself in Jasmine tests

    if (datamap) {
      datamap.destroy();
    }

    datamap = null;
    priv = null;
    grid = null;
    selection = null;
    editorManager = null;
    instance = null;
    GridSettings = null;
  };
  /**
   * Replacement for all methods after Handsotnable was destroyed.
   *
   * @private
   */


  function postMortem(method) {
    return function () {
      throw new Error("The \"".concat(method, "\" method cannot be called because this Handsontable instance has been destroyed"));
    };
  }
  /**
   * Returns the active editor class instance.
   *
   * @memberof Core#
   * @function getActiveEditor
   * @returns {BaseEditor} The active editor instance.
   */


  this.getActiveEditor = function () {
    return editorManager.getActiveEditor();
  };
  /**
   * Returns plugin instance by provided its name.
   *
   * @memberof Core#
   * @function getPlugin
   * @param {String} pluginName The plugin name.
   * @returns {BasePlugin} The plugin instance.
   */


  this.getPlugin = function (pluginName) {
    return (0, _plugins.getPlugin)(this, pluginName);
  };
  /**
   * Returns the Handsontable instance.
   *
   * @memberof Core#
   * @function getInstance
   * @returns {Handsontable} The Handsontable instance.
   */


  this.getInstance = function () {
    return instance;
  };
  /**
   * Adds listener to the specified hook name (only for this Handsontable instance).
   *
   * @memberof Core#
   * @function addHook
   * @see Hooks#add
   * @param {String} key Hook name (see {@link Hooks}).
   * @param {Function|Array} callback Function or array of functions.
   * @example
   * ```js
   * hot.addHook('beforeInit', myCallback);
   * ```
   */


  this.addHook = function (key, callback) {
    _pluginHooks.default.getSingleton().add(key, callback, instance);
  };
  /**
   * Check if for a specified hook name there are added listeners (only for this Handsontable instance). All available
   * hooks you will find {@link Hooks}.
   *
   * @memberof Core#
   * @function hasHook
   * @see Hooks#has
   * @param {String} key Hook name
   * @return {Boolean}
   *
   * @example
   * ```js
   * const hasBeforeInitListeners = hot.hasHook('beforeInit');
   * ```
   */


  this.hasHook = function (key) {
    return _pluginHooks.default.getSingleton().has(key, instance);
  };
  /**
   * Adds listener to specified hook name (only for this Handsontable instance). After the listener is triggered,
   * it will be automatically removed.
   *
   * @memberof Core#
   * @function addHookOnce
   * @see Hooks#once
   * @param {String} key Hook name (see {@link Hooks}).
   * @param {Function|Array} callback Function or array of functions.
   * @example
   * ```js
   * hot.addHookOnce('beforeInit', myCallback);
   * ```
   */


  this.addHookOnce = function (key, callback) {
    _pluginHooks.default.getSingleton().once(key, callback, instance);
  };
  /**
   * Removes the hook listener previously registered with {@link Core#addHook}.
   *
   * @memberof Core#
   * @function removeHook
   * @see Hooks#remove
   * @param {String} key Hook name.
   * @param {Function} callback Reference to the function which has been registered using {@link Core#addHook}.
   *
   * @example
   * ```js
   * hot.removeHook('beforeInit', myCallback);
   * ```
   */


  this.removeHook = function (key, callback) {
    _pluginHooks.default.getSingleton().remove(key, callback, instance);
  };
  /**
   * Run the callbacks for the hook provided in the `key` argument using the parameters given in the other arguments.
   *
   * @memberof Core#
   * @function runHooks
   * @see Hooks#run
   * @param {String} key Hook name.
   * @param {*} [p1] Argument passed to the callback.
   * @param {*} [p2] Argument passed to the callback.
   * @param {*} [p3] Argument passed to the callback.
   * @param {*} [p4] Argument passed to the callback.
   * @param {*} [p5] Argument passed to the callback.
   * @param {*} [p6] Argument passed to the callback.
   * @returns {*}
   *
   * @example
   * ```js
   * // Run built-in hook
   * hot.runHooks('beforeInit');
   * // Run custom hook
   * hot.runHooks('customAction', 10, 'foo');
   * ```
   */


  this.runHooks = function (key, p1, p2, p3, p4, p5, p6) {
    return _pluginHooks.default.getSingleton().run(instance, key, p1, p2, p3, p4, p5, p6);
  };
  /**
   * Get language phrase for specified dictionary key.
   *
   * @memberof Core#
   * @function getTranslatedPhrase
   * @since 0.35.0
   * @param {String} dictionaryKey Constant which is dictionary key.
   * @param {*} extraArguments Arguments which will be handled by formatters.
   * @returns {String}
   */


  this.getTranslatedPhrase = function (dictionaryKey, extraArguments) {
    return (0, _i18n.getTranslatedPhrase)(priv.settings.language, dictionaryKey, extraArguments);
  };

  this.timeouts = [];
  /**
   * Sets timeout. Purpose of this method is to clear all known timeouts when `destroy` method is called.
   *
   * @param {Number|Function} handle Handler returned from setTimeout or function to execute (it will be automatically wraped
   *                                 by setTimeout function).
   * @param {Number} [delay=0] If first argument is passed as a function this argument set delay of the execution of that function.
   * @private
   */

  this._registerTimeout = function (handle) {
    var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var handleFunc = handle;

    if (typeof handleFunc === 'function') {
      handleFunc = setTimeout(handleFunc, delay);
    }

    this.timeouts.push(handleFunc);
  };
  /**
   * Clears all known timeouts.
   *
   * @private
   */


  this._clearTimeouts = function () {
    (0, _array.arrayEach)(this.timeouts, function (handler) {
      clearTimeout(handler);
    });
  };

  this.immediates = [];
  /**
   * Execute function execution to the next event loop cycle. Purpose of this method is to clear all known timeouts when `destroy` method is called.
   *
   * @param {Function} callback Function to be delayed in execution.
   * @private
   */

  this._registerImmediate = function (callback) {
    this.immediates.push(setImmediate(callback));
  };
  /**
   * Clears all known timeouts.
   *
   * @private
   */


  this._clearImmediates = function () {
    (0, _array.arrayEach)(this.immediates, function (handler) {
      clearImmediate(handler);
    });
  };
  /**
   * Refresh selection borders. This is temporary method relic after selection rewrite.
   *
   * @private
   * @param {Boolean} [revertOriginal=false] If `true`, the previous value will be restored. Otherwise, the edited value will be saved.
   * @param {Boolean} [prepareEditorIfNeeded=true] If `true` the editor under the selected cell will be prepared to open.
   */


  this._refreshBorders = function () {
    var revertOriginal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var prepareEditorIfNeeded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    editorManager.destroyEditor(revertOriginal);
    instance.view.render();

    if (prepareEditorIfNeeded && selection.isSelected()) {
      editorManager.prepareEditor();
    }
  };

  _pluginHooks.default.getSingleton().run(instance, 'construct');
}

/***/ }),
/* 162 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.columnFactory = columnFactory;

var _object = __webpack_require__(4);

/* eslint-disable import/prefer-default-export */

/**
 * Factory for columns constructors.
 *
 * @param {Object} GridSettings
 * @param {Array} conflictList
 * @return {Object} ColumnSettings
 */
function columnFactory(GridSettings, conflictList) {
  function ColumnSettings() {}

  (0, _object.inherit)(ColumnSettings, GridSettings); // Clear conflict settings

  for (var i = 0, len = conflictList.length; i < len; i++) {
    ColumnSettings.prototype[conflictList[i]] = void 0;
  }

  return ColumnSettings;
}

/***/ }),
/* 163 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(105);

__webpack_require__(482);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

/**
 * @class GhostTable
 * @util
 */
var GhostTable =
/*#__PURE__*/
function () {
  function GhostTable(hotInstance) {
    (0, _classCallCheck2.default)(this, GhostTable);

    /**
     * Handsontable instance.
     *
     * @type {Core}
     */
    this.hot = hotInstance;
    /**
     * Container element where every table will be injected.
     *
     * @type {HTMLElement|null}
     */

    this.container = null;
    /**
     * Flag which determine is table was injected to DOM.
     *
     * @type {Boolean}
     */

    this.injected = false;
    /**
     * Added rows collection.
     *
     * @type {Array}
     */

    this.rows = [];
    /**
     * Added columns collection.
     *
     * @type {Array}
     */

    this.columns = [];
    /**
     * Samples prepared for calculations.
     *
     * @type {Map}
     * @default {null}
     */

    this.samples = null;
    /**
     * Ghost table settings.
     *
     * @type {Object}
     * @default {Object}
     */

    this.settings = {
      useHeaders: true
    };
  }
  /**
   * Add row.
   *
   * @param {Number} row Row index.
   * @param {Map} samples Samples Map object.
   */


  (0, _createClass2.default)(GhostTable, [{
    key: "addRow",
    value: function addRow(row, samples) {
      if (this.columns.length) {
        throw new Error('Doesn\'t support multi-dimensional table');
      }

      if (!this.rows.length) {
        this.container = this.createContainer(this.hot.rootElement.className);
      }

      var rowObject = {
        row: row
      };
      this.rows.push(rowObject);
      this.samples = samples;
      this.table = this.createTable(this.hot.table.className);
      this.table.colGroup.appendChild(this.createColGroupsCol());
      this.table.tr.appendChild(this.createRow(row));
      this.container.container.appendChild(this.table.fragment);
      rowObject.table = this.table.table;
    }
    /**
     * Add a row consisting of the column headers.
     */

  }, {
    key: "addColumnHeadersRow",
    value: function addColumnHeadersRow(samples) {
      var colHeader = this.hot.getColHeader(0);

      if (colHeader !== null && colHeader !== void 0) {
        var rowObject = {
          row: -1
        };
        this.rows.push(rowObject);
        this.container = this.createContainer(this.hot.rootElement.className);
        this.samples = samples;
        this.table = this.createTable(this.hot.table.className);
        this.table.colGroup.appendChild(this.createColGroupsCol());
        this.table.tHead.appendChild(this.createColumnHeadersRow());
        this.container.container.appendChild(this.table.fragment);
        rowObject.table = this.table.table;
      }
    }
    /**
     * Add column.
     *
     * @param {Number} column Column index.
     * @param {Map} samples Samples Map object.
     */

  }, {
    key: "addColumn",
    value: function addColumn(column, samples) {
      if (this.rows.length) {
        throw new Error('Doesn\'t support multi-dimensional table');
      }

      if (!this.columns.length) {
        this.container = this.createContainer(this.hot.rootElement.className);
      }

      var columnObject = {
        col: column
      };
      this.columns.push(columnObject);
      this.samples = samples;
      this.table = this.createTable(this.hot.table.className);

      if (this.getSetting('useHeaders') && this.hot.getColHeader(column) !== null) {
        this.hot.view.appendColHeader(column, this.table.th);
      }

      this.table.tBody.appendChild(this.createCol(column));
      this.container.container.appendChild(this.table.fragment);
      columnObject.table = this.table.table;
    }
    /**
     * Get calculated heights.
     *
     * @param {Function} callback Callback which will be fired for each calculated row.
     */

  }, {
    key: "getHeights",
    value: function getHeights(callback) {
      if (!this.injected) {
        this.injectTable();
      }

      (0, _array.arrayEach)(this.rows, function (row) {
        // -1 <- reduce border-top from table
        callback(row.row, (0, _element.outerHeight)(row.table) - 1);
      });
    }
    /**
     * Get calculated widths.
     *
     * @param {Function} callback Callback which will be fired for each calculated column.
     */

  }, {
    key: "getWidths",
    value: function getWidths(callback) {
      if (!this.injected) {
        this.injectTable();
      }

      (0, _array.arrayEach)(this.columns, function (column) {
        callback(column.col, (0, _element.outerWidth)(column.table));
      });
    }
    /**
     * Set the Ghost Table settings to the provided object.
     *
     * @param {Object} settings New Ghost Table Settings
     */

  }, {
    key: "setSettings",
    value: function setSettings(settings) {
      this.settings = settings;
    }
    /**
     * Set a single setting of the Ghost Table.
     *
     * @param {String} name Setting name.
     * @param {*} value Setting value.
     */

  }, {
    key: "setSetting",
    value: function setSetting(name, value) {
      if (!this.settings) {
        this.settings = {};
      }

      this.settings[name] = value;
    }
    /**
     * Get the Ghost Table settings.
     *
     * @returns {Object|null}
     */

  }, {
    key: "getSettings",
    value: function getSettings() {
      return this.settings;
    }
    /**
     * Get a single Ghost Table setting.
     *
     * @param {String} name
     * @returns {Boolean|null}
     */

  }, {
    key: "getSetting",
    value: function getSetting(name) {
      if (this.settings) {
        return this.settings[name];
      }

      return null;
    }
    /**
     * Create colgroup col elements.
     *
     * @returns {DocumentFragment}
     */

  }, {
    key: "createColGroupsCol",
    value: function createColGroupsCol() {
      var _this = this;

      var fragment = this.hot.rootDocument.createDocumentFragment();

      if (this.hot.hasRowHeaders()) {
        fragment.appendChild(this.createColElement(-1));
      }

      this.samples.forEach(function (sample) {
        (0, _array.arrayEach)(sample.strings, function (string) {
          fragment.appendChild(_this.createColElement(string.col));
        });
      });
      return fragment;
    }
    /**
     * Create table row element.
     *
     * @param {Number} row Row index.
     * @returns {DocumentFragment} Returns created table row elements.
     */

  }, {
    key: "createRow",
    value: function createRow(row) {
      var _this2 = this;

      var rootDocument = this.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();
      var th = rootDocument.createElement('th');

      if (this.hot.hasRowHeaders()) {
        this.hot.view.appendRowHeader(row, th);
        fragment.appendChild(th);
      }

      this.samples.forEach(function (sample) {
        (0, _array.arrayEach)(sample.strings, function (string) {
          var column = string.col;

          var cellProperties = _this2.hot.getCellMeta(row, column);

          cellProperties.col = column;
          cellProperties.row = row;

          var renderer = _this2.hot.getCellRenderer(cellProperties);

          var td = rootDocument.createElement('td'); // Indicate that this element is created and supported by GhostTable. It can be useful to
          // exclude rendering performance costly logic or exclude logic which doesn't work within a hidden table.

          td.setAttribute('ghost-table', 1);
          renderer(_this2.hot, td, row, column, _this2.hot.colToProp(column), string.value, cellProperties);
          fragment.appendChild(td);
        });
      });
      return fragment;
    }
  }, {
    key: "createColumnHeadersRow",
    value: function createColumnHeadersRow() {
      var _this3 = this;

      var rootDocument = this.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();

      if (this.hot.hasRowHeaders()) {
        var th = rootDocument.createElement('th');
        this.hot.view.appendColHeader(-1, th);
        fragment.appendChild(th);
      }

      this.samples.forEach(function (sample) {
        (0, _array.arrayEach)(sample.strings, function (string) {
          var column = string.col;
          var th = rootDocument.createElement('th');

          _this3.hot.view.appendColHeader(column, th);

          fragment.appendChild(th);
        });
      });
      return fragment;
    }
    /**
     * Create table column elements.
     *
     * @param {Number} column Column index.
     * @returns {DocumentFragment} Returns created column table column elements.
     */

  }, {
    key: "createCol",
    value: function createCol(column) {
      var _this4 = this;

      var rootDocument = this.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();
      this.samples.forEach(function (sample) {
        (0, _array.arrayEach)(sample.strings, function (string) {
          var row = string.row;

          var cellProperties = _this4.hot.getCellMeta(row, column);

          cellProperties.col = column;
          cellProperties.row = row;

          var renderer = _this4.hot.getCellRenderer(cellProperties);

          var td = rootDocument.createElement('td');
          var tr = rootDocument.createElement('tr'); // Indicate that this element is created and supported by GhostTable. It can be useful to
          // exclude rendering performance costly logic or exclude logic which doesn't work within a hidden table.

          td.setAttribute('ghost-table', 1);
          renderer(_this4.hot, td, row, column, _this4.hot.colToProp(column), string.value, cellProperties);
          tr.appendChild(td);
          fragment.appendChild(tr);
        });
      });
      return fragment;
    }
    /**
     * Remove table from document and reset internal state.
     */

  }, {
    key: "clean",
    value: function clean() {
      this.rows.length = 0;
      this.rows[-1] = void 0;
      this.columns.length = 0;

      if (this.samples) {
        this.samples.clear();
      }

      this.samples = null;
      this.removeTable();
    }
    /**
     * Inject generated table into document.
     *
     * @param {HTMLElement} [parent=null]
     */

  }, {
    key: "injectTable",
    value: function injectTable() {
      var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;

      if (!this.injected) {
        (parent || this.hot.rootElement).appendChild(this.container.fragment);
        this.injected = true;
      }
    }
    /**
     * Remove table from document.
     */

  }, {
    key: "removeTable",
    value: function removeTable() {
      if (this.injected && this.container.container.parentNode) {
        this.container.container.parentNode.removeChild(this.container.container);
        this.container = null;
        this.injected = false;
      }
    }
    /**
     * Create col element.
     *
     * @param {Number} column Column index.
     * @returns {HTMLElement}
     */

  }, {
    key: "createColElement",
    value: function createColElement(column) {
      var col = this.hot.rootDocument.createElement('col');
      col.style.width = "".concat(this.hot.view.wt.wtTable.getStretchedColumnWidth(column), "px");
      return col;
    }
    /**
     * Create table element.
     *
     * @param {String} className
     * @returns {Object}
     */

  }, {
    key: "createTable",
    value: function createTable() {
      var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
      var rootDocument = this.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();
      var table = rootDocument.createElement('table');
      var tHead = rootDocument.createElement('thead');
      var tBody = rootDocument.createElement('tbody');
      var colGroup = rootDocument.createElement('colgroup');
      var tr = rootDocument.createElement('tr');
      var th = rootDocument.createElement('th');

      if (this.isVertical()) {
        table.appendChild(colGroup);
      }

      if (this.isHorizontal()) {
        tr.appendChild(th);
        tHead.appendChild(tr);
        table.style.tableLayout = 'auto';
        table.style.width = 'auto';
      }

      table.appendChild(tHead);

      if (this.isVertical()) {
        tBody.appendChild(tr);
      }

      table.appendChild(tBody);
      (0, _element.addClass)(table, className);
      fragment.appendChild(table);
      return {
        fragment: fragment,
        table: table,
        tHead: tHead,
        tBody: tBody,
        colGroup: colGroup,
        tr: tr,
        th: th
      };
    }
    /**
     * Create container for tables.
     *
     * @param {String} className
     * @returns {Object}
     */

  }, {
    key: "createContainer",
    value: function createContainer() {
      var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
      var rootDocument = this.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();
      var container = rootDocument.createElement('div');
      var containerClassName = "htGhostTable htAutoSize ".concat(className.trim());
      (0, _element.addClass)(container, containerClassName);
      fragment.appendChild(container);
      return {
        fragment: fragment,
        container: container
      };
    }
    /**
     * Checks if table is raised vertically (checking rows).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isVertical",
    value: function isVertical() {
      return !!(this.rows.length && !this.columns.length);
    }
    /**
     * Checks if table is raised horizontally (checking columns).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isHorizontal",
    value: function isHorizontal() {
      return !!(this.columns.length && !this.rows.length);
    }
  }]);
  return GhostTable;
}();

var _default = GhostTable;
exports.default = _default;

/***/ }),
/* 164 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalMap = __webpack_require__(102)(1);

var SPECIES_SUPPORT = __webpack_require__(103)('map');

// `Array.prototype.map` method
// https://tc39.github.io/ecma262/#sec-array.prototype.map
// with adding support of @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
  map: function map(callbackfn /* , thisArg */) {
    return internalMap(this, callbackfn, arguments[1]);
  }
});


/***/ }),
/* 165 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(164);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.areValidSortStates = areValidSortStates;
exports.getNextSortOrder = getNextSortOrder;
exports.getHeaderSpanElement = getHeaderSpanElement;
exports.isFirstLevelColumnHeader = isFirstLevelColumnHeader;
exports.wasHeaderClickedProperly = wasHeaderClickedProperly;
exports.HEADER_SPAN_CLASS = exports.DESC_SORT_STATE = exports.ASC_SORT_STATE = void 0;

var _mixed = __webpack_require__(27);

var _object = __webpack_require__(4);

var _event = __webpack_require__(31);

var ASC_SORT_STATE = 'asc';
exports.ASC_SORT_STATE = ASC_SORT_STATE;
var DESC_SORT_STATE = 'desc';
exports.DESC_SORT_STATE = DESC_SORT_STATE;
var HEADER_SPAN_CLASS = 'colHeader';
/**
 * Get if column state is valid.
 *
 * @param {Number} columnState Particular column state.
 * @returns {Boolean}
 */

exports.HEADER_SPAN_CLASS = HEADER_SPAN_CLASS;

function isValidColumnState(columnState) {
  if ((0, _mixed.isUndefined)(columnState)) {
    return false;
  }

  var column = columnState.column,
      sortOrder = columnState.sortOrder;
  return Number.isInteger(column) && [ASC_SORT_STATE, DESC_SORT_STATE].includes(sortOrder);
}
/**
 * Get if all sorted columns states are valid.
 *
 * @param {Array} sortStates
 * @returns {Boolean}
 */


function areValidSortStates(sortStates) {
  if (Array.isArray(sortStates) === false || sortStates.every(function (columnState) {
    return (0, _object.isObject)(columnState);
  }) === false) {
    return false;
  }

  var sortedColumns = sortStates.map(function (_ref) {
    var column = _ref.column;
    return column;
  });
  var indexOccursOnlyOnce = new Set(sortedColumns).size === sortedColumns.length;
  return indexOccursOnlyOnce && sortStates.every(isValidColumnState);
}
/**
 * Get next sort order for particular column. The order sequence looks as follows: 'asc' -> 'desc' -> undefined -> 'asc'
 *
 * @param {String|undefined} sortOrder sort order (`asc` for ascending, `desc` for descending and undefined for not sorted).
 * @returns {String|undefined} Next sort order (`asc` for ascending, `desc` for descending and undefined for not sorted).
 */


function getNextSortOrder(sortOrder) {
  if (sortOrder === DESC_SORT_STATE) {
    return;
  } else if (sortOrder === ASC_SORT_STATE) {
    return DESC_SORT_STATE;
  }

  return ASC_SORT_STATE;
}
/**
 * Get `span` DOM element inside `th` DOM element.
 *
 * @param {Element} TH th HTML element.
 * @returns {Element | null}
 */


function getHeaderSpanElement(TH) {
  var headerSpanElement = TH.querySelector(".".concat(HEADER_SPAN_CLASS));
  return headerSpanElement;
}
/**
 *
 * Get if handled header is first level column header.
 *
 * @param {Number} column Visual column index.
 * @param {Element} TH th HTML element.
 * @returns {Boolean}
 */


function isFirstLevelColumnHeader(column, TH) {
  if (column < 0 || !TH.parentNode) {
    return false;
  }

  var TRs = TH.parentNode.parentNode.childNodes;
  var headerLevel = Array.from(TRs).indexOf(TH.parentNode) - TRs.length;

  if (headerLevel !== -1) {
    return false;
  }

  return true;
}
/**
 *  Get if header was clicked properly. Click on column header and NOT done by right click return `true`.
 *
 * @param {Number} row Visual row index.
 * @param {Number} column Visual column index.
 * @param {Event} clickEvent Click event.
 * @returns {Boolean}
 */


function wasHeaderClickedProperly(row, column, clickEvent) {
  return row === -1 && column >= 0 && (0, _event.isRightClick)(clickEvent) === false;
}

/***/ }),
/* 166 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = separatorItem;
exports.KEY = void 0;
var KEY = '---------';
exports.KEY = KEY;

function separatorItem() {
  return {
    name: KEY
  };
}

/***/ }),
/* 167 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(51);

__webpack_require__(76);

__webpack_require__(10);

__webpack_require__(130);

__webpack_require__(36);

__webpack_require__(37);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _core = _interopRequireDefault(__webpack_require__(161));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var _cursor = _interopRequireDefault(__webpack_require__(631));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _object = __webpack_require__(4);

var _mixed = __webpack_require__(27);

var _function = __webpack_require__(75);

var _utils = __webpack_require__(60);

var _unicode = __webpack_require__(50);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _predefinedItems = __webpack_require__(83);

var _event = __webpack_require__(31);

var MIN_WIDTH = 215;
/**
 * @class Menu
 * @plugin ContextMenu
 */

var Menu =
/*#__PURE__*/
function () {
  function Menu(hotInstance, options) {
    (0, _classCallCheck2.default)(this, Menu);
    this.hot = hotInstance;
    this.options = options || {
      parent: null,
      name: null,
      className: '',
      keepInViewport: true,
      standalone: false,
      minWidth: MIN_WIDTH
    };
    this.eventManager = new _eventManager.default(this);
    this.container = this.createContainer(this.options.name);
    this.hotMenu = null;
    this.hotSubMenus = {};
    this.parentMenu = this.options.parent || null;
    this.menuItems = null;
    this.origOutsideClickDeselects = null;
    this.keyEvent = false;
    this.offset = {
      above: 0,
      below: 0,
      left: 0,
      right: 0
    };
    this._afterScrollCallback = null;
    this.registerEvents();
  }
  /**
   * Register event listeners.
   *
   * @private
   */


  (0, _createClass2.default)(Menu, [{
    key: "registerEvents",
    value: function registerEvents() {
      var _this = this;

      this.eventManager.addEventListener(this.hot.rootDocument.documentElement, 'mousedown', function (event) {
        return _this.onDocumentMouseDown(event);
      });
    }
    /**
     * Set array of objects which defines menu items.
     *
     * @param {Array} menuItems Menu items to display.
     */

  }, {
    key: "setMenuItems",
    value: function setMenuItems(menuItems) {
      this.menuItems = menuItems;
    }
    /**
     * Set offset menu position for specified area (`above`, `below`, `left` or `right`).
     *
     * @param {String} area Specified area name (`above`, `below`, `left` or `right`).
     * @param {Number} offset Offset value.
     */

  }, {
    key: "setOffset",
    value: function setOffset(area) {
      var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      this.offset[area] = offset;
    }
    /**
     * Check if menu is using as sub-menu.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSubMenu",
    value: function isSubMenu() {
      return this.parentMenu !== null;
    }
    /**
     * Open menu.
     *
     * @fires Hooks#beforeContextMenuShow
     * @fires Hooks#afterContextMenuShow
     */

  }, {
    key: "open",
    value: function open() {
      var _this2 = this;

      this.runLocalHooks('beforeOpen');
      this.container.removeAttribute('style');
      this.container.style.display = 'block';
      var delayedOpenSubMenu = (0, _function.debounce)(function (row) {
        return _this2.openSubMenu(row);
      }, 300);
      var minWidthOfMenu = this.options.minWidth || MIN_WIDTH;
      var noItemsDefined = false;
      var filteredItems = (0, _array.arrayFilter)(this.menuItems, function (item) {
        if (item.key === _predefinedItems.NO_ITEMS) {
          noItemsDefined = true;
        }

        return (0, _utils.isItemHidden)(item, _this2.hot);
      });

      if (filteredItems.length < 1 && !noItemsDefined) {
        filteredItems.push((0, _predefinedItems.predefinedItems)()[_predefinedItems.NO_ITEMS]);
      } else if (filteredItems.length === 0) {
        return;
      }

      filteredItems = (0, _utils.filterSeparators)(filteredItems, _predefinedItems.SEPARATOR);
      var settings = {
        data: filteredItems,
        colHeaders: false,
        autoColumnSize: true,
        modifyColWidth: function modifyColWidth(width) {
          if ((0, _mixed.isDefined)(width) && width < minWidthOfMenu) {
            return minWidthOfMenu;
          }

          return width;
        },
        autoRowSize: false,
        readOnly: true,
        copyPaste: false,
        columns: [{
          data: 'name',
          renderer: function renderer(hot, TD, row, col, prop, value) {
            return _this2.menuItemRenderer(hot, TD, row, col, prop, value);
          }
        }],
        renderAllRows: true,
        fragmentSelection: 'cell',
        disableVisualSelection: 'area',
        beforeKeyDown: function beforeKeyDown(event) {
          return _this2.onBeforeKeyDown(event);
        },
        afterOnCellMouseOver: function afterOnCellMouseOver(event, coords) {
          if (_this2.isAllSubMenusClosed()) {
            delayedOpenSubMenu(coords.row);
          } else {
            _this2.openSubMenu(coords.row);
          }
        },
        rowHeights: function rowHeights(row) {
          return filteredItems[row].name === _predefinedItems.SEPARATOR ? 1 : 23;
        }
      };
      this.origOutsideClickDeselects = this.hot.getSettings().outsideClickDeselects;
      this.hot.getSettings().outsideClickDeselects = false;
      this.hotMenu = new _core.default(this.container, settings);
      this.hotMenu.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      this.hotMenu.addHook('afterSelection', function () {
        return _this2.onAfterSelection.apply(_this2, arguments);
      });
      this.hotMenu.init();
      this.hotMenu.listen();
      this.blockMainTableCallbacks();
      this.runLocalHooks('afterOpen');
    }
    /**
     * Close menu.
     *
     * @param {Boolean} [closeParent=false] if `true` try to close parent menu if exists.
     */

  }, {
    key: "close",
    value: function close() {
      var closeParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (!this.isOpened()) {
        return;
      }

      if (closeParent && this.parentMenu) {
        this.parentMenu.close();
      } else {
        this.closeAllSubMenus();
        this.container.style.display = 'none';
        this.releaseMainTableCallbacks();
        this.hotMenu.destroy();
        this.hotMenu = null;
        this.hot.getSettings().outsideClickDeselects = this.origOutsideClickDeselects;
        this.runLocalHooks('afterClose');

        if (this.parentMenu) {
          this.parentMenu.hotMenu.listen();
        }
      }
    }
    /**
     * Open sub menu at the provided row index.
     *
     * @param {Number} row Row index.
     * @returns {Menu|Boolean} Returns created menu or `false` if no one menu was created.
     */

  }, {
    key: "openSubMenu",
    value: function openSubMenu(row) {
      if (!this.hotMenu) {
        return false;
      }

      var cell = this.hotMenu.getCell(row, 0);
      this.closeAllSubMenus();

      if (!cell || !(0, _utils.hasSubMenu)(cell)) {
        return false;
      }

      var dataItem = this.hotMenu.getSourceDataAtRow(row);
      var subMenu = new Menu(this.hot, {
        parent: this,
        name: dataItem.name,
        className: this.options.className,
        keepInViewport: true
      });
      subMenu.setMenuItems(dataItem.submenu.items);
      subMenu.open();
      subMenu.setPosition(cell.getBoundingClientRect());
      this.hotSubMenus[dataItem.key] = subMenu;
      return subMenu;
    }
    /**
     * Close sub menu at row index.
     *
     * @param {Number} row Row index.
     */

  }, {
    key: "closeSubMenu",
    value: function closeSubMenu(row) {
      var dataItem = this.hotMenu.getSourceDataAtRow(row);
      var menus = this.hotSubMenus[dataItem.key];

      if (menus) {
        menus.destroy();
        delete this.hotSubMenus[dataItem.key];
      }
    }
    /**
     * Close all opened sub menus.
     */

  }, {
    key: "closeAllSubMenus",
    value: function closeAllSubMenus() {
      var _this3 = this;

      (0, _array.arrayEach)(this.hotMenu.getData(), function (value, row) {
        return _this3.closeSubMenu(row);
      });
    }
    /**
     * Checks if all created and opened sub menus are closed.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isAllSubMenusClosed",
    value: function isAllSubMenusClosed() {
      return Object.keys(this.hotSubMenus).length === 0;
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.clearLocalHooks();
      this.close();
      this.parentMenu = null;
      this.eventManager.destroy();
    }
    /**
     * Checks if menu was opened.
     *
     * @returns {Boolean} Returns `true` if menu was opened.
     */

  }, {
    key: "isOpened",
    value: function isOpened() {
      return this.hotMenu !== null;
    }
    /**
     * Execute menu command.
     *
     * @param {Event} [event]
     */

  }, {
    key: "executeCommand",
    value: function executeCommand(event) {
      if (!this.isOpened() || !this.hotMenu.getSelectedLast()) {
        return;
      }

      var selectedItem = this.hotMenu.getSourceDataAtRow(this.hotMenu.getSelectedLast()[0]);
      this.runLocalHooks('select', selectedItem, event);

      if (selectedItem.isCommand === false || selectedItem.name === _predefinedItems.SEPARATOR) {
        return;
      }

      var selRanges = this.hot.getSelectedRange();
      var normalizedSelection = selRanges ? (0, _utils.normalizeSelection)(selRanges) : [];
      var autoClose = true; // Don't close context menu if item is disabled or it has submenu

      if (selectedItem.disabled === true || typeof selectedItem.disabled === 'function' && selectedItem.disabled.call(this.hot) === true || selectedItem.submenu) {
        autoClose = false;
      }

      this.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event);

      if (this.isSubMenu()) {
        this.parentMenu.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event);
      }

      if (autoClose) {
        this.close(true);
      }
    }
    /**
     * Set menu position based on dom event or based on literal object.
     *
     * @param {Event|Object} coords Event or literal Object with coordinates.
     */

  }, {
    key: "setPosition",
    value: function setPosition(coords) {
      var cursor = new _cursor.default(coords, this.hot.rootWindow);

      if (this.options.keepInViewport) {
        if (cursor.fitsBelow(this.container)) {
          this.setPositionBelowCursor(cursor);
        } else if (cursor.fitsAbove(this.container)) {
          this.setPositionAboveCursor(cursor);
        } else {
          this.setPositionBelowCursor(cursor);
        }

        if (cursor.fitsOnRight(this.container)) {
          this.setPositionOnRightOfCursor(cursor);
        } else {
          this.setPositionOnLeftOfCursor(cursor);
        }
      } else {
        this.setPositionBelowCursor(cursor);
        this.setPositionOnRightOfCursor(cursor);
      }
    }
    /**
     * Set menu position above cursor object.
     *
     * @param {Cursor} cursor `Cursor` object.
     */

  }, {
    key: "setPositionAboveCursor",
    value: function setPositionAboveCursor(cursor) {
      var top = this.offset.above + cursor.top - this.container.offsetHeight;

      if (this.isSubMenu()) {
        top = cursor.top + cursor.cellHeight - this.container.offsetHeight + 3;
      }

      this.container.style.top = "".concat(top, "px");
    }
    /**
     * Set menu position below cursor object.
     *
     * @param {Cursor} cursor `Cursor` object.
     */

  }, {
    key: "setPositionBelowCursor",
    value: function setPositionBelowCursor(cursor) {
      var top = this.offset.below + cursor.top;

      if (this.isSubMenu()) {
        top = cursor.top - 1;
      }

      this.container.style.top = "".concat(top, "px");
    }
    /**
     * Set menu position on the right of cursor object.
     *
     * @param {Cursor} cursor `Cursor` object.
     */

  }, {
    key: "setPositionOnRightOfCursor",
    value: function setPositionOnRightOfCursor(cursor) {
      var left;

      if (this.isSubMenu()) {
        left = 1 + cursor.left + cursor.cellWidth;
      } else {
        left = this.offset.right + 1 + cursor.left;
      }

      this.container.style.left = "".concat(left, "px");
    }
    /**
     * Set menu position on the left of cursor object.
     *
     * @param {Cursor} cursor `Cursor` object.
     */

  }, {
    key: "setPositionOnLeftOfCursor",
    value: function setPositionOnLeftOfCursor(cursor) {
      var left = this.offset.left + cursor.left - this.container.offsetWidth + (0, _element.getScrollbarWidth)(this.hot.rootDocument) + 4;
      this.container.style.left = "".concat(left, "px");
    }
    /**
     * Select first cell in opened menu.
     */

  }, {
    key: "selectFirstCell",
    value: function selectFirstCell() {
      var cell = this.hotMenu.getCell(0, 0);

      if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
        this.selectNextCell(0, 0);
      } else {
        this.hotMenu.selectCell(0, 0);
      }
    }
    /**
     * Select last cell in opened menu.
     */

  }, {
    key: "selectLastCell",
    value: function selectLastCell() {
      var lastRow = this.hotMenu.countRows() - 1;
      var cell = this.hotMenu.getCell(lastRow, 0);

      if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
        this.selectPrevCell(lastRow, 0);
      } else {
        this.hotMenu.selectCell(lastRow, 0);
      }
    }
    /**
     * Select next cell in opened menu.
     *
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     */

  }, {
    key: "selectNextCell",
    value: function selectNextCell(row, col) {
      var nextRow = row + 1;
      var cell = nextRow < this.hotMenu.countRows() ? this.hotMenu.getCell(nextRow, col) : null;

      if (!cell) {
        return;
      }

      if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
        this.selectNextCell(nextRow, col);
      } else {
        this.hotMenu.selectCell(nextRow, col);
      }
    }
    /**
     * Select previous cell in opened menu.
     *
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     */

  }, {
    key: "selectPrevCell",
    value: function selectPrevCell(row, col) {
      var prevRow = row - 1;
      var cell = prevRow >= 0 ? this.hotMenu.getCell(prevRow, col) : null;

      if (!cell) {
        return;
      }

      if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
        this.selectPrevCell(prevRow, col);
      } else {
        this.hotMenu.selectCell(prevRow, col);
      }
    }
    /**
     * Menu item renderer.
     *
     * @private
     */

  }, {
    key: "menuItemRenderer",
    value: function menuItemRenderer(hot, TD, row, col, prop, value) {
      var _this4 = this;

      var item = hot.getSourceDataAtRow(row);
      var wrapper = this.hot.rootDocument.createElement('div');

      var isSubMenu = function isSubMenu(itemToTest) {
        return (0, _object.hasOwnProperty)(itemToTest, 'submenu');
      };

      var itemIsSeparator = function itemIsSeparator(itemToTest) {
        return new RegExp(_predefinedItems.SEPARATOR, 'i').test(itemToTest.name);
      };

      var itemIsDisabled = function itemIsDisabled(itemToTest) {
        return itemToTest.disabled === true || typeof itemToTest.disabled === 'function' && itemToTest.disabled.call(_this4.hot) === true;
      };

      var itemIsSelectionDisabled = function itemIsSelectionDisabled(itemToTest) {
        return itemToTest.disableSelection;
      };

      var itemValue = value;

      if (typeof itemValue === 'function') {
        itemValue = itemValue.call(this.hot);
      }

      (0, _element.empty)(TD);
      (0, _element.addClass)(wrapper, 'htItemWrapper');
      TD.appendChild(wrapper);

      if (itemIsSeparator(item)) {
        (0, _element.addClass)(TD, 'htSeparator');
      } else if (typeof item.renderer === 'function') {
        (0, _element.addClass)(TD, 'htCustomMenuRenderer');
        TD.appendChild(item.renderer(hot, wrapper, row, col, prop, itemValue));
      } else {
        (0, _element.fastInnerHTML)(wrapper, itemValue);
      }

      if (itemIsDisabled(item)) {
        (0, _element.addClass)(TD, 'htDisabled');
        this.eventManager.addEventListener(TD, 'mouseenter', function () {
          return hot.deselectCell();
        });
      } else if (itemIsSelectionDisabled(item)) {
        (0, _element.addClass)(TD, 'htSelectionDisabled');
        this.eventManager.addEventListener(TD, 'mouseenter', function () {
          return hot.deselectCell();
        });
      } else if (isSubMenu(item)) {
        (0, _element.addClass)(TD, 'htSubmenu');

        if (itemIsSelectionDisabled(item)) {
          this.eventManager.addEventListener(TD, 'mouseenter', function () {
            return hot.deselectCell();
          });
        } else {
          this.eventManager.addEventListener(TD, 'mouseenter', function () {
            return hot.selectCell(row, col, void 0, void 0, false, false);
          });
        }
      } else {
        (0, _element.removeClass)(TD, 'htSubmenu');
        (0, _element.removeClass)(TD, 'htDisabled');

        if (itemIsSelectionDisabled(item)) {
          this.eventManager.addEventListener(TD, 'mouseenter', function () {
            return hot.deselectCell();
          });
        } else {
          this.eventManager.addEventListener(TD, 'mouseenter', function () {
            return hot.selectCell(row, col, void 0, void 0, false, false);
          });
        }
      }
    }
    /**
     * Create container/wrapper for handsontable.
     *
     * @private
     * @param {String} [name] Class name.
     * @returns {HTMLElement}
     */

  }, {
    key: "createContainer",
    value: function createContainer() {
      var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      var rootDocument = this.hot.rootDocument;
      var className = name;
      var container;

      if (className) {
        if ((0, _function.isFunction)(className)) {
          className = className.call(this.hot);

          if (className === null || (0, _mixed.isUndefined)(className)) {
            className = '';
          } else {
            className = className.toString();
          }
        }

        className = className.replace(/[^A-z0-9]/g, '_');
        className = "".concat(this.options.className, "Sub_").concat(className);
        container = rootDocument.querySelector(".".concat(this.options.className, ".").concat(className));
      } else {
        container = rootDocument.querySelector(".".concat(this.options.className));
      }

      if (!container) {
        container = rootDocument.createElement('div');
        (0, _element.addClass)(container, "htMenu ".concat(this.options.className));

        if (className) {
          (0, _element.addClass)(container, className);
        }

        rootDocument.getElementsByTagName('body')[0].appendChild(container);
      }

      return container;
    }
    /**
     * @private
     */

  }, {
    key: "blockMainTableCallbacks",
    value: function blockMainTableCallbacks() {
      this._afterScrollCallback = function () {};

      this.hot.addHook('afterScrollVertically', this._afterScrollCallback);
      this.hot.addHook('afterScrollHorizontally', this._afterScrollCallback);
    }
    /**
     * @private
     */

  }, {
    key: "releaseMainTableCallbacks",
    value: function releaseMainTableCallbacks() {
      if (this._afterScrollCallback) {
        this.hot.removeHook('afterScrollVertically', this._afterScrollCallback);
        this.hot.removeHook('afterScrollHorizontally', this._afterScrollCallback);
        this._afterScrollCallback = null;
      }
    }
    /**
     * On before key down listener.
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown(event) {
      var selection = this.hotMenu.getSelectedLast();
      var stopEvent = false;
      this.keyEvent = true;

      switch (event.keyCode) {
        case _unicode.KEY_CODES.ESCAPE:
          this.close();
          stopEvent = true;
          break;

        case _unicode.KEY_CODES.ENTER:
          if (selection) {
            if (this.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
              stopEvent = true;
            } else {
              this.executeCommand(event);
              this.close(true);
            }
          }

          break;

        case _unicode.KEY_CODES.ARROW_DOWN:
          if (selection) {
            this.selectNextCell(selection[0], selection[1]);
          } else {
            this.selectFirstCell();
          }

          stopEvent = true;
          break;

        case _unicode.KEY_CODES.ARROW_UP:
          if (selection) {
            this.selectPrevCell(selection[0], selection[1]);
          } else {
            this.selectLastCell();
          }

          stopEvent = true;
          break;

        case _unicode.KEY_CODES.ARROW_RIGHT:
          if (selection) {
            var menu = this.openSubMenu(selection[0]);

            if (menu) {
              menu.selectFirstCell();
            }
          }

          stopEvent = true;
          break;

        case _unicode.KEY_CODES.ARROW_LEFT:
          if (selection && this.isSubMenu()) {
            this.close();

            if (this.parentMenu) {
              this.parentMenu.hotMenu.listen();
            }

            stopEvent = true;
          }

          break;

        default:
          break;
      }

      if (stopEvent) {
        event.preventDefault();
        (0, _event.stopImmediatePropagation)(event);
      }

      this.keyEvent = false;
    }
    /**
     * On after init listener.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      var wtTable = this.hotMenu.view.wt.wtTable;
      var data = this.hotMenu.getSettings().data;
      var hiderStyle = wtTable.hider.style;
      var holderStyle = wtTable.holder.style;
      var currentHiderWidth = parseInt(hiderStyle.width, 10);
      var realHeight = (0, _array.arrayReduce)(data, function (accumulator, value) {
        return accumulator + (value.name === _predefinedItems.SEPARATOR ? 1 : 26);
      }, 0);
      holderStyle.width = "".concat(currentHiderWidth + 22, "px");
      holderStyle.height = "".concat(realHeight + 4, "px");
      hiderStyle.height = holderStyle.height;
    }
    /**
     * On after selection listener.
     *
     * @param {Number} r Selection start row index.
     * @param {Number} c Selection start column index.
     * @param {Number} r2 Selection end row index.
     * @param {Number} c2 Selection end column index.
     * @param {Object} preventScrolling Object with `value` property where its value change will be observed.
     * @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
     */

  }, {
    key: "onAfterSelection",
    value: function onAfterSelection(r, c, r2, c2, preventScrolling) {
      if (this.keyEvent === false) {
        preventScrolling.value = true;
      }
    }
    /**
     * Document mouse down listener.
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "onDocumentMouseDown",
    value: function onDocumentMouseDown(event) {
      if (!this.isOpened()) {
        return;
      }

      if (this.container && (0, _element.isChildOf)(event.target, this.container)) {
        this.executeCommand(event);
      } // Close menu when clicked element is not belongs to menu itself


      if (this.options.standalone && this.hotMenu && !(0, _element.isChildOf)(event.target, this.hotMenu.rootElement)) {
        this.close(true); // Automatically close menu when clicked element is not belongs to menu or submenu (not necessarily to itself)
      } else if ((this.isAllSubMenusClosed() || this.isSubMenu()) && !(0, _element.isChildOf)(event.target, '.htMenu') && (0, _element.isChildOf)(event.target, this.hot.rootDocument)) {
        this.close(true);
      }
    }
  }]);
  return Menu;
}();

(0, _object.mixin)(Menu, _localHooks.default);
var _default = Menu;
exports.default = _default;

/***/ }),
/* 168 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _index = __webpack_require__(25);

var _templateLiteralTag = __webpack_require__(67);

function _templateObject4() {
  var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared at [", ", ", "] has \"rowspan\" or \"colspan\" declared as \n      \"0\", which is not supported. It cannot be added to the collection."]);

  _templateObject4 = function _templateObject4() {
    return data;
  };

  return data;
}

function _templateObject3() {
  var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared at [", ", ", "] has both \"rowspan\" \n     and \"colspan\" declared as \"1\", which makes it a single cell. It cannot be added to the collection."]);

  _templateObject3 = function _templateObject3() {
    return data;
  };

  return data;
}

function _templateObject2() {
  var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared at [", ", ", "] is positioned (or positioned partially) \n       outside of the table range. It was not added to the table, please fix your setup."]);

  _templateObject2 = function _templateObject2() {
    return data;
  };

  return data;
}

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared with {row: ", ", col: ", ", rowspan: \n    ", ", colspan: ", "} contains negative values, which is not supported. It \n    will not be added to the collection."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * The `MergedCellCoords` class represents a single merged cell.
 *
 * @class MergedCellCoords
 * @plugin MergeCells
 */
var MergedCellCoords =
/*#__PURE__*/
function () {
  function MergedCellCoords(row, column, rowspan, colspan) {
    (0, _classCallCheck2.default)(this, MergedCellCoords);

    /**
     * The index of the topmost merged cell row.
     *
     * @type {Number}
     */
    this.row = row;
    /**
     * The index of the leftmost column.
     *
     * @type {Number}
     */

    this.col = column;
    /**
     * The `rowspan` value of the merged cell.
     *
     * @type {Number}
     */

    this.rowspan = rowspan;
    /**
     * The `colspan` value of the merged cell.
     *
     * @type {Number}
     */

    this.colspan = colspan;
    /**
     * `true` only if the merged cell is bound to be removed.
     *
     * @type {Boolean}
     */

    this.removed = false;
  }
  /**
   * Get a warning message for when the declared merged cell data contains negative values.
   *
   * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
   * @return {String}
   */


  (0, _createClass2.default)(MergedCellCoords, [{
    key: "normalize",

    /**
     * Sanitize (prevent from going outside the boundaries) the merged cell.
     *
     * @param hotInstance
     */
    value: function normalize(hotInstance) {
      var totalRows = hotInstance.countRows();
      var totalColumns = hotInstance.countCols();

      if (this.row < 0) {
        this.row = 0;
      } else if (this.row > totalRows - 1) {
        this.row = totalRows - 1;
      }

      if (this.col < 0) {
        this.col = 0;
      } else if (this.col > totalColumns - 1) {
        this.col = totalColumns - 1;
      }

      if (this.row + this.rowspan > totalRows - 1) {
        this.rowspan = totalRows - this.row;
      }

      if (this.col + this.colspan > totalColumns - 1) {
        this.colspan = totalColumns - this.col;
      }
    }
    /**
     * Returns `true` if the provided coordinates are inside the merged cell.
     *
     * @param {Number} row The row index.
     * @param {Number} column The column index.
     * @return {Boolean}
     */

  }, {
    key: "includes",
    value: function includes(row, column) {
      return this.row <= row && this.col <= column && this.row + this.rowspan - 1 >= row && this.col + this.colspan - 1 >= column;
    }
    /**
     * Returns `true` if the provided `column` property is within the column span of the merged cell.
     *
     * @param {Number} column The column index.
     * @return {Boolean}
     */

  }, {
    key: "includesHorizontally",
    value: function includesHorizontally(column) {
      return this.col <= column && this.col + this.colspan - 1 >= column;
    }
    /**
     * Returns `true` if the provided `row` property is within the row span of the merged cell.
     *
     * @param {Number} row Row index.
     * @return {Boolean}
     */

  }, {
    key: "includesVertically",
    value: function includesVertically(row) {
      return this.row <= row && this.row + this.rowspan - 1 >= row;
    }
    /**
     * Shift (and possibly resize, if needed) the merged cell.
     *
     * @param {Array} shiftVector 2-element array containing the information on the shifting in the `x` and `y` axis.
     * @param {Number} indexOfChange Index of the preceding change.
     * @returns {Boolean} Returns `false` if the whole merged cell was removed.
     */

  }, {
    key: "shift",
    value: function shift(shiftVector, indexOfChange) {
      var shiftValue = shiftVector[0] || shiftVector[1];
      var shiftedIndex = indexOfChange + Math.abs(shiftVector[0] || shiftVector[1]) - 1;
      var span = shiftVector[0] ? 'colspan' : 'rowspan';
      var index = shiftVector[0] ? 'col' : 'row';
      var changeStart = Math.min(indexOfChange, shiftedIndex);
      var changeEnd = Math.max(indexOfChange, shiftedIndex);
      var mergeStart = this[index];
      var mergeEnd = this[index] + this[span] - 1;

      if (mergeStart >= indexOfChange) {
        this[index] += shiftValue;
      } // adding rows/columns


      if (shiftValue > 0) {
        if (indexOfChange <= mergeEnd && indexOfChange > mergeStart) {
          this[span] += shiftValue;
        } // removing rows/columns

      } else if (shiftValue < 0) {
        // removing the whole merge
        if (changeStart <= mergeStart && changeEnd >= mergeEnd) {
          this.removed = true;
          return false; // removing the merge partially, including the beginning
        } else if (mergeStart >= changeStart && mergeStart <= changeEnd) {
          var removedOffset = changeEnd - mergeStart + 1;
          var preRemovedOffset = Math.abs(shiftValue) - removedOffset;
          this[index] -= preRemovedOffset + shiftValue;
          this[span] -= removedOffset; // removing the middle part of the merge
        } else if (mergeStart <= changeStart && mergeEnd >= changeEnd) {
          this[span] += shiftValue; // removing the end part of the merge
        } else if (mergeStart <= changeStart && mergeEnd >= changeStart && mergeEnd < changeEnd) {
          var removedPart = mergeEnd - changeStart + 1;
          this[span] -= removedPart;
        }
      }

      return true;
    }
    /**
     * Check if the second provided merged cell is "farther" in the provided direction.
     *
     * @param {MergedCellCoords} mergedCell The merged cell to check.
     * @param {String} direction Drag direction.
     * @return {Boolean|null} `true` if the second provided merged cell is "farther".
     */

  }, {
    key: "isFarther",
    value: function isFarther(mergedCell, direction) {
      if (!mergedCell) {
        return true;
      }

      if (direction === 'down') {
        return mergedCell.row + mergedCell.rowspan - 1 < this.row + this.rowspan - 1;
      } else if (direction === 'up') {
        return mergedCell.row > this.row;
      } else if (direction === 'right') {
        return mergedCell.col + mergedCell.colspan - 1 < this.col + this.colspan - 1;
      } else if (direction === 'left') {
        return mergedCell.col > this.col;
      }

      return null;
    }
    /**
     * Get the bottom row index of the merged cell.
     *
     * @returns {Number}
     */

  }, {
    key: "getLastRow",
    value: function getLastRow() {
      return this.row + this.rowspan - 1;
    }
    /**
     * Get the rightmost column index of the merged cell.
     *
     * @returns {Number}
     */

  }, {
    key: "getLastColumn",
    value: function getLastColumn() {
      return this.col + this.colspan - 1;
    }
    /**
     * Get the range coordinates of the merged cell.
     *
     * @return {CellRange}
     */

  }, {
    key: "getRange",
    value: function getRange() {
      return new _index.CellRange(new _index.CellCoords(this.row, this.col), new _index.CellCoords(this.row, this.col), new _index.CellCoords(this.getLastRow(), this.getLastColumn()));
    }
  }], [{
    key: "NEGATIVE_VALUES_WARNING",
    value: function NEGATIVE_VALUES_WARNING(newMergedCell) {
      return (0, _templateLiteralTag.toSingleLine)(_templateObject(), newMergedCell.row, newMergedCell.col, newMergedCell.rowspan, newMergedCell.colspan);
    }
    /**
     * Get a warning message for when the declared merged cell data contains values exceeding the table limits.
     *
     * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
     * @return {String}
     */

  }, {
    key: "IS_OUT_OF_BOUNDS_WARNING",
    value: function IS_OUT_OF_BOUNDS_WARNING(newMergedCell) {
      return (0, _templateLiteralTag.toSingleLine)(_templateObject2(), newMergedCell.row, newMergedCell.col);
    }
    /**
     * Get a warning message for when the declared merged cell data represents a single cell.
     *
     * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
     * @return {String}
     */

  }, {
    key: "IS_SINGLE_CELL",
    value: function IS_SINGLE_CELL(newMergedCell) {
      return (0, _templateLiteralTag.toSingleLine)(_templateObject3(), newMergedCell.row, newMergedCell.col);
    }
    /**
     * Get a warning message for when the declared merged cell data contains "colspan" or "rowspan", that equals 0.
     *
     * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
     * @return {String}
     */

  }, {
    key: "ZERO_SPAN_WARNING",
    value: function ZERO_SPAN_WARNING(newMergedCell) {
      return (0, _templateLiteralTag.toSingleLine)(_templateObject4(), newMergedCell.row, newMergedCell.col);
    }
    /**
     * Check whether the values provided for a merged cell contain any negative values.
     *
     * @param {Object} mergedCellInfo Object containing the `row`, `col`, `rowspan` and `colspan` properties.
     * @return {Boolean}
     */

  }, {
    key: "containsNegativeValues",
    value: function containsNegativeValues(mergedCellInfo) {
      return mergedCellInfo.row < 0 || mergedCellInfo.col < 0 || mergedCellInfo.rowspan < 0 || mergedCellInfo.colspan < 0;
    }
    /**
     * Check whether the provided merged cell information object represents a single cell.
     *
     * @private
     * @param {Object} mergedCellInfo An object with `row`, `col`, `rowspan` and `colspan` properties.
     * @return {Boolean}
     */

  }, {
    key: "isSingleCell",
    value: function isSingleCell(mergedCellInfo) {
      return mergedCellInfo.colspan === 1 && mergedCellInfo.rowspan === 1;
    }
    /**
     * Check whether the provided merged cell information object contains a rowspan or colspan of 0.
     *
     * @private
     * @param {Object} mergedCellInfo An object with `row`, `col`, `rowspan` and `colspan` properties.
     * @return {Boolean}
     */

  }, {
    key: "containsZeroSpan",
    value: function containsZeroSpan(mergedCellInfo) {
      return mergedCellInfo.colspan === 0 || mergedCellInfo.rowspan === 0;
    }
    /**
     * Check whether the provided merged cell object is to be declared out of bounds of the table.
     *
     * @param {Object} mergeCell Object containing the `row`, `col`, `rowspan` and `colspan` properties.
     * @param {Number} rowCount Number of rows in the table.
     * @param {Number} columnCount Number of rows in the table.
     * @return {Boolean}
     */

  }, {
    key: "isOutOfBounds",
    value: function isOutOfBounds(mergeCell, rowCount, columnCount) {
      return mergeCell.row < 0 || mergeCell.col < 0 || mergeCell.row >= rowCount || mergeCell.row + mergeCell.rowspan - 1 >= rowCount || mergeCell.col >= columnCount || mergeCell.col + mergeCell.colspan - 1 >= columnCount;
    }
  }]);
  return MergedCellCoords;
}();

var _default = MergedCellCoords;
exports.default = _default;

/***/ }),
/* 169 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = getOptionsList;
exports.TYPES = exports.TYPE_DATE = exports.TYPE_TEXT = exports.TYPE_NUMERIC = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _predefinedItems = __webpack_require__(83);

var _conditionRegisterer = __webpack_require__(28);

var _none = __webpack_require__(707);

exports.CONDITION_NONE = _none.CONDITION_NAME;

var _empty = __webpack_require__(493);

exports.CONDITION_EMPTY = _empty.CONDITION_NAME;

var _notEmpty = __webpack_require__(708);

exports.CONDITION_NOT_EMPTY = _notEmpty.CONDITION_NAME;

var _equal = __webpack_require__(494);

exports.CONDITION_EQUAL = _equal.CONDITION_NAME;

var _notEqual = __webpack_require__(709);

exports.CONDITION_NOT_EQUAL = _notEqual.CONDITION_NAME;

var _greaterThan = __webpack_require__(710);

exports.CONDITION_GREATER_THAN = _greaterThan.CONDITION_NAME;

var _greaterThanOrEqual = __webpack_require__(711);

exports.CONDITION_GREATER_THAN_OR_EQUAL = _greaterThanOrEqual.CONDITION_NAME;

var _lessThan = __webpack_require__(712);

exports.CONDITION_LESS_THAN = _lessThan.CONDITION_NAME;

var _lessThanOrEqual = __webpack_require__(713);

exports.CONDITION_LESS_THAN_OR_EQUAL = _lessThanOrEqual.CONDITION_NAME;

var _between = __webpack_require__(495);

exports.CONDITION_BETWEEN = _between.CONDITION_NAME;

var _notBetween = __webpack_require__(714);

exports.CONDITION_NOT_BETWEEN = _notBetween.CONDITION_NAME;

var _beginsWith = __webpack_require__(715);

exports.CONDITION_BEGINS_WITH = _beginsWith.CONDITION_NAME;

var _endsWith = __webpack_require__(716);

exports.CONDITION_ENDS_WITH = _endsWith.CONDITION_NAME;

var _contains = __webpack_require__(498);

exports.CONDITION_CONTAINS = _contains.CONDITION_NAME;

var _notContains = __webpack_require__(718);

exports.CONDITION_NOT_CONTAINS = _notContains.CONDITION_NAME;

var _before = __webpack_require__(497);

exports.CONDITION_DATE_BEFORE = _before.CONDITION_NAME;

var _after = __webpack_require__(496);

exports.CONDITION_DATE_AFTER = _after.CONDITION_NAME;

var _tomorrow = __webpack_require__(719);

exports.CONDITION_TOMORROW = _tomorrow.CONDITION_NAME;

var _today = __webpack_require__(720);

exports.CONDITION_TODAY = _today.CONDITION_NAME;

var _yesterday = __webpack_require__(721);

exports.CONDITION_YESTERDAY = _yesterday.CONDITION_NAME;

var _byValue = __webpack_require__(722);

exports.CONDITION_BY_VALUE = _byValue.CONDITION_NAME;

var _true = __webpack_require__(723);

exports.CONDITION_TRUE = _true.CONDITION_NAME;

var _false = __webpack_require__(724);

exports.CONDITION_FALSE = _false.CONDITION_NAME;

var _conjunction = __webpack_require__(170);

exports.OPERATION_AND = _conjunction.OPERATION_ID;

var _disjunction = __webpack_require__(499);

exports.OPERATION_OR = _disjunction.OPERATION_ID;

var _disjunctionWithExtraCondition = __webpack_require__(500);

exports.OPERATION_OR_THEN_VARIABLE = _disjunctionWithExtraCondition.OPERATION_ID;

var _TYPES;

var TYPE_NUMERIC = 'numeric';
exports.TYPE_NUMERIC = TYPE_NUMERIC;
var TYPE_TEXT = 'text';
exports.TYPE_TEXT = TYPE_TEXT;
var TYPE_DATE = 'date';
/**
 * Default types and order for filter conditions.
 *
 * @type {Object}
 */

exports.TYPE_DATE = TYPE_DATE;
var TYPES = (_TYPES = {}, (0, _defineProperty2.default)(_TYPES, TYPE_NUMERIC, [_none.CONDITION_NAME, _predefinedItems.SEPARATOR, _empty.CONDITION_NAME, _notEmpty.CONDITION_NAME, _predefinedItems.SEPARATOR, _equal.CONDITION_NAME, _notEqual.CONDITION_NAME, _predefinedItems.SEPARATOR, _greaterThan.CONDITION_NAME, _greaterThanOrEqual.CONDITION_NAME, _lessThan.CONDITION_NAME, _lessThanOrEqual.CONDITION_NAME, _between.CONDITION_NAME, _notBetween.CONDITION_NAME]), (0, _defineProperty2.default)(_TYPES, TYPE_TEXT, [_none.CONDITION_NAME, _predefinedItems.SEPARATOR, _empty.CONDITION_NAME, _notEmpty.CONDITION_NAME, _predefinedItems.SEPARATOR, _equal.CONDITION_NAME, _notEqual.CONDITION_NAME, _predefinedItems.SEPARATOR, _beginsWith.CONDITION_NAME, _endsWith.CONDITION_NAME, _predefinedItems.SEPARATOR, _contains.CONDITION_NAME, _notContains.CONDITION_NAME]), (0, _defineProperty2.default)(_TYPES, TYPE_DATE, [_none.CONDITION_NAME, _predefinedItems.SEPARATOR, _empty.CONDITION_NAME, _notEmpty.CONDITION_NAME, _predefinedItems.SEPARATOR, _equal.CONDITION_NAME, _notEqual.CONDITION_NAME, _predefinedItems.SEPARATOR, _before.CONDITION_NAME, _after.CONDITION_NAME, _between.CONDITION_NAME, _predefinedItems.SEPARATOR, _tomorrow.CONDITION_NAME, _today.CONDITION_NAME, _yesterday.CONDITION_NAME]), _TYPES);
/**
 * Get options list for conditional filter by data type (e.q: `'text'`, `'numeric'`, `'date'`).
 *
 * @returns {Object}
 */

exports.TYPES = TYPES;

function getOptionsList(type) {
  var items = [];
  var typeName = type;

  if (!TYPES[typeName]) {
    typeName = TYPE_TEXT;
  }

  (0, _array.arrayEach)(TYPES[typeName], function (typeValue) {
    var option;

    if (typeValue === _predefinedItems.SEPARATOR) {
      option = {
        name: _predefinedItems.SEPARATOR
      };
    } else {
      option = (0, _object.clone)((0, _conditionRegisterer.getConditionDescriptor)(typeValue));
    }

    items.push(option);
  });
  return items;
}

/***/ }),
/* 170 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.operationResult = operationResult;
exports.SHORT_NAME_FOR_COMPONENT = exports.OPERATION_ID = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _logicalOperationRegisterer = __webpack_require__(109);

var OPERATION_ID = 'conjunction';
exports.OPERATION_ID = OPERATION_ID;
var SHORT_NAME_FOR_COMPONENT = C.FILTERS_LABELS_CONJUNCTION; // p AND q AND w AND x AND... === TRUE?

exports.SHORT_NAME_FOR_COMPONENT = SHORT_NAME_FOR_COMPONENT;

function operationResult(conditions, value) {
  return conditions.every(function (condition) {
    return condition.func(value);
  });
}

(0, _logicalOperationRegisterer.registerOperation)(OPERATION_ID, SHORT_NAME_FOR_COMPONENT, operationResult);

/***/ }),
/* 171 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _base = _interopRequireDefault(__webpack_require__(110));

var privatePool = new WeakMap();
/**
 * @class InputUI
 * @util
 */

var InputUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(InputUI, _BaseUI);
  (0, _createClass2.default)(InputUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        placeholder: '',
        type: 'text',
        tagName: 'input'
      });
    }
  }]);

  function InputUI(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, InputUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(InputUI).call(this, hotInstance, (0, _object.extend)(InputUI.DEFAULTS, options)));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {});

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   */


  (0, _createClass2.default)(InputUI, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.addLocalHook('click', function () {
        return _this2.onClick();
      });
      this.addLocalHook('keyup', function (event) {
        return _this2.onKeyup(event);
      });
    }
    /**
     * Build DOM structure.
     */

  }, {
    key: "build",
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(InputUI.prototype), "build", this).call(this);
      var priv = privatePool.get(this);
      var icon = this.hot.rootDocument.createElement('div');
      priv.input = this._element.firstChild;
      (0, _element.addClass)(this._element, 'htUIInput');
      (0, _element.addClass)(icon, 'htUIInputIcon');

      this._element.appendChild(icon);

      this.update();
    }
    /**
     * Update element.
     */

  }, {
    key: "update",
    value: function update() {
      if (!this.isBuilt()) {
        return;
      }

      var input = privatePool.get(this).input;
      input.type = this.options.type;
      input.placeholder = this.translateIfPossible(this.options.placeholder);
      input.value = this.translateIfPossible(this.options.value);
    }
    /**
     * Focus element.
     */

  }, {
    key: "focus",
    value: function focus() {
      if (this.isBuilt()) {
        privatePool.get(this).input.focus();
      }
    }
    /**
     * OnClick listener.
     */

  }, {
    key: "onClick",
    value: function onClick() {}
    /**
     * OnKeyup listener.
     *
     * @param {Event} event
     */

  }, {
    key: "onKeyup",
    value: function onKeyup(event) {
      this.options.value = event.target.value;
    }
  }]);
  return InputUI;
}(_base.default);

var _default = InputUI;
exports.default = _default;

/***/ }),
/* 172 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(51);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.getMixedMonthObject = getMixedMonthObject;
exports.getMixedMonthName = getMixedMonthName;
exports.getShorthand = getShorthand;
exports.getStartDate = getStartDate;
exports.getEndDate = getEndDate;
exports.getAdditionalData = getAdditionalData;
exports.setStartDate = setStartDate;
exports.setEndDate = setEndDate;
exports.parseDate = parseDate;
exports.getDateYear = getDateYear;
exports.WEEK_LENGTH = exports.DEC_LENGTH = void 0;

/**
 * Day count for December.
 *
 * @type {Number}
 */
var DEC_LENGTH = 31;
/**
 * Day count for a week.
 *
 * @type {Number}
 */

exports.DEC_LENGTH = DEC_LENGTH;
var WEEK_LENGTH = 7;
/**
 * Generate a mixed month object.
 *
 * @private
 * @param {String} monthName The month name.
 * @param {Number} index Index for the mixed month.
 * @returns {Object} The month object.
 */

exports.WEEK_LENGTH = WEEK_LENGTH;

function getMixedMonthObject(monthName, index) {
  return {
    name: monthName,
    days: WEEK_LENGTH,
    daysBeforeFullWeeks: 0,
    daysAfterFullWeeks: 0,
    fullWeeks: 1,
    index: index
  };
}
/**
 * Generate the name for a mixed month.
 *
 * @private
 * @param {Number} afterMonthIndex Index of the month after the mixed one.
 * @param {Array} monthList List of the months.
 * @returns {String} Name for the mixed month.
 */


function getMixedMonthName(afterMonthIndex, monthList) {
  var mixedMonthName = null;
  var afterMonthShorthand = getShorthand(monthList[afterMonthIndex].name);
  var beforeMonthShorthand = afterMonthIndex > 0 ? getShorthand(monthList[afterMonthIndex - 1].name) : null;
  var firstMonthShorthand = getShorthand(monthList[0].name);
  var lastMonthShorthand = getShorthand(monthList[monthList.length - 1].name);

  if (afterMonthIndex > 0) {
    mixedMonthName = "".concat(beforeMonthShorthand, "/").concat(afterMonthShorthand);
  } else if (afterMonthIndex === monthList.length - 1) {
    mixedMonthName = "".concat(afterMonthShorthand, "/").concat(firstMonthShorthand);
  } else {
    mixedMonthName = "".concat(lastMonthShorthand, "/").concat(afterMonthShorthand);
  }

  return mixedMonthName;
}
/**
 * Get the three first letters from the provided month name.
 *
 * @private
 * @param {String} monthName The month name.
 * @returns {String} The three-lettered shorthand for the month name.
 */


function getShorthand(monthName) {
  var MONTH_SHORT_LEN = 3;
  return monthName.substring(0, MONTH_SHORT_LEN);
}
/**
 * Get the start date of the provided range bar.
 *
 * @param {Object} rangeBar The range bar object.
 * @returns {Date} The start date.
 */


function getStartDate(rangeBar) {
  return parseDate(Array.isArray(rangeBar) ? rangeBar[1] : rangeBar.startDate);
}
/**
 * Get the end date of the provided range bar.
 *
 * @param {Object} rangeBar The range bar object.
 * @returns {Date} The end date.
 */


function getEndDate(rangeBar) {
  return parseDate(Array.isArray(rangeBar) ? rangeBar[2] : rangeBar.endDate);
}
/**
 * Get the additional data object of the provided range bar.
 *
 * @param {Object} rangeBar The range bar object.
 * @returns {Object} The additional data object.
 */


function getAdditionalData(rangeBar) {
  return Array.isArray(rangeBar) ? rangeBar[3] : rangeBar.additionalData;
}
/**
 * Set the start date of the provided range bar.
 *
 * @param {Object} rangeBar The range bar object.
 * @param {Date} value The new start date value.
 */


function setStartDate(rangeBar, value) {
  if (Array.isArray(rangeBar)) {
    rangeBar[1] = value;
  } else {
    rangeBar.startDate = value;
  }
}
/**
 * Set the end date of the provided range bar.
 *
 * @param {Object} rangeBar The range bar object.
 * @param {Date} value The new end date value.
 */


function setEndDate(rangeBar, value) {
  if (Array.isArray(rangeBar)) {
    rangeBar[2] = value;
  } else {
    rangeBar.endDate = value;
  }
}
/**
 * Parse the provided date and check if it's valid.
 *
 * @param {String|Date} date Date string or object.
 * @returns {Date|null} Parsed Date object or null, if not a valid date string.
 */


function parseDate(date) {
  var newDate = date;

  if (newDate === null) {
    return null;
  }

  if (!(newDate instanceof Date)) {
    newDate = new Date(newDate);

    if (newDate.toString() === 'Invalid Date') {
      return null;
    }
  }

  return newDate;
}
/**
 * Get the year of the provided date.
 *
 * @param {Date|String} date Date to get the year from.
 * @returns {Number|null} The year from the provided date.
 */


function getDateYear(date) {
  var newDate = parseDate(date);
  return newDate ? newDate.getFullYear() : null;
}

/***/ }),
/* 173 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

/**
 * Base class for the Nested Rows' UI sub-classes.
 *
 * @class
 * @util
 * @private
 */
var BaseUI = function BaseUI(pluginInstance, hotInstance) {
  (0, _classCallCheck2.default)(this, BaseUI);

  /**
   * Instance of Handsontable.
   *
   * @type {Core}
   */
  this.hot = hotInstance;
  /**
   * Reference to the main plugin instance.
   */

  this.plugin = pluginInstance;
};

var _default = BaseUI;
exports.default = _default;

/***/ }),
/* 174 */
/***/ (function(module, exports, __webpack_require__) {

// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIndexedObject = __webpack_require__(69);
var nativeGetOwnPropertyNames = __webpack_require__(93).f;
var toString = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function (it) {
  try {
    return nativeGetOwnPropertyNames(it);
  } catch (e) {
    return windowNames.slice();
  }
};

module.exports.f = function getOwnPropertyNames(it) {
  return windowNames && toString.call(it) == '[object Window]'
    ? getWindowNames(it)
    : nativeGetOwnPropertyNames(toIndexedObject(it));
};


/***/ }),
/* 175 */
/***/ (function(module, exports, __webpack_require__) {

var has = __webpack_require__(47);
var toIndexedObject = __webpack_require__(69);
var arrayIndexOf = __webpack_require__(140)(false);
var hiddenKeys = __webpack_require__(94);

module.exports = function (object, names) {
  var O = toIndexedObject(object);
  var i = 0;
  var result = [];
  var key;
  for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
  // Don't enum bug & hidden keys
  while (names.length > i) if (has(O, key = names[i++])) {
    ~arrayIndexOf(result, key) || result.push(key);
  }
  return result;
};


/***/ }),
/* 176 */
/***/ (function(module, exports, __webpack_require__) {

// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(52) && !__webpack_require__(29)(function () {
  return Object.defineProperty(__webpack_require__(142)('div'), 'a', {
    get: function () { return 7; }
  }).a != 7;
});


/***/ }),
/* 177 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(98)('native-function-to-string', Function.toString);


/***/ }),
/* 178 */
/***/ (function(module, exports, __webpack_require__) {

var nativeFunctionToString = __webpack_require__(177);
var WeakMap = __webpack_require__(32).WeakMap;

module.exports = typeof WeakMap === 'function' && /native code/.test(nativeFunctionToString.call(WeakMap));


/***/ }),
/* 179 */
/***/ (function(module, exports, __webpack_require__) {

var has = __webpack_require__(47);
var ownKeys = __webpack_require__(507);
var getOwnPropertyDescriptorModule = __webpack_require__(115);
var definePropertyModule = __webpack_require__(49);

module.exports = function (target, source) {
  var keys = ownKeys(source);
  var defineProperty = definePropertyModule.f;
  var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
  }
};


/***/ }),
/* 180 */
/***/ (function(module, exports, __webpack_require__) {

// Chrome 38 Symbol has incorrect toString conversion
module.exports = !__webpack_require__(29)(function () {
  // eslint-disable-next-line no-undef
  String(Symbol());
});


/***/ }),
/* 181 */
/***/ (function(module, exports, __webpack_require__) {

var document = __webpack_require__(32).document;

module.exports = document && document.documentElement;


/***/ }),
/* 182 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var getPrototypeOf = __webpack_require__(145);
var hide = __webpack_require__(61);
var has = __webpack_require__(47);
var IS_PURE = __webpack_require__(116);
var ITERATOR = __webpack_require__(35)('iterator');
var BUGGY_SAFARI_ITERATORS = false;

var returnThis = function () { return this; };

// `%IteratorPrototype%` object
// https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object
var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;

if ([].keys) {
  arrayIterator = [].keys();
  // Safari 8 has buggy iterators w/o `next`
  if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
  else {
    PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));
    if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
  }
}

if (IteratorPrototype == undefined) IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
if (!IS_PURE && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);

module.exports = {
  IteratorPrototype: IteratorPrototype,
  BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
};


/***/ }),
/* 183 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = !__webpack_require__(29)(function () {
  function F() { /* empty */ }
  F.prototype.constructor = null;
  return Object.getPrototypeOf(new F()) !== F.prototype;
});


/***/ }),
/* 184 */
/***/ (function(module, exports, __webpack_require__) {

// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var validateSetPrototypeOfArguments = __webpack_require__(513);

module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () { // eslint-disable-line
  var correctSetter = false;
  var test = {};
  var setter;
  try {
    setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
    setter.call(test, []);
    correctSetter = test instanceof Array;
  } catch (e) { /* empty */ }
  return function setPrototypeOf(O, proto) {
    validateSetPrototypeOfArguments(O, proto);
    if (correctSetter) setter.call(O, proto);
    else O.__proto__ = proto;
    return O;
  };
}() : undefined);


/***/ }),
/* 185 */
/***/ (function(module, exports, __webpack_require__) {

var classofRaw = __webpack_require__(77);
var TO_STRING_TAG = __webpack_require__(35)('toStringTag');
// ES3 wrong here
var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function (it, key) {
  try {
    return it[key];
  } catch (e) { /* empty */ }
};

// getting tag from ES6+ `Object.prototype.toString`
module.exports = function (it) {
  var O, tag, result;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag
    // builtinTag case
    : CORRECT_ARGUMENTS ? classofRaw(O)
    // ES3 arguments fallback
    : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
};


/***/ }),
/* 186 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var redefineAll = __webpack_require__(147);
var getWeakData = __webpack_require__(123).getWeakData;
var anObject = __webpack_require__(45);
var isObject = __webpack_require__(42);
var anInstance = __webpack_require__(148);
var iterate = __webpack_require__(149);
var createArrayMethod = __webpack_require__(102);
var $has = __webpack_require__(47);
var InternalStateModule = __webpack_require__(87);
var setInternalState = InternalStateModule.set;
var internalStateGetterFor = InternalStateModule.getterFor;
var arrayFind = createArrayMethod(5);
var arrayFindIndex = createArrayMethod(6);
var id = 0;

// fallback for uncaught frozen keys
var uncaughtFrozenStore = function (store) {
  return store.frozen || (store.frozen = new UncaughtFrozenStore());
};

var UncaughtFrozenStore = function () {
  this.entries = [];
};

var findUncaughtFrozen = function (store, key) {
  return arrayFind(store.entries, function (it) {
    return it[0] === key;
  });
};

UncaughtFrozenStore.prototype = {
  get: function (key) {
    var entry = findUncaughtFrozen(this, key);
    if (entry) return entry[1];
  },
  has: function (key) {
    return !!findUncaughtFrozen(this, key);
  },
  set: function (key, value) {
    var entry = findUncaughtFrozen(this, key);
    if (entry) entry[1] = value;
    else this.entries.push([key, value]);
  },
  'delete': function (key) {
    var index = arrayFindIndex(this.entries, function (it) {
      return it[0] === key;
    });
    if (~index) this.entries.splice(index, 1);
    return !!~index;
  }
};

module.exports = {
  getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
    var C = wrapper(function (that, iterable) {
      anInstance(that, C, CONSTRUCTOR_NAME);
      setInternalState(that, {
        type: CONSTRUCTOR_NAME,
        id: id++,
        frozen: undefined
      });
      if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);
    });

    var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);

    var define = function (that, key, value) {
      var state = getInternalState(that);
      var data = getWeakData(anObject(key), true);
      if (data === true) uncaughtFrozenStore(state).set(key, value);
      else data[state.id] = value;
      return that;
    };

    redefineAll(C.prototype, {
      // 23.3.3.2 WeakMap.prototype.delete(key)
      // 23.4.3.3 WeakSet.prototype.delete(value)
      'delete': function (key) {
        var state = getInternalState(this);
        if (!isObject(key)) return false;
        var data = getWeakData(key);
        if (data === true) return uncaughtFrozenStore(state)['delete'](key);
        return data && $has(data, state.id) && delete data[state.id];
      },
      // 23.3.3.4 WeakMap.prototype.has(key)
      // 23.4.3.4 WeakSet.prototype.has(value)
      has: function has(key) {
        var state = getInternalState(this);
        if (!isObject(key)) return false;
        var data = getWeakData(key);
        if (data === true) return uncaughtFrozenStore(state).has(key);
        return data && $has(data, state.id);
      }
    });

    redefineAll(C.prototype, IS_MAP ? {
      // 23.3.3.3 WeakMap.prototype.get(key)
      get: function get(key) {
        var state = getInternalState(this);
        if (isObject(key)) {
          var data = getWeakData(key);
          if (data === true) return uncaughtFrozenStore(state).get(key);
          return data ? data[state.id] : undefined;
        }
      },
      // 23.3.3.5 WeakMap.prototype.set(key, value)
      set: function set(key, value) {
        return define(this, key, value);
      }
    } : {
      // 23.4.3.1 WeakSet.prototype.add(value)
      add: function add(value) {
        return define(this, value, true);
      }
    });

    return C;
  }
};


/***/ }),
/* 187 */
/***/ (function(module, exports, __webpack_require__) {

// check on default Array iterator
var Iterators = __webpack_require__(100);
var ITERATOR = __webpack_require__(35)('iterator');
var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);
};


/***/ }),
/* 188 */
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__(185);
var ITERATOR = __webpack_require__(35)('iterator');
var Iterators = __webpack_require__(100);

module.exports = function (it) {
  if (it != undefined) return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};


/***/ }),
/* 189 */
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__(45);

// call something on iterator step with safe closing on error
module.exports = function (iterator, fn, value, ENTRIES) {
  try {
    return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
  // 7.4.6 IteratorClose(iterator, completion)
  } catch (e) {
    var returnMethod = iterator['return'];
    if (returnMethod !== undefined) anObject(returnMethod.call(iterator));
    throw e;
  }
};


/***/ }),
/* 190 */
/***/ (function(module, exports, __webpack_require__) {

var ITERATOR = __webpack_require__(35)('iterator');
var SAFE_CLOSING = false;

try {
  var called = 0;
  var iteratorWithReturn = {
    next: function () {
      return { done: !!called++ };
    },
    'return': function () {
      SAFE_CLOSING = true;
    }
  };
  iteratorWithReturn[ITERATOR] = function () {
    return this;
  };
  // eslint-disable-next-line no-throw-literal
  Array.from(iteratorWithReturn, function () { throw 2; });
} catch (e) { /* empty */ }

module.exports = function (exec, SKIP_CLOSING) {
  if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
  var ITERATION_SUPPORT = false;
  try {
    var object = {};
    object[ITERATOR] = function () {
      return {
        next: function () {
          return { done: ITERATION_SUPPORT = true };
        }
      };
    };
    exec(object);
  } catch (e) { /* empty */ }
  return ITERATION_SUPPORT;
};


/***/ }),
/* 191 */
/***/ (function(module, exports) {

// iterable DOM collections
// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
module.exports = {
  CSSRuleList: 0,
  CSSStyleDeclaration: 0,
  CSSValueList: 0,
  ClientRectList: 0,
  DOMRectList: 0,
  DOMStringList: 0,
  DOMTokenList: 1,
  DataTransferItemList: 0,
  FileList: 0,
  HTMLAllCollection: 0,
  HTMLCollection: 0,
  HTMLFormElement: 0,
  HTMLSelectElement: 0,
  MediaList: 0,
  MimeTypeArray: 0,
  NamedNodeMap: 0,
  NodeList: 1,
  PaintRequestList: 0,
  Plugin: 0,
  PluginArray: 0,
  SVGLengthList: 0,
  SVGNumberList: 0,
  SVGPathSegList: 0,
  SVGPointList: 0,
  SVGStringList: 0,
  SVGTransformList: 0,
  SourceBufferList: 0,
  StyleSheetList: 0,
  TextTrackCueList: 0,
  TextTrackList: 0,
  TouchList: 0
};


/***/ }),
/* 192 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var defineProperty = __webpack_require__(49).f;
var create = __webpack_require__(99);
var redefineAll = __webpack_require__(147);
var bind = __webpack_require__(101);
var anInstance = __webpack_require__(148);
var iterate = __webpack_require__(149);
var defineIterator = __webpack_require__(144);
var setSpecies = __webpack_require__(193);
var DESCRIPTORS = __webpack_require__(52);
var fastKey = __webpack_require__(123).fastKey;
var InternalStateModule = __webpack_require__(87);
var setInternalState = InternalStateModule.set;
var internalStateGetterFor = InternalStateModule.getterFor;

module.exports = {
  getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {
    var C = wrapper(function (that, iterable) {
      anInstance(that, C, CONSTRUCTOR_NAME);
      setInternalState(that, {
        type: CONSTRUCTOR_NAME,
        index: create(null),
        first: undefined,
        last: undefined,
        size: 0
      });
      if (!DESCRIPTORS) that.size = 0;
      if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);
    });

    var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);

    var define = function (that, key, value) {
      var state = getInternalState(that);
      var entry = getEntry(that, key);
      var previous, index;
      // change existing entry
      if (entry) {
        entry.value = value;
      // create new entry
      } else {
        state.last = entry = {
          index: index = fastKey(key, true),
          key: key,
          value: value,
          previous: previous = state.last,
          next: undefined,
          removed: false
        };
        if (!state.first) state.first = entry;
        if (previous) previous.next = entry;
        if (DESCRIPTORS) state.size++;
        else that.size++;
        // add to index
        if (index !== 'F') state.index[index] = entry;
      } return that;
    };

    var getEntry = function (that, key) {
      var state = getInternalState(that);
      // fast case
      var index = fastKey(key);
      var entry;
      if (index !== 'F') return state.index[index];
      // frozen object case
      for (entry = state.first; entry; entry = entry.next) {
        if (entry.key == key) return entry;
      }
    };

    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear() {
        var that = this;
        var state = getInternalState(that);
        var data = state.index;
        var entry = state.first;
        while (entry) {
          entry.removed = true;
          if (entry.previous) entry.previous = entry.previous.next = undefined;
          delete data[entry.index];
          entry = entry.next;
        }
        state.first = state.last = undefined;
        if (DESCRIPTORS) state.size = 0;
        else that.size = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function (key) {
        var that = this;
        var state = getInternalState(that);
        var entry = getEntry(that, key);
        if (entry) {
          var next = entry.next;
          var prev = entry.previous;
          delete state.index[entry.index];
          entry.removed = true;
          if (prev) prev.next = next;
          if (next) next.previous = prev;
          if (state.first == entry) state.first = next;
          if (state.last == entry) state.last = prev;
          if (DESCRIPTORS) state.size--;
          else that.size--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /* , that = undefined */) {
        var state = getInternalState(this);
        var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
        var entry;
        while (entry = entry ? entry.next : state.first) {
          boundFunction(entry.value, entry.key, this);
          // revert to the last existing entry
          while (entry && entry.removed) entry = entry.previous;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key) {
        return !!getEntry(this, key);
      }
    });

    redefineAll(C.prototype, IS_MAP ? {
      // 23.1.3.6 Map.prototype.get(key)
      get: function get(key) {
        var entry = getEntry(this, key);
        return entry && entry.value;
      },
      // 23.1.3.9 Map.prototype.set(key, value)
      set: function set(key, value) {
        return define(this, key === 0 ? 0 : key, value);
      }
    } : {
      // 23.2.3.1 Set.prototype.add(value)
      add: function add(value) {
        return define(this, value = value === 0 ? 0 : value, value);
      }
    });
    if (DESCRIPTORS) defineProperty(C.prototype, 'size', {
      get: function () {
        return getInternalState(this).size;
      }
    });
    return C;
  },
  setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {
    var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';
    var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME);
    var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME);
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {
      setInternalState(this, {
        type: ITERATOR_NAME,
        target: iterated,
        state: getInternalCollectionState(iterated),
        kind: kind,
        last: undefined
      });
    }, function () {
      var state = getInternalIteratorState(this);
      var kind = state.kind;
      var entry = state.last;
      // revert to the last existing entry
      while (entry && entry.removed) entry = entry.previous;
      // get next entry
      if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {
        // or finish the iteration
        state.target = undefined;
        return { value: undefined, done: true };
      }
      // return step by kind
      if (kind == 'keys') return { value: entry.key, done: false };
      if (kind == 'values') return { value: entry.value, done: false };
      return { value: [entry.key, entry.value], done: false };
    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(CONSTRUCTOR_NAME);
  }
};


/***/ }),
/* 193 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var getBuiltIn = __webpack_require__(516);
var definePropertyModule = __webpack_require__(49);
var DESCRIPTORS = __webpack_require__(52);
var SPECIES = __webpack_require__(35)('species');

module.exports = function (CONSTRUCTOR_NAME) {
  var C = getBuiltIn(CONSTRUCTOR_NAME);
  var defineProperty = definePropertyModule.f;
  if (DESCRIPTORS && C && !C[SPECIES]) defineProperty(C, SPECIES, {
    configurable: true,
    get: function () { return this; }
  });
};


/***/ }),
/* 194 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(32);


/***/ }),
/* 195 */
/***/ (function(module, exports) {

function _iterableToArray(iter) {
  if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}

module.exports = _iterableToArray;

/***/ }),
/* 196 */
/***/ (function(module, exports, __webpack_require__) {

var requireObjectCoercible = __webpack_require__(58);
var whitespace = '[' + __webpack_require__(197) + ']';
var ltrim = RegExp('^' + whitespace + whitespace + '*');
var rtrim = RegExp(whitespace + whitespace + '*$');

// 1 -> String#trimStart
// 2 -> String#trimEnd
// 3 -> String#trim
module.exports = function (string, TYPE) {
  string = String(requireObjectCoercible(string));
  if (TYPE & 1) string = string.replace(ltrim, '');
  if (TYPE & 2) string = string.replace(rtrim, '');
  return string;
};


/***/ }),
/* 197 */
/***/ (function(module, exports) {

// a string of all valid unicode whitespaces
// eslint-disable-next-line max-len
module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';


/***/ }),
/* 198 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var privatePool = new WeakMap();
/**
 * Calculates indexes of columns to render OR columns that are visible.
 * To redo the calculation, you need to create a new calculator.
 *
 * @class ViewportColumnsCalculator
 */

var ViewportColumnsCalculator =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(ViewportColumnsCalculator, null, [{
    key: "DEFAULT_WIDTH",

    /**
     * Default column width
     *
     * @type {Number}
     */
    get: function get() {
      return 50;
    }
    /**
     * @param {Number} viewportWidth Width of the viewport
     * @param {Number} scrollOffset Current horizontal scroll position of the viewport
     * @param {Number} totalColumns Total number of rows
     * @param {Function} columnWidthFn Function that returns the width of the column at a given index (in px)
     * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin)
     * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport
     * @param {Boolean} stretchH
     * @param {Function} [stretchingColumnWidthFn] Function that returns the new width of the stretched column.
     */

  }]);

  function ViewportColumnsCalculator(viewportWidth, scrollOffset, totalColumns, columnWidthFn, overrideFn, onlyFullyVisible, stretchH) {
    var stretchingColumnWidthFn = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : function (width) {
      return width;
    };
    (0, _classCallCheck2.default)(this, ViewportColumnsCalculator);
    privatePool.set(this, {
      viewportWidth: viewportWidth,
      scrollOffset: scrollOffset,
      totalColumns: totalColumns,
      columnWidthFn: columnWidthFn,
      overrideFn: overrideFn,
      onlyFullyVisible: onlyFullyVisible,
      stretchingColumnWidthFn: stretchingColumnWidthFn
    });
    /**
     * Number of rendered/visible columns
     *
     * @type {Number}
     */

    this.count = 0;
    /**
     * Index of the first rendered/visible column (can be overwritten using overrideFn)
     *
     * @type {Number|null}
     */

    this.startColumn = null;
    /**
     * Index of the last rendered/visible column (can be overwritten using overrideFn)
     *
     * @type {null}
     */

    this.endColumn = null;
    /**
     * Position of the first rendered/visible column (in px)
     *
     * @type {Number|null}
     */

    this.startPosition = null;
    this.stretchAllRatio = 0;
    this.stretchLastWidth = 0;
    this.stretch = stretchH;
    this.totalTargetWidth = 0;
    this.needVerifyLastColumnWidth = true;
    this.stretchAllColumnsWidth = [];
    this.calculate();
  }
  /**
   * Calculates viewport
   */


  (0, _createClass2.default)(ViewportColumnsCalculator, [{
    key: "calculate",
    value: function calculate() {
      var sum = 0;
      var needReverse = true;
      var startPositions = [];
      var columnWidth;
      var priv = privatePool.get(this);
      var onlyFullyVisible = priv.onlyFullyVisible;
      var overrideFn = priv.overrideFn;
      var scrollOffset = priv.scrollOffset;
      var totalColumns = priv.totalColumns;
      var viewportWidth = priv.viewportWidth;

      for (var i = 0; i < totalColumns; i++) {
        columnWidth = this._getColumnWidth(i);

        if (sum <= scrollOffset && !onlyFullyVisible) {
          this.startColumn = i;
        } // +1 pixel for row header width compensation for horizontal scroll > 0


        var compensatedViewportWidth = scrollOffset > 0 ? viewportWidth + 1 : viewportWidth;

        if (sum >= scrollOffset && sum + columnWidth <= scrollOffset + compensatedViewportWidth) {
          if (this.startColumn === null || this.startColumn === void 0) {
            this.startColumn = i;
          }

          this.endColumn = i;
        }

        startPositions.push(sum);
        sum += columnWidth;

        if (!onlyFullyVisible) {
          this.endColumn = i;
        }

        if (sum >= scrollOffset + viewportWidth) {
          needReverse = false;
          break;
        }
      }

      if (this.endColumn === totalColumns - 1 && needReverse) {
        this.startColumn = this.endColumn;

        while (this.startColumn > 0) {
          var viewportSum = startPositions[this.endColumn] + columnWidth - startPositions[this.startColumn - 1];

          if (viewportSum <= viewportWidth || !onlyFullyVisible) {
            this.startColumn -= 1;
          }

          if (viewportSum > viewportWidth) {
            break;
          }
        }
      }

      if (this.startColumn !== null && overrideFn) {
        overrideFn(this);
      }

      this.startPosition = startPositions[this.startColumn];

      if (this.startPosition === void 0) {
        this.startPosition = null;
      }

      if (this.startColumn !== null) {
        this.count = this.endColumn - this.startColumn + 1;
      }
    }
    /**
     * Recalculate columns stretching.
     *
     * @param {Number} totalWidth
     */

  }, {
    key: "refreshStretching",
    value: function refreshStretching(totalWidth) {
      if (this.stretch === 'none') {
        return;
      }

      var totalColumnsWidth = totalWidth;
      this.totalTargetWidth = totalColumnsWidth;
      var priv = privatePool.get(this);
      var totalColumns = priv.totalColumns;
      var sumAll = 0;

      for (var i = 0; i < totalColumns; i++) {
        var columnWidth = this._getColumnWidth(i);

        var permanentColumnWidth = priv.stretchingColumnWidthFn(void 0, i);

        if (typeof permanentColumnWidth === 'number') {
          totalColumnsWidth -= permanentColumnWidth;
        } else {
          sumAll += columnWidth;
        }
      }

      var remainingSize = totalColumnsWidth - sumAll;

      if (this.stretch === 'all' && remainingSize > 0) {
        this.stretchAllRatio = totalColumnsWidth / sumAll;
        this.stretchAllColumnsWidth = [];
        this.needVerifyLastColumnWidth = true;
      } else if (this.stretch === 'last' && totalColumnsWidth !== Infinity) {
        var _columnWidth = this._getColumnWidth(totalColumns - 1);

        var lastColumnWidth = remainingSize + _columnWidth;
        this.stretchLastWidth = lastColumnWidth >= 0 ? lastColumnWidth : _columnWidth;
      }
    }
    /**
     * Get stretched column width based on stretchH (all or last) setting passed in handsontable instance.
     *
     * @param {Number} column
     * @param {Number} baseWidth
     * @returns {Number|null}
     */

  }, {
    key: "getStretchedColumnWidth",
    value: function getStretchedColumnWidth(column, baseWidth) {
      var result = null;

      if (this.stretch === 'all' && this.stretchAllRatio !== 0) {
        result = this._getStretchedAllColumnWidth(column, baseWidth);
      } else if (this.stretch === 'last' && this.stretchLastWidth !== 0) {
        result = this._getStretchedLastColumnWidth(column);
      }

      return result;
    }
    /**
     * @param {Number} column
     * @param {Number} baseWidth
     * @returns {Number}
     * @private
     */

  }, {
    key: "_getStretchedAllColumnWidth",
    value: function _getStretchedAllColumnWidth(column, baseWidth) {
      var sumRatioWidth = 0;
      var priv = privatePool.get(this);
      var totalColumns = priv.totalColumns;

      if (!this.stretchAllColumnsWidth[column]) {
        var stretchedWidth = Math.round(baseWidth * this.stretchAllRatio);
        var newStretchedWidth = priv.stretchingColumnWidthFn(stretchedWidth, column);

        if (newStretchedWidth === void 0) {
          this.stretchAllColumnsWidth[column] = stretchedWidth;
        } else {
          this.stretchAllColumnsWidth[column] = isNaN(newStretchedWidth) ? this._getColumnWidth(column) : newStretchedWidth;
        }
      }

      if (this.stretchAllColumnsWidth.length === totalColumns && this.needVerifyLastColumnWidth) {
        this.needVerifyLastColumnWidth = false;

        for (var i = 0; i < this.stretchAllColumnsWidth.length; i++) {
          sumRatioWidth += this.stretchAllColumnsWidth[i];
        }

        if (sumRatioWidth !== this.totalTargetWidth) {
          this.stretchAllColumnsWidth[this.stretchAllColumnsWidth.length - 1] += this.totalTargetWidth - sumRatioWidth;
        }
      }

      return this.stretchAllColumnsWidth[column];
    }
    /**
     * @param {Number} column
     * @returns {Number|null}
     * @private
     */

  }, {
    key: "_getStretchedLastColumnWidth",
    value: function _getStretchedLastColumnWidth(column) {
      var priv = privatePool.get(this);
      var totalColumns = priv.totalColumns;

      if (column === totalColumns - 1) {
        return this.stretchLastWidth;
      }

      return null;
    }
    /**
     * @param {Number} column Column index.
     * @returns {Number}
     * @private
     */

  }, {
    key: "_getColumnWidth",
    value: function _getColumnWidth(column) {
      var width = privatePool.get(this).columnWidthFn(column);

      if (isNaN(width)) {
        width = ViewportColumnsCalculator.DEFAULT_WIDTH;
      }

      return width;
    }
  }]);
  return ViewportColumnsCalculator;
}();

var _default = ViewportColumnsCalculator;
exports.default = _default;

/***/ }),
/* 199 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var privatePool = new WeakMap();
/**
 * Calculates indexes of rows to render OR rows that are visible.
 * To redo the calculation, you need to create a new calculator.
 *
 * @class ViewportRowsCalculator
 */

var ViewportRowsCalculator =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(ViewportRowsCalculator, null, [{
    key: "DEFAULT_HEIGHT",

    /**
     * Default row height
     *
     * @type {Number}
     */
    get: function get() {
      return 23;
    }
    /**
     * @param {Number} viewportHeight Height of the viewport
     * @param {Number} scrollOffset Current vertical scroll position of the viewport
     * @param {Number} totalRows Total number of rows
     * @param {Function} rowHeightFn Function that returns the height of the row at a given index (in px)
     * @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin)
     * @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport
     * @param {Number} horizontalScrollbarHeight
     */

  }]);

  function ViewportRowsCalculator(viewportHeight, scrollOffset, totalRows, rowHeightFn, overrideFn, onlyFullyVisible, horizontalScrollbarHeight) {
    (0, _classCallCheck2.default)(this, ViewportRowsCalculator);
    privatePool.set(this, {
      viewportHeight: viewportHeight,
      scrollOffset: scrollOffset,
      totalRows: totalRows,
      rowHeightFn: rowHeightFn,
      overrideFn: overrideFn,
      onlyFullyVisible: onlyFullyVisible,
      horizontalScrollbarHeight: horizontalScrollbarHeight
    });
    /**
     * Number of rendered/visible rows
     *
     * @type {Number}
     */

    this.count = 0;
    /**
     * Index of the first rendered/visible row (can be overwritten using overrideFn)
     *
     * @type {Number|null}
     */

    this.startRow = null;
    /**
     * Index of the last rendered/visible row (can be overwritten using overrideFn)
     *
     * @type {null}
     */

    this.endRow = null;
    /**
     * Position of the first rendered/visible row (in px)
     *
     * @type {Number|null}
     */

    this.startPosition = null;
    this.calculate();
  }
  /**
   * Calculates viewport
   */


  (0, _createClass2.default)(ViewportRowsCalculator, [{
    key: "calculate",
    value: function calculate() {
      var sum = 0;
      var needReverse = true;
      var startPositions = [];
      var priv = privatePool.get(this);
      var onlyFullyVisible = priv.onlyFullyVisible;
      var overrideFn = priv.overrideFn;
      var rowHeightFn = priv.rowHeightFn;
      var scrollOffset = priv.scrollOffset;
      var totalRows = priv.totalRows;
      var viewportHeight = priv.viewportHeight;
      var horizontalScrollbarHeight = priv.horizontalScrollbarHeight || 0;
      var rowHeight; // Calculate the number (start and end index) of rows needed

      for (var i = 0; i < totalRows; i++) {
        rowHeight = rowHeightFn(i);

        if (isNaN(rowHeight)) {
          rowHeight = ViewportRowsCalculator.DEFAULT_HEIGHT;
        }

        if (sum <= scrollOffset && !onlyFullyVisible) {
          this.startRow = i;
        } // the row is within the "visible range"


        if (sum >= scrollOffset && sum + rowHeight <= scrollOffset + viewportHeight - horizontalScrollbarHeight) {
          if (this.startRow === null) {
            this.startRow = i;
          }

          this.endRow = i;
        }

        startPositions.push(sum);
        sum += rowHeight;

        if (!onlyFullyVisible) {
          this.endRow = i;
        }

        if (sum >= scrollOffset + viewportHeight - horizontalScrollbarHeight) {
          needReverse = false;
          break;
        }
      } // If the estimation has reached the last row and there is still some space available in the viewport,
      // we need to render in reverse in order to fill the whole viewport with rows


      if (this.endRow === totalRows - 1 && needReverse) {
        this.startRow = this.endRow;

        while (this.startRow > 0) {
          // rowHeight is the height of the last row
          var viewportSum = startPositions[this.endRow] + rowHeight - startPositions[this.startRow - 1];

          if (viewportSum <= viewportHeight - horizontalScrollbarHeight || !onlyFullyVisible) {
            this.startRow -= 1;
          }

          if (viewportSum >= viewportHeight - horizontalScrollbarHeight) {
            break;
          }
        }
      }

      if (this.startRow !== null && overrideFn) {
        overrideFn(this);
      }

      this.startPosition = startPositions[this.startRow];

      if (this.startPosition === void 0) {
        this.startPosition = null;
      }

      if (this.startRow !== null) {
        this.count = this.endRow - this.startRow + 1;
      }
    }
  }]);
  return ViewportRowsCalculator;
}();

var _default = ViewportRowsCalculator;
exports.default = _default;

/***/ }),
/* 200 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(39);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _coords = _interopRequireDefault(__webpack_require__(106));

/**
 * CellRange holds cell coordinates as {@link CellCoords} instances. This object represent unit of the selection layer which
 * can contains multiple contiquous cells or single cell.
 *
 * @util
 */
var CellRange =
/*#__PURE__*/
function () {
  function CellRange(highlight) {
    var from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : highlight;
    var to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : highlight;
    (0, _classCallCheck2.default)(this, CellRange);

    /**
     * Used to draw bold border around a cell where selection was started and to edit the cell when you press Enter.
     *
     * @type {CellCoords}
     */
    this.highlight = highlight;
    /**
     * Usually the same as highlight, but in Excel there is distinction - one can change highlight within a selection.
     *
     * @type {CellCoords}
     */

    this.from = from;
    /**
     * End selection.
     *
     * @type {CellCoords}
     */

    this.to = to;
  }
  /**
   * Set the new coordinates for highlighting selection.
   *
   * @param {CellCoords} coords Coordinates to use.
   */


  (0, _createClass2.default)(CellRange, [{
    key: "setHighlight",
    value: function setHighlight(coords) {
      this.highlight = coords;
      return this;
    }
    /**
     * Set the new coordinates where selection starts from.
     *
     * @param {CellCoords} coords Coordinates to use.
     */

  }, {
    key: "setFrom",
    value: function setFrom(coords) {
      this.from = coords;
      return this;
    }
    /**
     * Set new coordinates where selection ends from.
     *
     * @param {CellCoords} coords Coordinates to use.
     */

  }, {
    key: "setTo",
    value: function setTo(coords) {
      this.to = coords;
      return this;
    }
    /**
     * Checks if given coordinates are valid in context of a given Walkontable instance.
     *
     * @param {Walkontable} wot The Walkontable instance.
     * @returns {Boolean}
     */

  }, {
    key: "isValid",
    value: function isValid(wot) {
      return this.from.isValid(wot) && this.to.isValid(wot);
    }
    /**
     * Checks if this cell range is restricted to one cell
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSingle",
    value: function isSingle() {
      return this.from.row === this.to.row && this.from.col === this.to.col;
    }
    /**
     * Returns selected range height (in number of rows).
     *
     * @returns {Number}
     */

  }, {
    key: "getHeight",
    value: function getHeight() {
      return Math.max(this.from.row, this.to.row) - Math.min(this.from.row, this.to.row) + 1;
    }
    /**
     * Returns selected range width (in number of columns).
     *
     * @returns {Number}
     */

  }, {
    key: "getWidth",
    value: function getWidth() {
      return Math.max(this.from.col, this.to.col) - Math.min(this.from.col, this.to.col) + 1;
    }
    /**
     * Checks if given cell coordinates are within `from` and `to` cell coordinates of this range.
     *
     * @param {CellCoords} cellCoords The cell coordinates to check.
     * @returns {Boolean}
     */

  }, {
    key: "includes",
    value: function includes(cellCoords) {
      var row = cellCoords.row,
          col = cellCoords.col;
      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();
      return topLeft.row <= row && bottomRight.row >= row && topLeft.col <= col && bottomRight.col >= col;
    }
    /**
     * Checks if given range is within of this range.
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "includesRange",
    value: function includesRange(cellRange) {
      return this.includes(cellRange.getTopLeftCorner()) && this.includes(cellRange.getBottomRightCorner());
    }
    /**
     * Checks if given range is equal to this range.
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "isEqual",
    value: function isEqual(cellRange) {
      return Math.min(this.from.row, this.to.row) === Math.min(cellRange.from.row, cellRange.to.row) && Math.max(this.from.row, this.to.row) === Math.max(cellRange.from.row, cellRange.to.row) && Math.min(this.from.col, this.to.col) === Math.min(cellRange.from.col, cellRange.to.col) && Math.max(this.from.col, this.to.col) === Math.max(cellRange.from.col, cellRange.to.col);
    }
    /**
     * Checks if tested range overlaps with the range. Range A is considered to to be overlapping with range B
     * if intersection of A and B or B and A is not empty.
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "overlaps",
    value: function overlaps(cellRange) {
      return cellRange.isSouthEastOf(this.getTopLeftCorner()) && cellRange.isNorthWestOf(this.getBottomRightCorner());
    }
    /**
     * Checks if tested coordinates are positioned in south-east from this cell range.
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "isSouthEastOf",
    value: function isSouthEastOf(cellRange) {
      return this.getTopLeftCorner().isSouthEastOf(cellRange) || this.getBottomRightCorner().isSouthEastOf(cellRange);
    }
    /**
     * Checks if tested coordinates are positioned in north-west from this cell range.
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "isNorthWestOf",
    value: function isNorthWestOf(cellRange) {
      return this.getTopLeftCorner().isNorthWestOf(cellRange) || this.getBottomRightCorner().isNorthWestOf(cellRange);
    }
    /**
     * Returns `true` if the provided range is overlapping the current range horizontally (e.g. the current range's last
     * column is 5 and the provided range's first column is 3).
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "isOverlappingHorizontally",
    value: function isOverlappingHorizontally(cellRange) {
      return this.getTopRightCorner().col >= cellRange.getTopLeftCorner().col && this.getTopRightCorner().col <= cellRange.getTopRightCorner().col || this.getTopLeftCorner().col <= cellRange.getTopRightCorner().col && this.getTopLeftCorner().col >= cellRange.getTopLeftCorner().col;
    }
    /**
     * Returns `true` if the provided range is overlapping the current range vertically (e.g. the current range's last
     *  row is 5 and the provided range's first row is 3).
     *
     * @param {CellRange} cellRange The cells range to check.
     * @returns {Boolean}
     */

  }, {
    key: "isOverlappingVertically",
    value: function isOverlappingVertically(cellRange) {
      return this.getBottomRightCorner().row >= cellRange.getTopRightCorner().row && this.getBottomRightCorner().row <= cellRange.getBottomRightCorner().row || this.getTopRightCorner().row <= cellRange.getBottomRightCorner().row && this.getTopRightCorner().row >= cellRange.getTopRightCorner().row;
    }
    /**
     * Adds a cell to a range (only if exceeds corners of the range). Returns information if range was expanded.
     *
     * @param {CellCoords} cellCoords
     * @returns {Boolean}
     */

  }, {
    key: "expand",
    value: function expand(cellCoords) {
      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();

      if (cellCoords.row < topLeft.row || cellCoords.col < topLeft.col || cellCoords.row > bottomRight.row || cellCoords.col > bottomRight.col) {
        this.from = new _coords.default(Math.min(topLeft.row, cellCoords.row), Math.min(topLeft.col, cellCoords.col));
        this.to = new _coords.default(Math.max(bottomRight.row, cellCoords.row), Math.max(bottomRight.col, cellCoords.col));
        return true;
      }

      return false;
    }
    /**
     * Expand the current object by the range passed in the first argument.
     *
     * @param {CellRange} expandingRange Object extending the range.
     * @returns {Boolean}
     */

  }, {
    key: "expandByRange",
    value: function expandByRange(expandingRange) {
      if (this.includesRange(expandingRange) || !this.overlaps(expandingRange)) {
        return false;
      }

      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();
      var initialDirection = this.getDirection();
      var expandingTopLeft = expandingRange.getTopLeftCorner();
      var expandingBottomRight = expandingRange.getBottomRightCorner();
      var resultTopRow = Math.min(topLeft.row, expandingTopLeft.row);
      var resultTopCol = Math.min(topLeft.col, expandingTopLeft.col);
      var resultBottomRow = Math.max(bottomRight.row, expandingBottomRight.row);
      var resultBottomCol = Math.max(bottomRight.col, expandingBottomRight.col);
      var finalFrom = new _coords.default(resultTopRow, resultTopCol);
      var finalTo = new _coords.default(resultBottomRow, resultBottomCol);
      this.from = finalFrom;
      this.to = finalTo;
      this.setDirection(initialDirection);

      if (this.highlight.row === this.getBottomRightCorner().row && this.getVerticalDirection() === 'N-S') {
        this.flipDirectionVertically();
      }

      if (this.highlight.col === this.getTopRightCorner().col && this.getHorizontalDirection() === 'W-E') {
        this.flipDirectionHorizontally();
      }

      return true;
    }
    /**
     * Gets the direction of the selection.
     *
     * @returns {String} Returns one of the values: `'NW-SE'`, `'NE-SW'`, `'SE-NW'`, `'SW-NE'`.
     */

  }, {
    key: "getDirection",
    value: function getDirection() {
      if (this.from.isNorthWestOf(this.to)) {
        // NorthWest - SouthEast
        return 'NW-SE';
      } else if (this.from.isNorthEastOf(this.to)) {
        // NorthEast - SouthWest
        return 'NE-SW';
      } else if (this.from.isSouthEastOf(this.to)) {
        // SouthEast - NorthWest
        return 'SE-NW';
      } else if (this.from.isSouthWestOf(this.to)) {
        // SouthWest - NorthEast
        return 'SW-NE';
      }
    }
    /**
     * Sets the direction of the selection.
     *
     * @param {String} direction One of the values: `'NW-SE'`, `'NE-SW'`, `'SE-NW'`, `'SW-NE'`.
     */

  }, {
    key: "setDirection",
    value: function setDirection(direction) {
      switch (direction) {
        case 'NW-SE':
          var _ref = [this.getTopLeftCorner(), this.getBottomRightCorner()];
          this.from = _ref[0];
          this.to = _ref[1];
          break;

        case 'NE-SW':
          var _ref2 = [this.getTopRightCorner(), this.getBottomLeftCorner()];
          this.from = _ref2[0];
          this.to = _ref2[1];
          break;

        case 'SE-NW':
          var _ref3 = [this.getBottomRightCorner(), this.getTopLeftCorner()];
          this.from = _ref3[0];
          this.to = _ref3[1];
          break;

        case 'SW-NE':
          var _ref4 = [this.getBottomLeftCorner(), this.getTopRightCorner()];
          this.from = _ref4[0];
          this.to = _ref4[1];
          break;

        default:
          break;
      }
    }
    /**
     * Gets the vertical direction of the range.
     *
     * @returns {String} Returns one of the values: `N-S` (north->south), `S-N` (south->north).
     */

  }, {
    key: "getVerticalDirection",
    value: function getVerticalDirection() {
      return ['NE-SW', 'NW-SE'].indexOf(this.getDirection()) > -1 ? 'N-S' : 'S-N';
    }
    /**
     * Gets the horizontal direction of the range.
     *
     * @returns {String} Returns one of the values: `W-E` (west->east), `E-W` (east->west).
     */

  }, {
    key: "getHorizontalDirection",
    value: function getHorizontalDirection() {
      return ['NW-SE', 'SW-NE'].indexOf(this.getDirection()) > -1 ? 'W-E' : 'E-W';
    }
    /**
     * Flip the direction vertically. (e.g. `NW-SE` changes to `SW-NE`).
     */

  }, {
    key: "flipDirectionVertically",
    value: function flipDirectionVertically() {
      var direction = this.getDirection();

      switch (direction) {
        case 'NW-SE':
          this.setDirection('SW-NE');
          break;

        case 'NE-SW':
          this.setDirection('SE-NW');
          break;

        case 'SE-NW':
          this.setDirection('NE-SW');
          break;

        case 'SW-NE':
          this.setDirection('NW-SE');
          break;

        default:
          break;
      }
    }
    /**
     * Flip the direction horizontally. (e.g. `NW-SE` changes to `NE-SW`).
     */

  }, {
    key: "flipDirectionHorizontally",
    value: function flipDirectionHorizontally() {
      var direction = this.getDirection();

      switch (direction) {
        case 'NW-SE':
          this.setDirection('NE-SW');
          break;

        case 'NE-SW':
          this.setDirection('NW-SE');
          break;

        case 'SE-NW':
          this.setDirection('SW-NE');
          break;

        case 'SW-NE':
          this.setDirection('SE-NW');
          break;

        default:
          break;
      }
    }
    /**
     * Gets the top left corner of this range.
     *
     * @returns {CellCoords}
     */

  }, {
    key: "getTopLeftCorner",
    value: function getTopLeftCorner() {
      return new _coords.default(Math.min(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
    }
    /**
     * Gets the bottom right corner of this range.
     *
     * @returns {CellCoords}
     */

  }, {
    key: "getBottomRightCorner",
    value: function getBottomRightCorner() {
      return new _coords.default(Math.max(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
    }
    /**
     * Gets the top right corner of this range.
     *
     * @returns {CellCoords}
     */

  }, {
    key: "getTopRightCorner",
    value: function getTopRightCorner() {
      return new _coords.default(Math.min(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
    }
    /**
     * Gets the bottom left corner of this range.
     *
     * @returns {CellCoords}
     */

  }, {
    key: "getBottomLeftCorner",
    value: function getBottomLeftCorner() {
      return new _coords.default(Math.max(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
    }
    /**
     * Checks if coordinates match to one of the 4th corners of this range.
     *
     * @param {CellCoords} coords Cell coordinates to check.
     * @param {CellRange} [expandedRange]
     * @returns {Boolean}
     */

  }, {
    key: "isCorner",
    value: function isCorner(coords, expandedRange) {
      if (expandedRange && expandedRange.includes(coords) && (this.getTopLeftCorner().isEqual(new _coords.default(expandedRange.from.row, expandedRange.from.col)) || this.getTopRightCorner().isEqual(new _coords.default(expandedRange.from.row, expandedRange.to.col)) || this.getBottomLeftCorner().isEqual(new _coords.default(expandedRange.to.row, expandedRange.from.col)) || this.getBottomRightCorner().isEqual(new _coords.default(expandedRange.to.row, expandedRange.to.col)))) {
        return true;
      }

      return coords.isEqual(this.getTopLeftCorner()) || coords.isEqual(this.getTopRightCorner()) || coords.isEqual(this.getBottomLeftCorner()) || coords.isEqual(this.getBottomRightCorner());
    }
    /**
     * Gets coordinates of the corner which is opposite to the matched. When the passed coordinates matched to the
     * bottom-right corner of this range then the coordinates for top-left will be returned.
     *
     * @param {CellCoords} coords Cell coordinates to check.
     * @param {CellRange} [expandedRange]
     * @returns {CellCoords}
     */

  }, {
    key: "getOppositeCorner",
    value: function getOppositeCorner(coords, expandedRange) {
      if (!(coords instanceof _coords.default)) {
        return false;
      }

      if (expandedRange) {
        if (expandedRange.includes(coords)) {
          if (this.getTopLeftCorner().isEqual(new _coords.default(expandedRange.from.row, expandedRange.from.col))) {
            return this.getBottomRightCorner();
          }

          if (this.getTopRightCorner().isEqual(new _coords.default(expandedRange.from.row, expandedRange.to.col))) {
            return this.getBottomLeftCorner();
          }

          if (this.getBottomLeftCorner().isEqual(new _coords.default(expandedRange.to.row, expandedRange.from.col))) {
            return this.getTopRightCorner();
          }

          if (this.getBottomRightCorner().isEqual(new _coords.default(expandedRange.to.row, expandedRange.to.col))) {
            return this.getTopLeftCorner();
          }
        }
      }

      if (coords.isEqual(this.getBottomRightCorner())) {
        return this.getTopLeftCorner();
      } else if (coords.isEqual(this.getTopLeftCorner())) {
        return this.getBottomRightCorner();
      } else if (coords.isEqual(this.getTopRightCorner())) {
        return this.getBottomLeftCorner();
      } else if (coords.isEqual(this.getBottomLeftCorner())) {
        return this.getTopRightCorner();
      }
    }
    /**
     * @param {CellRange} range
     * @returns {Array}
     */

  }, {
    key: "getBordersSharedWith",
    value: function getBordersSharedWith(range) {
      if (!this.includesRange(range)) {
        return [];
      }

      var thisBorders = {
        top: Math.min(this.from.row, this.to.row),
        bottom: Math.max(this.from.row, this.to.row),
        left: Math.min(this.from.col, this.to.col),
        right: Math.max(this.from.col, this.to.col)
      };
      var rangeBorders = {
        top: Math.min(range.from.row, range.to.row),
        bottom: Math.max(range.from.row, range.to.row),
        left: Math.min(range.from.col, range.to.col),
        right: Math.max(range.from.col, range.to.col)
      };
      var result = [];

      if (thisBorders.top === rangeBorders.top) {
        result.push('top');
      }

      if (thisBorders.right === rangeBorders.right) {
        result.push('right');
      }

      if (thisBorders.bottom === rangeBorders.bottom) {
        result.push('bottom');
      }

      if (thisBorders.left === rangeBorders.left) {
        result.push('left');
      }

      return result;
    }
    /**
     * Get inner selected cell coords defined by this range
     *
     * @returns {Array}
     */

  }, {
    key: "getInner",
    value: function getInner() {
      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();
      var out = [];

      for (var r = topLeft.row; r <= bottomRight.row; r++) {
        for (var c = topLeft.col; c <= bottomRight.col; c++) {
          if (!(this.from.row === r && this.from.col === c) && !(this.to.row === r && this.to.col === c)) {
            out.push(new _coords.default(r, c));
          }
        }
      }

      return out;
    }
    /**
     * Get all selected cell coords defined by this range
     *
     * @returns {Array}
     */

  }, {
    key: "getAll",
    value: function getAll() {
      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();
      var out = [];

      for (var r = topLeft.row; r <= bottomRight.row; r++) {
        for (var c = topLeft.col; c <= bottomRight.col; c++) {
          if (topLeft.row === r && topLeft.col === c) {
            out.push(topLeft);
          } else if (bottomRight.row === r && bottomRight.col === c) {
            out.push(bottomRight);
          } else {
            out.push(new _coords.default(r, c));
          }
        }
      }

      return out;
    }
    /**
     * Runs a callback function against all cells in the range. You can break the iteration by returning
     * `false` in the callback function
     *
     * @param callback {Function}
     */

  }, {
    key: "forAll",
    value: function forAll(callback) {
      var topLeft = this.getTopLeftCorner();
      var bottomRight = this.getBottomRightCorner();

      for (var r = topLeft.row; r <= bottomRight.row; r++) {
        for (var c = topLeft.col; c <= bottomRight.col; c++) {
          var breakIteration = callback(r, c);

          if (breakIteration === false) {
            return;
          }
        }
      }
    }
    /**
     * Convert CellRange to literal object.
     *
     * @return {Object} Returns a literal object with `from` and `to` properties which each of that object
     *                  contains `row` and `col` keys.
     */

  }, {
    key: "toObject",
    value: function toObject() {
      return {
        from: this.from.toObject(),
        to: this.to.toObject()
      };
    }
  }]);
  return CellRange;
}();

var _default = CellRange;
exports.default = _default;

/***/ }),
/* 201 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

/**
 * @class ColumnFilter
 */
var ColumnFilter =
/*#__PURE__*/
function () {
  /**
   * @param {Number} offset
   * @param {Number} total
   * @param {Number} countTH
   */
  function ColumnFilter(offset, total, countTH) {
    (0, _classCallCheck2.default)(this, ColumnFilter);
    this.offset = offset;
    this.total = total;
    this.countTH = countTH;
  }
  /**
   * @param index
   * @returns {Number}
   */


  (0, _createClass2.default)(ColumnFilter, [{
    key: "offsetted",
    value: function offsetted(index) {
      return index + this.offset;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "unOffsetted",
    value: function unOffsetted(index) {
      return index - this.offset;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "renderedToSource",
    value: function renderedToSource(index) {
      return this.offsetted(index);
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "sourceToRendered",
    value: function sourceToRendered(index) {
      return this.unOffsetted(index);
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "offsettedTH",
    value: function offsettedTH(index) {
      return index - this.countTH;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "unOffsettedTH",
    value: function unOffsettedTH(index) {
      return index + this.countTH;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "visibleRowHeadedColumnToSourceColumn",
    value: function visibleRowHeadedColumnToSourceColumn(index) {
      return this.renderedToSource(this.offsettedTH(index));
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "sourceColumnToVisibleRowHeadedColumn",
    value: function sourceColumnToVisibleRowHeadedColumn(index) {
      return this.unOffsettedTH(this.sourceToRendered(index));
    }
  }]);
  return ColumnFilter;
}();

var _default = ColumnFilter;
exports.default = _default;

/***/ }),
/* 202 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

/**
 * @class RowFilter
 */
var RowFilter =
/*#__PURE__*/
function () {
  /**
   * @param {Number} offset
   * @param {Number} total
   * @param {Number} countTH
   */
  function RowFilter(offset, total, countTH) {
    (0, _classCallCheck2.default)(this, RowFilter);
    this.offset = offset;
    this.total = total;
    this.countTH = countTH;
  }
  /**
   * @param index
   * @returns {Number}
   */


  (0, _createClass2.default)(RowFilter, [{
    key: "offsetted",
    value: function offsetted(index) {
      return index + this.offset;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "unOffsetted",
    value: function unOffsetted(index) {
      return index - this.offset;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "renderedToSource",
    value: function renderedToSource(index) {
      return this.offsetted(index);
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "sourceToRendered",
    value: function sourceToRendered(index) {
      return this.unOffsetted(index);
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "offsettedTH",
    value: function offsettedTH(index) {
      return index - this.countTH;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "unOffsettedTH",
    value: function unOffsettedTH(index) {
      return index + this.countTH;
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "visibleColHeadedRowToSourceRow",
    value: function visibleColHeadedRowToSourceRow(index) {
      return this.renderedToSource(this.offsettedTH(index));
    }
    /**
     * @param index
     * @returns {Number}
     */

  }, {
    key: "sourceRowToVisibleColHeadedRow",
    value: function sourceRowToVisibleColHeadedRow(index) {
      return this.unOffsettedTH(this.sourceToRendered(index));
    }
  }]);
  return RowFilter;
}();

var _default = RowFilter;
exports.default = _default;

/***/ }),
/* 203 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var navigator = global.navigator;

module.exports = navigator && navigator.userAgent || '';


/***/ }),
/* 204 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalStringPad = __webpack_require__(525);
var userAgent = __webpack_require__(203);

// https://github.com/zloirock/core-js/issues/280
var WEBKIT_BUG = /Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(userAgent);

// `String.prototype.padStart` method
// https://tc39.github.io/ecma262/#sec-string.prototype.padstart
__webpack_require__(22)({ target: 'String', proto: true, forced: WEBKIT_BUG }, {
  padStart: function padStart(maxLength /* , fillString = ' ' */) {
    return internalStringPad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
  }
});


/***/ }),
/* 205 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toInteger = __webpack_require__(86);
var requireObjectCoercible = __webpack_require__(58);

// `String.prototype.repeat` method implementation
// https://tc39.github.io/ecma262/#sec-string.prototype.repeat
module.exports = ''.repeat || function repeat(count) {
  var str = String(requireObjectCoercible(this));
  var result = '';
  var n = toInteger(count);
  if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions');
  for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str;
  return result;
};


/***/ }),
/* 206 */
/***/ (function(module, exports) {

module.exports = function(module) {
	if (!module.webpackPolyfill) {
		module.deprecate = function() {};
		module.paths = [];
		// module.parent = undefined by default
		if (!module.children) module.children = [];
		Object.defineProperty(module, "loaded", {
			enumerable: true,
			get: function() {
				return module.l;
			}
		});
		Object.defineProperty(module, "id", {
			enumerable: true,
			get: function() {
				return module.i;
			}
		});
		module.webpackPolyfill = 1;
	}
	return module;
};


/***/ }),
/* 207 */
/***/ (function(module, exports) {



/***/ }),
/* 208 */
/***/ (function(module, exports) {



/***/ }),
/* 209 */
/***/ (function(module, exports) {



/***/ }),
/* 210 */
/***/ (function(module, exports) {



/***/ }),
/* 211 */
/***/ (function(module, exports) {



/***/ }),
/* 212 */
/***/ (function(module, exports) {



/***/ }),
/* 213 */
/***/ (function(module, exports) {



/***/ }),
/* 214 */
/***/ (function(module, exports) {



/***/ }),
/* 215 */
/***/ (function(module, exports) {



/***/ }),
/* 216 */
/***/ (function(module, exports) {



/***/ }),
/* 217 */
/***/ (function(module, exports) {



/***/ }),
/* 218 */
/***/ (function(module, exports) {



/***/ }),
/* 219 */
/***/ (function(module, exports) {



/***/ }),
/* 220 */
/***/ (function(module, exports) {



/***/ }),
/* 221 */
/***/ (function(module, exports) {



/***/ }),
/* 222 */
/***/ (function(module, exports) {



/***/ }),
/* 223 */
/***/ (function(module, exports) {



/***/ }),
/* 224 */
/***/ (function(module, exports) {



/***/ }),
/* 225 */
/***/ (function(module, exports) {



/***/ }),
/* 226 */
/***/ (function(module, exports) {



/***/ }),
/* 227 */
/***/ (function(module, exports) {



/***/ }),
/* 228 */
/***/ (function(module, exports) {



/***/ }),
/* 229 */
/***/ (function(module, exports) {



/***/ }),
/* 230 */
/***/ (function(module, exports) {



/***/ }),
/* 231 */
/***/ (function(module, exports) {



/***/ }),
/* 232 */
/***/ (function(module, exports) {



/***/ }),
/* 233 */
/***/ (function(module, exports) {



/***/ }),
/* 234 */
/***/ (function(module, exports) {



/***/ }),
/* 235 */
/***/ (function(module, exports) {



/***/ }),
/* 236 */
/***/ (function(module, exports) {



/***/ }),
/* 237 */
/***/ (function(module, exports) {



/***/ }),
/* 238 */
/***/ (function(module, exports) {



/***/ }),
/* 239 */
/***/ (function(module, exports) {



/***/ }),
/* 240 */
/***/ (function(module, exports) {



/***/ }),
/* 241 */
/***/ (function(module, exports) {



/***/ }),
/* 242 */
/***/ (function(module, exports) {



/***/ }),
/* 243 */
/***/ (function(module, exports) {



/***/ }),
/* 244 */
/***/ (function(module, exports) {



/***/ }),
/* 245 */
/***/ (function(module, exports) {



/***/ }),
/* 246 */
/***/ (function(module, exports) {



/***/ }),
/* 247 */
/***/ (function(module, exports) {



/***/ }),
/* 248 */
/***/ (function(module, exports) {



/***/ }),
/* 249 */
/***/ (function(module, exports) {



/***/ }),
/* 250 */
/***/ (function(module, exports) {



/***/ }),
/* 251 */
/***/ (function(module, exports) {



/***/ }),
/* 252 */
/***/ (function(module, exports) {



/***/ }),
/* 253 */
/***/ (function(module, exports) {



/***/ }),
/* 254 */
/***/ (function(module, exports) {



/***/ }),
/* 255 */
/***/ (function(module, exports) {



/***/ }),
/* 256 */
/***/ (function(module, exports) {



/***/ }),
/* 257 */
/***/ (function(module, exports) {



/***/ }),
/* 258 */
/***/ (function(module, exports) {



/***/ }),
/* 259 */
/***/ (function(module, exports) {



/***/ }),
/* 260 */
/***/ (function(module, exports) {



/***/ }),
/* 261 */
/***/ (function(module, exports) {



/***/ }),
/* 262 */
/***/ (function(module, exports) {



/***/ }),
/* 263 */
/***/ (function(module, exports) {



/***/ }),
/* 264 */
/***/ (function(module, exports) {



/***/ }),
/* 265 */
/***/ (function(module, exports) {



/***/ }),
/* 266 */
/***/ (function(module, exports) {



/***/ }),
/* 267 */
/***/ (function(module, exports) {



/***/ }),
/* 268 */
/***/ (function(module, exports) {



/***/ }),
/* 269 */
/***/ (function(module, exports) {



/***/ }),
/* 270 */
/***/ (function(module, exports) {



/***/ }),
/* 271 */
/***/ (function(module, exports) {



/***/ }),
/* 272 */
/***/ (function(module, exports) {



/***/ }),
/* 273 */
/***/ (function(module, exports) {



/***/ }),
/* 274 */
/***/ (function(module, exports) {



/***/ }),
/* 275 */
/***/ (function(module, exports) {



/***/ }),
/* 276 */
/***/ (function(module, exports) {



/***/ }),
/* 277 */
/***/ (function(module, exports) {



/***/ }),
/* 278 */
/***/ (function(module, exports) {



/***/ }),
/* 279 */
/***/ (function(module, exports) {



/***/ }),
/* 280 */
/***/ (function(module, exports) {



/***/ }),
/* 281 */
/***/ (function(module, exports) {



/***/ }),
/* 282 */
/***/ (function(module, exports) {



/***/ }),
/* 283 */
/***/ (function(module, exports) {



/***/ }),
/* 284 */
/***/ (function(module, exports) {



/***/ }),
/* 285 */
/***/ (function(module, exports) {



/***/ }),
/* 286 */
/***/ (function(module, exports) {



/***/ }),
/* 287 */
/***/ (function(module, exports) {



/***/ }),
/* 288 */
/***/ (function(module, exports) {



/***/ }),
/* 289 */
/***/ (function(module, exports) {



/***/ }),
/* 290 */
/***/ (function(module, exports) {



/***/ }),
/* 291 */
/***/ (function(module, exports) {



/***/ }),
/* 292 */
/***/ (function(module, exports) {



/***/ }),
/* 293 */
/***/ (function(module, exports) {



/***/ }),
/* 294 */
/***/ (function(module, exports) {



/***/ }),
/* 295 */
/***/ (function(module, exports) {



/***/ }),
/* 296 */
/***/ (function(module, exports) {



/***/ }),
/* 297 */
/***/ (function(module, exports) {



/***/ }),
/* 298 */
/***/ (function(module, exports) {



/***/ }),
/* 299 */
/***/ (function(module, exports) {



/***/ }),
/* 300 */
/***/ (function(module, exports) {



/***/ }),
/* 301 */
/***/ (function(module, exports) {



/***/ }),
/* 302 */
/***/ (function(module, exports) {



/***/ }),
/* 303 */
/***/ (function(module, exports) {



/***/ }),
/* 304 */
/***/ (function(module, exports) {



/***/ }),
/* 305 */
/***/ (function(module, exports) {



/***/ }),
/* 306 */
/***/ (function(module, exports) {



/***/ }),
/* 307 */
/***/ (function(module, exports) {



/***/ }),
/* 308 */
/***/ (function(module, exports) {



/***/ }),
/* 309 */
/***/ (function(module, exports) {



/***/ }),
/* 310 */
/***/ (function(module, exports) {



/***/ }),
/* 311 */
/***/ (function(module, exports) {



/***/ }),
/* 312 */
/***/ (function(module, exports) {



/***/ }),
/* 313 */
/***/ (function(module, exports) {



/***/ }),
/* 314 */
/***/ (function(module, exports) {



/***/ }),
/* 315 */
/***/ (function(module, exports) {



/***/ }),
/* 316 */
/***/ (function(module, exports) {



/***/ }),
/* 317 */
/***/ (function(module, exports) {



/***/ }),
/* 318 */
/***/ (function(module, exports) {



/***/ }),
/* 319 */
/***/ (function(module, exports) {



/***/ }),
/* 320 */
/***/ (function(module, exports) {



/***/ }),
/* 321 */
/***/ (function(module, exports) {



/***/ }),
/* 322 */
/***/ (function(module, exports) {



/***/ }),
/* 323 */
/***/ (function(module, exports) {



/***/ }),
/* 324 */
/***/ (function(module, exports) {



/***/ }),
/* 325 */
/***/ (function(module, exports) {



/***/ }),
/* 326 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _string = __webpack_require__(68);

var _event = _interopRequireDefault(__webpack_require__(327));

var _overlays = _interopRequireDefault(__webpack_require__(328));

var _scroll = _interopRequireDefault(__webpack_require__(329));

var _settings = _interopRequireDefault(__webpack_require__(330));

var _table = _interopRequireDefault(__webpack_require__(331));

var _viewport = _interopRequireDefault(__webpack_require__(335));

/**
 * @class Walkontable
 */
var Walkontable =
/*#__PURE__*/
function () {
  /**
   * @param {Object} settings
   */
  function Walkontable(settings) {
    (0, _classCallCheck2.default)(this, Walkontable);
    var originalHeaders = []; // this is the namespace for global events

    this.guid = "wt_".concat((0, _string.randomString)());
    this.rootDocument = settings.table.ownerDocument;
    this.rootWindow = this.rootDocument.defaultView; // bootstrap from settings

    if (settings.cloneSource) {
      this.cloneSource = settings.cloneSource;
      this.cloneOverlay = settings.cloneOverlay;
      this.wtSettings = settings.cloneSource.wtSettings;
      this.wtTable = new _table.default(this, settings.table, settings.wtRootElement);
      this.wtScroll = new _scroll.default(this);
      this.wtViewport = settings.cloneSource.wtViewport;
      this.wtEvent = new _event.default(this);
      this.selections = this.cloneSource.selections;
    } else {
      this.wtSettings = new _settings.default(this, settings);
      this.wtTable = new _table.default(this, settings.table);
      this.wtScroll = new _scroll.default(this);
      this.wtViewport = new _viewport.default(this);
      this.wtEvent = new _event.default(this);
      this.selections = this.getSetting('selections');
      this.wtOverlays = new _overlays.default(this);
      this.exportSettingsAsClassNames();
    } // find original headers


    if (this.wtTable.THEAD.childNodes.length && this.wtTable.THEAD.childNodes[0].childNodes.length) {
      for (var c = 0, clen = this.wtTable.THEAD.childNodes[0].childNodes.length; c < clen; c++) {
        originalHeaders.push(this.wtTable.THEAD.childNodes[0].childNodes[c].innerHTML);
      }

      if (!this.getSetting('columnHeaders').length) {
        this.update('columnHeaders', [function (column, TH) {
          (0, _element.fastInnerText)(TH, originalHeaders[column]);
        }]);
      }
    }

    this.drawn = false;
    this.drawInterrupted = false;
  }
  /**
   * Force rerender of Walkontable
   *
   * @param {Boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering
   *                                   the data. It will only work if Table.draw() does not force
   *                                   rendering anyway
   * @returns {Walkontable}
   */


  (0, _createClass2.default)(Walkontable, [{
    key: "draw",
    value: function draw() {
      var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      this.drawInterrupted = false;

      if (!fastDraw && !(0, _element.isVisible)(this.wtTable.TABLE)) {
        // draw interrupted because TABLE is not visible
        this.drawInterrupted = true;
      } else {
        this.wtTable.draw(fastDraw);
      }

      return this;
    }
    /**
     * Returns the TD at coords. If topmost is set to true, returns TD from the topmost overlay layer,
     * if not set or set to false, returns TD from the master table.
     *
     * @param {CellCoords} coords
     * @param {Boolean} [topmost=false]
     * @returns {Object}
     */

  }, {
    key: "getCell",
    value: function getCell(coords) {
      var topmost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

      if (!topmost) {
        return this.wtTable.getCell(coords);
      }

      var totalRows = this.wtSettings.getSetting('totalRows');
      var fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
      var fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom');
      var fixedColumns = this.wtSettings.getSetting('fixedColumnsLeft');

      if (coords.row < fixedRowsTop && coords.col < fixedColumns) {
        return this.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell(coords);
      } else if (coords.row < fixedRowsTop) {
        return this.wtOverlays.topOverlay.clone.wtTable.getCell(coords);
      } else if (coords.col < fixedColumns && coords.row >= totalRows - fixedRowsBottom) {
        if (this.wtOverlays.bottomLeftCornerOverlay && this.wtOverlays.bottomLeftCornerOverlay.clone) {
          return this.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell(coords);
        }
      } else if (coords.col < fixedColumns) {
        return this.wtOverlays.leftOverlay.clone.wtTable.getCell(coords);
      } else if (coords.row < totalRows && coords.row > totalRows - fixedRowsBottom) {
        if (this.wtOverlays.bottomOverlay && this.wtOverlays.bottomOverlay.clone) {
          return this.wtOverlays.bottomOverlay.clone.wtTable.getCell(coords);
        }
      }

      return this.wtTable.getCell(coords);
    }
    /**
     * @param {Object} settings
     * @param {*} value
     * @returns {Walkontable}
     */

  }, {
    key: "update",
    value: function update(settings, value) {
      return this.wtSettings.update(settings, value);
    }
    /**
     * Scrolls the viewport to a cell (rerenders if needed).
     *
     * @param {CellCoords} coords
     * @param {Boolean} [snapToTop]
     * @param {Boolean} [snapToRight]
     * @param {Boolean} [snapToBottom]
     * @param {Boolean} [snapToLeft]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewport",
    value: function scrollViewport(coords, snapToTop, snapToRight, snapToBottom, snapToLeft) {
      return this.wtScroll.scrollViewport(coords, snapToTop, snapToRight, snapToBottom, snapToLeft);
    }
    /**
     * Scrolls the viewport to a column (rerenders if needed).
     *
     * @param {Number} column Visual column index.
     * @param {Boolean} [snapToRight]
     * @param {Boolean} [snapToLeft]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportHorizontally",
    value: function scrollViewportHorizontally(column, snapToRight, snapToLeft) {
      return this.wtScroll.scrollViewportHorizontally(column, snapToRight, snapToLeft);
    }
    /**
     * Scrolls the viewport to a row (rerenders if needed).
     *
     * @param {Number} row Visual row index.
     * @param {Boolean} [snapToTop]
     * @param {Boolean} [snapToBottom]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportVertically",
    value: function scrollViewportVertically(row, snapToTop, snapToBottom) {
      return this.wtScroll.scrollViewportVertically(row, snapToTop, snapToBottom);
    }
    /**
     * @returns {Array}
     */

  }, {
    key: "getViewport",
    value: function getViewport() {
      return [this.wtTable.getFirstVisibleRow(), this.wtTable.getFirstVisibleColumn(), this.wtTable.getLastVisibleRow(), this.wtTable.getLastVisibleColumn()];
    }
    /**
     * Get overlay name
     *
     * @returns {String}
     */

  }, {
    key: "getOverlayName",
    value: function getOverlayName() {
      return this.cloneOverlay ? this.cloneOverlay.type : 'master';
    }
    /**
     * Check overlay type of this Walkontable instance.
     *
     * @param {String} name Clone type @see {Overlay.CLONE_TYPES}.
     * @returns {Boolean}
     */

  }, {
    key: "isOverlayName",
    value: function isOverlayName(name) {
      if (this.cloneOverlay) {
        return this.cloneOverlay.type === name;
      }

      return false;
    }
    /**
     * Export settings as class names added to the parent element of the table.
     */

  }, {
    key: "exportSettingsAsClassNames",
    value: function exportSettingsAsClassNames() {
      var _this = this;

      var toExport = {
        rowHeaders: ['array'],
        columnHeaders: ['array']
      };
      var allClassNames = [];
      var newClassNames = [];
      (0, _object.objectEach)(toExport, function (optionType, key) {
        if (optionType.indexOf('array') > -1 && _this.getSetting(key).length) {
          newClassNames.push("ht".concat((0, _string.toUpperCaseFirst)(key)));
        }

        allClassNames.push("ht".concat((0, _string.toUpperCaseFirst)(key)));
      });
      (0, _element.removeClass)(this.wtTable.wtRootElement.parentNode, allClassNames);
      (0, _element.addClass)(this.wtTable.wtRootElement.parentNode, newClassNames);
    }
    /**
     * Get/Set Walkontable instance setting
     *
     * @param {String} key
     * @param {*} [param1]
     * @param {*} [param2]
     * @param {*} [param3]
     * @param {*} [param4]
     * @returns {*}
     */

  }, {
    key: "getSetting",
    value: function getSetting(key, param1, param2, param3, param4) {
      // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
      return this.wtSettings.getSetting(key, param1, param2, param3, param4);
    }
    /**
     * Checks if setting exists
     *
     * @param {String} key
     * @returns {Boolean}
     */

  }, {
    key: "hasSetting",
    value: function hasSetting(key) {
      return this.wtSettings.has(key);
    }
    /**
     * Destroy instance
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.wtOverlays.destroy();
      this.wtEvent.destroy();
    }
  }]);
  return Walkontable;
}();

var _default = Walkontable;
exports.default = _default;

/***/ }),
/* 327 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _function = __webpack_require__(75);

var _feature = __webpack_require__(73);

var _browser = __webpack_require__(72);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var privatePool = new WeakMap();
/**
 * @class Event
 */

var Event =
/*#__PURE__*/
function () {
  /**
   * @param {*} instance Walkontable instance.
   */
  function Event(instance) {
    (0, _classCallCheck2.default)(this, Event);

    /**
     * Instance of {@link Walkontable}.
     *
     * @private
     * @type {Walkontable}
     */
    this.instance = instance;
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    this.eventManager = new _eventManager.default(instance);
    privatePool.set(this, {
      selectedCellBeforeTouchEnd: void 0,
      dblClickTimeout: [null, null],
      dblClickOrigin: [null, null]
    });
    this.registerEvents();
  }
  /**
   * Adds listeners for mouse and touch events.
   *
   * @private
   */


  (0, _createClass2.default)(Event, [{
    key: "registerEvents",
    value: function registerEvents() {
      var _this = this;

      this.eventManager.addEventListener(this.instance.wtTable.holder, 'contextmenu', function (event) {
        return _this.onContextMenu(event);
      });
      this.eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', function (event) {
        return _this.onMouseOver(event);
      });
      this.eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', function (event) {
        return _this.onMouseOut(event);
      });

      var initTouchEvents = function initTouchEvents() {
        _this.eventManager.addEventListener(_this.instance.wtTable.holder, 'touchstart', function (event) {
          return _this.onTouchStart(event);
        });

        _this.eventManager.addEventListener(_this.instance.wtTable.holder, 'touchend', function (event) {
          return _this.onTouchEnd(event);
        });

        if (!_this.instance.momentumScrolling) {
          _this.instance.momentumScrolling = {};
        }

        _this.eventManager.addEventListener(_this.instance.wtTable.holder, 'scroll', function () {
          clearTimeout(_this.instance.momentumScrolling._timeout);

          if (!_this.instance.momentumScrolling.ongoing) {
            _this.instance.getSetting('onBeforeTouchScroll');
          }

          _this.instance.momentumScrolling.ongoing = true;
          _this.instance.momentumScrolling._timeout = setTimeout(function () {
            if (!_this.instance.touchApplied) {
              _this.instance.momentumScrolling.ongoing = false;

              _this.instance.getSetting('onAfterMomentumScroll');
            }
          }, 200);
        });
      };

      var initMouseEvents = function initMouseEvents() {
        _this.eventManager.addEventListener(_this.instance.wtTable.holder, 'mouseup', function (event) {
          return _this.onMouseUp(event);
        });

        _this.eventManager.addEventListener(_this.instance.wtTable.holder, 'mousedown', function (event) {
          return _this.onMouseDown(event);
        });
      };

      if ((0, _browser.isMobileBrowser)()) {
        initTouchEvents();
      } else {
        // PC like devices which support both methods (touchscreen and ability to plug-in mouse).
        if ((0, _feature.isTouchSupported)()) {
          initTouchEvents();
        }

        initMouseEvents();
      }
    }
    /**
     * Checks if an element is already selected.
     *
     * @private
     * @param {Element} touchTarget
     * @returns {Boolean}
     */

  }, {
    key: "selectedCellWasTouched",
    value: function selectedCellWasTouched(touchTarget) {
      var priv = privatePool.get(this);
      var cellUnderFinger = this.parentCell(touchTarget);
      var coordsOfCellUnderFinger = cellUnderFinger.coords;

      if (priv.selectedCellBeforeTouchEnd && coordsOfCellUnderFinger) {
        var _ref = [coordsOfCellUnderFinger.row, priv.selectedCellBeforeTouchEnd.from.row],
            rowTouched = _ref[0],
            rowSelected = _ref[1];
        var _ref2 = [coordsOfCellUnderFinger.col, priv.selectedCellBeforeTouchEnd.from.col],
            colTouched = _ref2[0],
            colSelected = _ref2[1];
        return rowTouched === rowSelected && colTouched === colSelected;
      }

      return false;
    }
    /**
     * Gets closest TD or TH element.
     *
     * @private
     * @param {Element} elem
     * @returns {Object} Contains coordinates and reference to TD or TH if it exists. Otherwise it's empty object.
     */

  }, {
    key: "parentCell",
    value: function parentCell(elem) {
      var cell = {};
      var TABLE = this.instance.wtTable.TABLE;
      var TD = (0, _element.closestDown)(elem, ['TD', 'TH'], TABLE);

      if (TD) {
        cell.coords = this.instance.wtTable.getCoords(TD);
        cell.TD = TD;
      } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'current')) {
        cell.coords = this.instance.selections.getCell().cellRange.highlight;
        cell.TD = this.instance.wtTable.getCell(cell.coords);
      } else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'area')) {
        if (this.instance.selections.createOrGetArea().cellRange) {
          cell.coords = this.instance.selections.createOrGetArea().cellRange.to;
          cell.TD = this.instance.wtTable.getCell(cell.coords);
        }
      }

      return cell;
    }
    /**
     * onMouseDown callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseDown",
    value: function onMouseDown(event) {
      var priv = privatePool.get(this);
      var activeElement = this.instance.rootDocument.activeElement;
      var getParentNode = (0, _function.partial)(_element.getParent, event.realTarget);
      var realTarget = event.realTarget; // ignore focusable element from mouse down processing (https://github.com/handsontable/handsontable/issues/3555)

      if (realTarget === activeElement || getParentNode(0) === activeElement || getParentNode(1) === activeElement) {
        return;
      }

      var cell = this.parentCell(realTarget);

      if ((0, _element.hasClass)(realTarget, 'corner')) {
        this.instance.getSetting('onCellCornerMouseDown', event, realTarget);
      } else if (cell.TD && this.instance.hasSetting('onCellMouseDown')) {
        this.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, this.instance);
      }

      if (event.button !== 2 && cell.TD) {
        // if not right mouse button
        priv.dblClickOrigin[0] = cell.TD;
        clearTimeout(priv.dblClickTimeout[0]);
        priv.dblClickTimeout[0] = setTimeout(function () {
          priv.dblClickOrigin[0] = null;
        }, 1000);
      }
    }
    /**
     * onContextMenu callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onContextMenu",
    value: function onContextMenu(event) {
      if (this.instance.hasSetting('onCellContextMenu')) {
        var cell = this.parentCell(event.realTarget);

        if (cell.TD) {
          this.instance.getSetting('onCellContextMenu', event, cell.coords, cell.TD, this.instance);
        }
      }
    }
    /**
     * onMouseOver callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseOver",
    value: function onMouseOver(event) {
      if (!this.instance.hasSetting('onCellMouseOver')) {
        return;
      }

      var table = this.instance.wtTable.TABLE;
      var td = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
      var mainWOT = this.instance.cloneSource || this.instance;

      if (td && td !== mainWOT.lastMouseOver && (0, _element.isChildOf)(td, table)) {
        mainWOT.lastMouseOver = td;
        this.instance.getSetting('onCellMouseOver', event, this.instance.wtTable.getCoords(td), td, this.instance);
      }
    }
    /**
     * onMouseOut callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseOut",
    value: function onMouseOut(event) {
      if (!this.instance.hasSetting('onCellMouseOut')) {
        return;
      }

      var table = this.instance.wtTable.TABLE;
      var lastTD = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
      var nextTD = (0, _element.closestDown)(event.relatedTarget, ['TD', 'TH'], table);

      if (lastTD && lastTD !== nextTD && (0, _element.isChildOf)(lastTD, table)) {
        this.instance.getSetting('onCellMouseOut', event, this.instance.wtTable.getCoords(lastTD), lastTD, this.instance);
      }
    }
    /**
     * onMouseUp callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp(event) {
      if (event.button === 2) {
        return;
      } // if not right mouse button


      var priv = privatePool.get(this);
      var cell = this.parentCell(event.realTarget);

      if (cell.TD && this.instance.hasSetting('onCellMouseUp')) {
        this.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, this.instance);
      }

      if (cell.TD === priv.dblClickOrigin[0] && cell.TD === priv.dblClickOrigin[1]) {
        if ((0, _element.hasClass)(event.realTarget, 'corner')) {
          this.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, this.instance);
        } else {
          this.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, this.instance);
        }

        priv.dblClickOrigin[0] = null;
        priv.dblClickOrigin[1] = null;
      } else if (cell.TD === priv.dblClickOrigin[0]) {
        priv.dblClickOrigin[1] = cell.TD;
        clearTimeout(priv.dblClickTimeout[1]);
        priv.dblClickTimeout[1] = setTimeout(function () {
          priv.dblClickOrigin[1] = null;
        }, 500);
      }
    }
    /**
     * onTouchStart callback. Simulates mousedown event.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onTouchStart",
    value: function onTouchStart(event) {
      var priv = privatePool.get(this);
      priv.selectedCellBeforeTouchEnd = this.instance.selections.getCell().cellRange;
      this.instance.touchApplied = true;
      this.onMouseDown(event);
    }
    /**
     * onTouchEnd callback. Simulates mouseup event.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onTouchEnd",
    value: function onTouchEnd(event) {
      var excludeTags = ['A', 'BUTTON', 'INPUT'];
      var target = event.target;
      this.instance.touchApplied = false; // When the standard event was performed on the link element (a cell which contains HTML `a` element) then here
      // we check if it should be canceled. Click is blocked in a situation when the element is rendered outside
      // selected cells. This prevents accidentally page reloads while selecting adjacent cells.

      if (this.selectedCellWasTouched(target) === false && excludeTags.includes(target.tagName)) {
        event.preventDefault();
      }

      this.onMouseUp(event);
    }
    /**
     * Clears double-click timeouts and destroys the internal eventManager instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      var priv = privatePool.get(this);
      clearTimeout(priv.dblClickTimeout[0]);
      clearTimeout(priv.dblClickTimeout[1]);
      this.eventManager.destroy();
    }
  }]);
  return Event;
}();

var _default = Event;
exports.default = _default;

/***/ }),
/* 328 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var _unicode = __webpack_require__(50);

var _browser = __webpack_require__(72);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class Overlays
 */
var Overlays =
/*#__PURE__*/
function () {
  /**
   * @param {Walkontable} wotInstance
   */
  function Overlays(wotInstance) {
    (0, _classCallCheck2.default)(this, Overlays);

    /**
     * Walkontable instance's reference.
     *
     * @private
     * @type {Walkontable}
     */
    this.wot = wotInstance;
    var _this$wot = this.wot,
        rootDocument = _this$wot.rootDocument,
        rootWindow = _this$wot.rootWindow,
        wtTable = _this$wot.wtTable;
    /**
     * Sometimes `line-height` might be set to 'normal'. In that case, a default `font-size` should be multiplied by roughly 1.2.
     * https://developer.mozilla.org/pl/docs/Web/CSS/line-height#Values
     */

    var BODY_LINE_HEIGHT = parseInt(rootWindow.getComputedStyle(rootDocument.body).lineHeight, 10);
    var FALLBACK_BODY_LINE_HEIGHT = parseInt(rootWindow.getComputedStyle(rootDocument.body).fontSize, 10) * 1.2; // legacy support

    this.instance = this.wot;
    this.eventManager = new _eventManager.default(this.wot);
    this.scrollbarSize = (0, _element.getScrollbarWidth)(rootDocument);
    this.wot.update('scrollbarWidth', this.scrollbarSize);
    this.wot.update('scrollbarHeight', this.scrollbarSize);

    if (rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden') {
      this.scrollableElement = wtTable.holder;
    } else {
      this.scrollableElement = (0, _element.getScrollableElement)(wtTable.TABLE);
    }

    this.prepareOverlays();
    this.hasScrollbarBottom = false;
    this.hasScrollbarRight = false;
    this.destroyed = false;
    this.keyPressed = false;
    this.spreaderLastSize = {
      width: null,
      height: null
    };
    this.overlayScrollPositions = {
      master: {
        top: 0,
        left: 0
      },
      top: {
        top: null,
        left: 0
      },
      bottom: {
        top: null,
        left: 0
      },
      left: {
        top: 0,
        left: null
      }
    };
    this.pendingScrollCallbacks = {
      master: {
        top: 0,
        left: 0
      },
      top: {
        left: 0
      },
      bottom: {
        left: 0
      },
      left: {
        top: 0
      }
    };
    this.verticalScrolling = false;
    this.horizontalScrolling = false;
    this.delegatedScrollCallback = false;
    this.registeredListeners = [];
    this.browserLineHeight = BODY_LINE_HEIGHT || FALLBACK_BODY_LINE_HEIGHT;
    this.registerListeners();
    this.lastScrollX = rootWindow.scrollX;
    this.lastScrollY = rootWindow.scrollY;
  }
  /**
   * Prepare overlays based on user settings.
   *
   * @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization.
   */


  (0, _createClass2.default)(Overlays, [{
    key: "prepareOverlays",
    value: function prepareOverlays() {
      var syncScroll = false;

      if (this.topOverlay) {
        syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll;
      } else {
        this.topOverlay = _base.default.createOverlay(_base.default.CLONE_TOP, this.wot);
      }

      if (!_base.default.hasOverlay(_base.default.CLONE_BOTTOM)) {
        this.bottomOverlay = {
          needFullRender: false,
          updateStateOfRendering: function updateStateOfRendering() {
            return false;
          }
        };
      }

      if (!_base.default.hasOverlay(_base.default.CLONE_BOTTOM_LEFT_CORNER)) {
        this.bottomLeftCornerOverlay = {
          needFullRender: false,
          updateStateOfRendering: function updateStateOfRendering() {
            return false;
          }
        };
      }

      if (this.bottomOverlay) {
        syncScroll = this.bottomOverlay.updateStateOfRendering() || syncScroll;
      } else {
        this.bottomOverlay = _base.default.createOverlay(_base.default.CLONE_BOTTOM, this.wot);
      }

      if (this.leftOverlay) {
        syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll;
      } else {
        this.leftOverlay = _base.default.createOverlay(_base.default.CLONE_LEFT, this.wot);
      }

      if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) {
        if (this.topLeftCornerOverlay) {
          syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll;
        } else {
          this.topLeftCornerOverlay = _base.default.createOverlay(_base.default.CLONE_TOP_LEFT_CORNER, this.wot);
        }
      }

      if (this.bottomOverlay.needFullRender && this.leftOverlay.needFullRender) {
        if (this.bottomLeftCornerOverlay) {
          syncScroll = this.bottomLeftCornerOverlay.updateStateOfRendering() || syncScroll;
        } else {
          this.bottomLeftCornerOverlay = _base.default.createOverlay(_base.default.CLONE_BOTTOM_LEFT_CORNER, this.wot);
        }
      }

      if (this.wot.getSetting('debug') && !this.debug) {
        this.debug = _base.default.createOverlay(_base.default.CLONE_DEBUG, this.wot);
      }

      return syncScroll;
    }
    /**
     * Refresh and redraw table
     */

  }, {
    key: "refreshAll",
    value: function refreshAll() {
      if (!this.wot.drawn) {
        return;
      }

      if (!this.wot.wtTable.holder.parentNode) {
        // Walkontable was detached from DOM, but this handler was not removed
        this.destroy();
        return;
      }

      this.wot.draw(true);

      if (this.verticalScrolling) {
        this.leftOverlay.onScroll();
      }

      if (this.horizontalScrolling) {
        this.topOverlay.onScroll();
      }

      this.verticalScrolling = false;
      this.horizontalScrolling = false;
    }
    /**
     * Register all necessary event listeners.
     */

  }, {
    key: "registerListeners",
    value: function registerListeners() {
      var _this = this;

      var _this$wot2 = this.wot,
          rootDocument = _this$wot2.rootDocument,
          rootWindow = _this$wot2.rootWindow;
      var topOverlayScrollableElement = this.topOverlay.mainTableScrollableElement;
      var leftOverlayScrollableElement = this.leftOverlay.mainTableScrollableElement;
      var listenersToRegister = [];
      listenersToRegister.push([rootDocument.documentElement, 'keydown', function (event) {
        return _this.onKeyDown(event);
      }]);
      listenersToRegister.push([rootDocument.documentElement, 'keyup', function () {
        return _this.onKeyUp();
      }]);
      listenersToRegister.push([rootDocument, 'visibilitychange', function () {
        return _this.onKeyUp();
      }]);
      listenersToRegister.push([topOverlayScrollableElement, 'scroll', function (event) {
        return _this.onTableScroll(event);
      }, {
        passive: true
      }]);

      if (topOverlayScrollableElement !== leftOverlayScrollableElement) {
        listenersToRegister.push([leftOverlayScrollableElement, 'scroll', function (event) {
          return _this.onTableScroll(event);
        }, {
          passive: true
        }]);
      }

      var isHighPixelRatio = rootWindow.devicePixelRatio && rootWindow.devicePixelRatio > 1;

      if (isHighPixelRatio || !(0, _browser.isChrome)()) {
        listenersToRegister.push([this.wot.wtTable.wtRootElement.parentNode, 'wheel', function (event) {
          return _this.onCloneWheel(event);
        }, {
          passive: true
        }]);
      } else {
        if (this.topOverlay.needFullRender) {
          listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) {
            return _this.onCloneWheel(event);
          }, {
            passive: true
          }]);
        }

        if (this.bottomOverlay.needFullRender) {
          listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) {
            return _this.onCloneWheel(event);
          }, {
            passive: true
          }]);
        }

        if (this.leftOverlay.needFullRender) {
          listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) {
            return _this.onCloneWheel(event);
          }, {
            passive: true
          }]);
        }

        if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) {
          listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
            return _this.onCloneWheel(event);
          }, {
            passive: true
          }]);
        }

        if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) {
          listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
            return _this.onCloneWheel(event);
          }, {
            passive: true
          }]);
        }
      }

      var resizeTimeout;
      listenersToRegister.push([rootWindow, 'resize', function () {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(function () {
          _this.wot.getSetting('onWindowResize');
        }, 200);
      }]);

      while (listenersToRegister.length) {
        var _this$eventManager;

        var listener = listenersToRegister.pop();

        (_this$eventManager = this.eventManager).addEventListener.apply(_this$eventManager, (0, _toConsumableArray2.default)(listener));

        this.registeredListeners.push(listener);
      }
    }
    /**
     * Deregister all previously registered listeners.
     */

  }, {
    key: "deregisterListeners",
    value: function deregisterListeners() {
      while (this.registeredListeners.length) {
        var listener = this.registeredListeners.pop();
        this.eventManager.removeEventListener(listener[0], listener[1], listener[2]);
      }
    }
    /**
     * Scroll listener
     *
     * @param {Event} event
     */

  }, {
    key: "onTableScroll",
    value: function onTableScroll(event) {
      // There was if statement which controlled flow of this function. It avoided the execution of the next lines
      // on mobile devices. It was changed. Broader description of this case is included within issue #4856.
      var rootWindow = this.wot.rootWindow;
      var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
      var masterVertical = this.topOverlay.mainTableScrollableElement;
      var target = event.target; // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
      // by hot.refreshBorder

      if (this.keyPressed) {
        if (masterVertical !== rootWindow && target !== rootWindow && !event.target.contains(masterVertical) || masterHorizontal !== rootWindow && target !== rootWindow && !event.target.contains(masterHorizontal)) {
          return;
        }
      }

      this.syncScrollPositions(event);
    }
    /**
     * Wheel listener for cloned overlays.
     *
     * @param {Event} event
     */

  }, {
    key: "onCloneWheel",
    value: function onCloneWheel(event) {
      var rootWindow = this.wot.rootWindow; // There was if statement which controlled flow of this function. It avoided the execution of the next lines
      // on mobile devices. It was changed. Broader description of this case is included within issue #4856.

      var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
      var masterVertical = this.topOverlay.mainTableScrollableElement;
      var target = event.target; // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
      // by hot.refreshBorder

      var shouldNotWheelVertically = masterVertical !== rootWindow && target !== rootWindow && !event.target.contains(masterVertical);
      var shouldNotWheelHorizontally = masterHorizontal !== rootWindow && target !== rootWindow && !event.target.contains(masterHorizontal);

      if (this.keyPressed && (shouldNotWheelVertically || shouldNotWheelHorizontally)) {
        return;
      }

      this.translateMouseWheelToScroll(event);
    }
    /**
     * Key down listener
     */

  }, {
    key: "onKeyDown",
    value: function onKeyDown(event) {
      this.keyPressed = (0, _unicode.isKey)(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT');
    }
    /**
     * Key up listener
     */

  }, {
    key: "onKeyUp",
    value: function onKeyUp() {
      this.keyPressed = false;
    }
    /**
     * Translate wheel event into scroll event and sync scroll overlays position
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "translateMouseWheelToScroll",
    value: function translateMouseWheelToScroll(event) {
      var browserLineHeight = this.browserLineHeight;
      var deltaY = isNaN(event.deltaY) ? -1 * event.wheelDeltaY : event.deltaY;
      var deltaX = isNaN(event.deltaX) ? -1 * event.wheelDeltaX : event.deltaX;

      if (event.deltaMode === 1) {
        deltaX += deltaX * browserLineHeight;
        deltaY += deltaY * browserLineHeight;
      }

      this.scrollVertically(deltaY);
      this.scrollHorizontally(deltaX);
    }
    /**
     * Scrolls main scrollable element horizontally.
     *
     * @param {Number} delta Relative value to scroll.
     */

  }, {
    key: "scrollVertically",
    value: function scrollVertically(delta) {
      this.scrollableElement.scrollTop += delta;
    }
    /**
     * Scrolls main scrollable element horizontally.
     *
     * @param {Number} delta Relative value to scroll.
     */

  }, {
    key: "scrollHorizontally",
    value: function scrollHorizontally(delta) {
      this.scrollableElement.scrollLeft += delta;
    }
    /**
     * Synchronize scroll position between master table and overlay table.
     *
     * @private
     */

  }, {
    key: "syncScrollPositions",
    value: function syncScrollPositions() {
      if (this.destroyed) {
        return;
      }

      var rootWindow = this.wot.rootWindow;
      var topHolder = this.topOverlay.clone.wtTable.holder;
      var leftHolder = this.leftOverlay.clone.wtTable.holder;
      var _ref = [this.scrollableElement.scrollLeft, this.scrollableElement.scrollTop],
          scrollLeft = _ref[0],
          scrollTop = _ref[1];
      this.horizontalScrolling = topHolder.scrollLeft !== scrollLeft || this.lastScrollX !== rootWindow.scrollX;
      this.verticalScrolling = leftHolder.scrollTop !== scrollTop || this.lastScrollY !== rootWindow.scrollY;
      this.lastScrollX = rootWindow.scrollX;
      this.lastScrollY = rootWindow.scrollY;

      if (this.horizontalScrolling) {
        topHolder.scrollLeft = scrollLeft;
        var bottomHolder = this.bottomOverlay.needFullRender ? this.bottomOverlay.clone.wtTable.holder : null;

        if (bottomHolder) {
          bottomHolder.scrollLeft = scrollLeft;
        }
      }

      if (this.verticalScrolling) {
        leftHolder.scrollTop = scrollTop;
      }

      this.refreshAll();
    }
    /**
     * Synchronize overlay scrollbars with the master scrollbar
     */

  }, {
    key: "syncScrollWithMaster",
    value: function syncScrollWithMaster() {
      var master = this.topOverlay.mainTableScrollableElement;
      var scrollLeft = master.scrollLeft,
          scrollTop = master.scrollTop;

      if (this.topOverlay.needFullRender) {
        this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
      }

      if (this.bottomOverlay.needFullRender) {
        this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
      }

      if (this.leftOverlay.needFullRender) {
        this.leftOverlay.clone.wtTable.holder.scrollTop = scrollTop;
      }
    }
    /**
     * Update the main scrollable elements for all the overlays.
     */

  }, {
    key: "updateMainScrollableElements",
    value: function updateMainScrollableElements() {
      this.deregisterListeners();
      this.leftOverlay.updateMainScrollableElement();
      this.topOverlay.updateMainScrollableElement();

      if (this.bottomOverlay.needFullRender) {
        this.bottomOverlay.updateMainScrollableElement();
      }

      var _this$wot3 = this.wot,
          rootWindow = _this$wot3.rootWindow,
          wtTable = _this$wot3.wtTable;

      if (rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden') {
        this.scrollableElement = wtTable.holder;
      } else {
        this.scrollableElement = (0, _element.getScrollableElement)(wtTable.TABLE);
      }

      this.registerListeners();
    }
    /**
     *
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.eventManager.destroy();
      this.topOverlay.destroy();

      if (this.bottomOverlay.clone) {
        this.bottomOverlay.destroy();
      }

      this.leftOverlay.destroy();

      if (this.topLeftCornerOverlay) {
        this.topLeftCornerOverlay.destroy();
      }

      if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
        this.bottomLeftCornerOverlay.destroy();
      }

      if (this.debug) {
        this.debug.destroy();
      }

      this.destroyed = true;
    }
    /**
     * @param {Boolean} [fastDraw=false]
     */

  }, {
    key: "refresh",
    value: function refresh() {
      var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (this.topOverlay.areElementSizesAdjusted && this.leftOverlay.areElementSizesAdjusted) {
        var container = this.wot.wtTable.wtRootElement.parentNode || this.wot.wtTable.wtRootElement;
        var width = container.clientWidth;
        var height = container.clientHeight;

        if (width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height) {
          this.spreaderLastSize.width = width;
          this.spreaderLastSize.height = height;
          this.adjustElementsSize();
        }
      }

      if (this.bottomOverlay.clone) {
        this.bottomOverlay.refresh(fastDraw);
      }

      this.leftOverlay.refresh(fastDraw);
      this.topOverlay.refresh(fastDraw);

      if (this.topLeftCornerOverlay) {
        this.topLeftCornerOverlay.refresh(fastDraw);
      }

      if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
        this.bottomLeftCornerOverlay.refresh(fastDraw);
      }

      if (this.debug) {
        this.debug.refresh(fastDraw);
      }
    }
    /**
     * Adjust overlays elements size and master table size
     *
     * @param {Boolean} [force=false]
     */

  }, {
    key: "adjustElementsSize",
    value: function adjustElementsSize() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var _this$wot4 = this.wot,
          wtViewport = _this$wot4.wtViewport,
          wtTable = _this$wot4.wtTable;
      var totalColumns = this.wot.getSetting('totalColumns');
      var totalRows = this.wot.getSetting('totalRows');
      var headerRowSize = wtViewport.getRowHeaderWidth();
      var headerColumnSize = wtViewport.getColumnHeaderHeight();
      var hiderStyle = wtTable.hider.style;
      hiderStyle.width = "".concat(headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns), "px");
      hiderStyle.height = "".concat(headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1, "px");

      if (this.scrollbarSize > 0) {
        var _wtTable$wtRootElemen = wtTable.wtRootElement,
            rootElemScrollHeight = _wtTable$wtRootElemen.scrollHeight,
            rootElemScrollWidth = _wtTable$wtRootElemen.scrollWidth;
        var _wtTable$holder = wtTable.holder,
            holderScrollHeight = _wtTable$holder.scrollHeight,
            holderScrollWidth = _wtTable$holder.scrollWidth;
        this.hasScrollbarRight = rootElemScrollHeight < holderScrollHeight;
        this.hasScrollbarBottom = rootElemScrollWidth < holderScrollWidth;

        if (this.hasScrollbarRight && wtTable.hider.scrollWidth + this.scrollbarSize > rootElemScrollWidth) {
          this.hasScrollbarBottom = true;
        } else if (this.hasScrollbarBottom && wtTable.hider.scrollHeight + this.scrollbarSize > rootElemScrollHeight) {
          this.hasScrollbarRight = true;
        }
      }

      this.topOverlay.adjustElementsSize(force);
      this.leftOverlay.adjustElementsSize(force);
      this.bottomOverlay.adjustElementsSize(force);
    }
    /**
     *
     */

  }, {
    key: "applyToDOM",
    value: function applyToDOM() {
      if (!this.topOverlay.areElementSizesAdjusted || !this.leftOverlay.areElementSizesAdjusted) {
        this.adjustElementsSize();
      }

      this.topOverlay.applyToDOM();

      if (this.bottomOverlay.clone) {
        this.bottomOverlay.applyToDOM();
      }

      this.leftOverlay.applyToDOM();
    }
    /**
     * Get the parent overlay of the provided element.
     *
     * @param {HTMLElement} element
     * @returns {Object|null}
     */

  }, {
    key: "getParentOverlay",
    value: function getParentOverlay(element) {
      if (!element) {
        return null;
      }

      var overlays = [this.topOverlay, this.leftOverlay, this.bottomOverlay, this.topLeftCornerOverlay, this.bottomLeftCornerOverlay];
      var result = null;
      (0, _array.arrayEach)(overlays, function (elem) {
        if (!elem) {
          return;
        }

        if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) {
          result = elem.clone;
        }
      });
      return result;
    }
  }]);
  return Overlays;
}();

var _default = Overlays;
exports.default = _default;

/***/ }),
/* 329 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

/**
 * @class Scroll
 */
var Scroll =
/*#__PURE__*/
function () {
  /**
   * @param {Walkontable} wotInstance
   */
  function Scroll(wotInstance) {
    (0, _classCallCheck2.default)(this, Scroll);
    this.wot = wotInstance; // legacy support

    this.instance = wotInstance;
  }
  /**
   * Scrolls viewport to a cell.
   *
   * @param {CellCoords} coords
   * @param {Boolean} [snapToTop]
   * @param {Boolean} [snapToRight]
   * @param {Boolean} [snapToBottom]
   * @param {Boolean} [snapToLeft]
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Scroll, [{
    key: "scrollViewport",
    value: function scrollViewport(coords, snapToTop, snapToRight, snapToBottom, snapToLeft) {
      var scrolledHorizontally = this.scrollViewportHorizontally(coords.col, snapToRight, snapToLeft);
      var scrolledVertically = this.scrollViewportVertically(coords.row, snapToTop, snapToBottom);
      return scrolledHorizontally || scrolledVertically;
    }
    /**
     * Scrolls viewport to a column.
     *
     * @param {Number} column Visual column index.
     * @param {Boolean} [snapToRight]
     * @param {Boolean} [snapToLeft]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportHorizontally",
    value: function scrollViewportHorizontally(column, snapToRight, snapToLeft) {
      if (!this.wot.drawn) {
        return false;
      }

      var _this$_getVariables = this._getVariables(),
          fixedColumnsLeft = _this$_getVariables.fixedColumnsLeft,
          leftOverlay = _this$_getVariables.leftOverlay,
          totalColumns = _this$_getVariables.totalColumns;

      var result = false;

      if (column >= 0 && column <= Math.max(totalColumns - 1, 0)) {
        if (column >= fixedColumnsLeft && (column < this.getFirstVisibleColumn() || snapToLeft)) {
          result = leftOverlay.scrollTo(column);
        } else if (column > this.getLastVisibleColumn() || snapToRight) {
          result = leftOverlay.scrollTo(column, true);
        }
      }

      return result;
    }
    /**
     * Scrolls viewport to a row.
     *
     * @param {Number} row Visual row index.
     * @param {Boolean} [snapToTop]
     * @param {Boolean} [snapToBottom]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportVertically",
    value: function scrollViewportVertically(row, snapToTop, snapToBottom) {
      if (!this.wot.drawn) {
        return false;
      }

      var _this$_getVariables2 = this._getVariables(),
          fixedRowsBottom = _this$_getVariables2.fixedRowsBottom,
          fixedRowsTop = _this$_getVariables2.fixedRowsTop,
          topOverlay = _this$_getVariables2.topOverlay,
          totalRows = _this$_getVariables2.totalRows;

      var result = false;

      if (row >= 0 && row <= Math.max(totalRows - 1, 0)) {
        if (row >= fixedRowsTop && (row < this.getFirstVisibleRow() || snapToTop)) {
          result = topOverlay.scrollTo(row);
        } else if (row > this.getLastVisibleRow() && row < totalRows - fixedRowsBottom || snapToBottom) {
          result = topOverlay.scrollTo(row, true);
        }
      }

      return result;
    }
    /**
     * Get first visible row based on virtual dom and how table is visible in browser window viewport.
     *
     * @returns {Number}
     */

  }, {
    key: "getFirstVisibleRow",
    value: function getFirstVisibleRow() {
      var _this$_getVariables3 = this._getVariables(),
          topOverlay = _this$_getVariables3.topOverlay,
          wtTable = _this$_getVariables3.wtTable,
          wtViewport = _this$_getVariables3.wtViewport,
          totalRows = _this$_getVariables3.totalRows,
          fixedRowsTop = _this$_getVariables3.fixedRowsTop;

      var rootWindow = this.wot.rootWindow;
      var firstVisibleRow = wtTable.getFirstVisibleRow();

      if (topOverlay.mainTableScrollableElement === rootWindow) {
        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
        var totalTableHeight = (0, _element.innerHeight)(wtTable.hider);
        var windowHeight = (0, _element.innerHeight)(rootWindow);
        var windowScrollTop = (0, _element.getScrollTop)(rootWindow, rootWindow); // Only calculate firstVisibleRow when table didn't filled (from up) whole viewport space

        if (rootElementOffset.top + totalTableHeight - windowHeight <= windowScrollTop) {
          var rowsHeight = wtViewport.getColumnHeaderHeight();
          rowsHeight += topOverlay.sumCellSizes(0, fixedRowsTop);
          (0, _number.rangeEachReverse)(totalRows, 1, function (row) {
            rowsHeight += topOverlay.sumCellSizes(row - 1, row);

            if (rootElementOffset.top + totalTableHeight - rowsHeight <= windowScrollTop) {
              // Return physical row + 1
              firstVisibleRow = row;
              return false;
            }
          });
        }
      }

      return firstVisibleRow;
    }
    /**
     * Get last visible row based on virtual dom and how table is visible in browser window viewport.
     *
     * @returns {Number}
     */

  }, {
    key: "getLastVisibleRow",
    value: function getLastVisibleRow() {
      var _this$_getVariables4 = this._getVariables(),
          topOverlay = _this$_getVariables4.topOverlay,
          wtTable = _this$_getVariables4.wtTable,
          wtViewport = _this$_getVariables4.wtViewport,
          totalRows = _this$_getVariables4.totalRows;

      var rootWindow = this.wot.rootWindow;
      var lastVisibleRow = wtTable.getLastVisibleRow();

      if (topOverlay.mainTableScrollableElement === rootWindow) {
        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
        var windowHeight = (0, _element.innerHeight)(rootWindow);
        var windowScrollTop = (0, _element.getScrollTop)(rootWindow, rootWindow); // Only calculate lastVisibleRow when table didn't filled (from bottom) whole viewport space

        if (rootElementOffset.top > windowScrollTop) {
          var rowsHeight = wtViewport.getColumnHeaderHeight();
          (0, _number.rangeEach)(1, totalRows, function (row) {
            rowsHeight += topOverlay.sumCellSizes(row - 1, row);

            if (rootElementOffset.top + rowsHeight - windowScrollTop >= windowHeight) {
              // Return physical row - 1 (-2 because rangeEach gives row index + 1 - sumCellSizes requirements)
              lastVisibleRow = row - 2;
              return false;
            }
          });
        }
      }

      return lastVisibleRow;
    }
    /**
     * Get first visible column based on virtual dom and how table is visible in browser window viewport.
     *
     * @returns {Number}
     */

  }, {
    key: "getFirstVisibleColumn",
    value: function getFirstVisibleColumn() {
      var _this$_getVariables5 = this._getVariables(),
          leftOverlay = _this$_getVariables5.leftOverlay,
          wtTable = _this$_getVariables5.wtTable,
          wtViewport = _this$_getVariables5.wtViewport,
          totalColumns = _this$_getVariables5.totalColumns;

      var rootWindow = this.wot.rootWindow;
      var firstVisibleColumn = wtTable.getFirstVisibleColumn();

      if (leftOverlay.mainTableScrollableElement === rootWindow) {
        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
        var totalTableWidth = (0, _element.innerWidth)(wtTable.hider);
        var windowWidth = (0, _element.innerWidth)(rootWindow);
        var windowScrollLeft = (0, _element.getScrollLeft)(rootWindow, rootWindow); // Only calculate firstVisibleColumn when table didn't filled (from left) whole viewport space

        if (rootElementOffset.left + totalTableWidth - windowWidth <= windowScrollLeft) {
          var columnsWidth = wtViewport.getRowHeaderWidth();
          (0, _number.rangeEachReverse)(totalColumns, 1, function (column) {
            columnsWidth += leftOverlay.sumCellSizes(column - 1, column);

            if (rootElementOffset.left + totalTableWidth - columnsWidth <= windowScrollLeft) {
              // Return physical column + 1
              firstVisibleColumn = column;
              return false;
            }
          });
        }
      }

      return firstVisibleColumn;
    }
    /**
     * Get last visible column based on virtual dom and how table is visible in browser window viewport.
     *
     * @returns {Number}
     */

  }, {
    key: "getLastVisibleColumn",
    value: function getLastVisibleColumn() {
      var _this$_getVariables6 = this._getVariables(),
          leftOverlay = _this$_getVariables6.leftOverlay,
          wtTable = _this$_getVariables6.wtTable,
          wtViewport = _this$_getVariables6.wtViewport,
          totalColumns = _this$_getVariables6.totalColumns;

      var rootWindow = this.wot.rootWindow;
      var lastVisibleColumn = wtTable.getLastVisibleColumn();

      if (leftOverlay.mainTableScrollableElement === rootWindow) {
        var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
        var windowWidth = (0, _element.innerWidth)(rootWindow);
        var windowScrollLeft = (0, _element.getScrollLeft)(rootWindow, rootWindow); // Only calculate lastVisibleColumn when table didn't filled (from right) whole viewport space

        if (rootElementOffset.left > windowScrollLeft) {
          var columnsWidth = wtViewport.getRowHeaderWidth();
          (0, _number.rangeEach)(1, totalColumns, function (column) {
            columnsWidth += leftOverlay.sumCellSizes(column - 1, column);

            if (rootElementOffset.left + columnsWidth - windowScrollLeft >= windowWidth) {
              // Return physical column - 1 (-2 because rangeEach gives column index + 1 - sumCellSizes requirements)
              lastVisibleColumn = column - 2;
              return false;
            }
          });
        }
      }

      return lastVisibleColumn;
    }
    /**
     * Returns collection of variables used to rows and columns visibility calculations.
     *
     * @returns {Object}
     * @private
     */

  }, {
    key: "_getVariables",
    value: function _getVariables() {
      var wot = this.wot;
      var topOverlay = wot.wtOverlays.topOverlay;
      var leftOverlay = wot.wtOverlays.leftOverlay;
      var wtTable = wot.wtTable;
      var wtViewport = wot.wtViewport;
      var totalRows = wot.getSetting('totalRows');
      var totalColumns = wot.getSetting('totalColumns');
      var fixedRowsTop = wot.getSetting('fixedRowsTop');
      var fixedRowsBottom = wot.getSetting('fixedRowsBottom');
      var fixedColumnsLeft = wot.getSetting('fixedColumnsLeft');
      return {
        topOverlay: topOverlay,
        leftOverlay: leftOverlay,
        wtTable: wtTable,
        wtViewport: wtViewport,
        totalRows: totalRows,
        totalColumns: totalColumns,
        fixedRowsTop: fixedRowsTop,
        fixedRowsBottom: fixedRowsBottom,
        fixedColumnsLeft: fixedColumnsLeft
      };
    }
  }]);
  return Scroll;
}();

var _default = Scroll;
exports.default = _default;

/***/ }),
/* 330 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

/**
 * @class Settings
 */
var Settings =
/*#__PURE__*/
function () {
  /**
   * @param {Walkontable} wotInstance
   * @param {Object} settings
   */
  function Settings(wotInstance, settings) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Settings);
    this.wot = wotInstance; // legacy support

    this.instance = wotInstance; // default settings. void 0 means it is required, null means it can be empty

    this.defaults = {
      table: void 0,
      debug: false,
      // shows WalkontableDebugOverlay
      // presentation mode
      externalRowCalculator: false,
      stretchH: 'none',
      // values: all, last, none
      currentRowClassName: null,
      currentColumnClassName: null,
      preventOverflow: function preventOverflow() {
        return false;
      },
      // data source
      data: void 0,
      freezeOverlays: false,
      fixedColumnsLeft: 0,
      fixedRowsTop: 0,
      fixedRowsBottom: 0,
      minSpareRows: 0,
      // this must be array of functions: [function (row, TH) {}]
      rowHeaders: function rowHeaders() {
        return [];
      },
      // this must be array of functions: [function (column, TH) {}]
      columnHeaders: function columnHeaders() {
        return [];
      },
      totalRows: void 0,
      totalColumns: void 0,
      cellRenderer: function cellRenderer(row, column, TD) {
        var cellData = _this.getSetting('data', row, column);

        (0, _element.fastInnerText)(TD, cellData === void 0 || cellData === null ? '' : cellData);
      },
      // columnWidth: 50,
      columnWidth: function columnWidth() {// return undefined means use default size for the rendered cell content
      },
      rowHeight: function rowHeight() {// return undefined means use default size for the rendered cell content
      },
      defaultRowHeight: 23,
      defaultColumnWidth: 50,
      selections: null,
      hideBorderOnMouseDownOver: false,
      viewportRowCalculatorOverride: null,
      viewportColumnCalculatorOverride: null,
      // callbacks
      onCellMouseDown: null,
      onCellContextMenu: null,
      onCellMouseOver: null,
      onCellMouseOut: null,
      onCellMouseUp: null,
      //    onCellMouseOut: null,
      onCellDblClick: null,
      onCellCornerMouseDown: null,
      onCellCornerDblClick: null,
      beforeDraw: null,
      onDraw: null,
      onBeforeRemoveCellClassNames: null,
      onAfterDrawSelection: null,
      onBeforeDrawBorders: null,
      onScrollVertically: null,
      onScrollHorizontally: null,
      onBeforeTouchScroll: null,
      onAfterMomentumScroll: null,
      onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(width) {
        return width;
      },
      onModifyRowHeaderWidth: null,
      onModifyGetCellCoords: null,
      onWindowResize: null,
      // constants
      scrollbarWidth: 10,
      scrollbarHeight: 10,
      renderAllRows: false,
      groups: false,
      rowHeaderWidth: null,
      columnHeaderHeight: null,
      headerClassName: null
    }; // reference to settings

    this.settings = {};
    (0, _object.objectEach)(this.defaults, function (value, key) {
      if (settings[key] !== void 0) {
        _this.settings[key] = settings[key];
      } else if (value === void 0) {
        throw new Error("A required setting \"".concat(key, "\" was not provided"));
      } else {
        _this.settings[key] = value;
      }
    });
  }
  /**
   * Update settings
   *
   * @param {Object} settings
   * @param {*} value
   * @returns {Walkontable}
   */


  (0, _createClass2.default)(Settings, [{
    key: "update",
    value: function update(settings, value) {
      var _this2 = this;

      if (value === void 0) {
        // settings is object
        (0, _object.objectEach)(settings, function (settingValue, key) {
          _this2.settings[key] = settingValue;
        });
      } else {
        // if value is defined then settings is the key
        this.settings[settings] = value;
      }

      return this.wot;
    }
    /**
     * Get setting by name
     *
     * @param {String} key
     * @param {*} param1
     * @param {*} param2
     * @param {*} param3
     * @param {*} param4
     * @returns {*}
     */

  }, {
    key: "getSetting",
    value: function getSetting(key, param1, param2, param3, param4) {
      if (typeof this.settings[key] === 'function') {
        // this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
        return this.settings[key](param1, param2, param3, param4);
      } else if (param1 !== void 0 && Array.isArray(this.settings[key])) {
        // perhaps this can be removed, it is only used in tests
        return this.settings[key][param1];
      }

      return this.settings[key];
    }
    /**
     * Checks if setting exists
     *
     * @param {Boolean} key
     * @returns {Boolean}
     */

  }, {
    key: "has",
    value: function has(key) {
      return !!this.settings[key];
    }
  }]);
  return Settings;
}();

var _default = Settings;
exports.default = _default;

/***/ }),
/* 331 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(14);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _function = __webpack_require__(75);

var _coords = _interopRequireDefault(__webpack_require__(106));

var _column = _interopRequireDefault(__webpack_require__(201));

var _row = _interopRequireDefault(__webpack_require__(202));

var _tableRenderer = _interopRequireDefault(__webpack_require__(334));

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 *
 */
var Table =
/*#__PURE__*/
function () {
  /**
   * @param {Walkontable} wotInstance
   * @param {HTMLTableElement} table
   */
  function Table(wotInstance, table) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Table);
    this.wot = wotInstance; // legacy support

    this.instance = this.wot;
    this.TABLE = table;
    this.TBODY = null;
    this.THEAD = null;
    this.COLGROUP = null;
    this.tableOffset = 0;
    this.holderOffset = 0;
    (0, _element.removeTextNodes)(this.TABLE);
    this.spreader = this.createSpreader(this.TABLE);
    this.hider = this.createHider(this.spreader);
    this.holder = this.createHolder(this.hider);
    this.wtRootElement = this.holder.parentNode;
    this.alignOverlaysWithTrimmingContainer();
    this.fixTableDomTree();
    this.colgroupChildrenLength = this.COLGROUP.childNodes.length;
    this.theadChildrenLength = this.THEAD.firstChild ? this.THEAD.firstChild.childNodes.length : 0;
    this.tbodyChildrenLength = this.TBODY.childNodes.length;
    this.rowFilter = null;
    this.columnFilter = null;
    this.correctHeaderWidth = false;
    var origRowHeaderWidth = this.wot.wtSettings.settings.rowHeaderWidth; // Fix for jumping row headers (https://github.com/handsontable/handsontable/issues/3850)

    this.wot.wtSettings.settings.rowHeaderWidth = function () {
      return _this._modifyRowHeaderWidth(origRowHeaderWidth);
    };
  }
  /**
   *
   */


  (0, _createClass2.default)(Table, [{
    key: "fixTableDomTree",
    value: function fixTableDomTree() {
      var rootDocument = this.wot.rootDocument;
      this.TBODY = this.TABLE.querySelector('tbody');

      if (!this.TBODY) {
        this.TBODY = rootDocument.createElement('tbody');
        this.TABLE.appendChild(this.TBODY);
      }

      this.THEAD = this.TABLE.querySelector('thead');

      if (!this.THEAD) {
        this.THEAD = rootDocument.createElement('thead');
        this.TABLE.insertBefore(this.THEAD, this.TBODY);
      }

      this.COLGROUP = this.TABLE.querySelector('colgroup');

      if (!this.COLGROUP) {
        this.COLGROUP = rootDocument.createElement('colgroup');
        this.TABLE.insertBefore(this.COLGROUP, this.THEAD);
      }

      if (this.wot.getSetting('columnHeaders').length && !this.THEAD.childNodes.length) {
        this.THEAD.appendChild(rootDocument.createElement('TR'));
      }
    }
    /**
     * @param table
     * @returns {HTMLElement}
     */

  }, {
    key: "createSpreader",
    value: function createSpreader(table) {
      var parent = table.parentNode;
      var spreader;

      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
        spreader = this.wot.rootDocument.createElement('div');
        spreader.className = 'wtSpreader';

        if (parent) {
          // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
          parent.insertBefore(spreader, table);
        }

        spreader.appendChild(table);
      }

      spreader.style.position = 'relative';
      return spreader;
    }
    /**
     * @param spreader
     * @returns {HTMLElement}
     */

  }, {
    key: "createHider",
    value: function createHider(spreader) {
      var parent = spreader.parentNode;
      var hider;

      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
        hider = this.wot.rootDocument.createElement('div');
        hider.className = 'wtHider';

        if (parent) {
          // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
          parent.insertBefore(hider, spreader);
        }

        hider.appendChild(spreader);
      }

      return hider;
    }
    /**
     *
     * @param hider
     * @returns {HTMLElement}
     */

  }, {
    key: "createHolder",
    value: function createHolder(hider) {
      var parent = hider.parentNode;
      var holder;

      if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
        holder = this.wot.rootDocument.createElement('div');
        holder.style.position = 'relative';
        holder.className = 'wtHolder';

        if (parent) {
          // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
          parent.insertBefore(holder, hider);
        }

        if (!this.isWorkingOnClone()) {
          holder.parentNode.className += 'ht_master handsontable';
        }

        holder.appendChild(hider);
      }

      return holder;
    }
  }, {
    key: "alignOverlaysWithTrimmingContainer",
    value: function alignOverlaysWithTrimmingContainer() {
      var trimmingElement = (0, _element.getTrimmingContainer)(this.wtRootElement);

      if (!this.isWorkingOnClone()) {
        var rootWindow = this.wot.rootWindow;
        this.holder.parentNode.style.position = 'relative';

        if (trimmingElement === rootWindow) {
          var preventOverflow = this.wot.getSetting('preventOverflow');

          if (!preventOverflow) {
            this.holder.style.overflow = 'visible';
            this.wtRootElement.style.overflow = 'visible';
          }
        } else {
          var trimmingHeight = (0, _element.getStyle)(trimmingElement, 'height', rootWindow);
          var holderStyle = this.holder.style;
          var scrollWidth = trimmingElement.scrollWidth,
              scrollHeight = trimmingElement.scrollHeight;

          var _trimmingElement$getB = trimmingElement.getBoundingClientRect(),
              width = _trimmingElement$getB.width,
              height = _trimmingElement$getB.height;

          width = Math.min(width, scrollWidth);
          height = Math.min(height, scrollHeight);
          holderStyle.width = "".concat(width, "px");
          holderStyle.height = trimmingHeight === 'auto' ? 'auto' : "".concat(height, "px");
          holderStyle.overflow = '';
        }
      }
    }
  }, {
    key: "isWorkingOnClone",
    value: function isWorkingOnClone() {
      return !!this.wot.cloneSource;
    }
    /**
     * Redraws the table
     *
     * @param {Boolean} fastDraw If TRUE, will try to avoid full redraw and only update the border positions. If FALSE or UNDEFINED, will perform a full redraw
     * @returns {Table}
     */

  }, {
    key: "draw",
    value: function draw(fastDraw) {
      var wot = this.wot;
      var wtOverlays = wot.wtOverlays,
          wtViewport = wot.wtViewport;
      var totalRows = this.instance.getSetting('totalRows');
      var rowHeaders = wot.getSetting('rowHeaders').length;
      var columnHeaders = wot.getSetting('columnHeaders').length;
      var syncScroll = false;
      var runFastDraw = fastDraw;

      if (!this.isWorkingOnClone()) {
        this.holderOffset = (0, _element.offset)(this.holder);
        runFastDraw = wtViewport.createRenderCalculators(runFastDraw);

        if (rowHeaders && !wot.getSetting('fixedColumnsLeft')) {
          var leftScrollPos = wtOverlays.leftOverlay.getScrollPosition();
          var previousState = this.correctHeaderWidth;
          this.correctHeaderWidth = leftScrollPos > 0;

          if (previousState !== this.correctHeaderWidth) {
            runFastDraw = false;
          }
        }
      }

      if (!this.isWorkingOnClone()) {
        syncScroll = wtOverlays.prepareOverlays();
      }

      if (runFastDraw) {
        if (!this.isWorkingOnClone()) {
          // in case we only scrolled without redraw, update visible rows information in oldRowsCalculator
          wtViewport.createVisibleCalculators();
        }

        if (wtOverlays) {
          wtOverlays.refresh(true);
        }
      } else {
        var cloneOverlay = wot.cloneOverlay;

        if (this.isWorkingOnClone()) {
          this.tableOffset = wot.cloneSource.wtTable.tableOffset;
        } else {
          this.tableOffset = (0, _element.offset)(this.TABLE);
        }

        var startRow;

        if (_base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_DEBUG) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_TOP) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_TOP_LEFT_CORNER)) {
          startRow = 0;
        } else if (_base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_BOTTOM) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_BOTTOM_LEFT_CORNER)) {
          startRow = Math.max(totalRows - wot.getSetting('fixedRowsBottom'), 0);
        } else {
          startRow = wtViewport.rowsRenderCalculator.startRow;
        }

        var startColumn;

        if (_base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_DEBUG) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_LEFT) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_TOP_LEFT_CORNER) || _base.default.isOverlayTypeOf(cloneOverlay, _base.default.CLONE_BOTTOM_LEFT_CORNER)) {
          startColumn = 0;
        } else {
          startColumn = wtViewport.columnsRenderCalculator.startColumn;
        }

        this.rowFilter = new _row.default(startRow, totalRows, columnHeaders);
        this.columnFilter = new _column.default(startColumn, wot.getSetting('totalColumns'), rowHeaders);
        this.alignOverlaysWithTrimmingContainer();

        this._doDraw(); // creates calculator after draw

      }

      this.refreshSelections(runFastDraw);

      if (!this.isWorkingOnClone()) {
        wtOverlays.topOverlay.resetFixedPosition();

        if (wtOverlays.bottomOverlay.clone) {
          wtOverlays.bottomOverlay.resetFixedPosition();
        }

        wtOverlays.leftOverlay.resetFixedPosition();

        if (wtOverlays.topLeftCornerOverlay) {
          wtOverlays.topLeftCornerOverlay.resetFixedPosition();
        }

        if (wtOverlays.bottomLeftCornerOverlay && wtOverlays.bottomLeftCornerOverlay.clone) {
          wtOverlays.bottomLeftCornerOverlay.resetFixedPosition();
        }
      }

      if (syncScroll) {
        wtOverlays.syncScrollWithMaster();
      }

      wot.drawn = true;
      return this;
    }
  }, {
    key: "_doDraw",
    value: function _doDraw() {
      var wtRenderer = new _tableRenderer.default(this);
      wtRenderer.render();
    }
  }, {
    key: "removeClassFromCells",
    value: function removeClassFromCells(className) {
      var nodes = this.TABLE.querySelectorAll(".".concat(className));

      for (var i = 0, len = nodes.length; i < len; i++) {
        (0, _element.removeClass)(nodes[i], className);
      }
    }
    /**
     * Refresh the table selection by re-rendering Selection instances connected with that instance.
     *
     * @param {Boolean} fastDraw If fast drawing is enabled than additionally className clearing is applied.
     */

  }, {
    key: "refreshSelections",
    value: function refreshSelections(fastDraw) {
      var wot = this.wot;

      if (!wot.selections) {
        return;
      }

      var highlights = Array.from(wot.selections);
      var len = highlights.length;

      if (fastDraw) {
        var classesToRemove = [];

        for (var i = 0; i < len; i++) {
          var _highlights$i$setting = highlights[i].settings,
              highlightHeaderClassName = _highlights$i$setting.highlightHeaderClassName,
              highlightRowClassName = _highlights$i$setting.highlightRowClassName,
              highlightColumnClassName = _highlights$i$setting.highlightColumnClassName;
          var classNames = highlights[i].classNames;
          var classNamesLength = classNames.length;

          for (var j = 0; j < classNamesLength; j++) {
            if (!classesToRemove.includes(classNames[j])) {
              classesToRemove.push(classNames[j]);
            }
          }

          if (highlightHeaderClassName && !classesToRemove.includes(highlightHeaderClassName)) {
            classesToRemove.push(highlightHeaderClassName);
          }

          if (highlightRowClassName && !classesToRemove.includes(highlightRowClassName)) {
            classesToRemove.push(highlightRowClassName);
          }

          if (highlightColumnClassName && !classesToRemove.includes(highlightColumnClassName)) {
            classesToRemove.push(highlightColumnClassName);
          }
        }

        var additionalClassesToRemove = wot.getSetting('onBeforeRemoveCellClassNames');

        if (Array.isArray(additionalClassesToRemove)) {
          for (var _i = 0; _i < additionalClassesToRemove.length; _i++) {
            classesToRemove.push(additionalClassesToRemove[_i]);
          }
        }

        var classesToRemoveLength = classesToRemove.length;

        for (var _i2 = 0; _i2 < classesToRemoveLength; _i2++) {
          // there was no rerender, so we need to remove classNames by ourselves
          this.removeClassFromCells(classesToRemove[_i2]);
        }
      }

      for (var _i3 = 0; _i3 < len; _i3++) {
        highlights[_i3].draw(wot, fastDraw);
      }
    }
    /**
     * Get cell element at coords.
     *
     * @param {CellCoords} coords
     * @returns {HTMLElement|Number} HTMLElement on success or Number one of the exit codes on error:
     *  -1 row before viewport
     *  -2 row after viewport
     *  -3 column before viewport
     *  -4 column after viewport
     */

  }, {
    key: "getCell",
    value: function getCell(coords) {
      var row = coords.row;
      var column = coords.col;
      var hookResult = this.wot.getSetting('onModifyGetCellCoords', row, column);

      if (hookResult && Array.isArray(hookResult)) {
        var _hookResult = (0, _slicedToArray2.default)(hookResult, 2);

        row = _hookResult[0];
        column = _hookResult[1];
      }

      if (this.isRowBeforeRenderedRows(row)) {
        // row before rendered rows
        return -1;
      } else if (this.isRowAfterRenderedRows(row)) {
        // row after rendered rows
        return -2;
      } else if (this.isColumnBeforeRenderedColumns(column)) {
        // column before rendered columns
        return -3;
      } else if (this.isColumnAfterRenderedColumns(column)) {
        // column after rendered columns
        return -4;
      }

      var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)];

      if (TR) {
        return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(column)];
      }
    }
    /**
     * getColumnHeader
     *
     * @param {Number} col Column index
     * @param {Number} [level=0] Header level (0 = most distant to the table)
     * @returns {Object} HTMLElement on success or undefined on error
     */

  }, {
    key: "getColumnHeader",
    value: function getColumnHeader(col) {
      var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var TR = this.THEAD.childNodes[level];

      if (TR) {
        return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(col)];
      }
    }
    /**
     * getRowHeader
     *
     * @param {Number} row Row index
     * @returns {HTMLElement} HTMLElement on success or Number one of the exit codes on error: `null table doesn't have row headers`
     */

  }, {
    key: "getRowHeader",
    value: function getRowHeader(row) {
      if (this.columnFilter.sourceColumnToVisibleRowHeadedColumn(0) === 0) {
        return null;
      }

      var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)];

      if (TR) {
        return TR.childNodes[0];
      }
    }
    /**
     * Returns cell coords object for a given TD (or a child element of a TD element).
     *
     * @param {HTMLTableCellElement} TD A cell DOM element (or a child of one).
     * @returns {CellCoords|null} The coordinates of the provided TD element (or the closest TD element) or null, if the provided element is not applicable.
     */

  }, {
    key: "getCoords",
    value: function getCoords(TD) {
      var cellElement = TD;

      if (cellElement.nodeName !== 'TD' && cellElement.nodeName !== 'TH') {
        cellElement = (0, _element.closest)(cellElement, ['TD', 'TH']);
      }

      if (cellElement === null) {
        return null;
      }

      var TR = cellElement.parentNode;
      var CONTAINER = TR.parentNode;
      var row = (0, _element.index)(TR);
      var col = cellElement.cellIndex;

      if ((0, _element.overlayContainsElement)(_base.default.CLONE_TOP_LEFT_CORNER, cellElement) || (0, _element.overlayContainsElement)(_base.default.CLONE_TOP, cellElement)) {
        if (CONTAINER.nodeName === 'THEAD') {
          row -= CONTAINER.childNodes.length;
        }
      } else if ((0, _element.overlayContainsElement)(_base.default.CLONE_BOTTOM_LEFT_CORNER, cellElement) || (0, _element.overlayContainsElement)(_base.default.CLONE_BOTTOM, cellElement)) {
        var totalRows = this.wot.getSetting('totalRows');
        row = totalRows - CONTAINER.childNodes.length + row;
      } else if (CONTAINER === this.THEAD) {
        row = this.rowFilter.visibleColHeadedRowToSourceRow(row);
      } else {
        row = this.rowFilter.renderedToSource(row);
      }

      if ((0, _element.overlayContainsElement)(_base.default.CLONE_TOP_LEFT_CORNER, cellElement) || (0, _element.overlayContainsElement)(_base.default.CLONE_LEFT, cellElement) || (0, _element.overlayContainsElement)(_base.default.CLONE_BOTTOM_LEFT_CORNER, cellElement) || (0, _element.overlayContainsElement)(_base.default.CLONE_BOTTOM, cellElement)) {
        col = this.columnFilter.offsettedTH(col);
      } else {
        col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col);
      }

      return new _coords.default(row, col);
    }
  }, {
    key: "getTrForRow",
    value: function getTrForRow(row) {
      return this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)];
    }
  }, {
    key: "getFirstRenderedRow",
    value: function getFirstRenderedRow() {
      return this.wot.wtViewport.rowsRenderCalculator.startRow;
    }
  }, {
    key: "getFirstVisibleRow",
    value: function getFirstVisibleRow() {
      return this.wot.wtViewport.rowsVisibleCalculator.startRow;
    }
  }, {
    key: "getFirstRenderedColumn",
    value: function getFirstRenderedColumn() {
      return this.wot.wtViewport.columnsRenderCalculator.startColumn;
    }
    /**
     * @returns {Number} Returns -1 if no row is visible
     */

  }, {
    key: "getFirstVisibleColumn",
    value: function getFirstVisibleColumn() {
      return this.wot.wtViewport.columnsVisibleCalculator.startColumn;
    }
    /**
     * @returns {Number} Returns -1 if no row is visible
     */

  }, {
    key: "getLastRenderedRow",
    value: function getLastRenderedRow() {
      return this.wot.wtViewport.rowsRenderCalculator.endRow;
    }
  }, {
    key: "getLastVisibleRow",
    value: function getLastVisibleRow() {
      return this.wot.wtViewport.rowsVisibleCalculator.endRow;
    }
  }, {
    key: "getLastRenderedColumn",
    value: function getLastRenderedColumn() {
      return this.wot.wtViewport.columnsRenderCalculator.endColumn;
    }
    /**
     * @returns {Number} Returns -1 if no column is visible
     */

  }, {
    key: "getLastVisibleColumn",
    value: function getLastVisibleColumn() {
      return this.wot.wtViewport.columnsVisibleCalculator.endColumn;
    }
  }, {
    key: "isRowBeforeRenderedRows",
    value: function isRowBeforeRenderedRows(row) {
      return this.rowFilter && this.rowFilter.sourceToRendered(row) < 0 && row >= 0;
    }
  }, {
    key: "isRowAfterViewport",
    value: function isRowAfterViewport(row) {
      return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastVisibleRow();
    }
  }, {
    key: "isRowAfterRenderedRows",
    value: function isRowAfterRenderedRows(row) {
      return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastRenderedRow();
    }
  }, {
    key: "isColumnBeforeViewport",
    value: function isColumnBeforeViewport(column) {
      return this.columnFilter && this.columnFilter.sourceToRendered(column) < 0 && column >= 0;
    }
  }, {
    key: "isColumnBeforeRenderedColumns",
    value: function isColumnBeforeRenderedColumns(column) {
      return this.columnFilter && this.columnFilter.sourceColumnToVisibleRowHeadedColumn(column) < 0 && column >= 0;
    }
  }, {
    key: "isColumnAfterViewport",
    value: function isColumnAfterViewport(column) {
      return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastVisibleColumn();
    }
  }, {
    key: "isColumnAfterRenderedColumns",
    value: function isColumnAfterRenderedColumns(column) {
      return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastRenderedColumn();
    }
  }, {
    key: "isLastRowFullyVisible",
    value: function isLastRowFullyVisible() {
      return this.getLastVisibleRow() === this.getLastRenderedRow();
    }
  }, {
    key: "isLastColumnFullyVisible",
    value: function isLastColumnFullyVisible() {
      return this.getLastVisibleColumn() === this.getLastRenderedColumn();
    }
  }, {
    key: "getRenderedColumnsCount",
    value: function getRenderedColumnsCount() {
      var wot = this.wot;
      var totalColumns = wot.getSetting('totalColumns');
      var columnsCount = wot.wtViewport.columnsRenderCalculator.count;

      if (wot.isOverlayName(_base.default.CLONE_DEBUG)) {
        columnsCount = totalColumns;
      } else if (wot.isOverlayName(_base.default.CLONE_LEFT) || wot.isOverlayName(_base.default.CLONE_TOP_LEFT_CORNER) || wot.isOverlayName(_base.default.CLONE_BOTTOM_LEFT_CORNER)) {
        return Math.min(wot.getSetting('fixedColumnsLeft'), totalColumns);
      }

      return columnsCount;
    }
  }, {
    key: "getRenderedRowsCount",
    value: function getRenderedRowsCount() {
      var wot = this.wot;
      var totalRows = wot.getSetting('totalRows');
      var rowsCount = wot.wtViewport.rowsRenderCalculator.count;

      if (wot.isOverlayName(_base.default.CLONE_DEBUG)) {
        rowsCount = totalRows;
      } else if (wot.isOverlayName(_base.default.CLONE_TOP) || wot.isOverlayName(_base.default.CLONE_TOP_LEFT_CORNER)) {
        rowsCount = Math.min(wot.getSetting('fixedRowsTop'), totalRows);
      } else if (wot.isOverlayName(_base.default.CLONE_BOTTOM) || wot.isOverlayName(_base.default.CLONE_BOTTOM_LEFT_CORNER)) {
        rowsCount = Math.min(wot.getSetting('fixedRowsBottom'), totalRows);
      }

      return rowsCount;
    }
  }, {
    key: "getVisibleRowsCount",
    value: function getVisibleRowsCount() {
      return this.wot.wtViewport.rowsVisibleCalculator.count;
    }
  }, {
    key: "allRowsInViewport",
    value: function allRowsInViewport() {
      return this.wot.getSetting('totalRows') === this.getVisibleRowsCount();
    }
    /**
     * Checks if any of the row's cells content exceeds its initial height, and if so, returns the oversized height
     *
     * @param {Number} sourceRow
     * @returns {Number}
     */

  }, {
    key: "getRowHeight",
    value: function getRowHeight(sourceRow) {
      var height = this.wot.wtSettings.settings.rowHeight(sourceRow);
      var oversizedHeight = this.wot.wtViewport.oversizedRows[sourceRow];

      if (oversizedHeight !== void 0) {
        height = height === void 0 ? oversizedHeight : Math.max(height, oversizedHeight);
      }

      return height;
    }
  }, {
    key: "getColumnHeaderHeight",
    value: function getColumnHeaderHeight(level) {
      var height = this.wot.wtSettings.settings.defaultRowHeight;
      var oversizedHeight = this.wot.wtViewport.oversizedColumnHeaders[level];

      if (oversizedHeight !== void 0) {
        height = height ? Math.max(height, oversizedHeight) : oversizedHeight;
      }

      return height;
    }
  }, {
    key: "getVisibleColumnsCount",
    value: function getVisibleColumnsCount() {
      return this.wot.wtViewport.columnsVisibleCalculator.count;
    }
  }, {
    key: "allColumnsInViewport",
    value: function allColumnsInViewport() {
      return this.wot.getSetting('totalColumns') === this.getVisibleColumnsCount();
    }
  }, {
    key: "getColumnWidth",
    value: function getColumnWidth(sourceColumn) {
      var width = this.wot.wtSettings.settings.columnWidth;

      if (typeof width === 'function') {
        width = width(sourceColumn);
      } else if ((0, _typeof2.default)(width) === 'object') {
        width = width[sourceColumn];
      }

      return width || this.wot.wtSettings.settings.defaultColumnWidth;
    }
  }, {
    key: "getStretchedColumnWidth",
    value: function getStretchedColumnWidth(sourceColumn) {
      var columnWidth = this.getColumnWidth(sourceColumn);
      var width = columnWidth === null || columnWidth === void 0 ? this.instance.wtSettings.settings.defaultColumnWidth : columnWidth;
      var calculator = this.wot.wtViewport.columnsRenderCalculator;

      if (calculator) {
        var stretchedWidth = calculator.getStretchedColumnWidth(sourceColumn, width);

        if (stretchedWidth) {
          width = stretchedWidth;
        }
      }

      return width;
    }
    /**
     * Modify row header widths provided by user in class contructor.
     *
     * @private
     */

  }, {
    key: "_modifyRowHeaderWidth",
    value: function _modifyRowHeaderWidth(rowHeaderWidthFactory) {
      var widths = (0, _function.isFunction)(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null;

      if (Array.isArray(widths)) {
        widths = (0, _toConsumableArray2.default)(widths);
        widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]);
      } else {
        widths = this._correctRowHeaderWidth(widths);
      }

      return widths;
    }
    /**
     * Correct row header width if necessary.
     *
     * @private
     */

  }, {
    key: "_correctRowHeaderWidth",
    value: function _correctRowHeaderWidth(width) {
      var rowHeaderWidth = width;

      if (typeof width !== 'number') {
        rowHeaderWidth = this.wot.getSetting('defaultColumnWidth');
      }

      if (this.correctHeaderWidth) {
        rowHeaderWidth += 1;
      }

      return rowHeaderWidth;
    }
  }]);
  return Table;
}();

var _default = Table;
exports.default = _default;

/***/ }),
/* 332 */
/***/ (function(module, exports) {

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

module.exports = _arrayWithHoles;

/***/ }),
/* 333 */
/***/ (function(module, exports) {

function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance");
}

module.exports = _nonIterableRest;

/***/ }),
/* 334 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _console = __webpack_require__(55);

var _templateLiteralTag = __webpack_require__(67);

var _base = _interopRequireDefault(__webpack_require__(74));

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number\n          of rendered rows by specifying the table height and/or turning off the \"renderAllRows\" option."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

var performanceWarningAppeared = false;
/**
 * @class TableRenderer
 */

var TableRenderer =
/*#__PURE__*/
function () {
  /**
   * @param {WalkontableTable} wtTable
   */
  function TableRenderer(wtTable) {
    (0, _classCallCheck2.default)(this, TableRenderer);
    this.wtTable = wtTable;
    this.wot = wtTable.instance; // legacy support

    this.instance = wtTable.instance;
    this.rowFilter = wtTable.rowFilter;
    this.columnFilter = wtTable.columnFilter;
    this.TABLE = wtTable.TABLE;
    this.THEAD = wtTable.THEAD;
    this.TBODY = wtTable.TBODY;
    this.COLGROUP = wtTable.COLGROUP;
    this.rowHeaders = [];
    this.rowHeaderCount = 0;
    this.columnHeaders = [];
    this.columnHeaderCount = 0;
    this.fixedRowsTop = 0;
    this.fixedRowsBottom = 0;
  }
  /**
   *
   */


  (0, _createClass2.default)(TableRenderer, [{
    key: "render",
    value: function render() {
      if (!this.wtTable.isWorkingOnClone()) {
        var skipRender = {};
        this.wot.getSetting('beforeDraw', true, skipRender);

        if (skipRender.skipRender === true) {
          return;
        }
      }

      this.rowHeaders = this.wot.getSetting('rowHeaders');
      this.rowHeaderCount = this.rowHeaders.length;
      this.fixedRowsTop = this.wot.getSetting('fixedRowsTop');
      this.fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
      this.columnHeaders = this.wot.getSetting('columnHeaders');
      this.columnHeaderCount = this.columnHeaders.length;
      var columnsToRender = this.wtTable.getRenderedColumnsCount();
      var rowsToRender = this.wtTable.getRenderedRowsCount();
      var totalColumns = this.wot.getSetting('totalColumns');
      var totalRows = this.wot.getSetting('totalRows');
      var workspaceWidth;
      var adjusted = false;

      if (_base.default.isOverlayTypeOf(this.wot.cloneOverlay, _base.default.CLONE_BOTTOM) || _base.default.isOverlayTypeOf(this.wot.cloneOverlay, _base.default.CLONE_BOTTOM_LEFT_CORNER)) {
        // do NOT render headers on the bottom or bottom-left corner overlay
        this.columnHeaders = [];
        this.columnHeaderCount = 0;
      }

      if (totalColumns >= 0) {
        // prepare COL and TH elements for rendering
        this.adjustAvailableNodes();
        adjusted = true; // adjust column widths according to user widths settings

        this.renderColumnHeaders(); // Render table rows

        this.renderRows(totalRows, rowsToRender, columnsToRender);

        if (!this.wtTable.isWorkingOnClone()) {
          workspaceWidth = this.wot.wtViewport.getWorkspaceWidth();
          this.wot.wtViewport.containerWidth = null;
        }

        this.adjustColumnWidths(columnsToRender);
        this.markOversizedColumnHeaders();
        this.adjustColumnHeaderHeights();
      }

      if (!adjusted) {
        this.adjustAvailableNodes();
      }

      this.removeRedundantRows(rowsToRender);

      if (!this.wtTable.isWorkingOnClone() || this.wot.isOverlayName(_base.default.CLONE_BOTTOM)) {
        this.markOversizedRows();
      }

      if (!this.wtTable.isWorkingOnClone()) {
        this.wot.wtViewport.createVisibleCalculators();
        this.wot.wtOverlays.refresh(false);
        this.wot.wtOverlays.applyToDOM();
        var hiderWidth = (0, _element.outerWidth)(this.wtTable.hider);
        var tableWidth = (0, _element.outerWidth)(this.wtTable.TABLE);

        if (hiderWidth !== 0 && tableWidth !== hiderWidth) {
          // Recalculate the column widths, if width changes made in the overlays removed the scrollbar, thus changing the viewport width.
          this.adjustColumnWidths(columnsToRender);
        }

        if (workspaceWidth !== this.wot.wtViewport.getWorkspaceWidth()) {
          // workspace width changed though to shown/hidden vertical scrollbar. Let's reapply stretching
          this.wot.wtViewport.containerWidth = null;
          var firstRendered = this.wtTable.getFirstRenderedColumn();
          var lastRendered = this.wtTable.getLastRenderedColumn();
          var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
          var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');
          rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);

          if (rowHeaderWidthSetting !== null && rowHeaderWidthSetting !== void 0) {
            for (var i = 0; i < this.rowHeaderCount; i++) {
              var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
              width = width === null || width === void 0 ? defaultColumnWidth : width;
              this.COLGROUP.childNodes[i].style.width = "".concat(width, "px");
            }
          }

          for (var _i = firstRendered; _i < lastRendered; _i++) {
            var _width = this.wtTable.getStretchedColumnWidth(_i);

            var renderedIndex = this.columnFilter.sourceToRendered(_i);
            this.COLGROUP.childNodes[renderedIndex + this.rowHeaderCount].style.width = "".concat(_width, "px");
          }
        }

        this.wot.getSetting('onDraw', true);
      } else if (this.wot.isOverlayName(_base.default.CLONE_BOTTOM)) {
        this.wot.cloneSource.wtOverlays.adjustElementsSize();
      }
    }
    /**
     * @param {Number} renderedRowsCount
     */

  }, {
    key: "removeRedundantRows",
    value: function removeRedundantRows(renderedRowsCount) {
      while (this.wtTable.tbodyChildrenLength > renderedRowsCount) {
        this.TBODY.removeChild(this.TBODY.lastChild);
        this.wtTable.tbodyChildrenLength -= 1;
      }
    }
    /**
     * @param {Number} totalRows
     * @param {Number} rowsToRender
     * @param {Number} columnsToRender
     */

  }, {
    key: "renderRows",
    value: function renderRows(totalRows, rowsToRender, columnsToRender) {
      var TR;
      var visibleRowIndex = 0;
      var sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
      var isWorkingOnClone = this.wtTable.isWorkingOnClone();

      while (sourceRowIndex < totalRows && sourceRowIndex >= 0) {
        if (!performanceWarningAppeared && visibleRowIndex > 1000) {
          performanceWarningAppeared = true;
          (0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject()));
        }

        if (rowsToRender !== void 0 && visibleRowIndex === rowsToRender) {
          // We have as much rows as needed for this clone
          break;
        }

        TR = this.getOrCreateTrForRow(visibleRowIndex, TR); // Render row headers

        this.renderRowHeaders(sourceRowIndex, TR); // Add and/or remove TDs to TR to match the desired number

        this.adjustColumns(TR, columnsToRender + this.rowHeaderCount); // Render cells

        this.renderCells(sourceRowIndex, TR, columnsToRender);

        if (!isWorkingOnClone || // Necessary to refresh oversized row heights after editing cell in overlays
        this.wot.isOverlayName(_base.default.CLONE_BOTTOM)) {
          // Reset the oversized row cache for this row
          this.resetOversizedRow(sourceRowIndex);
        }

        if (TR.firstChild) {
          // if I have 2 fixed columns with one-line content and the 3rd column has a multiline content, this is
          // the way to make sure that the overlay will has same row height
          var height = this.wot.wtTable.getRowHeight(sourceRowIndex);

          if (height) {
            // Decrease height. 1 pixel will be "replaced" by 1px border top
            height -= 1;
            TR.firstChild.style.height = "".concat(height, "px");
          } else {
            TR.firstChild.style.height = '';
          }
        }

        visibleRowIndex += 1;
        sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
      }
    }
    /**
     * Reset the oversized row cache for the provided index
     *
     * @param {Number} sourceRow Row index
     */

  }, {
    key: "resetOversizedRow",
    value: function resetOversizedRow(sourceRow) {
      if (this.wot.getSetting('externalRowCalculator')) {
        return;
      }

      if (this.wot.wtViewport.oversizedRows && this.wot.wtViewport.oversizedRows[sourceRow]) {
        this.wot.wtViewport.oversizedRows[sourceRow] = void 0;
      }
    }
    /**
     * Check if any of the rendered rows is higher than expected, and if so, cache them
     */

  }, {
    key: "markOversizedRows",
    value: function markOversizedRows() {
      if (this.wot.getSetting('externalRowCalculator')) {
        return;
      }

      var rowCount = this.instance.wtTable.TBODY.childNodes.length;
      var expectedTableHeight = rowCount * this.instance.wtSettings.settings.defaultRowHeight;
      var actualTableHeight = (0, _element.innerHeight)(this.instance.wtTable.TBODY) - 1;
      var previousRowHeight;
      var rowInnerHeight;
      var sourceRowIndex;
      var currentTr;
      var rowHeader;

      if (expectedTableHeight === actualTableHeight && !this.instance.getSetting('fixedRowsBottom')) {
        // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them
        return;
      }

      while (rowCount) {
        rowCount -= 1;
        sourceRowIndex = this.instance.wtTable.rowFilter.renderedToSource(rowCount);
        previousRowHeight = this.instance.wtTable.getRowHeight(sourceRowIndex);
        currentTr = this.instance.wtTable.getTrForRow(sourceRowIndex);
        rowHeader = currentTr.querySelector('th');

        if (rowHeader) {
          rowInnerHeight = (0, _element.innerHeight)(rowHeader);
        } else {
          rowInnerHeight = (0, _element.innerHeight)(currentTr) - 1;
        }

        if (!previousRowHeight && this.instance.wtSettings.settings.defaultRowHeight < rowInnerHeight || previousRowHeight < rowInnerHeight) {
          rowInnerHeight += 1;
          this.instance.wtViewport.oversizedRows[sourceRowIndex] = rowInnerHeight;
        }
      }
    }
    /**
     * Check if any of the rendered columns is higher than expected, and if so, cache them.
     */

  }, {
    key: "markOversizedColumnHeaders",
    value: function markOversizedColumnHeaders() {
      var overlayName = this.wot.getOverlayName();

      if (!this.columnHeaderCount || this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] || this.wtTable.isWorkingOnClone()) {
        return;
      }

      var columnCount = this.wtTable.getRenderedColumnsCount();

      for (var i = 0; i < this.columnHeaderCount; i++) {
        for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
          this.markIfOversizedColumnHeader(renderedColumnIndex);
        }
      }

      this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] = true;
    }
    /**
     *
     */

  }, {
    key: "adjustColumnHeaderHeights",
    value: function adjustColumnHeaderHeights() {
      var columnHeaders = this.wot.getSetting('columnHeaders');
      var children = this.wot.wtTable.THEAD.childNodes;
      var oversizedColumnHeaders = this.wot.wtViewport.oversizedColumnHeaders;

      for (var i = 0, len = columnHeaders.length; i < len; i++) {
        if (oversizedColumnHeaders[i]) {
          if (!children[i] || children[i].childNodes.length === 0) {
            return;
          }

          children[i].childNodes[0].style.height = "".concat(oversizedColumnHeaders[i], "px");
        }
      }
    }
    /**
     * Check if column header for the specified column is higher than expected, and if so, cache it
     *
     * @param {Number} col Index of column
     */

  }, {
    key: "markIfOversizedColumnHeader",
    value: function markIfOversizedColumnHeader(col) {
      var sourceColIndex = this.wot.wtTable.columnFilter.renderedToSource(col);
      var level = this.columnHeaderCount;
      var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
      var previousColHeaderHeight;
      var currentHeader;
      var currentHeaderHeight;
      var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || [];

      while (level) {
        level -= 1;
        previousColHeaderHeight = this.wot.wtTable.getColumnHeaderHeight(level);
        currentHeader = this.wot.wtTable.getColumnHeader(sourceColIndex, level);

        if (!currentHeader) {
          /* eslint-disable no-continue */
          continue;
        }

        currentHeaderHeight = (0, _element.innerHeight)(currentHeader);

        if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) {
          this.wot.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight;
        }

        if (Array.isArray(columnHeaderHeightSetting)) {
          if (columnHeaderHeightSetting[level] !== null && columnHeaderHeightSetting[level] !== void 0) {
            this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level];
          }
        } else if (!isNaN(columnHeaderHeightSetting)) {
          this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting;
        }

        if (this.wot.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) {
          this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting;
        }
      }
    }
    /**
     * @param {Number} sourceRowIndex
     * @param {HTMLTableRowElement} TR
     * @param {Number} columnsToRender
     * @returns {HTMLTableCellElement}
     */

  }, {
    key: "renderCells",
    value: function renderCells(sourceRowIndex, TR, columnsToRender) {
      var TD;
      var sourceColIndex;

      for (var visibleColIndex = 0; visibleColIndex < columnsToRender; visibleColIndex++) {
        sourceColIndex = this.columnFilter.renderedToSource(visibleColIndex);

        if (visibleColIndex === 0) {
          TD = TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(sourceColIndex)];
        } else {
          TD = TD.nextSibling; // http://jsperf.com/nextsibling-vs-indexed-childnodes
        } // If the number of headers has been reduced, we need to replace excess TH with TD


        if (TD.nodeName === 'TH') {
          TD = replaceThWithTd(this.wot.rootDocument, TD, TR);
        }

        if (!(0, _element.hasClass)(TD, 'hide')) {
          TD.className = '';
        }

        TD.removeAttribute('style');
        this.wot.wtSettings.settings.cellRenderer(sourceRowIndex, sourceColIndex, TD);
      }

      return TD;
    }
    /**
     * @param {Number} columnsToRender Number of columns to render.
     */

  }, {
    key: "adjustColumnWidths",
    value: function adjustColumnWidths(columnsToRender) {
      var scrollbarCompensation = 0;
      var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
      var mainHolder = sourceInstance.wtTable.holder;
      var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
      var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');

      if (mainHolder.offsetHeight < mainHolder.scrollHeight) {
        scrollbarCompensation = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      }

      this.wot.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation);
      rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);

      if (rowHeaderWidthSetting !== null && rowHeaderWidthSetting !== void 0) {
        for (var i = 0; i < this.rowHeaderCount; i++) {
          var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
          width = width === null || width === void 0 ? defaultColumnWidth : width;
          this.COLGROUP.childNodes[i].style.width = "".concat(width, "px");
        }
      }

      for (var renderedColIndex = 0; renderedColIndex < columnsToRender; renderedColIndex++) {
        var _width2 = this.wtTable.getStretchedColumnWidth(this.columnFilter.renderedToSource(renderedColIndex));

        this.COLGROUP.childNodes[renderedColIndex + this.rowHeaderCount].style.width = "".concat(_width2, "px");
      }
    }
    /**
     * @param {HTMLTableCellElement} TR
     */

  }, {
    key: "appendToTbody",
    value: function appendToTbody(TR) {
      this.TBODY.appendChild(TR);
      this.wtTable.tbodyChildrenLength += 1;
    }
    /**
     * @param {Number} rowIndex
     * @param {HTMLTableRowElement} currentTr
     * @returns {HTMLTableCellElement}
     */

  }, {
    key: "getOrCreateTrForRow",
    value: function getOrCreateTrForRow(rowIndex, currentTr) {
      var TR;

      if (rowIndex >= this.wtTable.tbodyChildrenLength) {
        TR = this.createRow();
        this.appendToTbody(TR);
      } else if (rowIndex === 0) {
        TR = this.TBODY.firstChild;
      } else {
        // http://jsperf.com/nextsibling-vs-indexed-childnodes
        TR = currentTr.nextSibling;
      }

      if (TR.className) {
        TR.removeAttribute('class');
      }

      return TR;
    }
    /**
     * @returns {HTMLTableCellElement}
     */

  }, {
    key: "createRow",
    value: function createRow() {
      var rootDocument = this.wot.rootDocument;
      var TR = rootDocument.createElement('TR');

      for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
        TR.appendChild(rootDocument.createElement('TH'));
      }

      return TR;
    }
    /**
     * @param {Number} row
     * @param {Number} col
     * @param {HTMLTableCellElement} TH
     */

  }, {
    key: "renderRowHeader",
    value: function renderRowHeader(row, col, TH) {
      TH.className = '';
      TH.removeAttribute('style');
      this.rowHeaders[col](row, TH, col);
    }
    /**
     * @param {Number} row
     * @param {HTMLTableCellElement} TR
     */

  }, {
    key: "renderRowHeaders",
    value: function renderRowHeaders(row, TR) {
      for (var TH = TR.firstChild, visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
        // If the number of row headers increased we need to create TH or replace an existing TD node with TH
        if (!TH) {
          TH = this.wot.rootDocument.createElement('TH');
          TR.appendChild(TH);
        } else if (TH.nodeName === 'TD') {
          TH = replaceTdWithTh(this.wot.rootDocument, TH, TR);
        }

        this.renderRowHeader(row, visibleColIndex, TH); // http://jsperf.com/nextsibling-vs-indexed-childnodes

        TH = TH.nextSibling;
      }
    }
    /**
     * Adjust the number of COL and TH elements to match the number of columns and headers that need to be rendered
     */

  }, {
    key: "adjustAvailableNodes",
    value: function adjustAvailableNodes() {
      this.adjustColGroups();
      this.adjustThead();
    }
    /**
     * Renders the column headers
     */

  }, {
    key: "renderColumnHeaders",
    value: function renderColumnHeaders() {
      if (!this.columnHeaderCount) {
        return;
      }

      var columnCount = this.wtTable.getRenderedColumnsCount();

      for (var i = 0; i < this.columnHeaderCount; i++) {
        var TR = this.getTrForColumnHeaders(i);

        for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
          var sourceCol = this.columnFilter.renderedToSource(renderedColumnIndex);
          this.renderColumnHeader(i, sourceCol, TR.childNodes[renderedColumnIndex + this.rowHeaderCount]);
        }
      }
    }
    /**
     * Adjusts the number of COL elements to match the number of columns that need to be rendered
     */

  }, {
    key: "adjustColGroups",
    value: function adjustColGroups() {
      var columnCount = this.wtTable.getRenderedColumnsCount();

      while (this.wtTable.colgroupChildrenLength < columnCount + this.rowHeaderCount) {
        this.COLGROUP.appendChild(this.wot.rootDocument.createElement('COL'));
        this.wtTable.colgroupChildrenLength += 1;
      }

      while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) {
        this.COLGROUP.removeChild(this.COLGROUP.lastChild);
        this.wtTable.colgroupChildrenLength -= 1;
      }

      if (this.rowHeaderCount) {
        (0, _element.addClass)(this.COLGROUP.childNodes[0], 'rowHeader');
      }
    }
    /**
     * Adjusts the number of TH elements in THEAD to match the number of headers and columns that need to be rendered
     */

  }, {
    key: "adjustThead",
    value: function adjustThead() {
      var columnCount = this.wtTable.getRenderedColumnsCount();
      var TR = this.THEAD.firstChild;

      if (this.columnHeaders.length) {
        var rootDocument = this.wot.rootDocument;

        for (var i = 0, len = this.columnHeaders.length; i < len; i++) {
          TR = this.THEAD.childNodes[i];

          if (!TR) {
            TR = rootDocument.createElement('TR');
            this.THEAD.appendChild(TR);
          }

          this.theadChildrenLength = TR.childNodes.length;

          while (this.theadChildrenLength < columnCount + this.rowHeaderCount) {
            TR.appendChild(rootDocument.createElement('TH'));
            this.theadChildrenLength += 1;
          }

          while (this.theadChildrenLength > columnCount + this.rowHeaderCount) {
            TR.removeChild(TR.lastChild);
            this.theadChildrenLength -= 1;
          }
        }

        var theadChildrenLength = this.THEAD.childNodes.length;

        if (theadChildrenLength > this.columnHeaders.length) {
          for (var _i2 = this.columnHeaders.length; _i2 < theadChildrenLength; _i2++) {
            this.THEAD.removeChild(this.THEAD.lastChild);
          }
        }
      } else if (TR) {
        (0, _element.empty)(TR);
      }
    }
    /**
     * @param {Number} index
     * @returns {HTMLTableCellElement}
     */

  }, {
    key: "getTrForColumnHeaders",
    value: function getTrForColumnHeaders(index) {
      return this.THEAD.childNodes[index];
    }
    /**
     * @param {Number} row
     * @param {Number} col
     * @param {HTMLTableCellElement} TH
     * @returns {*}
     */

  }, {
    key: "renderColumnHeader",
    value: function renderColumnHeader(row, col, TH) {
      TH.className = '';
      TH.removeAttribute('style');
      return this.columnHeaders[row](col, TH, row);
    }
    /**
     * Add and/or remove the TDs to match the desired number
     *
     * @param {HTMLTableCellElement} TR Table row in question
     * @param {Number} desiredCount The desired number of TDs in the TR
     */

  }, {
    key: "adjustColumns",
    value: function adjustColumns(TR, desiredCount) {
      var rootDocument = this.wot.rootDocument;
      var count = TR.childNodes.length;

      while (count < desiredCount) {
        var TD = rootDocument.createElement('TD');
        TR.appendChild(TD);
        count += 1;
      }

      while (count > desiredCount) {
        TR.removeChild(TR.lastChild);
        count -= 1;
      }
    }
    /**
     * @param {Number} columnsToRender
     */

  }, {
    key: "removeRedundantColumns",
    value: function removeRedundantColumns(columnsToRender) {
      while (this.wtTable.tbodyChildrenLength > columnsToRender) {
        this.TBODY.removeChild(this.TBODY.lastChild);
        this.wtTable.tbodyChildrenLength -= 1;
      }
    }
  }]);
  return TableRenderer;
}();

function replaceTdWithTh(rootDocument, TD, TR) {
  var TH = rootDocument.createElement('TH');
  TR.insertBefore(TH, TD);
  TR.removeChild(TD);
  return TH;
}

function replaceThWithTd(rootDocument, TH, TR) {
  var TD = rootDocument.createElement('TD');
  TR.insertBefore(TD, TH);
  TR.removeChild(TH);
  return TD;
}

var _default = TableRenderer;
exports.default = _default;

/***/ }),
/* 335 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _viewportColumns = _interopRequireDefault(__webpack_require__(198));

var _viewportRows = _interopRequireDefault(__webpack_require__(199));

/**
 * @class Viewport
 */
var Viewport =
/*#__PURE__*/
function () {
  /**
   * @param wotInstance
   */
  function Viewport(wotInstance) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Viewport);
    this.wot = wotInstance; // legacy support

    this.instance = this.wot;
    this.oversizedRows = [];
    this.oversizedColumnHeaders = [];
    this.hasOversizedColumnHeadersMarked = {};
    this.clientHeight = 0;
    this.containerWidth = NaN;
    this.rowHeaderWidth = NaN;
    this.rowsVisibleCalculator = null;
    this.columnsVisibleCalculator = null;
    this.eventManager = new _eventManager.default(this.wot);
    this.eventManager.addEventListener(this.wot.rootWindow, 'resize', function () {
      _this.clientHeight = _this.getWorkspaceHeight();
    });
  }
  /**
   * @returns {number}
   */


  (0, _createClass2.default)(Viewport, [{
    key: "getWorkspaceHeight",
    value: function getWorkspaceHeight() {
      var currentDocument = this.wot.rootDocument;
      var trimmingContainer = this.instance.wtOverlays.topOverlay.trimmingContainer;
      var elemHeight;
      var height = 0;

      if (trimmingContainer === this.wot.rootWindow) {
        height = currentDocument.documentElement.clientHeight;
      } else {
        elemHeight = (0, _element.outerHeight)(trimmingContainer); // returns height without DIV scrollbar

        height = elemHeight > 0 && trimmingContainer.clientHeight > 0 ? trimmingContainer.clientHeight : Infinity;
      }

      return height;
    }
  }, {
    key: "getWorkspaceWidth",
    value: function getWorkspaceWidth() {
      var wot = this.wot;
      var rootDocument = wot.rootDocument,
          rootWindow = wot.rootWindow;
      var trimmingContainer = this.instance.wtOverlays.leftOverlay.trimmingContainer;
      var docOffsetWidth = rootDocument.documentElement.offsetWidth;
      var totalColumns = wot.getSetting('totalColumns');
      var stretchSetting = wot.getSetting('stretchH');
      var preventOverflow = wot.getSetting('preventOverflow');
      var width;
      var overflow;

      if (preventOverflow) {
        return (0, _element.outerWidth)(this.instance.wtTable.wtRootElement);
      }

      if (wot.getSetting('freezeOverlays')) {
        width = Math.min(docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
      } else {
        width = Math.min(this.getContainerFillWidth(), docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
      }

      if (trimmingContainer === rootWindow && totalColumns > 0 && this.sumColumnWidths(0, totalColumns - 1) > width) {
        // in case sum of column widths is higher than available stylesheet width, let's assume using the whole window
        // otherwise continue below, which will allow stretching
        // this is used in `scroll_window.html`
        // TODO test me
        return rootDocument.documentElement.clientWidth;
      }

      if (trimmingContainer !== rootWindow) {
        overflow = (0, _element.getStyle)(this.instance.wtOverlays.leftOverlay.trimmingContainer, 'overflow', rootWindow);

        if (overflow === 'scroll' || overflow === 'hidden' || overflow === 'auto') {
          // this is used in `scroll.html`
          // TODO test me
          return Math.max(width, trimmingContainer.clientWidth);
        }
      }

      if (stretchSetting === 'none' || !stretchSetting) {
        // if no stretching is used, return the maximum used workspace width
        return Math.max(width, (0, _element.outerWidth)(this.instance.wtTable.TABLE));
      } // if stretching is used, return the actual container width, so the columns can fit inside it


      return width;
    }
    /**
     * Checks if viewport has vertical scroll
     *
     * @returns {Boolean}
     */

  }, {
    key: "hasVerticalScroll",
    value: function hasVerticalScroll() {
      return this.getWorkspaceActualHeight() > this.getWorkspaceHeight();
    }
    /**
     * Checks if viewport has horizontal scroll
     *
     * @returns {Boolean}
     */

  }, {
    key: "hasHorizontalScroll",
    value: function hasHorizontalScroll() {
      return this.getWorkspaceActualWidth() > this.getWorkspaceWidth();
    }
    /**
     * @param from
     * @param length
     * @returns {Number}
     */

  }, {
    key: "sumColumnWidths",
    value: function sumColumnWidths(from, length) {
      var wtTable = this.wot.wtTable;
      var sum = 0;
      var column = from;

      while (column < length) {
        sum += wtTable.getColumnWidth(column);
        column += 1;
      }

      return sum;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getContainerFillWidth",
    value: function getContainerFillWidth() {
      if (this.containerWidth) {
        return this.containerWidth;
      }

      var mainContainer = this.instance.wtTable.holder;
      var dummyElement = this.wot.rootDocument.createElement('div');
      dummyElement.style.width = '100%';
      dummyElement.style.height = '1px';
      mainContainer.appendChild(dummyElement);
      var fillWidth = dummyElement.offsetWidth;
      this.containerWidth = fillWidth;
      mainContainer.removeChild(dummyElement);
      return fillWidth;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getWorkspaceOffset",
    value: function getWorkspaceOffset() {
      return (0, _element.offset)(this.wot.wtTable.TABLE);
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getWorkspaceActualHeight",
    value: function getWorkspaceActualHeight() {
      return (0, _element.outerHeight)(this.wot.wtTable.TABLE);
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getWorkspaceActualWidth",
    value: function getWorkspaceActualWidth() {
      var wtTable = this.wot.wtTable;
      return (0, _element.outerWidth)(wtTable.TABLE) || (0, _element.outerWidth)(wtTable.TBODY) || (0, _element.outerWidth)(wtTable.THEAD); // IE8 reports 0 as <table> offsetWidth;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getColumnHeaderHeight",
    value: function getColumnHeaderHeight() {
      var columnHeaders = this.instance.getSetting('columnHeaders');

      if (!columnHeaders.length) {
        this.columnHeaderHeight = 0;
      } else if (isNaN(this.columnHeaderHeight)) {
        this.columnHeaderHeight = (0, _element.outerHeight)(this.wot.wtTable.THEAD);
      }

      return this.columnHeaderHeight;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getViewportHeight",
    value: function getViewportHeight() {
      var containerHeight = this.getWorkspaceHeight();

      if (containerHeight === Infinity) {
        return containerHeight;
      }

      var columnHeaderHeight = this.getColumnHeaderHeight();

      if (columnHeaderHeight > 0) {
        containerHeight -= columnHeaderHeight;
      }

      return containerHeight;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getRowHeaderWidth",
    value: function getRowHeaderWidth() {
      var rowHeadersWidthSetting = this.instance.getSetting('rowHeaderWidth');
      var rowHeaders = this.instance.getSetting('rowHeaders');

      if (rowHeadersWidthSetting) {
        this.rowHeaderWidth = 0;

        for (var i = 0, len = rowHeaders.length; i < len; i++) {
          this.rowHeaderWidth += rowHeadersWidthSetting[i] || rowHeadersWidthSetting;
        }
      }

      if (this.wot.cloneSource) {
        return this.wot.cloneSource.wtViewport.getRowHeaderWidth();
      }

      if (isNaN(this.rowHeaderWidth)) {
        if (rowHeaders.length) {
          var TH = this.instance.wtTable.TABLE.querySelector('TH');
          this.rowHeaderWidth = 0;

          for (var _i = 0, _len = rowHeaders.length; _i < _len; _i++) {
            if (TH) {
              this.rowHeaderWidth += (0, _element.outerWidth)(TH);
              TH = TH.nextSibling;
            } else {
              // yes this is a cheat but it worked like that before, just taking assumption from CSS instead of measuring.
              // TODO: proper fix
              this.rowHeaderWidth += 50;
            }
          }
        } else {
          this.rowHeaderWidth = 0;
        }
      }

      this.rowHeaderWidth = this.instance.getSetting('onModifyRowHeaderWidth', this.rowHeaderWidth) || this.rowHeaderWidth;
      return this.rowHeaderWidth;
    }
    /**
     * @returns {Number}
     */

  }, {
    key: "getViewportWidth",
    value: function getViewportWidth() {
      var containerWidth = this.getWorkspaceWidth();

      if (containerWidth === Infinity) {
        return containerWidth;
      }

      var rowHeaderWidth = this.getRowHeaderWidth();

      if (rowHeaderWidth > 0) {
        return containerWidth - rowHeaderWidth;
      }

      return containerWidth;
    }
    /**
     * Creates:
     *  - rowsRenderCalculator (before draw, to qualify rows for rendering)
     *  - rowsVisibleCalculator (after draw, to measure which rows are actually visible)
     *
     * @returns {ViewportRowsCalculator}
     */

  }, {
    key: "createRowsCalculator",
    value: function createRowsCalculator() {
      var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var wot = this.wot;
      var wtSettings = wot.wtSettings,
          wtOverlays = wot.wtOverlays,
          wtTable = wot.wtTable,
          rootDocument = wot.rootDocument;
      var height;
      var scrollbarHeight;
      var fixedRowsHeight;
      this.rowHeaderWidth = NaN;

      if (wtSettings.settings.renderAllRows && !visible) {
        height = Infinity;
      } else {
        height = this.getViewportHeight();
      }

      var pos = wtOverlays.topOverlay.getScrollPosition() - wtOverlays.topOverlay.getTableParentOffset();

      if (pos < 0) {
        pos = 0;
      }

      var fixedRowsTop = wot.getSetting('fixedRowsTop');
      var fixedRowsBottom = wot.getSetting('fixedRowsBottom');
      var totalRows = wot.getSetting('totalRows');

      if (fixedRowsTop) {
        fixedRowsHeight = wtOverlays.topOverlay.sumCellSizes(0, fixedRowsTop);
        pos += fixedRowsHeight;
        height -= fixedRowsHeight;
      }

      if (fixedRowsBottom && wtOverlays.bottomOverlay.clone) {
        fixedRowsHeight = wtOverlays.bottomOverlay.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
        height -= fixedRowsHeight;
      }

      if (wtTable.holder.clientHeight === wtTable.holder.offsetHeight) {
        scrollbarHeight = 0;
      } else {
        scrollbarHeight = (0, _element.getScrollbarWidth)(rootDocument);
      }

      return new _viewportRows.default(height, pos, wot.getSetting('totalRows'), function (sourceRow) {
        return wtTable.getRowHeight(sourceRow);
      }, visible ? null : wtSettings.settings.viewportRowCalculatorOverride, visible, scrollbarHeight);
    }
    /**
     * Creates:
     *  - columnsRenderCalculator (before draw, to qualify columns for rendering)
     *  - columnsVisibleCalculator (after draw, to measure which columns are actually visible)
     *
     * @returns {ViewportRowsCalculator}
     */

  }, {
    key: "createColumnsCalculator",
    value: function createColumnsCalculator() {
      var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var wot = this.wot;
      var wtSettings = wot.wtSettings,
          wtOverlays = wot.wtOverlays,
          wtTable = wot.wtTable,
          rootDocument = wot.rootDocument;
      var width = this.getViewportWidth();
      var pos = wtOverlays.leftOverlay.getScrollPosition() - wtOverlays.leftOverlay.getTableParentOffset();
      this.columnHeaderHeight = NaN;

      if (pos < 0) {
        pos = 0;
      }

      var fixedColumnsLeft = wot.getSetting('fixedColumnsLeft');

      if (fixedColumnsLeft) {
        var fixedColumnsWidth = wtOverlays.leftOverlay.sumCellSizes(0, fixedColumnsLeft);
        pos += fixedColumnsWidth;
        width -= fixedColumnsWidth;
      }

      if (wtTable.holder.clientWidth !== wtTable.holder.offsetWidth) {
        width -= (0, _element.getScrollbarWidth)(rootDocument);
      }

      return new _viewportColumns.default(width, pos, wot.getSetting('totalColumns'), function (sourceCol) {
        return wot.wtTable.getColumnWidth(sourceCol);
      }, visible ? null : wtSettings.settings.viewportColumnCalculatorOverride, visible, wot.getSetting('stretchH'), function (stretchedWidth, column) {
        return wot.getSetting('onBeforeStretchingColumnWidth', stretchedWidth, column);
      });
    }
    /**
     * Creates rowsRenderCalculator and columnsRenderCalculator (before draw, to determine what rows and
     * cols should be rendered)
     *
     * @param fastDraw {Boolean} If `true`, will try to avoid full redraw and only update the border positions.
     *                           If `false` or `undefined`, will perform a full redraw
     * @returns fastDraw {Boolean} The fastDraw value, possibly modified
     */

  }, {
    key: "createRenderCalculators",
    value: function createRenderCalculators() {
      var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var runFastDraw = fastDraw;

      if (runFastDraw) {
        var proposedRowsVisibleCalculator = this.createRowsCalculator(true);
        var proposedColumnsVisibleCalculator = this.createColumnsCalculator(true);

        if (!(this.areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) && this.areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator))) {
          runFastDraw = false;
        }
      }

      if (!runFastDraw) {
        this.rowsRenderCalculator = this.createRowsCalculator();
        this.columnsRenderCalculator = this.createColumnsCalculator();
      } // delete temporarily to make sure that renderers always use rowsRenderCalculator, not rowsVisibleCalculator


      this.rowsVisibleCalculator = null;
      this.columnsVisibleCalculator = null;
      return runFastDraw;
    }
    /**
     * Creates rowsVisibleCalculator and columnsVisibleCalculator (after draw, to determine what are
     * the actually visible rows and columns)
     */

  }, {
    key: "createVisibleCalculators",
    value: function createVisibleCalculators() {
      this.rowsVisibleCalculator = this.createRowsCalculator(true);
      this.columnsVisibleCalculator = this.createColumnsCalculator(true);
    }
    /**
     * Returns information whether proposedRowsVisibleCalculator viewport
     * is contained inside rows rendered in previous draw (cached in rowsRenderCalculator)
     *
     * @param {Object} proposedRowsVisibleCalculator
     * @returns {Boolean} Returns `true` if all proposed visible rows are already rendered (meaning: redraw is not needed).
     *                    Returns `false` if at least one proposed visible row is not already rendered (meaning: redraw is needed)
     */

  }, {
    key: "areAllProposedVisibleRowsAlreadyRendered",
    value: function areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) {
      if (this.rowsVisibleCalculator) {
        if (proposedRowsVisibleCalculator.startRow < this.rowsRenderCalculator.startRow || proposedRowsVisibleCalculator.startRow === this.rowsRenderCalculator.startRow && proposedRowsVisibleCalculator.startRow > 0) {
          return false;
        } else if (proposedRowsVisibleCalculator.endRow > this.rowsRenderCalculator.endRow || proposedRowsVisibleCalculator.endRow === this.rowsRenderCalculator.endRow && proposedRowsVisibleCalculator.endRow < this.wot.getSetting('totalRows') - 1) {
          return false;
        }

        return true;
      }

      return false;
    }
    /**
     * Returns information whether proposedColumnsVisibleCalculator viewport
     * is contained inside column rendered in previous draw (cached in columnsRenderCalculator)
     *
     * @param {Object} proposedColumnsVisibleCalculator
     * @returns {Boolean} Returns `true` if all proposed visible columns are already rendered (meaning: redraw is not needed).
     *                    Returns `false` if at least one proposed visible column is not already rendered (meaning: redraw is needed)
     */

  }, {
    key: "areAllProposedVisibleColumnsAlreadyRendered",
    value: function areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator) {
      if (this.columnsVisibleCalculator) {
        if (proposedColumnsVisibleCalculator.startColumn < this.columnsRenderCalculator.startColumn || proposedColumnsVisibleCalculator.startColumn === this.columnsRenderCalculator.startColumn && proposedColumnsVisibleCalculator.startColumn > 0) {
          return false;
        } else if (proposedColumnsVisibleCalculator.endColumn > this.columnsRenderCalculator.endColumn || proposedColumnsVisibleCalculator.endColumn === this.columnsRenderCalculator.endColumn && proposedColumnsVisibleCalculator.endColumn < this.wot.getSetting('totalColumns') - 1) {
          return false;
        }

        return true;
      }

      return false;
    }
    /**
     * Resets values in keys of the hasOversizedColumnHeadersMarked object after updateSettings.
     */

  }, {
    key: "resetHasOversizedColumnHeadersMarked",
    value: function resetHasOversizedColumnHeadersMarked() {
      (0, _object.objectEach)(this.hasOversizedColumnHeadersMarked, function (value, key, object) {
        object[key] = void 0;
      });
    }
  }]);
  return Viewport;
}();

var _default = Viewport;
exports.default = _default;

/***/ }),
/* 336 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(34);

__webpack_require__(54);

__webpack_require__(39);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

var _object = __webpack_require__(4);

var _browser = __webpack_require__(72);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _coords = _interopRequireDefault(__webpack_require__(106));

/**
 *
 */
var Border =
/*#__PURE__*/
function () {
  /**
   * @param {Walkontable} wotInstance
   * @param {Object} settings
   */
  function Border(wotInstance, settings) {
    (0, _classCallCheck2.default)(this, Border);

    if (!settings) {
      return;
    }

    this.eventManager = new _eventManager.default(wotInstance);
    this.instance = wotInstance;
    this.wot = wotInstance;
    this.settings = settings;
    this.mouseDown = false;
    this.main = null;
    this.top = null;
    this.left = null;
    this.bottom = null;
    this.right = null;
    this.topStyle = null;
    this.leftStyle = null;
    this.bottomStyle = null;
    this.rightStyle = null;
    this.cornerDefaultStyle = {
      width: '6px',
      height: '6px',
      borderWidth: '1px',
      borderStyle: 'solid',
      borderColor: '#FFF'
    };
    this.corner = null;
    this.cornerStyle = null;
    this.createBorders(settings);
    this.registerListeners();
  }
  /**
   * Register all necessary events
   */


  (0, _createClass2.default)(Border, [{
    key: "registerListeners",
    value: function registerListeners() {
      var _this2 = this;

      var documentBody = this.wot.rootDocument.body;
      this.eventManager.addEventListener(documentBody, 'mousedown', function () {
        return _this2.onMouseDown();
      });
      this.eventManager.addEventListener(documentBody, 'mouseup', function () {
        return _this2.onMouseUp();
      });

      var _loop = function _loop(c, len) {
        _this2.eventManager.addEventListener(_this2.main.childNodes[c], 'mouseenter', function (event) {
          return _this2.onMouseEnter(event, _this2.main.childNodes[c]);
        });
      };

      for (var c = 0, len = this.main.childNodes.length; c < len; c++) {
        _loop(c, len);
      }
    }
    /**
     * Mouse down listener
     *
     * @private
     */

  }, {
    key: "onMouseDown",
    value: function onMouseDown() {
      this.mouseDown = true;
    }
    /**
     * Mouse up listener
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      this.mouseDown = false;
    }
    /**
     * Mouse enter listener for fragment selection functionality.
     *
     * @private
     * @param {Event} event Dom event
     * @param {HTMLElement} parentElement Part of border element.
     */

  }, {
    key: "onMouseEnter",
    value: function onMouseEnter(event, parentElement) {
      if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) {
        return;
      }

      event.preventDefault();
      (0, _event.stopImmediatePropagation)(event);

      var _this = this;

      var documentBody = this.wot.rootDocument.body;
      var bounds = parentElement.getBoundingClientRect(); // Hide border to prevents selection jumping when fragmentSelection is enabled.

      parentElement.style.display = 'none';

      function isOutside(mouseEvent) {
        if (mouseEvent.clientY < Math.floor(bounds.top)) {
          return true;
        }

        if (mouseEvent.clientY > Math.ceil(bounds.top + bounds.height)) {
          return true;
        }

        if (mouseEvent.clientX < Math.floor(bounds.left)) {
          return true;
        }

        if (mouseEvent.clientX > Math.ceil(bounds.left + bounds.width)) {
          return true;
        }
      }

      function handler(handlerEvent) {
        if (isOutside(handlerEvent)) {
          _this.eventManager.removeEventListener(documentBody, 'mousemove', handler);

          parentElement.style.display = 'block';
        }
      }

      this.eventManager.addEventListener(documentBody, 'mousemove', handler);
    }
    /**
     * Create border elements
     *
     * @param {Object} settings
     */

  }, {
    key: "createBorders",
    value: function createBorders(settings) {
      var rootDocument = this.wot.rootDocument;
      this.main = rootDocument.createElement('div');
      var borderDivs = ['top', 'left', 'bottom', 'right', 'corner'];
      var style = this.main.style;
      style.position = 'absolute';
      style.top = 0;
      style.left = 0;

      for (var i = 0; i < 5; i++) {
        var position = borderDivs[i];
        var div = rootDocument.createElement('div');
        div.className = "wtBorder ".concat(this.settings.className || ''); // + borderDivs[i];

        if (this.settings[position] && this.settings[position].hide) {
          div.className += ' hidden';
        }

        style = div.style;
        style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color;
        style.height = this.settings[position] && this.settings[position].width ? "".concat(this.settings[position].width, "px") : "".concat(settings.border.width, "px");
        style.width = this.settings[position] && this.settings[position].width ? "".concat(this.settings[position].width, "px") : "".concat(settings.border.width, "px");
        this.main.appendChild(div);
      }

      this.top = this.main.childNodes[0];
      this.left = this.main.childNodes[1];
      this.bottom = this.main.childNodes[2];
      this.right = this.main.childNodes[3];
      this.topStyle = this.top.style;
      this.leftStyle = this.left.style;
      this.bottomStyle = this.bottom.style;
      this.rightStyle = this.right.style;
      this.corner = this.main.childNodes[4];
      this.corner.className += ' corner';
      this.cornerStyle = this.corner.style;
      this.cornerStyle.width = this.cornerDefaultStyle.width;
      this.cornerStyle.height = this.cornerDefaultStyle.height;
      this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' ');

      if ((0, _browser.isMobileBrowser)()) {
        this.createMultipleSelectorHandles();
      }

      this.disappear();
      var wtTable = this.wot.wtTable;
      var bordersHolder = wtTable.bordersHolder;

      if (!bordersHolder) {
        bordersHolder = rootDocument.createElement('div');
        bordersHolder.className = 'htBorders';
        wtTable.bordersHolder = bordersHolder;
        wtTable.spreader.appendChild(bordersHolder);
      }

      bordersHolder.appendChild(this.main);
    }
    /**
     * Create multiple selector handler for mobile devices
     */

  }, {
    key: "createMultipleSelectorHandles",
    value: function createMultipleSelectorHandles() {
      var _this3 = this;

      var rootDocument = this.wot.rootDocument;
      this.selectionHandles = {
        topLeft: rootDocument.createElement('DIV'),
        topLeftHitArea: rootDocument.createElement('DIV'),
        bottomRight: rootDocument.createElement('DIV'),
        bottomRightHitArea: rootDocument.createElement('DIV')
      };
      var width = 10;
      var hitAreaWidth = 40;
      this.selectionHandles.topLeft.className = 'topLeftSelectionHandle';
      this.selectionHandles.topLeftHitArea.className = 'topLeftSelectionHandle-HitArea';
      this.selectionHandles.bottomRight.className = 'bottomRightSelectionHandle';
      this.selectionHandles.bottomRightHitArea.className = 'bottomRightSelectionHandle-HitArea';
      this.selectionHandles.styles = {
        topLeft: this.selectionHandles.topLeft.style,
        topLeftHitArea: this.selectionHandles.topLeftHitArea.style,
        bottomRight: this.selectionHandles.bottomRight.style,
        bottomRightHitArea: this.selectionHandles.bottomRightHitArea.style
      };
      var hitAreaStyle = {
        position: 'absolute',
        height: "".concat(hitAreaWidth, "px"),
        width: "".concat(hitAreaWidth, "px"),
        'border-radius': "".concat(parseInt(hitAreaWidth / 1.5, 10), "px")
      };
      (0, _object.objectEach)(hitAreaStyle, function (value, key) {
        _this3.selectionHandles.styles.bottomRightHitArea[key] = value;
        _this3.selectionHandles.styles.topLeftHitArea[key] = value;
      });
      var handleStyle = {
        position: 'absolute',
        height: "".concat(width, "px"),
        width: "".concat(width, "px"),
        'border-radius': "".concat(parseInt(width / 1.5, 10), "px"),
        background: '#F5F5FF',
        border: '1px solid #4285c8'
      };
      (0, _object.objectEach)(handleStyle, function (value, key) {
        _this3.selectionHandles.styles.bottomRight[key] = value;
        _this3.selectionHandles.styles.topLeft[key] = value;
      });
      this.main.appendChild(this.selectionHandles.topLeft);
      this.main.appendChild(this.selectionHandles.bottomRight);
      this.main.appendChild(this.selectionHandles.topLeftHitArea);
      this.main.appendChild(this.selectionHandles.bottomRightHitArea);
    }
  }, {
    key: "isPartRange",
    value: function isPartRange(row, col) {
      var areaSelection = this.wot.selections.createOrGetArea();

      if (areaSelection.cellRange) {
        if (row !== areaSelection.cellRange.to.row || col !== areaSelection.cellRange.to.col) {
          return true;
        }
      }

      return false;
    }
  }, {
    key: "updateMultipleSelectionHandlesPosition",
    value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) {
      var handleWidth = parseInt(this.selectionHandles.styles.topLeft.width, 10);
      var hitAreaWidth = parseInt(this.selectionHandles.styles.topLeftHitArea.width, 10);
      this.selectionHandles.styles.topLeft.top = "".concat(parseInt(top - handleWidth, 10), "px");
      this.selectionHandles.styles.topLeft.left = "".concat(parseInt(left - handleWidth, 10), "px");
      this.selectionHandles.styles.topLeftHitArea.top = "".concat(parseInt(top - hitAreaWidth / 4 * 3, 10), "px");
      this.selectionHandles.styles.topLeftHitArea.left = "".concat(parseInt(left - hitAreaWidth / 4 * 3, 10), "px");
      this.selectionHandles.styles.bottomRight.top = "".concat(parseInt(top + height, 10), "px");
      this.selectionHandles.styles.bottomRight.left = "".concat(parseInt(left + width, 10), "px");
      this.selectionHandles.styles.bottomRightHitArea.top = "".concat(parseInt(top + height - hitAreaWidth / 4, 10), "px");
      this.selectionHandles.styles.bottomRightHitArea.left = "".concat(parseInt(left + width - hitAreaWidth / 4, 10), "px");

      if (this.settings.border.cornerVisible && this.settings.border.cornerVisible()) {
        this.selectionHandles.styles.topLeft.display = 'block';
        this.selectionHandles.styles.topLeftHitArea.display = 'block';

        if (this.isPartRange(row, col)) {
          this.selectionHandles.styles.bottomRight.display = 'none';
          this.selectionHandles.styles.bottomRightHitArea.display = 'none';
        } else {
          this.selectionHandles.styles.bottomRight.display = 'block';
          this.selectionHandles.styles.bottomRightHitArea.display = 'block';
        }
      } else {
        this.selectionHandles.styles.topLeft.display = 'none';
        this.selectionHandles.styles.bottomRight.display = 'none';
        this.selectionHandles.styles.topLeftHitArea.display = 'none';
        this.selectionHandles.styles.bottomRightHitArea.display = 'none';
      }

      if (row === this.wot.wtSettings.getSetting('fixedRowsTop') || col === this.wot.wtSettings.getSetting('fixedColumnsLeft')) {
        this.selectionHandles.styles.topLeft.zIndex = '9999';
        this.selectionHandles.styles.topLeftHitArea.zIndex = '9999';
      } else {
        this.selectionHandles.styles.topLeft.zIndex = '';
        this.selectionHandles.styles.topLeftHitArea.zIndex = '';
      }
    }
    /**
     * Show border around one or many cells
     *
     * @param {Array} corners
     */

  }, {
    key: "appear",
    value: function appear(corners) {
      if (this.disabled) {
        return;
      }

      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootDocument = _this$wot.rootDocument,
          rootWindow = _this$wot.rootWindow;
      var fromRow;
      var toRow;
      var fromColumn;
      var toColumn;
      var rowsCount = wtTable.getRenderedRowsCount();

      for (var i = 0; i < rowsCount; i += 1) {
        var s = wtTable.rowFilter.renderedToSource(i);

        if (s >= corners[0] && s <= corners[2]) {
          fromRow = s;
          break;
        }
      }

      for (var _i = rowsCount - 1; _i >= 0; _i -= 1) {
        var _s = wtTable.rowFilter.renderedToSource(_i);

        if (_s >= corners[0] && _s <= corners[2]) {
          toRow = _s;
          break;
        }
      }

      var columnsCount = wtTable.getRenderedColumnsCount();

      for (var _i2 = 0; _i2 < columnsCount; _i2 += 1) {
        var _s2 = wtTable.columnFilter.renderedToSource(_i2);

        if (_s2 >= corners[1] && _s2 <= corners[3]) {
          fromColumn = _s2;
          break;
        }
      }

      for (var _i3 = columnsCount - 1; _i3 >= 0; _i3 -= 1) {
        var _s3 = wtTable.columnFilter.renderedToSource(_i3);

        if (_s3 >= corners[1] && _s3 <= corners[3]) {
          toColumn = _s3;
          break;
        }
      }

      if (fromRow === void 0 || fromColumn === void 0) {
        this.disappear();
        return;
      }

      var fromTD = wtTable.getCell(new _coords.default(fromRow, fromColumn));
      var isMultiple = fromRow !== toRow || fromColumn !== toColumn;
      var toTD = isMultiple ? wtTable.getCell(new _coords.default(toRow, toColumn)) : fromTD;
      var fromOffset = (0, _element.offset)(fromTD);
      var toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset;
      var containerOffset = (0, _element.offset)(wtTable.TABLE);
      var minTop = fromOffset.top;
      var minLeft = fromOffset.left;
      var left = minLeft - containerOffset.left - 1;
      var width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft;

      if (this.isEntireColumnSelected(fromRow, toRow)) {
        var modifiedValues = this.getDimensionsFromHeader('columns', fromColumn, toColumn, containerOffset);
        var fromTH = null;

        if (modifiedValues) {
          var _modifiedValues = (0, _slicedToArray2.default)(modifiedValues, 3);

          fromTH = _modifiedValues[0];
          left = _modifiedValues[1];
          width = _modifiedValues[2];
        }

        if (fromTH) {
          fromTD = fromTH;
        }
      }

      var top = minTop - containerOffset.top - 1;
      var height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop;

      if (this.isEntireRowSelected(fromColumn, toColumn)) {
        var _modifiedValues2 = this.getDimensionsFromHeader('rows', fromRow, toRow, containerOffset);

        var _fromTH = null;

        if (_modifiedValues2) {
          var _modifiedValues3 = (0, _slicedToArray2.default)(_modifiedValues2, 3);

          _fromTH = _modifiedValues3[0];
          top = _modifiedValues3[1];
          height = _modifiedValues3[2];
        }

        if (_fromTH) {
          fromTD = _fromTH;
        }
      }

      var style = (0, _element.getComputedStyle)(fromTD, rootWindow);

      if (parseInt(style.borderTopWidth, 10) > 0) {
        top += 1;
        height = height > 0 ? height - 1 : 0;
      }

      if (parseInt(style.borderLeftWidth, 10) > 0) {
        left += 1;
        width = width > 0 ? width - 1 : 0;
      }

      this.topStyle.top = "".concat(top, "px");
      this.topStyle.left = "".concat(left, "px");
      this.topStyle.width = "".concat(width, "px");
      this.topStyle.display = 'block';
      this.leftStyle.top = "".concat(top, "px");
      this.leftStyle.left = "".concat(left, "px");
      this.leftStyle.height = "".concat(height, "px");
      this.leftStyle.display = 'block';
      var delta = Math.floor(this.settings.border.width / 2);
      this.bottomStyle.top = "".concat(top + height - delta, "px");
      this.bottomStyle.left = "".concat(left, "px");
      this.bottomStyle.width = "".concat(width, "px");
      this.bottomStyle.display = 'block';
      this.rightStyle.top = "".concat(top, "px");
      this.rightStyle.left = "".concat(left + width - delta, "px");
      this.rightStyle.height = "".concat(height + 1, "px");
      this.rightStyle.display = 'block';
      var cornerVisibleSetting = this.settings.border.cornerVisible;
      cornerVisibleSetting = typeof cornerVisibleSetting === 'function' ? cornerVisibleSetting(this.settings.layerLevel) : cornerVisibleSetting;
      var hookResult = this.wot.getSetting('onModifyGetCellCoords', toRow, toColumn);
      var checkRow = toRow,
          checkCol = toColumn;

      if (hookResult && Array.isArray(hookResult)) {
        var _hookResult = (0, _slicedToArray2.default)(hookResult, 4);

        checkRow = _hookResult[2];
        checkCol = _hookResult[3];
      }

      if ((0, _browser.isMobileBrowser)() || !cornerVisibleSetting || this.isPartRange(checkRow, checkCol)) {
        this.cornerStyle.display = 'none';
      } else {
        this.cornerStyle.top = "".concat(top + height - 4, "px");
        this.cornerStyle.left = "".concat(left + width - 4, "px");
        this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth;
        this.cornerStyle.width = this.cornerDefaultStyle.width; // Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars.

        this.cornerStyle.display = 'none';
        var trimmingContainer = (0, _element.getTrimmingContainer)(wtTable.TABLE);
        var trimToWindow = trimmingContainer === rootWindow;

        if (trimToWindow) {
          trimmingContainer = rootDocument.documentElement;
        }

        if (toColumn === this.wot.getSetting('totalColumns') - 1) {
          var toTdOffsetLeft = trimToWindow ? toTD.getBoundingClientRect().left : toTD.offsetLeft;
          var cornerRightEdge = toTdOffsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2;
          var cornerOverlappingContainer = cornerRightEdge >= (0, _element.innerWidth)(trimmingContainer);

          if (cornerOverlappingContainer) {
            this.cornerStyle.left = "".concat(Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2), "px");
            this.cornerStyle.borderRightWidth = 0;
          }
        }

        if (toRow === this.wot.getSetting('totalRows') - 1) {
          var toTdOffsetTop = trimToWindow ? toTD.getBoundingClientRect().top : toTD.offsetTop;
          var cornerBottomEdge = toTdOffsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2;

          var _cornerOverlappingContainer = cornerBottomEdge >= (0, _element.innerHeight)(trimmingContainer);

          if (_cornerOverlappingContainer) {
            this.cornerStyle.top = "".concat(Math.floor(top + height - 3 - parseInt(this.cornerDefaultStyle.height, 10) / 2), "px");
            this.cornerStyle.borderBottomWidth = 0;
          }
        }

        this.cornerStyle.display = 'block';
      }

      if ((0, _browser.isMobileBrowser)()) {
        this.updateMultipleSelectionHandlesPosition(toRow, toColumn, top, left, width, height);
      }
    }
    /**
     * Check whether an entire column of cells is selected.
     *
     * @private
     * @param {Number} startRowIndex Start row index.
     * @param {Number} endRowIndex End row index.
     */

  }, {
    key: "isEntireColumnSelected",
    value: function isEntireColumnSelected(startRowIndex, endRowIndex) {
      return startRowIndex === this.wot.wtTable.getFirstRenderedRow() && endRowIndex === this.wot.wtTable.getLastRenderedRow();
    }
    /**
     * Check whether an entire row of cells is selected.
     *
     * @private
     * @param {Number} startColumnIndex Start column index.
     * @param {Number} endColumnIndex End column index.
     */

  }, {
    key: "isEntireRowSelected",
    value: function isEntireRowSelected(startColumnIndex, endColumnIndex) {
      return startColumnIndex === this.wot.wtTable.getFirstRenderedColumn() && endColumnIndex === this.wot.wtTable.getLastRenderedColumn();
    }
    /**
     * Get left/top index and width/height depending on the `direction` provided.
     *
     * @private
     * @param {String} direction `rows` or `columns`, defines if an entire column or row is selected.
     * @param {Number} fromIndex Start index of the selection.
     * @param {Number} toIndex End index of the selection.
     * @param {Number} containerOffset offset of the container.
     * @return {Array|Boolean} Returns an array of [headerElement, left, width] or [headerElement, top, height], depending on `direction` (`false` in case of an error getting the headers).
     */

  }, {
    key: "getDimensionsFromHeader",
    value: function getDimensionsFromHeader(direction, fromIndex, toIndex, containerOffset) {
      var wtTable = this.wot.wtTable;
      var rootHotElement = wtTable.wtRootElement.parentNode;
      var getHeaderFn = null;
      var dimensionFn = null;
      var entireSelectionClassname = null;
      var index = null;
      var dimension = null;
      var dimensionProperty = null;
      var startHeader = null;
      var endHeader = null;

      switch (direction) {
        case 'rows':
          getHeaderFn = function getHeaderFn() {
            return wtTable.getRowHeader.apply(wtTable, arguments);
          };

          dimensionFn = function dimensionFn() {
            return _element.outerHeight.apply(void 0, arguments);
          };

          entireSelectionClassname = 'ht__selection--rows';
          dimensionProperty = 'top';
          break;

        case 'columns':
          getHeaderFn = function getHeaderFn() {
            return wtTable.getColumnHeader.apply(wtTable, arguments);
          };

          dimensionFn = function dimensionFn() {
            return _element.outerWidth.apply(void 0, arguments);
          };

          entireSelectionClassname = 'ht__selection--columns';
          dimensionProperty = 'left';
          break;

        default:
      }

      if (rootHotElement.className.includes(entireSelectionClassname)) {
        var columnHeaderLevelCount = this.wot.getSetting('columnHeaders').length;
        startHeader = getHeaderFn(fromIndex, columnHeaderLevelCount - 1);
        endHeader = getHeaderFn(toIndex, columnHeaderLevelCount - 1);

        if (!startHeader || !endHeader) {
          return false;
        }

        var startHeaderOffset = (0, _element.offset)(startHeader);
        var endOffset = (0, _element.offset)(endHeader);

        if (startHeader && endHeader) {
          index = startHeaderOffset[dimensionProperty] - containerOffset[dimensionProperty] - 1;
          dimension = endOffset[dimensionProperty] + dimensionFn(endHeader) - startHeaderOffset[dimensionProperty];
        }

        return [startHeader, index, dimension];
      }

      return false;
    }
    /**
     * Change border style.
     *
     * @private
     * @param {String} borderElement Coordinate where add/remove border: top, right, bottom, left.
     */

  }, {
    key: "changeBorderStyle",
    value: function changeBorderStyle(borderElement, border) {
      var style = this[borderElement].style;
      var borderStyle = border[borderElement];

      if (!borderStyle || borderStyle.hide) {
        (0, _element.addClass)(this[borderElement], 'hidden');
      } else {
        if ((0, _element.hasClass)(this[borderElement], 'hidden')) {
          (0, _element.removeClass)(this[borderElement], 'hidden');
        }

        style.backgroundColor = borderStyle.color;

        if (borderElement === 'top' || borderElement === 'bottom') {
          style.height = "".concat(borderStyle.width, "px");
        }

        if (borderElement === 'right' || borderElement === 'left') {
          style.width = "".concat(borderStyle.width, "px");
        }
      }
    }
    /**
     * Change border style to default.
     *
     * @private
     * @param {HTMLElement} position
     */

  }, {
    key: "changeBorderToDefaultStyle",
    value: function changeBorderToDefaultStyle(position) {
      var defaultBorder = {
        width: 1,
        color: '#000'
      };
      var style = this[position].style;
      style.backgroundColor = defaultBorder.color;
      style.width = "".concat(defaultBorder.width, "px");
      style.height = "".concat(defaultBorder.width, "px");
    }
    /**
     * Toggle class 'hidden' to element.
     *
     * @private
     * @param {String} borderElement Coordinate where add/remove border: top, right, bottom, left.
     * @return {Boolean}
     */

  }, {
    key: "toggleHiddenClass",
    value: function toggleHiddenClass(borderElement, remove) {
      this.changeBorderToDefaultStyle(borderElement);

      if (remove) {
        (0, _element.addClass)(this[borderElement], 'hidden');
      } else {
        (0, _element.removeClass)(this[borderElement], 'hidden');
      }
    }
    /**
     * Hide border
     */

  }, {
    key: "disappear",
    value: function disappear() {
      this.topStyle.display = 'none';
      this.leftStyle.display = 'none';
      this.bottomStyle.display = 'none';
      this.rightStyle.display = 'none';
      this.cornerStyle.display = 'none';

      if ((0, _browser.isMobileBrowser)()) {
        this.selectionHandles.styles.topLeft.display = 'none';
        this.selectionHandles.styles.bottomRight.display = 'none';
      }
    }
  }]);
  return Border;
}();

var _default = Border;
exports.default = _default;

/***/ }),
/* 337 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

__webpack_require__(159);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(64);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(37);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _unicode = __webpack_require__(50);

var _mixed = __webpack_require__(27);

var _string = __webpack_require__(68);

var _array = __webpack_require__(3);

var _element = __webpack_require__(5);

var _handsontableEditor = _interopRequireDefault(__webpack_require__(338));

var privatePool = new WeakMap();
/**
 * @private
 * @editor AutocompleteEditor
 * @class AutocompleteEditor
 * @dependencies HandsontableEditor
 */

var AutocompleteEditor =
/*#__PURE__*/
function (_HandsontableEditor) {
  (0, _inherits2.default)(AutocompleteEditor, _HandsontableEditor);

  function AutocompleteEditor(instance) {
    var _this;

    (0, _classCallCheck2.default)(this, AutocompleteEditor);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(AutocompleteEditor).call(this, instance));
    /**
     * Query string to turn available values over.
     *
     * @type {String}
     */

    _this.query = null;
    /**
     * Contains stripped choices.
     *
     * @type {String[]}
     */

    _this.strippedChoices = [];
    /**
     * Contains raw choices.
     *
     * @type {Array}
     */

    _this.rawChoices = [];
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      skipOne: false
    });
    return _this;
  }
  /**
   * Gets current value from editable element.
   *
   * @returns {String}
   */


  (0, _createClass2.default)(AutocompleteEditor, [{
    key: "getValue",
    value: function getValue() {
      var _this2 = this;

      var selectedValue = this.rawChoices.find(function (value) {
        var strippedValue = _this2.stripValueIfNeeded(value);

        return strippedValue === _this2.TEXTAREA.value;
      });

      if ((0, _mixed.isDefined)(selectedValue)) {
        return selectedValue;
      }

      return this.TEXTAREA.value;
    }
    /**
     * Creates an editor's elements and adds necessary CSS classnames.
     */

  }, {
    key: "createElements",
    value: function createElements() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutocompleteEditor.prototype), "createElements", this).call(this);
      (0, _element.addClass)(this.htContainer, 'autocompleteEditor');
      (0, _element.addClass)(this.htContainer, this.hot.rootWindow.navigator.platform.indexOf('Mac') === -1 ? '' : 'htMacScroll');
    }
    /**
     * Opens the editor and adjust its size and internal Handsontable's instance.
     */

  }, {
    key: "open",
    value: function open() {
      var _this3 = this;

      var priv = privatePool.get(this); // this.addHook('beforeKeyDown', event => this.onBeforeKeyDown(event));
      // Ugly fix for handsontable which grab window object for autocomplete scroll listener instead table element.

      this.TEXTAREA_PARENT.style.overflow = 'auto';
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutocompleteEditor.prototype), "open", this).call(this);
      this.TEXTAREA_PARENT.style.overflow = '';
      var choicesListHot = this.htEditor.getInstance();
      var trimDropdown = this.cellProperties.trimDropdown === void 0 ? true : this.cellProperties.trimDropdown;
      this.showEditableElement();
      this.focus();
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.hot.rootDocument);
      choicesListHot.updateSettings({
        colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : void 0,
        width: trimDropdown ? (0, _element.outerWidth)(this.TEXTAREA) + scrollbarWidth + 2 : void 0,
        afterRenderer: function afterRenderer(TD, row, col, prop, value) {
          var _this3$cellProperties = _this3.cellProperties,
              filteringCaseSensitive = _this3$cellProperties.filteringCaseSensitive,
              allowHtml = _this3$cellProperties.allowHtml;
          var query = _this3.query;
          var cellValue = (0, _mixed.stringify)(value);
          var indexOfMatch;
          var match;

          if (cellValue && !allowHtml) {
            indexOfMatch = filteringCaseSensitive === true ? cellValue.indexOf(query) : cellValue.toLowerCase().indexOf(query.toLowerCase());

            if (indexOfMatch !== -1) {
              match = cellValue.substr(indexOfMatch, query.length);
              cellValue = cellValue.replace(match, "<strong>".concat(match, "</strong>"));
            }
          }

          TD.innerHTML = cellValue;
        },
        autoColumnSize: true,
        modifyColWidth: function modifyColWidth(width, col) {
          // workaround for <strong> text overlapping the dropdown, not really accurate
          var autoColumnSize = this.getPlugin('autoColumnSize');
          var columnWidth = width;

          if (autoColumnSize) {
            var autoWidths = autoColumnSize.widths;

            if (autoWidths[col]) {
              columnWidth = autoWidths[col];
            }
          }

          return trimDropdown ? columnWidth : columnWidth + 15;
        }
      }); // Add additional space for autocomplete holder

      this.htEditor.view.wt.wtTable.holder.parentNode.style['padding-right'] = "".concat(scrollbarWidth + 2, "px");

      if (priv.skipOne) {
        priv.skipOne = false;
      }

      this.hot._registerTimeout(function () {
        _this3.queryChoices(_this3.TEXTAREA.value);
      });
    }
    /**
     * Closes the editor.
     */

  }, {
    key: "close",
    value: function close() {
      this.removeHooksByKey('beforeKeyDown');
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutocompleteEditor.prototype), "close", this).call(this);
    }
    /**
     * Verifies result of validation or closes editor if user's cancelled changes. Re-renders WalkOnTable.
     *
     * @param {Boolean|undefined} result
     */

  }, {
    key: "discardEditor",
    value: function discardEditor(result) {
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutocompleteEditor.prototype), "discardEditor", this).call(this, result);
      this.hot.view.render();
    }
    /**
     * Prepares choices list based on applied argument.
     *
     * @private
     * @param {String} query
     */

  }, {
    key: "queryChoices",
    value: function queryChoices(query) {
      var _this4 = this;

      var source = this.cellProperties.source;
      this.query = query;

      if (typeof source === 'function') {
        source.call(this.cellProperties, query, function (choices) {
          _this4.rawChoices = choices;

          _this4.updateChoicesList(_this4.stripValuesIfNeeded(choices));
        });
      } else if (Array.isArray(source)) {
        this.rawChoices = source;
        this.updateChoicesList(this.stripValuesIfNeeded(source));
      } else {
        this.updateChoicesList([]);
      }
    }
    /**
     * Updates list of the possible completions to choose.
     *
     * @private
     * @param {Array} choicesList
     */

  }, {
    key: "updateChoicesList",
    value: function updateChoicesList(choicesList) {
      var pos = (0, _element.getCaretPosition)(this.TEXTAREA);
      var endPos = (0, _element.getSelectionEndPosition)(this.TEXTAREA);
      var sortByRelevanceSetting = this.cellProperties.sortByRelevance;
      var filterSetting = this.cellProperties.filter;
      var orderByRelevance = null;
      var highlightIndex = null;
      var choices = choicesList;

      if (sortByRelevanceSetting) {
        orderByRelevance = AutocompleteEditor.sortByRelevance(this.stripValueIfNeeded(this.getValue()), choices, this.cellProperties.filteringCaseSensitive);
      }

      var orderByRelevanceLength = Array.isArray(orderByRelevance) ? orderByRelevance.length : 0;

      if (filterSetting === false) {
        if (orderByRelevanceLength) {
          highlightIndex = orderByRelevance[0];
        }
      } else {
        var sorted = [];

        for (var i = 0, choicesCount = choices.length; i < choicesCount; i++) {
          if (sortByRelevanceSetting && orderByRelevanceLength <= i) {
            break;
          }

          if (orderByRelevanceLength) {
            sorted.push(choices[orderByRelevance[i]]);
          } else {
            sorted.push(choices[i]);
          }
        }

        highlightIndex = 0;
        choices = sorted;
      }

      this.strippedChoices = choices;
      this.htEditor.loadData((0, _array.pivot)([choices]));
      this.updateDropdownHeight();
      this.flipDropdownIfNeeded();

      if (this.cellProperties.strict === true) {
        this.highlightBestMatchingChoice(highlightIndex);
      }

      this.hot.listen(false);
      (0, _element.setCaretPosition)(this.TEXTAREA, pos, pos === endPos ? void 0 : endPos);
    }
    /**
     * Checks where is enough place to open editor.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "flipDropdownIfNeeded",
    value: function flipDropdownIfNeeded() {
      var textareaOffset = (0, _element.offset)(this.TEXTAREA);
      var textareaHeight = (0, _element.outerHeight)(this.TEXTAREA);
      var dropdownHeight = this.getDropdownHeight();
      var trimmingContainer = (0, _element.getTrimmingContainer)(this.hot.view.wt.wtTable.TABLE);
      var trimmingContainerScrollTop = trimmingContainer.scrollTop;
      var headersHeight = (0, _element.outerHeight)(this.hot.view.wt.wtTable.THEAD);
      var containerOffset = {
        row: 0,
        col: 0
      };

      if (trimmingContainer !== this.hot.rootWindow) {
        containerOffset = (0, _element.offset)(trimmingContainer);
      }

      var spaceAbove = textareaOffset.top - containerOffset.top - headersHeight + trimmingContainerScrollTop;
      var spaceBelow = trimmingContainer.scrollHeight - spaceAbove - headersHeight - textareaHeight;
      var flipNeeded = dropdownHeight > spaceBelow && spaceAbove > spaceBelow;

      if (flipNeeded) {
        this.flipDropdown(dropdownHeight);
      } else {
        this.unflipDropdown();
      }

      this.limitDropdownIfNeeded(flipNeeded ? spaceAbove : spaceBelow, dropdownHeight);
      return flipNeeded;
    }
    /**
     * Checks if the internal table should generate scrollbar or could be rendered without it.
     *
     * @private
     * @param {Number} spaceAvailable
     * @param {Number} dropdownHeight
     */

  }, {
    key: "limitDropdownIfNeeded",
    value: function limitDropdownIfNeeded(spaceAvailable, dropdownHeight) {
      if (dropdownHeight > spaceAvailable) {
        var tempHeight = 0;
        var i = 0;
        var lastRowHeight = 0;
        var height = null;

        do {
          lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.wt.wtSettings.settings.defaultRowHeight;
          tempHeight += lastRowHeight;
          i += 1;
        } while (tempHeight < spaceAvailable);

        height = tempHeight - lastRowHeight;

        if (this.htEditor.flipped) {
          this.htEditor.rootElement.style.top = "".concat(parseInt(this.htEditor.rootElement.style.top, 10) + dropdownHeight - height, "px");
        }

        this.setDropdownHeight(tempHeight - lastRowHeight);
      }
    }
    /**
     * Configures editor to open it at the top.
     *
     * @private
     * @param {Number} dropdownHeight
     */

  }, {
    key: "flipDropdown",
    value: function flipDropdown(dropdownHeight) {
      var dropdownStyle = this.htEditor.rootElement.style;
      dropdownStyle.position = 'absolute';
      dropdownStyle.top = "".concat(-dropdownHeight, "px");
      this.htEditor.flipped = true;
    }
    /**
     * Configures editor to open it at the bottom.
     *
     * @private
     */

  }, {
    key: "unflipDropdown",
    value: function unflipDropdown() {
      var dropdownStyle = this.htEditor.rootElement.style;

      if (dropdownStyle.position === 'absolute') {
        dropdownStyle.position = '';
        dropdownStyle.top = '';
      }

      this.htEditor.flipped = void 0;
    }
    /**
     * Updates width and height of the internal Handsontable's instance.
     *
     * @private
     */

  }, {
    key: "updateDropdownHeight",
    value: function updateDropdownHeight() {
      var currentDropdownWidth = this.htEditor.getColWidth(0) + (0, _element.getScrollbarWidth)(this.hot.rootDocument) + 2;
      var trimDropdown = this.cellProperties.trimDropdown;
      this.htEditor.updateSettings({
        height: this.getDropdownHeight(),
        width: trimDropdown ? void 0 : currentDropdownWidth
      });
      this.htEditor.view.wt.wtTable.alignOverlaysWithTrimmingContainer();
    }
    /**
     * Sets new height of the internal Handsontable's instance.
     *
     * @private
     * @param {Number} height
     */

  }, {
    key: "setDropdownHeight",
    value: function setDropdownHeight(height) {
      this.htEditor.updateSettings({
        height: height
      });
    }
    /**
     * Creates new selection on specified row index, or deselects selected cells.
     *
     * @private
     * @param {Number|undefined} index
     */

  }, {
    key: "highlightBestMatchingChoice",
    value: function highlightBestMatchingChoice(index) {
      if (typeof index === 'number') {
        this.htEditor.selectCell(index, 0, void 0, void 0, void 0, false);
      } else {
        this.htEditor.deselectCell();
      }
    }
    /**
     * Calculates and return the internal Handsontable's height.
     *
     * @private
     * @returns {Number}
     */

  }, {
    key: "getDropdownHeight",
    value: function getDropdownHeight() {
      var firstRowHeight = this.htEditor.getInstance().getRowHeight(0) || 23;
      var visibleRows = this.cellProperties.visibleRows;
      return this.strippedChoices.length >= visibleRows ? visibleRows * firstRowHeight : this.strippedChoices.length * firstRowHeight + 8;
    }
    /**
     * Sanitizes value from potential dangerous tags.
     *
     * @private
     * @param {String} value
     * @returns {String}
     */

  }, {
    key: "stripValueIfNeeded",
    value: function stripValueIfNeeded(value) {
      return this.stripValuesIfNeeded([value])[0];
    }
    /**
     * Sanitizes an array of the values from potential dangerous tags.
     *
     * @private
     * @param {String[]} values
     * @returns {String[]}
     */

  }, {
    key: "stripValuesIfNeeded",
    value: function stripValuesIfNeeded(values) {
      var allowHtml = this.cellProperties.allowHtml;
      var stringifiedValues = (0, _array.arrayMap)(values, function (value) {
        return (0, _mixed.stringify)(value);
      });
      var strippedValues = (0, _array.arrayMap)(stringifiedValues, function (value) {
        return allowHtml ? value : (0, _string.stripTags)(value);
      });
      return strippedValues;
    }
    /**
     * Captures use of arrow down and up to control their behaviour.
     *
     * @private
     * @param {Number} keyCode
     * @returns {Boolean}
     */

  }, {
    key: "allowKeyEventPropagation",
    value: function allowKeyEventPropagation(keyCode) {
      var selectedRange = this.htEditor.getSelectedRangeLast();
      var selected = {
        row: selectedRange ? selectedRange.from.row : -1
      };
      var allowed = false;

      if (keyCode === _unicode.KEY_CODES.ARROW_DOWN && selected.row > 0 && selected.row < this.htEditor.countRows() - 1) {
        allowed = true;
      }

      if (keyCode === _unicode.KEY_CODES.ARROW_UP && selected.row > -1) {
        allowed = true;
      }

      return allowed;
    }
    /**
     * onBeforeKeyDown callback.
     *
     * @private
     * @param {KeyboardEvent} event
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown(event) {
      var _this5 = this;

      var priv = privatePool.get(this);
      priv.skipOne = false;

      if ((0, _unicode.isPrintableChar)(event.keyCode) || event.keyCode === _unicode.KEY_CODES.BACKSPACE || event.keyCode === _unicode.KEY_CODES.DELETE || event.keyCode === _unicode.KEY_CODES.INSERT) {
        var timeOffset = 0; // on ctl+c / cmd+c don't update suggestion list

        if (event.keyCode === _unicode.KEY_CODES.C && (event.ctrlKey || event.metaKey)) {
          return;
        }

        if (!this.isOpened()) {
          timeOffset += 10;
        }

        if (this.htEditor) {
          this.hot._registerTimeout(function () {
            _this5.queryChoices(_this5.TEXTAREA.value);

            priv.skipOne = true;
          }, timeOffset);
        }
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(AutocompleteEditor.prototype), "onBeforeKeyDown", this).call(this, event);
    }
  }]);
  return AutocompleteEditor;
}(_handsontableEditor.default);
/**
 * Filters and sorts by relevance.
 *
 * @param value
 * @param choices
 * @param caseSensitive
 * @returns {Number[]} array of indexes in original choices array
 */


AutocompleteEditor.sortByRelevance = function (value, choices, caseSensitive) {
  var choicesRelevance = [];
  var currentItem;
  var valueLength = value.length;
  var valueIndex;
  var charsLeft;
  var result = [];
  var i;
  var choicesCount = choices.length;

  if (valueLength === 0) {
    for (i = 0; i < choicesCount; i++) {
      result.push(i);
    }

    return result;
  }

  for (i = 0; i < choicesCount; i++) {
    currentItem = (0, _string.stripTags)((0, _mixed.stringify)(choices[i]));

    if (caseSensitive) {
      valueIndex = currentItem.indexOf(value);
    } else {
      valueIndex = currentItem.toLowerCase().indexOf(value.toLowerCase());
    }

    if (valueIndex !== -1) {
      charsLeft = currentItem.length - valueIndex - valueLength;
      choicesRelevance.push({
        baseIndex: i,
        index: valueIndex,
        charsLeft: charsLeft,
        value: currentItem
      });
    }
  }

  choicesRelevance.sort(function (a, b) {
    if (b.index === -1) {
      return -1;
    }

    if (a.index === -1) {
      return 1;
    }

    if (a.index < b.index) {
      return -1;
    } else if (b.index < a.index) {
      return 1;
    } else if (a.index === b.index) {
      if (a.charsLeft < b.charsLeft) {
        return -1;
      } else if (a.charsLeft > b.charsLeft) {
        return 1;
      }
    }

    return 0;
  });

  for (i = 0, choicesCount = choicesRelevance.length; i < choicesCount; i++) {
    result.push(choicesRelevance[i].baseIndex);
  }

  return result;
};

var _default = AutocompleteEditor;
exports.default = _default;

/***/ }),
/* 338 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _unicode = __webpack_require__(50);

var _object = __webpack_require__(4);

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

var _textEditor = _interopRequireDefault(__webpack_require__(107));

/**
 * @private
 * @editor HandsontableEditor
 * @class HandsontableEditor
 * @dependencies TextEditor
 */
var HandsontableEditor =
/*#__PURE__*/
function (_TextEditor) {
  (0, _inherits2.default)(HandsontableEditor, _TextEditor);

  function HandsontableEditor() {
    (0, _classCallCheck2.default)(this, HandsontableEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HandsontableEditor).apply(this, arguments));
  }

  (0, _createClass2.default)(HandsontableEditor, [{
    key: "open",

    /**
     * Opens the editor and adjust its size.
     */
    value: function open() {
      // this.addHook('beforeKeyDown', event => this.onBeforeKeyDown(event));
      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "open", this).call(this);

      if (this.htEditor) {
        this.htEditor.destroy();
      }

      if (this.htContainer.style.display === 'none') {
        this.htContainer.style.display = '';
      } // Construct and initialise a new Handsontable


      this.htEditor = new this.hot.constructor(this.htContainer, this.htOptions);
      this.htEditor.init();
      this.htEditor.rootElement.style.display = '';

      if (this.cellProperties.strict) {
        this.htEditor.selectCell(0, 0);
      } else {
        this.htEditor.deselectCell();
      }

      (0, _element.setCaretPosition)(this.TEXTAREA, 0, this.TEXTAREA.value.length);
    }
    /**
     * Closes the editor.
     */

  }, {
    key: "close",
    value: function close() {
      this.htEditor.rootElement.style.display = 'none';
      this.removeHooksByKey('beforeKeyDown');
      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "close", this).call(this);
    }
    /**
     * Prepares editor's meta data and configuration of the internal Handsontable's instance.
     *
     * @param {Number} row
     * @param {Number} col
     * @param {Number|String} prop
     * @param {HTMLTableCellElement} td
     * @param {*} originalValue
     * @param {Object} cellProperties
     */

  }, {
    key: "prepare",
    value: function prepare(td, row, col, prop, value, cellProperties) {
      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "prepare", this).call(this, td, row, col, prop, value, cellProperties);
      var parent = this;
      var options = {
        startRows: 0,
        startCols: 0,
        minRows: 0,
        minCols: 0,
        className: 'listbox',
        copyPaste: false,
        autoColumnSize: false,
        autoRowSize: false,
        readOnly: true,
        fillHandle: false,
        autoWrapCol: false,
        autoWrapRow: false,
        afterOnCellMouseDown: function afterOnCellMouseDown(_, coords) {
          var sourceValue = this.getSourceData(coords.row, coords.col); // if the value is undefined then it means we don't want to set the value

          if (sourceValue !== void 0) {
            parent.setValue(sourceValue);
          }

          parent.instance.destroyEditor();
        }
      };

      if (this.cellProperties.handsontable) {
        (0, _object.extend)(options, cellProperties.handsontable);
      }

      this.htOptions = options;
    }
    /**
     * Begins editing on a highlighted cell and hides fillHandle corner if was present.
     *
     * @param {*} newInitialValue
     * @param {*} event
     */

  }, {
    key: "beginEditing",
    value: function beginEditing(newInitialValue, event) {
      var onBeginEditing = this.hot.getSettings().onBeginEditing;

      if (onBeginEditing && onBeginEditing() === false) {
        return;
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "beginEditing", this).call(this, newInitialValue, event);
    }
    /**
     * Sets focus state on the select element.
     */

  }, {
    key: "focus",
    value: function focus() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "focus", this).call(this);
    }
    /**
     * Creates an editor's elements and adds necessary CSS classnames.
     */

  }, {
    key: "createElements",
    value: function createElements() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "createElements", this).call(this);
      var DIV = this.hot.rootDocument.createElement('DIV');
      DIV.className = 'handsontableEditor';
      this.TEXTAREA_PARENT.appendChild(DIV);
      this.htContainer = DIV;
      this.assignHooks();
    }
    /**
     * Finishes editing and start saving or restoring process for editing cell or last selected range.
     *
     * @param {Boolean} restoreOriginalValue If true, then closes editor without saving value from the editor into a cell.
     * @param {Boolean} ctrlDown If true, then saveValue will save editor's value to each cell in the last selected range.
     * @param {Function} callback
     */

  }, {
    key: "finishEditing",
    value: function finishEditing(restoreOriginalValue, ctrlDown, callback) {
      if (this.htEditor && this.htEditor.isListening()) {
        // if focus is still in the HOT editor
        this.hot.listen(); // return the focus to the parent HOT instance
      }

      if (this.htEditor && this.htEditor.getSelectedLast()) {
        var value = this.htEditor.getInstance().getValue();

        if (value !== void 0) {
          // if the value is undefined then it means we don't want to set the value
          this.setValue(value);
        }
      }

      return (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "finishEditing", this).call(this, restoreOriginalValue, ctrlDown, callback);
    }
    /**
     * Assings afterDestroy callback to prevent memory leaks.
     *
     * @private
     */

  }, {
    key: "assignHooks",
    value: function assignHooks() {
      var _this = this;

      this.hot.addHook('afterDestroy', function () {
        if (_this.htEditor) {
          _this.htEditor.destroy();
        }
      });
    }
    /**
     * onBeforeKeyDown callback.
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown(event) {
      if ((0, _event.isImmediatePropagationStopped)(event)) {
        return;
      }

      var innerHOT = this.htEditor.getInstance();
      var rowToSelect;
      var selectedRow;

      if (event.keyCode === _unicode.KEY_CODES.ARROW_DOWN) {
        if (!innerHOT.getSelectedLast() && !innerHOT.flipped) {
          rowToSelect = 0;
        } else if (innerHOT.getSelectedLast()) {
          if (innerHOT.flipped) {
            rowToSelect = innerHOT.getSelectedLast()[0] + 1;
          } else if (!innerHOT.flipped) {
            var lastRow = innerHOT.countRows() - 1;
            selectedRow = innerHOT.getSelectedLast()[0];
            rowToSelect = Math.min(lastRow, selectedRow + 1);
          }
        }
      } else if (event.keyCode === _unicode.KEY_CODES.ARROW_UP) {
        if (!innerHOT.getSelectedLast() && innerHOT.flipped) {
          rowToSelect = innerHOT.countRows() - 1;
        } else if (innerHOT.getSelectedLast()) {
          if (innerHOT.flipped) {
            selectedRow = innerHOT.getSelectedLast()[0];
            rowToSelect = Math.max(0, selectedRow - 1);
          } else {
            selectedRow = innerHOT.getSelectedLast()[0];
            rowToSelect = selectedRow - 1;
          }
        }
      }

      if (rowToSelect !== void 0) {
        if (rowToSelect < 0 || innerHOT.flipped && rowToSelect > innerHOT.countRows() - 1) {
          innerHOT.deselectCell();
        } else {
          innerHOT.selectCell(rowToSelect, 0);
        }

        if (innerHOT.getData().length) {
          event.preventDefault();
          (0, _event.stopImmediatePropagation)(event);
          this.hot.listen();
          this.TEXTAREA.focus();
        }
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(HandsontableEditor.prototype), "onBeforeKeyDown", this).call(this, event);
    }
  }]);
  return HandsontableEditor;
}(_textEditor.default);

var _default = HandsontableEditor;
exports.default = _default;

/***/ }),
/* 339 */
/***/ (function(module, exports) {



/***/ }),
/* 340 */
/***/ (function(module, exports) {



/***/ }),
/* 341 */
/***/ (function(module, exports) {



/***/ }),
/* 342 */
/***/ (function(module, exports) {



/***/ }),
/* 343 */
/***/ (function(module, exports) {



/***/ }),
/* 344 */
/***/ (function(module, exports) {



/***/ }),
/* 345 */
/***/ (function(module, exports) {



/***/ }),
/* 346 */
/***/ (function(module, exports) {



/***/ }),
/* 347 */
/***/ (function(module, exports) {



/***/ }),
/* 348 */
/***/ (function(module, exports) {



/***/ }),
/* 349 */
/***/ (function(module, exports) {



/***/ }),
/* 350 */
/***/ (function(module, exports) {



/***/ }),
/* 351 */
/***/ (function(module, exports) {



/***/ }),
/* 352 */
/***/ (function(module, exports) {



/***/ }),
/* 353 */
/***/ (function(module, exports) {



/***/ }),
/* 354 */
/***/ (function(module, exports) {



/***/ }),
/* 355 */
/***/ (function(module, exports) {



/***/ }),
/* 356 */
/***/ (function(module, exports) {



/***/ }),
/* 357 */
/***/ (function(module, exports) {



/***/ }),
/* 358 */
/***/ (function(module, exports) {



/***/ }),
/* 359 */
/***/ (function(module, exports) {



/***/ }),
/* 360 */
/***/ (function(module, exports) {



/***/ }),
/* 361 */
/***/ (function(module, exports) {



/***/ }),
/* 362 */
/***/ (function(module, exports) {



/***/ }),
/* 363 */
/***/ (function(module, exports) {



/***/ }),
/* 364 */
/***/ (function(module, exports) {



/***/ }),
/* 365 */
/***/ (function(module, exports) {



/***/ }),
/* 366 */
/***/ (function(module, exports) {



/***/ }),
/* 367 */
/***/ (function(module, exports) {



/***/ }),
/* 368 */
/***/ (function(module, exports) {



/***/ }),
/* 369 */
/***/ (function(module, exports) {



/***/ }),
/* 370 */
/***/ (function(module, exports) {



/***/ }),
/* 371 */
/***/ (function(module, exports) {



/***/ }),
/* 372 */
/***/ (function(module, exports) {



/***/ }),
/* 373 */
/***/ (function(module, exports) {



/***/ }),
/* 374 */
/***/ (function(module, exports) {



/***/ }),
/* 375 */
/***/ (function(module, exports) {



/***/ }),
/* 376 */
/***/ (function(module, exports) {



/***/ }),
/* 377 */
/***/ (function(module, exports) {



/***/ }),
/* 378 */
/***/ (function(module, exports) {



/***/ }),
/* 379 */
/***/ (function(module, exports) {



/***/ }),
/* 380 */
/***/ (function(module, exports) {



/***/ }),
/* 381 */
/***/ (function(module, exports) {



/***/ }),
/* 382 */
/***/ (function(module, exports) {



/***/ }),
/* 383 */
/***/ (function(module, exports) {



/***/ }),
/* 384 */
/***/ (function(module, exports) {



/***/ }),
/* 385 */
/***/ (function(module, exports) {



/***/ }),
/* 386 */
/***/ (function(module, exports) {



/***/ }),
/* 387 */
/***/ (function(module, exports) {



/***/ }),
/* 388 */
/***/ (function(module, exports) {



/***/ }),
/* 389 */
/***/ (function(module, exports) {



/***/ }),
/* 390 */
/***/ (function(module, exports) {



/***/ }),
/* 391 */
/***/ (function(module, exports) {



/***/ }),
/* 392 */
/***/ (function(module, exports) {



/***/ }),
/* 393 */
/***/ (function(module, exports) {



/***/ }),
/* 394 */
/***/ (function(module, exports) {



/***/ }),
/* 395 */
/***/ (function(module, exports) {



/***/ }),
/* 396 */
/***/ (function(module, exports) {



/***/ }),
/* 397 */
/***/ (function(module, exports) {



/***/ }),
/* 398 */
/***/ (function(module, exports) {



/***/ }),
/* 399 */
/***/ (function(module, exports) {



/***/ }),
/* 400 */
/***/ (function(module, exports) {



/***/ }),
/* 401 */
/***/ (function(module, exports) {



/***/ }),
/* 402 */
/***/ (function(module, exports) {



/***/ }),
/* 403 */
/***/ (function(module, exports) {



/***/ }),
/* 404 */
/***/ (function(module, exports) {



/***/ }),
/* 405 */
/***/ (function(module, exports) {



/***/ }),
/* 406 */
/***/ (function(module, exports) {



/***/ }),
/* 407 */
/***/ (function(module, exports) {



/***/ }),
/* 408 */
/***/ (function(module, exports) {



/***/ }),
/* 409 */
/***/ (function(module, exports) {



/***/ }),
/* 410 */
/***/ (function(module, exports) {



/***/ }),
/* 411 */
/***/ (function(module, exports) {



/***/ }),
/* 412 */
/***/ (function(module, exports) {



/***/ }),
/* 413 */
/***/ (function(module, exports) {



/***/ }),
/* 414 */
/***/ (function(module, exports) {



/***/ }),
/* 415 */
/***/ (function(module, exports) {



/***/ }),
/* 416 */
/***/ (function(module, exports) {



/***/ }),
/* 417 */
/***/ (function(module, exports) {



/***/ }),
/* 418 */
/***/ (function(module, exports) {



/***/ }),
/* 419 */
/***/ (function(module, exports) {



/***/ }),
/* 420 */
/***/ (function(module, exports) {



/***/ }),
/* 421 */
/***/ (function(module, exports) {



/***/ }),
/* 422 */
/***/ (function(module, exports) {



/***/ }),
/* 423 */
/***/ (function(module, exports) {



/***/ }),
/* 424 */
/***/ (function(module, exports) {



/***/ }),
/* 425 */
/***/ (function(module, exports) {



/***/ }),
/* 426 */
/***/ (function(module, exports) {



/***/ }),
/* 427 */
/***/ (function(module, exports) {



/***/ }),
/* 428 */
/***/ (function(module, exports) {



/***/ }),
/* 429 */
/***/ (function(module, exports) {



/***/ }),
/* 430 */
/***/ (function(module, exports) {



/***/ }),
/* 431 */
/***/ (function(module, exports) {



/***/ }),
/* 432 */
/***/ (function(module, exports) {



/***/ }),
/* 433 */
/***/ (function(module, exports) {



/***/ }),
/* 434 */
/***/ (function(module, exports) {



/***/ }),
/* 435 */
/***/ (function(module, exports) {



/***/ }),
/* 436 */
/***/ (function(module, exports) {



/***/ }),
/* 437 */
/***/ (function(module, exports) {



/***/ }),
/* 438 */
/***/ (function(module, exports) {



/***/ }),
/* 439 */
/***/ (function(module, exports) {



/***/ }),
/* 440 */
/***/ (function(module, exports) {



/***/ }),
/* 441 */
/***/ (function(module, exports) {



/***/ }),
/* 442 */
/***/ (function(module, exports) {



/***/ }),
/* 443 */
/***/ (function(module, exports) {



/***/ }),
/* 444 */
/***/ (function(module, exports) {



/***/ }),
/* 445 */
/***/ (function(module, exports) {



/***/ }),
/* 446 */
/***/ (function(module, exports) {



/***/ }),
/* 447 */
/***/ (function(module, exports) {



/***/ }),
/* 448 */
/***/ (function(module, exports) {



/***/ }),
/* 449 */
/***/ (function(module, exports) {



/***/ }),
/* 450 */
/***/ (function(module, exports) {



/***/ }),
/* 451 */
/***/ (function(module, exports) {



/***/ }),
/* 452 */
/***/ (function(module, exports) {



/***/ }),
/* 453 */
/***/ (function(module, exports) {



/***/ }),
/* 454 */
/***/ (function(module, exports) {



/***/ }),
/* 455 */
/***/ (function(module, exports) {



/***/ }),
/* 456 */
/***/ (function(module, exports) {



/***/ }),
/* 457 */
/***/ (function(module, exports) {



/***/ }),
/* 458 */
/***/ (function(module, exports) {



/***/ }),
/* 459 */
/***/ (function(module, exports) {



/***/ }),
/* 460 */
/***/ (function(module, exports) {



/***/ }),
/* 461 */
/***/ (function(module, exports) {



/***/ }),
/* 462 */
/***/ (function(module, exports) {



/***/ }),
/* 463 */
/***/ (function(module, exports) {



/***/ }),
/* 464 */
/***/ (function(module, exports) {



/***/ }),
/* 465 */
/***/ (function(module, exports) {



/***/ }),
/* 466 */
/***/ (function(module, exports, __webpack_require__) {

var require;var require;!function(e){if(true)module.exports=e();else {}}(function(){return function e(t,n,r){function i(o,u){if(!n[o]){if(!t[o]){var s="function"==typeof require&&require;if(!u&&s)return require(o,!0);if(a)return a(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return i(n||e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){!function(e){"use strict";function n(e){function t(e,n){var r,i,a,o,u,s,c=this;if(!(c instanceof t))return q&&_(26,"constructor call without new",e),new t(e,n);if(null!=n&&Z(n,2,64,T,"base")){if(n|=0,s=e+"",10==n)return c=new t(e instanceof t?e:s),A(c,C+c.e+1,R);if((o="number"==typeof e)&&0*e!=0||!new RegExp("^-?"+(r="["+b.slice(0,n)+"]+")+"(?:\\."+r+")?$",n<37?"i":"").test(s))return E(c,s,o,n);o?(c.s=1/e<0?(s=s.slice(1),-1):1,q&&s.replace(/^0\.0*|\./,"").length>15&&_(T,y,e),o=!1):c.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1,s=g(s,10,n,c.s)}else{if(e instanceof t)return c.s=e.s,c.e=e.e,c.c=(e=e.c)?e.slice():e,void(T=0);if((o="number"==typeof e)&&0*e==0){if(c.s=1/e<0?(e=-e,-1):1,e===~~e){for(i=0,a=e;a>=10;a/=10,i++);return c.e=i,c.c=[e],void(T=0)}s=e+""}else{if(!p.test(s=e+""))return E(c,s,o);c.s=45===s.charCodeAt(0)?(s=s.slice(1),-1):1}}for((i=s.indexOf("."))>-1&&(s=s.replace(".","")),(a=s.search(/e/i))>0?(i<0&&(i=a),i+=+s.slice(a+1),s=s.substring(0,a)):i<0&&(i=s.length),a=0;48===s.charCodeAt(a);a++);for(u=s.length;48===s.charCodeAt(--u););if(s=s.slice(a,u+1))if(u=s.length,o&&q&&u>15&&(e>S||e!==h(e))&&_(T,y,c.s*e),(i=i-a-1)>V)c.c=c.e=null;else if(i<I)c.c=[c.e=0];else{if(c.e=i,c.c=[],a=(i+1)%x,i<0&&(a+=x),a<u){for(a&&c.c.push(+s.slice(0,a)),u-=x;a<u;)c.c.push(+s.slice(a,a+=x));s=s.slice(a),a=x-s.length}else a-=u;for(;a--;s+="0");c.c.push(+s)}else c.c=[c.e=0];T=0}function g(e,n,r,a){var o,u,c,f,g,p,d,h=e.indexOf("."),v=C,m=R;for(r<37&&(e=e.toLowerCase()),h>=0&&(c=W,W=0,e=e.replace(".",""),g=(d=new t(r)).pow(e.length-h),W=c,d.c=s(l(i(g.c),g.e),10,n),d.e=d.c.length),u=c=(p=s(e,r,n)).length;0==p[--c];p.pop());if(!p[0])return"0";if(h<0?--u:(g.c=p,g.e=u,g.s=a,p=(g=L(g,d,v,m,n)).c,f=g.r,u=g.e),o=u+v+1,h=p[o],c=n/2,f=f||o<0||null!=p[o+1],f=m<4?(null!=h||f)&&(0==m||m==(g.s<0?3:2)):h>c||h==c&&(4==m||f||6==m&&1&p[o-1]||m==(g.s<0?8:7)),o<1||!p[0])e=f?l("1",-v):"0";else{if(p.length=o,f)for(--n;++p[--o]>n;)p[o]=0,o||(++u,p=[1].concat(p));for(c=p.length;!p[--c];);for(h=0,e="";h<=c;e+=b.charAt(p[h++]));e=l(e,u)}return e}function F(e,n,r,a){var o,u,s,f,g;if(r=null!=r&&Z(r,0,8,a,m)?0|r:R,!e.c)return e.toString();if(o=e.c[0],s=e.e,null==n)g=i(e.c),g=19==a||24==a&&s<=$?c(g,s):l(g,s);else if(e=A(new t(e),n,r),u=e.e,g=i(e.c),f=g.length,19==a||24==a&&(n<=u||u<=$)){for(;f<n;g+="0",f++);g=c(g,u)}else if(n-=s,g=l(g,u),u+1>f){if(--n>0)for(g+=".";n--;g+="0");}else if((n+=u-f)>0)for(u+1==f&&(g+=".");n--;g+="0");return e.s<0&&o?"-"+g:g}function D(e,n){var r,i,a=0;for(u(e[0])&&(e=e[0]),r=new t(e[0]);++a<e.length;){if(!(i=new t(e[a])).s){r=i;break}n.call(r,i)&&(r=i)}return r}function B(e,t,n,r,i){return(e<t||e>n||e!=f(e))&&_(r,(i||"decimal places")+(e<t||e>n?" out of range":" not an integer"),e),!0}function k(e,t,n){for(var r=1,i=t.length;!t[--i];t.pop());for(i=t[0];i>=10;i/=10,r++);return(n=r+n*x-1)>V?e.c=e.e=null:n<I?e.c=[e.e=0]:(e.e=n,e.c=t),e}function _(e,t,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][e]+"() "+t+": "+n);throw r.name="BigNumber Error",T=0,r}function A(e,t,n,r){var i,a,o,u,s,c,l,f=e.c,g=N;if(f){e:{for(i=1,u=f[0];u>=10;u/=10,i++);if((a=t-i)<0)a+=x,o=t,l=(s=f[c=0])/g[i-o-1]%10|0;else if((c=d((a+1)/x))>=f.length){if(!r)break e;for(;f.length<=c;f.push(0));s=l=0,i=1,o=(a%=x)-x+1}else{for(s=u=f[c],i=1;u>=10;u/=10,i++);l=(o=(a%=x)-x+i)<0?0:s/g[i-o-1]%10|0}if(r=r||t<0||null!=f[c+1]||(o<0?s:s%g[i-o-1]),r=n<4?(l||r)&&(0==n||n==(e.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(a>0?o>0?s/g[i-o]:0:f[c-1])%10&1||n==(e.s<0?8:7)),t<1||!f[0])return f.length=0,r?(t-=e.e+1,f[0]=g[(x-t%x)%x],e.e=-t||0):f[0]=e.e=0,e;if(0==a?(f.length=c,u=1,c--):(f.length=c+1,u=g[x-a],f[c]=o>0?h(s/g[i-o]%g[o])*u:0),r)for(;;){if(0==c){for(a=1,o=f[0];o>=10;o/=10,a++);for(o=f[0]+=u,u=1;o>=10;o/=10,u++);a!=u&&(e.e++,f[0]==w&&(f[0]=1));break}if(f[c]+=u,f[c]!=w)break;f[c--]=0,u=1}for(a=f.length;0===f[--a];f.pop());}e.e>V?e.c=e.e=null:e.e<I&&(e.c=[e.e=0])}return e}var L,E,T=0,U=t.prototype,j=new t(1),C=20,R=4,$=-7,P=21,I=-1e7,V=1e7,q=!0,Z=B,z=!1,G=1,W=0,H={decimalSeparator:".",groupSeparator:",",groupSize:3,secondaryGroupSize:0,fractionGroupSeparator:" ",fractionGroupSize:0};return t.another=n,t.ROUND_UP=0,t.ROUND_DOWN=1,t.ROUND_CEIL=2,t.ROUND_FLOOR=3,t.ROUND_HALF_UP=4,t.ROUND_HALF_DOWN=5,t.ROUND_HALF_EVEN=6,t.ROUND_HALF_CEIL=7,t.ROUND_HALF_FLOOR=8,t.EUCLID=9,t.config=t.set=function(){var e,t,n=0,r={},i=arguments,a=i[0],s=a&&"object"==typeof a?function(){if(a.hasOwnProperty(t))return null!=(e=a[t])}:function(){if(i.length>n)return null!=(e=i[n++])};return s(t="DECIMAL_PLACES")&&Z(e,0,M,2,t)&&(C=0|e),r[t]=C,s(t="ROUNDING_MODE")&&Z(e,0,8,2,t)&&(R=0|e),r[t]=R,s(t="EXPONENTIAL_AT")&&(u(e)?Z(e[0],-M,0,2,t)&&Z(e[1],0,M,2,t)&&($=0|e[0],P=0|e[1]):Z(e,-M,M,2,t)&&($=-(P=0|(e<0?-e:e)))),r[t]=[$,P],s(t="RANGE")&&(u(e)?Z(e[0],-M,-1,2,t)&&Z(e[1],1,M,2,t)&&(I=0|e[0],V=0|e[1]):Z(e,-M,M,2,t)&&(0|e?I=-(V=0|(e<0?-e:e)):q&&_(2,t+" cannot be zero",e))),r[t]=[I,V],s(t="ERRORS")&&(e===!!e||1===e||0===e?(T=0,Z=(q=!!e)?B:o):q&&_(2,t+v,e)),r[t]=q,s(t="CRYPTO")&&(!0===e||!1===e||1===e||0===e?e?!(e="undefined"==typeof crypto)&&crypto&&(crypto.getRandomValues||crypto.randomBytes)?z=!0:q?_(2,"crypto unavailable",e?void 0:crypto):z=!1:z=!1:q&&_(2,t+v,e)),r[t]=z,s(t="MODULO_MODE")&&Z(e,0,9,2,t)&&(G=0|e),r[t]=G,s(t="POW_PRECISION")&&Z(e,0,M,2,t)&&(W=0|e),r[t]=W,s(t="FORMAT")&&("object"==typeof e?H=e:q&&_(2,t+" not an object",e)),r[t]=H,r},t.max=function(){return D(arguments,U.lt)},t.min=function(){return D(arguments,U.gt)},t.random=function(){var e=9007199254740992*Math.random()&2097151?function(){return h(9007199254740992*Math.random())}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(n){var r,i,a,o,u,s=0,c=[],l=new t(j);if(n=null!=n&&Z(n,0,M,14)?0|n:C,o=d(n/x),z)if(crypto.getRandomValues){for(r=crypto.getRandomValues(new Uint32Array(o*=2));s<o;)(u=131072*r[s]+(r[s+1]>>>11))>=9e15?(i=crypto.getRandomValues(new Uint32Array(2)),r[s]=i[0],r[s+1]=i[1]):(c.push(u%1e14),s+=2);s=o/2}else if(crypto.randomBytes){for(r=crypto.randomBytes(o*=7);s<o;)(u=281474976710656*(31&r[s])+1099511627776*r[s+1]+4294967296*r[s+2]+16777216*r[s+3]+(r[s+4]<<16)+(r[s+5]<<8)+r[s+6])>=9e15?crypto.randomBytes(7).copy(r,s):(c.push(u%1e14),s+=7);s=o/7}else z=!1,q&&_(14,"crypto unavailable",crypto);if(!z)for(;s<o;)(u=e())<9e15&&(c[s++]=u%1e14);for(o=c[--s],n%=x,o&&n&&(u=N[x-n],c[s]=h(o/u)*u);0===c[s];c.pop(),s--);if(s<0)c=[a=0];else{for(a=-1;0===c[0];c.splice(0,1),a-=x);for(s=1,u=c[0];u>=10;u/=10,s++);s<x&&(a-=x-s)}return l.e=a,l.c=c,l}}(),L=function(){function e(e,t,n){var r,i,a,o,u=0,s=e.length,c=t%O,l=t/O|0;for(e=e.slice();s--;)u=((i=c*(a=e[s]%O)+(r=l*a+(o=e[s]/O|0)*c)%O*O+u)/n|0)+(r/O|0)+l*o,e[s]=i%n;return u&&(e=[u].concat(e)),e}function n(e,t,n,r){var i,a;if(n!=r)a=n>r?1:-1;else for(i=a=0;i<n;i++)if(e[i]!=t[i]){a=e[i]>t[i]?1:-1;break}return a}function i(e,t,n,r){for(var i=0;n--;)e[n]-=i,i=e[n]<t[n]?1:0,e[n]=i*r+e[n]-t[n];for(;!e[0]&&e.length>1;e.splice(0,1));}return function(a,o,u,s,c){var l,f,g,p,d,v,m,y,b,S,N,O,M,F,D,B,k,_=a.s==o.s?1:-1,L=a.c,E=o.c;if(!(L&&L[0]&&E&&E[0]))return new t(a.s&&o.s&&(L?!E||L[0]!=E[0]:E)?L&&0==L[0]||!E?0*_:_/0:NaN);for(b=(y=new t(_)).c=[],_=u+(f=a.e-o.e)+1,c||(c=w,f=r(a.e/x)-r(o.e/x),_=_/x|0),g=0;E[g]==(L[g]||0);g++);if(E[g]>(L[g]||0)&&f--,_<0)b.push(1),p=!0;else{for(F=L.length,B=E.length,g=0,_+=2,(d=h(c/(E[0]+1)))>1&&(E=e(E,d,c),L=e(L,d,c),B=E.length,F=L.length),M=B,N=(S=L.slice(0,B)).length;N<B;S[N++]=0);k=E.slice(),k=[0].concat(k),D=E[0],E[1]>=c/2&&D++;do{if(d=0,(l=n(E,S,B,N))<0){if(O=S[0],B!=N&&(O=O*c+(S[1]||0)),(d=h(O/D))>1)for(d>=c&&(d=c-1),m=(v=e(E,d,c)).length,N=S.length;1==n(v,S,m,N);)d--,i(v,B<m?k:E,m,c),m=v.length,l=1;else 0==d&&(l=d=1),m=(v=E.slice()).length;if(m<N&&(v=[0].concat(v)),i(S,v,N,c),N=S.length,-1==l)for(;n(E,S,B,N)<1;)d++,i(S,B<N?k:E,N,c),N=S.length}else 0===l&&(d++,S=[0]);b[g++]=d,S[0]?S[N++]=L[M]||0:(S=[L[M]],N=1)}while((M++<F||null!=S[0])&&_--);p=null!=S[0],b[0]||b.splice(0,1)}if(c==w){for(g=1,_=b[0];_>=10;_/=10,g++);A(y,u+(y.e=g+f*x-1)+1,s,p)}else y.e=f,y.r=+p;return y}}(),E=function(){var e=/^(-?)0([xbo])(?=\w[\w.]*$)/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,i=/^-?(Infinity|NaN)$/,a=/^\s*\+(?=[\w.])|^\s+|\s+$/g;return function(o,u,s,c){var l,f=s?u:u.replace(a,"");if(i.test(f))o.s=isNaN(f)?null:f<0?-1:1;else{if(!s&&(f=f.replace(e,function(e,t,n){return l="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=l?e:t}),c&&(l=c,f=f.replace(n,"$1").replace(r,"0.$1")),u!=f))return new t(f,l);q&&_(T,"not a"+(c?" base "+c:"")+" number",u),o.s=null}o.c=o.e=null,T=0}}(),U.absoluteValue=U.abs=function(){var e=new t(this);return e.s<0&&(e.s=1),e},U.ceil=function(){return A(new t(this),this.e+1,2)},U.comparedTo=U.cmp=function(e,n){return T=1,a(this,new t(e,n))},U.decimalPlaces=U.dp=function(){var e,t,n=this.c;if(!n)return null;if(e=((t=n.length-1)-r(this.e/x))*x,t=n[t])for(;t%10==0;t/=10,e--);return e<0&&(e=0),e},U.dividedBy=U.div=function(e,n){return T=3,L(this,new t(e,n),C,R)},U.dividedToIntegerBy=U.divToInt=function(e,n){return T=4,L(this,new t(e,n),0,1)},U.equals=U.eq=function(e,n){return T=5,0===a(this,new t(e,n))},U.floor=function(){return A(new t(this),this.e+1,3)},U.greaterThan=U.gt=function(e,n){return T=6,a(this,new t(e,n))>0},U.greaterThanOrEqualTo=U.gte=function(e,n){return T=7,1===(n=a(this,new t(e,n)))||0===n},U.isFinite=function(){return!!this.c},U.isInteger=U.isInt=function(){return!!this.c&&r(this.e/x)>this.c.length-2},U.isNaN=function(){return!this.s},U.isNegative=U.isNeg=function(){return this.s<0},U.isZero=function(){return!!this.c&&0==this.c[0]},U.lessThan=U.lt=function(e,n){return T=8,a(this,new t(e,n))<0},U.lessThanOrEqualTo=U.lte=function(e,n){return T=9,-1===(n=a(this,new t(e,n)))||0===n},U.minus=U.sub=function(e,n){var i,a,o,u,s=this,c=s.s;if(T=10,e=new t(e,n),n=e.s,!c||!n)return new t(NaN);if(c!=n)return e.s=-n,s.plus(e);var l=s.e/x,f=e.e/x,g=s.c,p=e.c;if(!l||!f){if(!g||!p)return g?(e.s=-n,e):new t(p?s:NaN);if(!g[0]||!p[0])return p[0]?(e.s=-n,e):new t(g[0]?s:3==R?-0:0)}if(l=r(l),f=r(f),g=g.slice(),c=l-f){for((u=c<0)?(c=-c,o=g):(f=l,o=p),o.reverse(),n=c;n--;o.push(0));o.reverse()}else for(a=(u=(c=g.length)<(n=p.length))?c:n,c=n=0;n<a;n++)if(g[n]!=p[n]){u=g[n]<p[n];break}if(u&&(o=g,g=p,p=o,e.s=-e.s),(n=(a=p.length)-(i=g.length))>0)for(;n--;g[i++]=0);for(n=w-1;a>c;){if(g[--a]<p[a]){for(i=a;i&&!g[--i];g[i]=n);--g[i],g[a]+=w}g[a]-=p[a]}for(;0==g[0];g.splice(0,1),--f);return g[0]?k(e,g,f):(e.s=3==R?-1:1,e.c=[e.e=0],e)},U.modulo=U.mod=function(e,n){var r,i,a=this;return T=11,e=new t(e,n),!a.c||!e.s||e.c&&!e.c[0]?new t(NaN):!e.c||a.c&&!a.c[0]?new t(a):(9==G?(i=e.s,e.s=1,r=L(a,e,0,3),e.s=i,r.s*=i):r=L(a,e,0,G),a.minus(r.times(e)))},U.negated=U.neg=function(){var e=new t(this);return e.s=-e.s||null,e},U.plus=U.add=function(e,n){var i,a=this,o=a.s;if(T=12,e=new t(e,n),n=e.s,!o||!n)return new t(NaN);if(o!=n)return e.s=-n,a.minus(e);var u=a.e/x,s=e.e/x,c=a.c,l=e.c;if(!u||!s){if(!c||!l)return new t(o/0);if(!c[0]||!l[0])return l[0]?e:new t(c[0]?a:0*o)}if(u=r(u),s=r(s),c=c.slice(),o=u-s){for(o>0?(s=u,i=l):(o=-o,i=c),i.reverse();o--;i.push(0));i.reverse()}for((o=c.length)-(n=l.length)<0&&(i=l,l=c,c=i,n=o),o=0;n;)o=(c[--n]=c[n]+l[n]+o)/w|0,c[n]=w===c[n]?0:c[n]%w;return o&&(c=[o].concat(c),++s),k(e,c,s)},U.precision=U.sd=function(e){var t,n,r=this,i=r.c;if(null!=e&&e!==!!e&&1!==e&&0!==e&&(q&&_(13,"argument"+v,e),e!=!!e&&(e=null)),!i)return null;if(n=i.length-1,t=n*x+1,n=i[n]){for(;n%10==0;n/=10,t--);for(n=i[0];n>=10;n/=10,t++);}return e&&r.e+1>t&&(t=r.e+1),t},U.round=function(e,n){var r=new t(this);return(null==e||Z(e,0,M,15))&&A(r,~~e+this.e+1,null!=n&&Z(n,0,8,15,m)?0|n:R),r},U.shift=function(e){var n=this;return Z(e,-S,S,16,"argument")?n.times("1e"+f(e)):new t(n.c&&n.c[0]&&(e<-S||e>S)?n.s*(e<0?0:1/0):n)},U.squareRoot=U.sqrt=function(){var e,n,a,o,u,s=this,c=s.c,l=s.s,f=s.e,g=C+4,p=new t("0.5");if(1!==l||!c||!c[0])return new t(!l||l<0&&(!c||c[0])?NaN:c?s:1/0);if(0==(l=Math.sqrt(+s))||l==1/0?(((n=i(c)).length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=r((f+1)/2)-(f<0||f%2),a=new t(n=l==1/0?"1e"+f:(n=l.toExponential()).slice(0,n.indexOf("e")+1)+f)):a=new t(l+""),a.c[0])for((l=(f=a.e)+g)<3&&(l=0);;)if(u=a,a=p.times(u.plus(L(s,u,g,1))),i(u.c).slice(0,l)===(n=i(a.c)).slice(0,l)){if(a.e<f&&--l,"9999"!=(n=n.slice(l-3,l+1))&&(o||"4999"!=n)){+n&&(+n.slice(1)||"5"!=n.charAt(0))||(A(a,a.e+C+2,1),e=!a.times(a).eq(s));break}if(!o&&(A(u,u.e+C+2,0),u.times(u).eq(s))){a=u;break}g+=4,l+=4,o=1}return A(a,a.e+C+1,R,e)},U.times=U.mul=function(e,n){var i,a,o,u,s,c,l,f,g,p,d,h,v,m,y,b=this,S=b.c,N=(T=17,e=new t(e,n)).c;if(!(S&&N&&S[0]&&N[0]))return!b.s||!e.s||S&&!S[0]&&!N||N&&!N[0]&&!S?e.c=e.e=e.s=null:(e.s*=b.s,S&&N?(e.c=[0],e.e=0):e.c=e.e=null),e;for(a=r(b.e/x)+r(e.e/x),e.s*=b.s,(l=S.length)<(p=N.length)&&(v=S,S=N,N=v,o=l,l=p,p=o),o=l+p,v=[];o--;v.push(0));for(m=w,y=O,o=p;--o>=0;){for(i=0,d=N[o]%y,h=N[o]/y|0,u=o+(s=l);u>o;)i=((f=d*(f=S[--s]%y)+(c=h*f+(g=S[s]/y|0)*d)%y*y+v[u]+i)/m|0)+(c/y|0)+h*g,v[u--]=f%m;v[u]=i}return i?++a:v.splice(0,1),k(e,v,a)},U.toDigits=function(e,n){var r=new t(this);return e=null!=e&&Z(e,1,M,18,"precision")?0|e:null,n=null!=n&&Z(n,0,8,18,m)?0|n:R,e?A(r,e,n):r},U.toExponential=function(e,t){return F(this,null!=e&&Z(e,0,M,19)?1+~~e:null,t,19)},U.toFixed=function(e,t){return F(this,null!=e&&Z(e,0,M,20)?~~e+this.e+1:null,t,20)},U.toFormat=function(e,t){var n=F(this,null!=e&&Z(e,0,M,21)?~~e+this.e+1:null,t,21);if(this.c){var r,i=n.split("."),a=+H.groupSize,o=+H.secondaryGroupSize,u=H.groupSeparator,s=i[0],c=i[1],l=this.s<0,f=l?s.slice(1):s,g=f.length;if(o&&(r=a,a=o,o=r,g-=r),a>0&&g>0){for(r=g%a||a,s=f.substr(0,r);r<g;r+=a)s+=u+f.substr(r,a);o>0&&(s+=u+f.slice(r)),l&&(s="-"+s)}n=c?s+H.decimalSeparator+((o=+H.fractionGroupSize)?c.replace(new RegExp("\\d{"+o+"}\\B","g"),"$&"+H.fractionGroupSeparator):c):s}return n},U.toFraction=function(e){var n,r,a,o,u,s,c,l,f,g=q,p=this,d=p.c,h=new t(j),v=r=new t(j),m=c=new t(j);if(null!=e&&(q=!1,s=new t(e),q=g,(g=s.isInt())&&!s.lt(j)||(q&&_(22,"max denominator "+(g?"out of range":"not an integer"),e),e=!g&&s.c&&A(s,s.e+1,1).gte(j)?s:null)),!d)return p.toString();for(f=i(d),o=h.e=f.length-p.e-1,h.c[0]=N[(u=o%x)<0?x+u:u],e=!e||s.cmp(h)>0?o>0?h:v:s,u=V,V=1/0,s=new t(f),c.c[0]=0;l=L(s,h,0,1),1!=(a=r.plus(l.times(m))).cmp(e);)r=m,m=a,v=c.plus(l.times(a=v)),c=a,h=s.minus(l.times(a=h)),s=a;return a=L(e.minus(r),m,0,1),c=c.plus(a.times(v)),r=r.plus(a.times(m)),c.s=v.s=p.s,o*=2,n=L(v,m,o,R).minus(p).abs().cmp(L(c,r,o,R).minus(p).abs())<1?[v.toString(),m.toString()]:[c.toString(),r.toString()],V=u,n},U.toNumber=function(){return+this},U.toPower=U.pow=function(e,n){var r,i,a,o=h(e<0?-e:+e),u=this;if(null!=n&&(T=23,n=new t(n)),!Z(e,-S,S,23,"exponent")&&(!isFinite(e)||o>S&&(e/=0)||parseFloat(e)!=e&&!(e=NaN))||0==e)return r=Math.pow(+u,e),new t(n?r%n:r);for(n?e>1&&u.gt(j)&&u.isInt()&&n.gt(j)&&n.isInt()?u=u.mod(n):(a=n,n=null):W&&(r=d(W/x+2)),i=new t(j);;){if(o%2){if(!(i=i.times(u)).c)break;r?i.c.length>r&&(i.c.length=r):n&&(i=i.mod(n))}if(!(o=h(o/2)))break;u=u.times(u),r?u.c&&u.c.length>r&&(u.c.length=r):n&&(u=u.mod(n))}return n?i:(e<0&&(i=j.div(i)),a?i.mod(a):r?A(i,W,R):i)},U.toPrecision=function(e,t){return F(this,null!=e&&Z(e,1,M,24,"precision")?0|e:null,t,24)},U.toString=function(e){var t,n=this,r=n.s,a=n.e;return null===a?r?(t="Infinity",r<0&&(t="-"+t)):t="NaN":(t=i(n.c),t=null!=e&&Z(e,2,64,25,"base")?g(l(t,a),0|e,10,r):a<=$||a>=P?c(t,a):l(t,a),r<0&&n.c[0]&&(t="-"+t)),t},U.truncated=U.trunc=function(){return A(new t(this),this.e+1,1)},U.valueOf=U.toJSON=function(){var e,t=this,n=t.e;return null===n?t.toString():(e=i(t.c),e=n<=$||n>=P?c(e,n):l(e,n),t.s<0?"-"+e:e)},U.isBigNumber=!0,null!=e&&t.config(e),t}function r(e){var t=0|e;return e>0||e===t?t:t-1}function i(e){for(var t,n,r=1,i=e.length,a=e[0]+"";r<i;){for(t=e[r++]+"",n=x-t.length;n--;t="0"+t);a+=t}for(i=a.length;48===a.charCodeAt(--i););return a.slice(0,i+1||1)}function a(e,t){var n,r,i=e.c,a=t.c,o=e.s,u=t.s,s=e.e,c=t.e;if(!o||!u)return null;if(n=i&&!i[0],r=a&&!a[0],n||r)return n?r?0:-u:o;if(o!=u)return o;if(n=o<0,r=s==c,!i||!a)return r?0:!i^n?1:-1;if(!r)return s>c^n?1:-1;for(u=(s=i.length)<(c=a.length)?s:c,o=0;o<u;o++)if(i[o]!=a[o])return i[o]>a[o]^n?1:-1;return s==c?0:s>c^n?1:-1}function o(e,t,n){return(e=f(e))>=t&&e<=n}function u(e){return"[object Array]"==Object.prototype.toString.call(e)}function s(e,t,n){for(var r,i,a=[0],o=0,u=e.length;o<u;){for(i=a.length;i--;a[i]*=t);for(a[r=0]+=b.indexOf(e.charAt(o++));r<a.length;r++)a[r]>n-1&&(null==a[r+1]&&(a[r+1]=0),a[r+1]+=a[r]/n|0,a[r]%=n)}return a.reverse()}function c(e,t){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(t<0?"e":"e+")+t}function l(e,t){var n,r;if(t<0){for(r="0.";++t;r+="0");e=r+e}else if(n=e.length,++t>n){for(r="0",t-=n;--t;r+="0");e+=r}else t<n&&(e=e.slice(0,t)+"."+e.slice(t));return e}function f(e){return(e=parseFloat(e))<0?d(e):h(e)}var g,p=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,d=Math.ceil,h=Math.floor,v=" not a boolean or binary digit",m="rounding mode",y="number type has more than 15 significant digits",b="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",w=1e14,x=14,S=9007199254740991,N=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],O=1e7,M=1e9;(g=n()).default=g.BigNumber=g,void 0!==t&&t.exports?t.exports=g:(e||(e="undefined"!=typeof self?self:Function("return this")()),e.BigNumber=g)}(this)},{}],2:[function(e,t,n){"use strict";t.exports={languageTag:"en-US",delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},spaceSeparated:!1,ordinal:function(e){var t=e%10;return 1==~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th"},currency:{symbol:"$",position:"prefix",code:"USD"},currencyFormat:{thousandSeparated:!0,totalLength:4,spaceSeparated:!0},formats:{fourDigits:{totalLength:4,spaceSeparated:!0},fullWithTwoDecimals:{output:"currency",thousandSeparated:!0,mantissa:2},fullWithTwoDecimalsNoCurrency:{thousandSeparated:!0,mantissa:2},fullWithNoDecimals:{output:"currency",thousandSeparated:!0,mantissa:0}}}},{}],3:[function(e,t,n){"use strict";function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments[2];if("string"==typeof t&&(t=L.parseFormat(t)),!A.validateFormat(t))return"ERROR: invalid format";var r=t.prefix||"",a=t.postfix||"",o=i(e,t,n);return o=M(o,r),o=F(o,a)}function i(e,t,n){switch(t.output){case"currency":return t=B(t,_.currentCurrencyDefaultFormat()),p(e,t,_);case"percent":return t=B(t,_.currentPercentageDefaultFormat()),g(e,t,_,n);case"byte":return t=B(t,_.currentByteDefaultFormat()),c(e,t,_,n);case"time":return t=B(t,_.currentTimeDefaultFormat()),f(e);case"ordinal":return t=B(t,_.currentOrdinalDefaultFormat()),l(e,t,_);case"number":default:return D({instance:e,providedFormat:t,numbro:n})}}function a(e){var t=T.decimal;return s(e._value,t.suffixes,t.scale).suffix}function o(e){var t=T.binary;return s(e._value,t.suffixes,t.scale).suffix}function u(e){var t=T.general;return s(e._value,t.suffixes,t.scale).suffix}function s(e,t,n){var r=t[0],i=Math.abs(e);if(i>=n){for(var a=1;a<t.length;++a){var o=Math.pow(n,a),u=Math.pow(n,a+1);if(i>=o&&i<u){r=t[a],e/=o;break}}r===t[0]&&(e/=Math.pow(n,t.length-1),r=t[t.length-1])}return{value:e,suffix:r}}function c(e,t,n,r){var i=t.base||"binary",a=T[i],o=s(e._value,a.suffixes,a.scale),u=o.value,c=o.suffix;return D({instance:r(u),providedFormat:t,state:n,defaults:n.currentByteDefaultFormat()})+(n.currentAbbreviations().spaced?" ":"")+c}function l(e,t,n){var r=n.currentOrdinal(),i=Object.assign({},U,t),a=D({instance:e,providedFormat:t,state:n}),o=r(e._value);return a+(i.spaceSeparated?" ":"")+o}function f(e){var t=Math.floor(e._value/60/60),n=Math.floor((e._value-60*t*60)/60),r=Math.round(e._value-60*t*60-60*n);return t+":"+(n<10?"0":"")+n+":"+(r<10?"0":"")+r}function g(e,t,n,r){var i=t.prefixSymbol,a=D({instance:r(100*e._value),providedFormat:t,state:n}),o=Object.assign({},U,t);return i?"%"+(o.spaceSeparated?" ":"")+a:a+(o.spaceSeparated?" ":"")+"%"}function p(e,t,n){var r=n.currentCurrency(),i=Object.assign({},U,t),a=void 0,o="",u=!!i.totalLength||!!i.forceAverage||i.average,s=t.currencyPosition||r.position,c=t.currencySymbol||r.symbol;i.spaceSeparated&&(o=" "),"infix"===s&&(a=o+c+o);var l=D({instance:e,providedFormat:t,state:n,decimalSeparator:a});return"prefix"===s&&(l=e._value<0&&"sign"===i.negative?"-"+o+c+l.slice(1):c+o+l),s&&"postfix"!==s||(l=l+(o=u?"":o)+c),l}function d(e){var t=e.value,n=e.forceAverage,r=e.abbreviations,i=e.spaceSeparated,a=void 0!==i&&i,o=e.totalLength,u=void 0===o?0:o,s="",c=Math.abs(t),l=-1;c>=Math.pow(10,12)&&!n||"trillion"===n?(s=r.trillion,t/=Math.pow(10,12)):c<Math.pow(10,12)&&c>=Math.pow(10,9)&&!n||"billion"===n?(s=r.billion,t/=Math.pow(10,9)):c<Math.pow(10,9)&&c>=Math.pow(10,6)&&!n||"million"===n?(s=r.million,t/=Math.pow(10,6)):(c<Math.pow(10,6)&&c>=Math.pow(10,3)&&!n||"thousand"===n)&&(s=r.thousand,t/=Math.pow(10,3));var f=a?" ":"";if(s&&(s=f+s),u){var g=t.toString().split(".")[0];l=Math.max(u-g.length,0)}return{value:t,abbreviation:s,mantissaPrecision:l}}function h(e){var t=e.value,n=e.characteristicPrecision,r=void 0===n?0:n,i=t.toExponential().split("e"),a=k(i,2),o=a[0],u=a[1],s=+o;if(!r)return{value:s,abbreviation:"e"+u};return 1<r&&(s*=Math.pow(10,r-1),u=(u=+u-(r-1))>=0?"+"+u:u),{value:s,abbreviation:"e"+u}}function v(e){for(var t="",n=0;n<e;n++)t+="0";return t}function m(e,t){var n=e.toString(),r=n.split("e"),i=k(r,2),a=i[0],o=i[1],u=a.split("."),s=k(u,2),c=s[0],l=s[1],f=void 0===l?"":l;if(+o>0)n=c+f+v(o-f.length);else{var g=".";g=+c<0?"-0"+g:"0"+g;var p=(v(-o-1)+Math.abs(c)+f).substr(0,t);p.length<t&&(p+=v(t-p.length)),n=g+p}return+o>0&&t>0&&(n+="."+v(t)),n}function y(e,t){return-1!==e.toString().indexOf("e")?m(e,t):(Math.round(+(e+"e+"+t))/Math.pow(10,t)).toFixed(t)}function b(e,t,n,r,i){if(-1===r)return e;var a=y(t,r),o=a.toString().split("."),u=k(o,2),s=u[0],c=u[1],l=void 0===c?"":c;if(l.match(/^0+$/)&&(n||i))return s;var f=l.match(/0+$/);return i&&f?s+"."+l.toString().slice(0,f.index):a.toString()}function w(e,t,n,r){var i=e,a=i.toString().split("."),o=k(a,2),u=o[0],s=o[1];if(u.match(/^-?0$/)&&n)return s?u.replace("0","")+"."+s:u.replace("0","");if(u.length<r)for(var c=r-u.length,l=0;l<c;l++)i="0"+i;return i.toString()}function x(e,t){for(var n=[],r=0,i=e;i>0;i--)r===t&&(n.unshift(i),r=0),r++;return n}function S(e,t,n,r,i){var a=r.currentDelimiters(),o=a.thousands;i=i||a.decimal;var u=a.thousandsSize||3,s=e.toString(),c=s.split(".")[0],l=s.split(".")[1];return n&&(t<0&&(c=c.slice(1)),x(c.length,u).forEach(function(e,t){c=c.slice(0,e+t)+o+c.slice(e+t)}),t<0&&(c="-"+c)),s=l?c+i+l:c}function N(e,t){return e+t}function O(e,t,n){return 0===t?e:0==+e?e.replace("-",""):t>0?"+"+e:"sign"===n?e:"("+e.replace("-","")+")"}function M(e,t){return t+e}function F(e,t){return e+t}function D(e){var t=e.instance,n=e.providedFormat,r=e.state,i=void 0===r?_:r,a=e.decimalSeparator,o=e.defaults,u=void 0===o?i.currentDefaults():o,s=t._value;if(0===s&&i.hasZeroFormat())return i.getZeroFormat();if(!isFinite(s))return s.toString();var c=Object.assign({},U,u,n),l=c.totalLength,f=l?0:c.characteristic,g=c.optionalCharacteristic,p=c.forceAverage,v=!!l||!!p||c.average,m=l?-1:v&&void 0===n.mantissa?0:c.mantissa,y=!l&&(void 0===n.optionalMantissa?-1===m:c.optionalMantissa),x=c.trimMantissa,M=c.thousandSeparated,F=c.spaceSeparated,D=c.negative,B=c.forceSign,k=c.exponential,A="";if(v){var L=d({value:s,forceAverage:p,abbreviations:i.currentAbbreviations(),spaceSeparated:F,totalLength:l});s=L.value,A+=L.abbreviation,l&&(m=L.mantissaPrecision)}if(k){var E=h({value:s,characteristicPrecision:f});s=E.value,A=E.abbreviation+A}var T=b(s.toString(),s,y,m,x);return T=w(T,s,g,f),T=S(T,s,M,i,a),(v||k)&&(T=N(T,A)),(B||s<0)&&(T=O(T,s,D)),T}function B(e,t){if(!e)return t;var n=Object.keys(e);return 1===n.length&&"output"===n[0]?t:e}var k=function(){function e(e,t){var n=[],r=!0,i=!1,a=void 0;try{for(var o,u=e[Symbol.iterator]();!(r=(o=u.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{!r&&u.return&&u.return()}finally{if(i)throw a}}return n}return function(t,n){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),_=e("./globalState"),A=e("./validating"),L=e("./parsing"),E=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],T={general:{scale:1024,suffixes:E,marker:"bd"},binary:{scale:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],marker:"b"},decimal:{scale:1e3,suffixes:E,marker:"d"}},U={totalLength:0,characteristic:0,forceAverage:!1,average:!1,mantissa:-1,optionalMantissa:!0,thousandSeparated:!1,spaceSeparated:!1,negative:"sign",forceSign:!1};t.exports=function(e){return{format:function(){for(var t=arguments.length,n=Array(t),i=0;i<t;i++)n[i]=arguments[i];return r.apply(void 0,n.concat([e]))},getByteUnit:function(){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];return u.apply(void 0,n.concat([e]))},getBinaryByteUnit:function(){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];return o.apply(void 0,n.concat([e]))},getDecimalByteUnit:function(){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];return a.apply(void 0,n.concat([e]))},formatOrDefault:B}}},{"./globalState":4,"./parsing":8,"./validating":10}],4:[function(e,t,n){"use strict";function r(e){c=e}function i(){return l[c]}var a=e("./en-US"),o=e("./validating"),u=e("./parsing"),s={},c=void 0,l={},f=null,g={};s.languages=function(){return Object.assign({},l)},s.currentLanguage=function(){return c},s.currentCurrency=function(){return i().currency},s.currentAbbreviations=function(){return i().abbreviations},s.currentDelimiters=function(){return i().delimiters},s.currentOrdinal=function(){return i().ordinal},s.currentDefaults=function(){return Object.assign({},i().defaults,g)},s.currentOrdinalDefaultFormat=function(){return Object.assign({},s.currentDefaults(),i().ordinalFormat)},s.currentByteDefaultFormat=function(){return Object.assign({},s.currentDefaults(),i().byteFormat)},s.currentPercentageDefaultFormat=function(){return Object.assign({},s.currentDefaults(),i().percentageFormat)},s.currentCurrencyDefaultFormat=function(){return Object.assign({},s.currentDefaults(),i().currencyFormat)},s.currentTimeDefaultFormat=function(){return Object.assign({},s.currentDefaults(),i().timeFormat)},s.setDefaults=function(e){e=u.parseFormat(e),o.validateFormat(e)&&(g=e)},s.getZeroFormat=function(){return f},s.setZeroFormat=function(e){return f="string"==typeof e?e:null},s.hasZeroFormat=function(){return null!==f},s.languageData=function(e){if(e){if(l[e])return l[e];throw new Error('Unknown tag "'+e+'"')}return i()},s.registerLanguage=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!o.validateLanguage(e))throw new Error("Invalid language data");l[e.languageTag]=e,t&&r(e.languageTag)},s.setLanguage=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a.languageTag;if(!l[e]){var n=e.split("-")[0],i=Object.keys(l).find(function(e){return e.split("-")[0]===n});return l[i]?void r(i):void r(t)}r(e)},s.registerLanguage(a),c=a.languageTag,t.exports=s},{"./en-US":2,"./parsing":8,"./validating":10}],5:[function(e,t,n){"use strict";function r(t,n){t.forEach(function(t){var r=void 0;try{r=e("../languages/"+t)}catch(e){console.error('Unable to load "'+t+'". No matching language file found.')}r&&n.registerLanguage(r)})}t.exports=function(e){return{loadLanguagesInNode:function(t){return r(t,e)}}}},{}],6:[function(e,t,n){"use strict";function r(e,t,n){var r=new c(e._value),i=t;return n.isNumbro(t)&&(i=t._value),i=new c(i),e._value=r.add(i).toNumber(),e}function i(e,t,n){var r=new c(e._value),i=t;return n.isNumbro(t)&&(i=t._value),i=new c(i),e._value=r.minus(i).toNumber(),e}function a(e,t,n){var r=new c(e._value),i=t;return n.isNumbro(t)&&(i=t._value),i=new c(i),e._value=r.times(i).toNumber(),e}function o(e,t,n){var r=new c(e._value),i=t;return n.isNumbro(t)&&(i=t._value),i=new c(i),e._value=r.dividedBy(i).toNumber(),e}function u(e,t,n){var r=t;return n.isNumbro(t)&&(r=t._value),e._value=r,e}function s(e,t,n){var r=n(e._value);return i(r,t,n),Math.abs(r._value)}var c=e("bignumber.js");t.exports=function(e){return{add:function(t,n){return r(t,n,e)},subtract:function(t,n){return i(t,n,e)},multiply:function(t,n){return a(t,n,e)},divide:function(t,n){return o(t,n,e)},set:function(t,n){return u(t,n,e)},difference:function(t,n){return s(t,n,e)}}}},{"bignumber.js":1}],7:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e){var t=e;return a.isNumbro(e)?t=e._value:"string"==typeof e?t=a.unformat(e):isNaN(e)&&(t=NaN),t}function a(e){return new d(i(e))}var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=e("./globalState"),s=e("./validating"),c=e("./loading")(a),l=e("./unformatting"),f=e("./formatting")(a),g=e("./manipulating")(a),p=e("./parsing"),d=function(){function e(t){r(this,e),this._value=t}return o(e,[{key:"clone",value:function(){return a(this._value)}},{key:"format",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return f.format(this,e)}},{key:"formatCurrency",value:function(e){return"string"==typeof e&&(e=p.parseFormat(e)),e=f.formatOrDefault(e,u.currentCurrencyDefaultFormat()),e.output="currency",f.format(this,e)}},{key:"formatTime",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e.output="time",f.format(this,e)}},{key:"binaryByteUnits",value:function(){return f.getBinaryByteUnit(this)}},{key:"decimalByteUnits",value:function(){return f.getDecimalByteUnit(this)}},{key:"byteUnits",value:function(){return f.getByteUnit(this)}},{key:"difference",value:function(e){return g.difference(this,e)}},{key:"add",value:function(e){return g.add(this,e)}},{key:"subtract",value:function(e){return g.subtract(this,e)}},{key:"multiply",value:function(e){return g.multiply(this,e)}},{key:"divide",value:function(e){return g.divide(this,e)}},{key:"set",value:function(e){return g.set(this,i(e))}},{key:"value",value:function(){return this._value}},{key:"valueOf",value:function(){return this._value}}]),e}();a.version="2.1.1",a.isNumbro=function(e){return e instanceof d},a.language=u.currentLanguage,a.registerLanguage=u.registerLanguage,a.setLanguage=u.setLanguage,a.languages=u.languages,a.languageData=u.languageData,a.zeroFormat=u.setZeroFormat,a.defaultFormat=u.currentDefaults,a.setDefaults=u.setDefaults,a.defaultCurrencyFormat=u.currentCurrencyDefaultFormat,a.validate=s.validate,a.loadLanguagesInNode=c.loadLanguagesInNode,a.unformat=l.unformat,t.exports=a},{"./formatting":3,"./globalState":4,"./loading":5,"./manipulating":6,"./parsing":8,"./unformatting":9,"./validating":10}],8:[function(e,t,n){"use strict";function r(e,t){var n=e.match(/^{([^}]*)}/);return n?(t.prefix=n[1],e.slice(n[0].length)):e}function i(e,t){var n=e.match(/{([^}]*)}$/);return n?(t.postfix=n[1],e.slice(0,-n[0].length)):e}function a(e,t){if(-1===e.indexOf("$")){if(-1===e.indexOf("%"))return-1!==e.indexOf("bd")?(t.output="byte",void(t.base="general")):-1!==e.indexOf("b")?(t.output="byte",void(t.base="binary")):-1!==e.indexOf("d")?(t.output="byte",void(t.base="decimal")):void(-1===e.indexOf(":")?-1!==e.indexOf("o")&&(t.output="ordinal"):t.output="time");t.output="percent"}else t.output="currency"}function o(e,t){-1!==e.indexOf(",")&&(t.thousandSeparated=!0)}function u(e,t){-1!==e.indexOf(" ")&&(t.spaceSeparated=!0)}function s(e,t){var n=e.match(/[1-9]+[0-9]*/);n&&(t.totalLength=+n[0])}function c(e,t){var n=e.split(".")[0].match(/0+/);n&&(t.characteristic=n[0].length)}function l(e,t){var n=e.split(".")[1];if(n){var r=n.match(/0+/);r&&(t.mantissa=r[0].length)}}function f(e,t){-1!==e.indexOf("a")&&(t.average=!0)}function g(e,t){-1!==e.indexOf("K")?t.forceAverage="thousand":-1!==e.indexOf("M")?t.forceAverage="million":-1!==e.indexOf("B")?t.forceAverage="billion":-1!==e.indexOf("T")&&(t.forceAverage="trillion")}function p(e,t){e.match(/\[\.]/)?t.optionalMantissa=!0:e.match(/\./)&&(t.optionalMantissa=!1)}function d(e,t){if(-1!==e.indexOf(".")){var n=e.split(".")[0];t.optionalCharacteristic=-1===n.indexOf("0")}}function h(e,t){e.match(/^\+?\([^)]*\)$/)&&(t.negative="parenthesis"),e.match(/^\+?-/)&&(t.negative="sign")}function v(e,t){e.match(/^\+/)&&(t.forceSign=!0)}t.exports={parseFormat:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return"string"!=typeof e?e:(e=r(e,t),e=i(e,t),a(e,t),s(e,t),c(e,t),d(e,t),f(e,t),g(e,t),l(e,t),p(e,t),o(e,t),u(e,t),h(e,t),v(e,t),t)}}},{}],9:[function(e,t,n){"use strict";function r(e){return e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")}function i(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",a=arguments[3],o=arguments[4],u=arguments[5],s=arguments[6];if(!isNaN(+e))return+e;var l="",f=e.replace(/(^[^(]*)\((.*)\)([^)]*$)/,"$1$2$3");if(f!==e)return-1*i(f,t,n,a,o,u,s);for(var g=0;g<c.length;g++){var p=c[g];if((l=e.replace(p.key,""))!==e)return i(l,t,n,a,o,u,s)*p.factor}if((l=e.replace("%",""))!==e)return i(l,t,n,a,o,u,s)/100;var d=parseFloat(e);if(!isNaN(d)){var h=a(d);if(h&&"."!==h&&(l=e.replace(new RegExp(r(h)+"$"),""))!==e)return i(l,t,n,a,o,u,s);var v={};Object.keys(u).forEach(function(e){v[u[e]]=e});for(var m=Object.keys(v).sort().reverse(),y=m.length,b=0;b<y;b++){var w=m[b],x=v[w];if((l=e.replace(w,""))!==e){var S=void 0;switch(x){case"thousand":S=Math.pow(10,3);break;case"million":S=Math.pow(10,6);break;case"billion":S=Math.pow(10,9);break;case"trillion":S=Math.pow(10,12)}return i(l,t,n,a,o,u,s)*S}}}}function a(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=e.replace(n,"");return i=i.replace(new RegExp("([0-9])"+r(t.thousands)+"([0-9])","g"),"$1$2"),i=i.replace(t.decimal,".")}function o(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",r=arguments[3],o=arguments[4],u=arguments[5],s=arguments[6];if(""!==e)return isNaN(+e)?e===o?0:i(a(e,t,n),t,n,r,o,u,s):+e}function u(e,t){if(!(e.indexOf(":")&&":"!==t.thousands))return!1;var n=e.split(":");if(3!==n.length)return!1;var r=+n[0],i=+n[1],a=+n[2];return!isNaN(r)&&!isNaN(i)&&!isNaN(a)}function s(e){var t=e.split(":"),n=+t[0],r=+t[1];return+t[2]+60*r+3600*n}var c=[{key:"ZiB",factor:Math.pow(1024,7)},{key:"ZB",factor:Math.pow(1e3,7)},{key:"YiB",factor:Math.pow(1024,8)},{key:"YB",factor:Math.pow(1e3,8)},{key:"TiB",factor:Math.pow(1024,4)},{key:"TB",factor:Math.pow(1e3,4)},{key:"PiB",factor:Math.pow(1024,5)},{key:"PB",factor:Math.pow(1e3,5)},{key:"MiB",factor:Math.pow(1024,2)},{key:"MB",factor:Math.pow(1e3,2)},{key:"KiB",factor:Math.pow(1024,1)},{key:"KB",factor:Math.pow(1e3,1)},{key:"GiB",factor:Math.pow(1024,3)},{key:"GB",factor:Math.pow(1e3,3)},{key:"EiB",factor:Math.pow(1024,6)},{key:"EB",factor:Math.pow(1e3,6)},{key:"B",factor:1}];t.exports={unformat:function(t,n){var r=e("./globalState"),i=r.currentDelimiters(),a=r.currentCurrency().symbol,c=r.currentOrdinal(),l=r.getZeroFormat(),f=r.currentAbbreviations(),g=void 0;if("string"==typeof t)g=u(t,i)?s(t):o(t,i,a,c,l,f,n);else{if("number"!=typeof t)return;g=t}if(void 0!==g)return g}}},{"./globalState":4}],10:[function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}function i(e){return!!s.unformat(e)}function a(e,t,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3],o=Object.keys(e).map(function(r){if(!t[r])return console.error(n+" Invalid key: "+r),!1;var i=e[r],o=t[r];if("string"==typeof o&&(o={type:o}),"format"===o.type){if(!a(i,l,"[Validate "+r+"]",!0))return!1}else if((void 0===i?"undefined":u(i))!==o.type)return console.error(n+" "+r+' type mismatched: "'+o.type+'" expected, "'+(void 0===i?"undefined":u(i))+'" provided'),!1;if(o.restrictions&&o.restrictions.length)for(var s=o.restrictions.length,c=0;c<s;c++){var f=o.restrictions[c],g=f.restriction,p=f.message;if(!g(i,e))return console.error(n+" "+r+" invalid value: "+p),!1}return o.restriction&&!o.restriction(i,e)?(console.error(n+" "+r+" invalid value: "+o.message),!1):o.validValues&&-1===o.validValues.indexOf(i)?(console.error(n+" "+r+" invalid value: must be among "+JSON.stringify(o.validValues)+', "'+i+'" provided'),!1):!(o.children&&!a(i,o.children,"[Validate "+r+"]"))});return i||o.push.apply(o,r(Object.keys(t).map(function(r){var i=t[r];if("string"==typeof i&&(i={type:i}),i.mandatory){var a=i.mandatory;if("function"==typeof a&&(a=a(e)),a&&void 0===e[r])return console.error(n+' Missing mandatory key "'+r+'"'),!1}return!0}))),o.reduce(function(e,t){return e&&t},!0)}function o(e){return a(e,l,"[Validate format]")}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s=e("./unformatting"),c=/^[a-z]{2,3}(-[a-zA-Z]{4})?(-([A-Z]{2}|[0-9]{3}))?$/,l={output:{type:"string",validValues:["currency","percent","byte","time","ordinal","number"]},base:{type:"string",validValues:["decimal","binary","general"],restriction:function(e,t){return"byte"===t.output},message:"`base` must be provided only when the output is `byte`",mandatory:function(e){return"byte"===e.output}},characteristic:{type:"number",restriction:function(e){return e>=0},message:"value must be positive"},prefix:"string",postfix:"string",forceAverage:{type:"string",validValues:["trillion","billion","million","thousand"]},average:"boolean",currencyPosition:{type:"string",validValues:["prefix","infix","postfix"]},currencySymbol:"string",totalLength:{type:"number",restrictions:[{restriction:function(e){return e>=0},message:"value must be positive"},{restriction:function(e,t){return!t.exponential},message:"`totalLength` is incompatible with `exponential`"}]},mantissa:{type:"number",restriction:function(e){return e>=0},message:"value must be positive"},optionalMantissa:"boolean",trimMantissa:"boolean",optionalCharacteristic:"boolean",thousandSeparated:"boolean",spaceSeparated:"boolean",abbreviations:{type:"object",children:{thousand:"string",million:"string",billion:"string",trillion:"string"}},negative:{type:"string",validValues:["sign","parenthesis"]},forceSign:"boolean",exponential:{type:"boolean"},prefixSymbol:{type:"boolean",restriction:function(e,t){return"percent"===t.output},message:"`prefixSymbol` can be provided only when the output is `percent`"}},f={languageTag:{type:"string",mandatory:!0,restriction:function(e){return e.match(c)},message:"the language tag must follow the BCP 47 specification (see https://tools.ieft.org/html/bcp47)"},delimiters:{type:"object",children:{thousands:"string",decimal:"string",thousandsSize:"number"},mandatory:!0},abbreviations:{type:"object",children:{thousand:{type:"string",mandatory:!0},million:{type:"string",mandatory:!0},billion:{type:"string",mandatory:!0},trillion:{type:"string",mandatory:!0}},mandatory:!0},spaceSeparated:"boolean",ordinal:{type:"function",mandatory:!0},currency:{type:"object",children:{symbol:"string",position:"string",code:"string"},mandatory:!0},defaults:"format",ordinalFormat:"format",byteFormat:"format",percentageFormat:"format",currencyFormat:"format",timeDefaults:"format",formats:{type:"object",children:{fourDigits:{type:"format",mandatory:!0},fullWithTwoDecimals:{type:"format",mandatory:!0},fullWithTwoDecimalsNoCurrency:{type:"format",mandatory:!0},fullWithNoDecimals:{type:"format",mandatory:!0}}}};t.exports={validate:function(e,t){var n=i(e),r=o(t);return n&&r},validateFormat:o,validateInput:i,validateLanguage:function(e){return a(e,f,"[Validate language]")}}},{"./unformatting":9}]},{},[7])(7)});
//# sourceMappingURL=numbro.min.js.map


/*** EXPORTS FROM exports-to-window-loader ***/
window['numbro'] = __webpack_require__(466);

/***/ }),
/* 467 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var anObject = __webpack_require__(45);
var requireObjectCoercible = __webpack_require__(58);
var sameValue = __webpack_require__(556);
var regExpExec = __webpack_require__(128);

// @@search logic
__webpack_require__(129)(
  'search',
  1,
  function (SEARCH, nativeSearch, maybeCallNative) {
    return [
      // `String.prototype.search` method
      // https://tc39.github.io/ecma262/#sec-string.prototype.search
      function search(regexp) {
        var O = requireObjectCoercible(this);
        var searcher = regexp == undefined ? undefined : regexp[SEARCH];
        return searcher !== undefined ? searcher.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
      },
      // `RegExp.prototype[@@search]` method
      // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search
      function (regexp) {
        var res = maybeCallNative(nativeSearch, regexp, this);
        if (res.done) return res.value;

        var rx = anObject(regexp);
        var S = String(this);

        var previousLastIndex = rx.lastIndex;
        if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;
        var result = regExpExec(rx, S);
        if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;
        return result === null ? -1 : result.index;
      }
    ];
  }
);


/***/ }),
/* 468 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.getNormalizedDate = getNormalizedDate;

/* eslint-disable import/prefer-default-export */

/**
 * Get normalized Date object for the ISO formatted date strings.
 * Natively, the date object parsed from a ISO 8601 string will be offsetted by the timezone difference, which may result in returning a wrong date.
 * See: Github issue #3338.
 *
 * @param {String} dateString String representing the date.
 * @returns {Date} The proper Date object.
 */
function getNormalizedDate(dateString) {
  var nativeDate = new Date(dateString); // NaN if dateString is not in ISO format

  if (!isNaN(new Date("".concat(dateString, "T00:00")).getDate())) {
    // Compensate timezone offset
    return new Date(nativeDate.getTime() + nativeDate.getTimezoneOffset() * 60000);
  }

  return nativeDate;
}

/***/ }),
/* 469 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(12);

__webpack_require__(37);

__webpack_require__(46);

/**
 * SheetClip - Spreadsheet Clipboard Parser
 * version 0.2
 *
 * This tiny library transforms JavaScript arrays to strings that are pasteable by LibreOffice, OpenOffice,
 * Google Docs and Microsoft Excel.
 *
 * Copyright 2012, Marcin Warpechowski
 * Licensed under the MIT license.
 * http://github.com/warpech/sheetclip/
 */

/*jslint white: true*/
(function (global) {
  "use strict";

  function countQuotes(str) {
    return str.split('"').length - 1;
  }

  var SheetClip = {
    /**
     * Decode spreadsheet string into array
     *
     * @param {String} str
     * @returns {Array}
     */
    parse: function parse(str) {
      var r,
          rLen,
          rows,
          arr = [],
          a = 0,
          c,
          cLen,
          multiline,
          last;
      rows = str.replace(/\r\n|\r/g, '\n').split('\n');

      if (rows.length > 1 && rows[rows.length - 1] === '') {
        rows.pop();
      }

      for (r = 0, rLen = rows.length; r < rLen; r += 1) {
        rows[r] = rows[r].split('\t');

        for (c = 0, cLen = rows[r].length; c < cLen; c += 1) {
          if (!arr[a]) {
            arr[a] = [];
          }

          if (multiline && c === 0) {
            last = arr[a].length - 1;
            arr[a][last] = arr[a][last] + '\n' + rows[r][0];

            if (multiline && countQuotes(rows[r][0]) & 1) {
              //& 1 is a bitwise way of performing mod 2
              multiline = false;
              arr[a][last] = arr[a][last].substring(0, arr[a][last].length - 1).replace(/""/g, '"');
            }
          } else {
            if (c === cLen - 1 && rows[r][c].indexOf('"') === 0 && countQuotes(rows[r][c]) & 1) {
              arr[a].push(rows[r][c].substring(1).replace(/""/g, '"'));
              multiline = true;
            } else {
              arr[a].push(rows[r][c].replace(/""/g, '"'));
              multiline = false;
            }
          }
        }

        if (!multiline) {
          a += 1;
        }
      }

      return arr;
    },

    /**
     * Encode array into valid spreadsheet string
     *
     * @param arr
     * @returns {String}
     */
    stringify: function stringify(arr) {
      var r,
          rLen,
          c,
          cLen,
          str = '',
          val;

      for (r = 0, rLen = arr.length; r < rLen; r += 1) {
        cLen = arr[r].length;

        for (c = 0; c < cLen; c += 1) {
          if (c > 0) {
            str += '\t';
          }

          val = arr[r][c];

          if (typeof val === 'string') {
            if (val.indexOf('\n') > -1) {
              str += '"' + val.replace(/"/g, '""') + '"';
            } else {
              str += val;
            }
          } else if (val === null || val === void 0) {
            // void 0 resolves to undefined
            str += '';
          } else {
            str += val;
          }
        }

        if (r !== rLen - 1) {
          str += '\n';
        }
      }

      return str;
    }
  };

  if (true) {
    exports.parse = SheetClip.parse;
    exports.stringify = SheetClip.stringify;
  } else {}
})(window);

/***/ }),
/* 470 */
/***/ (function(module, exports, __webpack_require__) {

var toObject = __webpack_require__(62);
var nativeGetPrototypeOf = __webpack_require__(145);
var CORRECT_PROTOTYPE_GETTER = __webpack_require__(183);
var FAILS_ON_PRIMITIVES = __webpack_require__(29)(function () { nativeGetPrototypeOf(1); });

// `Object.getPrototypeOf` method
// https://tc39.github.io/ecma262/#sec-object.getprototypeof
__webpack_require__(22)({
  target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES, sham: !CORRECT_PROTOTYPE_GETTER
}, {
  getPrototypeOf: function getPrototypeOf(it) {
    return nativeGetPrototypeOf(toObject(it));
  }
});



/***/ }),
/* 471 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.mouseDown = mouseDown;
exports.mouseOver = mouseOver;
exports.handleMouseEvent = handleMouseEvent;

var _event = __webpack_require__(31);

var _src = __webpack_require__(25);

/**
 * MouseDown handler.
 *
 * @param {Object} options
 * @param {Boolean} options.isShiftKey The flag which indicates if the shift key is pressed.
 * @param {Boolean} options.isLeftClick The flag which indicates if the left mouse button is pressed.
 * @param {Boolean} options.isRightClick The flag which indicates if the right mouse button is pressed.
 * @param {CellRange} options.coords The CellCoords object with defined visual coordinates.
 * @param {Selection} options.selection The Selection class instance.
 * @param {Object} options.controller An object with keys `row`, `column`, `cell` which indicate what
 *                                    operation will be performed in later selection stages.
 */
function mouseDown(_ref) {
  var isShiftKey = _ref.isShiftKey,
      isLeftClick = _ref.isLeftClick,
      isRightClick = _ref.isRightClick,
      coords = _ref.coords,
      selection = _ref.selection,
      controller = _ref.controller;
  var currentSelection = selection.isSelected() ? selection.getSelectedRange().current() : null;
  var selectedCorner = selection.isSelectedByCorner();
  var selectedRow = selection.isSelectedByRowHeader();

  if (isShiftKey && currentSelection) {
    if (coords.row >= 0 && coords.col >= 0 && !controller.cells) {
      selection.setRangeEnd(coords);
    } else if ((selectedCorner || selectedRow) && coords.row >= 0 && coords.col >= 0 && !controller.cells) {
      selection.setRangeEnd(new _src.CellCoords(coords.row, coords.col));
    } else if (selectedCorner && coords.row < 0 && !controller.column) {
      selection.setRangeEnd(new _src.CellCoords(currentSelection.to.row, coords.col));
    } else if (selectedRow && coords.col < 0 && !controller.row) {
      selection.setRangeEnd(new _src.CellCoords(coords.row, currentSelection.to.col));
    } else if ((!selectedCorner && !selectedRow && coords.col < 0 || selectedCorner && coords.col < 0) && !controller.row) {
      selection.selectRows(currentSelection.from.row, coords.row);
    } else if ((!selectedCorner && !selectedRow && coords.row < 0 || selectedRow && coords.row < 0) && !controller.column) {
      selection.selectColumns(currentSelection.from.col, coords.col);
    }
  } else {
    var newCoord = new _src.CellCoords(coords.row, coords.col);

    if (newCoord.row < 0) {
      newCoord.row = 0;
    }

    if (newCoord.col < 0) {
      newCoord.col = 0;
    }

    var allowRightClickSelection = !selection.inInSelection(newCoord);
    var performSelection = isLeftClick || isRightClick && allowRightClickSelection; // clicked row header and when some column was selected

    if (coords.row < 0 && coords.col >= 0 && !controller.column) {
      if (performSelection) {
        selection.selectColumns(coords.col);
      } // clicked column header and when some row was selected

    } else if (coords.col < 0 && coords.row >= 0 && !controller.row) {
      if (performSelection) {
        selection.selectRows(coords.row);
      }
    } else if (coords.col >= 0 && coords.row >= 0 && !controller.cells) {
      if (performSelection) {
        selection.setRangeStart(coords);
      }
    } else if (coords.col < 0 && coords.row < 0) {
      selection.setRangeStart(coords);
    }
  }
}
/**
 * MouseOver handler.
 *
 * @param {Object} options
 * @param {Boolean} options.isLeftClick
 * @param {CellRange} options.coords The CellCoords object with defined visual coordinates.
 * @param {Selection} options.selection The Selection class instance.
 * @param {Object} options.controller An object with keys `row`, `column`, `cell` which indicate what
 *                                    operation will be performed in later selection stages.
 */


function mouseOver(_ref2) {
  var isLeftClick = _ref2.isLeftClick,
      coords = _ref2.coords,
      selection = _ref2.selection,
      controller = _ref2.controller;

  if (!isLeftClick) {
    return;
  }

  var selectedRow = selection.isSelectedByRowHeader();
  var selectedColumn = selection.isSelectedByColumnHeader();
  var countCols = selection.tableProps.countCols();
  var countRows = selection.tableProps.countRows();

  if (selectedColumn && !controller.column) {
    selection.setRangeEnd(new _src.CellCoords(countRows - 1, coords.col));
  } else if (selectedRow && !controller.row) {
    selection.setRangeEnd(new _src.CellCoords(coords.row, countCols - 1));
  } else if (!controller.cell) {
    selection.setRangeEnd(coords);
  }
}

var handlers = new Map([['mousedown', mouseDown], ['mouseover', mouseOver], ['touchstart', mouseDown]]);
/**
 * Mouse handler for selection functionality.
 *
 * @param {Event} event An native event to handle.
 * @param {Object} options
 * @param {CellRange} options.coords The CellCoords object with defined visual coordinates.
 * @param {Selection} options.selection The Selection class instance.
 * @param {Object} options.controller An object with keys `row`, `column`, `cell` which indicate what
 *                                    operation will be performed in later selection stages.
 */

function handleMouseEvent(event, _ref3) {
  var coords = _ref3.coords,
      selection = _ref3.selection,
      controller = _ref3.controller;
  handlers.get(event.type)({
    coords: coords,
    selection: selection,
    controller: controller,
    isShiftKey: event.shiftKey,
    isLeftClick: (0, _event.isLeftClick)(event) || event.type === 'touchstart',
    isRightClick: (0, _event.isRightClick)(event)
  });
}

/***/ }),
/* 472 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(133);

__webpack_require__(134);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.registerAsRootInstance = registerAsRootInstance;
exports.hasValidParameter = hasValidParameter;
exports.isRootInstance = isRootInstance;
exports.rootInstanceSymbol = exports.holder = void 0;
var holder = new WeakMap();
exports.holder = holder;
var rootInstanceSymbol = Symbol('rootInstance');
/**
 * Register an object as a root instance.
 *
 * @param  {Object} object An object to associate with root instance flag.
 */

exports.rootInstanceSymbol = rootInstanceSymbol;

function registerAsRootInstance(object) {
  holder.set(object, true);
}
/**
 * Check if the source of the root indication call is valid.
 *
 * @param  {Symbol} rootSymbol A symbol as a source of truth.
 * @return {Boolean}
 */


function hasValidParameter(rootSymbol) {
  return rootSymbol === rootInstanceSymbol;
}
/**
 * Check if passed an object was flagged as a root instance.
 *
 * @param  {Object} object An object to check.
 * @return {Boolean}
 */


function isRootInstance(object) {
  return holder.has(object);
}

/***/ }),
/* 473 */
/***/ (function(module, exports, __webpack_require__) {

exports.f = __webpack_require__(35);


/***/ }),
/* 474 */
/***/ (function(module, exports, __webpack_require__) {

var path = __webpack_require__(194);
var has = __webpack_require__(47);
var wrappedWellKnownSymbolModule = __webpack_require__(473);
var defineProperty = __webpack_require__(49).f;

module.exports = function (NAME) {
  var Symbol = path.Symbol || (path.Symbol = {});
  if (!has(Symbol, NAME)) defineProperty(Symbol, NAME, {
    value: wrappedWellKnownSymbolModule.f(NAME)
  });
};


/***/ }),
/* 475 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _mixed = __webpack_require__(27);

var _object = __webpack_require__(4);

/**
 * @alias Options
 * @constructor
 * @description

 * ## Constructor options
 *
 * Constructor options are applied using an object literal passed as a second argument to the Handsontable constructor.
 *
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: myArray,
 *   width: 400,
 *   height: 300
 * });
 * ```
 *
 * ---
 * ## Cascading configuration
 *
 * Handsontable is using *Cascading Configuration*, which is a fast way to provide configuration options
 * for the entire table, including its columns and particular cells.
 *
 * Consider the following example:
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   readOnly: true,
 *   columns: [
 *     {readOnly: false},
 *     {},
 *     {}
 *   ],
 *   cells: function(row, col, prop) {
 *     var cellProperties = {};
 *
 *     if (row === 0 && col === 0) {
 *       cellProperties.readOnly = true;
 *     }
 *
 *     return cellProperties;
 *   }
 * });
 * ```
 *
 * The above notation will result in all TDs being *read only*, except for first column TDs which will be *editable*, except for the TD in top left corner which will still be *read only*.
 *
 * ### The Cascading Configuration model
 *
 * ##### 1. Constructor
 *
 * Configuration options that are provided using first-level `handsontable(container, {option: "value"})` and `updateSettings` method.
 *
 * ##### 2. Columns
 *
 * Configuration options that are provided using second-level object `handsontable(container, {columns: {option: "value"}]})`
 *
 * ##### 3. Cells
 *
 * Configuration options that are provided using third-level function `handsontable(container, {cells: function: (row, col, prop){ }})`
 *
 * ---
 * ## Architecture performance
 *
 * The Cascading Configuration model is based on prototypical inheritance. It is much faster and memory efficient
 * compared to the previous model that used jQuery extend. See: [http://jsperf.com/extending-settings](http://jsperf.com/extending-settings).
 *
 * ---
 * __Important notice:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`.
 */
function DefaultSettings() {}

DefaultSettings.prototype = {
  /**
   * License key for commercial version of Handsontable.
   *
   * @type {String}
   * @default undefined
   * @example
   * ```js
   * licenseKey: '00000-00000-00000-00000-00000',
   * // or
   * licenseKey: 'non-commercial-and-evaluation',
   * ```
   */
  licenseKey: void 0,

  /**
   * @description
   * Initial data source that will be bound to the data grid __by reference__ (editing data grid alters the data source).
   * Can be declared as an array of arrays, array of objects or a function.
   *
   * See [Understanding binding as reference](https://docs.handsontable.com/tutorial-data-binding.html#page-reference).
   *
   * @type {Array[]|Object[]}
   * @default undefined
   * @example
   * ```js
   * // as an array of arrays
   * data: [
   *   ['A', 'B', 'C'],
   *   ['D', 'E', 'F'],
   *   ['G', 'H', 'J']
   * ]
   *
   * // as an array of objects
   * data: [
   *   {id: 1, name: 'Ted Right'},
   *   {id: 2, name: 'Frank Honest'},
   *   {id: 3, name: 'Joan Well'},
   *   {id: 4, name: 'Gail Polite'},
   *   {id: 5, name: 'Michael Fair'},
   * ]
   * ```
   */
  data: void 0,

  /**
   * @description
   * Defines the structure of a new row when data source is an array of objects.
   *
   * See [data-schema](https://docs.handsontable.com/tutorial-data-sources.html#page-data-schema) for more options.
   *
   * @type {Object}
   * @default undefined
   *
   * @example
   * ```
   * // with data schema we can start with an empty table
   * data: null,
   * dataSchema: {id: null, name: {first: null, last: null}, address: null},
   * colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
   * columns: [
   *   {data: 'id'},
   *   {data: 'name.first'},
   *   {data: 'name.last'},
   *   {data: 'address'}
   * ],
   * startRows: 5,
   * minSpareRows: 1
   * ```
   */
  dataSchema: void 0,

  /**
   * Width of the grid. Can be a value or a function that returns a value.
   *
   * @type {Number|String|Function}
   * @default undefined
   *
   * @example
   * ```
   * // as a number
   * width: 500,
   *
   * // as a string
   * width: '75vw',
   *
   * // as a function
   * width: function() {
   *   return 500;
   * },
   * ```
   */
  width: void 0,

  /**
   * Height of the grid. Can be a number or a function that returns a number.
   *
   * @type {Number|String|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // as a number
   * height: 500,
   *
   * // as a string
   * height: '75vh',
   *
   * // as a function
   * height: function() {
   *   return 500;
   * },
   * ```
   */
  height: void 0,

  /**
   * @description
   * Initial number of rows.
   *
   * __Note:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
   *
   * @type {Number}
   * @default 5
   *
   * @example
   * ```js
   * // start with 15 empty rows
   * startRows: 15,
   * ```
   */
  startRows: 5,

  /**
   * @description
   * Initial number of columns.
   *
   * __Note:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
   *
   * @type {Number}
   * @default 5
   *
   * @example
   * ```js
   * // start with 15 empty columns
   * startCols: 15,
   * ```
   */
  startCols: 5,

  /**
   * Setting `true` or `false` will enable or disable the default row headers (1, 2, 3).
   * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers.
   * If a function is set the index of the row is passed as a parameter.
   *
   * @type {Boolean|String[]|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean
   * rowHeaders: true,
   *
   * // as an array
   * rowHeaders: ['1', '2', '3'],
   *
   * // as a function
   * rowHeaders: function(index) {
   *   return index + ': AB';
   * },
   * ```
   */
  rowHeaders: void 0,

  /**
   * Setting `true` or `false` will enable or disable the default column headers (A, B, C).
   * You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers.
   * If a function is set, then the index of the column is passed as a parameter.
   *
   * @type {Boolean|String[]|Function}
   * @default null
   *
   * @example
   * ```js
   * // as a boolean
   * colHeaders: true,
   *
   * // as an array
   * colHeaders: ['A', 'B', 'C'],
   *
   * // as a function
   * colHeaders: function(index) {
   *   return index + ': AB';
   * },
   * ```
   */
  colHeaders: null,

  /**
   * Defines column widths in pixels. Accepts number, string (that will be converted to a number), array of numbers
   * (if you want to define column width separately for each column) or a function (if you want to set column width
   * dynamically on each render).
   *
   * @type {Number|Number[]|String|String[]|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // as a number, for each column.
   * colWidths: 100,
   *
   * // as a string, for each column.
   * colWidths: '100px',
   *
   * // as an array, based on visual indexes. The rest of the columns have a default width.
   * colWidths: [100, 120, 90],
   *
   * // as a function, based on visual indexes.
   * colWidths: function(index) {
   *   return index * 10;
   * },
   * ```
   */
  colWidths: void 0,

  /**
   * Defines row heights in pixels. Accepts numbers, strings (that will be converted into a number), array of numbers
   * (if you want to define row height separately for each row) or a function (if you want to set row height dynamically
   * on each render).
   *
   * If the {@link ManualRowResize} or {@link AutoRowSize} plugins are enabled, this is also the minimum height that can
   * be set via either of those two plugins.
   *
   * Height should be equal or greater than 23px. Table is rendered incorrectly if height is less than 23px.
   *
   * @type {Number|Number[]|String|String[]|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // as a number, the same for all rows
   * rowHeights: 100,
   *
   * // as a string, the same for all row
   * rowHeights: '100px',
   *
   * // as an array, based on visual indexes. The rest of the rows have a default height
   * rowHeights: [100, 120, 90],
   *
   * // as a function, based on visual indexes
   * rowHeights: function(index) {
   *   return index * 10;
   * },
   * ```
   */
  rowHeights: void 0,

  /**
   * @description
   * Defines the cell properties and data binding for certain columns.
   *
   * __Note:__ Using this option sets a fixed number of columns (options `startCols`, `minCols`, `maxCols` will be ignored).
   *
   * See [documentation -> datasources.html](https://docs.handsontable.com/tutorial-data-sources.html#page-nested) for examples.
   *
   * @type {Object[]|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // as an array of objects
   * // order of the objects in array is representation of physical indexes.
   * columns: [
   *   {
   *     // column options for the first column
   *     type: 'numeric',
   *     numericFormat: {
   *       pattern: '0,0.00 $'
   *     }
   *   },
   *   {
   *     // column options for the second column
   *     type: 'text',
   *     readOnly: true
   *   }
   * ],
   *
   * // or as a function, based on physical indexes
   * columns: function(index) {
   *   return {
   *     type: index > 0 ? 'numeric' : 'text',
   *     readOnly: index < 1
   *   }
   * }
   * ```
   */
  columns: void 0,

  /**
   * @description
   * Defines the cell properties for given `row`, `col`, `prop` coordinates. Any constructor or column option may be
   * overwritten for a particular cell (row/column combination) using the `cells` property in the Handsontable constructor.
   *
   * __Note:__ Parameters `row` and `col` always represent __physical indexes__. Example below show how to execute
   * operations based on the __visual__ representation of Handsontable.
   *
   * Possible values of `prop`:
   * - property name for column's data source object, when dataset is an [array of objects](/tutorial-data-sources.html#page-object)
   * - the same number as `col`, when dataset is an [array of arrays](/tutorial-data-sources.html#page-array)
   *
   * @type {Function}
   * @default undefined
   *
   * @example
   * ```js
   * cells: function(row, column, prop) {
   *   const cellProperties = {};
   *   const visualRowIndex = this.instance.toVisualRow(row);
   *   const visualColIndex = this.instance.toVisualColumn(column);
   *
   *   if (visualRowIndex === 0 && visualColIndex === 0) {
   *     cellProperties.readOnly = true;
   *   }
   *
   *   return cellProperties;
   * },
   * ```
   */
  cells: void 0,

  /**
   * Any constructor or column option may be overwritten for a particular cell (row/column combination), using `cell`
   * array passed to the Handsontable constructor.
   *
   * @type {Array[]}
   * @default []
   *
   * @example
   * ```js
   * // make cell with coordinates (0, 0) read only
   * cell: [
   *   {
   *     row: 0,
   *     col: 0,
   *     readOnly: true
   *   }
   * ],
   * ```
   */
  cell: [],

  /**
   * @description
   * If `true`, enables the {@link Comments} plugin, which enables an option to apply cell comments through the context menu
   * (configurable with context menu keys `commentsAddEdit`, `commentsRemove`).
   *
   * To initialize Handsontable with predefined comments, provide cell coordinates and comment text values in a form of
   * an array.
   *
   * See [Comments](https://docs.handsontable.com/demo-comments_.html) demo for examples.
   *
   * @type {Boolean|Object[]}
   * @default false
   *
   * @example
   * ```js
   * // enable comments plugin
   * comments: true,
   *
   * // or
   * // enable comments plugin and add predefined comments
   * comments: [
   *   {
   *     row: 1,
   *     col: 1,
   *     comment: {
   *       value: "Test comment"
   *     }
   *   }
   * ],
   * ```
   */
  comments: false,

  /**
   * @description
   * If `true`, enables the {@link CustomBorders} plugin, which enables an option to apply custom borders through the context
   * menu (configurable with context menu key `borders`). To initialize Handsontable with predefined custom borders,
   * provide cell coordinates and border styles in a form of an array.
   *
   * See [Custom Borders](https://docs.handsontable.com/demo-custom-borders.html) demo for examples.
   *
   * @type {Boolean|Object[]}
   * @default false
   *
   * @example
   * ```js
   * // enable custom borders
   * customBorders: true,
   *
   * // or
   * // enable custom borders and start with predefined left border
   * customBorders: [
   *   {
   *     range: {
   *       from: {
   *         row: 1,
   *         col: 1
   *       },
   *       to: {
   *         row: 3,
   *         col: 4
   *       }
   *     },
   *     left: {
   *       width: 2,
   *       color: 'red'
   *     },
   *     right: {},
   *     top: {},
   *     bottom: {}
   *   }
   * ],
   *
   * // or
   * customBorders: [
   *   {
   *     row: 2,
   *     col: 2,
   *     left: {
   *       width: 2,
   *       color: 'red'
   *     },
   *     right: {
   *       width: 1,
   *       color: 'green'
   *     },
   *     top: '',
   *     bottom: ''
   *   }
   * ],
   * ```
   */
  customBorders: false,

  /**
   * Minimum number of rows. At least that number of rows will be created during initialization.
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // set minimum table size to 10 rows
   * minRows: 10,
   * ```
   */
  minRows: 0,

  /**
   * Minimum number of columns. At least that number of columns will be created during initialization.
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // set minimum table size to 10 columns
   * minCols: 10,
   * ```
   */
  minCols: 0,

  /**
   * Maximum number of rows. If set to a value lower than the initial row count, the data will be trimmed to the provided
   * value as the number of rows.
   *
   * @type {Number}
   * @default Infinity
   *
   * @example
   * ```js
   * // limit table size to maximum 300 rows
   * maxRows: 300,
   * ```
   */
  maxRows: Infinity,

  /**
   * Maximum number of cols. If set to a value lower than the initial col count, the data will be trimmed to the provided
   * value as the number of cols.
   *
   * @type {Number}
   * @default Infinity
   *
   * @example
   * ```js
   * // limit table size to maximum 300 columns
   * maxCols: 300,
   * ```
   */
  maxCols: Infinity,

  /**
   * When set to 1 (or more), Handsontable will add a new row at the end of grid if there are no more empty rows.
   * (unless the number of rows exceeds the one set in the `maxRows` property)
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // always add 3 empty rows at the table end
   * minSpareRows: 3,
   * ```
   */
  minSpareRows: 0,

  /**
   * When set to 1 (or more), Handsontable will add a new column at the end of grid if there are no more empty columns.
   * (unless the number of rows exceeds the one set in the `maxCols` property)
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // always add 3 empty columns at the table end
   * minSpareCols: 3,
   * ```
   */
  minSpareCols: 0,

  /**
   * If set to `false`, there won't be an option to insert new rows in the Context Menu.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // hide "Insert row above" and "Insert row below" options from the Context Menu
   * allowInsertRow: false,
   * ```
   */
  allowInsertRow: true,

  /**
   * If set to `false`, there won't be an option to insert new columns in the Context Menu.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // hide "Insert column left" and "Insert column right" options from the Context Menu
   * allowInsertColumn: false,
   * ```
   */
  allowInsertColumn: true,

  /**
   * If set to `false`, there won't be an option to remove rows in the Context Menu.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // hide "Remove row" option from the Context Menu
   * allowRemoveRow: false,
   * ```
   */
  allowRemoveRow: true,

  /**
   * If set to `false`, there won't be an option to remove columns in the Context Menu.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // hide "Remove column" option from the Context Menu
   * allowRemoveColumn: false,
   * ```
   */
  allowRemoveColumn: true,

  /**
   * @description
   * Defines how the table selection reacts. The selection support three different behaviors defined as:
   *  * `'single'` Only a single cell can be selected.
   *  * `'range'` Multiple cells within a single range can be selected.
   *  * `'multiple'` Multiple ranges of cells can be selected.
   *
   * To see how to interact with selection by getting selected data or change styles of the selected cells go to
   * [https://docs.handsontable.com/demo-selecting-ranges.html](https://docs.handsontable.com/demo-selecting-ranges.html).
   *
   * @type {String}
   * @default 'multiple'
   *
   * @example
   * ```js
   * // only one cell can be selected at a time
   * selectionMode: 'single',
   * ```
   */
  selectionMode: 'multiple',

  /**
   * Enables the fill handle (drag-down and copy-down) functionality, which shows a small rectangle in bottom
   * right corner of the selected area, that let's you expand values to the adjacent cells.
   *
   * Setting to `true` enables the fillHandle plugin. Possible values: `true` (to enable in all directions),
   * `'vertical'` or `'horizontal'` (to enable in one direction), `false` (to disable completely), an object with
   * options: `autoInsertRow`, `direction`.
   *
   * If `autoInsertRow` option is `true`, fill-handler will create new rows till it reaches the last row.
   * It is enabled by default.
   *
   * @type {Boolean|String|Object}
   * @default true
   *
   * @example
   * ```js
   * // enable plugin in all directions and with autoInsertRow as true
   * fillHandle: true,
   *
   * // or
   * // enable plugin in vertical direction and with autoInsertRow as true
   * fillHandle: 'vertical',
   *
   * // or
   * fillHandle: {
   *   // enable plugin in both directions and with autoInsertRow as false
   *   autoInsertRow: false,
   * },
   *
   * // or
   * fillHandle: {
   *   // enable plugin in vertical direction and with autoInsertRow as false
   *   autoInsertRow: false,
   *   direction: 'vertical'
   * },
   * ```
   */
  fillHandle: {
    autoInsertRow: false
  },

  /**
   * Allows to specify the number of fixed (or *frozen*) rows at the top of the table.
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // freeze the first 3 rows of the table.
   * fixedRowsTop: 3,
   * ```
   */
  fixedRowsTop: 0,

  /**
   * Allows to specify the number of fixed (or *frozen*) rows at the bottom of the table.
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // freeze the last 3 rows of the table.
   * fixedRowsBottom: 3,
   * ```
   */
  fixedRowsBottom: 0,

  /**
   * Allows to specify the number of fixed (or *frozen*) columns on the left of the table.
   *
   * @type {Number}
   * @default 0
   *
   * @example
   * ```js
   * // freeze first 3 columns of the table.
   * fixedColumnsLeft: 3,
   * ```
   */
  fixedColumnsLeft: 0,

  /**
   * If `true`, mouse click outside the grid will deselect the current selection. Can be a function that takes the
   * click event target and returns a boolean.
   *
   * @type {Boolean|Function}
   * @default true
   *
   * @example
   * ```js
   * // don't clear current selection when mouse click was outside the grid
   * outsideClickDeselects: false,
   *
   * // or
   * outsideClickDeselects: function(event) {
   *   return false;
   * }
   * ```
   */
  outsideClickDeselects: true,

  /**
   * If `true`, <kbd>ENTER</kbd> begins editing mode (like in Google Docs). If `false`, <kbd>ENTER</kbd> moves to next
   * row (like Excel) and adds a new row if necessary. <kbd>TAB</kbd> adds new column if necessary.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * enterBeginsEditing: false,
   * ```
   */
  enterBeginsEditing: true,

  /**
   * Defines the cursor movement after <kbd>ENTER</kbd> was pressed (<kbd>SHIFT</kbd> + <kbd>ENTER</kbd> uses a negative vector). Can
   * be an object or a function that returns an object. The event argument passed to the function is a DOM Event object
   * received after the <kbd>ENTER</kbd> key has been pressed. This event object can be used to check whether user pressed
   * <kbd>ENTER</kbd> or <kbd>SHIFT</kbd> + <kbd>ENTER</kbd>.
   *
   * @type {Object|Function}
   * @default {row: 1, col: 0}
   *
   * @example
   * ```js
   * // move selection diagonal by 1 cell in x and y axis
   * enterMoves: {row: 1, col: 1},
   * // or as a function
   * enterMoves: function(event) {
   *   return {row: 1, col: 1};
   * },
   * ```
   */
  enterMoves: {
    row: 1,
    col: 0
  },

  /**
   * Defines the cursor movement after <kbd>TAB</kbd> is pressed (<kbd>SHIFT</kbd> + <kbd>TAB</kbd> uses a negative vector). Can
   * be an object or a function that returns an object. The event argument passed to the function is a DOM Event object
   * received after the <kbd>TAB</kbd> key has been pressed. This event object can be used to check whether user pressed
   * <kbd>TAB</kbd> or <kbd>SHIFT</kbd> + <kbd>TAB</kbd>.
   *
   * @type {Object|Function}
   * @default {row: 0, col: 1}
   *
   * @example
   * ```js
   * // move selection 2 cells away after TAB pressed.
   * tabMoves: {row: 2, col: 2},
   * // or as a function
   * tabMoves: function(event) {
   *   return {row: 2, col: 2};
   * },
   * ```
   */
  tabMoves: {
    row: 0,
    col: 1
  },

  /**
   * If `true`, pressing <kbd>TAB</kbd> or right arrow in the last column will move to first column in next row.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // stop TAB key navigation on the last column
   * autoWrapRow: false,
   * ```
   */
  autoWrapRow: true,

  /**
   * If `true`, pressing <kbd>ENTER</kbd> or down arrow in the last row will move to the first row in the next column.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // stop ENTER key navigation on the last row
   * autoWrapCol: false,
   * ```
   */
  autoWrapCol: true,

  /**
   * @description
   * Turns on saving the state of column sorting, column positions and column sizes in local storage.
   *
   * You can save any sort of data in local storage to preserve table state between page reloads.  In order to enable
   * data storage mechanism, `persistentState` option must be set to `true` (you can set it either during Handsontable
   * initialization or using the `updateSettings` method). When `persistentState` is enabled it exposes 3 hooks:
   *
   * __persistentStateSave__ (key: String, value: Mixed)
   *
   *   * Saves value under given key in browser local storage.
   *
   * __persistentStateLoad__ (key: String, valuePlaceholder: Object)
   *
   *   * Loads `value`, saved under given key, form browser local storage. The loaded `value` will be saved in
   *   `valuePlaceholder.value` (this is due to specific behaviour of `Hooks.run()` method). If no value have
   *   been saved under key `valuePlaceholder.value` will be `undefined`.
   *
   * __persistentStateReset__ (key: String)
   *
   *   * Clears the value saved under `key`. If no `key` is given, all values associated with table will be cleared.
   *
   * __Note:__ The main reason behind using `persistentState` hooks rather than regular LocalStorage API is that it
   * ensures separation of data stored by multiple Handsontable instances. In other words, if you have two (or more)
   * instances of Handsontable on one page, data saved by one instance won't be accessible by the second instance.
   * Those two instances can store data under the same key and no data would be overwritten.
   *
   * __Important:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`.
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * // enable the persistent state plugin
   * persistentState: true,
   * ```
   */
  persistentState: void 0,

  /**
   * Class name for all visible rows in the current selection.
   *
   * @type {String}
   * @default undefined
   *
   * @example
   * ```js
   * // This will add a 'currentRow' class name to appropriate table cells.
   * currentRowClassName: 'currentRow',
   * ```
   */
  currentRowClassName: void 0,

  /**
   * Class name for all visible columns in the current selection.
   *
   * @type {String}
   * @default undefined
   *
   * @example
   * ```js
   * // This will add a 'currentColumn' class name to appropriate table cells.
   * currentColClassName: 'currentColumn',
   * ```
   */
  currentColClassName: void 0,

  /**
   * Class name for all visible headers in current selection.
   *
   * @type {String}
   * @default 'ht__highlight'
   *
   * @example
   * ```js
   * // This will add a 'ht__highlight' class name to appropriate table headers.
   * currentHeaderClassName: 'ht__highlight',
   * ```
   */
  currentHeaderClassName: 'ht__highlight',

  /**
   * Class name for all active headers in selections. The header will be marked with this class name
   * only when a whole column or row will be selected.
   *
   * @type {String}
   * @since 0.38.2
   * @default 'ht__active_highlight'
   *
   * @example
   * ```js
   * // this will add a 'ht__active_highlight' class name to appropriate table headers.
   * activeHeaderClassName: 'ht__active_highlight',
   * ```
   */
  activeHeaderClassName: 'ht__active_highlight',

  /**
   * Class name for the Handsontable container element.
   *
   * @type {String|String[]}
   * @default undefined
   *
   * @example
   * ```js
   * // set custom class for table container
   * className: 'your__class--name',
   *
   * // or
   * className: ['first-class-name', 'second-class-name'],
   * ```
   */
  className: void 0,

  /**
   * Class name for all tables inside container element.
   *
   * @type {String|String[]}
   * @default undefined
   *
   * @example
   * ```js
   * // set custom class for table element
   * tableClassName: 'your__class--name',
   *
   * // or
   * tableClassName: ['first-class-name', 'second-class-name'],
   * ```
   */
  tableClassName: void 0,

  /**
   * @description
   * Defines how the columns react, when the declared table width is different than the calculated sum of all column widths.
   * [See more](https://docs.handsontable.com/demo-stretching.html) mode. Possible values:
   *  * `'none'` Disable stretching
   *  * `'last'` Stretch only the last column
   *  * `'all'` Stretch all the columns evenly
   *
   * @type {String}
   * @default 'none'
   *
   * @example
   * ```js
   * // fit table to the container
   * stretchH: 'all',
   * ```
   */
  stretchH: 'none',

  /**
   * Overwrites the default `isEmptyRow` method, which checks if row at the provided index is empty.
   *
   * @type {Function}
   * @param {Number} row Visual row index.
   * @returns {Boolean}
   *
   * @example
   * ```js
   * // define custom checks for empty row
   * isEmptyRow: function(row) {
   *    ...
   * },
   * ```
   */
  isEmptyRow: function isEmptyRow(row) {
    var col;
    var colLen;
    var value;
    var meta;

    for (col = 0, colLen = this.countCols(); col < colLen; col++) {
      value = this.getDataAtCell(row, col);

      if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) {
        if ((0, _typeof2.default)(value) === 'object') {
          meta = this.getCellMeta(row, col);
          return (0, _object.isObjectEqual)(this.getSchema()[meta.prop], value);
        }

        return false;
      }
    }

    return true;
  },

  /**
   * Overwrites the default `isEmptyCol` method, which checks if column at the provided index is empty.
   *
   * @type {Function}
   * @param {Number} column Visual column index
   * @returns {Boolean}
   *
   * @example
   * ```js
   * // define custom checks for empty column
   * isEmptyCol: function(column) {
   *    return false;
   * },
   * ```
   */
  isEmptyCol: function isEmptyCol(col) {
    var row;
    var rowLen;
    var value;

    for (row = 0, rowLen = this.countRows(); row < rowLen; row++) {
      value = this.getDataAtCell(row, col);

      if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) {
        return false;
      }
    }

    return true;
  },

  /**
   * When set to `true`, the table is re-rendered when it is detected that it was made visible in DOM.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // don't rerender the table on visibility changes
   * observeDOMVisibility: false,
   * ```
   */
  observeDOMVisibility: true,

  /**
   * If set to `true`, Handsontable will accept values that were marked as invalid by the cell `validator`. It will
   * result with *invalid* cells being treated as *valid* (will save the *invalid* value into the Handsontable data source).
   * If set to `false`, Handsontable will *not* accept the invalid values and won't allow the user to close the editor.
   * This option will be particularly useful when used with the Autocomplete's `strict` mode.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // don't save the invalid values
   * allowInvalid: false,
   * ```
   */
  allowInvalid: true,

  /**
   * If set to `true`, Handsontable will accept values that are empty (`null`, `undefined` or `''`). If set to `false`,
   * Handsontable will *not* accept the empty values and mark cell as invalid.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // allow empty values for all cells (whole table)
   * allowEmpty: true,
   *
   * // or
   * columns: [
   *   {
   *     data: 'date',
   *     dateFormat: 'DD/MM/YYYY',
   *     // allow empty values only for the 'date' column
   *     allowEmpty: true
   *   }
   * ],
   * ```
   */
  allowEmpty: true,

  /**
   * CSS class name for cells that did not pass validation.
   *
   * @type {String}
   * @default 'htInvalid'
   *
   * @example
   * ```js
   * // set custom validation error class
   * invalidCellClassName: 'highlight--error',
   * ```
   */
  invalidCellClassName: 'htInvalid',

  /**
   * When set to an non-empty string, displayed as the cell content for empty cells. If a value of a different type is provided,
   * it will be stringified and applied as a string.
   *
   * @type {String}
   * @default undefined
   *
   * @example
   * ```js
   * // add custom placeholder content to empty cells
   * placeholder: 'Empty Cell',
   * ```
   */
  placeholder: void 0,

  /**
   * CSS class name for cells that have a placeholder in use.
   *
   * @type {String}
   * @default 'htPlaceholder'
   *
   * @example
   * ```js
   * // set custom placeholder class
   * placeholderCellClassName: 'has-placeholder',
   * ```
   */
  placeholderCellClassName: 'htPlaceholder',

  /**
   * CSS class name for read-only cells.
   *
   * @type {String}
   * @default 'htDimmed'
   *
   * @example
   * ```js
   * // set custom read-only class
   * readOnlyCellClassName: 'is-readOnly',
   * ```
   */
  readOnlyCellClassName: 'htDimmed',

  /**
   * @description
   * If a string is provided, it may be one of the following predefined values:
   * * `autocomplete`,
   * * `checkbox`,
   * * `html`,
   * * `numeric`,
   * * `password`.
   * * `text`.
   *
   * Or you can [register](https://docs.handsontable.com/demo-custom-renderers.html) the custom renderer under specified name and use its name as an alias in your
   * configuration.
   *
   * If a function is provided, it will receive the following arguments:
   * ```js
   * function(instance, TD, row, col, prop, value, cellProperties) {}
   * ```
   *
   * You can read more about custom renderes [in the documentation](https://docs.handsontable.com/demo-custom-renderers.html).
   *
   * @type {String|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // register custom renderer
   * Handsontable.renderers.registerRenderer('my.renderer', function(instance, TD, row, col, prop, value, cellProperties) {
   *   TD.innerHTML = value;
   * });
   *
   * // use it for selected column:
   * columns: [
   *   {
   *     // as a string with the name of build in renderer
   *     renderer: 'autocomplete',
   *     editor: 'select'
   *   },
   *   {
   *     // as an alias to custom renderer registered above
   *     renderer: 'my.renderer'
   *   },
   *   {
   *     // renderer as custom function
   *     renderer: function(hotInstance, TD, row, col, prop, value, cellProperties) {
   *       TD.style.color = 'blue';
   *       TD.innerHTML = value;
   *     }
   *   }
   * ],
   * ```
   */
  renderer: void 0,

  /**
   * CSS class name added to the commented cells.
   *
   * @type {String}
   * @default 'htCommentCell'
   *
   * @example
   * ```js
   * // set custom class for commented cells
   * commentedCellClassName: 'has-comment',
   * ```
   */
  commentedCellClassName: 'htCommentCell',

  /**
   * If set to `true`, it enables the browser's native selection of a fragment of the text within a single cell, between
   * adjacent cells or in a whole table. If set to `'cell'`, it enables the possibility of selecting a fragment of the
   * text within a single cell's body.
   *
   * @type {Boolean|String}
   * @default false
   *
   * @example
   * ```js
   * // enable text selection within table
   * fragmentSelection: true,
   *
   * // or
   * // enable text selection within cells only
   * fragmentSelection: 'cell',
   * ```
   */
  fragmentSelection: false,

  /**
   * @description
   * Makes cell [read only](https://docs.handsontable.com/demo-read-only.html).
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * // set cell as read only
   * readOnly: true,
   * ```
   */
  readOnly: false,

  /**
   * @description
   * When added to a `column` property, it skips the column on paste and pastes the data on the next column to the right.
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     // don't paste data to this column
   *     skipColumnOnPaste: true
   *   }
   * ],
   * ```
   */
  skipColumnOnPaste: false,

  /**
   * @description
   * Setting to `true` enables the {@link Search} plugin (see [demo](https://docs.handsontable.com/demo-search-for-values.html)).
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * // enable search plugin
   * search: true,
   *
   * // or
   * // as an object with detailed configuration
   * search: {
   *   searchResultClass: 'customClass',
   *   queryMethod: function(queryStr, value) {
   *     ...
   *   },
   *   callback: function(instance, row, column, value, result) {
   *     ...
   *   }
   * }
   * ```
   */
  search: false,

  /**
   * @description
   * Shortcut to define the combination of the cell renderer, editor and validator for the column, cell or whole table.
   *
   * Possible values:
   *  * [autocomplete](https://docs.handsontable.com/demo-autocomplete.html)
   *  * [checkbox](https://docs.handsontable.com/demo-checkbox.html)
   *  * [date](https://docs.handsontable.com/demo-date.html)
   *  * [dropdown](https://docs.handsontable.com/demo-dropdown.html)
   *  * [handsontable](https://docs.handsontable.com/demo-handsontable.html)
   *  * [numeric](https://docs.handsontable.com/demo-numeric.html)
   *  * [password](https://docs.handsontable.com/demo-password.html)
   *  * text
   *  * [time](https://docs.handsontable.com/demo-time.html)
   *
   * Or you can register the custom cell type under specified name and use
   * its name as an alias in your configuration.
   *
   * @type {String}
   * @default 'text'
   *
   * @example
   * ```js
   * // register custom cell type:
   * Handsontable.cellTypes.registerCellType('my.type', {
   *   editor: MyEditorClass,
   *   renderer: function(hot, td, row, col, prop, value, cellProperties) {
   *     td.innerHTML = value;
   *   },
   *   validator: function(value, callback) {
   *     callback(value === 'foo' ? true : false);
   *   }
   * });
   *
   * // use it in column settings:
   * columns: [
   *   {
   *     type: 'text'
   *   },
   *   {
   *     // an alias to custom type
   *     type: 'my.type'
   *   },
   *   {
   *     type: 'checkbox'
   *   }
   * ],
   * ```
   */
  type: 'text',

  /**
   * @description
   * Makes a cell copyable (pressing <kbd>CTRL</kbd> + <kbd>C</kbd> on your keyboard moves its value to system clipboard).
   *
   * __Note:__ this setting is `false` by default for cells with type `password`.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * cells: [
   *   {
   *     cell: 0,
   *     row: 0,
   *     // cell with coordinates (0, 0) can't be copied
   *     copyable: false,
   *   }
   * ],
   * ```
   */
  copyable: true,

  /**
   * Defines the editor for the table/column/cell.
   *
   * If a string is provided, it may be one of the following predefined values:
   *  * [autocomplete](https://docs.handsontable.com/demo-autocomplete.html)
   *  * [checkbox](https://docs.handsontable.com/demo-checkbox.html)
   *  * [date](https://docs.handsontable.com/demo-date.html)
   *  * [dropdown](https://docs.handsontable.com/demo-dropdown.html)
   *  * [handsontable](https://docs.handsontable.com/demo-handsontable.html)
   *  * [mobile](https://docs.handsontable.com/demo-mobiles-and-tablets.html)
   *  * [password](https://docs.handsontable.com/demo-password.html)
   *  * [select](https://docs.handsontable.com/demo-select.html)
   *  * text
   *
   * Or you can [register](https://docs.handsontable.com/tutorial-cell-editor.html#registering-an-editor) the custom editor under specified name and use its name as an alias in your
   * configuration.
   *
   * To disable cell editing completely set `editor` property to `false`.
   *
   * @type {String|Function|Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     // set editor for the first column
   *     editor: 'select'
   *   },
   *   {
   *     // disable editor for the second column
   *     editor: false
   *   }
   * ],
   * ```
   */
  editor: void 0,

  /**
   * Control number of choices for the autocomplete (or dropdown) typed cells. After exceeding it, a scrollbar for the
   * dropdown list of choices will appear.
   *
   * @type {Number}
   * @default 10
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'autocomplete',
   *     // set autocomplete options list height
   *     visibleRows: 15,
   *   }
   * ],
   * ```
   */
  visibleRows: 10,

  /**
   * Makes autocomplete or dropdown width the same as the edited cell width. If `false` then editor will be scaled
   * according to its content.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'autocomplete',
   *     // don't trim dropdown width with column width
   *     trimDropdown: false,
   *   }
   * ],
   * ```
   */
  trimDropdown: true,

  /**
   * Setting to `true` enables the debug mode, currently used to test the correctness of the row and column
   * header fixed positioning on a layer above the master table.
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * // enable debug mode
   * debug: true,
   * ```
   */
  debug: false,

  /**
   * When set to `true`, the text of the cell content is wrapped if it does not fit in the fixed column width.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * colWidths: 100,
   * columns: [
   *   {
   *     // fixed column width is set but don't wrap the content
   *     wordWrap: false,
   *   }
   * ],
   * ```
   */
  wordWrap: true,

  /**
   * CSS class name added to cells with cell meta `wordWrap: false`.
   *
   * @type {String}
   * @default 'htNoWrap'
   *
   * @example
   * ```js
   * // set custom class for cells which content won't be wrapped
   * noWordWrapClassName: 'is-noWrapCell',
   * ```
   */
  noWordWrapClassName: 'htNoWrap',

  /**
   * @description
   * Defines if the right-click context menu should be enabled. Context menu allows to create new row or column at any
   * place in the grid among [other features](https://docs.handsontable.com/demo-context-menu.html).
   * Possible values:
   * * `true` (to enable default options),
   * * `false` (to disable completely)
   * * an array of [predefined options](https://docs.handsontable.com/demo-context-menu.html#page-specific),
   * * an object [with defined structure](https://docs.handsontable.com/demo-context-menu.html#page-custom)
   *
   * See [the context menu demo](https://docs.handsontable.com/demo-context-menu.html) for examples.
   *
   * @type {Boolean|String[]|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean
   * contextMenu: true,
   *
   * // as an array
   * contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo'],
   *
   * // as an object (`name` attribute is required in the custom keys)
   * contextMenu: {
   *   items: {
   *     "option1": {
   *       name: "option1"
   *     },
   *     "option2": {
   *       name: "option2",
   *       submenu: {
   *         items: [
   *           {
   *             key: "option2:suboption1",
   *             name: "option2:suboption1",
   *             callback: function(key, options) {
   *               ...
   *             }
   *           },
   *           ...
   *         ]
   *       }
   *     }
   *   }
   * },
   * ```
   */
  contextMenu: void 0,

  /**
   * Disables or enables the copy/paste functionality.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // disable copy and paste
   * copyPaste: false,
   * ```
   */
  copyPaste: true,

  /**
   * If `true`, undo/redo functionality is enabled.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * // enable undo and redo
   * undo: true,
   * ```
   */
  undo: void 0,

  /**
   * @description
   * Turns on [Column sorting](https://docs.handsontable.com/demo-sorting-data.html). Can be either a boolean (`true` / `false`) or an object with a declared sorting options:
   * * `initialConfig` - Object with predefined keys:
   *   * `column` - sorted column
   *   * `sortOrder` - order in which column will be sorted
   *     * `'asc'` = ascending
   *     * `'desc'` = descending
   * * `indicator` - display status for sorting order indicator (an arrow icon in the column header, specifying the sorting order).
   *   * `true` = show sort indicator for sorted columns
   *   * `false` = don't show sort indicator for sorted columns
   * * `headerAction` - allow to click on the headers to sort
   *   * `true` = turn on possibility to click on the headers to sort
   *   * `false` = turn off possibility to click on the headers to sort
   * * `sortEmptyCells` - how empty values should be handled
   *   * `true` = the table sorts empty cells
   *   * `false` = the table moves all empty cells to the end of the table
   * * `compareFunctionFactory` - curry function returning compare function; compare function should work in the same way as function which is handled by native `Array.sort` method); please take a look at below examples for more information.
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // as boolean
   * columnSorting: true
   *
   * // as an object with initial sort config (sort ascending for column at index 1)
   * columnSorting: {
   *   initialConfig: {
   *     column: 1,
   *     sortOrder: 'asc'
   *   }
   * }
   *
   * // as an object which define specific sorting options for all columns
   * columnSorting: {
   *   sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
   *   indicator: true, // true = shows indicator for all columns, false = don't show indicator for columns
   *   headerAction: false, // true = allow to click on the headers to sort, false = turn off possibility to click on the headers to sort
   *   compareFunctionFactory: function(sortOrder, columnMeta) {
   *     return function(value, nextValue) {
   *       // Some value comparisons which will return -1, 0 or 1...
   *     }
   *   }
   * }```
   */
  columnSorting: void 0,

  /**
   * Turns on [Manual column move](https://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial column order (as an array of column indexes).
   *
   * @type {Boolean|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean to enable column move
   * manualColumnMove: true,
   *
   * // as a array with initial order
   * // (move column index at 0 to 1 and move column index at 1 to 4)
   * manualColumnMove: [1, 4],
   * ```
   */
  manualColumnMove: void 0,

  /**
   * @description
   * Turns on [Manual column resize](https://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial column resized widths (an an array of widths).
   *
   * @type {Boolean|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean to enable column resize
   * manualColumnResize: true,
   *
   * // as a array with initial widths
   * // (column at 0 index has 40px and column at 1 index has 50px)
   * manualColumnResize: [40, 50],
   * ```
   */
  manualColumnResize: void 0,

  /**
   * @description
   * Turns on [Manual row move](https://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial row order (as an array of row indexes).
   *
   * @type {Boolean|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean
   * manualRowMove: true,
   *
   * // as a array with initial order
   * // (move row index at 0 to 1 and move row index at 1 to 4)
   * manualRowMove: [1, 4],
   * ```
   */
  manualRowMove: void 0,

  /**
   * @description
   * Turns on [Manual row resize](https://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial row resized heights (as an array of heights).
   *
   * @type {Boolean|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // as a boolean to enable row resize
   * manualRowResize: true,
   *
   * // as an array to set initial heights
   * // (row at 0 index has 40px and row at 1 index has 50px)
   * manualRowResize: [40, 50],
   * ```
   */
  manualRowResize: void 0,

  /**
   * @description
   * If set to `true`, it enables a possibility to merge cells. If set to an array of objects, it merges the cells provided
   * in the objects (see the example below). More information on [the demo page](https://docs.handsontable.com/demo-merge-cells.html).
   *
   * @type {Boolean|Object[]}
   * @default false
   *
   * @example
   * ```js
   * // enables the mergeCells plugin
   * margeCells: true,
   *
   * // declares a list of merged sections
   * mergeCells: [
   *   // rowspan and colspan properties declare the width and height of a merged section in cells
   *   {row: 1, col: 1, rowspan: 3, colspan: 3},
   *   {row: 3, col: 4, rowspan: 2, colspan: 2},
   *   {row: 5, col: 6, rowspan: 3, colspan: 3}
   * ],
   * ```
   */
  mergeCells: false,

  /**
   * @description
   * Turns on [Multi-column sorting](https://docs.handsontable.com/pro/demo-multicolumn-sorting.html). Can be either a boolean (`true` / `false`) or an object with a declared sorting options:
   * * `initialConfig` - Array containing objects, every with predefined keys:
   *   * `column` - sorted column
   *   * `sortOrder` - order in which column will be sorted
   *     * `'asc'` = ascending
   *     * `'desc'` = descending
   * * `indicator` - display status for sorting order indicator (an arrow icon in the column header, specifying the sorting order).
   *   * `true` = show sort indicator for sorted columns
   *   * `false` = don't show sort indicator for sorted columns
   * * `headerAction` - allow to click on the headers to sort
   *   * `true` = turn on possibility to click on the headers to sort
   *   * `false` = turn off possibility to click on the headers to sort
   * * `sortEmptyCells` - how empty values should be handled
   *   * `true` = the table sorts empty cells
   *   * `false` = the table moves all empty cells to the end of the table
   * * `compareFunctionFactory` - curry function returning compare function; compare function should work in the same way as function which is handled by native `Array.sort` method); please take a look at below examples for more information.
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // as boolean
   * multiColumnSorting: true
   *
   * // as an object with initial sort config (sort ascending for column at index 1 and then sort descending for column at index 0)
   * multiColumnSorting: {
   *   initialConfig: [{
   *     column: 1,
   *     sortOrder: 'asc'
   *   }, {
   *     column: 0,
   *     sortOrder: 'desc'
   *   }]
   * }
   *
   * // as an object which define specific sorting options for all columns
   * multiColumnSorting: {
   *   sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
   *   indicator: true, // true = shows indicator for all columns, false = don't show indicator for columns
   *   headerAction: false, // true = allow to click on the headers to sort, false = turn off possibility to click on the headers to sort
   *   compareFunctionFactory: function(sortOrder, columnMeta) {
   *     return function(value, nextValue) {
   *       // Some value comparisons which will return -1, 0 or 1...
   *     }
   *   }
   * }```
   */
  multiColumnSorting: void 0,

  /**
   * @description
   * Number of rows to be rendered outside of the visible part of the table. By default, it's set to `'auto'`, which
   * makes Handsontable to attempt to calculate the best offset performance-wise.
   *
   * You may test out different values to find the best one that works for your specific implementation.
   *
   * @type {Number|String}
   * @default 'auto'
   *
   * @example
   * ```js
   * viewportRowRenderingOffset: 70,
   * ```
   */
  viewportRowRenderingOffset: 'auto',

  /**
   * @description
   * Number of columns to be rendered outside of the visible part of the table. By default, it's set to `'auto'`, which
   * makes Handsontable try calculating the best offset performance-wise.
   *
   * You may experiment with the value to find the one that works best for your specific implementation.
   *
   * @type {Number|String}
   * @default 'auto'
   *
   * @example
   * ```js
   * viewportColumnRenderingOffset: 70,
   * ```
   */
  viewportColumnRenderingOffset: 'auto',

  /**
   * @description
   * A function, regular expression or a string, which will be used in the process of cell validation. If a function is
   * used, be sure to execute the callback argument with either `true` (`callback(true)`) if the validation passed
   * or with `false` (`callback(false)`), if the validation failed.
   *
   * __Note__, that `this` in the function points to the `cellProperties` object.
   *
   * If a string is provided, it may be one of the following predefined values:
   * * `autocomplete`,
   * * `date`,
   * * `numeric`,
   * * `time`.
   *
   * Or you can [register](https://docs.handsontable.com/demo-data-validation.html) the validator function under specified name and use its name as an alias in your
   * configuration.
   *
   * See more [in the demo](https://docs.handsontable.com/demo-data-validation.html).
   *
   * @type {Function|RegExp|String}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [
   *    {
   *      // as a function
   *      validator: function(value, callback) {
   *          ...
   *      }
   *    },
   *    {
   *      // regular expression
   *      validator: /^[0-9]$/
   *    },
   *    {
   *      // as a string
   *      validator: 'numeric'
   *    }
   * ],
   * ```
   */
  validator: void 0,

  /**
   * @description
   * Disables visual cells selection.
   *
   * Possible values:
   *  * `true` - Disables any type of visual selection (current and area selection),
   *  * `false` - Enables any type of visual selection. This is default value.
   *  * `'current'` - Disables the selection of a currently selected cell, the area selection is still present.
   *  * `'area'` - Disables the area selection, the currently selected cell selection is still present.
   *  * `'header'` - Disables the headers selection, the currently selected cell selection is still present.
   *
   * @type {Boolean|String|String[]}
   * @default false
   *
   * @example
   * ```js
   * // as a boolean
   * disableVisualSelection: true,
   *
   * // as a string ('current', 'area' or 'header')
   * disableVisualSelection: 'current',
   *
   * // as an array
   * disableVisualSelection: ['current', 'area'],
   * ```
   */
  disableVisualSelection: false,

  /**
   * Disables or enables {@link ManualColumnFreeze} plugin.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * // enable fixed columns
   * manualColumnFreeze: true,
   * ```
   */
  manualColumnFreeze: void 0,

  /**
   * Defines whether Handsontable should trim the whitespace at the beginning and the end of the cell contents.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     // don't remove whitespace
   *     trimWhitespace: false
   *   }
   * ]
   * ```
   */
  trimWhitespace: true,

  /**
   * Defines data source for Autocomplete or Dropdown cell types.
   *
   * @type {Array|Function}
   * @default undefined
   *
   * @example
   * ```js
   * // source as a array
   * columns: [{
   *   type: 'autocomplete',
   *   source: ['A', 'B', 'C', 'D']
   * }],
   *
   * // source as a function
   * columns: [{
   *   type: 'autocomplete',
   *   source: function(query, callback) {
   *     fetch('https://example.com/query?q=' + query, function(response) {
   *       callback(response.items);
   *     })
   *   }
   * }],
   * ```
   */
  source: void 0,

  /**
   * @description
   * Defines the column header name.
   *
   * @type {String}
   * @default undefined
   *
   * @example
   * ```js
   * // set header names for every column
   * columns: [
   *   {
   *     title: 'First name',
   *     type: 'text',
   *   },
   *   {
   *     title: 'Last name',
   *     type: 'text',
   *   }
   * ],
   * ```
   */
  title: void 0,

  /**
   * Data template for `'checkbox'` type when checkbox is checked.
   *
   * @type {Boolean|String|Number}
   * @default true
   *
   * @example
   * ```js
   * checkedTemplate: 'good'
   *
   * // if a checkbox-typed cell is checked, then getDataAtCell(x, y),
   * // where x and y are the coordinates of the cell will return 'good'.
   * ```
   */
  checkedTemplate: void 0,

  /**
   * Data template for `'checkbox'` type when checkbox is unchecked.
   *
   * @type {Boolean|String|Number}
   * @default false
   *
   * @example
   * ```js
   * uncheckedTemplate: 'bad'
   *
   * // if a checkbox-typed cell is not checked, then getDataAtCell(x,y),
   * // where x and y are the coordinates of the cell will return 'bad'.
   * ```
   */
  uncheckedTemplate: void 0,

  /**
   * @description
   * Object which describes if renderer should create checkbox element with label element as a parent.
   *
   * __Note__, this option only works for [checkbox-typed](https://docs.handsontable.com/demo-checkbox.html) cells.
   *
   * By default the [checkbox](https://docs.handsontable.com/demo-checkbox.html) renderer renders the checkbox without a label.
   *
   * Possible object properties:
   *  * `property` - Defines the property name of the data object, which will to be used as a label.
   *  (eg. `label: {property: 'name.last'}`). This option works only if data was passed as an array of objects.
   *  * `position` - String which describes where to place the label text (before or after checkbox element).
   * Valid values are `'before'` and '`after`' (defaults to `'after'`).
   *  * `value` - String or a Function which will be used as label text.
   *
   * @type {Object}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [{
   *   type: 'checkbox',
   *   // add "My label:" after the checkbox
   *   label: {position: 'after', value: 'My label: '}
   * }],
   * ```
   */
  label: void 0,

  /**
   * Display format for numeric typed renderers.
   *
   * __Note__, this option only works for [numeric-typed](https://docs.handsontable.com/demo-numeric.html) cells.
   *
   * Format is described by two properties:
   * * `pattern` - Handled by `numbro` for purpose of formatting numbers to desired pattern. List of supported patterns can be found [here](http://numbrojs.com/format.html#numbers).
   * * `culture` - Handled by `numbro` for purpose of formatting currencies. Examples showing how it works can be found [here](http://numbrojs.com/format.html#currency). List of supported cultures can be found [here](http://numbrojs.com/languages.html#supported-languages).
   *
   * __Note:__ Please keep in mind that this option is used only to format the displayed output! It has no effect on the input data provided for the cell. The numeric data can be entered to the table only as floats (separated by a dot or a comma) or integers, and are stored in the source dataset as JavaScript numbers.
   *
   * Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting.
   *
   * @since 0.35.0
   * @type {Object}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'numeric',
   *     // set desired format pattern and
   *     numericFormat: {
   *       pattern: '0,00',
   *       culture: 'en-US'
   *     }
   *   }
   * ],
   * ```
   */
  numericFormat: void 0,

  /**
   * Language for Handsontable translation. Possible language codes are [listed here](https://docs.handsontable.com/tutorial-internationalization.html#available-languages).
   *
   * @type {String}
   * @default 'en-US'
   *
   * @example
   * ```js
   * // set Polish language
   * language: 'pl-PL',
   * ```
   */
  language: 'en-US',

  /**
   * Data source for [select-typed](https://docs.handsontable.com/demo-select.html) cells.
   *
   * __Note__, this option only works for [select-typed](https://docs.handsontable.com/demo-select.html) cells.
   *
   * @type {String[]}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     editor: 'select',
   *     // add three select options to choose from
   *     selectOptions: ['A', 'B', 'C'],
   *   }
   * ],
   * ```
   */
  selectOptions: void 0,

  /**
   * Enables or disables the {@link AutoColumnSize} plugin. Default value is `undefined`, which has the same effect as `true`.
   * Disabling this plugin can increase performance, as no size-related calculations would be done.
   *
   * Column width calculations are divided into sync and async part. Each of those parts has their own advantages and
   * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous
   * operations don't block the browser UI.
   *
   * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value.
   *
   * You can also use the `useHeaders` option to take the column headers width into calculation.
   *
   * @type {Object|Boolean}
   * @default {syncLimit: 50}
   *
   * @example
   * ```js
   * // as a number (300 columns in sync, rest async)
   * autoColumnSize: {syncLimit: 300},
   *
   * // as a string (percent)
   * autoColumnSize: {syncLimit: '40%'},
   *
   * // use headers width while calculating the column width
   * autoColumnSize: {useHeaders: true},
   * ```
   */
  autoColumnSize: void 0,

  /**
   * Enables or disables {@link AutoRowSize} plugin. Default value is `undefined`, which has the same effect as `false`
   * (disabled). Enabling this plugin can decrease performance, as size-related calculations would be performed.
   *
   * Row height calculations are divided into sync and async stages. Each of these stages has their own advantages and
   * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous
   * operations don't block the browser UI.
   *
   * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value.
   *
   * @type {Object|Boolean}
   * @default {syncLimit: 500}
   *
   * @example
   * ```js
   * // as a number (300 columns in sync, rest async)
   * autoRowSize: {syncLimit: 300},
   *
   * // as a string (percent)
   * autoRowSize: {syncLimit: '40%'},
   * ```
   */
  autoRowSize: void 0,

  /**
   * Date validation format.
   *
   * __Note__, this option only works for [date-typed](https://docs.handsontable.com/demo-date.html) cells.
   *
   * @type {String}
   * @default 'DD/MM/YYYY'
   *
   * @example
   * ```js
   * columns: [{
   *   type: 'date',
   *   // localise date format
   *   dateFormat: 'MM/DD/YYYY'
   * }],
   * ```
   */
  dateFormat: 'DD/MM/YYYY',

  /**
   * If `true` then dates will be automatically formatted to match the desired format.
   *
   * __Note__, this option only works for [date-typed](https://docs.handsontable.com/demo-date.html) cells.
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * columns: [{
   *   type: 'date',
   *   dateFormat: 'YYYY-MM-DD',
   *   // force selected date format
   *   correctFormat: true
   * }],
   * ```
   */
  correctFormat: false,

  /**
   * Definition of default value which will fill the empty cells.
   *
   * __Note__, this option only works for [date-typed](https://docs.handsontable.com/demo-date.html) cells.
   *
   * @type {String}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'date',
   *     // always set this date for empty cells
   *     defaultDate: '2015-02-02'
   *   }
   * ],
   * ```
   */
  defaultDate: void 0,

  /**
   * If set to `true`, the value entered into the cell must match (case-sensitive) the autocomplete source.
   * Otherwise, cell won't pass the validation. When filtering the autocomplete source list, the editor will
   * be working in case-insensitive mode.
   *
   * __Note__, this option only works for [autocomplete-typed](https://docs.handsontable.com/demo-autocomplete.html) cells.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * columns: [{
   *   type: 'autocomplete',
   *   source: ['A', 'B', 'C'],
   *   // force selected value to match the source list
   *   strict: true
   * }],
   * ```
   */
  strict: void 0,

  /**
   * If set to `true`, data defined in `source` of the autocomplete or dropdown cell will be treated as HTML.
   *
   * __Warning:__ Enabling this option can cause serious XSS vulnerabilities.
   *
   * __Note__, this option only works for [autocomplete-typed](https://docs.handsontable.com/demo-autocomplete.html) cells.
   *
   * @type {Boolean}
   * @default false
   *
   * @example
   * ```js
   * columns: [{
   *   type: 'autocomplete',
   *   // use HTML in the source list
   *   allowHtml: true,
   *   source: ['<strong>foo</strong>', '<strong>bar</strong>']
   * }],
   * ```
   */
  allowHtml: false,

  /**
   * If typed `true` then virtual rendering mechanism for handsontable will be disabled.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * // disable virtual rows rendering
   * renderAllRows: true,
   * ```
   */
  renderAllRows: void 0,

  /**
   * Prevents table to overlap outside the parent element. If `'horizontal'` option is chosen then table will show
   * a horizontal scrollbar if parent's width is narrower then table's width.
   *
   * Possible values:
   *  * `false` - Disables functionality.
   *  * `horizontal` - Prevents horizontal overflow table.
   *  * `vertical` - Prevents vertical overflow table.
   *
   * @type {String|Boolean}
   * @default false
   *
   * @example
   * ```js
   * preventOverflow: 'horizontal',
   * ```
   */
  preventOverflow: false,

  /**
   * @description
   * Enables the functionality of the {@link BindRowsWithHeaders} plugin which allows binding the table rows with their headers.
   * If the plugin is enabled, the table row headers will "stick" to the rows, when they are hidden/moved. Basically,
   * if at the initialization row 0 has a header titled "A", it will have it no matter what you do with the table.
   *
   * @type {Boolean|String}
   * @default undefined
   *
   * @example
   * ```js
   * // keep row data and row headers in sync
   * bindRowsWithHeaders: true
   * ```
   */
  bindRowsWithHeaders: void 0,

  /**
   * @description
   * The {@link CollapsibleColumns} plugin allows collapsing of columns, covered by a header with the `colspan` property
   * defined.
   *
   * Clicking the "collapse/expand" button collapses (or expands) all "child" headers except the first one.
   *
   * Setting the `collapsibleColumns` property to `true` will display a "collapse/expand" button in every
   * header with a defined colspan` property.
   *
   * To limit this functionality to a smaller group of headers, define the `collapsibleColumns` property
   * as an array of objects, as in the example below.
   *
   * @type {Boolean|Object[]}
   * @default undefined
   *
   * @example
   * ```js
   * // enable collapsing for all headers
   * collapsibleColumns: true,
   *
   * // or
   * // enable collapsing for selected headers
   * collapsibleColumns: [
   *   {row: -4, col: 1, collapsible: true},
   *   {row: -3, col: 5, collapsible: true}
   * ],
   * ```
   */
  collapsibleColumns: void 0,

  /**
   * @description
   * Allows making pre-defined calculations on the cell values and display the results within Handsontable.
   *
   * Possible types:
   *  * `'sum'`
   *  * `'min'`
   *  * `'max'`
   *  * `'count'`
   *  * `'average'`
   *  * `'custom'` - add `customFunction`
   *
   * [See the demo for more information](https://docs.handsontable.com/pro/demo-summary-calculations.html).
   *
   * @type {Object[]|Function}
   * @default undefined
   *
   * @example
   * ```
   * columnSummary: [
   *   {
   *     destinationRow: 4,
   *     destinationColumn: 1,
   *     forceNumeric: true,
   *     reversedRowCoords: true,
   *     suppressDataTypeErrors: false,
   *     readOnly: true,
   *     roundFloat: false,
   *     type: 'custom',
   *     customFunction: function(endpoint) {
   *        return 100;
   *     }
   *   }
   * ],
   * ```
   */
  columnSummary: void 0,

  /**
   * This plugin allows adding a configurable dropdown menu to the table's column headers. The dropdown menu acts like
   * the {@link Options#contextMenu}, but is triggered by clicking the button in the header.
   *
   * @type {Boolean|Object|String[]}
   * @default undefined
   *
   * @example
   * ```js
   * // enable dropdown menu
   * dropdownMenu: true,
   *
   * // or
   * // enable and configure dropdown menu options
   * dropdownMenu: ['remove_col', '---------', 'make_read_only', 'alignment']
   * ```
   */
  dropdownMenu: void 0,

  /**
   * The {@link Filters} plugin allows filtering the table data either by the built-in component or with the API.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * // enable filters
   * filters: true,
   * ```
   */
  filters: void 0,

  /**
   * The {@link Formulas} plugin allows Handsontable to process formula expressions defined in the provided data.
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // enable formulas plugin
   * formulas: true,
   *
   * // or as an object with custom variables to be used in formula expressions
   * formulas: {
   *   variables: {
   *     FOO: 64,
   *     BAR: 'baz',
   *   }
   * },
   * ```
   */
  formulas: void 0,

  /**
   * @description
   * The {@link GanttChart} plugin enables a possibility to create a Gantt chart using a Handsontable instance. In this
   * case, the whole table becomes read-only.
   *
   * @type {Object}
   * @default undefined
   */
  ganttChart: void 0,

  /**
   * @description
   * Allows adding a tooltip to the table headers.
   *
   * Available options:
   * * the `rows` property defines if tooltips should be added to row headers,
   * * the `columns` property defines if tooltips should be added to column headers,
   * * the `onlyTrimmed` property defines if tooltips should be added only to headers, which content is trimmed by the header itself (the content being wider then the header).
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // enable tooltips for all headers
   * headerTooltips: true,
   *
   * // or
   * headerTooltips: {
   *   rows: false,
   *   columns: true,
   *   onlyTrimmed: true
   * }
   * ```
   */
  headerTooltips: void 0,

  /**
   * The {@link HiddenColumns} plugin allows hiding of certain columns. You can pass additional configuration with an
   * object notation. Options that are then available are:
   *  * `columns` - an array of rows that should be hidden on plugin initialization
   *  * `indicators` - enables small ui markers to indicate where are hidden columns
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // enable column hiding
   * hiddenColumns: true,
   *
   * // or
   * hiddenColumns: {
   *   // set columns that are hidden by default
   *   columns: [5, 10, 15],
   *   // show where are hidden columns
   *   indicators: true
   * }
   * ```
   */
  hiddenColumns: void 0,

  /**
   * The {@link HiddenRows} plugin allows hiding of certain rows. You can pass additional configuration with an
   * object notation. Options that are then available are:
   *  * `rows` - an array of rows that should be hidden on plugin initialization
   *  * `indicators` - enables small ui markers to indicate where are hidden columns
   *
   * @type {Boolean|Object}
   * @default undefined
   *
   * @example
   * ```js
   * // enable row hiding
   * hiddenRows: true,
   *
   * // or
   * hiddenRows: {
   *   // set rows that are hidden by default
   *   rows: [5, 10, 15],
   *   // show where are hidden rows
   *   indicators: true
   * }
   * ```
   */
  hiddenRows: void 0,

  /**
   * @description
   * Allows creating a nested header structure, using the HTML's colspan attribute.
   *
   * @type {Array[]}
   * @default undefined
   *
   * @example
   * ```
   * nestedHeaders: [
   *   ['A', {label: 'B', colspan: 8}, 'C'],
   *   ['D', {label: 'E', colspan: 4}, {label: 'F', colspan: 4}, 'G'],
   *   ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'R', 'S', 'T']
   * ],
   * ```
   */
  nestedHeaders: void 0,

  /**
   * @description
   * Plugin allowing hiding of certain rows.
   *
   * @type {Boolean|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // enable plugin
   * trimRows: true,
   *
   * // or
   * // trim selected rows on table initialization
   * trimRows: [5, 10, 15],
   * ```
   */
  trimRows: void 0,

  /**
   * @description
   * Allows setting a custom width of the row headers. You can provide a number or an array of widths, if many row
   * header levels are defined.
   *
   * @type {Number|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // set width for all row headers
   * rowHeaderWidth: 25,
   *
   * // or
   * // set width for selected headers only
   * rowHeaderWidth: [25, 30, 55],
   * ```
   */
  rowHeaderWidth: void 0,

  /**
   * @description
   * Allows setting a custom height of the column headers. You can provide a number or an array of heights, if many
   * column header levels are defined.
   *
   * @type {Number|Number[]}
   * @default undefined
   *
   * @example
   * ```js
   * // set shared height for all headers
   * columnHeaderHeight: 35,
   *
   * // or
   * // set height for each header individually
   * columnHeaderHeight: [35, 20, 55],
   *
   * // or
   * // skipped headers will fallback to default value
   * columnHeaderHeight: [35, undefined, 55],
   * ```
   */
  columnHeaderHeight: void 0,

  /**
   * @description
   * Enables the {@link ObserveChanges} plugin switches table into one-way data binding where changes are applied into
   * data source (from outside table) will be automatically reflected in the table.
   *
   * For every data change [afterChangesObserved](Hooks.html#event:afterChangesObserved) hook will be fired.
   *
   * @type {Boolean}
   * @default undefined
   *
   * @example
   * ```js
   * observeChanges: true,
   * ```
   */
  observeChanges: void 0,

  /**
   * If defined as `true`, the Autocomplete's suggestion list would be sorted by relevance (the closer to the left the
   * match is, the higher the suggestion).
   *
   * __Note__, this option only works for [autocomplete-typed](https://docs.handsontable.com/demo-autocomplete.html) cells.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'autocomplete',
   *     source: [ ... ],
   *     // keep options order as they were defined
   *     sortByRelevance: false
   *   }
   * ],
   * ```
   */
  sortByRelevance: true,

  /**
   * If defined as `true`, when the user types into the input area the Autocomplete's suggestion list is updated to only
   * include those choices starting with what has been typed; if defined as `false` all suggestions remain shown, with
   * those matching what has been typed marked in bold.
   *
   * __Note__, this option only works for [autocomplete-typed](https://docs.handsontable.com/demo-autocomplete.html) cells.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'autocomplete',
   *     source: [ ... ],
   *     // don't hide options that don't match search query
   *     filter: false
   *   }
   * ],
   * ```
   */
  filter: true,

  /**
   * If defined as `true`, filtering in the Autocomplete Editor will be case-sensitive.
   *
   * __Note__, this option only works for [autocomplete-typed](https://docs.handsontable.com/demo-autocomplete.html) cells.
   *
   * @type {Boolean}
   * @default: false
   *
   * @example
   * ```js
   * columns: [
   *   {
   *     type: 'autocomplete',
   *     source: [ ... ],
   *     // match case while searching autocomplete options
   *     filteringCaseSensitive: true
   *   }
   * ],
   * ```
   */
  filteringCaseSensitive: false,

  /**
   * @description
   * Disables or enables the drag to scroll functionality.
   *
   * @type {Boolean}
   * @default true
   *
   * @example
   * ```js
   * // don't scroll the viewport when selection gets to the viewport edge
   * dragToScroll: false,
   * ```
   */
  dragToScroll: true,

  /**
   * @description
   * Disable or enable the nested rows functionality - displaying nested structures in a two-dimensional data table.
   *
   * See [quick setup of the Nested rows](https://docs.handsontable.kbudnik/pro/next/demo-nested-rows.html).
   * @example
   * ```js
   * nestedRows: true,
   * ```
   *
   * @type {Boolean}
   * @default false
   */
  nestedRows: void 0
};
var _default = DefaultSettings;
exports.default = _default;

/***/ }),
/* 476 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.getTranslatedPhrase = getTranslatedPhrase;

var _array = __webpack_require__(3);

var _dictionariesManager = __webpack_require__(135);

var _phraseFormatters = __webpack_require__(578);

var _mixed = __webpack_require__(27);

/**
 * Get phrase for specified dictionary key.
 *
 * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'.
 * @param {String} dictionaryKey Constant which is dictionary key.
 * @param {*} argumentsForFormatters Arguments which will be handled by formatters.
 *
 * @returns {String}
 */
// eslint-disable-next-line import/prefer-default-export
function getTranslatedPhrase(languageCode, dictionaryKey, argumentsForFormatters) {
  var languageDictionary = (0, _dictionariesManager.getLanguageDictionary)(languageCode);

  if (languageDictionary === null) {
    return null;
  }

  var phrasePropositions = languageDictionary[dictionaryKey];

  if ((0, _mixed.isUndefined)(phrasePropositions)) {
    return null;
  }

  var formattedPhrase = getFormattedPhrase(phrasePropositions, argumentsForFormatters);

  if (Array.isArray(formattedPhrase)) {
    return formattedPhrase[0];
  }

  return formattedPhrase;
}
/**
 * Get formatted phrase from phrases propositions for specified dictionary key.
 *
 * @private
 * @param {Array|string} phrasePropositions List of phrase propositions.
 * @param {*} argumentsForFormatters Arguments which will be handled by formatters.
 *
 * @returns {Array|string}
 */


function getFormattedPhrase(phrasePropositions, argumentsForFormatters) {
  var formattedPhrasePropositions = phrasePropositions;
  (0, _array.arrayEach)((0, _phraseFormatters.getPhraseFormatters)(), function (formatter) {
    formattedPhrasePropositions = formatter(phrasePropositions, argumentsForFormatters);
  });
  return formattedPhrasePropositions;
}

/***/ }),
/* 477 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

exports.__esModule = true;
exports.extendNotExistingKeys = extendNotExistingKeys;
exports.createCellHeadersRange = createCellHeadersRange;
exports.normalizeLanguageCode = normalizeLanguageCode;
exports.applyLanguageSetting = applyLanguageSetting;
exports.warnUserAboutLanguageRegistration = warnUserAboutLanguageRegistration;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _mixed = __webpack_require__(27);

var _object = __webpack_require__(4);

var _console = __webpack_require__(55);

var _templateLiteralTag = __webpack_require__(67);

var _dictionariesManager = __webpack_require__(135);

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["Language with code \"", "\" was not found. You should register particular language \n    before using it. Read more about this issue at: https://docs.handsontable.com/i18n/missing-language-code."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * Perform shallow extend of a target object with only this extension's properties which doesn't exist in the target.
 *
 * @param {Object} target An object that will receive the new properties.
 * @param {Object} extension An object containing additional properties to merge into the target.
 */
// TODO: Maybe it should be moved to global helpers? It's changed `extend` function.
function extendNotExistingKeys(target, extension) {
  (0, _object.objectEach)(extension, function (value, key) {
    if ((0, _mixed.isUndefined)(target[key])) {
      target[key] = value;
    }
  });
  return target;
}
/**
 * Create range of values basing on cell indexes. For example, it will create below ranges for specified function arguments:
 *
 * createCellHeadersRange(2, 7) => `2-7`
 * createCellHeadersRange(7, 2) => `2-7`
 * createCellHeadersRange(0, 4, 'A', 'D') => `A-D`
 * createCellHeadersRange(4, 0, 'D', 'A') => `A-D`
 *
 * @param {number} firstRowIndex Index of "first" cell
 * @param {number} nextRowIndex Index of "next" cell
 * @param {*} fromValue Value which will represent "first" cell
 * @param {*} toValue Value which will represent "next" cell
 * @returns {String} Value representing range i.e. A-Z, 11-15.
 */


function createCellHeadersRange(firstRowIndex, nextRowIndex) {
  var fromValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : firstRowIndex;
  var toValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : nextRowIndex;
  // Will swap `fromValue` with `toValue` if it's necessary.
  var from = fromValue,
      to = toValue;

  if (firstRowIndex > nextRowIndex) {
    var _ref = [to, from];
    from = _ref[0];
    to = _ref[1];
  }

  return "".concat(from, "-").concat(to);
}
/**
 * Normalize language code. It takes handled languageCode proposition and change it to proper languageCode.
 * For example, when it takes `eN-us` as parameter it return `en-US`
 *
 * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'.
 * @returns {String}
 */


function normalizeLanguageCode(languageCode) {
  var languageCodePattern = /^([a-zA-Z]{2})-([a-zA-Z]{2})$/;
  var partsOfLanguageCode = languageCodePattern.exec(languageCode);

  if (partsOfLanguageCode) {
    return "".concat(partsOfLanguageCode[1].toLowerCase(), "-").concat(partsOfLanguageCode[2].toUpperCase());
  }

  return languageCode;
}
/**
 * Set proper start language code. User may set language code which is not proper.
 *
 * @param {Object} settings Settings object.
 * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'.
 * @returns {String}
 */


function applyLanguageSetting(settings, languageCode) {
  var normalizedLanguageCode = normalizeLanguageCode(languageCode);

  if ((0, _dictionariesManager.hasLanguageDictionary)(normalizedLanguageCode)) {
    settings.language = normalizedLanguageCode;
  } else {
    settings.language = _dictionariesManager.DEFAULT_LANGUAGE_CODE;
    warnUserAboutLanguageRegistration(languageCode);
  }
}
/**
 *
 * Warn user if there is no registered language.
 *
 * @param {String} languageCode Language code for specific language i.e. 'en-US', 'pt-BR', 'de-DE'.
 */


function warnUserAboutLanguageRegistration(languageCode) {
  if ((0, _mixed.isDefined)(languageCode)) {
    (0, _console.error)((0, _templateLiteralTag.toSingleLine)(_templateObject(), languageCode));
  }
}

/***/ }),
/* 478 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;

var _highlight = _interopRequireDefault(__webpack_require__(479));

exports.Highlight = _highlight.default;

var _selection = _interopRequireDefault(__webpack_require__(589));

exports.Selection = _selection.default;

var _mouseEventHandler = __webpack_require__(471);

exports.handleMouseEvent = _mouseEventHandler.handleMouseEvent;

var _utils = __webpack_require__(137);

exports.detectSelectionType = _utils.detectSelectionType;
exports.normalizeSelectionFactory = _utils.normalizeSelectionFactory;

/***/ }),
/* 479 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(133);

__webpack_require__(134);

__webpack_require__(480);

__webpack_require__(18);

__webpack_require__(580);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = exports.CUSTOM_SELECTION = exports.HEADER_TYPE = exports.FILL_TYPE = exports.CELL_TYPE = exports.AREA_TYPE = exports.ACTIVE_HEADER_TYPE = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _objectSpread2 = _interopRequireDefault(__webpack_require__(481));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _types = __webpack_require__(582);

var _array = __webpack_require__(3);

var ACTIVE_HEADER_TYPE = 'active-header';
exports.ACTIVE_HEADER_TYPE = ACTIVE_HEADER_TYPE;
var AREA_TYPE = 'area';
exports.AREA_TYPE = AREA_TYPE;
var CELL_TYPE = 'cell';
exports.CELL_TYPE = CELL_TYPE;
var FILL_TYPE = 'fill';
exports.FILL_TYPE = FILL_TYPE;
var HEADER_TYPE = 'header';
exports.HEADER_TYPE = HEADER_TYPE;
var CUSTOM_SELECTION = 'custom-selection';
/**
 * Highlight class responsible for managing Walkontable Selection classes.
 *
 * With Highlight object you can manipulate four different highlight types:
 *  - `cell` can be added only to a single cell at a time and it defines currently selected cell;
 *  - `fill` can occur only once and its highlight defines selection of autofill functionality (managed by the plugin with the same name);
 *  - `areas` can be added to multiple cells at a time. This type highlights selected cell or multiple cells.
 *    The multiple cells have to be defined as an uninterrupted order (regular shape). Otherwise, the new layer of
 *    that type should be created to manage not-consecutive selection;
 *  - `header` can occur multiple times. This type is designed to highlight only headers. Like `area` type it
 *    can appear with multiple highlights (accessed under different level layers).
 *
 * @class Highlight
 * @util
 */

exports.CUSTOM_SELECTION = CUSTOM_SELECTION;

var Highlight =
/*#__PURE__*/
function () {
  function Highlight(options) {
    (0, _classCallCheck2.default)(this, Highlight);

    /**
     * Options consumed by Highlight class and Walkontable Selection classes.
     *
     * @type {Object}
     */
    this.options = options;
    /**
     * The property which describes which layer level of the visual selection will be modified.
     * This option is valid only for `area` and `header` highlight types which occurs multiple times on
     * the table (as a non-consecutive selection).
     *
     * An order of the layers is the same as the order of added new non-consecutive selections.
     *
     * @type {Number}
     * @default 0
     */

    this.layerLevel = 0;
    /**
     * `cell` highlight object which describes attributes for the currently selected cell.
     * It can only occur only once on the table.
     *
     * @type {Selection}
     */

    this.cell = (0, _types.createHighlight)(CELL_TYPE, options);
    /**
     * `fill` highlight object which describes attributes for the borders for autofill functionality.
     * It can only occur only once on the table.
     *
     * @type {Selection}
     */

    this.fill = (0, _types.createHighlight)(FILL_TYPE, options);
    /**
     * Collection of the `area` highlights. That objects describes attributes for the borders and selection of
     * the multiple selected cells. It can occur multiple times on the table.
     *
     * @type {Map.<number, Selection>}
     */

    this.areas = new Map();
    /**
     * Collection of the `header` highlights. That objects describes attributes for the selection of
     * the multiple selected rows and columns in the table header. It can occur multiple times on the table.
     *
     * @type {Map.<number, Selection>}
     */

    this.headers = new Map();
    /**
     * Collection of the `active-header` highlights. That objects describes attributes for the selection of
     * the multiple selected rows and columns in the table header. The table headers which have selected all items in
     * a row will be marked as `active-header`.
     *
     * @type {Map.<number, Selection>}
     */

    this.activeHeaders = new Map();
    /**
     * Collection of the `custom-selection`, holder for example borders added through CustomBorders plugin.
     *
     * @type {Selection[]}
     */

    this.customSelections = [];
  }
  /**
   * Check if highlight cell rendering is disabled for specyfied highlight type.
   *
   * @param {String} highlightType Highlight type. Possible values are: `cell`, `area`, `fill` or `header`.
   * @return {Boolean}
   */


  (0, _createClass2.default)(Highlight, [{
    key: "isEnabledFor",
    value: function isEnabledFor(highlightType) {
      // Legacy compatibility.
      var type = highlightType === 'current' ? CELL_TYPE : highlightType;
      var disableHighlight = this.options.disableHighlight;

      if (typeof disableHighlight === 'string') {
        disableHighlight = [disableHighlight];
      }

      return disableHighlight === false || Array.isArray(disableHighlight) && !disableHighlight.includes(type);
    }
    /**
     * Set a new layer level to make access to the desire `area` and `header` highlights.
     *
     * @param {Number} [level=0] Layer level to use.
     * @returns {Highlight}
     */

  }, {
    key: "useLayerLevel",
    value: function useLayerLevel() {
      var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
      this.layerLevel = level;
      return this;
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the currently selected/edited cell.
     *
     * @return {Selection}
     */

  }, {
    key: "getCell",
    value: function getCell() {
      return this.cell;
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the autofill functionality.
     *
     * @return {Selection}
     */

  }, {
    key: "getFill",
    value: function getFill() {
      return this.fill;
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected cells.
     *
     * @return {Selection}
     */

  }, {
    key: "createOrGetArea",
    value: function createOrGetArea() {
      var layerLevel = this.layerLevel;
      var area;

      if (this.areas.has(layerLevel)) {
        area = this.areas.get(layerLevel);
      } else {
        area = (0, _types.createHighlight)(AREA_TYPE, (0, _objectSpread2.default)({
          layerLevel: layerLevel
        }, this.options));
        this.areas.set(layerLevel, area);
      }

      return area;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the cells.
     *
     * @return {Selection[]}
     */

  }, {
    key: "getAreas",
    value: function getAreas() {
      return (0, _toConsumableArray2.default)(this.areas.values());
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected header cells.
     *
     * @return {Selection}
     */

  }, {
    key: "createOrGetHeader",
    value: function createOrGetHeader() {
      var layerLevel = this.layerLevel;
      var header;

      if (this.headers.has(layerLevel)) {
        header = this.headers.get(layerLevel);
      } else {
        header = (0, _types.createHighlight)(HEADER_TYPE, (0, _objectSpread2.default)({}, this.options));
        this.headers.set(layerLevel, header);
      }

      return header;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers.
     *
     * @return {Selection[]}
     */

  }, {
    key: "getHeaders",
    value: function getHeaders() {
      return (0, _toConsumableArray2.default)(this.headers.values());
    }
    /**
     * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
     * of the multiple selected active header cells.
     *
     * @return {Selection}
     */

  }, {
    key: "createOrGetActiveHeader",
    value: function createOrGetActiveHeader() {
      var layerLevel = this.layerLevel;
      var header;

      if (this.activeHeaders.has(layerLevel)) {
        header = this.activeHeaders.get(layerLevel);
      } else {
        header = (0, _types.createHighlight)(ACTIVE_HEADER_TYPE, (0, _objectSpread2.default)({}, this.options));
        this.activeHeaders.set(layerLevel, header);
      }

      return header;
    }
    /**
     * Get all Walkontable Selection instances which describes the state of the visual highlight of the active headers.
     *
     * @return {Selection[]}
     */

  }, {
    key: "getActiveHeaders",
    value: function getActiveHeaders() {
      return (0, _toConsumableArray2.default)(this.activeHeaders.values());
    }
    /**
     * Get Walkontable Selection instance created for controlling highlight of the custom selection functionality.
     *
     * @return {Selection}
     */

  }, {
    key: "getCustomSelections",
    value: function getCustomSelections() {
      return (0, _toConsumableArray2.default)(this.customSelections.values());
    }
    /**
     * Add selection to the custom selection instance. The new selection are added to the end of the selection collection.
     *
     * @param {Object} options
     */

  }, {
    key: "addCustomSelection",
    value: function addCustomSelection(options) {
      this.customSelections.push((0, _types.createHighlight)(CUSTOM_SELECTION, (0, _objectSpread2.default)({}, options)));
    }
    /**
     * Perform cleaning visual highlights for the whole table.
     */

  }, {
    key: "clear",
    value: function clear() {
      this.cell.clear();
      this.fill.clear();
      (0, _array.arrayEach)(this.areas.values(), function (highlight) {
        return void highlight.clear();
      });
      (0, _array.arrayEach)(this.headers.values(), function (highlight) {
        return void highlight.clear();
      });
      (0, _array.arrayEach)(this.activeHeaders.values(), function (highlight) {
        return void highlight.clear();
      });
    }
    /**
     * This object can be iterate over using `for of` syntax or using internal `arrayEach` helper.
     */

  }, {
    key: Symbol.iterator,
    value: function value() {
      return [this.cell, this.fill].concat((0, _toConsumableArray2.default)(this.areas.values()), (0, _toConsumableArray2.default)(this.headers.values()), (0, _toConsumableArray2.default)(this.activeHeaders.values()), (0, _toConsumableArray2.default)(this.customSelections))[Symbol.iterator]();
    }
  }]);
  return Highlight;
}();

var _default = Highlight;
exports.default = _default;

/***/ }),
/* 480 */
/***/ (function(module, exports, __webpack_require__) {

// `Symbol.iterator` well-known symbol
// https://tc39.github.io/ecma262/#sec-symbol.iterator
__webpack_require__(474)('iterator');


/***/ }),
/* 481 */
/***/ (function(module, exports, __webpack_require__) {

var defineProperty = __webpack_require__(71);

function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i] != null ? arguments[i] : {};
    var ownKeys = Object.keys(source);

    if (typeof Object.getOwnPropertySymbols === 'function') {
      ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
        return Object.getOwnPropertyDescriptor(source, sym).enumerable;
      }));
    }

    ownKeys.forEach(function (key) {
      defineProperty(target, key, source[key]);
    });
  }

  return target;
}

module.exports = _objectSpread;

/***/ }),
/* 482 */
/***/ (function(module, exports, __webpack_require__) {

var DOMIterables = __webpack_require__(191);
var forEach = __webpack_require__(593);
var hide = __webpack_require__(61);
var global = __webpack_require__(32);

for (var COLLECTION_NAME in DOMIterables) {
  var Collection = global[COLLECTION_NAME];
  var CollectionPrototype = Collection && Collection.prototype;
  // some Chrome versions have non-configurable methods on DOMTokenList
  if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try {
    hide(CollectionPrototype, 'forEach', forEach);
  } catch (e) {
    CollectionPrototype.forEach = forEach;
  }
}


/***/ }),
/* 483 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(76);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var _mixed = __webpack_require__(27);

/**
 * @class SamplesGenerator
 * @util
 */
var SamplesGenerator =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(SamplesGenerator, null, [{
    key: "SAMPLE_COUNT",

    /**
     * Number of samples to take of each value length.
     *
     * @type {Number}
     */
    get: function get() {
      return 3;
    }
  }]);

  function SamplesGenerator(dataFactory) {
    (0, _classCallCheck2.default)(this, SamplesGenerator);

    /**
     * Samples prepared for calculations.
     *
     * @type {Map}
     * @default {null}
     */
    this.samples = null;
    /**
     * Function which give the data to collect samples.
     *
     * @type {Function}
     */

    this.dataFactory = dataFactory;
    /**
     * Custom number of samples to take of each value length.
     *
     * @type {Number}
     * @default {null}
     */

    this.customSampleCount = null;
    /**
     * `true` if duplicate samples collection should be allowed, `false` otherwise.
     *
     * @type {Boolean}
     * @default {false}
     */

    this.allowDuplicates = false;
  }
  /**
   * Get the sample count for this instance.
   *
   * @returns {Number}
   */


  (0, _createClass2.default)(SamplesGenerator, [{
    key: "getSampleCount",
    value: function getSampleCount() {
      if (this.customSampleCount) {
        return this.customSampleCount;
      }

      return SamplesGenerator.SAMPLE_COUNT;
    }
    /**
     * Set the sample count.
     *
     * @param {Number} sampleCount Number of samples to be collected.
     */

  }, {
    key: "setSampleCount",
    value: function setSampleCount(sampleCount) {
      this.customSampleCount = sampleCount;
    }
    /**
     * Set if the generator should accept duplicate values.
     *
     * @param {Boolean} allowDuplicates `true` to allow duplicate values.
     */

  }, {
    key: "setAllowDuplicates",
    value: function setAllowDuplicates(allowDuplicates) {
      this.allowDuplicates = allowDuplicates;
    }
    /**
     * Generate samples for row. You can control which area should be sampled by passing `rowRange` object and `colRange` object.
     *
     * @param {Object|Number} rowRange
     * @param {Object} colRange
     * @returns {Object}
     */

  }, {
    key: "generateRowSamples",
    value: function generateRowSamples(rowRange, colRange) {
      return this.generateSamples('row', colRange, rowRange);
    }
    /**
     * Generate samples for column. You can control which area should be sampled by passing `colRange` object and `rowRange` object.
     *
     * @param {Object} colRange Column index.
     * @param {Object} rowRange Column index.
     * @returns {Object}
     */

  }, {
    key: "generateColumnSamples",
    value: function generateColumnSamples(colRange, rowRange) {
      return this.generateSamples('col', rowRange, colRange);
    }
    /**
     * Generate collection of samples.
     *
     * @param {String} type Type to generate. Can be `col` or `row`.
     * @param {Object} range
     * @param {Object|Number} specifierRange
     * @returns {Map}
     */

  }, {
    key: "generateSamples",
    value: function generateSamples(type, range, specifierRange) {
      var _this = this;

      var samples = new Map();

      var _ref = typeof specifierRange === 'number' ? {
        from: specifierRange,
        to: specifierRange
      } : specifierRange,
          from = _ref.from,
          to = _ref.to;

      (0, _number.rangeEach)(from, to, function (index) {
        var sample = _this.generateSample(type, range, index);

        samples.set(index, sample);
      });
      return samples;
    }
    /**
     * Generate sample for specified type (`row` or `col`).
     *
     * @param {String} type Samples type `row` or `col`.
     * @param {Object} range
     * @param {Number} specifierValue
     * @returns {Map}
     */

  }, {
    key: "generateSample",
    value: function generateSample(type, range, specifierValue) {
      var _this2 = this;

      if (type !== 'row' && type !== 'col') {
        throw new Error('Unsupported sample type');
      }

      var samples = new Map();
      var computedKey = type === 'row' ? 'col' : 'row';
      var sampledValues = [];
      (0, _number.rangeEach)(range.from, range.to, function (index) {
        var _ref2 = type === 'row' ? _this2.dataFactory(specifierValue, index) : _this2.dataFactory(index, specifierValue),
            value = _ref2.value,
            bundleCountSeed = _ref2.bundleCountSeed;

        var hasCustomBundleSeed = bundleCountSeed > 0;
        var length;

        if ((0, _object.isObject)(value)) {
          length = Object.keys(value).length;
        } else if (Array.isArray(value)) {
          length = value.length;
        } else {
          length = (0, _mixed.stringify)(value).length;
        }

        if (hasCustomBundleSeed) {
          length += bundleCountSeed;
        }

        if (!samples.has(length)) {
          samples.set(length, {
            needed: _this2.getSampleCount(),
            strings: []
          });
        }

        var sample = samples.get(length);

        if (sample.needed) {
          var duplicate = sampledValues.indexOf(value) > -1;

          if (!duplicate || _this2.allowDuplicates || hasCustomBundleSeed) {
            sample.strings.push((0, _defineProperty2.default)({
              value: value
            }, computedKey, index));
            sampledValues.push(value);
            sample.needed -= 1;
          }
        }
      });
      return samples;
    }
  }]);
  return SamplesGenerator;
}();

var _default = SamplesGenerator;
exports.default = _default;

/***/ }),
/* 484 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(16);

__webpack_require__(164);

__webpack_require__(40);

__webpack_require__(64);

__webpack_require__(70);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(485);

__webpack_require__(470);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _objectSpread2 = _interopRequireDefault(__webpack_require__(481));

var _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(602));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _mixed = __webpack_require__(27);

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _keyStateObserver = __webpack_require__(136);

var _columnStatesManager = __webpack_require__(604);

var _utils = __webpack_require__(165);

var _domHelpers = __webpack_require__(605);

var _rowsMapper = _interopRequireDefault(__webpack_require__(606));

var _rootComparator = __webpack_require__(607);

var _sortService = __webpack_require__(88);

var APPEND_COLUMN_CONFIG_STRATEGY = 'append';
var REPLACE_COLUMN_CONFIG_STRATEGY = 'replace';
var PLUGIN_KEY = 'columnSorting';
(0, _sortService.registerRootComparator)(PLUGIN_KEY, _rootComparator.rootComparator);

_pluginHooks.default.getSingleton().register('beforeColumnSort');

_pluginHooks.default.getSingleton().register('afterColumnSort'); // DIFF - MultiColumnSorting & ColumnSorting: changed configuration documentation.

/**
 * @plugin ColumnSorting
 *
 * @description
 * This plugin sorts the view by columns (but does not sort the data source!). To enable the plugin, set the
 * {@link Options#columnSorting} property to the correct value (see the examples below).
 *
 * @example
 * ```js
 * // as boolean
 * columnSorting: true
 *
 * // as an object with initial sort config (sort ascending for column at index 1)
 * columnSorting: {
 *   initialConfig: {
 *     column: 1,
 *     sortOrder: 'asc'
 *   }
 * }
 *
 * // as an object which define specific sorting options for all columns
 * columnSorting: {
 *   sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table (by default)
 *   indicator: true, // true = shows indicator for all columns (by default), false = don't show indicator for columns
 *   headerAction: true, // true = allow to click on the headers to sort (by default), false = turn off possibility to click on the headers to sort
 *   compareFunctionFactory: function(sortOrder, columnMeta) {
 *     return function(value, nextValue) {
 *       // Some value comparisons which will return -1, 0 or 1...
 *     }
 *   }
 * }
 *
 * // as an object passed to the `column` property, allows specifying a custom options for the desired column.
 * // please take a look at documentation of `column` property: https://docs.handsontable.com/pro/Options.html#columns
 * columns: [{
 *   columnSorting: {
 *     indicator: false, // disable indicator for the first column,
 *     sortEmptyCells: true,
 *     headerAction: false, // clicks on the first column won't sort
 *     compareFunctionFactory: function(sortOrder, columnMeta) {
 *       return function(value, nextValue) {
 *         return 0; // Custom compare function for the first column (don't sort)
 *       }
 *     }
 *   }
 * }]```
 *
 * @dependencies ObserveChanges
 */


var ColumnSorting =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ColumnSorting, _BasePlugin);

  function ColumnSorting(hotInstance) {
    var _this2;

    (0, _classCallCheck2.default)(this, ColumnSorting);
    _this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ColumnSorting).call(this, hotInstance));
    /**
     * Instance of column state manager.
     *
     * @private
     * @type {ColumnStatesManager}
     */

    _this2.columnStatesManager = new _columnStatesManager.ColumnStatesManager();
    /**
     * Object containing visual row indexes mapped to data source indexes.
     *
     * @private
     * @type {RowsMapper}
     */

    _this2.rowsMapper = new _rowsMapper.default((0, _assertThisInitialized2.default)(_this2));
    /**
     * It blocks the plugin translation, this flag is checked inside `onModifyRow` callback.
     *
     * @private
     * @type {Boolean}
     */

    _this2.blockPluginTranslation = true;
    /**
     * Cached column properties from plugin like i.e. `indicator`, `headerAction`.
     *
     * @private
     * @type {Map<number, Object>}
     */

    _this2.columnMetaCache = new Map();
    /**
     * Main settings key designed for the plugin.
     *
     * @private
     * @type {String}
     */

    _this2.pluginKey = PLUGIN_KEY;
    return _this2;
  }
  /**
   * Checks if the plugin is enabled in the Handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ColumnSorting#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ColumnSorting, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings()[this.pluginKey];
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this3 = this;

      if (this.enabled) {
        return;
      }

      if ((0, _mixed.isUndefined)(this.hot.getSettings().observeChanges)) {
        this.enableObserveChangesPlugin();
      }

      this.addHook('afterTrimRow', function () {
        return _this3.sortByPresetSortStates();
      });
      this.addHook('afterUntrimRow', function () {
        return _this3.sortByPresetSortStates();
      });
      this.addHook('modifyRow', function (row, source) {
        return _this3.onModifyRow(row, source);
      });
      this.addHook('unmodifyRow', function (row, source) {
        return _this3.onUnmodifyRow(row, source);
      });
      this.addHook('afterGetColHeader', function (column, TH) {
        return _this3.onAfterGetColHeader(column, TH);
      });
      this.addHook('beforeOnCellMouseDown', function (event, coords, TD, controller) {
        return _this3.onBeforeOnCellMouseDown(event, coords, TD, controller);
      });
      this.addHook('afterOnCellMouseDown', function (event, target) {
        return _this3.onAfterOnCellMouseDown(event, target);
      });
      this.addHook('afterCreateRow', function (index, amount) {
        return _this3.onAfterCreateRow(index, amount);
      });
      this.addHook('afterRemoveRow', function (index, amount) {
        return _this3.onAfterRemoveRow(index, amount);
      });
      this.addHook('afterInit', function () {
        return _this3.loadOrSortBySettings();
      });
      this.addHook('afterLoadData', function (initialLoad) {
        return _this3.onAfterLoadData(initialLoad);
      });
      this.addHook('afterCreateCol', function () {
        return _this3.onAfterCreateCol();
      });
      this.addHook('afterRemoveCol', function () {
        return _this3.onAfterRemoveCol();
      }); // TODO: Workaround? It should be refactored / described.

      if (this.hot.view) {
        this.loadOrSortBySettings();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSorting.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      var _this4 = this;

      var clearColHeader = function clearColHeader(column, TH) {
        var headerSpanElement = (0, _utils.getHeaderSpanElement)(TH);

        if ((0, _utils.isFirstLevelColumnHeader)(column, TH) === false || headerSpanElement === null) {
          return;
        }

        _this4.updateHeaderClasses(headerSpanElement);
      }; // Changing header width and removing indicator.


      this.hot.addHook('afterGetColHeader', clearColHeader);
      this.hot.addHookOnce('afterRender', function () {
        _this4.hot.removeHook('afterGetColHeader', clearColHeader);
      });
      this.rowsMapper.clearMap();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSorting.prototype), "disablePlugin", this).call(this);
    } // DIFF - MultiColumnSorting & ColumnSorting: changed function documentation.

    /**
     * Sorts the table by chosen columns and orders.
     *
     * @param {undefined|Object} sortConfig Single column sort configuration. The configuration object contains `column` and `sortOrder` properties.
     * First of them contains visual column index, the second one contains sort order (`asc` for ascending, `desc` for descending).
     *
     * **Note**: Please keep in mind that every call of `sort` function set an entirely new sort order. Previous sort configs aren't preserved.
     *
     * @example
     * ```js
     * // sort ascending first visual column
     * hot.getPlugin('columnSorting').sort({ column: 0, sortOrder: 'asc' });
     * ```
     *
     * @fires Hooks#beforeColumnSort
     * @fires Hooks#afterColumnSort
     */

  }, {
    key: "sort",
    value: function sort(sortConfig) {
      var _this5 = this;

      var currentSortConfig = this.getSortConfig(); // We always pass configs defined as an array to `beforeColumnSort` and `afterColumnSort` hooks.

      var destinationSortConfigs = this.getNormalizedSortConfigs(sortConfig);
      var sortPossible = this.areValidSortConfigs(destinationSortConfigs);
      var allowSort = this.hot.runHooks('beforeColumnSort', currentSortConfig, destinationSortConfigs, sortPossible);

      if (allowSort === false) {
        return;
      }

      if (sortPossible) {
        var translateColumnToPhysical = function translateColumnToPhysical(_ref) {
          var visualColumn = _ref.column,
              restOfProperties = (0, _objectWithoutProperties2.default)(_ref, ["column"]);
          return (0, _objectSpread2.default)({
            column: _this5.hot.toPhysicalColumn(visualColumn)
          }, restOfProperties);
        };

        var internalSortStates = (0, _array.arrayMap)(destinationSortConfigs, function (columnSortConfig) {
          return translateColumnToPhysical(columnSortConfig);
        });
        this.columnStatesManager.setSortStates(internalSortStates);
        this.sortByPresetSortStates();
        this.saveAllSortSettings();
        this.hot.render();
        this.hot.view.wt.draw(true); // TODO: Workaround? One test won't pass after removal. It should be refactored / described.
      }

      this.hot.runHooks('afterColumnSort', currentSortConfig, this.getSortConfig(), sortPossible);
    }
    /**
     * Clear the sort performed on the table.
     */

  }, {
    key: "clearSort",
    value: function clearSort() {
      this.sort([]);
    }
    /**
     * Checks if the table is sorted (any column have to be sorted).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSorted",
    value: function isSorted() {
      return this.enabled && !this.columnStatesManager.isListOfSortedColumnsEmpty();
    }
    /**
     * Get sort configuration for particular column or for all sorted columns. Objects contain `column` and `sortOrder` properties.
     *
     * **Note**: Please keep in mind that returned objects expose **visual** column index under the `column` key. They are handled by the `sort` function.
     *
     * @param {Number} [column] Visual column index.
     * @returns {undefined|Object|Array}
     */

  }, {
    key: "getSortConfig",
    value: function getSortConfig(column) {
      var _this6 = this;

      var translateColumnToVisual = function translateColumnToVisual(_ref2) {
        var physicalColumn = _ref2.column,
            restOfProperties = (0, _objectWithoutProperties2.default)(_ref2, ["column"]);
        return (0, _objectSpread2.default)({
          column: _this6.hot.toVisualColumn(physicalColumn)
        }, restOfProperties);
      };

      if ((0, _mixed.isDefined)(column)) {
        var physicalColumn = this.hot.toPhysicalColumn(column);
        var columnSortState = this.columnStatesManager.getColumnSortState(physicalColumn);

        if ((0, _mixed.isDefined)(columnSortState)) {
          return translateColumnToVisual(columnSortState);
        }

        return;
      }

      var sortStates = this.columnStatesManager.getSortStates();
      return (0, _array.arrayMap)(sortStates, function (columnState) {
        return translateColumnToVisual(columnState);
      });
    }
    /**
     * @description
     * Warn: Useful mainly for providing server side sort implementation (see in the example below). It doesn't sort the data set. It just sets sort configuration for all sorted columns.
     * Note: Please keep in mind that this method doesn't re-render the table.
     *
     * @example
     * ```js
     * beforeColumnSort: function(currentSortConfig, destinationSortConfigs) {
     *   const columnSortPlugin = this.getPlugin('columnSorting');
     *
     *   columnSortPlugin.setSortConfig(destinationSortConfigs);
     *
     *   // const newData = ... // Calculated data set, ie. from an AJAX call.
     *
     *   this.loadData(newData); // Load new data set and re-render the table.
     *
     *   return false; // The blockade for the default sort action.
     * }```
     *
     * @param {undefined|Object|Array} sortConfig Single column sort configuration or full sort configuration (for all sorted columns).
     * The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
     * sort order (`asc` for ascending, `desc` for descending).
     */

  }, {
    key: "setSortConfig",
    value: function setSortConfig(sortConfig) {
      var _this7 = this;

      // We always set configs defined as an array.
      var destinationSortConfigs = this.getNormalizedSortConfigs(sortConfig);

      if (this.areValidSortConfigs(destinationSortConfigs)) {
        var translateColumnToPhysical = function translateColumnToPhysical(_ref3) {
          var visualColumn = _ref3.column,
              restOfProperties = (0, _objectWithoutProperties2.default)(_ref3, ["column"]);
          return (0, _objectSpread2.default)({
            column: _this7.hot.toPhysicalColumn(visualColumn)
          }, restOfProperties);
        };

        var internalSortStates = (0, _array.arrayMap)(destinationSortConfigs, function (columnSortConfig) {
          return translateColumnToPhysical(columnSortConfig);
        });
        this.columnStatesManager.setSortStates(internalSortStates);
      }
    }
    /**
     * Get normalized sort configs.
     *
     * @private
     * @param {Object|Array} [sortConfig=[]] Single column sort configuration or full sort configuration (for all sorted columns).
     * The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
     * sort order (`asc` for ascending, `desc` for descending).
     * @returns {Array}
     */

  }, {
    key: "getNormalizedSortConfigs",
    value: function getNormalizedSortConfigs() {
      var sortConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

      if (Array.isArray(sortConfig)) {
        return sortConfig.slice(0, 1);
      }

      return [sortConfig].slice(0, 1);
    }
    /**
     * Get if sort configs are valid.
     *
     * @private
     * @param {Array} sortConfigs Sort configuration for all sorted columns. Objects contain `column` and `sortOrder` properties.
     * @returns {Boolean}
     */

  }, {
    key: "areValidSortConfigs",
    value: function areValidSortConfigs(sortConfigs) {
      if (Array.isArray(sortConfigs) === false) {
        return false;
      }

      var sortedColumns = sortConfigs.map(function (_ref4) {
        var column = _ref4.column;
        return column;
      });
      var numberOfColumns = this.hot.countCols();
      var onlyExistingVisualIndexes = sortedColumns.every(function (visualColumn) {
        return visualColumn <= numberOfColumns && visualColumn >= 0;
      });
      return (0, _utils.areValidSortStates)(sortConfigs) && onlyExistingVisualIndexes; // We don't translate visual indexes to physical indexes.
    }
    /**
     * Saves all sorting settings. Saving works only when {@link Options#persistentState} option is enabled.
     *
     * @private
     * @fires Hooks#persistentStateSave
     */

  }, {
    key: "saveAllSortSettings",
    value: function saveAllSortSettings() {
      var allSortSettings = this.columnStatesManager.getAllColumnsProperties();
      allSortSettings.initialConfig = this.columnStatesManager.getSortStates();
      this.hot.runHooks('persistentStateSave', 'columnSorting', allSortSettings);
    }
    /**
     * Get all saved sorting settings. Loading works only when {@link Options#persistentState} option is enabled.
     *
     * @private
     * @returns {Object} Previously saved sort settings.
     *
     * @fires Hooks#persistentStateLoad
     */

  }, {
    key: "getAllSavedSortSettings",
    value: function getAllSavedSortSettings() {
      var _this8 = this;

      var storedAllSortSettings = {};
      this.hot.runHooks('persistentStateLoad', 'columnSorting', storedAllSortSettings);
      var allSortSettings = storedAllSortSettings.value;

      var translateColumnToVisual = function translateColumnToVisual(_ref5) {
        var physicalColumn = _ref5.column,
            restOfProperties = (0, _objectWithoutProperties2.default)(_ref5, ["column"]);
        return (0, _objectSpread2.default)({
          column: _this8.hot.toVisualColumn(physicalColumn)
        }, restOfProperties);
      };

      if ((0, _mixed.isDefined)(allSortSettings) && Array.isArray(allSortSettings.initialConfig)) {
        allSortSettings.initialConfig = (0, _array.arrayMap)(allSortSettings.initialConfig, translateColumnToVisual);
      }

      return allSortSettings;
    }
    /**
     * Get next sort configuration for particular column. Object contain `column` and `sortOrder` properties.
     *
     * **Note**: Please keep in mind that returned object expose **visual** column index under the `column` key.
     *
     * @private
     * @param {Number} column Visual column index.
     * @returns {undefined|Object}
     */

  }, {
    key: "getColumnNextConfig",
    value: function getColumnNextConfig(column) {
      var physicalColumn = this.hot.toPhysicalColumn(column);

      if (this.columnStatesManager.isColumnSorted(physicalColumn)) {
        var columnSortConfig = this.getSortConfig(column);
        var sortOrder = (0, _utils.getNextSortOrder)(columnSortConfig.sortOrder);

        if ((0, _mixed.isDefined)(sortOrder)) {
          columnSortConfig.sortOrder = sortOrder;
          return columnSortConfig;
        }

        return;
      }

      var nrOfColumns = this.hot.countCols();

      if (Number.isInteger(column) && column >= 0 && column < nrOfColumns) {
        return {
          column: column,
          sortOrder: (0, _utils.getNextSortOrder)()
        };
      }
    }
    /**
     * Get sort configuration with "next order" for particular column.
     *
     * @private
     * @param {Number} columnToChange Visual column index of column which order will be changed.
     * @param {String} strategyId ID of strategy. Possible values: 'append' and 'replace'. The first one
     * change order of particular column and change it's position in the sort queue to the last one. The second one
     * just change order of particular column.
     *
     * **Note**: Please keep in mind that returned objects expose **visual** column index under the `column` key.
     *
     * @returns {Array}
     */

  }, {
    key: "getNextSortConfig",
    value: function getNextSortConfig(columnToChange) {
      var strategyId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : APPEND_COLUMN_CONFIG_STRATEGY;
      var physicalColumn = this.hot.toPhysicalColumn(columnToChange);
      var indexOfColumnToChange = this.columnStatesManager.getIndexOfColumnInSortQueue(physicalColumn);
      var isColumnSorted = this.columnStatesManager.isColumnSorted(physicalColumn);
      var currentSortConfig = this.getSortConfig();
      var nextColumnConfig = this.getColumnNextConfig(columnToChange);

      if (isColumnSorted) {
        if ((0, _mixed.isUndefined)(nextColumnConfig)) {
          return [].concat((0, _toConsumableArray2.default)(currentSortConfig.slice(0, indexOfColumnToChange)), (0, _toConsumableArray2.default)(currentSortConfig.slice(indexOfColumnToChange + 1)));
        }

        if (strategyId === APPEND_COLUMN_CONFIG_STRATEGY) {
          return [].concat((0, _toConsumableArray2.default)(currentSortConfig.slice(0, indexOfColumnToChange)), (0, _toConsumableArray2.default)(currentSortConfig.slice(indexOfColumnToChange + 1)), [nextColumnConfig]);
        } else if (strategyId === REPLACE_COLUMN_CONFIG_STRATEGY) {
          return [].concat((0, _toConsumableArray2.default)(currentSortConfig.slice(0, indexOfColumnToChange)), [nextColumnConfig], (0, _toConsumableArray2.default)(currentSortConfig.slice(indexOfColumnToChange + 1)));
        }
      }

      if ((0, _mixed.isDefined)(nextColumnConfig)) {
        return currentSortConfig.concat(nextColumnConfig);
      }

      return currentSortConfig;
    }
    /**
     * Saves to cache part of plugins related properties, properly merged from cascade settings.
     *
     * @private
     * @param {Number} column Visual column index.
     * @returns {Object}
     */
    // TODO: Workaround. Inheriting of non-primitive cell meta values doesn't work. Using this function we don't count
    // merged properties few times.

  }, {
    key: "setMergedPluginSettings",
    value: function setMergedPluginSettings(column) {
      var physicalColumnIndex = this.hot.toPhysicalColumn(column);
      var pluginMainSettings = this.hot.getSettings()[this.pluginKey];
      var storedColumnProperties = this.columnStatesManager.getAllColumnsProperties();
      var cellMeta = this.hot.getCellMeta(0, column);
      var columnMeta = Object.getPrototypeOf(cellMeta);
      var columnMetaHasPluginSettings = Object.hasOwnProperty.call(columnMeta, this.pluginKey);
      var pluginColumnConfig = columnMetaHasPluginSettings ? columnMeta[this.pluginKey] : {};
      this.columnMetaCache.set(physicalColumnIndex, Object.assign(storedColumnProperties, pluginMainSettings, pluginColumnConfig));
    }
    /**
     * Get copy of settings for first cell in the column.
     *
     * @private
     * @param {Number} column Visual column index.
     * @returns {Object}
     */
    // TODO: Workaround. Inheriting of non-primitive cell meta values doesn't work. Instead of getting properties from
    // column meta we call this function.

  }, {
    key: "getFirstCellSettings",
    value: function getFirstCellSettings(column) {
      // TODO: Remove test named: "should not break the dataset when inserted new row" (#5431).
      var actualBlockTranslationFlag = this.blockPluginTranslation;
      this.blockPluginTranslation = true;

      if (this.columnMetaCache.size === 0 || this.columnMetaCache.size < this.hot.countCols()) {
        this.rebuildColumnMetaCache();
      }

      var cellMeta = this.hot.getCellMeta(0, column);
      this.blockPluginTranslation = actualBlockTranslationFlag;
      var cellMetaCopy = Object.create(cellMeta);
      cellMetaCopy[this.pluginKey] = this.columnMetaCache.get(this.hot.toPhysicalColumn(column));
      return cellMetaCopy;
    }
    /**
     * Rebuild the column meta cache for all the columns.
     *
     * @private
     */

  }, {
    key: "rebuildColumnMetaCache",
    value: function rebuildColumnMetaCache() {
      var _this9 = this;

      var numberOfColumns = this.hot.countCols();

      if (numberOfColumns === 0) {
        this.columnMetaCache.clear();
      } else {
        (0, _number.rangeEach)(numberOfColumns - 1, function (visualColumnIndex) {
          return _this9.setMergedPluginSettings(visualColumnIndex);
        });
      }
    }
    /**
     * Get number of rows which should be sorted.
     *
     * @private
     * @param {Number} numberOfRows Total number of displayed rows.
     * @returns {Number}
     */

  }, {
    key: "getNumberOfRowsToSort",
    value: function getNumberOfRowsToSort(numberOfRows) {
      var settings = this.hot.getSettings(); // `maxRows` option doesn't take into account `minSpareRows` option in this case.

      if (settings.maxRows <= numberOfRows) {
        return settings.maxRows;
      }

      return numberOfRows - settings.minSpareRows;
    }
    /**
     * Performs the sorting using a stable sort function basing on internal state of sorting.
     *
     * @private
     */

  }, {
    key: "sortByPresetSortStates",
    value: function sortByPresetSortStates() {
      var _this10 = this;

      if (this.columnStatesManager.isListOfSortedColumnsEmpty()) {
        this.rowsMapper.clearMap();
        return;
      }

      var indexesWithData = [];
      var sortedColumnsList = this.columnStatesManager.getSortedColumns();
      var numberOfRows = this.hot.countRows(); // Function `getDataAtCell` won't call the indices translation inside `onModifyRow` callback - we check the `blockPluginTranslation`
      // flag inside it (we just want to get data not already modified by `columnSorting` plugin translation).

      this.blockPluginTranslation = true;

      var getDataForSortedColumns = function getDataForSortedColumns(visualRowIndex) {
        return (0, _array.arrayMap)(sortedColumnsList, function (physicalColumn) {
          return _this10.hot.getDataAtCell(visualRowIndex, _this10.hot.toVisualColumn(physicalColumn));
        });
      };

      for (var visualRowIndex = 0; visualRowIndex < this.getNumberOfRowsToSort(numberOfRows); visualRowIndex += 1) {
        indexesWithData.push([visualRowIndex].concat(getDataForSortedColumns(visualRowIndex)));
      }

      (0, _sortService.sort)(indexesWithData, this.pluginKey, (0, _array.arrayMap)(sortedColumnsList, function (physicalColumn) {
        return _this10.columnStatesManager.getSortOrderOfColumn(physicalColumn);
      }), (0, _array.arrayMap)(sortedColumnsList, function (physicalColumn) {
        return _this10.getFirstCellSettings(_this10.hot.toVisualColumn(physicalColumn));
      })); // Append spareRows

      for (var _visualRowIndex = indexesWithData.length; _visualRowIndex < numberOfRows; _visualRowIndex += 1) {
        indexesWithData.push([_visualRowIndex].concat(getDataForSortedColumns(_visualRowIndex)));
      } // The blockade of the indices translation is released.


      this.blockPluginTranslation = false; // Save all indexes to arrayMapper, a completely new sequence is set by the plugin

      this.rowsMapper._arrayMap = (0, _array.arrayMap)(indexesWithData, function (indexWithData) {
        return indexWithData[0];
      });
    }
    /**
     * Load saved settings or sort by predefined plugin configuration.
     *
     * @private
     */

  }, {
    key: "loadOrSortBySettings",
    value: function loadOrSortBySettings() {
      this.columnMetaCache.clear();
      var storedAllSortSettings = this.getAllSavedSortSettings();

      if ((0, _object.isObject)(storedAllSortSettings)) {
        this.sortBySettings(storedAllSortSettings);
      } else {
        var allSortSettings = this.hot.getSettings()[this.pluginKey];
        this.sortBySettings(allSortSettings);
      }
    }
    /**
     * Sort the table by provided configuration.
     *
     * @private
     * @param {Object} allSortSettings All sort config settings. Object may contain `initialConfig`, `indicator`,
     * `sortEmptyCells`, `headerAction` and `compareFunctionFactory` properties.
     */

  }, {
    key: "sortBySettings",
    value: function sortBySettings(allSortSettings) {
      if ((0, _object.isObject)(allSortSettings)) {
        this.columnStatesManager.updateAllColumnsProperties(allSortSettings);
        var initialConfig = allSortSettings.initialConfig;

        if (Array.isArray(initialConfig) || (0, _object.isObject)(initialConfig)) {
          this.sort(initialConfig);
        }
      } else {
        // Extra render for headers. Their width may change.
        this.hot.render();
      }
    }
    /**
     * Enables the ObserveChanges plugin.
     *
     * @private
     */

  }, {
    key: "enableObserveChangesPlugin",
    value: function enableObserveChangesPlugin() {
      var _this = this;

      this.hot._registerTimeout(setTimeout(function () {
        _this.hot.updateSettings({
          observeChanges: true
        });
      }, 0));
    }
    /**
     * Callback for `modifyRow` hook. Translates visual row index to the sorted row index.
     *
     * @private
     * @param {Number} row Visual row index.
     * @returns {Number} Physical row index.
     */

  }, {
    key: "onModifyRow",
    value: function onModifyRow(row, source) {
      if (this.blockPluginTranslation === false && source !== this.pluginName && this.isSorted()) {
        var rowInMapper = this.rowsMapper.getValueByIndex(row);
        row = rowInMapper === null ? row : rowInMapper;
      }

      return row;
    }
    /**
     * Callback for `unmodifyRow` hook. Translates sorted row index to visual row index.
     *
     * @private
     * @param {Number} row Physical row index.
     * @returns {Number} Visual row index.
     */

  }, {
    key: "onUnmodifyRow",
    value: function onUnmodifyRow(row, source) {
      if (this.blockPluginTranslation === false && source !== this.pluginName && this.isSorted()) {
        row = this.rowsMapper.getIndexByValue(row);
      }

      return row;
    }
    /**
     * Callback for the `onAfterGetColHeader` hook. Adds column sorting CSS classes.
     *
     * @private
     * @param {Number} column Visual column index.
     * @param {Element} TH TH HTML element.
     */

  }, {
    key: "onAfterGetColHeader",
    value: function onAfterGetColHeader(column, TH) {
      var headerSpanElement = (0, _utils.getHeaderSpanElement)(TH);

      if ((0, _utils.isFirstLevelColumnHeader)(column, TH) === false || headerSpanElement === null) {
        return;
      }

      var physicalColumn = this.hot.toPhysicalColumn(column);
      var pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
      var showSortIndicator = pluginSettingsForColumn.indicator;
      var headerActionEnabled = pluginSettingsForColumn.headerAction;
      this.updateHeaderClasses(headerSpanElement, this.columnStatesManager, physicalColumn, showSortIndicator, headerActionEnabled);
    }
    /**
     * Update header classes.
     *
     * @private
     * @param {HTMLElement} headerSpanElement Header span element.
     * @param {...*} args Extra arguments for helpers.
     */

  }, {
    key: "updateHeaderClasses",
    value: function updateHeaderClasses(headerSpanElement) {
      (0, _element.removeClass)(headerSpanElement, (0, _domHelpers.getClassedToRemove)(headerSpanElement));

      if (this.enabled !== false) {
        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        (0, _element.addClass)(headerSpanElement, _domHelpers.getClassesToAdd.apply(void 0, args));
      }
    }
    /**
     * Overwriting base plugin's `onUpdateSettings` method. Please keep in mind that `onAfterUpdateSettings` isn't called
     * for `updateSettings` in specific situations.
     *
     * @private
     * @param {Object} newSettings New settings object.
     */

  }, {
    key: "onUpdateSettings",
    value: function onUpdateSettings(newSettings) {
      (0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSorting.prototype), "onUpdateSettings", this).call(this);
      this.columnMetaCache.clear();

      if ((0, _mixed.isDefined)(newSettings[this.pluginKey])) {
        this.sortBySettings(newSettings[this.pluginKey]);
      }
    }
    /**
     * Callback for the `afterLoadData` hook.
     *
     * @private
     * @param {Boolean} initialLoad flag that determines whether the data has been loaded during the initialization.
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData(initialLoad) {
      this.rowsMapper.clearMap();
      this.columnMetaCache.clear();

      if (initialLoad === true) {
        // TODO: Workaround? It should be refactored / described.
        if (this.hot.view) {
          this.loadOrSortBySettings();
        }
      }
    }
    /**
     * Callback for the `afterCreateRow` hook.
     *
     * @private
     * @param {Number} index Visual index of the created row.
     * @param {Number} amount Amount of created rows.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount) {
      this.rowsMapper.shiftItems(index, amount);
    }
    /**
     * Callback for the `afterRemoveRow` hook.
     *
     * @private
     * @param {Number} index Visual index of the removed row.
     * @param {Number} amount Amount of removed rows.
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow(index, amount) {
      this.rowsMapper.unshiftItems(index, amount);
    } // TODO: Workaround. Inheriting of non-primitive cell meta values doesn't work. We clear the cache after action which reorganize sequence of columns.
    // TODO: Remove test named: "should add new columns properly when the `columnSorting` plugin is enabled (inheriting of non-primitive cell meta values)".

    /**
     * Callback for the `afterCreateCol` hook.
     *
     * @private
     */

  }, {
    key: "onAfterCreateCol",
    value: function onAfterCreateCol() {
      this.columnMetaCache.clear();
    } // TODO: Workaround. Inheriting of non-primitive cell meta values doesn't work. We clear the cache after action which reorganize sequence of columns.
    // TODO: Remove test named: "should add new columns properly when the `columnSorting` plugin is enabled (inheriting of non-primitive cell meta values)".

    /**
     * Callback for the `afterRemoveCol` hook.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveCol",
    value: function onAfterRemoveCol() {
      this.columnMetaCache.clear();
    }
    /**
     * Indicates if clickable header was clicked.
     *
     * @private
     * @param {MouseEvent} event The `mousedown` event.
     * @param {Number} column Visual column index.
     * @returns {Boolean}
     */

  }, {
    key: "wasClickableHeaderClicked",
    value: function wasClickableHeaderClicked(event, column) {
      var pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
      var headerActionEnabled = pluginSettingsForColumn.headerAction;
      return headerActionEnabled && event.realTarget.nodeName === 'SPAN';
    }
    /**
     * Changes the behavior of selection / dragging.
     *
     * @private
     * @param {MouseEvent} event The `mousedown` event.
     * @param {CellCoords} coords Visual coordinates.
     * @param {HTMLElement} TD
     * @param {Object} blockCalculations
     */

  }, {
    key: "onBeforeOnCellMouseDown",
    value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) {
      if ((0, _utils.wasHeaderClickedProperly)(coords.row, coords.col, event) === false) {
        return;
      }

      if (this.wasClickableHeaderClicked(event, coords.col) && (0, _keyStateObserver.isPressedCtrlKey)()) {
        blockCalculations.column = true;
      }
    }
    /**
     * Callback for the `onAfterOnCellMouseDown` hook.
     *
     * @private
     * @param {Event} event Event which are provided by hook.
     * @param {CellCoords} coords Visual coords of the selected cell.
     */

  }, {
    key: "onAfterOnCellMouseDown",
    value: function onAfterOnCellMouseDown(event, coords) {
      if ((0, _utils.wasHeaderClickedProperly)(coords.row, coords.col, event) === false) {
        return;
      }

      if (this.wasClickableHeaderClicked(event, coords.col)) {
        if ((0, _keyStateObserver.isPressedCtrlKey)()) {
          this.hot.deselectCell();
          this.hot.selectColumns(coords.col);
        }

        this.sort(this.getColumnNextConfig(coords.col));
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.rowsMapper.destroy();
      this.columnStatesManager.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSorting.prototype), "destroy", this).call(this);
    }
  }]);
  return ColumnSorting;
}(_base.default);

(0, _plugins.registerPlugin)(PLUGIN_KEY, ColumnSorting);
var _default = ColumnSorting;
exports.default = _default;

/***/ }),
/* 485 */
/***/ (function(module, exports, __webpack_require__) {

var assign = __webpack_require__(601);

// `Object.assign` method
// https://tc39.github.io/ecma262/#sec-object.assign
__webpack_require__(22)({ target: 'Object', stat: true, forced: Object.assign !== assign }, { assign: assign });


/***/ }),
/* 486 */
/***/ (function(module, exports, __webpack_require__) {

var arrayWithHoles = __webpack_require__(332);

var iterableToArray = __webpack_require__(195);

var nonIterableRest = __webpack_require__(333);

function _toArray(arr) {
  return arrayWithHoles(arr) || iterableToArray(arr) || nonIterableRest();
}

module.exports = _toArray;

/***/ }),
/* 487 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.getCompareFunctionFactory = getCompareFunctionFactory;
exports.getRootComparator = exports.registerRootComparator = void 0;

var _default = __webpack_require__(608);

var _numeric = __webpack_require__(609);

var _date = __webpack_require__(610);

var _staticRegister3 = _interopRequireDefault(__webpack_require__(78));

var _staticRegister = (0, _staticRegister3.default)('sorting.compareFunctionFactory'),
    registerCompareFunctionFactory = _staticRegister.register,
    getGloballyCompareFunctionFactory = _staticRegister.getItem,
    hasGloballyCompareFunctionFactory = _staticRegister.hasItem;

var _staticRegister2 = (0, _staticRegister3.default)('sorting.mainSortComparator'),
    registerRootComparator = _staticRegister2.register,
    getRootComparator = _staticRegister2.getItem;
/**
 * Gets sort function for the particular column basing on it's data type.
 *
 * @param {String} dataType Data type for the particular column.
 * @returns {Function}
 */


exports.getRootComparator = getRootComparator;
exports.registerRootComparator = registerRootComparator;

function getCompareFunctionFactory(type) {
  if (hasGloballyCompareFunctionFactory(type)) {
    return getGloballyCompareFunctionFactory(type);
  }

  return getGloballyCompareFunctionFactory(_default.COLUMN_DATA_TYPE);
}

registerCompareFunctionFactory(_numeric.COLUMN_DATA_TYPE, _numeric.compareFunctionFactory);
registerCompareFunctionFactory(_date.COLUMN_DATA_TYPE, _date.compareFunctionFactory);
registerCompareFunctionFactory(_default.COLUMN_DATA_TYPE, _default.compareFunctionFactory);

/***/ }),
/* 488 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(54);

__webpack_require__(46);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

/**
 * Command executor for ContextMenu.
 *
 * @class CommandExecutor
 * @plugin ContextMenu
 */
var CommandExecutor =
/*#__PURE__*/
function () {
  function CommandExecutor(hotInstance) {
    (0, _classCallCheck2.default)(this, CommandExecutor);
    this.hot = hotInstance;
    this.commands = {};
    this.commonCallback = null;
  }
  /**
   * Register command.
   *
   * @param {String} name Command name.
   * @param {Object} commandDescriptor Command descriptor object with properties like `key` (command id),
   *                                   `callback` (task to execute), `name` (command name), `disabled` (command availability).
   */


  (0, _createClass2.default)(CommandExecutor, [{
    key: "registerCommand",
    value: function registerCommand(name, commandDescriptor) {
      this.commands[name] = commandDescriptor;
    }
    /**
     * Set common callback which will be trigger on every executed command.
     *
     * @param {Function} callback Function which will be fired on every command execute.
     */

  }, {
    key: "setCommonCallback",
    value: function setCommonCallback(callback) {
      this.commonCallback = callback;
    }
    /**
     * Execute command by its name.
     *
     * @param {String} commandName Command id.
     * @param {*} params Arguments passed to command task.
     */

  }, {
    key: "execute",
    value: function execute(commandName) {
      var _this = this;

      for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        params[_key - 1] = arguments[_key];
      }

      var commandSplit = commandName.split(':');
      var commandNamePrimary = commandSplit[0];
      var subCommandName = commandSplit.length === 2 ? commandSplit[1] : null;
      var command = this.commands[commandNamePrimary];

      if (!command) {
        throw new Error("Menu command '".concat(commandNamePrimary, "' not exists."));
      }

      if (subCommandName && command.submenu) {
        command = findSubCommand(subCommandName, command.submenu.items);
      }

      if (command.disabled === true) {
        return;
      }

      if (typeof command.disabled === 'function' && command.disabled.call(this.hot) === true) {
        return;
      }

      if ((0, _object.hasOwnProperty)(command, 'submenu')) {
        return;
      }

      var callbacks = [];

      if (typeof command.callback === 'function') {
        callbacks.push(command.callback);
      }

      if (typeof this.commonCallback === 'function') {
        callbacks.push(this.commonCallback);
      }

      params.unshift(commandSplit.join(':'));
      (0, _array.arrayEach)(callbacks, function (callback) {
        return callback.apply(_this.hot, params);
      });
    }
  }]);
  return CommandExecutor;
}();

function findSubCommand(subCommandName, subCommands) {
  var command;
  (0, _array.arrayEach)(subCommands, function (cmd) {
    var cmds = cmd.key ? cmd.key.split(':') : null;

    if (Array.isArray(cmds) && cmds[1] === subCommandName) {
      command = cmd;
      return false;
    }
  });
  return command;
}

var _default = CommandExecutor;
exports.default = _default;

/***/ }),
/* 489 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(51);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _predefinedItems = __webpack_require__(83);

/**
 * Predefined items class factory for menu items.
 *
 * @class ItemsFactory
 * @plugin ContextMenu
 */
var ItemsFactory =
/*#__PURE__*/
function () {
  function ItemsFactory(hotInstance) {
    var orderPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
    (0, _classCallCheck2.default)(this, ItemsFactory);
    this.hot = hotInstance;
    this.predefinedItems = (0, _predefinedItems.predefinedItems)();
    this.defaultOrderPattern = orderPattern;
  }
  /**
   * Set predefined items.
   *
   * @param {Array} predefinedItemsCollection Array of predefined items.
   */


  (0, _createClass2.default)(ItemsFactory, [{
    key: "setPredefinedItems",
    value: function setPredefinedItems(predefinedItemsCollection) {
      var _this = this;

      var items = {};
      this.defaultOrderPattern.length = 0;
      (0, _object.objectEach)(predefinedItemsCollection, function (value, key) {
        var menuItemKey = '';

        if (value.name === _predefinedItems.SEPARATOR) {
          items[_predefinedItems.SEPARATOR] = value;
          menuItemKey = _predefinedItems.SEPARATOR; // Menu item added as a property to array
        } else if (isNaN(parseInt(key, 10))) {
          value.key = value.key === void 0 ? key : value.key;
          items[key] = value;
          menuItemKey = value.key;
        } else {
          items[value.key] = value;
          menuItemKey = value.key;
        }

        _this.defaultOrderPattern.push(menuItemKey);
      });
      this.predefinedItems = items;
    }
    /**
     * Get all menu items based on pattern.
     *
     * @param {Array|Object|Boolean} pattern Pattern which you can define by displaying menu items order. If `true` default
     *                                       pattern will be used.
     * @returns {Array}
     */

  }, {
    key: "getItems",
    value: function getItems() {
      var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      return _getItems(pattern, this.defaultOrderPattern, this.predefinedItems);
    }
  }]);
  return ItemsFactory;
}();

function _getItems() {
  var itemsPattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
  var defaultPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var items = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var result = [];
  var pattern = itemsPattern;

  if (pattern && pattern.items) {
    pattern = pattern.items;
  } else if (!Array.isArray(pattern)) {
    pattern = defaultPattern;
  }

  if ((0, _object.isObject)(pattern)) {
    (0, _object.objectEach)(pattern, function (value, key) {
      var item = items[typeof value === 'string' ? value : key];

      if (!item) {
        item = value;
      }

      if ((0, _object.isObject)(value)) {
        (0, _object.extend)(item, value);
      } else if (typeof item === 'string') {
        item = {
          name: item
        };
      }

      if (item.key === void 0) {
        item.key = key;
      }

      result.push(item);
    });
  } else {
    (0, _array.arrayEach)(pattern, function (name, key) {
      var item = items[name]; // Item deleted from settings `allowInsertRow: false` etc.

      if (!item && _predefinedItems.ITEMS.indexOf(name) >= 0) {
        return;
      }

      if (!item) {
        item = {
          name: name,
          key: "".concat(key)
        };
      }

      if ((0, _object.isObject)(name)) {
        (0, _object.extend)(item, name);
      }

      if (item.key === void 0) {
        item.key = key;
      }

      result.push(item);
    });
  }

  return result;
}

var _default = ItemsFactory;
exports.default = _default;

/***/ }),
/* 490 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _number = __webpack_require__(15);

var STATE_INITIALIZED = 0;
var STATE_BUILT = 1;
var STATE_APPENDED = 2;
var UNIT = 'px';
/**
 * @class
 * @private
 */

var BaseUI =
/*#__PURE__*/
function () {
  function BaseUI(hotInstance) {
    (0, _classCallCheck2.default)(this, BaseUI);

    /**
     * Instance of Handsontable.
     *
     * @type {Core}
     */
    this.hot = hotInstance;
    /**
     * DOM element representing the ui element.
     *
     * @type {HTMLElement}
     * @private
     */

    this._element = null;
    /**
     * Flag which determines build state of element.
     *
     * @type {Boolean}
     */

    this.state = STATE_INITIALIZED;
  }
  /**
   * Add created UI elements to table.
   *
   * @param {HTMLElement} wrapper Element which are parent for our UI element.
   */


  (0, _createClass2.default)(BaseUI, [{
    key: "appendTo",
    value: function appendTo(wrapper) {
      wrapper.appendChild(this._element);
      this.state = STATE_APPENDED;
    }
    /**
     * Method for create UI element. Only create, without append to table.
     */

  }, {
    key: "build",
    value: function build() {
      this._element = this.hot.rootDocument.createElement('div');
      this.state = STATE_BUILT;
    }
    /**
     * Method for remove UI element.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.isAppended()) {
        this._element.parentElement.removeChild(this._element);
      }

      this._element = null;
      this.state = STATE_INITIALIZED;
    }
    /**
     * Check if UI element are appended.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isAppended",
    value: function isAppended() {
      return this.state === STATE_APPENDED;
    }
    /**
     * Check if UI element are built.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isBuilt",
    value: function isBuilt() {
      return this.state >= STATE_BUILT;
    }
    /**
     * Setter for position.
     *
     * @param {Number} top New top position of the element.
     * @param {Number} left New left position of the element.
     */

  }, {
    key: "setPosition",
    value: function setPosition(top, left) {
      if ((0, _number.isNumeric)(top)) {
        this._element.style.top = top + UNIT;
      }

      if ((0, _number.isNumeric)(left)) {
        this._element.style.left = left + UNIT;
      }
    }
    /**
     * Getter for the element position.
     *
     * @returns {Object} Object contains left and top position of the element.
     */

  }, {
    key: "getPosition",
    value: function getPosition() {
      return {
        top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0,
        left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0
      };
    }
    /**
     * Setter for the element size.
     *
     * @param {Number} width New width of the element.
     * @param {Number} height New height of the element.
     */

  }, {
    key: "setSize",
    value: function setSize(width, height) {
      if ((0, _number.isNumeric)(width)) {
        this._element.style.width = width + UNIT;
      }

      if ((0, _number.isNumeric)(height)) {
        this._element.style.height = height + UNIT;
      }
    }
    /**
     * Getter for the element position.
     *
     * @returns {Object} Object contains height and width of the element.
     */

  }, {
    key: "getSize",
    value: function getSize() {
      return {
        width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0,
        height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0
      };
    }
    /**
     * Setter for the element offset. Offset means marginTop and marginLeft of the element.
     *
     * @param {Number} top New margin top of the element.
     * @param {Number} left New margin left of the element.
     */

  }, {
    key: "setOffset",
    value: function setOffset(top, left) {
      if ((0, _number.isNumeric)(top)) {
        this._element.style.marginTop = top + UNIT;
      }

      if ((0, _number.isNumeric)(left)) {
        this._element.style.marginLeft = left + UNIT;
      }
    }
    /**
     * Getter for the element offset.
     *
     * @returns {Object} Object contains top and left offset of the element.
     */

  }, {
    key: "getOffset",
    value: function getOffset() {
      return {
        top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0,
        left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0
      };
    }
  }]);
  return BaseUI;
}();

var _default = BaseUI;
exports.default = _default;

/***/ }),
/* 491 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var STATE_INITIALIZED = 0;
var STATE_BUILT = 1;
var STATE_APPENDED = 2;
var UNIT = 'px';
/**
 * @class
 * @private
 */

var BaseUI =
/*#__PURE__*/
function () {
  function BaseUI(hotInstance) {
    (0, _classCallCheck2.default)(this, BaseUI);

    /**
     * Instance of Handsontable.
     *
     * @type {Core}
     */
    this.hot = hotInstance;
    /**
     * DOM element representing the ui element.
     *
     * @type {HTMLElement}
     * @private
     */

    this._element = null;
    /**
     * Flag which determines build state of element.
     *
     * @type {Boolean}
     */

    this.state = STATE_INITIALIZED;
  }
  /**
   * Add created UI elements to table.
   *
   * @param {HTMLElement} wrapper Element which are parent for our UI element.
   */


  (0, _createClass2.default)(BaseUI, [{
    key: "appendTo",
    value: function appendTo(wrapper) {
      wrapper.appendChild(this._element);
      this.state = STATE_APPENDED;
    }
    /**
     * Method for create UI element. Only create, without append to table.
     */

  }, {
    key: "build",
    value: function build() {
      this._element = this.hot.rootDocument.createElement('div');
      this.state = STATE_BUILT;
    }
    /**
     * Method for remove UI element.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.isAppended()) {
        this._element.parentElement.removeChild(this._element);
      }

      this._element = null;
      this.state = STATE_INITIALIZED;
    }
    /**
     * Check if UI element are appended.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isAppended",
    value: function isAppended() {
      return this.state === STATE_APPENDED;
    }
    /**
     * Check if UI element are built.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isBuilt",
    value: function isBuilt() {
      return this.state >= STATE_BUILT;
    }
    /**
     * Setter for position.
     *
     * @param {Number} top New top position of the element.
     * @param {Number} left New left position of the element.
     */

  }, {
    key: "setPosition",
    value: function setPosition(top, left) {
      if (top !== void 0) {
        this._element.style.top = top + UNIT;
      }

      if (left !== void 0) {
        this._element.style.left = left + UNIT;
      }
    }
    /**
     * Getter for the element position.
     *
     * @returns {Object} Object contains left and top position of the element.
     */

  }, {
    key: "getPosition",
    value: function getPosition() {
      return {
        top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0,
        left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0
      };
    }
    /**
     * Setter for the element size.
     *
     * @param {Number} width New width of the element.
     * @param {Number} height New height of the element.
     */

  }, {
    key: "setSize",
    value: function setSize(width, height) {
      if (width) {
        this._element.style.width = width + UNIT;
      }

      if (height) {
        this._element.style.height = height + UNIT;
      }
    }
    /**
     * Getter for the element position.
     *
     * @returns {Object} Object contains height and width of the element.
     */

  }, {
    key: "getSize",
    value: function getSize() {
      return {
        width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0,
        height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0
      };
    }
    /**
     * Setter for the element offset. Offset means marginTop and marginLeft of the element.
     *
     * @param {Number} top New margin top of the element.
     * @param {Number} left New margin left of the element.
     */

  }, {
    key: "setOffset",
    value: function setOffset(top, left) {
      if (top) {
        this._element.style.marginTop = top + UNIT;
      }

      if (left) {
        this._element.style.marginLeft = left + UNIT;
      }
    }
    /**
     * Getter for the element offset.
     *
     * @returns {Object} Object contains top and left offset of the element.
     */

  }, {
    key: "getOffset",
    value: function getOffset() {
      return {
        top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0,
        left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0
      };
    }
  }]);
  return BaseUI;
}();

var _default = BaseUI;
exports.default = _default;

/***/ }),
/* 492 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.applySpanProperties = applySpanProperties;

/**
 * Apply the `colspan`/`rowspan` properties.
 *
 * @param {HTMLElement} TD The soon-to-be-modified cell.
 * @param {MergedCellCoords} merged cellInfo The merged cell in question.
 * @param {Number} row Row index.
 * @param {Number} col Column index.
 */
// eslint-disable-next-line import/prefer-default-export
function applySpanProperties(TD, mergedCellInfo, row, col) {
  if (mergedCellInfo) {
    if (mergedCellInfo.row === row && mergedCellInfo.col === col) {
      TD.setAttribute('rowspan', mergedCellInfo.rowspan.toString());
      TD.setAttribute('colspan', mergedCellInfo.colspan.toString());
    } else {
      TD.removeAttribute('rowspan');
      TD.removeAttribute('colspan');
      TD.style.display = 'none';
    }
  } else {
    TD.removeAttribute('rowspan');
    TD.removeAttribute('colspan');
    TD.style.display = '';
  }
}

/***/ }),
/* 493 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'empty';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow) {
  return dataRow.value === '' || dataRow.value === null || dataRow.value === void 0;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_EMPTY,
  inputsCount: 0,
  showOperators: true
});

/***/ }),
/* 494 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _mixed = __webpack_require__(27);

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'eq';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  return (0, _mixed.stringify)(dataRow.value).toLowerCase() === (0, _mixed.stringify)(value);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_EQUAL,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 495 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var _after = __webpack_require__(496);

var _before = __webpack_require__(497);

var CONDITION_NAME = 'between';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
      from = _ref2[0],
      to = _ref2[1];

  var fromValue = from;
  var toValue = to;

  if (dataRow.meta.type === 'numeric') {
    var _from = parseFloat(fromValue, 10);

    var _to = parseFloat(toValue, 10);

    fromValue = Math.min(_from, _to);
    toValue = Math.max(_from, _to);
  } else if (dataRow.meta.type === 'date') {
    var dateBefore = (0, _conditionRegisterer.getCondition)(_before.CONDITION_NAME, [toValue]);
    var dateAfter = (0, _conditionRegisterer.getCondition)(_after.CONDITION_NAME, [fromValue]);
    return dateBefore(dataRow) && dateAfter(dataRow);
  }

  return dataRow.value >= fromValue && dataRow.value <= toValue;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_BETWEEN,
  inputsCount: 2,
  showOperators: true
});

/***/ }),
/* 496 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _moment = _interopRequireDefault(__webpack_require__(63));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'date_after';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);
  var inputDate = (0, _moment.default)(value, dataRow.meta.dateFormat);

  if (!date.isValid() || !inputDate.isValid()) {
    return false;
  }

  return date.diff(inputDate) >= 0;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_AFTER,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 497 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _moment = _interopRequireDefault(__webpack_require__(63));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'date_before';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);
  var inputDate = (0, _moment.default)(value, dataRow.meta.dateFormat);

  if (!date.isValid() || !inputDate.isValid()) {
    return false;
  }

  return date.diff(inputDate) <= 0;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_BEFORE,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 498 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _mixed = __webpack_require__(27);

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'contains';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  return (0, _mixed.stringify)(dataRow.value).toLowerCase().indexOf((0, _mixed.stringify)(value)) >= 0;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_CONTAINS,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 499 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.operationResult = operationResult;
exports.SHORT_NAME_FOR_COMPONENT = exports.OPERATION_ID = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _logicalOperationRegisterer = __webpack_require__(109);

var OPERATION_ID = 'disjunction';
exports.OPERATION_ID = OPERATION_ID;
var SHORT_NAME_FOR_COMPONENT = C.FILTERS_LABELS_DISJUNCTION; // (p OR q OR w OR x OR...) === TRUE?

exports.SHORT_NAME_FOR_COMPONENT = SHORT_NAME_FOR_COMPONENT;

function operationResult(conditions, value) {
  return conditions.some(function (condition) {
    return condition.func(value);
  });
}

(0, _logicalOperationRegisterer.registerOperation)(OPERATION_ID, SHORT_NAME_FOR_COMPONENT, operationResult);

/***/ }),
/* 500 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

__webpack_require__(40);

exports.__esModule = true;
exports.operationResult = operationResult;
exports.SHORT_NAME_FOR_COMPONENT = exports.OPERATION_ID = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _logicalOperationRegisterer = __webpack_require__(109);

var OPERATION_ID = 'disjunctionWithExtraCondition';
exports.OPERATION_ID = OPERATION_ID;
var SHORT_NAME_FOR_COMPONENT = C.FILTERS_LABELS_DISJUNCTION; // ((p OR q OR w OR x OR...) AND z) === TRUE?

exports.SHORT_NAME_FOR_COMPONENT = SHORT_NAME_FOR_COMPONENT;

function operationResult(conditions, value) {
  if (conditions.length < 3) {
    throw Error('Operation doesn\'t work on less then three conditions.');
  }

  return conditions.slice(0, conditions.length - 1).some(function (condition) {
    return condition.func(value);
  }) && conditions[conditions.length - 1].func(value);
}

(0, _logicalOperationRegisterer.registerOperation)(OPERATION_ID, SHORT_NAME_FOR_COMPONENT, operationResult);

/***/ }),
/* 501 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(33);

__webpack_require__(51);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _templateLiteralTag = __webpack_require__(67);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _conditionRegisterer = __webpack_require__(28);

var _conjunction = __webpack_require__(170);

var _logicalOperationRegisterer = __webpack_require__(109);

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["The column of index ", " has been already applied with a `", "`\n        filter operation. Use `removeConditions` to clear the current conditions and then add new ones.\n        Mind that you cannot mix different types of operations (for instance, if you use `conjunction`,\n        use it consequently for a particular column)."], ["The column of index ", " has been already applied with a \\`", "\\`\n        filter operation. Use \\`removeConditions\\` to clear the current conditions and then add new ones.\n        Mind that you cannot mix different types of operations (for instance, if you use \\`conjunction\\`,\n        use it consequently for a particular column)."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * @class ConditionCollection
 * @plugin Filters
 */
var ConditionCollection =
/*#__PURE__*/
function () {
  function ConditionCollection() {
    (0, _classCallCheck2.default)(this, ConditionCollection);

    /**
     * Conditions collection grouped by operation type and then column index.
     *
     * @type {Object}
     */
    this.conditions = this.initConditionsCollection();
    /**
     * Types of operations grouped by column index.
     *
     * @type {Object}
     */

    this.columnTypes = {};
    /**
     * Order of added condition filters.
     *
     * @type {Array}
     */

    this.orderStack = [];
  }
  /**
   * Check if condition collection is empty (so no needed to filter data).
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ConditionCollection, [{
    key: "isEmpty",
    value: function isEmpty() {
      return !this.orderStack.length;
    }
    /**
     * Check if value is matched to the criteria of conditions chain.
     *
     * @param {Object} value Object with `value` and `meta` keys.
     * @param {Number} [column] Column index.
     * @returns {Boolean}
     */

  }, {
    key: "isMatch",
    value: function isMatch(value, column) {
      var _this = this;

      var result = true;

      if (column === void 0) {
        (0, _object.objectEach)(this.columnTypes, function (columnType, columnIndex) {
          result = _this.isMatchInConditions(_this.conditions[columnType][columnIndex], value, columnType);
          return result;
        });
      } else {
        var columnType = this.columnTypes[column];
        result = this.isMatchInConditions(this.getConditions(column), value, columnType);
      }

      return result;
    }
    /**
     * Check if the value is matches the conditions.
     *
     * @param {Array} conditions List of conditions.
     * @param {Object} value Object with `value` and `meta` keys.
     * @param {String} [operationType='conjunction'] Type of conditions operation
     * @returns {Boolean}
     */

  }, {
    key: "isMatchInConditions",
    value: function isMatchInConditions(conditions, value) {
      var operationType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _conjunction.OPERATION_ID;
      var result = false;

      if (conditions.length) {
        result = (0, _logicalOperationRegisterer.getOperationFunc)(operationType)(conditions, value);
      } else {
        result = true;
      }

      return result;
    }
    /**
     * Add condition to the collection.
     *
     * @param {Number} column Column index.
     * @param {Object} conditionDefinition Object with keys:
     *  * `command` Object, Command object with condition name as `key` property.
     *  * `args` Array, Condition arguments.
     * @param {String} [operation='conjunction'] Type of conditions operation
     * @fires ConditionCollection#beforeAdd
     * @fires ConditionCollection#afterAdd
     */

  }, {
    key: "addCondition",
    value: function addCondition(column, conditionDefinition) {
      var operation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _conjunction.OPERATION_ID;
      var args = (0, _array.arrayMap)(conditionDefinition.args, function (v) {
        return typeof v === 'string' ? v.toLowerCase() : v;
      });
      var name = conditionDefinition.name || conditionDefinition.command.key;
      this.runLocalHooks('beforeAdd', column);

      if (this.orderStack.indexOf(column) === -1) {
        this.orderStack.push(column);
      }

      var columnType = this.columnTypes[column];

      if (columnType) {
        if (columnType !== operation) {
          throw Error((0, _templateLiteralTag.toSingleLine)(_templateObject(), column, columnType));
        }
      } else {
        if (!this.conditions[operation]) {
          throw new Error("Unexpected operation named `".concat(operation, "`. Possible ones are `disjunction` and `conjunction`."));
        }

        this.columnTypes[column] = operation;
      } // Add condition


      this.getConditions(column).push({
        name: name,
        args: args,
        func: (0, _conditionRegisterer.getCondition)(name, args)
      });
      this.runLocalHooks('afterAdd', column);
    }
    /**
     * Get all added conditions from the collection at specified column index.
     *
     * @param {Number} column Column index.
     * @returns {Array} Returns conditions collection as an array.
     */

  }, {
    key: "getConditions",
    value: function getConditions(column) {
      var columnType = this.columnTypes[column];

      if (!columnType) {
        return [];
      }

      if (!this.conditions[columnType][column]) {
        this.conditions[columnType][column] = [];
      }

      return this.conditions[columnType][column];
    }
    /**
     * Export all previously added conditions.
     *
     * @returns {Array}
     */

  }, {
    key: "exportAllConditions",
    value: function exportAllConditions() {
      var _this2 = this;

      var result = [];
      (0, _array.arrayEach)(this.orderStack, function (column) {
        var conditions = (0, _array.arrayMap)(_this2.getConditions(column), function (_ref) {
          var name = _ref.name,
              args = _ref.args;
          return {
            name: name,
            args: args
          };
        });
        var operation = _this2.columnTypes[column];
        result.push({
          column: column,
          operation: operation,
          conditions: conditions
        });
      });
      return result;
    }
    /**
     * Import conditions to the collection.
     */

  }, {
    key: "importAllConditions",
    value: function importAllConditions(conditions) {
      var _this3 = this;

      this.clean();
      (0, _array.arrayEach)(conditions, function (stack) {
        _this3.orderStack.push(stack.column);

        (0, _array.arrayEach)(stack.conditions, function (condition) {
          return _this3.addCondition(stack.column, condition);
        });
      });
    }
    /**
     * Remove conditions at given column index.
     *
     * @param {Number} column Column index.
     * @fires ConditionCollection#beforeRemove
     * @fires ConditionCollection#afterRemove
     */

  }, {
    key: "removeConditions",
    value: function removeConditions(column) {
      this.runLocalHooks('beforeRemove', column);

      if (this.orderStack.indexOf(column) >= 0) {
        this.orderStack.splice(this.orderStack.indexOf(column), 1);
      }

      this.clearConditions(column);
      this.runLocalHooks('afterRemove', column);
    }
    /**
     * Clear conditions at specified column index but without clearing stack order.
     *
     * @param {Number }column Column index.
     * @fires ConditionCollection#beforeClear
     * @fires ConditionCollection#afterClear
     */

  }, {
    key: "clearConditions",
    value: function clearConditions(column) {
      this.runLocalHooks('beforeClear', column);
      this.getConditions(column).length = 0;
      delete this.columnTypes[column];
      this.runLocalHooks('afterClear', column);
    }
    /**
     * Check if at least one condition was added at specified column index. And if second parameter is passed then additionally
     * check if condition exists under its name.
     *
     * @param {Number} column Column index.
     * @param {String} [name] Condition name.
     * @returns {Boolean}
     */

  }, {
    key: "hasConditions",
    value: function hasConditions(column, name) {
      var columnType = this.columnTypes[column];
      var result = false;

      if (!columnType) {
        return false;
      }

      var conditions = this.getConditions(column);

      if (name) {
        result = (0, _array.arrayFilter)(conditions, function (condition) {
          return condition.name === name;
        }).length > 0;
      } else {
        result = conditions.length > 0;
      }

      return result;
    }
    /**
     * Clean all conditions collection and reset order stack.
     *
     * @fires ConditionCollection#beforeClean
     * @fires ConditionCollection#afterClean
     */

  }, {
    key: "clean",
    value: function clean() {
      this.runLocalHooks('beforeClean');
      this.columnTypes = Object.create(null);
      this.orderStack.length = 0;
      this.conditions = this.initConditionsCollection();
      this.runLocalHooks('afterClean');
    }
    /**
     * Destroy object.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.clearLocalHooks();
      this.conditions = null;
      this.orderStack = null;
      this.columnTypes = null;
    }
    /**
     * Init conditions collection
     *
     * @private
     */

  }, {
    key: "initConditionsCollection",
    value: function initConditionsCollection() {
      var conditions = Object.create(null);
      (0, _object.objectEach)(_logicalOperationRegisterer.operations, function (_, operation) {
        conditions[operation] = Object.create(null);
      });
      return conditions;
    }
  }]);
  return ConditionCollection;
}();

(0, _object.mixin)(ConditionCollection, _localHooks.default);
var _default = ConditionCollection;
exports.default = _default;

/***/ }),
/* 502 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

/**
 * @class DataFilter
 * @plugin Filters
 */
var DataFilter =
/*#__PURE__*/
function () {
  function DataFilter(conditionCollection) {
    var columnDataFactory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
      return [];
    };
    (0, _classCallCheck2.default)(this, DataFilter);

    /**
     * Reference to the instance of {ConditionCollection}.
     *
     * @type {ConditionCollection}
     */
    this.conditionCollection = conditionCollection;
    /**
     * Function which provide source data factory for specified column.
     *
     * @type {Function}
     */

    this.columnDataFactory = columnDataFactory;
  }
  /**
   * Filter data based on the conditions collection.
   *
   * @returns {Array}
   */


  (0, _createClass2.default)(DataFilter, [{
    key: "filter",
    value: function filter() {
      var _this = this;

      var filteredData = [];

      if (!this.conditionCollection.isEmpty()) {
        (0, _array.arrayEach)(this.conditionCollection.orderStack, function (column, index) {
          var columnData = _this.columnDataFactory(column);

          if (index) {
            columnData = _this._getIntersectData(columnData, filteredData);
          }

          filteredData = _this.filterByColumn(column, columnData);
        });
      }

      return filteredData;
    }
    /**
     * Filter data based on specified column index.
     *
     * @param {Number} column Column index.
     * @param {Array} [dataSource] Data source as array of objects with `value` and `meta` keys (e.g. `{value: 'foo', meta: {}}`).
     * @returns {Array} Returns filtered data.
     */

  }, {
    key: "filterByColumn",
    value: function filterByColumn(column) {
      var _this2 = this;

      var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var filteredData = [];
      (0, _array.arrayEach)(dataSource, function (dataRow) {
        if (dataRow !== void 0 && _this2.conditionCollection.isMatch(dataRow, column)) {
          filteredData.push(dataRow);
        }
      });
      return filteredData;
    }
    /**
     * Intersect data.
     *
     * @private
     * @param {Array} data
     * @param {Array} needles
     * @returns {Array}
     */

  }, {
    key: "_getIntersectData",
    value: function _getIntersectData(data, needles) {
      var result = [];
      (0, _array.arrayEach)(needles, function (needleRow) {
        var row = needleRow.meta.visualRow;

        if (data[row] !== void 0) {
          result[row] = data[row];
        }
      });
      return result;
    }
  }]);
  return DataFilter;
}();

var _default = DataFilter;
exports.default = _default;

/***/ }),
/* 503 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _hotFormulaParser = __webpack_require__(111);

var _object = __webpack_require__(4);

/**
 * @class BaseCell
 * @util
 */
var BaseCell =
/*#__PURE__*/
function () {
  function BaseCell(row, column) {
    (0, _classCallCheck2.default)(this, BaseCell);
    var rowObject = (0, _object.isObject)(row);
    var columnObject = (0, _object.isObject)(column);
    this._row = rowObject ? row.index : row;
    this.rowAbsolute = rowObject ? row.isAbsolute : true;
    this._column = columnObject ? column.index : column;
    this.columnAbsolute = columnObject ? column.isAbsolute : true;
    this.rowOffset = 0;
    this.columnOffset = 0; // TODO: Change syntax to es6 after upgrade tests to newer version of phantom and jasmine.

    Object.defineProperty(this, 'row', {
      get: function get() {
        return this.rowOffset + this._row;
      },
      set: function set(rowIndex) {
        this._row = rowIndex;
      },
      enumerable: true,
      configurable: true
    });
    Object.defineProperty(this, 'column', {
      get: function get() {
        return this.columnOffset + this._column;
      },
      set: function set(columnIndex) {
        this._column = columnIndex;
      },
      enumerable: true,
      configurable: true
    });
  }
  /**
   * Translate cell coordinates.
   *
   * @param {Number} rowOffset Row offset to move.
   * @param {Number} columnOffset Column offset to move.
   */


  (0, _createClass2.default)(BaseCell, [{
    key: "translateTo",
    value: function translateTo(rowOffset, columnOffset) {
      this.row = this.row + rowOffset;
      this.column = this.column + columnOffset;
    }
    /**
     * Check if cell is equal to provided one.
     *
     * @param {BaseCell} cell Cell object.
     * @returns {Boolean}
     */

  }, {
    key: "isEqual",
    value: function isEqual(cell) {
      return cell.row === this.row && cell.column === this.column;
    }
    /**
     * Stringify object.
     *
     * @returns {String}
     */

  }, {
    key: "toString",
    value: function toString() {
      return (0, _hotFormulaParser.toLabel)({
        index: this.row,
        isAbsolute: this.rowAbsolute
      }, {
        index: this.column,
        isAbsolute: this.columnAbsolute
      });
    }
  }]);
  return BaseCell;
}();

var _default = BaseCell;
exports.default = _default;

/***/ }),
/* 504 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(173));

/**
 * Class responsible for the UI in the Nested Rows' row headers.
 *
 * @class HeadersUI
 * @util
 * @extends BaseUI
 */
var HeadersUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(HeadersUI, _BaseUI);
  (0, _createClass2.default)(HeadersUI, null, [{
    key: "CSS_CLASSES",

    /**
     * CSS classes used in the row headers.
     *
     * @type {Object}
     */
    get: function get() {
      return {
        indicatorContainer: 'ht_nestingLevels',
        parent: 'ht_nestingParent',
        indicator: 'ht_nestingLevel',
        emptyIndicator: 'ht_nestingLevel_empty',
        button: 'ht_nestingButton',
        expandButton: 'ht_nestingExpand',
        collapseButton: 'ht_nestingCollapse'
      };
    }
  }]);

  function HeadersUI(nestedRowsPlugin, hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, HeadersUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HeadersUI).call(this, nestedRowsPlugin, hotInstance));
    /**
     * Reference to the DataManager instance connected with the Nested Rows plugin.
     *
     * @type {DataManager}
     */

    _this.dataManager = _this.plugin.dataManager; // /**
    //  * Level cache array.
    //  *
    //  * @type {Array}
    //  */
    // this.levelCache = this.dataManager.cache.levels;

    /**
     * Reference to the CollapsingUI instance connected with the Nested Rows plugin.
     *
     * @type {CollapsingUI}
     */

    _this.collapsingUI = _this.plugin.collapsingUI;
    /**
     * Cache for the row headers width.
     *
     * @type {null|Number}
     */

    _this.rowHeaderWidthCache = null;
    /**
     * Reference to the TrimRows instance connected with the Nested Rows plugin.
     *
     * @type {TrimRows}
     */

    _this.trimRowsPlugin = nestedRowsPlugin.trimRowsPlugin;
    return _this;
  }
  /**
   * Append nesting indicators and buttons to the row headers.
   *
   * @private
   * @param {Number} row Row index.
   * @param {HTMLElement} TH TH 3element.
   */


  (0, _createClass2.default)(HeadersUI, [{
    key: "appendLevelIndicators",
    value: function appendLevelIndicators(row, TH) {
      var rowIndex = this.trimRowsPlugin.rowsMapper.getValueByIndex(row);
      var rowLevel = this.dataManager.getRowLevel(rowIndex);
      var rowObject = this.dataManager.getDataObject(rowIndex);
      var innerDiv = TH.getElementsByTagName('DIV')[0];
      var innerSpan = innerDiv.querySelector('span.rowHeader');
      var previousIndicators = innerDiv.querySelectorAll('[class^="ht_nesting"]');
      (0, _array.arrayEach)(previousIndicators, function (elem) {
        if (elem) {
          innerDiv.removeChild(elem);
        }
      });
      (0, _element.addClass)(TH, HeadersUI.CSS_CLASSES.indicatorContainer);

      if (rowLevel) {
        var rootDocument = this.hot.rootDocument;
        var initialContent = innerSpan.cloneNode(true);
        innerDiv.innerHTML = '';
        (0, _number.rangeEach)(0, rowLevel - 1, function () {
          var levelIndicator = rootDocument.createElement('SPAN');
          (0, _element.addClass)(levelIndicator, HeadersUI.CSS_CLASSES.emptyIndicator);
          innerDiv.appendChild(levelIndicator);
        });
        innerDiv.appendChild(initialContent);
      }

      if (this.dataManager.hasChildren(rowObject)) {
        var buttonsContainer = this.hot.rootDocument.createElement('DIV');
        (0, _element.addClass)(TH, HeadersUI.CSS_CLASSES.parent);

        if (this.collapsingUI.areChildrenCollapsed(rowIndex)) {
          (0, _element.addClass)(buttonsContainer, "".concat(HeadersUI.CSS_CLASSES.button, " ").concat(HeadersUI.CSS_CLASSES.expandButton));
        } else {
          (0, _element.addClass)(buttonsContainer, "".concat(HeadersUI.CSS_CLASSES.button, " ").concat(HeadersUI.CSS_CLASSES.collapseButton));
        }

        innerDiv.appendChild(buttonsContainer);
      }
    }
    /**
     * Update the row header width according to number of levels in the dataset.
     *
     * @private
     * @param {Number} deepestLevel Cached deepest level of nesting.
     */

  }, {
    key: "updateRowHeaderWidth",
    value: function updateRowHeaderWidth(deepestLevel) {
      var deepestLevelIndex = deepestLevel;

      if (!deepestLevelIndex) {
        deepestLevelIndex = this.dataManager.cache.levelCount;
      }

      this.rowHeaderWidthCache = Math.max(50, 11 + 10 * deepestLevelIndex + 25);
      this.hot.render();
    }
  }]);
  return HeadersUI;
}(_base.default);

var _default = HeadersUI;
exports.default = _default;

/***/ }),
/* 505 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(506);

exports.__esModule = true;
exports.default = void 0;

__webpack_require__(508);

__webpack_require__(509);

__webpack_require__(510);

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var _cellTypes = __webpack_require__(160);

var _core = _interopRequireDefault(__webpack_require__(161));

var _jquery = _interopRequireDefault(__webpack_require__(592));

var _eventManager = _interopRequireWildcard(__webpack_require__(23));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _ghostTable = _interopRequireDefault(__webpack_require__(163));

var arrayHelpers = _interopRequireWildcard(__webpack_require__(3));

var browserHelpers = _interopRequireWildcard(__webpack_require__(72));

var dataHelpers = _interopRequireWildcard(__webpack_require__(132));

var dateHelpers = _interopRequireWildcard(__webpack_require__(468));

var featureHelpers = _interopRequireWildcard(__webpack_require__(73));

var functionHelpers = _interopRequireWildcard(__webpack_require__(75));

var mixedHelpers = _interopRequireWildcard(__webpack_require__(27));

var numberHelpers = _interopRequireWildcard(__webpack_require__(15));

var objectHelpers = _interopRequireWildcard(__webpack_require__(4));

var settingHelpers = _interopRequireWildcard(__webpack_require__(162));

var stringHelpers = _interopRequireWildcard(__webpack_require__(68));

var unicodeHelpers = _interopRequireWildcard(__webpack_require__(50));

var domHelpers = _interopRequireWildcard(__webpack_require__(5));

var domEventHelpers = _interopRequireWildcard(__webpack_require__(31));

var plugins = _interopRequireWildcard(__webpack_require__(594));

var _plugins = __webpack_require__(20);

var _defaultSettings = _interopRequireDefault(__webpack_require__(475));

var _rootInstance = __webpack_require__(472);

var _i18n = __webpack_require__(476);

var constants = _interopRequireWildcard(__webpack_require__(11));

var _dictionariesManager = __webpack_require__(135);

function Handsontable(rootElement, userSettings) {
  var instance = new _core.default(rootElement, userSettings || {}, _rootInstance.rootInstanceSymbol);
  instance.init();
  return instance;
}

(0, _jquery.default)(Handsontable);
Handsontable.Core = _core.default;
Handsontable.DefaultSettings = _defaultSettings.default;
Handsontable.EventManager = _eventManager.default;
Handsontable._getListenersCounter = _eventManager.getListenersCounter; // For MemoryLeak tests

Handsontable.packageName = 'handsontable';
Handsontable.buildDate = "29/03/2019 11:28:56";
Handsontable.version = "7.0.1"; // Export Hooks singleton

Handsontable.hooks = _pluginHooks.default.getSingleton(); // TODO: Remove this exports after rewrite tests about this module

Handsontable.__GhostTable = _ghostTable.default; //
// Export all helpers to the Handsontable object

var HELPERS = [arrayHelpers, browserHelpers, dataHelpers, dateHelpers, featureHelpers, functionHelpers, mixedHelpers, numberHelpers, objectHelpers, settingHelpers, stringHelpers, unicodeHelpers];
var DOM = [domHelpers, domEventHelpers];
Handsontable.helper = {};
Handsontable.dom = {}; // Fill general helpers.

arrayHelpers.arrayEach(HELPERS, function (helper) {
  arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) {
    if (key.charAt(0) !== '_') {
      Handsontable.helper[key] = helper[key];
    }
  });
}); // Fill DOM helpers.

arrayHelpers.arrayEach(DOM, function (helper) {
  arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) {
    if (key.charAt(0) !== '_') {
      Handsontable.dom[key] = helper[key];
    }
  });
}); // Export cell types.

Handsontable.cellTypes = {};
arrayHelpers.arrayEach((0, _cellTypes.getRegisteredCellTypeNames)(), function (cellTypeName) {
  Handsontable.cellTypes[cellTypeName] = (0, _cellTypes.getCellType)(cellTypeName);
});
Handsontable.cellTypes.registerCellType = _cellTypes.registerCellType;
Handsontable.cellTypes.getCellType = _cellTypes.getCellType; // Export all registered editors from the Handsontable.

Handsontable.editors = {};
arrayHelpers.arrayEach((0, _editors.getRegisteredEditorNames)(), function (editorName) {
  Handsontable.editors["".concat(stringHelpers.toUpperCaseFirst(editorName), "Editor")] = (0, _editors.getEditor)(editorName);
});
Handsontable.editors.registerEditor = _editors.registerEditor;
Handsontable.editors.getEditor = _editors.getEditor; // Export all registered renderers from the Handsontable.

Handsontable.renderers = {};
arrayHelpers.arrayEach((0, _renderers.getRegisteredRendererNames)(), function (rendererName) {
  var renderer = (0, _renderers.getRenderer)(rendererName);

  if (rendererName === 'base') {
    Handsontable.renderers.cellDecorator = renderer;
  }

  Handsontable.renderers["".concat(stringHelpers.toUpperCaseFirst(rendererName), "Renderer")] = renderer;
});
Handsontable.renderers.registerRenderer = _renderers.registerRenderer;
Handsontable.renderers.getRenderer = _renderers.getRenderer; // Export all registered validators from the Handsontable.

Handsontable.validators = {};
arrayHelpers.arrayEach((0, _validators.getRegisteredValidatorNames)(), function (validatorName) {
  Handsontable.validators["".concat(stringHelpers.toUpperCaseFirst(validatorName), "Validator")] = (0, _validators.getValidator)(validatorName);
});
Handsontable.validators.registerValidator = _validators.registerValidator;
Handsontable.validators.getValidator = _validators.getValidator; // Export all registered plugins from the Handsontable.

Handsontable.plugins = {};
arrayHelpers.arrayEach(Object.getOwnPropertyNames(plugins), function (pluginName) {
  var plugin = plugins[pluginName];

  if (pluginName === 'Base') {
    Handsontable.plugins["".concat(pluginName, "Plugin")] = plugin;
  } else {
    Handsontable.plugins[pluginName] = plugin;
  }
});
Handsontable.plugins.registerPlugin = _plugins.registerPlugin;
Handsontable.languages = {};
Handsontable.languages.dictionaryKeys = constants;
Handsontable.languages.getLanguageDictionary = _dictionariesManager.getLanguageDictionary;
Handsontable.languages.getLanguagesDictionaries = _dictionariesManager.getLanguagesDictionaries;
Handsontable.languages.registerLanguageDictionary = _dictionariesManager.registerLanguageDictionary; // Alias to `getTranslatedPhrase` function, for more information check it API.

Handsontable.languages.getTranslatedPhrase = function () {
  return _i18n.getTranslatedPhrase.apply(void 0, arguments);
};

var _default = Handsontable;
exports.default = _default;

/***/ }),
/* 506 */
/***/ (function(module, exports, __webpack_require__) {

var nativeGetOwnPropertyNames = __webpack_require__(174).f;
var FAILS_ON_PRIMITIVES = __webpack_require__(29)(function () { Object.getOwnPropertyNames(1); });

// `Object.getOwnPropertyNames` method
// https://tc39.github.io/ecma262/#sec-object.getownpropertynames
__webpack_require__(22)({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {
  getOwnPropertyNames: nativeGetOwnPropertyNames
});


/***/ }),
/* 507 */
/***/ (function(module, exports, __webpack_require__) {

var getOwnPropertyNamesModule = __webpack_require__(93);
var getOwnPropertySymbolsModule = __webpack_require__(119);
var anObject = __webpack_require__(45);
var Reflect = __webpack_require__(32).Reflect;

// all object keys, includes non-enumerable and symbols
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {
  var keys = getOwnPropertyNamesModule.f(anObject(it));
  var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
  return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
};


/***/ }),
/* 508 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 509 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 510 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 511 */
/***/ (function(module, exports, __webpack_require__) {

var DESCRIPTORS = __webpack_require__(52);
var definePropertyModule = __webpack_require__(49);
var anObject = __webpack_require__(45);
var objectKeys = __webpack_require__(89);

module.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) {
  anObject(O);
  var keys = objectKeys(Properties);
  var length = keys.length;
  var i = 0;
  var key;
  while (length > i) definePropertyModule.f(O, key = keys[i++], Properties[key]);
  return O;
};


/***/ }),
/* 512 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var IteratorPrototype = __webpack_require__(182).IteratorPrototype;
var create = __webpack_require__(99);
var createPropertyDescriptor = __webpack_require__(96);
var setToStringTag = __webpack_require__(122);
var Iterators = __webpack_require__(100);

var returnThis = function () { return this; };

module.exports = function (IteratorConstructor, NAME, next) {
  var TO_STRING_TAG = NAME + ' Iterator';
  IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(1, next) });
  setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);
  Iterators[TO_STRING_TAG] = returnThis;
  return IteratorConstructor;
};


/***/ }),
/* 513 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var anObject = __webpack_require__(45);

module.exports = function (O, proto) {
  anObject(O);
  if (!isObject(proto) && proto !== null) {
    throw TypeError("Can't set " + String(proto) + ' as a prototype');
  }
};


/***/ }),
/* 514 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var classof = __webpack_require__(185);
var TO_STRING_TAG = __webpack_require__(35)('toStringTag');
var test = {};

test[TO_STRING_TAG] = 'z';

// `Object.prototype.toString` method implementation
// https://tc39.github.io/ecma262/#sec-object.prototype.tostring
module.exports = String(test) !== '[object z]' ? function toString() {
  return '[object ' + classof(this) + ']';
} : test.toString;


/***/ }),
/* 515 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = !__webpack_require__(29)(function () {
  return Object.isExtensible(Object.preventExtensions({}));
});


/***/ }),
/* 516 */
/***/ (function(module, exports, __webpack_require__) {

var path = __webpack_require__(194);
var global = __webpack_require__(32);

var aFunction = function (variable) {
  return typeof variable == 'function' ? variable : undefined;
};

module.exports = function (namespace, method) {
  return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])
    : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];
};


/***/ }),
/* 517 */
/***/ (function(module, exports) {

function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
      arr2[i] = arr[i];
    }

    return arr2;
  }
}

module.exports = _arrayWithoutHoles;

/***/ }),
/* 518 */
/***/ (function(module, exports) {

function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance");
}

module.exports = _nonIterableSpread;

/***/ }),
/* 519 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var bind = __webpack_require__(101);
var toObject = __webpack_require__(62);
var callWithSafeIterationClosing = __webpack_require__(189);
var isArrayIteratorMethod = __webpack_require__(187);
var toLength = __webpack_require__(48);
var createProperty = __webpack_require__(127);
var getIteratorMethod = __webpack_require__(188);

// `Array.from` method
// https://tc39.github.io/ecma262/#sec-array.from
module.exports = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
  var O = toObject(arrayLike);
  var C = typeof this == 'function' ? this : Array;
  var argumentsLength = arguments.length;
  var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
  var mapping = mapfn !== undefined;
  var index = 0;
  var iteratorMethod = getIteratorMethod(O);
  var length, result, step, iterator;
  if (mapping) mapfn = bind(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);
  // if the target is not iterable or it's an array with the default iterator - use a simple case
  if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {
    iterator = iteratorMethod.call(O);
    result = new C();
    for (;!(step = iterator.next()).done; index++) {
      createProperty(result, index, mapping
        ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true)
        : step.value
      );
    }
  } else {
    length = toLength(O.length);
    result = new C(length);
    for (;length > index; index++) {
      createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
    }
  }
  result.length = index;
  return result;
};


/***/ }),
/* 520 */
/***/ (function(module, exports, __webpack_require__) {

var anObject = __webpack_require__(45);
var aFunction = __webpack_require__(150);
var SPECIES = __webpack_require__(35)('species');

// `SpeciesConstructor` abstract operation
// https://tc39.github.io/ecma262/#sec-speciesconstructor
module.exports = function (O, defaultConstructor) {
  var C = anObject(O).constructor;
  var S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction(S);
};


/***/ }),
/* 521 */
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__(29);
var whitespaces = __webpack_require__(197);
var non = '\u200b\u0085\u180e';

// check that a method works with the correct list
// of whitespaces and has a correct name
module.exports = function (METHOD_NAME) {
  return fails(function () {
    return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;
  });
};


/***/ }),
/* 522 */
/***/ (function(module, exports) {

function _setPrototypeOf(o, p) {
  module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };

  return _setPrototypeOf(o, p);
}

module.exports = _setPrototypeOf;

/***/ }),
/* 523 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * A overlay that renders ALL available rows & columns positioned on top of the original Walkontable instance and all other overlays.
 * Used for debugging purposes to see if the other overlays (that render only part of the rows & columns) are positioned correctly
 *
 * @class DebugOverlay
 */
var DebugOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(DebugOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function DebugOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, DebugOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DebugOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_DEBUG);
    _this.clone.wtTable.holder.style.opacity = 0.4;
    _this.clone.wtTable.holder.style.textShadow = '0 0 2px #ff0000';
    (0, _element.addClass)(_this.clone.wtTable.holder.parentNode, 'wtDebugVisible');
    return _this;
  }

  return DebugOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_DEBUG, DebugOverlay);

var _default = DebugOverlay;
exports.default = _default;

/***/ }),
/* 524 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var internalCodePointAt = __webpack_require__(146);

// `String.prototype.codePointAt` method
// https://tc39.github.io/ecma262/#sec-string.prototype.codepointat
__webpack_require__(22)({ target: 'String', proto: true }, {
  codePointAt: function codePointAt(pos) {
    return internalCodePointAt(this, pos);
  }
});


/***/ }),
/* 525 */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/tc39/proposal-string-pad-start-end
var toLength = __webpack_require__(48);
var repeat = __webpack_require__(205);
var requireObjectCoercible = __webpack_require__(58);

module.exports = function (that, maxLength, fillString, left) {
  var S = String(requireObjectCoercible(that));
  var stringLength = S.length;
  var fillStr = fillString === undefined ? ' ' : String(fillString);
  var intMaxLength = toLength(maxLength);
  var fillLen, stringFiller;
  if (intMaxLength <= stringLength || fillStr == '') return S;
  fillLen = intMaxLength - stringLength;
  stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
  if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
  return left ? stringFiller + S : S + stringFiller;
};


/***/ }),
/* 526 */
/***/ (function(module, exports, __webpack_require__) {

var map = {
	"./af": 207,
	"./af.js": 207,
	"./ar": 208,
	"./ar-dz": 209,
	"./ar-dz.js": 209,
	"./ar-kw": 210,
	"./ar-kw.js": 210,
	"./ar-ly": 211,
	"./ar-ly.js": 211,
	"./ar-ma": 212,
	"./ar-ma.js": 212,
	"./ar-sa": 213,
	"./ar-sa.js": 213,
	"./ar-tn": 214,
	"./ar-tn.js": 214,
	"./ar.js": 208,
	"./az": 215,
	"./az.js": 215,
	"./be": 216,
	"./be.js": 216,
	"./bg": 217,
	"./bg.js": 217,
	"./bm": 218,
	"./bm.js": 218,
	"./bn": 219,
	"./bn.js": 219,
	"./bo": 220,
	"./bo.js": 220,
	"./br": 221,
	"./br.js": 221,
	"./bs": 222,
	"./bs.js": 222,
	"./ca": 223,
	"./ca.js": 223,
	"./cs": 224,
	"./cs.js": 224,
	"./cv": 225,
	"./cv.js": 225,
	"./cy": 226,
	"./cy.js": 226,
	"./da": 227,
	"./da.js": 227,
	"./de": 228,
	"./de-at": 229,
	"./de-at.js": 229,
	"./de-ch": 230,
	"./de-ch.js": 230,
	"./de.js": 228,
	"./dv": 231,
	"./dv.js": 231,
	"./el": 232,
	"./el.js": 232,
	"./en-au": 233,
	"./en-au.js": 233,
	"./en-ca": 234,
	"./en-ca.js": 234,
	"./en-gb": 235,
	"./en-gb.js": 235,
	"./en-ie": 236,
	"./en-ie.js": 236,
	"./en-nz": 237,
	"./en-nz.js": 237,
	"./eo": 238,
	"./eo.js": 238,
	"./es": 239,
	"./es-do": 240,
	"./es-do.js": 240,
	"./es-us": 241,
	"./es-us.js": 241,
	"./es.js": 239,
	"./et": 242,
	"./et.js": 242,
	"./eu": 243,
	"./eu.js": 243,
	"./fa": 244,
	"./fa.js": 244,
	"./fi": 245,
	"./fi.js": 245,
	"./fo": 246,
	"./fo.js": 246,
	"./fr": 247,
	"./fr-ca": 248,
	"./fr-ca.js": 248,
	"./fr-ch": 249,
	"./fr-ch.js": 249,
	"./fr.js": 247,
	"./fy": 250,
	"./fy.js": 250,
	"./gd": 251,
	"./gd.js": 251,
	"./gl": 252,
	"./gl.js": 252,
	"./gom-latn": 253,
	"./gom-latn.js": 253,
	"./gu": 254,
	"./gu.js": 254,
	"./he": 255,
	"./he.js": 255,
	"./hi": 256,
	"./hi.js": 256,
	"./hr": 257,
	"./hr.js": 257,
	"./hu": 258,
	"./hu.js": 258,
	"./hy-am": 259,
	"./hy-am.js": 259,
	"./id": 260,
	"./id.js": 260,
	"./is": 261,
	"./is.js": 261,
	"./it": 262,
	"./it.js": 262,
	"./ja": 263,
	"./ja.js": 263,
	"./jv": 264,
	"./jv.js": 264,
	"./ka": 265,
	"./ka.js": 265,
	"./kk": 266,
	"./kk.js": 266,
	"./km": 267,
	"./km.js": 267,
	"./kn": 268,
	"./kn.js": 268,
	"./ko": 269,
	"./ko.js": 269,
	"./ky": 270,
	"./ky.js": 270,
	"./lb": 271,
	"./lb.js": 271,
	"./lo": 272,
	"./lo.js": 272,
	"./lt": 273,
	"./lt.js": 273,
	"./lv": 274,
	"./lv.js": 274,
	"./me": 275,
	"./me.js": 275,
	"./mi": 276,
	"./mi.js": 276,
	"./mk": 277,
	"./mk.js": 277,
	"./ml": 278,
	"./ml.js": 278,
	"./mr": 279,
	"./mr.js": 279,
	"./ms": 280,
	"./ms-my": 281,
	"./ms-my.js": 281,
	"./ms.js": 280,
	"./mt": 282,
	"./mt.js": 282,
	"./my": 283,
	"./my.js": 283,
	"./nb": 284,
	"./nb.js": 284,
	"./ne": 285,
	"./ne.js": 285,
	"./nl": 286,
	"./nl-be": 287,
	"./nl-be.js": 287,
	"./nl.js": 286,
	"./nn": 288,
	"./nn.js": 288,
	"./pa-in": 289,
	"./pa-in.js": 289,
	"./pl": 290,
	"./pl.js": 290,
	"./pt": 291,
	"./pt-br": 292,
	"./pt-br.js": 292,
	"./pt.js": 291,
	"./ro": 293,
	"./ro.js": 293,
	"./ru": 294,
	"./ru.js": 294,
	"./sd": 295,
	"./sd.js": 295,
	"./se": 296,
	"./se.js": 296,
	"./si": 297,
	"./si.js": 297,
	"./sk": 298,
	"./sk.js": 298,
	"./sl": 299,
	"./sl.js": 299,
	"./sq": 300,
	"./sq.js": 300,
	"./sr": 301,
	"./sr-cyrl": 302,
	"./sr-cyrl.js": 302,
	"./sr.js": 301,
	"./ss": 303,
	"./ss.js": 303,
	"./sv": 304,
	"./sv.js": 304,
	"./sw": 305,
	"./sw.js": 305,
	"./ta": 306,
	"./ta.js": 306,
	"./te": 307,
	"./te.js": 307,
	"./tet": 308,
	"./tet.js": 308,
	"./th": 309,
	"./th.js": 309,
	"./tl-ph": 310,
	"./tl-ph.js": 310,
	"./tlh": 311,
	"./tlh.js": 311,
	"./tr": 312,
	"./tr.js": 312,
	"./tzl": 313,
	"./tzl.js": 313,
	"./tzm": 314,
	"./tzm-latn": 315,
	"./tzm-latn.js": 315,
	"./tzm.js": 314,
	"./uk": 316,
	"./uk.js": 316,
	"./ur": 317,
	"./ur.js": 317,
	"./uz": 318,
	"./uz-latn": 319,
	"./uz-latn.js": 319,
	"./uz.js": 318,
	"./vi": 320,
	"./vi.js": 320,
	"./x-pseudo": 321,
	"./x-pseudo.js": 321,
	"./yo": 322,
	"./yo.js": 322,
	"./zh-cn": 323,
	"./zh-cn.js": 323,
	"./zh-hk": 324,
	"./zh-hk.js": 324,
	"./zh-tw": 325,
	"./zh-tw.js": 325
};


function webpackContext(req) {
	var id = webpackContextResolve(req);
	return __webpack_require__(id);
}
function webpackContextResolve(req) {
	if(!__webpack_require__.o(map, req)) {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return map[req];
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 526;

/***/ }),
/* 527 */
/***/ (function(module, exports) {

function _iterableToArrayLimit(arr, i) {
  var _arr = [];
  var _n = true;
  var _d = false;
  var _e = undefined;

  try {
    for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

module.exports = _iterableToArrayLimit;

/***/ }),
/* 528 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class LeftOverlay
 */
var LeftOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(LeftOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function LeftOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, LeftOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(LeftOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_LEFT);
    return _this;
  }
  /**
   * Checks if overlay should be fully rendered.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(LeftOverlay, [{
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      return !!(this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length);
    }
    /**
     * Updates the left overlay position.
     */

  }, {
    key: "resetFixedPosition",
    value: function resetFixedPosition() {
      var wtTable = this.wot.wtTable;

      if (!this.needFullRender || !wtTable.holder.parentNode) {
        // removed from DOM
        return;
      }

      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var headerPosition = 0;
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer === this.wot.rootWindow && (!preventOverflow || preventOverflow !== 'horizontal')) {
        var box = wtTable.hider.getBoundingClientRect();
        var left = Math.ceil(box.left);
        var right = Math.ceil(box.right);
        var finalLeft;
        var finalTop;
        finalTop = wtTable.hider.style.top;
        finalTop = finalTop === '' ? 0 : finalTop;

        if (left < 0 && right - overlayRoot.offsetWidth > 0) {
          finalLeft = -left;
        } else {
          finalLeft = 0;
        }

        headerPosition = finalLeft;
        finalLeft += 'px';
        (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
      } else {
        headerPosition = this.getScrollPosition();
        (0, _element.resetCssTransform)(overlayRoot);
      }

      this.adjustHeaderBordersPosition(headerPosition);
      this.adjustElementsSize();
    }
    /**
     * Sets the main overlay's horizontal scroll position.
     *
     * @param {Number} pos
     * @returns {Boolean}
     */

  }, {
    key: "setScrollPosition",
    value: function setScrollPosition(pos) {
      var rootWindow = this.wot.rootWindow;
      var result = false;

      if (this.mainTableScrollableElement === rootWindow && rootWindow.scrollX !== pos) {
        rootWindow.scrollTo(pos, (0, _element.getWindowScrollTop)(rootWindow));
        result = true;
      } else if (this.mainTableScrollableElement.scrollLeft !== pos) {
        this.mainTableScrollableElement.scrollLeft = pos;
        result = true;
      }

      return result;
    }
    /**
     * Triggers onScroll hook callback.
     */

  }, {
    key: "onScroll",
    value: function onScroll() {
      this.wot.getSetting('onScrollVertically');
    }
    /**
     * Calculates total sum cells width.
     *
     * @param {Number} from Column index which calculates started from.
     * @param {Number} to Column index where calculation is finished.
     * @returns {Number} Width sum.
     */

  }, {
    key: "sumCellSizes",
    value: function sumCellSizes(from, to) {
      var defaultColumnWidth = this.wot.wtSettings.defaultColumnWidth;
      var column = from;
      var sum = 0;

      while (column < to) {
        sum += this.wot.wtTable.getStretchedColumnWidth(column) || defaultColumnWidth;
        column += 1;
      }

      return sum;
    }
    /**
     * Adjust overlay root element, childs and master table element sizes (width, height).
     *
     * @param {Boolean} [force=false]
     */

  }, {
    key: "adjustElementsSize",
    value: function adjustElementsSize() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      this.updateTrimmingContainer();

      if (this.needFullRender || force) {
        this.adjustRootElementSize();
        this.adjustRootChildrenSize();

        if (!force) {
          this.areElementSizesAdjusted = true;
        }
      }
    }
    /**
     * Adjust overlay root element size (width and height).
     */

  }, {
    key: "adjustRootElementSize",
    value: function adjustRootElementSize() {
      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootDocument = _this$wot.rootDocument,
          rootWindow = _this$wot.rootWindow;
      var scrollbarHeight = (0, _element.getScrollbarWidth)(rootDocument);
      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var overlayRootStyle = overlayRoot.style;
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer !== rootWindow || preventOverflow === 'vertical') {
        var height = this.wot.wtViewport.getWorkspaceHeight();

        if (this.wot.wtOverlays.hasScrollbarBottom) {
          height -= scrollbarHeight;
        }

        height = Math.min(height, wtTable.wtRootElement.scrollHeight);
        overlayRootStyle.height = "".concat(height, "px");
      } else {
        overlayRootStyle.height = '';
      }

      this.clone.wtTable.holder.style.height = overlayRootStyle.height;
      var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
      overlayRootStyle.width = "".concat(tableWidth === 0 ? tableWidth : tableWidth + 4, "px");
    }
    /**
     * Adjust overlay root childs size.
     */

  }, {
    key: "adjustRootChildrenSize",
    value: function adjustRootChildrenSize() {
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      this.clone.wtTable.hider.style.height = this.hider.style.height;
      this.clone.wtTable.holder.style.height = this.clone.wtTable.holder.parentNode.style.height;

      if (scrollbarWidth === 0) {
        scrollbarWidth = 30;
      }

      this.clone.wtTable.holder.style.width = "".concat(parseInt(this.clone.wtTable.holder.parentNode.style.width, 10) + scrollbarWidth, "px");
    }
    /**
     * Adjust the overlay dimensions and position.
     */

  }, {
    key: "applyToDOM",
    value: function applyToDOM() {
      var total = this.wot.getSetting('totalColumns');

      if (!this.areElementSizesAdjusted) {
        this.adjustElementsSize();
      }

      if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
        this.spreader.style.left = "".concat(this.wot.wtViewport.columnsRenderCalculator.startPosition, "px");
      } else if (total === 0) {
        this.spreader.style.left = '0';
      } else {
        throw new Error('Incorrect value of the columnsRenderCalculator');
      }

      this.spreader.style.right = '';

      if (this.needFullRender) {
        this.syncOverlayOffset();
      }
    }
    /**
     * Synchronize calculated top position to an element.
     */

  }, {
    key: "syncOverlayOffset",
    value: function syncOverlayOffset() {
      if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
        this.clone.wtTable.spreader.style.top = "".concat(this.wot.wtViewport.rowsRenderCalculator.startPosition, "px");
      } else {
        this.clone.wtTable.spreader.style.top = '';
      }
    }
    /**
     * Scrolls horizontally to a column at the left edge of the viewport.
     *
     * @param {Number} sourceCol  Column index which you want to scroll to.
     * @param {Boolean} [beyondRendered]  if `true`, scrolls according to the bottom edge (top edge is by default).
     * @returns {Boolean}
     */

  }, {
    key: "scrollTo",
    value: function scrollTo(sourceCol, beyondRendered) {
      var newX = this.getTableParentOffset();
      var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
      var mainHolder = sourceInstance.wtTable.holder;
      var scrollbarCompensation = 0;

      if (beyondRendered && mainHolder.offsetWidth !== mainHolder.clientWidth) {
        scrollbarCompensation = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      }

      if (beyondRendered) {
        newX += this.sumCellSizes(0, sourceCol + 1);
        newX -= this.wot.wtViewport.getViewportWidth();
      } else {
        newX += this.sumCellSizes(this.wot.getSetting('fixedColumnsLeft'), sourceCol);
      }

      newX += scrollbarCompensation;
      return this.setScrollPosition(newX);
    }
    /**
     * Gets table parent left position.
     *
     * @returns {Number}
     */

  }, {
    key: "getTableParentOffset",
    value: function getTableParentOffset() {
      var preventOverflow = this.wot.getSetting('preventOverflow');
      var offset = 0;

      if (!preventOverflow && this.trimmingContainer === this.wot.rootWindow) {
        offset = this.wot.wtTable.holderOffset.left;
      }

      return offset;
    }
    /**
     * Gets the main overlay's horizontal scroll position.
     *
     * @returns {Number} Main table's vertical scroll position.
     */

  }, {
    key: "getScrollPosition",
    value: function getScrollPosition() {
      return (0, _element.getScrollLeft)(this.mainTableScrollableElement, this.wot.rootWindow);
    }
    /**
     * Adds css classes to hide the header border's header (cell-selection border hiding issue).
     *
     * @param {Number} position Header X position if trimming container is window or scroll top if not.
     */

  }, {
    key: "adjustHeaderBordersPosition",
    value: function adjustHeaderBordersPosition(position) {
      var masterParent = this.wot.wtTable.holder.parentNode;
      var rowHeaders = this.wot.getSetting('rowHeaders');
      var fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft');
      var totalRows = this.wot.getSetting('totalRows');

      if (totalRows) {
        (0, _element.removeClass)(masterParent, 'emptyRows');
      } else {
        (0, _element.addClass)(masterParent, 'emptyRows');
      }

      if (fixedColumnsLeft && !rowHeaders.length) {
        (0, _element.addClass)(masterParent, 'innerBorderLeft');
      } else if (!fixedColumnsLeft && rowHeaders.length) {
        var previousState = (0, _element.hasClass)(masterParent, 'innerBorderLeft');

        if (position) {
          (0, _element.addClass)(masterParent, 'innerBorderLeft');
        } else {
          (0, _element.removeClass)(masterParent, 'innerBorderLeft');
        }

        if (!previousState && position || previousState && !position) {
          this.wot.wtOverlays.adjustElementsSize();
        }
      }
    }
  }]);
  return LeftOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_LEFT, LeftOverlay);

var _default = LeftOverlay;
exports.default = _default;

/***/ }),
/* 529 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class TopOverlay
 */
var TopOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(TopOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function TopOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, TopOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TopOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_TOP);
    return _this;
  }
  /**
   * Checks if overlay should be fully rendered.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(TopOverlay, [{
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      return !!(this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length);
    }
    /**
     * Updates the top overlay position.
     */

  }, {
    key: "resetFixedPosition",
    value: function resetFixedPosition() {
      if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) {
        // removed from DOM
        return;
      }

      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var headerPosition = 0;
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer === this.wot.rootWindow && (!preventOverflow || preventOverflow !== 'vertical')) {
        var box = this.wot.wtTable.hider.getBoundingClientRect();
        var top = Math.ceil(box.top);
        var bottom = Math.ceil(box.bottom);
        var finalLeft;
        var finalTop;
        finalLeft = this.wot.wtTable.hider.style.left;
        finalLeft = finalLeft === '' ? 0 : finalLeft;

        if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
          finalTop = -top;
        } else {
          finalTop = 0;
        }

        headerPosition = finalTop;
        finalTop += 'px';
        (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
      } else {
        headerPosition = this.getScrollPosition();
        (0, _element.resetCssTransform)(overlayRoot);
      }

      this.adjustHeaderBordersPosition(headerPosition);
      this.adjustElementsSize();
    }
    /**
     * Sets the main overlay's vertical scroll position.
     *
     * @param {Number} pos
     * @returns {Boolean}
     */

  }, {
    key: "setScrollPosition",
    value: function setScrollPosition(pos) {
      var rootWindow = this.wot.rootWindow;
      var result = false;

      if (this.mainTableScrollableElement === rootWindow && rootWindow.scrollY !== pos) {
        rootWindow.scrollTo((0, _element.getWindowScrollLeft)(rootWindow), pos);
        result = true;
      } else if (this.mainTableScrollableElement.scrollTop !== pos) {
        this.mainTableScrollableElement.scrollTop = pos;
        result = true;
      }

      return result;
    }
    /**
     * Triggers onScroll hook callback.
     */

  }, {
    key: "onScroll",
    value: function onScroll() {
      this.wot.getSetting('onScrollHorizontally');
    }
    /**
     * Calculates total sum cells height.
     *
     * @param {Number} from Row index which calculates started from.
     * @param {Number} to Row index where calculation is finished.
     * @returns {Number} Height sum.
     */

  }, {
    key: "sumCellSizes",
    value: function sumCellSizes(from, to) {
      var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
      var row = from;
      var sum = 0;

      while (row < to) {
        var height = this.wot.wtTable.getRowHeight(row);
        sum += height === void 0 ? defaultRowHeight : height;
        row += 1;
      }

      return sum;
    }
    /**
     * Adjust overlay root element, childs and master table element sizes (width, height).
     *
     * @param {Boolean} [force=false]
     */

  }, {
    key: "adjustElementsSize",
    value: function adjustElementsSize() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      this.updateTrimmingContainer();

      if (this.needFullRender || force) {
        this.adjustRootElementSize();
        this.adjustRootChildrenSize();

        if (!force) {
          this.areElementSizesAdjusted = true;
        }
      }
    }
    /**
     * Adjust overlay root element size (width and height).
     */

  }, {
    key: "adjustRootElementSize",
    value: function adjustRootElementSize() {
      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootDocument = _this$wot.rootDocument,
          rootWindow = _this$wot.rootWindow;
      var scrollbarWidth = (0, _element.getScrollbarWidth)(rootDocument);
      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var overlayRootStyle = overlayRoot.style;
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer !== rootWindow || preventOverflow === 'horizontal') {
        var width = this.wot.wtViewport.getWorkspaceWidth();

        if (this.wot.wtOverlays.hasScrollbarRight) {
          width -= scrollbarWidth;
        }

        width = Math.min(width, wtTable.wtRootElement.scrollWidth);
        overlayRootStyle.width = "".concat(width, "px");
      } else {
        overlayRootStyle.width = '';
      }

      this.clone.wtTable.holder.style.width = overlayRootStyle.width;
      var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
      overlayRootStyle.height = "".concat(tableHeight === 0 ? tableHeight : tableHeight + 4, "px");
    }
    /**
     * Adjust overlay root childs size.
     */

  }, {
    key: "adjustRootChildrenSize",
    value: function adjustRootChildrenSize() {
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      this.clone.wtTable.hider.style.width = this.hider.style.width;
      this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width;

      if (scrollbarWidth === 0) {
        scrollbarWidth = 30;
      }

      this.clone.wtTable.holder.style.height = "".concat(parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth, "px");
    }
    /**
     * Adjust the overlay dimensions and position.
     */

  }, {
    key: "applyToDOM",
    value: function applyToDOM() {
      var total = this.wot.getSetting('totalRows');

      if (!this.areElementSizesAdjusted) {
        this.adjustElementsSize();
      }

      if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
        this.spreader.style.top = "".concat(this.wot.wtViewport.rowsRenderCalculator.startPosition, "px");
      } else if (total === 0) {
        // can happen if there are 0 rows
        this.spreader.style.top = '0';
      } else {
        throw new Error('Incorrect value of the rowsRenderCalculator');
      }

      this.spreader.style.bottom = '';

      if (this.needFullRender) {
        this.syncOverlayOffset();
      }
    }
    /**
     * Synchronize calculated left position to an element.
     */

  }, {
    key: "syncOverlayOffset",
    value: function syncOverlayOffset() {
      if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
        this.clone.wtTable.spreader.style.left = "".concat(this.wot.wtViewport.columnsRenderCalculator.startPosition, "px");
      } else {
        this.clone.wtTable.spreader.style.left = '';
      }
    }
    /**
     * Scrolls vertically to a row.
     *
     * @param {Number} sourceRow Row index which you want to scroll to.
     * @param {Boolean} [bottomEdge] if `true`, scrolls according to the bottom edge (top edge is by default).
     * @returns {Boolean}
     */

  }, {
    key: "scrollTo",
    value: function scrollTo(sourceRow, bottomEdge) {
      var wot = this.wot;
      var sourceInstance = wot.cloneSource ? wot.cloneSource : wot;
      var mainHolder = sourceInstance.wtTable.holder;
      var newY = this.getTableParentOffset();
      var scrollbarCompensation = 0;

      if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) {
        scrollbarCompensation = (0, _element.getScrollbarWidth)(wot.rootDocument);
      }

      if (bottomEdge) {
        var fixedRowsBottom = wot.getSetting('fixedRowsBottom');
        var totalRows = wot.getSetting('totalRows');
        newY += this.sumCellSizes(0, sourceRow + 1);
        newY -= wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows); // Fix 1 pixel offset when cell is selected

        newY += 1;
      } else {
        newY += this.sumCellSizes(wot.getSetting('fixedRowsTop'), sourceRow);
      }

      newY += scrollbarCompensation;
      return this.setScrollPosition(newY);
    }
    /**
     * Gets table parent top position.
     *
     * @returns {Number}
     */

  }, {
    key: "getTableParentOffset",
    value: function getTableParentOffset() {
      if (this.mainTableScrollableElement === this.wot.rootWindow) {
        return this.wot.wtTable.holderOffset.top;
      }

      return 0;
    }
    /**
     * Gets the main overlay's vertical scroll position.
     *
     * @returns {Number} Main table's vertical scroll position.
     */

  }, {
    key: "getScrollPosition",
    value: function getScrollPosition() {
      return (0, _element.getScrollTop)(this.mainTableScrollableElement, this.wot.rootWindow);
    }
    /**
     * Redraw borders of selection.
     *
     * @param {WalkontableSelection} selection Selection for redraw.
     */

  }, {
    key: "redrawSelectionBorders",
    value: function redrawSelectionBorders(selection) {
      if (selection && selection.cellRange) {
        var border = selection.getBorder(this.wot);
        var corners = selection.getCorners();
        border.disappear();
        border.appear(corners);
      }
    }
    /**
     * Redrawing borders of all selections.
     */

  }, {
    key: "redrawAllSelectionsBorders",
    value: function redrawAllSelectionsBorders() {
      var _this2 = this;

      var selections = this.wot.selections;
      this.redrawSelectionBorders(selections.getCell());
      (0, _array.arrayEach)(selections.getAreas(), function (area) {
        _this2.redrawSelectionBorders(area);
      });
      this.redrawSelectionBorders(selections.getFill());
      this.wot.wtTable.wot.wtOverlays.leftOverlay.refresh();
    }
    /**
     * Adds css classes to hide the header border's header (cell-selection border hiding issue).
     *
     * @param {Number} position Header Y position if trimming container is window or scroll top if not.
     */

  }, {
    key: "adjustHeaderBordersPosition",
    value: function adjustHeaderBordersPosition(position) {
      var masterParent = this.wot.wtTable.holder.parentNode;
      var totalColumns = this.wot.getSetting('totalColumns');

      if (totalColumns) {
        (0, _element.removeClass)(masterParent, 'emptyColumns');
      } else {
        (0, _element.addClass)(masterParent, 'emptyColumns');
      }

      if (this.wot.getSetting('fixedRowsTop') === 0 && this.wot.getSetting('columnHeaders').length > 0) {
        var previousState = (0, _element.hasClass)(masterParent, 'innerBorderTop');

        if (position || this.wot.getSetting('totalRows') === 0) {
          (0, _element.addClass)(masterParent, 'innerBorderTop');
        } else {
          (0, _element.removeClass)(masterParent, 'innerBorderTop');
        }

        if (!previousState && position || previousState && !position) {
          this.wot.wtOverlays.adjustElementsSize(); // cell borders should be positioned once again,
          // because we added / removed 1px border from table header

          this.redrawAllSelectionsBorders();
        }
      } // nasty workaround for double border in the header, TODO: find a pure-css solution


      if (this.wot.getSetting('rowHeaders').length === 0) {
        var secondHeaderCell = this.clone.wtTable.THEAD.querySelectorAll('th:nth-of-type(2)');

        if (secondHeaderCell) {
          for (var i = 0; i < secondHeaderCell.length; i++) {
            secondHeaderCell[i].style['border-left-width'] = 0;
          }
        }
      }
    }
  }]);
  return TopOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_TOP, TopOverlay);

var _default = TopOverlay;
exports.default = _default;

/***/ }),
/* 530 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class TopLeftCornerOverlay
 */
var TopLeftCornerOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(TopLeftCornerOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function TopLeftCornerOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, TopLeftCornerOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TopLeftCornerOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_TOP_LEFT_CORNER);
    return _this;
  }
  /**
   * Checks if overlay should be fully rendered
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(TopLeftCornerOverlay, [{
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      var wot = this.wot;
      return !!((wot.getSetting('fixedRowsTop') || wot.getSetting('columnHeaders').length) && (wot.getSetting('fixedColumnsLeft') || wot.getSetting('rowHeaders').length));
    }
    /**
     * Updates the corner overlay position
     */

  }, {
    key: "resetFixedPosition",
    value: function resetFixedPosition() {
      this.updateTrimmingContainer();

      if (!this.wot.wtTable.holder.parentNode) {
        // removed from DOM
        return;
      }

      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
      var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer === this.wot.rootWindow) {
        var box = this.wot.wtTable.hider.getBoundingClientRect();
        var top = Math.ceil(box.top);
        var left = Math.ceil(box.left);
        var bottom = Math.ceil(box.bottom);
        var right = Math.ceil(box.right);
        var finalLeft = '0';
        var finalTop = '0';

        if (!preventOverflow || preventOverflow === 'vertical') {
          if (left < 0 && right - overlayRoot.offsetWidth > 0) {
            finalLeft = "".concat(-left, "px");
          }
        }

        if (!preventOverflow || preventOverflow === 'horizontal') {
          if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
            finalTop = "".concat(-top, "px");
          }
        }

        (0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
      } else {
        (0, _element.resetCssTransform)(overlayRoot);
      }

      overlayRoot.style.height = "".concat(tableHeight === 0 ? tableHeight : tableHeight + 4, "px");
      overlayRoot.style.width = "".concat(tableWidth === 0 ? tableWidth : tableWidth + 4, "px");
    }
  }]);
  return TopLeftCornerOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_TOP_LEFT_CORNER, TopLeftCornerOverlay);

var _default = TopLeftCornerOverlay;
exports.default = _default;

/***/ }),
/* 531 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class BottomOverlay
 */
var BottomOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(BottomOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function BottomOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, BottomOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BottomOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_BOTTOM);
    return _this;
  }
  /**
   *
   */


  (0, _createClass2.default)(BottomOverlay, [{
    key: "repositionOverlay",
    value: function repositionOverlay() {
      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootDocument = _this$wot.rootDocument;
      var cloneRoot = this.clone.wtTable.holder.parentNode;
      var scrollbarWidth = (0, _element.getScrollbarWidth)(rootDocument);

      if (wtTable.holder.clientHeight === wtTable.holder.offsetHeight) {
        scrollbarWidth = 0;
      }

      cloneRoot.style.top = '';
      cloneRoot.style.bottom = "".concat(scrollbarWidth, "px");
    }
    /**
     * Checks if overlay should be fully rendered
     *
     * @returns {Boolean}
     */

  }, {
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      /* eslint-disable no-unneeded-ternary */
      return this.wot.getSetting('fixedRowsBottom') ? true : false;
    }
    /**
     * Updates the top overlay position
     */

  }, {
    key: "resetFixedPosition",
    value: function resetFixedPosition() {
      if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) {
        // removed from DOM
        return;
      }

      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var headerPosition = 0;
      overlayRoot.style.top = '';

      if (this.wot.wtOverlays.leftOverlay.trimmingContainer === this.wot.rootWindow) {
        var _this$wot2 = this.wot,
            rootDocument = _this$wot2.rootDocument,
            wtTable = _this$wot2.wtTable;
        var box = wtTable.hider.getBoundingClientRect();
        var bottom = Math.ceil(box.bottom);
        var finalLeft;
        var finalBottom;
        var bodyHeight = rootDocument.body.offsetHeight;
        finalLeft = wtTable.hider.style.left;
        finalLeft = finalLeft === '' ? 0 : finalLeft;

        if (bottom > bodyHeight) {
          finalBottom = bottom - bodyHeight;
        } else {
          finalBottom = 0;
        }

        headerPosition = finalBottom;
        finalBottom += 'px';
        overlayRoot.style.top = '';
        overlayRoot.style.left = finalLeft;
        overlayRoot.style.bottom = finalBottom;
      } else {
        headerPosition = this.getScrollPosition();
        (0, _element.resetCssTransform)(overlayRoot);
        this.repositionOverlay();
      }

      this.adjustHeaderBordersPosition(headerPosition);
    }
    /**
     * Sets the main overlay's vertical scroll position
     *
     * @param {Number} pos
     */

  }, {
    key: "setScrollPosition",
    value: function setScrollPosition(pos) {
      var rootWindow = this.wot.rootWindow;

      if (this.mainTableScrollableElement === rootWindow) {
        rootWindow.scrollTo((0, _element.getWindowScrollLeft)(rootWindow), pos);
      } else {
        this.mainTableScrollableElement.scrollTop = pos;
      }
    }
    /**
     * Triggers onScroll hook callback
     */

  }, {
    key: "onScroll",
    value: function onScroll() {
      this.wot.getSetting('onScrollVertically');
    }
    /**
     * Calculates total sum cells height
     *
     * @param {Number} from Row index which calculates started from
     * @param {Number} to Row index where calculation is finished
     * @returns {Number} Height sum
     */

  }, {
    key: "sumCellSizes",
    value: function sumCellSizes(from, to) {
      var _this$wot3 = this.wot,
          wtTable = _this$wot3.wtTable,
          wtSettings = _this$wot3.wtSettings;
      var defaultRowHeight = wtSettings.settings.defaultRowHeight;
      var row = from;
      var sum = 0;

      while (row < to) {
        var height = wtTable.getRowHeight(row);
        sum += height === void 0 ? defaultRowHeight : height;
        row += 1;
      }

      return sum;
    }
    /**
     * Adjust overlay root element, childs and master table element sizes (width, height).
     *
     * @param {Boolean} [force=false]
     */

  }, {
    key: "adjustElementsSize",
    value: function adjustElementsSize() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      this.updateTrimmingContainer();

      if (this.needFullRender || force) {
        this.adjustRootElementSize();
        this.adjustRootChildrenSize();

        if (!force) {
          this.areElementSizesAdjusted = true;
        }
      }
    }
    /**
     * Adjust overlay root element size (width and height).
     */

  }, {
    key: "adjustRootElementSize",
    value: function adjustRootElementSize() {
      var _this$wot4 = this.wot,
          wtTable = _this$wot4.wtTable,
          wtViewport = _this$wot4.wtViewport,
          rootWindow = _this$wot4.rootWindow;
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var overlayRootStyle = overlayRoot.style;
      var preventOverflow = this.wot.getSetting('preventOverflow');

      if (this.trimmingContainer !== rootWindow || preventOverflow === 'horizontal') {
        var width = wtViewport.getWorkspaceWidth();

        if (this.wot.wtOverlays.hasScrollbarRight) {
          width -= scrollbarWidth;
        }

        width = Math.min(width, wtTable.wtRootElement.scrollWidth);
        overlayRootStyle.width = "".concat(width, "px");
      } else {
        overlayRootStyle.width = '';
      }

      this.clone.wtTable.holder.style.width = overlayRootStyle.width;
      var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
      overlayRootStyle.height = "".concat(tableHeight === 0 ? tableHeight : tableHeight, "px");
    }
    /**
     * Adjust overlay root childs size
     */

  }, {
    key: "adjustRootChildrenSize",
    value: function adjustRootChildrenSize() {
      var scrollbarWidth = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      this.clone.wtTable.hider.style.width = this.hider.style.width;
      this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width;

      if (scrollbarWidth === 0) {
        scrollbarWidth = 30;
      }

      this.clone.wtTable.holder.style.height = "".concat(parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth, "px");
    }
    /**
     * Adjust the overlay dimensions and position
     */

  }, {
    key: "applyToDOM",
    value: function applyToDOM() {
      var total = this.wot.getSetting('totalRows');

      if (!this.areElementSizesAdjusted) {
        this.adjustElementsSize();
      }

      if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
        this.spreader.style.top = "".concat(this.wot.wtViewport.rowsRenderCalculator.startPosition, "px");
      } else if (total === 0) {
        // can happen if there are 0 rows
        this.spreader.style.top = '0';
      } else {
        throw new Error('Incorrect value of the rowsRenderCalculator');
      }

      this.spreader.style.bottom = '';

      if (this.needFullRender) {
        this.syncOverlayOffset();
      }
    }
    /**
     * Synchronize calculated left position to an element
     */

  }, {
    key: "syncOverlayOffset",
    value: function syncOverlayOffset() {
      if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
        this.clone.wtTable.spreader.style.left = "".concat(this.wot.wtViewport.columnsRenderCalculator.startPosition, "px");
      } else {
        this.clone.wtTable.spreader.style.left = '';
      }
    }
    /**
     * Scrolls vertically to a row
     *
     * @param sourceRow {Number} Row index which you want to scroll to
     * @param [bottomEdge=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default)
     */

  }, {
    key: "scrollTo",
    value: function scrollTo(sourceRow, bottomEdge) {
      var newY = this.getTableParentOffset();
      var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
      var mainHolder = sourceInstance.wtTable.holder;
      var scrollbarCompensation = 0;

      if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) {
        scrollbarCompensation = (0, _element.getScrollbarWidth)(this.wot.rootDocument);
      }

      if (bottomEdge) {
        newY += this.sumCellSizes(0, sourceRow + 1);
        newY -= this.wot.wtViewport.getViewportHeight(); // Fix 1 pixel offset when cell is selected

        newY += 1;
      } else {
        newY += this.sumCellSizes(this.wot.getSetting('fixedRowsBottom'), sourceRow);
      }

      newY += scrollbarCompensation;
      this.setScrollPosition(newY);
    }
    /**
     * Gets table parent top position
     *
     * @returns {Number}
     */

  }, {
    key: "getTableParentOffset",
    value: function getTableParentOffset() {
      if (this.mainTableScrollableElement === this.wot.rootWindow) {
        return this.wot.wtTable.holderOffset.top;
      }

      return 0;
    }
    /**
     * Gets the main overlay's vertical scroll position
     *
     * @returns {Number} Main table's vertical scroll position
     */

  }, {
    key: "getScrollPosition",
    value: function getScrollPosition() {
      return (0, _element.getScrollTop)(this.mainTableScrollableElement, this.wot.rootWindow);
    }
    /**
     * Adds css classes to hide the header border's header (cell-selection border hiding issue)
     *
     * @param {Number} position Header Y position if trimming container is window or scroll top if not
     */

  }, {
    key: "adjustHeaderBordersPosition",
    value: function adjustHeaderBordersPosition(position) {
      if (this.wot.getSetting('fixedRowsBottom') === 0 && this.wot.getSetting('columnHeaders').length > 0) {
        var masterParent = this.wot.wtTable.holder.parentNode;
        var previousState = (0, _element.hasClass)(masterParent, 'innerBorderTop');

        if (position) {
          (0, _element.addClass)(masterParent, 'innerBorderTop');
        } else {
          (0, _element.removeClass)(masterParent, 'innerBorderTop');
        }

        if (!previousState && position || previousState && !position) {
          this.wot.wtOverlays.adjustElementsSize();
        }
      } // nasty workaround for double border in the header, TODO: find a pure-css solution


      if (this.wot.getSetting('rowHeaders').length === 0) {
        var secondHeaderCell = this.clone.wtTable.THEAD.querySelector('th:nth-of-type(2)');

        if (secondHeaderCell) {
          secondHeaderCell.style['border-left-width'] = 0;
        }
      }
    }
  }]);
  return BottomOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_BOTTOM, BottomOverlay);

var _default = BottomOverlay;
exports.default = _default;

/***/ }),
/* 532 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(74));

/**
 * @class TopLeftCornerOverlay
 */
var BottomLeftCornerOverlay =
/*#__PURE__*/
function (_Overlay) {
  (0, _inherits2.default)(BottomLeftCornerOverlay, _Overlay);

  /**
   * @param {Walkontable} wotInstance
   */
  function BottomLeftCornerOverlay(wotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, BottomLeftCornerOverlay);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BottomLeftCornerOverlay).call(this, wotInstance));
    _this.clone = _this.makeClone(_base.default.CLONE_BOTTOM_LEFT_CORNER);
    return _this;
  }
  /**
   * Checks if overlay should be fully rendered
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(BottomLeftCornerOverlay, [{
    key: "shouldBeRendered",
    value: function shouldBeRendered() {
      var wot = this.wot;
      /* eslint-disable no-unneeded-ternary */

      return wot.getSetting('fixedRowsBottom') && (wot.getSetting('fixedColumnsLeft') || wot.getSetting('rowHeaders').length) ? true : false;
    }
    /**
     * Reposition the overlay.
     */

  }, {
    key: "repositionOverlay",
    value: function repositionOverlay() {
      var _this$wot = this.wot,
          wtTable = _this$wot.wtTable,
          rootDocument = _this$wot.rootDocument;
      var cloneRoot = this.clone.wtTable.holder.parentNode;
      var scrollbarWidth = (0, _element.getScrollbarWidth)(rootDocument);

      if (wtTable.holder.clientHeight === wtTable.holder.offsetHeight) {
        scrollbarWidth = 0;
      }

      cloneRoot.style.top = '';
      cloneRoot.style.bottom = "".concat(scrollbarWidth, "px");
    }
    /**
     * Updates the corner overlay position
     */

  }, {
    key: "resetFixedPosition",
    value: function resetFixedPosition() {
      var wot = this.wot;
      this.updateTrimmingContainer();

      if (!wot.wtTable.holder.parentNode) {
        // removed from DOM
        return;
      }

      var overlayRoot = this.clone.wtTable.holder.parentNode;
      var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
      var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
      overlayRoot.style.top = '';

      if (this.trimmingContainer === wot.rootWindow) {
        var box = wot.wtTable.hider.getBoundingClientRect();
        var bottom = Math.ceil(box.bottom);
        var left = Math.ceil(box.left);
        var finalLeft;
        var finalBottom;
        var bodyHeight = wot.rootDocument.body.offsetHeight;

        if (left < 0) {
          finalLeft = -left;
        } else {
          finalLeft = 0;
        }

        if (bottom > bodyHeight) {
          finalBottom = bottom - bodyHeight;
        } else {
          finalBottom = 0;
        }

        finalBottom += 'px';
        finalLeft += 'px';
        overlayRoot.style.top = '';
        overlayRoot.style.left = finalLeft;
        overlayRoot.style.bottom = finalBottom;
      } else {
        (0, _element.resetCssTransform)(overlayRoot);
        this.repositionOverlay();
      }

      overlayRoot.style.height = "".concat(tableHeight === 0 ? tableHeight : tableHeight, "px");
      overlayRoot.style.width = "".concat(tableWidth === 0 ? tableWidth : tableWidth, "px");
    }
  }]);
  return BottomLeftCornerOverlay;
}(_base.default);

_base.default.registerOverlay(_base.default.CLONE_BOTTOM_LEFT_CORNER, BottomLeftCornerOverlay);

var _default = BottomLeftCornerOverlay;
exports.default = _default;

/***/ }),
/* 533 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(39);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _border = _interopRequireDefault(__webpack_require__(336));

var _coords = _interopRequireDefault(__webpack_require__(106));

var _range = _interopRequireDefault(__webpack_require__(200));

/**
 * @class Selection
 */
var Selection =
/*#__PURE__*/
function () {
  /**
   * @param {Object} settings
   * @param {CellRange} cellRange
   */
  function Selection(settings, cellRange) {
    (0, _classCallCheck2.default)(this, Selection);
    this.settings = settings;
    this.cellRange = cellRange || null;
    this.instanceBorders = {};
    this.classNames = [this.settings.className];
    this.classNameGenerator = this.linearClassNameGenerator(this.settings.className, this.settings.layerLevel);
  }
  /**
   * Each Walkontable clone requires it's own border for every selection. This method creates and returns selection
   * borders per instance
   *
   * @param {Walkontable} wotInstance
   * @returns {Border}
   */


  (0, _createClass2.default)(Selection, [{
    key: "getBorder",
    value: function getBorder(wotInstance) {
      if (!this.instanceBorders[wotInstance.guid]) {
        this.instanceBorders[wotInstance.guid] = new _border.default(wotInstance, this.settings);
      }

      return this.instanceBorders[wotInstance.guid];
    }
    /**
     * Checks if selection is empty
     *
     * @returns {Boolean}
     */

  }, {
    key: "isEmpty",
    value: function isEmpty() {
      return this.cellRange === null;
    }
    /**
     * Adds a cell coords to the selection
     *
     * @param {CellCoords} coords
     */

  }, {
    key: "add",
    value: function add(coords) {
      if (this.isEmpty()) {
        this.cellRange = new _range.default(coords);
      } else {
        this.cellRange.expand(coords);
      }

      return this;
    }
    /**
     * If selection range from or to property equals oldCoords, replace it with newCoords. Return boolean
     * information about success
     *
     * @param {CellCoords} oldCoords
     * @param {CellCoords} newCoords
     * @returns {Boolean}
     */

  }, {
    key: "replace",
    value: function replace(oldCoords, newCoords) {
      if (!this.isEmpty()) {
        if (this.cellRange.from.isEqual(oldCoords)) {
          this.cellRange.from = newCoords;
          return true;
        }

        if (this.cellRange.to.isEqual(oldCoords)) {
          this.cellRange.to = newCoords;
          return true;
        }
      }

      return false;
    }
    /**
     * Clears selection
     *
     * @returns {Selection}
     */

  }, {
    key: "clear",
    value: function clear() {
      this.cellRange = null;
      return this;
    }
    /**
     * Returns the top left (TL) and bottom right (BR) selection coordinates
     *
     * @returns {Array} Returns array of coordinates for example `[1, 1, 5, 5]`
     */

  }, {
    key: "getCorners",
    value: function getCorners() {
      var topLeft = this.cellRange.getTopLeftCorner();
      var bottomRight = this.cellRange.getBottomRightCorner();
      return [topLeft.row, topLeft.col, bottomRight.row, bottomRight.col];
    }
    /**
     * Adds class name to cell element at given coords
     *
     * @param {Walkontable} wotInstance Walkontable instance
     * @param {Number} sourceRow Cell row coord
     * @param {Number} sourceColumn Cell column coord
     * @param {String} className Class name
     * @param {Boolean} [markIntersections=false] If `true`, linear className generator will be used to add CSS classes
     *                                            in a continuous way.
     * @returns {Selection}
     */

  }, {
    key: "addClassAtCoords",
    value: function addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) {
      var markIntersections = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
      var TD = wotInstance.wtTable.getCell(new _coords.default(sourceRow, sourceColumn));

      if ((0, _typeof2.default)(TD) === 'object') {
        var cellClassName = className;

        if (markIntersections) {
          cellClassName = this.classNameGenerator(TD);

          if (!this.classNames.includes(cellClassName)) {
            this.classNames.push(cellClassName);
          }
        }

        (0, _element.addClass)(TD, cellClassName);
      }

      return this;
    }
    /**
     * Generate helper for calculating classNames based on previously added base className.
     * The generated className is always generated as a continuation of the previous className. For example, when
     * the currently checked element has 'area-2' className the generated new className will be 'area-3'. When
     * the element doesn't have any classNames than the base className will be returned ('area');
     *
     * @param {String} baseClassName Base className to be used.
     * @param {Number} layerLevelOwner Layer level which the instance of the Selection belongs to.
     * @return {Function}
     */

  }, {
    key: "linearClassNameGenerator",
    value: function linearClassNameGenerator(baseClassName, layerLevelOwner) {
      // TODO: Make this recursive function Proper Tail Calls (TCO/PTC) friendly.
      return function calcClassName(element) {
        var previousIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;

        if (layerLevelOwner === 0 || previousIndex === 0) {
          return baseClassName;
        }

        var index = previousIndex >= 0 ? previousIndex : layerLevelOwner;
        var className = baseClassName;
        index -= 1;
        var previousClassName = index === 0 ? baseClassName : "".concat(baseClassName, "-").concat(index);

        if ((0, _element.hasClass)(element, previousClassName)) {
          var currentLayer = index + 1;
          className = "".concat(baseClassName, "-").concat(currentLayer);
        } else {
          className = calcClassName(element, index);
        }

        return className;
      };
    }
    /**
     * @param wotInstance
     */

  }, {
    key: "draw",
    value: function draw(wotInstance) {
      if (this.isEmpty()) {
        if (this.settings.border) {
          this.getBorder(wotInstance).disappear();
        }

        return;
      }

      var renderedRows = wotInstance.wtTable.getRenderedRowsCount();
      var renderedColumns = wotInstance.wtTable.getRenderedColumnsCount();
      var corners = this.getCorners();

      var _corners = (0, _slicedToArray2.default)(corners, 4),
          topRow = _corners[0],
          topColumn = _corners[1],
          bottomRow = _corners[2],
          bottomColumn = _corners[3];

      for (var column = 0; column < renderedColumns; column += 1) {
        var sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column);

        if (sourceCol >= topColumn && sourceCol <= bottomColumn) {
          var TH = wotInstance.wtTable.getColumnHeader(sourceCol);

          if (TH) {
            var newClasses = [];

            if (this.settings.highlightHeaderClassName) {
              newClasses.push(this.settings.highlightHeaderClassName);
            }

            if (this.settings.highlightColumnClassName) {
              newClasses.push(this.settings.highlightColumnClassName);
            }

            (0, _element.addClass)(TH, newClasses);
          }
        }
      }

      for (var row = 0; row < renderedRows; row += 1) {
        var sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row);

        if (sourceRow >= topRow && sourceRow <= bottomRow) {
          var _TH = wotInstance.wtTable.getRowHeader(sourceRow);

          if (_TH) {
            var _newClasses = [];

            if (this.settings.highlightHeaderClassName) {
              _newClasses.push(this.settings.highlightHeaderClassName);
            }

            if (this.settings.highlightRowClassName) {
              _newClasses.push(this.settings.highlightRowClassName);
            }

            (0, _element.addClass)(_TH, _newClasses);
          }
        }

        for (var _column = 0; _column < renderedColumns; _column += 1) {
          var _sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(_column);

          if (sourceRow >= topRow && sourceRow <= bottomRow && _sourceCol >= topColumn && _sourceCol <= bottomColumn) {
            // selected cell
            if (this.settings.className) {
              this.addClassAtCoords(wotInstance, sourceRow, _sourceCol, this.settings.className, this.settings.markIntersections);
            }
          } else if (sourceRow >= topRow && sourceRow <= bottomRow) {
            // selection is in this row
            if (this.settings.highlightRowClassName) {
              this.addClassAtCoords(wotInstance, sourceRow, _sourceCol, this.settings.highlightRowClassName);
            }
          } else if (_sourceCol >= topColumn && _sourceCol <= bottomColumn) {
            // selection is in this column
            if (this.settings.highlightColumnClassName) {
              this.addClassAtCoords(wotInstance, sourceRow, _sourceCol, this.settings.highlightColumnClassName);
            }
          }

          var additionalSelectionClass = wotInstance.getSetting('onAfterDrawSelection', sourceRow, _sourceCol, corners, this.settings.layerLevel);

          if (typeof additionalSelectionClass === 'string') {
            this.addClassAtCoords(wotInstance, sourceRow, _sourceCol, additionalSelectionClass);
          }
        }
      }

      wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className);

      if (this.settings.border) {
        // warning! border.appear modifies corners!
        this.getBorder(wotInstance).appear(corners);
      }
    }
  }]);
  return Selection;
}();

var _default = Selection;
exports.default = _default;

/***/ }),
/* 534 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var MIXIN_NAME = 'hooksRefRegisterer';
/**
 * Mixin object to extend objects functionality for auto registering hooks in an Handsontable instance.
 *
 * @type {Object}
 */

var hooksRefRegisterer = {
  /**
   * Internal hooks storage.
   */
  _hooksStorage: Object.create(null),

  /**
   * Add hook to the collection.
   *
   * @param {String} key Hook name.
   * @param {Function} callback Hook callback
   * @returns {Object}
   */
  addHook: function addHook(key, callback) {
    if (!this._hooksStorage[key]) {
      this._hooksStorage[key] = [];
    }

    this.hot.addHook(key, callback);

    this._hooksStorage[key].push(callback);

    return this;
  },

  /**
   * Remove all hooks listeners by hook name.
   *
   * @param {String} key
   */
  removeHooksByKey: function removeHooksByKey(key) {
    var _this = this;

    (0, _array.arrayEach)(this._hooksStorage[key] || [], function (callback) {
      _this.hot.removeHook(key, callback);
    });
  },

  /**
   * Clear all added hooks.
   */
  clearHooks: function clearHooks() {
    var _this2 = this;

    (0, _object.objectEach)(this._hooksStorage, function (callbacks, name) {
      return _this2.removeHooksByKey(name);
    });
    this._hooksStorage = {};
  }
};
(0, _object.defineGetter)(hooksRefRegisterer, 'MIXIN_NAME', MIXIN_NAME, {
  writable: false,
  enumerable: false
});
var _default = hooksRefRegisterer;
exports.default = _default;

/***/ }),
/* 535 */
/***/ (function(module, exports, __webpack_require__) {

var getPrototypeOf = __webpack_require__(6);

function _superPropBase(object, property) {
  while (!Object.prototype.hasOwnProperty.call(object, property)) {
    object = getPrototypeOf(object);
    if (object === null) break;
  }

  return object;
}

module.exports = _superPropBase;

/***/ }),
/* 536 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(30);

/**
 * autoResize - resizes a DOM element to the width and height of another DOM element
 *
 * Copyright 2014, Marcin Warpechowski
 * Licensed under the MIT license
 */
function autoResize() {
  var defaults = {
    minHeight: 200,
    maxHeight: 300,
    minWidth: 100,
    maxWidth: 300
  },
      el,
      body = document.body,
      text = document.createTextNode(''),
      span = document.createElement('SPAN'),
      observe = function observe(element, event, handler) {
    element.addEventListener(event, handler, false);
  },
      _unObserve = function unObserve(element, event, handler) {
    element.removeEventListener(event, handler, false);
  },
      resize = function resize(newChar) {
    var width, scrollHeight;

    if (!newChar) {
      newChar = "";
    } else if (!/^[a-zA-Z \.,\\\/\|0-9]$/.test(newChar)) {
      newChar = ".";
    }

    if (text.textContent !== void 0) {
      text.textContent = el.value + newChar;
    } else {
      text.data = el.value + newChar; //IE8
    }

    span.style.fontSize = getComputedStyle(el).fontSize;
    span.style.fontFamily = getComputedStyle(el).fontFamily;
    span.style.whiteSpace = "pre";
    body.appendChild(span);
    width = span.clientWidth + 2;
    body.removeChild(span);
    el.style.height = defaults.minHeight + 'px';

    if (defaults.minWidth > width) {
      el.style.width = defaults.minWidth + 'px';
    } else if (width > defaults.maxWidth) {
      el.style.width = defaults.maxWidth + 'px';
    } else {
      el.style.width = width + 'px';
    }

    scrollHeight = el.scrollHeight ? el.scrollHeight - 1 : 0;

    if (defaults.minHeight > scrollHeight) {
      el.style.height = defaults.minHeight + 'px';
    } else if (defaults.maxHeight < scrollHeight) {
      el.style.height = defaults.maxHeight + 'px';
      el.style.overflowY = 'visible';
    } else {
      el.style.height = scrollHeight + 'px';
    }
  },
      delayedResize = function delayedResize() {
    window.setTimeout(resize, 0);
  },
      extendDefaults = function extendDefaults(config) {
    if (config && config.minHeight) {
      if (config.minHeight == 'inherit') {
        defaults.minHeight = el.clientHeight;
      } else {
        var minHeight = parseInt(config.minHeight);

        if (!isNaN(minHeight)) {
          defaults.minHeight = minHeight;
        }
      }
    }

    if (config && config.maxHeight) {
      if (config.maxHeight == 'inherit') {
        defaults.maxHeight = el.clientHeight;
      } else {
        var maxHeight = parseInt(config.maxHeight);

        if (!isNaN(maxHeight)) {
          defaults.maxHeight = maxHeight;
        }
      }
    }

    if (config && config.minWidth) {
      if (config.minWidth == 'inherit') {
        defaults.minWidth = el.clientWidth;
      } else {
        var minWidth = parseInt(config.minWidth);

        if (!isNaN(minWidth)) {
          defaults.minWidth = minWidth;
        }
      }
    }

    if (config && config.maxWidth) {
      if (config.maxWidth == 'inherit') {
        defaults.maxWidth = el.clientWidth;
      } else {
        var maxWidth = parseInt(config.maxWidth);

        if (!isNaN(maxWidth)) {
          defaults.maxWidth = maxWidth;
        }
      }
    }

    if (!span.firstChild) {
      span.className = "autoResize";
      span.style.display = 'inline-block';
      span.appendChild(text);
    }
  },
      _init = function init(el_, config, doObserve) {
    el = el_;
    extendDefaults(config);

    if (el.nodeName == 'TEXTAREA') {
      el.style.resize = 'none';
      el.style.overflowY = '';
      el.style.height = defaults.minHeight + 'px';
      el.style.minWidth = defaults.minWidth + 'px';
      el.style.maxWidth = defaults.maxWidth + 'px';
      el.style.overflowY = 'hidden';
    }

    if (doObserve) {
      observe(el, 'change', resize);
      observe(el, 'cut', delayedResize);
      observe(el, 'paste', delayedResize);
      observe(el, 'drop', delayedResize);
      observe(el, 'keydown', delayedResize);
      observe(el, 'focus', resize);
      observe(el, 'compositionstart', delayedResize);
      observe(el, 'compositionupdate', delayedResize);
      observe(el, 'compositionend', delayedResize);
    }

    resize();
  };

  function getComputedStyle(element) {
    return element.currentStyle || document.defaultView.getComputedStyle(element);
  }

  return {
    init: function init(el_, config, doObserve) {
      _init(el_, config, doObserve);
    },
    unObserve: function unObserve() {
      _unObserve(el, 'change', resize);

      _unObserve(el, 'cut', delayedResize);

      _unObserve(el, 'paste', delayedResize);

      _unObserve(el, 'drop', delayedResize);

      _unObserve(el, 'keydown', delayedResize);

      _unObserve(el, 'focus', resize);

      _unObserve(el, 'compositionstart', delayedResize);

      _unObserve(el, 'compositionupdate', delayedResize);

      _unObserve(el, 'compositionend', delayedResize);
    },
    resize: resize
  };
}

if (true) {
  module.exports = autoResize;
}

/***/ }),
/* 537 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _baseEditor = _interopRequireDefault(__webpack_require__(104));

var _element = __webpack_require__(5);

/**
 * @private
 * @editor CheckboxEditor
 * @class CheckboxEditor
 */
var CheckboxEditor =
/*#__PURE__*/
function (_BaseEditor) {
  (0, _inherits2.default)(CheckboxEditor, _BaseEditor);

  function CheckboxEditor() {
    (0, _classCallCheck2.default)(this, CheckboxEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CheckboxEditor).apply(this, arguments));
  }

  (0, _createClass2.default)(CheckboxEditor, [{
    key: "beginEditing",
    value: function beginEditing(initialValue, event) {
      // Just some events connected with checkbox editor are delegated here. Some `keydown` events like `enter` and `space` key press
      // are handled inside `checkboxRenderer`. Some events come here from `editorManager`. Below `if` statement was created by author
      // for purpose of handling only `doubleclick` event which may be done on a cell with checkbox.
      if (event && event.type === 'mouseup') {
        var checkbox = this.TD.querySelector('input[type="checkbox"]');

        if (!(0, _element.hasClass)(checkbox, 'htBadValue')) {
          checkbox.click();
        }
      }
    }
  }, {
    key: "finishEditing",
    value: function finishEditing() {}
  }, {
    key: "init",
    value: function init() {}
  }, {
    key: "open",
    value: function open() {}
  }, {
    key: "close",
    value: function close() {}
  }, {
    key: "getValue",
    value: function getValue() {}
  }, {
    key: "setValue",
    value: function setValue() {}
  }, {
    key: "focus",
    value: function focus() {}
  }]);
  return CheckboxEditor;
}(_baseEditor.default);

var _default = CheckboxEditor;
exports.default = _default;

/***/ }),
/* 538 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _moment = _interopRequireDefault(__webpack_require__(63));

var _pikaday = _interopRequireDefault(__webpack_require__(539));

__webpack_require__(542);

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _unicode = __webpack_require__(50);

var _event = __webpack_require__(31);

var _textEditor = _interopRequireDefault(__webpack_require__(107));

/**
 * @private
 * @editor DateEditor
 * @class DateEditor
 * @dependencies TextEditor
 */
var DateEditor =
/*#__PURE__*/
function (_TextEditor) {
  (0, _inherits2.default)(DateEditor, _TextEditor);

  /**
   * @param {Core} hotInstance Handsontable instance
   * @private
   */
  function DateEditor(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, DateEditor);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DateEditor).call(this, hotInstance)); // TODO: Move this option to general settings

    _this.defaultDateFormat = 'DD/MM/YYYY';
    _this.isCellEdited = false;
    _this.parentDestroyed = false;
    return _this;
  }

  (0, _createClass2.default)(DateEditor, [{
    key: "init",
    value: function init() {
      var _this2 = this;

      if (typeof _moment.default !== 'function') {
        throw new Error('You need to include moment.js to your project.');
      }

      if (typeof _pikaday.default !== 'function') {
        throw new Error('You need to include Pikaday to your project.');
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "init", this).call(this);
      this.instance.addHook('afterDestroy', function () {
        _this2.parentDestroyed = true;

        _this2.destroyElements();
      });
    }
    /**
     * Create data picker instance
     */

  }, {
    key: "createElements",
    value: function createElements() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "createElements", this).call(this);
      this.datePicker = this.hot.rootDocument.createElement('DIV');
      this.datePickerStyle = this.datePicker.style;
      this.datePickerStyle.position = 'absolute';
      this.datePickerStyle.top = 0;
      this.datePickerStyle.left = 0;
      this.datePickerStyle.zIndex = 9999;
      (0, _element.addClass)(this.datePicker, 'htDatepickerHolder');
      this.hot.rootDocument.body.appendChild(this.datePicker);
      this.$datePicker = new _pikaday.default(this.getDatePickerConfig());
      var eventManager = new _eventManager.default(this);
      /**
       * Prevent recognizing clicking on datepicker as clicking outside of table
       */

      eventManager.addEventListener(this.datePicker, 'mousedown', function (event) {
        return (0, _event.stopPropagation)(event);
      });
      this.hideDatepicker();
    }
    /**
     * Destroy data picker instance
     */

  }, {
    key: "destroyElements",
    value: function destroyElements() {
      this.$datePicker.destroy();
    }
    /**
     * Prepare editor to appear
     *
     * @param {Number} row Row index
     * @param {Number} col Column index
     * @param {String} prop Property name (passed when datasource is an array of objects)
     * @param {HTMLTableCellElement} td Table cell element
     * @param {*} originalValue Original value
     * @param {Object} cellProperties Object with cell properties ({@see Core#getCellMeta})
     */

  }, {
    key: "prepare",
    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "prepare", this).call(this, row, col, prop, td, originalValue, cellProperties);
    }
    /**
     * Open editor
     *
     * @param {Event} [event=null]
     */

  }, {
    key: "open",
    value: function open() {
      var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "open", this).call(this);
      this.showDatepicker(event);
    }
    /**
     * Close editor
     */

  }, {
    key: "close",
    value: function close() {
      var _this3 = this;

      this._opened = false;

      this.instance._registerTimeout(function () {
        _this3.instance._refreshBorders();
      });

      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "close", this).call(this);
    }
    /**
     * @param {Boolean} [isCancelled=false]
     * @param {Boolean} [ctrlDown=false]
     */

  }, {
    key: "finishEditing",
    value: function finishEditing() {
      var isCancelled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var ctrlDown = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

      if (isCancelled) {
        // pressed ESC, restore original value
        // var value = this.instance.getDataAtCell(this.row, this.col);
        var value = this.originalValue;

        if (value !== void 0) {
          this.setValue(value);
        }
      }

      this.hideDatepicker();
      (0, _get2.default)((0, _getPrototypeOf2.default)(DateEditor.prototype), "finishEditing", this).call(this, isCancelled, ctrlDown);
    }
    /**
     * Show data picker
     *
     * @param {Event} event
     */

  }, {
    key: "showDatepicker",
    value: function showDatepicker(event) {
      this.$datePicker.config(this.getDatePickerConfig());
      var offset = this.TD.getBoundingClientRect();
      var dateFormat = this.cellProperties.dateFormat || this.defaultDateFormat;
      var datePickerConfig = this.$datePicker.config();
      var dateStr;
      var isMouseDown = this.instance.view.isMouseDown();
      var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false;
      this.datePickerStyle.top = "".concat(this.hot.rootWindow.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD), "px");
      this.datePickerStyle.left = "".concat(this.hot.rootWindow.pageXOffset + offset.left, "px");

      this.$datePicker._onInputFocus = function () {};

      datePickerConfig.format = dateFormat;

      if (this.originalValue) {
        dateStr = this.originalValue;

        if ((0, _moment.default)(dateStr, dateFormat, true).isValid()) {
          this.$datePicker.setMoment((0, _moment.default)(dateStr, dateFormat), true);
        } // workaround for date/time cells - pikaday resets the cell value to 12:00 AM by default, this will overwrite the value.


        if (this.getValue() !== this.originalValue) {
          this.setValue(this.originalValue);
        }

        if (!isMeta && !isMouseDown) {
          this.setValue('');
        }
      } else if (this.cellProperties.defaultDate) {
        dateStr = this.cellProperties.defaultDate;
        datePickerConfig.defaultDate = dateStr;

        if ((0, _moment.default)(dateStr, dateFormat, true).isValid()) {
          this.$datePicker.setMoment((0, _moment.default)(dateStr, dateFormat), true);
        }

        if (!isMeta && !isMouseDown) {
          this.setValue('');
        }
      } else {
        // if a default date is not defined, set a soft-default-date: display the current day and month in the
        // datepicker, but don't fill the editor input
        this.$datePicker.gotoToday();
      }

      this.datePickerStyle.display = 'block';
      this.$datePicker.show();
    }
    /**
     * Hide data picker
     */

  }, {
    key: "hideDatepicker",
    value: function hideDatepicker() {
      this.datePickerStyle.display = 'none';
      this.$datePicker.hide();
    }
    /**
     * Get date picker options.
     *
     * @returns {Object}
     */

  }, {
    key: "getDatePickerConfig",
    value: function getDatePickerConfig() {
      var _this4 = this;

      var htInput = this.TEXTAREA;
      var options = {};

      if (this.cellProperties && this.cellProperties.datePickerConfig) {
        (0, _object.deepExtend)(options, this.cellProperties.datePickerConfig);
      }

      var origOnSelect = options.onSelect;
      var origOnClose = options.onClose;
      options.field = htInput;
      options.trigger = htInput;
      options.container = this.datePicker;
      options.bound = false;
      options.format = options.format || this.defaultDateFormat;
      options.reposition = options.reposition || false;

      options.onSelect = function (value) {
        var dateStr = value;

        if (!isNaN(dateStr.getTime())) {
          dateStr = (0, _moment.default)(dateStr).format(_this4.cellProperties.dateFormat || _this4.defaultDateFormat);
        }

        _this4.setValue(dateStr);

        _this4.hideDatepicker();

        if (origOnSelect) {
          origOnSelect();
        }
      };

      options.onClose = function () {
        if (!_this4.parentDestroyed) {
          _this4.finishEditing(false);
        }

        if (origOnClose) {
          origOnClose();
        }
      };

      return options;
    }
  }]);
  return DateEditor;
}(_textEditor.default);

var _default = DateEditor;
exports.default = _default;

/***/ }),
/* 539 */
/***/ (function(module, exports, __webpack_require__) {

/*!
 * Pikaday
 *
 * Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
 */

(function (root, factory)
{
    'use strict';

    var moment;
    if (true) {
        // CommonJS module
        // Load moment.js as an optional dependency
        try { moment = __webpack_require__(540); } catch (e) {}
        module.exports = factory(moment);
    } else {}
}(this, function (moment)
{
    'use strict';

    /**
     * feature detection and helper functions
     */
    var hasMoment = typeof moment === 'function',

    hasEventListeners = !!window.addEventListener,

    document = window.document,

    sto = window.setTimeout,

    addEvent = function(el, e, callback, capture)
    {
        if (hasEventListeners) {
            el.addEventListener(e, callback, !!capture);
        } else {
            el.attachEvent('on' + e, callback);
        }
    },

    removeEvent = function(el, e, callback, capture)
    {
        if (hasEventListeners) {
            el.removeEventListener(e, callback, !!capture);
        } else {
            el.detachEvent('on' + e, callback);
        }
    },

    fireEvent = function(el, eventName, data)
    {
        var ev;

        if (document.createEvent) {
            ev = document.createEvent('HTMLEvents');
            ev.initEvent(eventName, true, false);
            ev = extend(ev, data);
            el.dispatchEvent(ev);
        } else if (document.createEventObject) {
            ev = document.createEventObject();
            ev = extend(ev, data);
            el.fireEvent('on' + eventName, ev);
        }
    },

    trim = function(str)
    {
        return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
    },

    hasClass = function(el, cn)
    {
        return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
    },

    addClass = function(el, cn)
    {
        if (!hasClass(el, cn)) {
            el.className = (el.className === '') ? cn : el.className + ' ' + cn;
        }
    },

    removeClass = function(el, cn)
    {
        el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
    },

    isArray = function(obj)
    {
        return (/Array/).test(Object.prototype.toString.call(obj));
    },

    isDate = function(obj)
    {
        return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
    },

    isWeekend = function(date)
    {
        var day = date.getDay();
        return day === 0 || day === 6;
    },

    isLeapYear = function(year)
    {
        // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
        return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
    },

    getDaysInMonth = function(year, month)
    {
        return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    },

    setToStartOfDay = function(date)
    {
        if (isDate(date)) date.setHours(0,0,0,0);
    },

    compareDates = function(a,b)
    {
        // weak date comparison (use setToStartOfDay(date) to ensure correct result)
        return a.getTime() === b.getTime();
    },

    extend = function(to, from, overwrite)
    {
        var prop, hasProp;
        for (prop in from) {
            hasProp = to[prop] !== undefined;
            if (hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined) {
                if (isDate(from[prop])) {
                    if (overwrite) {
                        to[prop] = new Date(from[prop].getTime());
                    }
                }
                else if (isArray(from[prop])) {
                    if (overwrite) {
                        to[prop] = from[prop].slice(0);
                    }
                } else {
                    to[prop] = extend({}, from[prop], overwrite);
                }
            } else if (overwrite || !hasProp) {
                to[prop] = from[prop];
            }
        }
        return to;
    },

    adjustCalendar = function(calendar) {
        if (calendar.month < 0) {
            calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
            calendar.month += 12;
        }
        if (calendar.month > 11) {
            calendar.year += Math.floor(Math.abs(calendar.month)/12);
            calendar.month -= 12;
        }
        return calendar;
    },

    /**
     * defaults and localisation
     */
    defaults = {

        // bind the picker to a form field
        field: null,

        // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
        bound: undefined,

        // position of the datepicker, relative to the field (default to bottom & left)
        // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
        position: 'bottom left',

        // automatically fit in the viewport even if it means repositioning from the position option
        reposition: true,

        // the default output format for `.toString()` and `field` value
        format: 'YYYY-MM-DD',

        // the initial date to view when first opened
        defaultDate: null,

        // make the `defaultDate` the initial selected value
        setDefaultDate: false,

        // first day of week (0: Sunday, 1: Monday etc)
        firstDay: 0,

        // the default flag for moment's strict date parsing
        formatStrict: false,

        // the minimum/earliest date that can be selected
        minDate: null,
        // the maximum/latest date that can be selected
        maxDate: null,

        // number of years either side, or array of upper/lower range
        yearRange: 10,

        // show week numbers at head of row
        showWeekNumber: false,

        // used internally (don't config outside)
        minYear: 0,
        maxYear: 9999,
        minMonth: undefined,
        maxMonth: undefined,

        startRange: null,
        endRange: null,

        isRTL: false,

        // Additional text to append to the year in the calendar title
        yearSuffix: '',

        // Render the month after year in the calendar title
        showMonthAfterYear: false,

        // Render days of the calendar grid that fall in the next or previous month
        showDaysInNextAndPreviousMonths: false,

        // how many months are visible
        numberOfMonths: 1,

        // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
        // only used for the first display or when a selected date is not visible
        mainCalendar: 'left',

        // Specify a DOM element to render the calendar in
        container: undefined,

        // internationalization
        i18n: {
            previousMonth : 'Previous Month',
            nextMonth     : 'Next Month',
            months        : ['January','February','March','April','May','June','July','August','September','October','November','December'],
            weekdays      : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
            weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
        },

        // Theme Classname
        theme: null,

        // callback function
        onSelect: null,
        onOpen: null,
        onClose: null,
        onDraw: null
    },


    /**
     * templating functions to abstract HTML rendering
     */
    renderDayName = function(opts, day, abbr)
    {
        day += opts.firstDay;
        while (day >= 7) {
            day -= 7;
        }
        return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
    },

    renderDay = function(opts)
    {
        var arr = [];
        var ariaSelected = 'false';
        if (opts.isEmpty) {
            if (opts.showDaysInNextAndPreviousMonths) {
                arr.push('is-outside-current-month');
            } else {
                return '<td class="is-empty"></td>';
            }
        }
        if (opts.isDisabled) {
            arr.push('is-disabled');
        }
        if (opts.isToday) {
            arr.push('is-today');
        }
        if (opts.isSelected) {
            arr.push('is-selected');
            ariaSelected = 'true';
        }
        if (opts.isInRange) {
            arr.push('is-inrange');
        }
        if (opts.isStartRange) {
            arr.push('is-startrange');
        }
        if (opts.isEndRange) {
            arr.push('is-endrange');
        }
        return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '" aria-selected="' + ariaSelected + '">' +
                 '<button class="pika-button pika-day" type="button" ' +
                    'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
                        opts.day +
                 '</button>' +
               '</td>';
    },

    renderWeek = function (d, m, y) {
        // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
        var onejan = new Date(y, 0, 1),
            weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
        return '<td class="pika-week">' + weekNum + '</td>';
    },

    renderRow = function(days, isRTL)
    {
        return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
    },

    renderBody = function(rows)
    {
        return '<tbody>' + rows.join('') + '</tbody>';
    },

    renderHead = function(opts)
    {
        var i, arr = [];
        if (opts.showWeekNumber) {
            arr.push('<th></th>');
        }
        for (i = 0; i < 7; i++) {
            arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
        }
        return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
    },

    renderTitle = function(instance, c, year, month, refYear, randId)
    {
        var i, j, arr,
            opts = instance._o,
            isMinYear = year === opts.minYear,
            isMaxYear = year === opts.maxYear,
            html = '<div id="' + randId + '" class="pika-title" role="heading" aria-live="assertive">',
            monthHtml,
            yearHtml,
            prev = true,
            next = true;

        for (arr = [], i = 0; i < 12; i++) {
            arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
                (i === month ? ' selected="selected"': '') +
                ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled="disabled"' : '') + '>' +
                opts.i18n.months[i] + '</option>');
        }

        monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';

        if (isArray(opts.yearRange)) {
            i = opts.yearRange[0];
            j = opts.yearRange[1] + 1;
        } else {
            i = year - opts.yearRange;
            j = 1 + year + opts.yearRange;
        }

        for (arr = []; i < j && i <= opts.maxYear; i++) {
            if (i >= opts.minYear) {
                arr.push('<option value="' + i + '"' + (i === year ? ' selected="selected"': '') + '>' + (i) + '</option>');
            }
        }
        yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';

        if (opts.showMonthAfterYear) {
            html += yearHtml + monthHtml;
        } else {
            html += monthHtml + yearHtml;
        }

        if (isMinYear && (month === 0 || opts.minMonth >= month)) {
            prev = false;
        }

        if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
            next = false;
        }

        if (c === 0) {
            html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
        }
        if (c === (instance._o.numberOfMonths - 1) ) {
            html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
        }

        return html += '</div>';
    },

    renderTable = function(opts, data, randId)
    {
        return '<table cellpadding="0" cellspacing="0" class="pika-table" role="grid" aria-labelledby="' + randId + '">' + renderHead(opts) + renderBody(data) + '</table>';
    },


    /**
     * Pikaday constructor
     */
    Pikaday = function(options)
    {
        var self = this,
            opts = self.config(options);

        self._onMouseDown = function(e)
        {
            if (!self._v) {
                return;
            }
            e = e || window.event;
            var target = e.target || e.srcElement;
            if (!target) {
                return;
            }

            if (!hasClass(target, 'is-disabled')) {
                if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty') && !hasClass(target.parentNode, 'is-disabled')) {
                    self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
                    if (opts.bound) {
                        sto(function() {
                            self.hide();
                            if (opts.field) {
                                opts.field.blur();
                            }
                        }, 100);
                    }
                }
                else if (hasClass(target, 'pika-prev')) {
                    self.prevMonth();
                }
                else if (hasClass(target, 'pika-next')) {
                    self.nextMonth();
                }
            }
            if (!hasClass(target, 'pika-select')) {
                // if this is touch event prevent mouse events emulation
                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                    return false;
                }
            } else {
                self._c = true;
            }
        };

        self._onChange = function(e)
        {
            e = e || window.event;
            var target = e.target || e.srcElement;
            if (!target) {
                return;
            }
            if (hasClass(target, 'pika-select-month')) {
                self.gotoMonth(target.value);
            }
            else if (hasClass(target, 'pika-select-year')) {
                self.gotoYear(target.value);
            }
        };

        self._onKeyChange = function(e)
        {
            e = e || window.event;

            if (self.isVisible()) {

                switch(e.keyCode){
                    case 13:
                    case 27:
                        opts.field.blur();
                        break;
                    case 37:
                        e.preventDefault();
                        self.adjustDate('subtract', 1);
                        break;
                    case 38:
                        self.adjustDate('subtract', 7);
                        break;
                    case 39:
                        self.adjustDate('add', 1);
                        break;
                    case 40:
                        self.adjustDate('add', 7);
                        break;
                }
            }
        };

        self._onInputChange = function(e)
        {
            var date;

            if (e.firedBy === self) {
                return;
            }
            if (hasMoment) {
                date = moment(opts.field.value, opts.format, opts.formatStrict);
                date = (date && date.isValid()) ? date.toDate() : null;
            }
            else {
                date = new Date(Date.parse(opts.field.value));
            }
            if (isDate(date)) {
              self.setDate(date);
            }
            if (!self._v) {
                self.show();
            }
        };

        self._onInputFocus = function()
        {
            self.show();
        };

        self._onInputClick = function()
        {
            self.show();
        };

        self._onInputBlur = function()
        {
            // IE allows pika div to gain focus; catch blur the input field
            var pEl = document.activeElement;
            do {
                if (hasClass(pEl, 'pika-single')) {
                    return;
                }
            }
            while ((pEl = pEl.parentNode));

            if (!self._c) {
                self._b = sto(function() {
                    self.hide();
                }, 50);
            }
            self._c = false;
        };

        self._onClick = function(e)
        {
            e = e || window.event;
            var target = e.target || e.srcElement,
                pEl = target;
            if (!target) {
                return;
            }
            if (!hasEventListeners && hasClass(target, 'pika-select')) {
                if (!target.onchange) {
                    target.setAttribute('onchange', 'return;');
                    addEvent(target, 'change', self._onChange);
                }
            }
            do {
                if (hasClass(pEl, 'pika-single') || pEl === opts.trigger) {
                    return;
                }
            }
            while ((pEl = pEl.parentNode));
            if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
                self.hide();
            }
        };

        self.el = document.createElement('div');
        self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');

        addEvent(self.el, 'mousedown', self._onMouseDown, true);
        addEvent(self.el, 'touchend', self._onMouseDown, true);
        addEvent(self.el, 'change', self._onChange);
        addEvent(document, 'keydown', self._onKeyChange);

        if (opts.field) {
            if (opts.container) {
                opts.container.appendChild(self.el);
            } else if (opts.bound) {
                document.body.appendChild(self.el);
            } else {
                opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
            }
            addEvent(opts.field, 'change', self._onInputChange);

            if (!opts.defaultDate) {
                if (hasMoment && opts.field.value) {
                    opts.defaultDate = moment(opts.field.value, opts.format).toDate();
                } else {
                    opts.defaultDate = new Date(Date.parse(opts.field.value));
                }
                opts.setDefaultDate = true;
            }
        }

        var defDate = opts.defaultDate;

        if (isDate(defDate)) {
            if (opts.setDefaultDate) {
                self.setDate(defDate, true);
            } else {
                self.gotoDate(defDate);
            }
        } else {
            self.gotoDate(new Date());
        }

        if (opts.bound) {
            this.hide();
            self.el.className += ' is-bound';
            addEvent(opts.trigger, 'click', self._onInputClick);
            addEvent(opts.trigger, 'focus', self._onInputFocus);
            addEvent(opts.trigger, 'blur', self._onInputBlur);
        } else {
            this.show();
        }
    };


    /**
     * public Pikaday API
     */
    Pikaday.prototype = {


        /**
         * configure functionality
         */
        config: function(options)
        {
            if (!this._o) {
                this._o = extend({}, defaults, true);
            }

            var opts = extend(this._o, options, true);

            opts.isRTL = !!opts.isRTL;

            opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;

            opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;

            opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);

            opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;

            opts.disableWeekends = !!opts.disableWeekends;

            opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;

            var nom = parseInt(opts.numberOfMonths, 10) || 1;
            opts.numberOfMonths = nom > 4 ? 4 : nom;

            if (!isDate(opts.minDate)) {
                opts.minDate = false;
            }
            if (!isDate(opts.maxDate)) {
                opts.maxDate = false;
            }
            if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) {
                opts.maxDate = opts.minDate = false;
            }
            if (opts.minDate) {
                this.setMinDate(opts.minDate);
            }
            if (opts.maxDate) {
                this.setMaxDate(opts.maxDate);
            }

            if (isArray(opts.yearRange)) {
                var fallback = new Date().getFullYear() - 10;
                opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
                opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
            } else {
                opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
                if (opts.yearRange > 100) {
                    opts.yearRange = 100;
                }
            }

            return opts;
        },

        /**
         * return a formatted string of the current selection (using Moment.js if available)
         */
        toString: function(format)
        {
            return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString();
        },

        /**
         * return a Moment.js object of the current selection (if available)
         */
        getMoment: function()
        {
            return hasMoment ? moment(this._d) : null;
        },

        /**
         * set the current selection from a Moment.js object (if available)
         */
        setMoment: function(date, preventOnSelect)
        {
            if (hasMoment && moment.isMoment(date)) {
                this.setDate(date.toDate(), preventOnSelect);
            }
        },

        /**
         * return a Date object of the current selection with fallback for the current date
         */
        getDate: function()
        {
            return isDate(this._d) ? new Date(this._d.getTime()) : new Date();
        },

        /**
         * set the current selection
         */
        setDate: function(date, preventOnSelect)
        {
            if (!date) {
                this._d = null;

                if (this._o.field) {
                    this._o.field.value = '';
                    fireEvent(this._o.field, 'change', { firedBy: this });
                }

                return this.draw();
            }
            if (typeof date === 'string') {
                date = new Date(Date.parse(date));
            }
            if (!isDate(date)) {
                return;
            }

            var min = this._o.minDate,
                max = this._o.maxDate;

            if (isDate(min) && date < min) {
                date = min;
            } else if (isDate(max) && date > max) {
                date = max;
            }

            this._d = new Date(date.getTime());
            setToStartOfDay(this._d);
            this.gotoDate(this._d);

            if (this._o.field) {
                this._o.field.value = this.toString();
                fireEvent(this._o.field, 'change', { firedBy: this });
            }
            if (!preventOnSelect && typeof this._o.onSelect === 'function') {
                this._o.onSelect.call(this, this.getDate());
            }
        },

        /**
         * change view to a specific date
         */
        gotoDate: function(date)
        {
            var newCalendar = true;

            if (!isDate(date)) {
                return;
            }

            if (this.calendars) {
                var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
                    lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
                    visibleDate = date.getTime();
                // get the end of the month
                lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);
                lastVisibleDate.setDate(lastVisibleDate.getDate()-1);
                newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
            }

            if (newCalendar) {
                this.calendars = [{
                    month: date.getMonth(),
                    year: date.getFullYear()
                }];
                if (this._o.mainCalendar === 'right') {
                    this.calendars[0].month += 1 - this._o.numberOfMonths;
                }
            }

            this.adjustCalendars();
        },

        adjustDate: function(sign, days) {

            var day = this.getDate();
            var difference = parseInt(days)*24*60*60*1000;

            var newDay;

            if (sign === 'add') {
                newDay = new Date(day.valueOf() + difference);
            } else if (sign === 'subtract') {
                newDay = new Date(day.valueOf() - difference);
            }

            if (hasMoment) {
                if (sign === 'add') {
                    newDay = moment(day).add(days, "days").toDate();
                } else if (sign === 'subtract') {
                    newDay = moment(day).subtract(days, "days").toDate();
                }
            }

            this.setDate(newDay);
        },

        adjustCalendars: function() {
            this.calendars[0] = adjustCalendar(this.calendars[0]);
            for (var c = 1; c < this._o.numberOfMonths; c++) {
                this.calendars[c] = adjustCalendar({
                    month: this.calendars[0].month + c,
                    year: this.calendars[0].year
                });
            }
            this.draw();
        },

        gotoToday: function()
        {
            this.gotoDate(new Date());
        },

        /**
         * change view to a specific month (zero-index, e.g. 0: January)
         */
        gotoMonth: function(month)
        {
            if (!isNaN(month)) {
                this.calendars[0].month = parseInt(month, 10);
                this.adjustCalendars();
            }
        },

        nextMonth: function()
        {
            this.calendars[0].month++;
            this.adjustCalendars();
        },

        prevMonth: function()
        {
            this.calendars[0].month--;
            this.adjustCalendars();
        },

        /**
         * change view to a specific full year (e.g. "2012")
         */
        gotoYear: function(year)
        {
            if (!isNaN(year)) {
                this.calendars[0].year = parseInt(year, 10);
                this.adjustCalendars();
            }
        },

        /**
         * change the minDate
         */
        setMinDate: function(value)
        {
            if(value instanceof Date) {
                setToStartOfDay(value);
                this._o.minDate = value;
                this._o.minYear  = value.getFullYear();
                this._o.minMonth = value.getMonth();
            } else {
                this._o.minDate = defaults.minDate;
                this._o.minYear  = defaults.minYear;
                this._o.minMonth = defaults.minMonth;
                this._o.startRange = defaults.startRange;
            }

            this.draw();
        },

        /**
         * change the maxDate
         */
        setMaxDate: function(value)
        {
            if(value instanceof Date) {
                setToStartOfDay(value);
                this._o.maxDate = value;
                this._o.maxYear = value.getFullYear();
                this._o.maxMonth = value.getMonth();
            } else {
                this._o.maxDate = defaults.maxDate;
                this._o.maxYear = defaults.maxYear;
                this._o.maxMonth = defaults.maxMonth;
                this._o.endRange = defaults.endRange;
            }

            this.draw();
        },

        setStartRange: function(value)
        {
            this._o.startRange = value;
        },

        setEndRange: function(value)
        {
            this._o.endRange = value;
        },

        /**
         * refresh the HTML
         */
        draw: function(force)
        {
            if (!this._v && !force) {
                return;
            }
            var opts = this._o,
                minYear = opts.minYear,
                maxYear = opts.maxYear,
                minMonth = opts.minMonth,
                maxMonth = opts.maxMonth,
                html = '',
                randId;

            if (this._y <= minYear) {
                this._y = minYear;
                if (!isNaN(minMonth) && this._m < minMonth) {
                    this._m = minMonth;
                }
            }
            if (this._y >= maxYear) {
                this._y = maxYear;
                if (!isNaN(maxMonth) && this._m > maxMonth) {
                    this._m = maxMonth;
                }
            }

            randId = 'pika-title-' + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2);

            for (var c = 0; c < opts.numberOfMonths; c++) {
                html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId) + '</div>';
            }

            this.el.innerHTML = html;

            if (opts.bound) {
                if(opts.field.type !== 'hidden') {
                    sto(function() {
                        opts.trigger.focus();
                    }, 1);
                }
            }

            if (typeof this._o.onDraw === 'function') {
                this._o.onDraw(this);
            }

            if (opts.bound) {
                // let the screen reader user know to use arrow keys
                opts.field.setAttribute('aria-label', 'Use the arrow keys to pick a date');
            }
        },

        adjustPosition: function()
        {
            var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;

            if (this._o.container) return;

            this.el.style.position = 'absolute';

            field = this._o.trigger;
            pEl = field;
            width = this.el.offsetWidth;
            height = this.el.offsetHeight;
            viewportWidth = window.innerWidth || document.documentElement.clientWidth;
            viewportHeight = window.innerHeight || document.documentElement.clientHeight;
            scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;

            if (typeof field.getBoundingClientRect === 'function') {
                clientRect = field.getBoundingClientRect();
                left = clientRect.left + window.pageXOffset;
                top = clientRect.bottom + window.pageYOffset;
            } else {
                left = pEl.offsetLeft;
                top  = pEl.offsetTop + pEl.offsetHeight;
                while((pEl = pEl.offsetParent)) {
                    left += pEl.offsetLeft;
                    top  += pEl.offsetTop;
                }
            }

            // default position is bottom & left
            if ((this._o.reposition && left + width > viewportWidth) ||
                (
                    this._o.position.indexOf('right') > -1 &&
                    left - width + field.offsetWidth > 0
                )
            ) {
                left = left - width + field.offsetWidth;
            }
            if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
                (
                    this._o.position.indexOf('top') > -1 &&
                    top - height - field.offsetHeight > 0
                )
            ) {
                top = top - height - field.offsetHeight;
            }

            this.el.style.left = left + 'px';
            this.el.style.top = top + 'px';
        },

        /**
         * render HTML for a particular month
         */
        render: function(year, month, randId)
        {
            var opts   = this._o,
                now    = new Date(),
                days   = getDaysInMonth(year, month),
                before = new Date(year, month, 1).getDay(),
                data   = [],
                row    = [];
            setToStartOfDay(now);
            if (opts.firstDay > 0) {
                before -= opts.firstDay;
                if (before < 0) {
                    before += 7;
                }
            }
            var previousMonth = month === 0 ? 11 : month - 1,
                nextMonth = month === 11 ? 0 : month + 1,
                yearOfPreviousMonth = month === 0 ? year - 1 : year,
                yearOfNextMonth = month === 11 ? year + 1 : year,
                daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth);
            var cells = days + before,
                after = cells;
            while(after > 7) {
                after -= 7;
            }
            cells += 7 - after;
            for (var i = 0, r = 0; i < cells; i++)
            {
                var day = new Date(year, month, 1 + (i - before)),
                    isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
                    isToday = compareDates(day, now),
                    isEmpty = i < before || i >= (days + before),
                    dayNumber = 1 + (i - before),
                    monthNumber = month,
                    yearNumber = year,
                    isStartRange = opts.startRange && compareDates(opts.startRange, day),
                    isEndRange = opts.endRange && compareDates(opts.endRange, day),
                    isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
                    isDisabled = (opts.minDate && day < opts.minDate) ||
                                 (opts.maxDate && day > opts.maxDate) ||
                                 (opts.disableWeekends && isWeekend(day)) ||
                                 (opts.disableDayFn && opts.disableDayFn(day));

                if (isEmpty) {
                    if (i < before) {
                        dayNumber = daysInPreviousMonth + dayNumber;
                        monthNumber = previousMonth;
                        yearNumber = yearOfPreviousMonth;
                    } else {
                        dayNumber = dayNumber - days;
                        monthNumber = nextMonth;
                        yearNumber = yearOfNextMonth;
                    }
                }

                var dayConfig = {
                        day: dayNumber,
                        month: monthNumber,
                        year: yearNumber,
                        isSelected: isSelected,
                        isToday: isToday,
                        isDisabled: isDisabled,
                        isEmpty: isEmpty,
                        isStartRange: isStartRange,
                        isEndRange: isEndRange,
                        isInRange: isInRange,
                        showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths
                    };

                row.push(renderDay(dayConfig));

                if (++r === 7) {
                    if (opts.showWeekNumber) {
                        row.unshift(renderWeek(i - before, month, year));
                    }
                    data.push(renderRow(row, opts.isRTL));
                    row = [];
                    r = 0;
                }
            }
            return renderTable(opts, data, randId);
        },

        isVisible: function()
        {
            return this._v;
        },

        show: function()
        {
            if (!this.isVisible()) {
                removeClass(this.el, 'is-hidden');
                this._v = true;
                this.draw();
                if (this._o.bound) {
                    addEvent(document, 'click', this._onClick);
                    this.adjustPosition();
                }
                if (typeof this._o.onOpen === 'function') {
                    this._o.onOpen.call(this);
                }
            }
        },

        hide: function()
        {
            var v = this._v;
            if (v !== false) {
                if (this._o.bound) {
                    removeEvent(document, 'click', this._onClick);
                }
                this.el.style.position = 'static'; // reset
                this.el.style.left = 'auto';
                this.el.style.top = 'auto';
                addClass(this.el, 'is-hidden');
                this._v = false;
                if (v !== undefined && typeof this._o.onClose === 'function') {
                    this._o.onClose.call(this);
                }
            }
        },

        /**
         * GAME OVER
         */
        destroy: function()
        {
            this.hide();
            removeEvent(this.el, 'mousedown', this._onMouseDown, true);
            removeEvent(this.el, 'touchend', this._onMouseDown, true);
            removeEvent(this.el, 'change', this._onChange);
            if (this._o.field) {
                removeEvent(this._o.field, 'change', this._onInputChange);
                if (this._o.bound) {
                    removeEvent(this._o.trigger, 'click', this._onInputClick);
                    removeEvent(this._o.trigger, 'focus', this._onInputFocus);
                    removeEvent(this._o.trigger, 'blur', this._onInputBlur);
                }
            }
            if (this.el.parentNode) {
                this.el.parentNode.removeChild(this.el);
            }
        }

    };

    return Pikaday;

}));


/***/ }),
/* 540 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js

;(function (global, factory) {
     true ? module.exports = factory() :
    undefined
}(this, (function () { 'use strict';

    var hookCallback;

    function hooks () {
        return hookCallback.apply(null, arguments);
    }

    // This is done to register the method called with moment()
    // without creating circular dependencies.
    function setHookCallback (callback) {
        hookCallback = callback;
    }

    function isArray(input) {
        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
    }

    function isObject(input) {
        // IE8 will treat undefined and null as object if it wasn't for
        // input != null
        return input != null && Object.prototype.toString.call(input) === '[object Object]';
    }

    function isObjectEmpty(obj) {
        if (Object.getOwnPropertyNames) {
            return (Object.getOwnPropertyNames(obj).length === 0);
        } else {
            var k;
            for (k in obj) {
                if (obj.hasOwnProperty(k)) {
                    return false;
                }
            }
            return true;
        }
    }

    function isUndefined(input) {
        return input === void 0;
    }

    function isNumber(input) {
        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
    }

    function isDate(input) {
        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
    }

    function map(arr, fn) {
        var res = [], i;
        for (i = 0; i < arr.length; ++i) {
            res.push(fn(arr[i], i));
        }
        return res;
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    function createUTC (input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, true).utc();
    }

    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty           : false,
            unusedTokens    : [],
            unusedInput     : [],
            overflow        : -2,
            charsLeftOver   : 0,
            nullInput       : false,
            invalidMonth    : null,
            invalidFormat   : false,
            userInvalidated : false,
            iso             : false,
            parsedDateParts : [],
            meridiem        : null,
            rfc2822         : false,
            weekdayMismatch : false
        };
    }

    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }

    var some;
    if (Array.prototype.some) {
        some = Array.prototype.some;
    } else {
        some = function (fun) {
            var t = Object(this);
            var len = t.length >>> 0;

            for (var i = 0; i < len; i++) {
                if (i in t && fun.call(this, t[i], i, t)) {
                    return true;
                }
            }

            return false;
        };
    }

    function isValid(m) {
        if (m._isValid == null) {
            var flags = getParsingFlags(m);
            var parsedParts = some.call(flags.parsedDateParts, function (i) {
                return i != null;
            });
            var isNowValid = !isNaN(m._d.getTime()) &&
                flags.overflow < 0 &&
                !flags.empty &&
                !flags.invalidMonth &&
                !flags.invalidWeekday &&
                !flags.weekdayMismatch &&
                !flags.nullInput &&
                !flags.invalidFormat &&
                !flags.userInvalidated &&
                (!flags.meridiem || (flags.meridiem && parsedParts));

            if (m._strict) {
                isNowValid = isNowValid &&
                    flags.charsLeftOver === 0 &&
                    flags.unusedTokens.length === 0 &&
                    flags.bigHour === undefined;
            }

            if (Object.isFrozen == null || !Object.isFrozen(m)) {
                m._isValid = isNowValid;
            }
            else {
                return isNowValid;
            }
        }
        return m._isValid;
    }

    function createInvalid (flags) {
        var m = createUTC(NaN);
        if (flags != null) {
            extend(getParsingFlags(m), flags);
        }
        else {
            getParsingFlags(m).userInvalidated = true;
        }

        return m;
    }

    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = hooks.momentProperties = [];

    function copyConfig(to, from) {
        var i, prop, val;

        if (!isUndefined(from._isAMomentObject)) {
            to._isAMomentObject = from._isAMomentObject;
        }
        if (!isUndefined(from._i)) {
            to._i = from._i;
        }
        if (!isUndefined(from._f)) {
            to._f = from._f;
        }
        if (!isUndefined(from._l)) {
            to._l = from._l;
        }
        if (!isUndefined(from._strict)) {
            to._strict = from._strict;
        }
        if (!isUndefined(from._tzm)) {
            to._tzm = from._tzm;
        }
        if (!isUndefined(from._isUTC)) {
            to._isUTC = from._isUTC;
        }
        if (!isUndefined(from._offset)) {
            to._offset = from._offset;
        }
        if (!isUndefined(from._pf)) {
            to._pf = getParsingFlags(from);
        }
        if (!isUndefined(from._locale)) {
            to._locale = from._locale;
        }

        if (momentProperties.length > 0) {
            for (i = 0; i < momentProperties.length; i++) {
                prop = momentProperties[i];
                val = from[prop];
                if (!isUndefined(val)) {
                    to[prop] = val;
                }
            }
        }

        return to;
    }

    var updateInProgress = false;

    // Moment prototype object
    function Moment(config) {
        copyConfig(this, config);
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
        if (!this.isValid()) {
            this._d = new Date(NaN);
        }
        // Prevent infinite loop in case updateOffset creates new moment
        // objects.
        if (updateInProgress === false) {
            updateInProgress = true;
            hooks.updateOffset(this);
            updateInProgress = false;
        }
    }

    function isMoment (obj) {
        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
    }

    function absFloor (number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }

    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;

        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }

        return value;
    }

    // compare two arrays, return the number of differences
    function compareArrays(array1, array2, dontConvert) {
        var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
        for (i = 0; i < len; i++) {
            if ((dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
                diffs++;
            }
        }
        return diffs + lengthDiff;
    }

    function warn(msg) {
        if (hooks.suppressDeprecationWarnings === false &&
                (typeof console !==  'undefined') && console.warn) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (hooks.deprecationHandler != null) {
                hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [];
                var arg;
                for (var i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (var key in arguments[0]) {
                            arg += key + ': ' + arguments[0][key] + ', ';
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    var deprecations = {};

    function deprecateSimple(name, msg) {
        if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(name, msg);
        }
        if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
        }
    }

    hooks.suppressDeprecationWarnings = false;
    hooks.deprecationHandler = null;

    function isFunction(input) {
        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
    }

    function set (config) {
        var prop, i;
        for (i in config) {
            prop = config[i];
            if (isFunction(prop)) {
                this[i] = prop;
            } else {
                this['_' + i] = prop;
            }
        }
        this._config = config;
        // Lenient ordinal parsing accepts just a number in addition to
        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
        // TODO: Remove "ordinalParse" fallback in next major release.
        this._dayOfMonthOrdinalParseLenient = new RegExp(
            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
                '|' + (/\d{1,2}/).source);
    }

    function mergeConfigs(parentConfig, childConfig) {
        var res = extend({}, parentConfig), prop;
        for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                    res[prop] = {};
                    extend(res[prop], parentConfig[prop]);
                    extend(res[prop], childConfig[prop]);
                } else if (childConfig[prop] != null) {
                    res[prop] = childConfig[prop];
                } else {
                    delete res[prop];
                }
            }
        }
        for (prop in parentConfig) {
            if (hasOwnProp(parentConfig, prop) &&
                    !hasOwnProp(childConfig, prop) &&
                    isObject(parentConfig[prop])) {
                // make sure changes to properties don't modify parent config
                res[prop] = extend({}, res[prop]);
            }
        }
        return res;
    }

    function Locale(config) {
        if (config != null) {
            this.set(config);
        }
    }

    var keys;

    if (Object.keys) {
        keys = Object.keys;
    } else {
        keys = function (obj) {
            var i, res = [];
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        };
    }

    var defaultCalendar = {
        sameDay : '[Today at] LT',
        nextDay : '[Tomorrow at] LT',
        nextWeek : 'dddd [at] LT',
        lastDay : '[Yesterday at] LT',
        lastWeek : '[Last] dddd [at] LT',
        sameElse : 'L'
    };

    function calendar (key, mom, now) {
        var output = this._calendar[key] || this._calendar['sameElse'];
        return isFunction(output) ? output.call(mom, now) : output;
    }

    var defaultLongDateFormat = {
        LTS  : 'h:mm:ss A',
        LT   : 'h:mm A',
        L    : 'MM/DD/YYYY',
        LL   : 'MMMM D, YYYY',
        LLL  : 'MMMM D, YYYY h:mm A',
        LLLL : 'dddd, MMMM D, YYYY h:mm A'
    };

    function longDateFormat (key) {
        var format = this._longDateFormat[key],
            formatUpper = this._longDateFormat[key.toUpperCase()];

        if (format || !formatUpper) {
            return format;
        }

        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
            return val.slice(1);
        });

        return this._longDateFormat[key];
    }

    var defaultInvalidDate = 'Invalid date';

    function invalidDate () {
        return this._invalidDate;
    }

    var defaultOrdinal = '%d';
    var defaultDayOfMonthOrdinalParse = /\d{1,2}/;

    function ordinal (number) {
        return this._ordinal.replace('%d', number);
    }

    var defaultRelativeTime = {
        future : 'in %s',
        past   : '%s ago',
        s  : 'a few seconds',
        ss : '%d seconds',
        m  : 'a minute',
        mm : '%d minutes',
        h  : 'an hour',
        hh : '%d hours',
        d  : 'a day',
        dd : '%d days',
        M  : 'a month',
        MM : '%d months',
        y  : 'a year',
        yy : '%d years'
    };

    function relativeTime (number, withoutSuffix, string, isFuture) {
        var output = this._relativeTime[string];
        return (isFunction(output)) ?
            output(number, withoutSuffix, string, isFuture) :
            output.replace(/%d/i, number);
    }

    function pastFuture (diff, output) {
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
    }

    var aliases = {};

    function addUnitAlias (unit, shorthand) {
        var lowerCase = unit.toLowerCase();
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
    }

    function normalizeUnits(units) {
        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
    }

    function normalizeObjectUnits(inputObject) {
        var normalizedInput = {},
            normalizedProp,
            prop;

        for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
                normalizedProp = normalizeUnits(prop);
                if (normalizedProp) {
                    normalizedInput[normalizedProp] = inputObject[prop];
                }
            }
        }

        return normalizedInput;
    }

    var priorities = {};

    function addUnitPriority(unit, priority) {
        priorities[unit] = priority;
    }

    function getPrioritizedUnits(unitsObj) {
        var units = [];
        for (var u in unitsObj) {
            units.push({unit: u, priority: priorities[u]});
        }
        units.sort(function (a, b) {
            return a.priority - b.priority;
        });
        return units;
    }

    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
    }

    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

    var formatFunctions = {};

    var formatTokenFunctions = {};

    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken (token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(func.apply(this, arguments), token);
            };
        }
    }

    function removeFormattingTokens(input) {
        if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, '');
        }
        return input.replace(/\\/g, '');
    }

    function makeFormatFunction(format) {
        var array = format.match(formattingTokens), i, length;

        for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
                array[i] = formatTokenFunctions[array[i]];
            } else {
                array[i] = removeFormattingTokens(array[i]);
            }
        }

        return function (mom) {
            var output = '', i;
            for (i = 0; i < length; i++) {
                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
            }
            return output;
        };
    }

    // format date using native date object
    function formatMoment(m, format) {
        if (!m.isValid()) {
            return m.localeData().invalidDate();
        }

        format = expandFormat(format, m.localeData());
        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

        return formatFunctions[format](m);
    }

    function expandFormat(format, locale) {
        var i = 5;

        function replaceLongDateFormatTokens(input) {
            return locale.longDateFormat(input) || input;
        }

        localFormattingTokens.lastIndex = 0;
        while (i >= 0 && localFormattingTokens.test(format)) {
            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
            localFormattingTokens.lastIndex = 0;
            i -= 1;
        }

        return format;
    }

    var match1         = /\d/;            //       0 - 9
    var match2         = /\d\d/;          //      00 - 99
    var match3         = /\d{3}/;         //     000 - 999
    var match4         = /\d{4}/;         //    0000 - 9999
    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
    var match1to2      = /\d\d?/;         //       0 - 99
    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
    var match1to3      = /\d{1,3}/;       //       0 - 999
    var match1to4      = /\d{1,4}/;       //       0 - 9999
    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999

    var matchUnsigned  = /\d+/;           //       0 - inf
    var matchSigned    = /[+-]?\d+/;      //    -inf - inf

    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

    // any word (or two) characters or numbers including two/three word month in arabic.
    // includes scottish gaelic two word and hyphenated months
    var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;

    var regexes = {};

    function addRegexToken (token, regex, strictRegex) {
        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
            return (isStrict && strictRegex) ? strictRegex : regex;
        };
    }

    function getParseRegexForToken (token, config) {
        if (!hasOwnProp(regexes, token)) {
            return new RegExp(unescapeFormat(token));
        }

        return regexes[token](config._strict, config._locale);
    }

    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
    function unescapeFormat(s) {
        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
            return p1 || p2 || p3 || p4;
        }));
    }

    function regexEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }

    var tokens = {};

    function addParseToken (token, callback) {
        var i, func = callback;
        if (typeof token === 'string') {
            token = [token];
        }
        if (isNumber(callback)) {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        for (i = 0; i < token.length; i++) {
            tokens[token[i]] = func;
        }
    }

    function addWeekParseToken (token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }

    function addTimeToArrayFromToken(token, input, config) {
        if (input != null && hasOwnProp(tokens, token)) {
            tokens[token](input, config._a, config, token);
        }
    }

    var YEAR = 0;
    var MONTH = 1;
    var DATE = 2;
    var HOUR = 3;
    var MINUTE = 4;
    var SECOND = 5;
    var MILLISECOND = 6;
    var WEEK = 7;
    var WEEKDAY = 8;

    // FORMATTING

    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? '' + y : '+' + y;
    });

    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });

    addFormatToken(0, ['YYYY',   4],       0, 'year');
    addFormatToken(0, ['YYYYY',  5],       0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

    // ALIASES

    addUnitAlias('year', 'y');

    // PRIORITIES

    addUnitPriority('year', 1);

    // PARSING

    addRegexToken('Y',      matchSigned);
    addRegexToken('YY',     match1to2, match2);
    addRegexToken('YYYY',   match1to4, match4);
    addRegexToken('YYYYY',  match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);

    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });

    // HELPERS

    function daysInYear(year) {
        return isLeapYear(year) ? 366 : 365;
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    // HOOKS

    hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };

    // MOMENTS

    var getSetYear = makeGetSet('FullYear', true);

    function getIsLeapYear () {
        return isLeapYear(this.year());
    }

    function makeGetSet (unit, keepTime) {
        return function (value) {
            if (value != null) {
                set$1(this, unit, value);
                hooks.updateOffset(this, keepTime);
                return this;
            } else {
                return get(this, unit);
            }
        };
    }

    function get (mom, unit) {
        return mom.isValid() ?
            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
    }

    function set$1 (mom, unit, value) {
        if (mom.isValid() && !isNaN(value)) {
            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
            }
            else {
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
            }
        }
    }

    // MOMENTS

    function stringGet (units) {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units]();
        }
        return this;
    }


    function stringSet (units, value) {
        if (typeof units === 'object') {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units);
            for (var i = 0; i < prioritized.length; i++) {
                this[prioritized[i].unit](units[prioritized[i].unit]);
            }
        } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
                return this[units](value);
            }
        }
        return this;
    }

    function mod(n, x) {
        return ((n % x) + x) % x;
    }

    var indexOf;

    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    function daysInMonth(year, month) {
        if (isNaN(year) || isNaN(month)) {
            return NaN;
        }
        var modMonth = mod(month, 12);
        year += (month - modMonth) / 12;
        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
    }

    // FORMATTING

    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });

    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });

    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });

    // ALIASES

    addUnitAlias('month', 'M');

    // PRIORITY

    addUnitPriority('month', 8);

    // PARSING

    addRegexToken('M',    match1to2);
    addRegexToken('MM',   match1to2, match2);
    addRegexToken('MMM',  function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });

    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });

    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });

    // LOCALES

    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
    function localeMonths (m, format) {
        if (!m) {
            return isArray(this._months) ? this._months :
                this._months['standalone'];
        }
        return isArray(this._months) ? this._months[m.month()] :
            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
    }

    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
    function localeMonthsShort (m, format) {
        if (!m) {
            return isArray(this._monthsShort) ? this._monthsShort :
                this._monthsShort['standalone'];
        }
        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
    }

    function handleStrictParse(monthName, format, strict) {
        var i, ii, mom, llc = monthName.toLocaleLowerCase();
        if (!this._monthsParse) {
            // this is not used
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
                mom = createUTC([2000, i]);
                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeMonthsParse (monthName, format, strict) {
        var i, mom, regex;

        if (this._monthsParseExact) {
            return handleStrictParse.call(this, monthName, format, strict);
        }

        if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
        }

        // TODO: add sorting
        // Sorting makes sure if one month (or abbr) is a prefix of another
        // see sorting in computeMonthsParse
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            if (strict && !this._longMonthsParse[i]) {
                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
            }
            if (!strict && !this._monthsParse[i]) {
                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
                return i;
            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
                return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function setMonth (mom, value) {
        var dayOfMonth;

        if (!mom.isValid()) {
            // No op
            return mom;
        }

        if (typeof value === 'string') {
            if (/^\d+$/.test(value)) {
                value = toInt(value);
            } else {
                value = mom.localeData().monthsParse(value);
                // TODO: Another silent failure?
                if (!isNumber(value)) {
                    return mom;
                }
            }
        }

        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
        return mom;
    }

    function getSetMonth (value) {
        if (value != null) {
            setMonth(this, value);
            hooks.updateOffset(this, true);
            return this;
        } else {
            return get(this, 'Month');
        }
    }

    function getDaysInMonth () {
        return daysInMonth(this.year(), this.month());
    }

    var defaultMonthsShortRegex = matchWord;
    function monthsShortRegex (isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsShortStrictRegex;
            } else {
                return this._monthsShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsShortRegex')) {
                this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict ?
                this._monthsShortStrictRegex : this._monthsShortRegex;
        }
    }

    var defaultMonthsRegex = matchWord;
    function monthsRegex (isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsStrictRegex;
            } else {
                return this._monthsRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsRegex')) {
                this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict ?
                this._monthsStrictRegex : this._monthsRegex;
        }
    }

    function computeMonthsParse () {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var shortPieces = [], longPieces = [], mixedPieces = [],
            i, mom;
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            shortPieces.push(this.monthsShort(mom, ''));
            longPieces.push(this.months(mom, ''));
            mixedPieces.push(this.months(mom, ''));
            mixedPieces.push(this.monthsShort(mom, ''));
        }
        // Sorting makes sure if one month (or abbr) is a prefix of another it
        // will match the longer piece.
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 12; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
        }
        for (i = 0; i < 24; i++) {
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._monthsShortRegex = this._monthsRegex;
        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
    }

    function createDate (y, m, d, h, M, s, ms) {
        // can't just apply() to create a date:
        // https://stackoverflow.com/q/181348
        var date;
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            date = new Date(y + 400, m, d, h, M, s, ms);
            if (isFinite(date.getFullYear())) {
                date.setFullYear(y);
            }
        } else {
            date = new Date(y, m, d, h, M, s, ms);
        }

        return date;
    }

    function createUTCDate (y) {
        var date;
        // the Date.UTC function remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            var args = Array.prototype.slice.call(arguments);
            // preserve leap years using a full 400 year cycle, then reset
            args[0] = y + 400;
            date = new Date(Date.UTC.apply(null, args));
            if (isFinite(date.getUTCFullYear())) {
                date.setUTCFullYear(y);
            }
        } else {
            date = new Date(Date.UTC.apply(null, arguments));
        }

        return date;
    }

    // start-of-first-week - start-of-year
    function firstWeekOffset(year, dow, doy) {
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
            fwd = 7 + dow - doy,
            // first-week day local weekday -- which local weekday is fwd
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

        return -fwdlw + fwd - 1;
    }

    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
        var localWeekday = (7 + weekday - dow) % 7,
            weekOffset = firstWeekOffset(year, dow, doy),
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
            resYear, resDayOfYear;

        if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
        } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
        } else {
            resYear = year;
            resDayOfYear = dayOfYear;
        }

        return {
            year: resYear,
            dayOfYear: resDayOfYear
        };
    }

    function weekOfYear(mom, dow, doy) {
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
            resWeek, resYear;

        if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
        } else {
            resYear = mom.year();
            resWeek = week;
        }

        return {
            week: resWeek,
            year: resYear
        };
    }

    function weeksInYear(year, dow, doy) {
        var weekOffset = firstWeekOffset(year, dow, doy),
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
    }

    // FORMATTING

    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

    // ALIASES

    addUnitAlias('week', 'w');
    addUnitAlias('isoWeek', 'W');

    // PRIORITIES

    addUnitPriority('week', 5);
    addUnitPriority('isoWeek', 5);

    // PARSING

    addRegexToken('w',  match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W',  match1to2);
    addRegexToken('WW', match1to2, match2);

    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
        week[token.substr(0, 1)] = toInt(input);
    });

    // HELPERS

    // LOCALES

    function localeWeek (mom) {
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
    }

    var defaultLocaleWeek = {
        dow : 0, // Sunday is the first day of the week.
        doy : 6  // The week that contains Jan 6th is the first week of the year.
    };

    function localeFirstDayOfWeek () {
        return this._week.dow;
    }

    function localeFirstDayOfYear () {
        return this._week.doy;
    }

    // MOMENTS

    function getSetWeek (input) {
        var week = this.localeData().week(this);
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    function getSetISOWeek (input) {
        var week = weekOfYear(this, 1, 4).week;
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    // FORMATTING

    addFormatToken('d', 0, 'do', 'day');

    addFormatToken('dd', 0, 0, function (format) {
        return this.localeData().weekdaysMin(this, format);
    });

    addFormatToken('ddd', 0, 0, function (format) {
        return this.localeData().weekdaysShort(this, format);
    });

    addFormatToken('dddd', 0, 0, function (format) {
        return this.localeData().weekdays(this, format);
    });

    addFormatToken('e', 0, 0, 'weekday');
    addFormatToken('E', 0, 0, 'isoWeekday');

    // ALIASES

    addUnitAlias('day', 'd');
    addUnitAlias('weekday', 'e');
    addUnitAlias('isoWeekday', 'E');

    // PRIORITY
    addUnitPriority('day', 11);
    addUnitPriority('weekday', 11);
    addUnitPriority('isoWeekday', 11);

    // PARSING

    addRegexToken('d',    match1to2);
    addRegexToken('e',    match1to2);
    addRegexToken('E',    match1to2);
    addRegexToken('dd',   function (isStrict, locale) {
        return locale.weekdaysMinRegex(isStrict);
    });
    addRegexToken('ddd',   function (isStrict, locale) {
        return locale.weekdaysShortRegex(isStrict);
    });
    addRegexToken('dddd',   function (isStrict, locale) {
        return locale.weekdaysRegex(isStrict);
    });

    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
        // if we didn't get a weekday name, mark the date as invalid
        if (weekday != null) {
            week.d = weekday;
        } else {
            getParsingFlags(config).invalidWeekday = input;
        }
    });

    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
        week[token] = toInt(input);
    });

    // HELPERS

    function parseWeekday(input, locale) {
        if (typeof input !== 'string') {
            return input;
        }

        if (!isNaN(input)) {
            return parseInt(input, 10);
        }

        input = locale.weekdaysParse(input);
        if (typeof input === 'number') {
            return input;
        }

        return null;
    }

    function parseIsoWeekday(input, locale) {
        if (typeof input === 'string') {
            return locale.weekdaysParse(input) % 7 || 7;
        }
        return isNaN(input) ? null : input;
    }

    // LOCALES
    function shiftWeekdays (ws, n) {
        return ws.slice(n, 7).concat(ws.slice(0, n));
    }

    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
    function localeWeekdays (m, format) {
        var weekdays = isArray(this._weekdays) ? this._weekdays :
            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];
        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)
            : (m) ? weekdays[m.day()] : weekdays;
    }

    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
    function localeWeekdaysShort (m) {
        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)
            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
    }

    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
    function localeWeekdaysMin (m) {
        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)
            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
    }

    function handleStrictParse$1(weekdayName, format, strict) {
        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];

            for (i = 0; i < 7; ++i) {
                mom = createUTC([2000, 1]).day(i);
                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeWeekdaysParse (weekdayName, format, strict) {
        var i, mom, regex;

        if (this._weekdaysParseExact) {
            return handleStrictParse$1.call(this, weekdayName, format, strict);
        }

        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
        }

        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already

            mom = createUTC([2000, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
            }
            if (!this._weekdaysParse[i]) {
                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function getSetDayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
        if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, 'd');
        } else {
            return day;
        }
    }

    function getSetLocaleDayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
        return input == null ? weekday : this.add(input - weekday, 'd');
    }

    function getSetISODayOfWeek (input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }

        // behaves the same as moment#day except
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
        // as a setter, sunday should belong to the previous week.

        if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
        } else {
            return this.day() || 7;
        }
    }

    var defaultWeekdaysRegex = matchWord;
    function weekdaysRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysStrictRegex;
            } else {
                return this._weekdaysRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict ?
                this._weekdaysStrictRegex : this._weekdaysRegex;
        }
    }

    var defaultWeekdaysShortRegex = matchWord;
    function weekdaysShortRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysShortStrictRegex;
            } else {
                return this._weekdaysShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict ?
                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
        }
    }

    var defaultWeekdaysMinRegex = matchWord;
    function weekdaysMinRegex (isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysMinStrictRegex;
            } else {
                return this._weekdaysMinRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict ?
                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
        }
    }


    function computeWeekdaysParse () {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
            i, mom, minp, shortp, longp;
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, 1]).day(i);
            minp = this.weekdaysMin(mom, '');
            shortp = this.weekdaysShort(mom, '');
            longp = this.weekdays(mom, '');
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
        }
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
        // will match the longer piece.
        minPieces.sort(cmpLenRev);
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 7; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._weekdaysShortRegex = this._weekdaysRegex;
        this._weekdaysMinRegex = this._weekdaysRegex;

        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
    }

    // FORMATTING

    function hFormat() {
        return this.hours() % 12 || 12;
    }

    function kFormat() {
        return this.hours() || 24;
    }

    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);

    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });

    addFormatToken('hmmss', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });

    addFormatToken('Hmmss', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    function meridiem (token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
        });
    }

    meridiem('a', true);
    meridiem('A', false);

    // ALIASES

    addUnitAlias('hour', 'h');

    // PRIORITY
    addUnitPriority('hour', 13);

    // PARSING

    function matchMeridiem (isStrict, locale) {
        return locale._meridiemParse;
    }

    addRegexToken('a',  matchMeridiem);
    addRegexToken('A',  matchMeridiem);
    addRegexToken('H',  match1to2);
    addRegexToken('h',  match1to2);
    addRegexToken('k',  match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);
    addRegexToken('kk', match1to2, match2);

    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);

    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['k', 'kk'], function (input, array, config) {
        var kInput = toInt(input);
        array[HOUR] = kInput === 24 ? 0 : kInput;
    });
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });

    // LOCALES

    function localeIsPM (input) {
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
        // Using charAt should be more compatible.
        return ((input + '').toLowerCase().charAt(0) === 'p');
    }

    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
    function localeMeridiem (hours, minutes, isLower) {
        if (hours > 11) {
            return isLower ? 'pm' : 'PM';
        } else {
            return isLower ? 'am' : 'AM';
        }
    }


    // MOMENTS

    // Setting the hour should keep the time, because the user explicitly
    // specified which hour they want. So trying to maintain the same hour (in
    // a new timezone) makes sense. Adding/subtracting hours does not follow
    // this rule.
    var getSetHour = makeGetSet('Hours', true);

    var baseConfig = {
        calendar: defaultCalendar,
        longDateFormat: defaultLongDateFormat,
        invalidDate: defaultInvalidDate,
        ordinal: defaultOrdinal,
        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
        relativeTime: defaultRelativeTime,

        months: defaultLocaleMonths,
        monthsShort: defaultLocaleMonthsShort,

        week: defaultLocaleWeek,

        weekdays: defaultLocaleWeekdays,
        weekdaysMin: defaultLocaleWeekdaysMin,
        weekdaysShort: defaultLocaleWeekdaysShort,

        meridiemParse: defaultLocaleMeridiemParse
    };

    // internal storage for locale config files
    var locales = {};
    var localeFamilies = {};
    var globalLocale;

    function normalizeLocale(key) {
        return key ? key.toLowerCase().replace('_', '-') : key;
    }

    // pick the locale from the array
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
    function chooseLocale(names) {
        var i = 0, j, next, locale, split;

        while (i < names.length) {
            split = normalizeLocale(names[i]).split('-');
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split('-') : null;
            while (j > 0) {
                locale = loadLocale(split.slice(0, j).join('-'));
                if (locale) {
                    return locale;
                }
                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                    //the next array item is better than a shallower substring of this one
                    break;
                }
                j--;
            }
            i++;
        }
        return globalLocale;
    }

    function loadLocale(name) {
        var oldLocale = null;
        // TODO: Find a better way to register and load all the locales in Node
        if (!locales[name] && (typeof module !== 'undefined') &&
                module && module.exports) {
            try {
                oldLocale = globalLocale._abbr;
                var aliasedRequire = require;
                __webpack_require__(541)("./" + name);
                getSetGlobalLocale(oldLocale);
            } catch (e) {}
        }
        return locales[name];
    }

    // This function will load locale and then set the global locale.  If
    // no arguments are passed in, it will simply return the current global
    // locale key.
    function getSetGlobalLocale (key, values) {
        var data;
        if (key) {
            if (isUndefined(values)) {
                data = getLocale(key);
            }
            else {
                data = defineLocale(key, values);
            }

            if (data) {
                // moment.duration._locale = moment._locale = data;
                globalLocale = data;
            }
            else {
                if ((typeof console !==  'undefined') && console.warn) {
                    //warn user if arguments are passed but the locale could not be set
                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
                }
            }
        }

        return globalLocale._abbr;
    }

    function defineLocale (name, config) {
        if (config !== null) {
            var locale, parentConfig = baseConfig;
            config.abbr = name;
            if (locales[name] != null) {
                deprecateSimple('defineLocaleOverride',
                        'use moment.updateLocale(localeName, config) to change ' +
                        'an existing locale. moment.defineLocale(localeName, ' +
                        'config) should only be used for creating a new locale ' +
                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
                parentConfig = locales[name]._config;
            } else if (config.parentLocale != null) {
                if (locales[config.parentLocale] != null) {
                    parentConfig = locales[config.parentLocale]._config;
                } else {
                    locale = loadLocale(config.parentLocale);
                    if (locale != null) {
                        parentConfig = locale._config;
                    } else {
                        if (!localeFamilies[config.parentLocale]) {
                            localeFamilies[config.parentLocale] = [];
                        }
                        localeFamilies[config.parentLocale].push({
                            name: name,
                            config: config
                        });
                        return null;
                    }
                }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config));

            if (localeFamilies[name]) {
                localeFamilies[name].forEach(function (x) {
                    defineLocale(x.name, x.config);
                });
            }

            // backwards compat for now: also set the locale
            // make sure we set the locale AFTER all child locales have been
            // created, so we won't end up with the child locale set.
            getSetGlobalLocale(name);


            return locales[name];
        } else {
            // useful for testing
            delete locales[name];
            return null;
        }
    }

    function updateLocale(name, config) {
        if (config != null) {
            var locale, tmpLocale, parentConfig = baseConfig;
            // MERGE
            tmpLocale = loadLocale(name);
            if (tmpLocale != null) {
                parentConfig = tmpLocale._config;
            }
            config = mergeConfigs(parentConfig, config);
            locale = new Locale(config);
            locale.parentLocale = locales[name];
            locales[name] = locale;

            // backwards compat for now: also set the locale
            getSetGlobalLocale(name);
        } else {
            // pass null for config to unupdate, useful for tests
            if (locales[name] != null) {
                if (locales[name].parentLocale != null) {
                    locales[name] = locales[name].parentLocale;
                } else if (locales[name] != null) {
                    delete locales[name];
                }
            }
        }
        return locales[name];
    }

    // returns locale data
    function getLocale (key) {
        var locale;

        if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
        }

        if (!key) {
            return globalLocale;
        }

        if (!isArray(key)) {
            //short-circuit everything else
            locale = loadLocale(key);
            if (locale) {
                return locale;
            }
            key = [key];
        }

        return chooseLocale(key);
    }

    function listLocales() {
        return keys(locales);
    }

    function checkOverflow (m) {
        var overflow;
        var a = m._a;

        if (a && getParsingFlags(m).overflow === -2) {
            overflow =
                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
                -1;

            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
                overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                overflow = WEEKDAY;
            }

            getParsingFlags(m).overflow = overflow;
        }

        return m;
    }

    // Pick the first defined of two or three arguments.
    function defaults(a, b, c) {
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return c;
    }

    function currentDateArray(config) {
        // hooks is actually the exported moment object
        var nowValue = new Date(hooks.now());
        if (config._useUTC) {
            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
        }
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
    }

    // convert an array to a date.
    // the array should mirror the parameters below
    // note: all values past the year are optional and will default to the lowest possible value.
    // [year, month, day , hour, minute, second, millisecond]
    function configFromArray (config) {
        var i, date, input = [], currentDate, expectedWeekday, yearToUse;

        if (config._d) {
            return;
        }

        currentDate = currentDateArray(config);

        //compute day of the year from weeks and weekdays
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config);
        }

        //if the day of the year is set, figure out what it is
        if (config._dayOfYear != null) {
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
                getParsingFlags(config)._overflowDayOfYear = true;
            }

            date = createUTCDate(yearToUse, 0, config._dayOfYear);
            config._a[MONTH] = date.getUTCMonth();
            config._a[DATE] = date.getUTCDate();
        }

        // Default to current date.
        // * if no year, month, day of month are given, default to today
        // * if day of month is given, default month and year
        // * if month is given, default only year
        // * if year is given, don't default anything
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
            config._a[i] = input[i] = currentDate[i];
        }

        // Zero out whatever was not defaulted, including time
        for (; i < 7; i++) {
            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
        }

        // Check for 24:00:00.000
        if (config._a[HOUR] === 24 &&
                config._a[MINUTE] === 0 &&
                config._a[SECOND] === 0 &&
                config._a[MILLISECOND] === 0) {
            config._nextDay = true;
            config._a[HOUR] = 0;
        }

        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();

        // Apply timezone offset from input. The actual utcOffset can be changed
        // with parseZone.
        if (config._tzm != null) {
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
        }

        if (config._nextDay) {
            config._a[HOUR] = 24;
        }

        // check for mismatching day of week
        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
            getParsingFlags(config).weekdayMismatch = true;
        }
    }

    function dayOfYearFromWeekInfo(config) {
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

        w = config._w;
        if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;

            // TODO: We need to take the current isoWeekYear, but that depends on
            // how we interpret now (local, utc, fixed offset). So create
            // a now version of current config (take local/utc/offset flags, and
            // create now).
            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
                weekdayOverflow = true;
            }
        } else {
            dow = config._locale._week.dow;
            doy = config._locale._week.doy;

            var curWeek = weekOfYear(createLocal(), dow, doy);

            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);

            // Default to current week.
            week = defaults(w.w, curWeek.week);

            if (w.d != null) {
                // weekday -- low day numbers are considered next week
                weekday = w.d;
                if (weekday < 0 || weekday > 6) {
                    weekdayOverflow = true;
                }
            } else if (w.e != null) {
                // local weekday -- counting starts from beginning of week
                weekday = w.e + dow;
                if (w.e < 0 || w.e > 6) {
                    weekdayOverflow = true;
                }
            } else {
                // default to beginning of week
                weekday = dow;
            }
        }
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config)._overflowWeeks = true;
        } else if (weekdayOverflow != null) {
            getParsingFlags(config)._overflowWeekday = true;
        } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    }

    // iso 8601 regex
    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;

    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

    var isoDates = [
        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
        ['YYYY-DDD', /\d{4}-\d{3}/],
        ['YYYY-MM', /\d{4}-\d\d/, false],
        ['YYYYYYMMDD', /[+-]\d{10}/],
        ['YYYYMMDD', /\d{8}/],
        // YYYYMM is NOT allowed by the standard
        ['GGGG[W]WWE', /\d{4}W\d{3}/],
        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
        ['YYYYDDD', /\d{7}/]
    ];

    // iso time formats and regexes
    var isoTimes = [
        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
        ['HH:mm', /\d\d:\d\d/],
        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
        ['HHmmss', /\d\d\d\d\d\d/],
        ['HHmm', /\d\d\d\d/],
        ['HH', /\d\d/]
    ];

    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

    // date from iso format
    function configFromISO(config) {
        var i, l,
            string = config._i,
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
            allowTime, dateFormat, timeFormat, tzFormat;

        if (match) {
            getParsingFlags(config).iso = true;

            for (i = 0, l = isoDates.length; i < l; i++) {
                if (isoDates[i][1].exec(match[1])) {
                    dateFormat = isoDates[i][0];
                    allowTime = isoDates[i][2] !== false;
                    break;
                }
            }
            if (dateFormat == null) {
                config._isValid = false;
                return;
            }
            if (match[3]) {
                for (i = 0, l = isoTimes.length; i < l; i++) {
                    if (isoTimes[i][1].exec(match[3])) {
                        // match[2] should be 'T' or space
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
                        break;
                    }
                }
                if (timeFormat == null) {
                    config._isValid = false;
                    return;
                }
            }
            if (!allowTime && timeFormat != null) {
                config._isValid = false;
                return;
            }
            if (match[4]) {
                if (tzRegex.exec(match[4])) {
                    tzFormat = 'Z';
                } else {
                    config._isValid = false;
                    return;
                }
            }
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
            configFromStringAndFormat(config);
        } else {
            config._isValid = false;
        }
    }

    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;

    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
        var result = [
            untruncateYear(yearStr),
            defaultLocaleMonthsShort.indexOf(monthStr),
            parseInt(dayStr, 10),
            parseInt(hourStr, 10),
            parseInt(minuteStr, 10)
        ];

        if (secondStr) {
            result.push(parseInt(secondStr, 10));
        }

        return result;
    }

    function untruncateYear(yearStr) {
        var year = parseInt(yearStr, 10);
        if (year <= 49) {
            return 2000 + year;
        } else if (year <= 999) {
            return 1900 + year;
        }
        return year;
    }

    function preprocessRFC2822(s) {
        // Remove comments and folding whitespace and replace multiple-spaces with a single space
        return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }

    function checkWeekday(weekdayStr, parsedInput, config) {
        if (weekdayStr) {
            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
            if (weekdayProvided !== weekdayActual) {
                getParsingFlags(config).weekdayMismatch = true;
                config._isValid = false;
                return false;
            }
        }
        return true;
    }

    var obsOffsets = {
        UT: 0,
        GMT: 0,
        EDT: -4 * 60,
        EST: -5 * 60,
        CDT: -5 * 60,
        CST: -6 * 60,
        MDT: -6 * 60,
        MST: -7 * 60,
        PDT: -7 * 60,
        PST: -8 * 60
    };

    function calculateOffset(obsOffset, militaryOffset, numOffset) {
        if (obsOffset) {
            return obsOffsets[obsOffset];
        } else if (militaryOffset) {
            // the only allowed military tz is Z
            return 0;
        } else {
            var hm = parseInt(numOffset, 10);
            var m = hm % 100, h = (hm - m) / 100;
            return h * 60 + m;
        }
    }

    // date and time from ref 2822 format
    function configFromRFC2822(config) {
        var match = rfc2822.exec(preprocessRFC2822(config._i));
        if (match) {
            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
            if (!checkWeekday(match[1], parsedArray, config)) {
                return;
            }

            config._a = parsedArray;
            config._tzm = calculateOffset(match[8], match[9], match[10]);

            config._d = createUTCDate.apply(null, config._a);
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);

            getParsingFlags(config).rfc2822 = true;
        } else {
            config._isValid = false;
        }
    }

    // date from iso format or fallback
    function configFromString(config) {
        var matched = aspNetJsonRegex.exec(config._i);

        if (matched !== null) {
            config._d = new Date(+matched[1]);
            return;
        }

        configFromISO(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }

        configFromRFC2822(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }

        // Final attempt, use Input Fallback
        hooks.createFromInputFallback(config);
    }

    hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
        'discouraged and will be removed in an upcoming major release. Please refer to ' +
        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

    // constant that refers to the ISO standard
    hooks.ISO_8601 = function () {};

    // constant that refers to the RFC 2822 form
    hooks.RFC_2822 = function () {};

    // date from string and format string
    function configFromStringAndFormat(config) {
        // TODO: Move this to another part of the creation flow to prevent circular deps
        if (config._f === hooks.ISO_8601) {
            configFromISO(config);
            return;
        }
        if (config._f === hooks.RFC_2822) {
            configFromRFC2822(config);
            return;
        }
        config._a = [];
        getParsingFlags(config).empty = true;

        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var string = '' + config._i,
            i, parsedInput, tokens, token, skipped,
            stringLength = string.length,
            totalParsedInputLength = 0;

        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

        for (i = 0; i < tokens.length; i++) {
            token = tokens[i];
            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
            // console.log('token', token, 'parsedInput', parsedInput,
            //         'regex', getParseRegexForToken(token, config));
            if (parsedInput) {
                skipped = string.substr(0, string.indexOf(parsedInput));
                if (skipped.length > 0) {
                    getParsingFlags(config).unusedInput.push(skipped);
                }
                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
                totalParsedInputLength += parsedInput.length;
            }
            // don't parse if it's not a known token
            if (formatTokenFunctions[token]) {
                if (parsedInput) {
                    getParsingFlags(config).empty = false;
                }
                else {
                    getParsingFlags(config).unusedTokens.push(token);
                }
                addTimeToArrayFromToken(token, parsedInput, config);
            }
            else if (config._strict && !parsedInput) {
                getParsingFlags(config).unusedTokens.push(token);
            }
        }

        // add remaining unparsed input length to the string
        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
        if (string.length > 0) {
            getParsingFlags(config).unusedInput.push(string);
        }

        // clear _12h flag if hour is <= 12
        if (config._a[HOUR] <= 12 &&
            getParsingFlags(config).bigHour === true &&
            config._a[HOUR] > 0) {
            getParsingFlags(config).bigHour = undefined;
        }

        getParsingFlags(config).parsedDateParts = config._a.slice(0);
        getParsingFlags(config).meridiem = config._meridiem;
        // handle meridiem
        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

        configFromArray(config);
        checkOverflow(config);
    }


    function meridiemFixWrap (locale, hour, meridiem) {
        var isPm;

        if (meridiem == null) {
            // nothing to do
            return hour;
        }
        if (locale.meridiemHour != null) {
            return locale.meridiemHour(hour, meridiem);
        } else if (locale.isPM != null) {
            // Fallback
            isPm = locale.isPM(meridiem);
            if (isPm && hour < 12) {
                hour += 12;
            }
            if (!isPm && hour === 12) {
                hour = 0;
            }
            return hour;
        } else {
            // this is not supposed to happen
            return hour;
        }
    }

    // date from string and array of format strings
    function configFromStringAndArray(config) {
        var tempConfig,
            bestMoment,

            scoreToBeat,
            i,
            currentScore;

        if (config._f.length === 0) {
            getParsingFlags(config).invalidFormat = true;
            config._d = new Date(NaN);
            return;
        }

        for (i = 0; i < config._f.length; i++) {
            currentScore = 0;
            tempConfig = copyConfig({}, config);
            if (config._useUTC != null) {
                tempConfig._useUTC = config._useUTC;
            }
            tempConfig._f = config._f[i];
            configFromStringAndFormat(tempConfig);

            if (!isValid(tempConfig)) {
                continue;
            }

            // if there is any input that was not parsed add a penalty for that format
            currentScore += getParsingFlags(tempConfig).charsLeftOver;

            //or tokens
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

            getParsingFlags(tempConfig).score = currentScore;

            if (scoreToBeat == null || currentScore < scoreToBeat) {
                scoreToBeat = currentScore;
                bestMoment = tempConfig;
            }
        }

        extend(config, bestMoment || tempConfig);
    }

    function configFromObject(config) {
        if (config._d) {
            return;
        }

        var i = normalizeObjectUnits(config._i);
        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
            return obj && parseInt(obj, 10);
        });

        configFromArray(config);
    }

    function createFromConfig (config) {
        var res = new Moment(checkOverflow(prepareConfig(config)));
        if (res._nextDay) {
            // Adding is smart enough around DST
            res.add(1, 'd');
            res._nextDay = undefined;
        }

        return res;
    }

    function prepareConfig (config) {
        var input = config._i,
            format = config._f;

        config._locale = config._locale || getLocale(config._l);

        if (input === null || (format === undefined && input === '')) {
            return createInvalid({nullInput: true});
        }

        if (typeof input === 'string') {
            config._i = input = config._locale.preparse(input);
        }

        if (isMoment(input)) {
            return new Moment(checkOverflow(input));
        } else if (isDate(input)) {
            config._d = input;
        } else if (isArray(format)) {
            configFromStringAndArray(config);
        } else if (format) {
            configFromStringAndFormat(config);
        }  else {
            configFromInput(config);
        }

        if (!isValid(config)) {
            config._d = null;
        }

        return config;
    }

    function configFromInput(config) {
        var input = config._i;
        if (isUndefined(input)) {
            config._d = new Date(hooks.now());
        } else if (isDate(input)) {
            config._d = new Date(input.valueOf());
        } else if (typeof input === 'string') {
            configFromString(config);
        } else if (isArray(input)) {
            config._a = map(input.slice(0), function (obj) {
                return parseInt(obj, 10);
            });
            configFromArray(config);
        } else if (isObject(input)) {
            configFromObject(config);
        } else if (isNumber(input)) {
            // from milliseconds
            config._d = new Date(input);
        } else {
            hooks.createFromInputFallback(config);
        }
    }

    function createLocalOrUTC (input, format, locale, strict, isUTC) {
        var c = {};

        if (locale === true || locale === false) {
            strict = locale;
            locale = undefined;
        }

        if ((isObject(input) && isObjectEmpty(input)) ||
                (isArray(input) && input.length === 0)) {
            input = undefined;
        }
        // object construction must be done this way.
        // https://github.com/moment/moment/issues/1423
        c._isAMomentObject = true;
        c._useUTC = c._isUTC = isUTC;
        c._l = locale;
        c._i = input;
        c._f = format;
        c._strict = strict;

        return createFromConfig(c);
    }

    function createLocal (input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, false);
    }

    var prototypeMin = deprecate(
        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other < this ? this : other;
            } else {
                return createInvalid();
            }
        }
    );

    var prototypeMax = deprecate(
        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other > this ? this : other;
            } else {
                return createInvalid();
            }
        }
    );

    // Pick a moment m from moments so that m[fn](other) is true for all
    // other. This relies on the function fn to be transitive.
    //
    // moments should either be an array of moment objects or an array, whose
    // first element is an array of moment objects.
    function pickBy(fn, moments) {
        var res, i;
        if (moments.length === 1 && isArray(moments[0])) {
            moments = moments[0];
        }
        if (!moments.length) {
            return createLocal();
        }
        res = moments[0];
        for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
                res = moments[i];
            }
        }
        return res;
    }

    // TODO: Use [].sort instead?
    function min () {
        var args = [].slice.call(arguments, 0);

        return pickBy('isBefore', args);
    }

    function max () {
        var args = [].slice.call(arguments, 0);

        return pickBy('isAfter', args);
    }

    var now = function () {
        return Date.now ? Date.now() : +(new Date());
    };

    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];

    function isDurationValid(m) {
        for (var key in m) {
            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
                return false;
            }
        }

        var unitHasDecimal = false;
        for (var i = 0; i < ordering.length; ++i) {
            if (m[ordering[i]]) {
                if (unitHasDecimal) {
                    return false; // only allow non-integers for smallest unit
                }
                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                    unitHasDecimal = true;
                }
            }
        }

        return true;
    }

    function isValid$1() {
        return this._isValid;
    }

    function createInvalid$1() {
        return createDuration(NaN);
    }

    function Duration (duration) {
        var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;

        this._isValid = isDurationValid(normalizedInput);

        // representation for dateAddRemove
        this._milliseconds = +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
        // Because of dateAddRemove treats 24 hours as different from a
        // day when working around DST, we need to store them separately
        this._days = +days +
            weeks * 7;
        // It is impossible to translate months into days without knowing
        // which months you are are talking about, so we have to store
        // it separately.
        this._months = +months +
            quarters * 3 +
            years * 12;

        this._data = {};

        this._locale = getLocale();

        this._bubble();
    }

    function isDuration (obj) {
        return obj instanceof Duration;
    }

    function absRound (number) {
        if (number < 0) {
            return Math.round(-1 * number) * -1;
        } else {
            return Math.round(number);
        }
    }

    // FORMATTING

    function offset (token, separator) {
        addFormatToken(token, 0, 0, function () {
            var offset = this.utcOffset();
            var sign = '+';
            if (offset < 0) {
                offset = -offset;
                sign = '-';
            }
            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
        });
    }

    offset('Z', ':');
    offset('ZZ', '');

    // PARSING

    addRegexToken('Z',  matchShortOffset);
    addRegexToken('ZZ', matchShortOffset);
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
        config._useUTC = true;
        config._tzm = offsetFromString(matchShortOffset, input);
    });

    // HELPERS

    // timezone chunker
    // '+10:00' > ['10',  '00']
    // '-1530'  > ['-15', '30']
    var chunkOffset = /([\+\-]|\d\d)/gi;

    function offsetFromString(matcher, string) {
        var matches = (string || '').match(matcher);

        if (matches === null) {
            return null;
        }

        var chunk   = matches[matches.length - 1] || [];
        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
        var minutes = +(parts[1] * 60) + toInt(parts[2]);

        return minutes === 0 ?
          0 :
          parts[0] === '+' ? minutes : -minutes;
    }

    // Return a moment from input, that is local/utc/zone equivalent to model.
    function cloneWithOffset(input, model) {
        var res, diff;
        if (model._isUTC) {
            res = model.clone();
            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
            // Use low-level api, because this fn is low-level api.
            res._d.setTime(res._d.valueOf() + diff);
            hooks.updateOffset(res, false);
            return res;
        } else {
            return createLocal(input).local();
        }
    }

    function getDateOffset (m) {
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
        // https://github.com/moment/moment/pull/1871
        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
    }

    // HOOKS

    // This function will be called whenever a moment is mutated.
    // It is intended to keep the offset in sync with the timezone.
    hooks.updateOffset = function () {};

    // MOMENTS

    // keepLocalTime = true means only change the timezone, without
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
    // +0200, so we adjust the time as needed, to be valid.
    //
    // Keeping the time actually adds/subtracts (one hour)
    // from the actual represented time. That is why we call updateOffset
    // a second time. In case it wants us to change the offset again
    // _changeInProgress == true case, then we have to adjust, because
    // there is no such time in the given timezone.
    function getSetOffset (input, keepLocalTime, keepMinutes) {
        var offset = this._offset || 0,
            localAdjust;
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        if (input != null) {
            if (typeof input === 'string') {
                input = offsetFromString(matchShortOffset, input);
                if (input === null) {
                    return this;
                }
            } else if (Math.abs(input) < 16 && !keepMinutes) {
                input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
                localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
                this.add(localAdjust, 'm');
            }
            if (offset !== input) {
                if (!keepLocalTime || this._changeInProgress) {
                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);
                } else if (!this._changeInProgress) {
                    this._changeInProgress = true;
                    hooks.updateOffset(this, true);
                    this._changeInProgress = null;
                }
            }
            return this;
        } else {
            return this._isUTC ? offset : getDateOffset(this);
        }
    }

    function getSetZone (input, keepLocalTime) {
        if (input != null) {
            if (typeof input !== 'string') {
                input = -input;
            }

            this.utcOffset(input, keepLocalTime);

            return this;
        } else {
            return -this.utcOffset();
        }
    }

    function setOffsetToUTC (keepLocalTime) {
        return this.utcOffset(0, keepLocalTime);
    }

    function setOffsetToLocal (keepLocalTime) {
        if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;

            if (keepLocalTime) {
                this.subtract(getDateOffset(this), 'm');
            }
        }
        return this;
    }

    function setOffsetToParsedOffset () {
        if (this._tzm != null) {
            this.utcOffset(this._tzm, false, true);
        } else if (typeof this._i === 'string') {
            var tZone = offsetFromString(matchOffset, this._i);
            if (tZone != null) {
                this.utcOffset(tZone);
            }
            else {
                this.utcOffset(0, true);
            }
        }
        return this;
    }

    function hasAlignedHourOffset (input) {
        if (!this.isValid()) {
            return false;
        }
        input = input ? createLocal(input).utcOffset() : 0;

        return (this.utcOffset() - input) % 60 === 0;
    }

    function isDaylightSavingTime () {
        return (
            this.utcOffset() > this.clone().month(0).utcOffset() ||
            this.utcOffset() > this.clone().month(5).utcOffset()
        );
    }

    function isDaylightSavingTimeShifted () {
        if (!isUndefined(this._isDSTShifted)) {
            return this._isDSTShifted;
        }

        var c = {};

        copyConfig(c, this);
        c = prepareConfig(c);

        if (c._a) {
            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
            this._isDSTShifted = this.isValid() &&
                compareArrays(c._a, other.toArray()) > 0;
        } else {
            this._isDSTShifted = false;
        }

        return this._isDSTShifted;
    }

    function isLocal () {
        return this.isValid() ? !this._isUTC : false;
    }

    function isUtcOffset () {
        return this.isValid() ? this._isUTC : false;
    }

    function isUtc () {
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
    }

    // ASP.NET json date format regex
    var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
    // and further modified to allow for strings containing both week and day
    var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;

    function createDuration (input, key) {
        var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            diffRes;

        if (isDuration(input)) {
            duration = {
                ms : input._milliseconds,
                d  : input._days,
                M  : input._months
            };
        } else if (isNumber(input)) {
            duration = {};
            if (key) {
                duration[key] = input;
            } else {
                duration.milliseconds = input;
            }
        } else if (!!(match = aspNetRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y  : 0,
                d  : toInt(match[DATE])                         * sign,
                h  : toInt(match[HOUR])                         * sign,
                m  : toInt(match[MINUTE])                       * sign,
                s  : toInt(match[SECOND])                       * sign,
                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
            };
        } else if (!!(match = isoRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y : parseIso(match[2], sign),
                M : parseIso(match[3], sign),
                w : parseIso(match[4], sign),
                d : parseIso(match[5], sign),
                h : parseIso(match[6], sign),
                m : parseIso(match[7], sign),
                s : parseIso(match[8], sign)
            };
        } else if (duration == null) {// checks for null or undefined
            duration = {};
        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));

            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
        }

        ret = new Duration(duration);

        if (isDuration(input) && hasOwnProp(input, '_locale')) {
            ret._locale = input._locale;
        }

        return ret;
    }

    createDuration.fn = Duration.prototype;
    createDuration.invalid = createInvalid$1;

    function parseIso (inp, sign) {
        // We'd normally use ~~inp for this, but unfortunately it also
        // converts floats to ints.
        // inp may be undefined, so careful calling replace on it.
        var res = inp && parseFloat(inp.replace(',', '.'));
        // apply sign while we're at it
        return (isNaN(res) ? 0 : res) * sign;
    }

    function positiveMomentsDifference(base, other) {
        var res = {};

        res.months = other.month() - base.month() +
            (other.year() - base.year()) * 12;
        if (base.clone().add(res.months, 'M').isAfter(other)) {
            --res.months;
        }

        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

        return res;
    }

    function momentsDifference(base, other) {
        var res;
        if (!(base.isValid() && other.isValid())) {
            return {milliseconds: 0, months: 0};
        }

        other = cloneWithOffset(other, base);
        if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
        } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
        }

        return res;
    }

    // TODO: remove 'name' arg after deprecation is removed
    function createAdder(direction, name) {
        return function (val, period) {
            var dur, tmp;
            //invert the arguments, but complain about it
            if (period !== null && !isNaN(+period)) {
                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
                tmp = val; val = period; period = tmp;
            }

            val = typeof val === 'string' ? +val : val;
            dur = createDuration(val, period);
            addSubtract(this, dur, direction);
            return this;
        };
    }

    function addSubtract (mom, duration, isAdding, updateOffset) {
        var milliseconds = duration._milliseconds,
            days = absRound(duration._days),
            months = absRound(duration._months);

        if (!mom.isValid()) {
            // No op
            return;
        }

        updateOffset = updateOffset == null ? true : updateOffset;

        if (months) {
            setMonth(mom, get(mom, 'Month') + months * isAdding);
        }
        if (days) {
            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
        }
        if (milliseconds) {
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
        }
        if (updateOffset) {
            hooks.updateOffset(mom, days || months);
        }
    }

    var add      = createAdder(1, 'add');
    var subtract = createAdder(-1, 'subtract');

    function getCalendarFormat(myMoment, now) {
        var diff = myMoment.diff(now, 'days', true);
        return diff < -6 ? 'sameElse' :
                diff < -1 ? 'lastWeek' :
                diff < 0 ? 'lastDay' :
                diff < 1 ? 'sameDay' :
                diff < 2 ? 'nextDay' :
                diff < 7 ? 'nextWeek' : 'sameElse';
    }

    function calendar$1 (time, formats) {
        // We want to compare the start of today, vs this.
        // Getting start-of-today depends on whether we're local/utc/offset or not.
        var now = time || createLocal(),
            sod = cloneWithOffset(now, this).startOf('day'),
            format = hooks.calendarFormat(this, sod) || 'sameElse';

        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
    }

    function clone () {
        return new Moment(this);
    }

    function isAfter (input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() > localInput.valueOf();
        } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
        }
    }

    function isBefore (input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() < localInput.valueOf();
        } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
        }
    }

    function isBetween (from, to, units, inclusivity) {
        var localFrom = isMoment(from) ? from : createLocal(from),
            localTo = isMoment(to) ? to : createLocal(to);
        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
            return false;
        }
        inclusivity = inclusivity || '()';
        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&
            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
    }

    function isSame (input, units) {
        var localInput = isMoment(input) ? input : createLocal(input),
            inputMs;
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() === localInput.valueOf();
        } else {
            inputMs = localInput.valueOf();
            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
        }
    }

    function isSameOrAfter (input, units) {
        return this.isSame(input, units) || this.isAfter(input, units);
    }

    function isSameOrBefore (input, units) {
        return this.isSame(input, units) || this.isBefore(input, units);
    }

    function diff (input, units, asFloat) {
        var that,
            zoneDelta,
            output;

        if (!this.isValid()) {
            return NaN;
        }

        that = cloneWithOffset(input, this);

        if (!that.isValid()) {
            return NaN;
        }

        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

        units = normalizeUnits(units);

        switch (units) {
            case 'year': output = monthDiff(this, that) / 12; break;
            case 'month': output = monthDiff(this, that); break;
            case 'quarter': output = monthDiff(this, that) / 3; break;
            case 'second': output = (this - that) / 1e3; break; // 1000
            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
            default: output = this - that;
        }

        return asFloat ? output : absFloor(output);
    }

    function monthDiff (a, b) {
        // difference in months
        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2, adjust;

        if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor - anchor2);
        } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor2 - anchor);
        }

        //check for negative zero, return zero if negative zero
        return -(wholeMonthDiff + adjust) || 0;
    }

    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

    function toString () {
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
    }

    function toISOString(keepOffset) {
        if (!this.isValid()) {
            return null;
        }
        var utc = keepOffset !== true;
        var m = utc ? this.clone().utc() : this;
        if (m.year() < 0 || m.year() > 9999) {
            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
        }
        if (isFunction(Date.prototype.toISOString)) {
            // native implementation is ~50x faster, use it when we can
            if (utc) {
                return this.toDate().toISOString();
            } else {
                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
            }
        }
        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
    }

    /**
     * Return a human readable representation of a moment that can
     * also be evaluated to get a new moment which is the same
     *
     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
     */
    function inspect () {
        if (!this.isValid()) {
            return 'moment.invalid(/* ' + this._i + ' */)';
        }
        var func = 'moment';
        var zone = '';
        if (!this.isLocal()) {
            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
            zone = 'Z';
        }
        var prefix = '[' + func + '("]';
        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
        var datetime = '-MM-DD[T]HH:mm:ss.SSS';
        var suffix = zone + '[")]';

        return this.format(prefix + year + datetime + suffix);
    }

    function format (inputString) {
        if (!inputString) {
            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
        }
        var output = formatMoment(this, inputString);
        return this.localeData().postformat(output);
    }

    function from (time, withoutSuffix) {
        if (this.isValid() &&
                ((isMoment(time) && time.isValid()) ||
                 createLocal(time).isValid())) {
            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function fromNow (withoutSuffix) {
        return this.from(createLocal(), withoutSuffix);
    }

    function to (time, withoutSuffix) {
        if (this.isValid() &&
                ((isMoment(time) && time.isValid()) ||
                 createLocal(time).isValid())) {
            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function toNow (withoutSuffix) {
        return this.to(createLocal(), withoutSuffix);
    }

    // If passed a locale key, it will set the locale for this
    // instance.  Otherwise, it will return the locale configuration
    // variables for this instance.
    function locale (key) {
        var newLocaleData;

        if (key === undefined) {
            return this._locale._abbr;
        } else {
            newLocaleData = getLocale(key);
            if (newLocaleData != null) {
                this._locale = newLocaleData;
            }
            return this;
        }
    }

    var lang = deprecate(
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
        function (key) {
            if (key === undefined) {
                return this.localeData();
            } else {
                return this.locale(key);
            }
        }
    );

    function localeData () {
        return this._locale;
    }

    var MS_PER_SECOND = 1000;
    var MS_PER_MINUTE = 60 * MS_PER_SECOND;
    var MS_PER_HOUR = 60 * MS_PER_MINUTE;
    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;

    // actual modulo - handles negative numbers (for dates before 1970):
    function mod$1(dividend, divisor) {
        return (dividend % divisor + divisor) % divisor;
    }

    function localStartOfDate(y, m, d) {
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return new Date(y, m, d).valueOf();
        }
    }

    function utcStartOfDate(y, m, d) {
        // Date.UTC remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return Date.UTC(y, m, d);
        }
    }

    function startOf (units) {
        var time;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }

        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;

        switch (units) {
            case 'year':
                time = startOfDate(this.year(), 0, 1);
                break;
            case 'quarter':
                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
                break;
            case 'month':
                time = startOfDate(this.year(), this.month(), 1);
                break;
            case 'week':
                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
                break;
            case 'isoWeek':
                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date());
                break;
            case 'hour':
                time = this._d.valueOf();
                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
                break;
            case 'minute':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_MINUTE);
                break;
            case 'second':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_SECOND);
                break;
        }

        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }

    function endOf (units) {
        var time;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }

        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;

        switch (units) {
            case 'year':
                time = startOfDate(this.year() + 1, 0, 1) - 1;
                break;
            case 'quarter':
                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
                break;
            case 'month':
                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
                break;
            case 'week':
                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
                break;
            case 'isoWeek':
                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
                break;
            case 'hour':
                time = this._d.valueOf();
                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
                break;
            case 'minute':
                time = this._d.valueOf();
                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
                break;
            case 'second':
                time = this._d.valueOf();
                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
                break;
        }

        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }

    function valueOf () {
        return this._d.valueOf() - ((this._offset || 0) * 60000);
    }

    function unix () {
        return Math.floor(this.valueOf() / 1000);
    }

    function toDate () {
        return new Date(this.valueOf());
    }

    function toArray () {
        var m = this;
        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
    }

    function toObject () {
        var m = this;
        return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds()
        };
    }

    function toJSON () {
        // new Date(NaN).toJSON() === null
        return this.isValid() ? this.toISOString() : null;
    }

    function isValid$2 () {
        return isValid(this);
    }

    function parsingFlags () {
        return extend({}, getParsingFlags(this));
    }

    function invalidAt () {
        return getParsingFlags(this).overflow;
    }

    function creationData() {
        return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict
        };
    }

    // FORMATTING

    addFormatToken(0, ['gg', 2], 0, function () {
        return this.weekYear() % 100;
    });

    addFormatToken(0, ['GG', 2], 0, function () {
        return this.isoWeekYear() % 100;
    });

    function addWeekYearFormatToken (token, getter) {
        addFormatToken(0, [token, token.length], 0, getter);
    }

    addWeekYearFormatToken('gggg',     'weekYear');
    addWeekYearFormatToken('ggggg',    'weekYear');
    addWeekYearFormatToken('GGGG',  'isoWeekYear');
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');

    // ALIASES

    addUnitAlias('weekYear', 'gg');
    addUnitAlias('isoWeekYear', 'GG');

    // PRIORITY

    addUnitPriority('weekYear', 1);
    addUnitPriority('isoWeekYear', 1);


    // PARSING

    addRegexToken('G',      matchSigned);
    addRegexToken('g',      matchSigned);
    addRegexToken('GG',     match1to2, match2);
    addRegexToken('gg',     match1to2, match2);
    addRegexToken('GGGG',   match1to4, match4);
    addRegexToken('gggg',   match1to4, match4);
    addRegexToken('GGGGG',  match1to6, match6);
    addRegexToken('ggggg',  match1to6, match6);

    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
        week[token.substr(0, 2)] = toInt(input);
    });

    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
        week[token] = hooks.parseTwoDigitYear(input);
    });

    // MOMENTS

    function getSetWeekYear (input) {
        return getSetWeekYearHelper.call(this,
                input,
                this.week(),
                this.weekday(),
                this.localeData()._week.dow,
                this.localeData()._week.doy);
    }

    function getSetISOWeekYear (input) {
        return getSetWeekYearHelper.call(this,
                input, this.isoWeek(), this.isoWeekday(), 1, 4);
    }

    function getISOWeeksInYear () {
        return weeksInYear(this.year(), 1, 4);
    }

    function getWeeksInYear () {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
    }

    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
        var weeksTarget;
        if (input == null) {
            return weekOfYear(this, dow, doy).year;
        } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
                week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
        }
    }

    function setWeekAll(weekYear, week, weekday, dow, doy) {
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

        this.year(date.getUTCFullYear());
        this.month(date.getUTCMonth());
        this.date(date.getUTCDate());
        return this;
    }

    // FORMATTING

    addFormatToken('Q', 0, 'Qo', 'quarter');

    // ALIASES

    addUnitAlias('quarter', 'Q');

    // PRIORITY

    addUnitPriority('quarter', 7);

    // PARSING

    addRegexToken('Q', match1);
    addParseToken('Q', function (input, array) {
        array[MONTH] = (toInt(input) - 1) * 3;
    });

    // MOMENTS

    function getSetQuarter (input) {
        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
    }

    // FORMATTING

    addFormatToken('D', ['DD', 2], 'Do', 'date');

    // ALIASES

    addUnitAlias('date', 'D');

    // PRIORITY
    addUnitPriority('date', 9);

    // PARSING

    addRegexToken('D',  match1to2);
    addRegexToken('DD', match1to2, match2);
    addRegexToken('Do', function (isStrict, locale) {
        // TODO: Remove "ordinalParse" fallback in next major release.
        return isStrict ?
          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
          locale._dayOfMonthOrdinalParseLenient;
    });

    addParseToken(['D', 'DD'], DATE);
    addParseToken('Do', function (input, array) {
        array[DATE] = toInt(input.match(match1to2)[0]);
    });

    // MOMENTS

    var getSetDayOfMonth = makeGetSet('Date', true);

    // FORMATTING

    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

    // ALIASES

    addUnitAlias('dayOfYear', 'DDD');

    // PRIORITY
    addUnitPriority('dayOfYear', 4);

    // PARSING

    addRegexToken('DDD',  match1to3);
    addRegexToken('DDDD', match3);
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
        config._dayOfYear = toInt(input);
    });

    // HELPERS

    // MOMENTS

    function getSetDayOfYear (input) {
        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
    }

    // FORMATTING

    addFormatToken('m', ['mm', 2], 0, 'minute');

    // ALIASES

    addUnitAlias('minute', 'm');

    // PRIORITY

    addUnitPriority('minute', 14);

    // PARSING

    addRegexToken('m',  match1to2);
    addRegexToken('mm', match1to2, match2);
    addParseToken(['m', 'mm'], MINUTE);

    // MOMENTS

    var getSetMinute = makeGetSet('Minutes', false);

    // FORMATTING

    addFormatToken('s', ['ss', 2], 0, 'second');

    // ALIASES

    addUnitAlias('second', 's');

    // PRIORITY

    addUnitPriority('second', 15);

    // PARSING

    addRegexToken('s',  match1to2);
    addRegexToken('ss', match1to2, match2);
    addParseToken(['s', 'ss'], SECOND);

    // MOMENTS

    var getSetSecond = makeGetSet('Seconds', false);

    // FORMATTING

    addFormatToken('S', 0, 0, function () {
        return ~~(this.millisecond() / 100);
    });

    addFormatToken(0, ['SS', 2], 0, function () {
        return ~~(this.millisecond() / 10);
    });

    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
    addFormatToken(0, ['SSSS', 4], 0, function () {
        return this.millisecond() * 10;
    });
    addFormatToken(0, ['SSSSS', 5], 0, function () {
        return this.millisecond() * 100;
    });
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
        return this.millisecond() * 1000;
    });
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
        return this.millisecond() * 10000;
    });
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
        return this.millisecond() * 100000;
    });
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
        return this.millisecond() * 1000000;
    });


    // ALIASES

    addUnitAlias('millisecond', 'ms');

    // PRIORITY

    addUnitPriority('millisecond', 16);

    // PARSING

    addRegexToken('S',    match1to3, match1);
    addRegexToken('SS',   match1to3, match2);
    addRegexToken('SSS',  match1to3, match3);

    var token;
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
        addRegexToken(token, matchUnsigned);
    }

    function parseMs(input, array) {
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
    }

    for (token = 'S'; token.length <= 9; token += 'S') {
        addParseToken(token, parseMs);
    }
    // MOMENTS

    var getSetMillisecond = makeGetSet('Milliseconds', false);

    // FORMATTING

    addFormatToken('z',  0, 0, 'zoneAbbr');
    addFormatToken('zz', 0, 0, 'zoneName');

    // MOMENTS

    function getZoneAbbr () {
        return this._isUTC ? 'UTC' : '';
    }

    function getZoneName () {
        return this._isUTC ? 'Coordinated Universal Time' : '';
    }

    var proto = Moment.prototype;

    proto.add               = add;
    proto.calendar          = calendar$1;
    proto.clone             = clone;
    proto.diff              = diff;
    proto.endOf             = endOf;
    proto.format            = format;
    proto.from              = from;
    proto.fromNow           = fromNow;
    proto.to                = to;
    proto.toNow             = toNow;
    proto.get               = stringGet;
    proto.invalidAt         = invalidAt;
    proto.isAfter           = isAfter;
    proto.isBefore          = isBefore;
    proto.isBetween         = isBetween;
    proto.isSame            = isSame;
    proto.isSameOrAfter     = isSameOrAfter;
    proto.isSameOrBefore    = isSameOrBefore;
    proto.isValid           = isValid$2;
    proto.lang              = lang;
    proto.locale            = locale;
    proto.localeData        = localeData;
    proto.max               = prototypeMax;
    proto.min               = prototypeMin;
    proto.parsingFlags      = parsingFlags;
    proto.set               = stringSet;
    proto.startOf           = startOf;
    proto.subtract          = subtract;
    proto.toArray           = toArray;
    proto.toObject          = toObject;
    proto.toDate            = toDate;
    proto.toISOString       = toISOString;
    proto.inspect           = inspect;
    proto.toJSON            = toJSON;
    proto.toString          = toString;
    proto.unix              = unix;
    proto.valueOf           = valueOf;
    proto.creationData      = creationData;
    proto.year       = getSetYear;
    proto.isLeapYear = getIsLeapYear;
    proto.weekYear    = getSetWeekYear;
    proto.isoWeekYear = getSetISOWeekYear;
    proto.quarter = proto.quarters = getSetQuarter;
    proto.month       = getSetMonth;
    proto.daysInMonth = getDaysInMonth;
    proto.week           = proto.weeks        = getSetWeek;
    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
    proto.weeksInYear    = getWeeksInYear;
    proto.isoWeeksInYear = getISOWeeksInYear;
    proto.date       = getSetDayOfMonth;
    proto.day        = proto.days             = getSetDayOfWeek;
    proto.weekday    = getSetLocaleDayOfWeek;
    proto.isoWeekday = getSetISODayOfWeek;
    proto.dayOfYear  = getSetDayOfYear;
    proto.hour = proto.hours = getSetHour;
    proto.minute = proto.minutes = getSetMinute;
    proto.second = proto.seconds = getSetSecond;
    proto.millisecond = proto.milliseconds = getSetMillisecond;
    proto.utcOffset            = getSetOffset;
    proto.utc                  = setOffsetToUTC;
    proto.local                = setOffsetToLocal;
    proto.parseZone            = setOffsetToParsedOffset;
    proto.hasAlignedHourOffset = hasAlignedHourOffset;
    proto.isDST                = isDaylightSavingTime;
    proto.isLocal              = isLocal;
    proto.isUtcOffset          = isUtcOffset;
    proto.isUtc                = isUtc;
    proto.isUTC                = isUtc;
    proto.zoneAbbr = getZoneAbbr;
    proto.zoneName = getZoneName;
    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

    function createUnix (input) {
        return createLocal(input * 1000);
    }

    function createInZone () {
        return createLocal.apply(null, arguments).parseZone();
    }

    function preParsePostFormat (string) {
        return string;
    }

    var proto$1 = Locale.prototype;

    proto$1.calendar        = calendar;
    proto$1.longDateFormat  = longDateFormat;
    proto$1.invalidDate     = invalidDate;
    proto$1.ordinal         = ordinal;
    proto$1.preparse        = preParsePostFormat;
    proto$1.postformat      = preParsePostFormat;
    proto$1.relativeTime    = relativeTime;
    proto$1.pastFuture      = pastFuture;
    proto$1.set             = set;

    proto$1.months            =        localeMonths;
    proto$1.monthsShort       =        localeMonthsShort;
    proto$1.monthsParse       =        localeMonthsParse;
    proto$1.monthsRegex       = monthsRegex;
    proto$1.monthsShortRegex  = monthsShortRegex;
    proto$1.week = localeWeek;
    proto$1.firstDayOfYear = localeFirstDayOfYear;
    proto$1.firstDayOfWeek = localeFirstDayOfWeek;

    proto$1.weekdays       =        localeWeekdays;
    proto$1.weekdaysMin    =        localeWeekdaysMin;
    proto$1.weekdaysShort  =        localeWeekdaysShort;
    proto$1.weekdaysParse  =        localeWeekdaysParse;

    proto$1.weekdaysRegex       =        weekdaysRegex;
    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;

    proto$1.isPM = localeIsPM;
    proto$1.meridiem = localeMeridiem;

    function get$1 (format, index, field, setter) {
        var locale = getLocale();
        var utc = createUTC().set(setter, index);
        return locale[field](utc, format);
    }

    function listMonthsImpl (format, index, field) {
        if (isNumber(format)) {
            index = format;
            format = undefined;
        }

        format = format || '';

        if (index != null) {
            return get$1(format, index, field, 'month');
        }

        var i;
        var out = [];
        for (i = 0; i < 12; i++) {
            out[i] = get$1(format, i, field, 'month');
        }
        return out;
    }

    // ()
    // (5)
    // (fmt, 5)
    // (fmt)
    // (true)
    // (true, 5)
    // (true, fmt, 5)
    // (true, fmt)
    function listWeekdaysImpl (localeSorted, format, index, field) {
        if (typeof localeSorted === 'boolean') {
            if (isNumber(format)) {
                index = format;
                format = undefined;
            }

            format = format || '';
        } else {
            format = localeSorted;
            index = format;
            localeSorted = false;

            if (isNumber(format)) {
                index = format;
                format = undefined;
            }

            format = format || '';
        }

        var locale = getLocale(),
            shift = localeSorted ? locale._week.dow : 0;

        if (index != null) {
            return get$1(format, (index + shift) % 7, field, 'day');
        }

        var i;
        var out = [];
        for (i = 0; i < 7; i++) {
            out[i] = get$1(format, (i + shift) % 7, field, 'day');
        }
        return out;
    }

    function listMonths (format, index) {
        return listMonthsImpl(format, index, 'months');
    }

    function listMonthsShort (format, index) {
        return listMonthsImpl(format, index, 'monthsShort');
    }

    function listWeekdays (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
    }

    function listWeekdaysShort (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
    }

    function listWeekdaysMin (localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
    }

    getSetGlobalLocale('en', {
        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
        ordinal : function (number) {
            var b = number % 10,
                output = (toInt(number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
            return number + output;
        }
    });

    // Side effect imports

    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);

    var mathAbs = Math.abs;

    function abs () {
        var data           = this._data;

        this._milliseconds = mathAbs(this._milliseconds);
        this._days         = mathAbs(this._days);
        this._months       = mathAbs(this._months);

        data.milliseconds  = mathAbs(data.milliseconds);
        data.seconds       = mathAbs(data.seconds);
        data.minutes       = mathAbs(data.minutes);
        data.hours         = mathAbs(data.hours);
        data.months        = mathAbs(data.months);
        data.years         = mathAbs(data.years);

        return this;
    }

    function addSubtract$1 (duration, input, value, direction) {
        var other = createDuration(input, value);

        duration._milliseconds += direction * other._milliseconds;
        duration._days         += direction * other._days;
        duration._months       += direction * other._months;

        return duration._bubble();
    }

    // supports only 2.0-style add(1, 's') or add(duration)
    function add$1 (input, value) {
        return addSubtract$1(this, input, value, 1);
    }

    // supports only 2.0-style subtract(1, 's') or subtract(duration)
    function subtract$1 (input, value) {
        return addSubtract$1(this, input, value, -1);
    }

    function absCeil (number) {
        if (number < 0) {
            return Math.floor(number);
        } else {
            return Math.ceil(number);
        }
    }

    function bubble () {
        var milliseconds = this._milliseconds;
        var days         = this._days;
        var months       = this._months;
        var data         = this._data;
        var seconds, minutes, hours, years, monthsFromDays;

        // if we have a mix of positive and negative values, bubble down first
        // check: https://github.com/moment/moment/issues/2166
        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
                (milliseconds <= 0 && days <= 0 && months <= 0))) {
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
            days = 0;
            months = 0;
        }

        // The following code bubbles up values, see the tests for
        // examples of what that means.
        data.milliseconds = milliseconds % 1000;

        seconds           = absFloor(milliseconds / 1000);
        data.seconds      = seconds % 60;

        minutes           = absFloor(seconds / 60);
        data.minutes      = minutes % 60;

        hours             = absFloor(minutes / 60);
        data.hours        = hours % 24;

        days += absFloor(hours / 24);

        // convert days to months
        monthsFromDays = absFloor(daysToMonths(days));
        months += monthsFromDays;
        days -= absCeil(monthsToDays(monthsFromDays));

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;

        data.days   = days;
        data.months = months;
        data.years  = years;

        return this;
    }

    function daysToMonths (days) {
        // 400 years have 146097 days (taking into account leap year rules)
        // 400 years have 12 months === 4800
        return days * 4800 / 146097;
    }

    function monthsToDays (months) {
        // the reverse of daysToMonths
        return months * 146097 / 4800;
    }

    function as (units) {
        if (!this.isValid()) {
            return NaN;
        }
        var days;
        var months;
        var milliseconds = this._milliseconds;

        units = normalizeUnits(units);

        if (units === 'month' || units === 'quarter' || units === 'year') {
            days = this._days + milliseconds / 864e5;
            months = this._months + daysToMonths(days);
            switch (units) {
                case 'month':   return months;
                case 'quarter': return months / 3;
                case 'year':    return months / 12;
            }
        } else {
            // handle milliseconds separately because of floating point math errors (issue #1867)
            days = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
                case 'week'   : return days / 7     + milliseconds / 6048e5;
                case 'day'    : return days         + milliseconds / 864e5;
                case 'hour'   : return days * 24    + milliseconds / 36e5;
                case 'minute' : return days * 1440  + milliseconds / 6e4;
                case 'second' : return days * 86400 + milliseconds / 1000;
                // Math.floor prevents floating point math errors here
                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
                default: throw new Error('Unknown unit ' + units);
            }
        }
    }

    // TODO: Use this.as('ms')?
    function valueOf$1 () {
        if (!this.isValid()) {
            return NaN;
        }
        return (
            this._milliseconds +
            this._days * 864e5 +
            (this._months % 12) * 2592e6 +
            toInt(this._months / 12) * 31536e6
        );
    }

    function makeAs (alias) {
        return function () {
            return this.as(alias);
        };
    }

    var asMilliseconds = makeAs('ms');
    var asSeconds      = makeAs('s');
    var asMinutes      = makeAs('m');
    var asHours        = makeAs('h');
    var asDays         = makeAs('d');
    var asWeeks        = makeAs('w');
    var asMonths       = makeAs('M');
    var asQuarters     = makeAs('Q');
    var asYears        = makeAs('y');

    function clone$1 () {
        return createDuration(this);
    }

    function get$2 (units) {
        units = normalizeUnits(units);
        return this.isValid() ? this[units + 's']() : NaN;
    }

    function makeGetter(name) {
        return function () {
            return this.isValid() ? this._data[name] : NaN;
        };
    }

    var milliseconds = makeGetter('milliseconds');
    var seconds      = makeGetter('seconds');
    var minutes      = makeGetter('minutes');
    var hours        = makeGetter('hours');
    var days         = makeGetter('days');
    var months       = makeGetter('months');
    var years        = makeGetter('years');

    function weeks () {
        return absFloor(this.days() / 7);
    }

    var round = Math.round;
    var thresholds = {
        ss: 44,         // a few seconds to seconds
        s : 45,         // seconds to minute
        m : 45,         // minutes to hour
        h : 22,         // hours to day
        d : 26,         // days to month
        M : 11          // months to year
    };

    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
    }

    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
        var duration = createDuration(posNegDuration).abs();
        var seconds  = round(duration.as('s'));
        var minutes  = round(duration.as('m'));
        var hours    = round(duration.as('h'));
        var days     = round(duration.as('d'));
        var months   = round(duration.as('M'));
        var years    = round(duration.as('y'));

        var a = seconds <= thresholds.ss && ['s', seconds]  ||
                seconds < thresholds.s   && ['ss', seconds] ||
                minutes <= 1             && ['m']           ||
                minutes < thresholds.m   && ['mm', minutes] ||
                hours   <= 1             && ['h']           ||
                hours   < thresholds.h   && ['hh', hours]   ||
                days    <= 1             && ['d']           ||
                days    < thresholds.d   && ['dd', days]    ||
                months  <= 1             && ['M']           ||
                months  < thresholds.M   && ['MM', months]  ||
                years   <= 1             && ['y']           || ['yy', years];

        a[2] = withoutSuffix;
        a[3] = +posNegDuration > 0;
        a[4] = locale;
        return substituteTimeAgo.apply(null, a);
    }

    // This function allows you to set the rounding function for relative time strings
    function getSetRelativeTimeRounding (roundingFunction) {
        if (roundingFunction === undefined) {
            return round;
        }
        if (typeof(roundingFunction) === 'function') {
            round = roundingFunction;
            return true;
        }
        return false;
    }

    // This function allows you to set a threshold for relative time strings
    function getSetRelativeTimeThreshold (threshold, limit) {
        if (thresholds[threshold] === undefined) {
            return false;
        }
        if (limit === undefined) {
            return thresholds[threshold];
        }
        thresholds[threshold] = limit;
        if (threshold === 's') {
            thresholds.ss = limit - 1;
        }
        return true;
    }

    function humanize (withSuffix) {
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }

        var locale = this.localeData();
        var output = relativeTime$1(this, !withSuffix, locale);

        if (withSuffix) {
            output = locale.pastFuture(+this, output);
        }

        return locale.postformat(output);
    }

    var abs$1 = Math.abs;

    function sign(x) {
        return ((x > 0) - (x < 0)) || +x;
    }

    function toISOString$1() {
        // for ISO strings we do not use the normal bubbling rules:
        //  * milliseconds bubble up until they become hours
        //  * days do not bubble at all
        //  * months bubble up until they become years
        // This is because there is no context-free conversion between hours and days
        // (think of clock changes)
        // and also not between days and months (28-31 days per month)
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }

        var seconds = abs$1(this._milliseconds) / 1000;
        var days         = abs$1(this._days);
        var months       = abs$1(this._months);
        var minutes, hours, years;

        // 3600 seconds -> 60 minutes -> 1 hour
        minutes           = absFloor(seconds / 60);
        hours             = absFloor(minutes / 60);
        seconds %= 60;
        minutes %= 60;

        // 12 months -> 1 year
        years  = absFloor(months / 12);
        months %= 12;


        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
        var Y = years;
        var M = months;
        var D = days;
        var h = hours;
        var m = minutes;
        var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
        var total = this.asSeconds();

        if (!total) {
            // this is the same as C#'s (Noda) and python (isodate)...
            // but not other JS (goog.date)
            return 'P0D';
        }

        var totalSign = total < 0 ? '-' : '';
        var ymSign = sign(this._months) !== sign(total) ? '-' : '';
        var daysSign = sign(this._days) !== sign(total) ? '-' : '';
        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';

        return totalSign + 'P' +
            (Y ? ymSign + Y + 'Y' : '') +
            (M ? ymSign + M + 'M' : '') +
            (D ? daysSign + D + 'D' : '') +
            ((h || m || s) ? 'T' : '') +
            (h ? hmsSign + h + 'H' : '') +
            (m ? hmsSign + m + 'M' : '') +
            (s ? hmsSign + s + 'S' : '');
    }

    var proto$2 = Duration.prototype;

    proto$2.isValid        = isValid$1;
    proto$2.abs            = abs;
    proto$2.add            = add$1;
    proto$2.subtract       = subtract$1;
    proto$2.as             = as;
    proto$2.asMilliseconds = asMilliseconds;
    proto$2.asSeconds      = asSeconds;
    proto$2.asMinutes      = asMinutes;
    proto$2.asHours        = asHours;
    proto$2.asDays         = asDays;
    proto$2.asWeeks        = asWeeks;
    proto$2.asMonths       = asMonths;
    proto$2.asQuarters     = asQuarters;
    proto$2.asYears        = asYears;
    proto$2.valueOf        = valueOf$1;
    proto$2._bubble        = bubble;
    proto$2.clone          = clone$1;
    proto$2.get            = get$2;
    proto$2.milliseconds   = milliseconds;
    proto$2.seconds        = seconds;
    proto$2.minutes        = minutes;
    proto$2.hours          = hours;
    proto$2.days           = days;
    proto$2.weeks          = weeks;
    proto$2.months         = months;
    proto$2.years          = years;
    proto$2.humanize       = humanize;
    proto$2.toISOString    = toISOString$1;
    proto$2.toString       = toISOString$1;
    proto$2.toJSON         = toISOString$1;
    proto$2.locale         = locale;
    proto$2.localeData     = localeData;

    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
    proto$2.lang = lang;

    // Side effect imports

    // FORMATTING

    addFormatToken('X', 0, 0, 'unix');
    addFormatToken('x', 0, 0, 'valueOf');

    // PARSING

    addRegexToken('x', matchSigned);
    addRegexToken('X', matchTimestamp);
    addParseToken('X', function (input, array, config) {
        config._d = new Date(parseFloat(input, 10) * 1000);
    });
    addParseToken('x', function (input, array, config) {
        config._d = new Date(toInt(input));
    });

    // Side effect imports


    hooks.version = '2.24.0';

    setHookCallback(createLocal);

    hooks.fn                    = proto;
    hooks.min                   = min;
    hooks.max                   = max;
    hooks.now                   = now;
    hooks.utc                   = createUTC;
    hooks.unix                  = createUnix;
    hooks.months                = listMonths;
    hooks.isDate                = isDate;
    hooks.locale                = getSetGlobalLocale;
    hooks.invalid               = createInvalid;
    hooks.duration              = createDuration;
    hooks.isMoment              = isMoment;
    hooks.weekdays              = listWeekdays;
    hooks.parseZone             = createInZone;
    hooks.localeData            = getLocale;
    hooks.isDuration            = isDuration;
    hooks.monthsShort           = listMonthsShort;
    hooks.weekdaysMin           = listWeekdaysMin;
    hooks.defineLocale          = defineLocale;
    hooks.updateLocale          = updateLocale;
    hooks.locales               = listLocales;
    hooks.weekdaysShort         = listWeekdaysShort;
    hooks.normalizeUnits        = normalizeUnits;
    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
    hooks.calendarFormat        = getCalendarFormat;
    hooks.prototype             = proto;

    // currently HTML5 input type only supports 24-hour formats
    hooks.HTML5_FMT = {
        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
        DATE: 'YYYY-MM-DD',                             // <input type="date" />
        TIME: 'HH:mm',                                  // <input type="time" />
        TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
        TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
        WEEK: 'GGGG-[W]WW',                             // <input type="week" />
        MONTH: 'YYYY-MM'                                // <input type="month" />
    };

    return hooks;

})));

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(206)(module)))

/***/ }),
/* 541 */
/***/ (function(module, exports, __webpack_require__) {

var map = {
	"./af": 339,
	"./af.js": 339,
	"./ar": 340,
	"./ar-dz": 341,
	"./ar-dz.js": 341,
	"./ar-kw": 342,
	"./ar-kw.js": 342,
	"./ar-ly": 343,
	"./ar-ly.js": 343,
	"./ar-ma": 344,
	"./ar-ma.js": 344,
	"./ar-sa": 345,
	"./ar-sa.js": 345,
	"./ar-tn": 346,
	"./ar-tn.js": 346,
	"./ar.js": 340,
	"./az": 347,
	"./az.js": 347,
	"./be": 348,
	"./be.js": 348,
	"./bg": 349,
	"./bg.js": 349,
	"./bm": 350,
	"./bm.js": 350,
	"./bn": 351,
	"./bn.js": 351,
	"./bo": 352,
	"./bo.js": 352,
	"./br": 353,
	"./br.js": 353,
	"./bs": 354,
	"./bs.js": 354,
	"./ca": 355,
	"./ca.js": 355,
	"./cs": 356,
	"./cs.js": 356,
	"./cv": 357,
	"./cv.js": 357,
	"./cy": 358,
	"./cy.js": 358,
	"./da": 359,
	"./da.js": 359,
	"./de": 360,
	"./de-at": 361,
	"./de-at.js": 361,
	"./de-ch": 362,
	"./de-ch.js": 362,
	"./de.js": 360,
	"./dv": 363,
	"./dv.js": 363,
	"./el": 364,
	"./el.js": 364,
	"./en-SG": 365,
	"./en-SG.js": 365,
	"./en-au": 366,
	"./en-au.js": 366,
	"./en-ca": 367,
	"./en-ca.js": 367,
	"./en-gb": 368,
	"./en-gb.js": 368,
	"./en-ie": 369,
	"./en-ie.js": 369,
	"./en-il": 370,
	"./en-il.js": 370,
	"./en-nz": 371,
	"./en-nz.js": 371,
	"./eo": 372,
	"./eo.js": 372,
	"./es": 373,
	"./es-do": 374,
	"./es-do.js": 374,
	"./es-us": 375,
	"./es-us.js": 375,
	"./es.js": 373,
	"./et": 376,
	"./et.js": 376,
	"./eu": 377,
	"./eu.js": 377,
	"./fa": 378,
	"./fa.js": 378,
	"./fi": 379,
	"./fi.js": 379,
	"./fo": 380,
	"./fo.js": 380,
	"./fr": 381,
	"./fr-ca": 382,
	"./fr-ca.js": 382,
	"./fr-ch": 383,
	"./fr-ch.js": 383,
	"./fr.js": 381,
	"./fy": 384,
	"./fy.js": 384,
	"./ga": 385,
	"./ga.js": 385,
	"./gd": 386,
	"./gd.js": 386,
	"./gl": 387,
	"./gl.js": 387,
	"./gom-latn": 388,
	"./gom-latn.js": 388,
	"./gu": 389,
	"./gu.js": 389,
	"./he": 390,
	"./he.js": 390,
	"./hi": 391,
	"./hi.js": 391,
	"./hr": 392,
	"./hr.js": 392,
	"./hu": 393,
	"./hu.js": 393,
	"./hy-am": 394,
	"./hy-am.js": 394,
	"./id": 395,
	"./id.js": 395,
	"./is": 396,
	"./is.js": 396,
	"./it": 397,
	"./it-ch": 398,
	"./it-ch.js": 398,
	"./it.js": 397,
	"./ja": 399,
	"./ja.js": 399,
	"./jv": 400,
	"./jv.js": 400,
	"./ka": 401,
	"./ka.js": 401,
	"./kk": 402,
	"./kk.js": 402,
	"./km": 403,
	"./km.js": 403,
	"./kn": 404,
	"./kn.js": 404,
	"./ko": 405,
	"./ko.js": 405,
	"./ku": 406,
	"./ku.js": 406,
	"./ky": 407,
	"./ky.js": 407,
	"./lb": 408,
	"./lb.js": 408,
	"./lo": 409,
	"./lo.js": 409,
	"./lt": 410,
	"./lt.js": 410,
	"./lv": 411,
	"./lv.js": 411,
	"./me": 412,
	"./me.js": 412,
	"./mi": 413,
	"./mi.js": 413,
	"./mk": 414,
	"./mk.js": 414,
	"./ml": 415,
	"./ml.js": 415,
	"./mn": 416,
	"./mn.js": 416,
	"./mr": 417,
	"./mr.js": 417,
	"./ms": 418,
	"./ms-my": 419,
	"./ms-my.js": 419,
	"./ms.js": 418,
	"./mt": 420,
	"./mt.js": 420,
	"./my": 421,
	"./my.js": 421,
	"./nb": 422,
	"./nb.js": 422,
	"./ne": 423,
	"./ne.js": 423,
	"./nl": 424,
	"./nl-be": 425,
	"./nl-be.js": 425,
	"./nl.js": 424,
	"./nn": 426,
	"./nn.js": 426,
	"./pa-in": 427,
	"./pa-in.js": 427,
	"./pl": 428,
	"./pl.js": 428,
	"./pt": 429,
	"./pt-br": 430,
	"./pt-br.js": 430,
	"./pt.js": 429,
	"./ro": 431,
	"./ro.js": 431,
	"./ru": 432,
	"./ru.js": 432,
	"./sd": 433,
	"./sd.js": 433,
	"./se": 434,
	"./se.js": 434,
	"./si": 435,
	"./si.js": 435,
	"./sk": 436,
	"./sk.js": 436,
	"./sl": 437,
	"./sl.js": 437,
	"./sq": 438,
	"./sq.js": 438,
	"./sr": 439,
	"./sr-cyrl": 440,
	"./sr-cyrl.js": 440,
	"./sr.js": 439,
	"./ss": 441,
	"./ss.js": 441,
	"./sv": 442,
	"./sv.js": 442,
	"./sw": 443,
	"./sw.js": 443,
	"./ta": 444,
	"./ta.js": 444,
	"./te": 445,
	"./te.js": 445,
	"./tet": 446,
	"./tet.js": 446,
	"./tg": 447,
	"./tg.js": 447,
	"./th": 448,
	"./th.js": 448,
	"./tl-ph": 449,
	"./tl-ph.js": 449,
	"./tlh": 450,
	"./tlh.js": 450,
	"./tr": 451,
	"./tr.js": 451,
	"./tzl": 452,
	"./tzl.js": 452,
	"./tzm": 453,
	"./tzm-latn": 454,
	"./tzm-latn.js": 454,
	"./tzm.js": 453,
	"./ug-cn": 455,
	"./ug-cn.js": 455,
	"./uk": 456,
	"./uk.js": 456,
	"./ur": 457,
	"./ur.js": 457,
	"./uz": 458,
	"./uz-latn": 459,
	"./uz-latn.js": 459,
	"./uz.js": 458,
	"./vi": 460,
	"./vi.js": 460,
	"./x-pseudo": 461,
	"./x-pseudo.js": 461,
	"./yo": 462,
	"./yo.js": 462,
	"./zh-cn": 463,
	"./zh-cn.js": 463,
	"./zh-hk": 464,
	"./zh-hk.js": 464,
	"./zh-tw": 465,
	"./zh-tw.js": 465
};


function webpackContext(req) {
	var id = webpackContextResolve(req);
	return __webpack_require__(id);
}
function webpackContextResolve(req) {
	if(!__webpack_require__.o(map, req)) {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return map[req];
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 541;

/***/ }),
/* 542 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 543 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _autocompleteEditor = _interopRequireDefault(__webpack_require__(337));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

/**
 * @private
 * @editor DropdownEditor
 * @class DropdownEditor
 * @dependencies AutocompleteEditor
 */
var DropdownEditor =
/*#__PURE__*/
function (_AutocompleteEditor) {
  (0, _inherits2.default)(DropdownEditor, _AutocompleteEditor);

  function DropdownEditor() {
    (0, _classCallCheck2.default)(this, DropdownEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DropdownEditor).apply(this, arguments));
  }

  (0, _createClass2.default)(DropdownEditor, [{
    key: "prepare",
    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
      (0, _get2.default)((0, _getPrototypeOf2.default)(DropdownEditor.prototype), "prepare", this).call(this, row, col, prop, td, originalValue, cellProperties);
      this.cellProperties.filter = false;
      this.cellProperties.strict = true;
    }
  }]);
  return DropdownEditor;
}(_autocompleteEditor.default);

_pluginHooks.default.getSingleton().add('beforeValidate', function (value, row, col) {
  var cellMeta = this.getCellMeta(row, this.propToCol(col));

  if (cellMeta.editor === DropdownEditor) {
    if (cellMeta.strict === void 0) {
      cellMeta.filter = false;
      cellMeta.strict = true;
    }
  }
});

var _default = DropdownEditor;
exports.default = _default;

/***/ }),
/* 544 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _textEditor = _interopRequireDefault(__webpack_require__(107));

/**
 * @private
 * @editor NumericEditor
 * @class NumericEditor
 */
var NumericEditor =
/*#__PURE__*/
function (_TextEditor) {
  (0, _inherits2.default)(NumericEditor, _TextEditor);

  function NumericEditor() {
    (0, _classCallCheck2.default)(this, NumericEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NumericEditor).apply(this, arguments));
  }

  return NumericEditor;
}(_textEditor.default);

var _default = NumericEditor;
exports.default = _default;

/***/ }),
/* 545 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _textEditor = _interopRequireDefault(__webpack_require__(107));

/**
 * @private
 * @editor PasswordEditor
 * @class PasswordEditor
 * @dependencies TextEditor
 */
var PasswordEditor =
/*#__PURE__*/
function (_TextEditor) {
  (0, _inherits2.default)(PasswordEditor, _TextEditor);

  function PasswordEditor() {
    (0, _classCallCheck2.default)(this, PasswordEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(PasswordEditor).apply(this, arguments));
  }

  (0, _createClass2.default)(PasswordEditor, [{
    key: "createElements",
    value: function createElements() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(PasswordEditor.prototype), "createElements", this).call(this);
      this.TEXTAREA = this.hot.rootDocument.createElement('input');
      this.TEXTAREA.setAttribute('type', 'password');
      this.TEXTAREA.className = 'handsontableInput';
      this.textareaStyle = this.TEXTAREA.style;
      this.textareaStyle.width = 0;
      this.textareaStyle.height = 0;
      (0, _element.empty)(this.TEXTAREA_PARENT);
      this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
    }
  }]);
  return PasswordEditor;
}(_textEditor.default);

var _default = PasswordEditor;
exports.default = _default;

/***/ }),
/* 546 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

var _unicode = __webpack_require__(50);

var _baseEditor = _interopRequireWildcard(__webpack_require__(104));

var _object = __webpack_require__(4);

/**
 * @private
 * @editor SelectEditor
 * @class SelectEditor
 */
var SelectEditor =
/*#__PURE__*/
function (_BaseEditor) {
  (0, _inherits2.default)(SelectEditor, _BaseEditor);

  function SelectEditor() {
    (0, _classCallCheck2.default)(this, SelectEditor);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(SelectEditor).apply(this, arguments));
  }

  (0, _createClass2.default)(SelectEditor, [{
    key: "init",

    /**
     * Initializes editor instance, DOM Element and mount hooks.
     */
    value: function init() {
      this.select = this.hot.rootDocument.createElement('SELECT');
      (0, _element.addClass)(this.select, 'htSelectEditor');
      this.select.style.display = 'none';
      this.hot.rootElement.appendChild(this.select);
      this.registerHooks();
    }
    /**
     * Returns select's value.
     *
     * @returns {*}
     */

  }, {
    key: "getValue",
    value: function getValue() {
      return this.select.value;
    }
    /**
     * Sets value in the select element.
     *
     * @param {*} value A new select's value.
     */

  }, {
    key: "setValue",
    value: function setValue(value) {
      this.select.value = value;
    }
    /**
     * Opens the editor and adjust its size.
     */

  }, {
    key: "open",
    value: function open() {
      var _this = this;

      this._opened = true;
      this.refreshDimensions();
      this.select.style.display = '';
      this.addHook('beforeKeyDown', function () {
        return _this.onBeforeKeyDown();
      });
    }
    /**
     * Closes the editor.
     */

  }, {
    key: "close",
    value: function close() {
      this._opened = false;
      this.select.style.display = 'none';
      this.clearHooks();
    }
    /**
     * Sets focus state on the select element.
     */

  }, {
    key: "focus",
    value: function focus() {
      this.select.focus();
    }
    /**
     * Binds hooks to refresh editor's size after scrolling of the viewport or resizing of columns/rows.
     *
     * @private
     */

  }, {
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.addHook('afterScrollHorizontally', function () {
        return _this2.refreshDimensions();
      });
      this.addHook('afterScrollVertically', function () {
        return _this2.refreshDimensions();
      });
      this.addHook('afterColumnResize', function () {
        return _this2.refreshDimensions();
      });
      this.addHook('afterRowResize', function () {
        return _this2.refreshDimensions();
      });
    }
    /**
     * Prepares editor's meta data and a list of available options.
     *
     * @param {Number} row
     * @param {Number} col
     * @param {Number|String} prop
     * @param {HTMLTableCellElement} td
     * @param {*} originalValue
     * @param {Object} cellProperties
     */

  }, {
    key: "prepare",
    value: function prepare(row, col, prop, td, originalValue, cellProperties) {
      var _this3 = this;

      (0, _get2.default)((0, _getPrototypeOf2.default)(SelectEditor.prototype), "prepare", this).call(this, row, col, prop, td, originalValue, cellProperties);
      var selectOptions = this.cellProperties.selectOptions;
      var options;

      if (typeof selectOptions === 'function') {
        options = this.prepareOptions(selectOptions(this.row, this.col, this.prop));
      } else {
        options = this.prepareOptions(selectOptions);
      }

      (0, _element.empty)(this.select);
      (0, _object.objectEach)(options, function (value, key) {
        var optionElement = _this3.hot.rootDocument.createElement('OPTION');

        optionElement.value = key;
        (0, _element.fastInnerHTML)(optionElement, value);

        _this3.select.appendChild(optionElement);
      });
    }
    /**
     * Creates consistent list of available options.
     *
     * @private
     * @param {Array|Object} optionsToPrepare
     * @returns {Object}
     */

  }, {
    key: "prepareOptions",
    value: function prepareOptions(optionsToPrepare) {
      var preparedOptions = {};

      if (Array.isArray(optionsToPrepare)) {
        for (var i = 0, len = optionsToPrepare.length; i < len; i++) {
          preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i];
        }
      } else if ((0, _typeof2.default)(optionsToPrepare) === 'object') {
        preparedOptions = optionsToPrepare;
      }

      return preparedOptions;
    }
    /**
     * Refreshes editor's value using source data.
     *
     * @private
     */

  }, {
    key: "refreshValue",
    value: function refreshValue() {
      var sourceData = this.hot.getSourceDataAtCell(this.row, this.prop);
      this.originalValue = sourceData;
      this.setValue(sourceData);
      this.refreshDimensions();
    }
    /**
     * Refreshes editor's size and position.
     *
     * @private
     */

  }, {
    key: "refreshDimensions",
    value: function refreshDimensions() {
      if (this.state !== _baseEditor.EditorState.EDITING) {
        return;
      }

      this.TD = this.getEditedCell(); // TD is outside of the viewport.

      if (!this.TD) {
        this.close();
        return;
      }

      var wtOverlays = this.hot.view.wt.wtOverlays;
      var currentOffset = (0, _element.offset)(this.TD);
      var containerOffset = (0, _element.offset)(this.hot.rootElement);
      var scrollableContainer = wtOverlays.scrollableElement;
      var editorSection = this.checkEditorSection();
      var width = (0, _element.outerWidth)(this.TD) + 1;
      var height = (0, _element.outerHeight)(this.TD) + 1;
      var editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0);
      var editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0);
      var cssTransformOffset;

      switch (editorSection) {
        case 'top':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'left':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'top-left-corner':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'bottom-left-corner':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
          break;

        case 'bottom':
          cssTransformOffset = (0, _element.getCssTransform)(wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
          break;

        default:
          break;
      }

      if (this.hot.getSelectedLast()[0] === 0) {
        editTop += 1;
      }

      if (this.hot.getSelectedLast()[1] === 0) {
        editLeft += 1;
      }

      var selectStyle = this.select.style;

      if (cssTransformOffset && cssTransformOffset !== -1) {
        selectStyle[cssTransformOffset[0]] = cssTransformOffset[1];
      } else {
        (0, _element.resetCssTransform)(this.select);
      }

      var cellComputedStyle = (0, _element.getComputedStyle)(this.TD, this.hot.rootWindow);

      if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) {
        height -= 1;
      }

      if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) {
        width -= 1;
      }

      selectStyle.height = "".concat(height, "px");
      selectStyle.minWidth = "".concat(width, "px");
      selectStyle.top = "".concat(editTop, "px");
      selectStyle.left = "".concat(editLeft, "px");
      selectStyle.margin = '0px';
    }
    /**
     * Gets HTMLTableCellElement of the edited cell if exist.
     *
     * @private
     * @returns {HTMLTableCellElement|undefined}
     */

  }, {
    key: "getEditedCell",
    value: function getEditedCell() {
      var wtOverlays = this.hot.view.wt.wtOverlays;
      var editorSection = this.checkEditorSection();
      var editedCell;

      switch (editorSection) {
        case 'top':
          editedCell = wtOverlays.topOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.select.style.zIndex = 101;
          break;

        case 'corner':
          editedCell = wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.select.style.zIndex = 103;
          break;

        case 'left':
          editedCell = wtOverlays.leftOverlay.clone.wtTable.getCell({
            row: this.row,
            col: this.col
          });
          this.select.style.zIndex = 102;
          break;

        default:
          editedCell = this.hot.getCell(this.row, this.col);
          this.select.style.zIndex = '';
          break;
      }

      return editedCell < 0 ? void 0 : editedCell;
    }
    /**
     * onBeforeKeyDown callback.
     *
     * @private
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown() {
      var previousOptionIndex = this.select.selectedIndex - 1;
      var nextOptionIndex = this.select.selectedIndex + 1;

      switch (event.keyCode) {
        case _unicode.KEY_CODES.ARROW_UP:
          if (previousOptionIndex >= 0) {
            this.select[previousOptionIndex].selected = true;
          }

          (0, _event.stopImmediatePropagation)(event);
          event.preventDefault();
          break;

        case _unicode.KEY_CODES.ARROW_DOWN:
          if (nextOptionIndex <= this.select.length - 1) {
            this.select[nextOptionIndex].selected = true;
          }

          (0, _event.stopImmediatePropagation)(event);
          event.preventDefault();
          break;

        default:
          break;
      }
    }
  }]);
  return SelectEditor;
}(_baseEditor.default);

var _default = SelectEditor;
exports.default = _default;

/***/ }),
/* 547 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

/**
 * Adds appropriate CSS class to table cell, based on cellProperties
 */
function cellDecorator(instance, TD, row, col, prop, value, cellProperties) {
  var classesToAdd = [];
  var classesToRemove = [];

  if (cellProperties.className) {
    if (TD.className) {
      TD.className = "".concat(TD.className, " ").concat(cellProperties.className);
    } else {
      TD.className = cellProperties.className;
    }
  }

  if (cellProperties.readOnly) {
    classesToAdd.push(cellProperties.readOnlyCellClassName);
  }

  if (cellProperties.valid === false && cellProperties.invalidCellClassName) {
    classesToAdd.push(cellProperties.invalidCellClassName);
  } else {
    classesToRemove.push(cellProperties.invalidCellClassName);
  }

  if (cellProperties.wordWrap === false && cellProperties.noWordWrapClassName) {
    classesToAdd.push(cellProperties.noWordWrapClassName);
  }

  if (!value && cellProperties.placeholder) {
    classesToAdd.push(cellProperties.placeholderCellClassName);
  }

  (0, _element.removeClass)(TD, classesToRemove);
  (0, _element.addClass)(TD, classesToAdd);
}

var _default = cellDecorator;
exports.default = _default;

/***/ }),
/* 548 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _src = __webpack_require__(25);

var _index = __webpack_require__(41);

/**
 * Autocomplete renderer
 *
 * @private
 * @renderer AutocompleteRenderer
 * @param {Object} instance Handsontable instance
 * @param {Element} TD Table cell where to render
 * @param {Number} row
 * @param {Number} col
 * @param {String|Number} prop Row object property name
 * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
 * @param {Object} cellProperties Cell properites (shared by cell renderer and editor)
 */
function autocompleteRenderer(instance, TD, row, col, prop, value, cellProperties) {
  var rootDocument = instance.rootDocument;
  var rendererType = cellProperties.allowHtml ? 'html' : 'text';
  var ARROW = rootDocument.createElement('DIV');
  ARROW.className = 'htAutocompleteArrow';
  ARROW.appendChild(rootDocument.createTextNode(String.fromCharCode(9660)));

  for (var _len = arguments.length, args = new Array(_len > 7 ? _len - 7 : 0), _key = 7; _key < _len; _key++) {
    args[_key - 7] = arguments[_key];
  }

  (0, _index.getRenderer)(rendererType).apply(this, [instance, TD, row, col, prop, value, cellProperties].concat(args));

  if (!TD.firstChild) {
    // http://jsperf.com/empty-node-if-needed
    // otherwise empty fields appear borderless in demo/renderers.html (IE)
    TD.appendChild(rootDocument.createTextNode(String.fromCharCode(160))); // workaround for https://github.com/handsontable/handsontable/issues/1946
    // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
  }

  TD.insertBefore(ARROW, TD.firstChild);
  (0, _element.addClass)(TD, 'htAutocomplete');

  if (!instance.acArrowListener) {
    var eventManager = new _eventManager.default(instance); // not very elegant but easy and fast

    instance.acArrowListener = function (event) {
      if ((0, _element.hasClass)(event.target, 'htAutocompleteArrow')) {
        instance.view.wt.getSetting('onCellDblClick', null, new _src.CellCoords(row, col), TD);
      }
    };

    eventManager.addEventListener(instance.rootElement, 'mousedown', instance.acArrowListener); // We need to unbind the listener after the table has been destroyed

    instance.addHookOnce('afterDestroy', function () {
      eventManager.destroy();
    });
  }
}

var _default = autocompleteRenderer;
exports.default = _default;

/***/ }),
/* 549 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

var _string = __webpack_require__(68);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _unicode = __webpack_require__(50);

var _function = __webpack_require__(75);

var _event = __webpack_require__(31);

var _index = __webpack_require__(41);

var isListeningKeyDownEvent = new WeakMap();
var isCheckboxListenerAdded = new WeakMap();
var BAD_VALUE_CLASS = 'htBadValue';
/**
 * Checkbox renderer
 *
 * @private
 * @param {Object} instance Handsontable instance
 * @param {Element} TD Table cell where to render
 * @param {Number} row
 * @param {Number} col
 * @param {String|Number} prop Row object property name
 * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
 * @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
 */

function checkboxRenderer(instance, TD, row, col, prop, value, cellProperties) {
  var rootDocument = instance.rootDocument;

  for (var _len = arguments.length, args = new Array(_len > 7 ? _len - 7 : 0), _key = 7; _key < _len; _key++) {
    args[_key - 7] = arguments[_key];
  }

  (0, _index.getRenderer)('base').apply(this, [instance, TD, row, col, prop, value, cellProperties].concat(args));
  registerEvents(instance);
  var input = createInput(rootDocument);
  var labelOptions = cellProperties.label;
  var badValue = false;

  if (typeof cellProperties.checkedTemplate === 'undefined') {
    cellProperties.checkedTemplate = true;
  }

  if (typeof cellProperties.uncheckedTemplate === 'undefined') {
    cellProperties.uncheckedTemplate = false;
  }

  (0, _element.empty)(TD); // TODO identify under what circumstances this line can be removed

  if (value === cellProperties.checkedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.checkedTemplate)) {
    input.checked = true;
  } else if (value === cellProperties.uncheckedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.uncheckedTemplate)) {
    input.checked = false;
  } else if (value === null) {
    // default value
    (0, _element.addClass)(input, 'noValue');
  } else {
    input.style.display = 'none';
    (0, _element.addClass)(input, BAD_VALUE_CLASS);
    badValue = true;
  }

  input.setAttribute('data-row', row);
  input.setAttribute('data-col', col);

  if (!badValue && labelOptions) {
    var labelText = '';

    if (labelOptions.value) {
      labelText = typeof labelOptions.value === 'function' ? labelOptions.value.call(this, row, col, prop, value) : labelOptions.value;
    } else if (labelOptions.property) {
      labelText = instance.getDataAtRowProp(row, labelOptions.property);
    }

    var label = createLabel(rootDocument, labelText);

    if (labelOptions.position === 'before') {
      label.appendChild(input);
    } else {
      label.insertBefore(input, label.firstChild);
    }

    input = label;
  }

  TD.appendChild(input);

  if (badValue) {
    TD.appendChild(rootDocument.createTextNode('#bad-value#'));
  }

  if (!isListeningKeyDownEvent.has(instance)) {
    isListeningKeyDownEvent.set(instance, true);
    instance.addHook('beforeKeyDown', onBeforeKeyDown);
  }
  /**
   * On before key down DOM listener.
   *
   * @private
   * @param {Event} event
   */


  function onBeforeKeyDown(event) {
    var toggleKeys = 'SPACE|ENTER';
    var switchOffKeys = 'DELETE|BACKSPACE';
    var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);

    if (!instance.getSettings().enterBeginsEditing && isKeyCode('ENTER')) {
      return;
    }

    if (isKeyCode("".concat(toggleKeys, "|").concat(switchOffKeys)) && !(0, _event.isImmediatePropagationStopped)(event)) {
      eachSelectedCheckboxCell(function () {
        (0, _event.stopImmediatePropagation)(event);
        event.preventDefault();
      });
    }

    if (isKeyCode(toggleKeys)) {
      changeSelectedCheckboxesState();
    }

    if (isKeyCode(switchOffKeys)) {
      changeSelectedCheckboxesState(true);
    }
  }
  /**
   * Change checkbox checked property
   *
   * @private
   * @param {Boolean} [uncheckCheckbox=false]
   */


  function changeSelectedCheckboxesState() {
    var uncheckCheckbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var selRange = instance.getSelectedRangeLast();

    if (!selRange) {
      return;
    }

    var _selRange$getTopLeftC = selRange.getTopLeftCorner(),
        startRow = _selRange$getTopLeftC.row,
        startColumn = _selRange$getTopLeftC.col;

    var _selRange$getBottomRi = selRange.getBottomRightCorner(),
        endRow = _selRange$getBottomRi.row,
        endColumn = _selRange$getBottomRi.col;

    var changes = [];

    for (var visualRow = startRow; visualRow <= endRow; visualRow += 1) {
      for (var visualColumn = startColumn; visualColumn <= endColumn; visualColumn += 1) {
        var cachedCellProperties = instance.getCellMeta(visualRow, visualColumn);

        if (cachedCellProperties.type !== 'checkbox') {
          return;
        }
        /* eslint-disable no-continue */


        if (cachedCellProperties.readOnly === true) {
          continue;
        }

        if (typeof cachedCellProperties.checkedTemplate === 'undefined') {
          cachedCellProperties.checkedTemplate = true;
        }

        if (typeof cachedCellProperties.uncheckedTemplate === 'undefined') {
          cachedCellProperties.uncheckedTemplate = false;
        }

        var dataAtCell = instance.getDataAtCell(visualRow, visualColumn);

        if (uncheckCheckbox === false) {
          if ([cachedCellProperties.checkedTemplate, cachedCellProperties.checkedTemplate.toString()].includes(dataAtCell)) {
            changes.push([visualRow, visualColumn, cachedCellProperties.uncheckedTemplate]);
          } else if ([cachedCellProperties.uncheckedTemplate, cachedCellProperties.uncheckedTemplate.toString(), null, void 0].includes(dataAtCell)) {
            changes.push([visualRow, visualColumn, cachedCellProperties.checkedTemplate]);
          }
        } else {
          changes.push([visualRow, visualColumn, cachedCellProperties.uncheckedTemplate]);
        }
      }
    }

    if (changes.length > 0) {
      instance.setDataAtCell(changes);
    }
  }
  /**
   * Call callback for each found selected cell with checkbox type.
   *
   * @private
   * @param {Function} callback
   */


  function eachSelectedCheckboxCell(callback) {
    var selRange = instance.getSelectedRangeLast();

    if (!selRange) {
      return;
    }

    var topLeft = selRange.getTopLeftCorner();
    var bottomRight = selRange.getBottomRightCorner();

    for (var visualRow = topLeft.row; visualRow <= bottomRight.row; visualRow++) {
      for (var visualColumn = topLeft.col; visualColumn <= bottomRight.col; visualColumn++) {
        var cachedCellProperties = instance.getCellMeta(visualRow, visualColumn);

        if (cachedCellProperties.type !== 'checkbox') {
          return;
        }

        var cell = instance.getCell(visualRow, visualColumn);

        if (cell === null || cell === void 0) {
          callback(visualRow, visualColumn, cachedCellProperties);
        } else {
          var checkboxes = cell.querySelectorAll('input[type=checkbox]');

          if (checkboxes.length > 0 && !cachedCellProperties.readOnly) {
            callback(checkboxes);
          }
        }
      }
    }
  }
}
/**
 * Register checkbox listeners.
 *
 * @param {Handsontable} instance Handsontable instance.
 * @returns {EventManager}
 */


function registerEvents(instance) {
  var eventManager = isCheckboxListenerAdded.get(instance);

  if (!eventManager) {
    var rootElement = instance.rootElement;
    eventManager = new _eventManager.default(instance);
    eventManager.addEventListener(rootElement, 'click', function (event) {
      return onClick(event, instance);
    });
    eventManager.addEventListener(rootElement, 'mouseup', function (event) {
      return onMouseUp(event, instance);
    });
    eventManager.addEventListener(rootElement, 'change', function (event) {
      return onChange(event, instance);
    });
    isCheckboxListenerAdded.set(instance, eventManager);
  }

  return eventManager;
}
/**
 * Create input element.
 *
 * @param {Document} rootDocument
 * @returns {Node}
 */


function createInput(rootDocument) {
  var input = rootDocument.createElement('input');
  input.className = 'htCheckboxRendererInput';
  input.type = 'checkbox';
  input.setAttribute('autocomplete', 'off');
  input.setAttribute('tabindex', '-1');
  return input.cloneNode(false);
}
/**
 * Create label element.
 *
 * @param {Document} rootDocument
 * @param {String} text
 * @returns {Node}
 */


function createLabel(rootDocument, text) {
  var label = rootDocument.createElement('label');
  label.className = 'htCheckboxRendererLabel';
  label.appendChild(rootDocument.createTextNode(text));
  return label.cloneNode(true);
}
/**
 * `mouseup` callback.
 *
 * @private
 * @param {Event} event `mouseup` event.
 * @param {Object} instance Handsontable instance.
 */


function onMouseUp(event, instance) {
  if (!isCheckboxInput(event.target)) {
    return;
  }

  setTimeout(instance.listen, 10);
}
/**
 * `click` callback.
 *
 * @private
 * @param {Event} event `click` event.
 * @param {Object} instance Handsontable instance.
 */


function onClick(event, instance) {
  if (!isCheckboxInput(event.target)) {
    return false;
  }

  var row = parseInt(event.target.getAttribute('data-row'), 10);
  var col = parseInt(event.target.getAttribute('data-col'), 10);
  var cellProperties = instance.getCellMeta(row, col);

  if (cellProperties.readOnly) {
    event.preventDefault();
  }
}
/**
 * `change` callback.
 *
 * @param {Event} event `change` event.
 * @param {Object} instance Handsontable instance.
 * @param {Object} cellProperties Reference to cell properties.
 * @returns {Boolean}
 */


function onChange(event, instance) {
  if (!isCheckboxInput(event.target)) {
    return false;
  }

  var row = parseInt(event.target.getAttribute('data-row'), 10);
  var col = parseInt(event.target.getAttribute('data-col'), 10);
  var cellProperties = instance.getCellMeta(row, col);

  if (!cellProperties.readOnly) {
    var newCheckboxValue = null;

    if (event.target.checked) {
      newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? true : cellProperties.checkedTemplate;
    } else {
      newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? false : cellProperties.uncheckedTemplate;
    }

    instance.setDataAtCell(row, col, newCheckboxValue);
  }
}
/**
 * Check if the provided element is the checkbox input.
 *
 * @private
 * @param {HTMLElement} element The element in question.
 * @returns {Boolean}
 */


function isCheckboxInput(element) {
  return element.tagName === 'INPUT' && element.getAttribute('type') === 'checkbox';
}

var _default = checkboxRenderer;
exports.default = _default;

/***/ }),
/* 550 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

var _index = __webpack_require__(41);

/**
 * @private
 * @renderer HtmlRenderer
 * @param instance
 * @param TD
 * @param row
 * @param col
 * @param prop
 * @param value
 * @param cellProperties
 */
function htmlRenderer(instance, TD, row, col, prop, value) {
  for (var _len = arguments.length, args = new Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) {
    args[_key - 6] = arguments[_key];
  }

  (0, _index.getRenderer)('base').apply(this, [instance, TD, row, col, prop, value].concat(args));
  (0, _element.fastInnerHTML)(TD, value === null || value === void 0 ? '' : value);
}

var _default = htmlRenderer;
exports.default = _default;

/***/ }),
/* 551 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(54);

__webpack_require__(37);

__webpack_require__(46);

exports.__esModule = true;
exports.default = void 0;

var _numbro = _interopRequireDefault(__webpack_require__(466));

var _index = __webpack_require__(41);

var _number = __webpack_require__(15);

/**
 * Numeric cell renderer
 *
 * @private
 * @renderer NumericRenderer
 * @param {Object} instance Handsontable instance
 * @param {Element} TD Table cell where to render
 * @param {Number} row
 * @param {Number} col
 * @param {String|Number} prop Row object property name
 * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
 * @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
 */
function numericRenderer(instance, TD, row, col, prop, value, cellProperties) {
  var newValue = value;

  if ((0, _number.isNumeric)(newValue)) {
    var numericFormat = cellProperties.numericFormat;
    var cellCulture = numericFormat && numericFormat.culture || '-';
    var cellFormatPattern = numericFormat && numericFormat.pattern;
    var className = cellProperties.className || '';
    var classArr = className.length ? className.split(' ') : [];

    if (typeof cellCulture !== 'undefined' && !_numbro.default.languages()[cellCulture]) {
      var shortTag = cellCulture.replace('-', '');
      var langData = _numbro.default.allLanguages ? _numbro.default.allLanguages[cellCulture] : _numbro.default[shortTag];

      if (langData) {
        _numbro.default.registerLanguage(langData);
      }
    }

    _numbro.default.setLanguage(cellCulture);

    newValue = (0, _numbro.default)(newValue).format(cellFormatPattern || '0');

    if (classArr.indexOf('htLeft') < 0 && classArr.indexOf('htCenter') < 0 && classArr.indexOf('htRight') < 0 && classArr.indexOf('htJustify') < 0) {
      classArr.push('htRight');
    }

    if (classArr.indexOf('htNumeric') < 0) {
      classArr.push('htNumeric');
    }

    cellProperties.className = classArr.join(' ');
  }

  (0, _index.getRenderer)('text')(instance, TD, row, col, prop, newValue, cellProperties);
}

var _default = numericRenderer;
exports.default = _default;

/***/ }),
/* 552 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

var _index = __webpack_require__(41);

var _number = __webpack_require__(15);

/**
 * @private
 * @renderer PasswordRenderer
 * @param instance
 * @param TD
 * @param row
 * @param col
 * @param prop
 * @param value
 * @param cellProperties
 */
function passwordRenderer(instance, TD, row, col, prop, value, cellProperties) {
  for (var _len = arguments.length, args = new Array(_len > 7 ? _len - 7 : 0), _key = 7; _key < _len; _key++) {
    args[_key - 7] = arguments[_key];
  }

  (0, _index.getRenderer)('text').apply(this, [instance, TD, row, col, prop, value, cellProperties].concat(args));
  var hashLength = cellProperties.hashLength || TD.innerHTML.length;
  var hashSymbol = cellProperties.hashSymbol || '*';
  var hash = '';
  (0, _number.rangeEach)(hashLength - 1, function () {
    hash += hashSymbol;
  });
  (0, _element.fastInnerHTML)(TD, hash);
}

var _default = passwordRenderer;
exports.default = _default;

/***/ }),
/* 553 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(37);

exports.__esModule = true;
exports.default = void 0;

var _element = __webpack_require__(5);

var _mixed = __webpack_require__(27);

var _index = __webpack_require__(41);

/**
 * Default text renderer
 *
 * @private
 * @renderer TextRenderer
 * @param {Object} instance Handsontable instance
 * @param {Element} TD Table cell where to render
 * @param {Number} row
 * @param {Number} col
 * @param {String|Number} prop Row object property name
 * @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
 * @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
 */
function textRenderer(instance, TD, row, col, prop, value, cellProperties) {
  for (var _len = arguments.length, args = new Array(_len > 7 ? _len - 7 : 0), _key = 7; _key < _len; _key++) {
    args[_key - 7] = arguments[_key];
  }

  (0, _index.getRenderer)('base').apply(this, [instance, TD, row, col, prop, value, cellProperties].concat(args));
  var escaped = value;

  if (!escaped && cellProperties.placeholder) {
    escaped = cellProperties.placeholder;
  }

  escaped = (0, _mixed.stringify)(escaped);

  if (!instance.getSettings().trimWhitespace) {
    escaped = escaped.replace(/ /g, String.fromCharCode(160));
  }

  if (cellProperties.rendererTemplate) {
    (0, _element.empty)(TD);
    var TEMPLATE = instance.rootDocument.createElement('TEMPLATE');
    TEMPLATE.setAttribute('bind', '{{}}');
    TEMPLATE.innerHTML = cellProperties.rendererTemplate;
    HTMLTemplateElement.decorate(TEMPLATE);
    TEMPLATE.model = instance.getSourceDataAtRow(row);
    TD.appendChild(TEMPLATE);
  } else {
    // this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
    (0, _element.fastInnerText)(TD, escaped);
  }
}

var _default = textRenderer;
exports.default = _default;

/***/ }),
/* 554 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = autocompleteValidator;

/**
 * Autocomplete cell validator.
 *
 * @private
 * @validator AutocompleteValidator
 * @param {*} value - Value of edited cell
 * @param {Function} callback - Callback called with validation result
 */
function autocompleteValidator(value, callback) {
  var valueToValidate = value;

  if (valueToValidate === null || valueToValidate === void 0) {
    valueToValidate = '';
  }

  if (this.allowEmpty && valueToValidate === '') {
    callback(true);
    return;
  }

  if (this.strict && this.source) {
    if (typeof this.source === 'function') {
      this.source(valueToValidate, process(valueToValidate, callback));
    } else {
      process(valueToValidate, callback)(this.source);
    }
  } else {
    callback(true);
  }
}
/**
 * Function responsible for validation of autocomplete value.
 *
 * @param {*} value - Value of edited cell
 * @param {Function} callback - Callback called with validation result
 */


function process(value, callback) {
  var originalVal = value;
  return function (source) {
    var found = false;

    for (var s = 0, slen = source.length; s < slen; s++) {
      if (originalVal === source[s]) {
        found = true; // perfect match

        break;
      }
    }

    callback(found);
  };
}

/***/ }),
/* 555 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(467);

exports.__esModule = true;
exports.default = dateValidator;
exports.correctFormat = correctFormat;

var _moment = _interopRequireDefault(__webpack_require__(63));

var _date = __webpack_require__(468);

var _editors = __webpack_require__(53);

/**
 * Date cell validator
 *
 * @private
 * @validator DateValidator
 * @param {*} value - Value of edited cell
 * @param {Function} callback - Callback called with validation result
 */
function dateValidator(value, callback) {
  var dateEditor = (0, _editors.getEditorInstance)('date', this.instance);
  var valueToValidate = value;
  var valid = true;

  if (valueToValidate === null || valueToValidate === void 0) {
    valueToValidate = '';
  }

  var isValidDate = (0, _moment.default)(new Date(valueToValidate)).isValid() || (0, _moment.default)(valueToValidate, this.dateFormat || dateEditor.defaultDateFormat, true).isValid(); // is it in the specified format

  var isValidFormat = (0, _moment.default)(valueToValidate, this.dateFormat || dateEditor.defaultDateFormat, true).isValid();

  if (this.allowEmpty && valueToValidate === '') {
    isValidDate = true;
    isValidFormat = true;
  }

  if (!isValidDate) {
    valid = false;
  }

  if (!isValidDate && isValidFormat) {
    valid = true;
  }

  if (isValidDate && !isValidFormat) {
    if (this.correctFormat === true) {
      // if format correction is enabled
      var correctedValue = correctFormat(valueToValidate, this.dateFormat);
      var row = this.instance.runHooks('unmodifyRow', this.row);
      var column = this.instance.runHooks('unmodifyCol', this.col);
      this.instance.setDataAtCell(row, column, correctedValue, 'dateValidator');
      valid = true;
    } else {
      valid = false;
    }
  }

  callback(valid);
}
/**
 * Format the given string using moment.js' format feature
 *
 * @param {String} value
 * @param {String} dateFormat
 * @returns {String}
 */


function correctFormat(value, dateFormat) {
  var dateFromDate = (0, _moment.default)((0, _date.getNormalizedDate)(value));
  var dateFromMoment = (0, _moment.default)(value, dateFormat);
  var isAlphanumeric = value.search(/[A-z]/g) > -1;
  var date;

  if (dateFromDate.isValid() && dateFromDate.format('x') === dateFromMoment.format('x') || !dateFromMoment.isValid() || isAlphanumeric) {
    date = dateFromDate;
  } else {
    date = dateFromMoment;
  }

  return date.format(dateFormat);
}

/***/ }),
/* 556 */
/***/ (function(module, exports) {

// `SameValue` abstract operation
// https://tc39.github.io/ecma262/#sec-samevalue
module.exports = Object.is || function is(x, y) {
  // eslint-disable-next-line no-self-compare
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};


/***/ }),
/* 557 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = numericValidator;

var _number = __webpack_require__(15);

/**
 * Numeric cell validator
 *
 * @private
 * @validator NumericValidator
 * @param {*} value - Value of edited cell
 * @param {*} callback - Callback called with validation result
 */
function numericValidator(value, callback) {
  var valueToValidate = value;

  if (valueToValidate === null || valueToValidate === void 0) {
    valueToValidate = '';
  }

  if (this.allowEmpty && valueToValidate === '') {
    callback(true);
  } else if (valueToValidate === '') {
    callback(false);
  } else {
    callback((0, _number.isNumeric)(value));
  }
}

/***/ }),
/* 558 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = timeValidator;

var _moment = _interopRequireDefault(__webpack_require__(63));

// Formats which are correctly parsed to time (supported by momentjs)
var STRICT_FORMATS = ['YYYY-MM-DDTHH:mm:ss.SSSZ', 'X', // Unix timestamp
'x' // Unix ms timestamp
];
/**
 * Time cell validator
 *
 * @private
 * @validator TimeValidator
 * @param {*} value - Value of edited cell
 * @param {Function} callback - Callback called with validation result
 */

function timeValidator(value, callback) {
  var timeFormat = this.timeFormat || 'h:mm:ss a';
  var valid = true;
  var valueToValidate = value;

  if (valueToValidate === null) {
    valueToValidate = '';
  }

  valueToValidate = /^\d{3,}$/.test(valueToValidate) ? parseInt(valueToValidate, 10) : valueToValidate;
  var twoDigitValue = /^\d{1,2}$/.test(valueToValidate);

  if (twoDigitValue) {
    valueToValidate += ':00';
  }

  var date = (0, _moment.default)(valueToValidate, STRICT_FORMATS, true).isValid() ? (0, _moment.default)(valueToValidate) : (0, _moment.default)(valueToValidate, timeFormat);
  var isValidTime = date.isValid(); // is it in the specified format

  var isValidFormat = (0, _moment.default)(valueToValidate, timeFormat, true).isValid() && !twoDigitValue;

  if (this.allowEmpty && valueToValidate === '') {
    isValidTime = true;
    isValidFormat = true;
  }

  if (!isValidTime) {
    valid = false;
  }

  if (!isValidTime && isValidFormat) {
    valid = true;
  }

  if (isValidTime && !isValidFormat) {
    if (this.correctFormat === true) {
      // if format correction is enabled
      var correctedValue = date.format(timeFormat);
      var row = this.instance.runHooks('unmodifyRow', this.row);
      var column = this.instance.runHooks('unmodifyCol', this.col);
      this.instance.setDataAtCell(row, column, correctedValue, 'timeValidator');
      valid = true;
    } else {
      valid = false;
    }
  }

  callback(valid);
}

/***/ }),
/* 559 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var CELL_TYPE = 'autocomplete';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
  validator: (0, _validators.getValidator)(CELL_TYPE)
};
exports.default = _default;

/***/ }),
/* 560 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var CELL_TYPE = 'checkbox';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  renderer: (0, _renderers.getRenderer)(CELL_TYPE)
};
exports.default = _default;

/***/ }),
/* 561 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var CELL_TYPE = 'date';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  // displays small gray arrow on right side of the cell
  renderer: (0, _renderers.getRenderer)('autocomplete'),
  validator: (0, _validators.getValidator)(CELL_TYPE)
};
exports.default = _default;

/***/ }),
/* 562 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var CELL_TYPE = 'dropdown';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  // displays small gray arrow on right side of the cell
  renderer: (0, _renderers.getRenderer)('autocomplete'),
  validator: (0, _validators.getValidator)('autocomplete')
};
exports.default = _default;

/***/ }),
/* 563 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var CELL_TYPE = 'handsontable';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  // displays small gray arrow on right side of the cell
  renderer: (0, _renderers.getRenderer)('autocomplete')
};
exports.default = _default;

/***/ }),
/* 564 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var CELL_TYPE = 'numeric';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
  validator: (0, _validators.getValidator)(CELL_TYPE),
  dataType: 'number'
};
exports.default = _default;

/***/ }),
/* 565 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var CELL_TYPE = 'password';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  renderer: (0, _renderers.getRenderer)(CELL_TYPE),
  copyable: false
};
exports.default = _default;

/***/ }),
/* 566 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var CELL_TYPE = 'text';
var _default = {
  editor: (0, _editors.getEditor)(CELL_TYPE),
  renderer: (0, _renderers.getRenderer)(CELL_TYPE)
};
exports.default = _default;

/***/ }),
/* 567 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _editors = __webpack_require__(53);

var _renderers = __webpack_require__(41);

var _validators = __webpack_require__(79);

var CELL_TYPE = 'time';
var _default = {
  editor: (0, _editors.getEditor)('text'),
  // displays small gray arrow on right side of the cell
  renderer: (0, _renderers.getRenderer)('text'),
  validator: (0, _validators.getValidator)(CELL_TYPE)
};
exports.default = _default;

/***/ }),
/* 568 */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(42);
var floor = Math.floor;

// `Number.isInteger` method implementation
// https://tc39.github.io/ecma262/#sec-number.isinteger
module.exports = function isInteger(it) {
  return !isObject(it) && isFinite(it) && floor(it) === it;
};


/***/ }),
/* 569 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var task = __webpack_require__(570);
var FORCED = !global.setImmediate || !global.clearImmediate;

__webpack_require__(22)({ global: true, bind: true, enumerable: true, forced: FORCED }, {
  setImmediate: task.set,
  clearImmediate: task.clear
});


/***/ }),
/* 570 */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(32);
var classof = __webpack_require__(77);
var bind = __webpack_require__(101);
var html = __webpack_require__(181);
var createElement = __webpack_require__(142);
var set = global.setImmediate;
var clear = global.clearImmediate;
var process = global.process;
var MessageChannel = global.MessageChannel;
var Dispatch = global.Dispatch;
var counter = 0;
var queue = {};
var ONREADYSTATECHANGE = 'onreadystatechange';
var defer, channel, port;

var run = function () {
  var id = +this;
  // eslint-disable-next-line no-prototype-builtins
  if (queue.hasOwnProperty(id)) {
    var fn = queue[id];
    delete queue[id];
    fn();
  }
};

var listener = function (event) {
  run.call(event.data);
};

// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if (!set || !clear) {
  set = function setImmediate(fn) {
    var args = [];
    var i = 1;
    while (arguments.length > i) args.push(arguments[i++]);
    queue[++counter] = function () {
      // eslint-disable-next-line no-new-func
      (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
    };
    defer(counter);
    return counter;
  };
  clear = function clearImmediate(id) {
    delete queue[id];
  };
  // Node.js 0.8-
  if (classof(process) == 'process') {
    defer = function (id) {
      process.nextTick(bind(run, id, 1));
    };
  // Sphere (JS game engine) Dispatch API
  } else if (Dispatch && Dispatch.now) {
    defer = function (id) {
      Dispatch.now(bind(run, id, 1));
    };
  // Browsers with MessageChannel, includes WebWorkers
  } else if (MessageChannel) {
    channel = new MessageChannel();
    port = channel.port2;
    channel.port1.onmessage = listener;
    defer = bind(port.postMessage, port, 1);
  // Browsers with postMessage, skip WebWorkers
  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
    defer = function (id) {
      global.postMessage(id + '', '*');
    };
    global.addEventListener('message', listener, false);
  // IE8-
  } else if (ONREADYSTATECHANGE in createElement('script')) {
    defer = function (id) {
      html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () {
        html.removeChild(this);
        run.call(id);
      };
    };
  // Rest old browsers
  } else {
    defer = function (id) {
      setTimeout(bind(run, id, 1), 0);
    };
  }
}

module.exports = {
  set: set,
  clear: clear
};


/***/ }),
/* 571 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(40);

__webpack_require__(64);

__webpack_require__(33);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(46);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _SheetClip = _interopRequireDefault(__webpack_require__(469));

var _data = __webpack_require__(132);

var _setting = __webpack_require__(162);

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _interval = _interopRequireDefault(__webpack_require__(572));

var _number = __webpack_require__(15);

var copyableLookup = (0, _data.cellMethodLookupFactory)('copyable', false);
/**
 * Utility class that gets and saves data from/to the data source using mapping of columns numbers to object property names
 * @todo refactor arguments of methods getRange, getText to be numbers (not objects)
 * @todo remove priv, GridSettings from object constructor
 *
 * @util
 * @class DataMap
 * @private
 */

var DataMap =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(DataMap, null, [{
    key: "DESTINATION_RENDERER",

    /**
     * @type {Number}
     */
    get: function get() {
      return 1;
    }
    /**
     * @type {Number}
     */

  }, {
    key: "DESTINATION_CLIPBOARD_GENERATOR",
    get: function get() {
      return 2;
    }
    /**
     * @param {Object} instance Instance of Handsontable
     * @param {*} priv
     * @param {GridSettings} GridSettings Grid settings
     */

  }]);

  function DataMap(instance, priv, GridSettings) {
    var _this = this;

    (0, _classCallCheck2.default)(this, DataMap);

    /**
     * Instance of {@link Handsontable}
     *
     * @private
     * @type {Handsontable}
     */
    this.instance = instance;
    /**
     * Private settings object.
     *
     * @private
     * @type {Object}
     */

    this.priv = priv;
    /**
     * Instance of {@link GridSettings}
     *
     * @private
     * @type {GridSettings}
     */

    this.GridSettings = GridSettings;
    /**
     * Reference to the original dataset.
     *
     * @type {*}
     */

    this.dataSource = this.instance.getSettings().data;
    /**
     * Cached rows number.
     *
     * @type {Number}
     */

    this.cachedLength = null;
    /**
     * Flag determines if the cache should be used.
     *
     * @type {Boolean}
     */

    this.skipCache = false;
    /**
     * Cached sourceData rows number.
     *
     * @type {Number}
     */

    this.latestSourceRowsCount = 0;
    /**
     * Generated schema based on the first row from the source data.
     *
     * @type {Object}
     */

    this.duckSchema = this.dataSource && this.dataSource[0] ? (0, _object.duckSchema)(this.dataSource[0]) : {};
    /**
     * Cached array of properties to columns.
     *
     * @type {Array}
     */

    this.colToPropCache = void 0;
    /**
     * Cached map of properties to columns.
     *
     * @type {Map}
     */

    this.propToColCache = void 0;
    this.createMap();
    /**
     * Instance of {@link Interval}
     *
     * @type {Interval}
     */

    this.interval = _interval.default.create(function () {
      return _this.clearLengthCache();
    }, '15fps');
    this.instance.addHook('skipLengthCache', function (delay) {
      return _this.onSkipLengthCache(delay);
    });
    this.onSkipLengthCache(500);
  }
  /**
   * Generates cache for property to and from column addressation.
   */


  (0, _createClass2.default)(DataMap, [{
    key: "createMap",
    value: function createMap() {
      var schema = this.getSchema();
      var i;

      if (typeof schema === 'undefined') {
        throw new Error('trying to create `columns` definition but you didn\'t provide `schema` nor `data`');
      }

      this.colToPropCache = [];
      this.propToColCache = new Map();
      var columns = this.instance.getSettings().columns;

      if (columns) {
        var maxCols = this.instance.getSettings().maxCols;
        var columnsLen = Math.min(maxCols, columns.length);
        var filteredIndex = 0;
        var columnsAsFunc = false;
        var schemaLen = (0, _object.deepObjectSize)(schema);

        if (typeof columns === 'function') {
          columnsLen = schemaLen > 0 ? schemaLen : this.instance.countSourceCols();
          columnsAsFunc = true;
        }

        for (i = 0; i < columnsLen; i++) {
          var column = columnsAsFunc ? columns(i) : columns[i];

          if ((0, _object.isObject)(column)) {
            if (typeof column.data !== 'undefined') {
              var index = columnsAsFunc ? filteredIndex : i;
              this.colToPropCache[index] = column.data;
              this.propToColCache.set(column.data, index);
            }

            filteredIndex += 1;
          }
        }
      } else {
        this.recursiveDuckColumns(schema);
      }
    }
    /**
     * Generates columns' translation cache.
     *
     * @param {Object} schema
     * @param {Number} lastCol
     * @param {Number} parent
     * @returns {Number}
     */

  }, {
    key: "recursiveDuckColumns",
    value: function recursiveDuckColumns(schema, lastCol, parent) {
      var _this2 = this;

      var lastColumn = lastCol;
      var propertyParent = parent;
      var prop;

      if (typeof lastColumn === 'undefined') {
        lastColumn = 0;
        propertyParent = '';
      }

      if ((0, _typeof2.default)(schema) === 'object' && !Array.isArray(schema)) {
        (0, _object.objectEach)(schema, function (value, key) {
          if (value === null) {
            prop = propertyParent + key;

            _this2.colToPropCache.push(prop);

            _this2.propToColCache.set(prop, lastColumn);

            lastColumn += 1;
          } else {
            lastColumn = _this2.recursiveDuckColumns(value, lastColumn, "".concat(key, "."));
          }
        });
      }

      return lastColumn;
    }
    /**
     * Returns property name that corresponds with the given column index.
     *
     * @param {Number} col Visual column index.
     * @returns {Number} Physical column index.
     */

  }, {
    key: "colToProp",
    value: function colToProp(col) {
      var physicalColumn = this.instance.toPhysicalColumn(col);

      if (!isNaN(physicalColumn) && this.colToPropCache && typeof this.colToPropCache[physicalColumn] !== 'undefined') {
        return this.colToPropCache[physicalColumn];
      }

      return physicalColumn;
    }
    /**
     * Translates property into visual column index.
     *
     * @param {Object} prop
     * @fires Hooks#modifyCol
     * @returns {Number}
     */

  }, {
    key: "propToCol",
    value: function propToCol(prop) {
      var col;

      if (typeof this.propToColCache.get(prop) === 'undefined') {
        col = prop;
      } else {
        col = this.propToColCache.get(prop);
      }

      col = this.instance.toVisualColumn(col);
      return col;
    }
    /**
     * Returns data's schema.
     *
     * @returns {Object}
     */

  }, {
    key: "getSchema",
    value: function getSchema() {
      var schema = this.instance.getSettings().dataSchema;

      if (schema) {
        if (typeof schema === 'function') {
          return schema();
        }

        return schema;
      }

      return this.duckSchema;
    }
    /**
     * Creates row at the bottom of the data array.
     *
     * @param {Number} [index] Physical index of the row before which the new row will be inserted.
     * @param {Number} [amount=1] An amount of rows to add.
     * @param {String} [source] Source of method call.
     * @fires Hooks#afterCreateRow
     * @returns {Number} Returns number of created rows.
     */

  }, {
    key: "createRow",
    value: function createRow(index) {
      var _this3 = this;

      var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var source = arguments.length > 2 ? arguments[2] : undefined;
      var numberOfCreatedRows = 0;
      var rowIndex = index;

      if (typeof rowIndex !== 'number' || rowIndex >= this.instance.countSourceRows()) {
        rowIndex = this.instance.countSourceRows();
      }

      var continueProcess = this.instance.runHooks('beforeCreateRow', rowIndex, amount, source);

      if (continueProcess === false) {
        return 0;
      }

      var maxRows = this.instance.getSettings().maxRows;
      var columnCount = this.instance.countCols();

      var _loop = function _loop() {
        var row = null;

        if (_this3.instance.dataType === 'array') {
          if (_this3.instance.getSettings().dataSchema) {
            // Clone template array
            row = (0, _object.deepClone)(_this3.getSchema());
          } else {
            row = [];
            /* eslint-disable no-loop-func */

            (0, _number.rangeEach)(columnCount - 1, function () {
              return row.push(null);
            });
          }
        } else if (_this3.instance.dataType === 'function') {
          row = _this3.instance.getSettings().dataSchema(rowIndex);
        } else {
          row = {};
          (0, _object.deepExtend)(row, _this3.getSchema());
        }

        if (rowIndex === _this3.instance.countSourceRows()) {
          _this3.dataSource.push(row);
        } else {
          _this3.spliceData(rowIndex, 0, row);
        }

        numberOfCreatedRows += 1;
      };

      while (numberOfCreatedRows < amount && this.instance.countSourceRows() < maxRows) {
        _loop();
      }

      this.instance.runHooks('afterCreateRow', rowIndex, numberOfCreatedRows, source);
      this.instance.forceFullRender = true; // used when data was changed

      return numberOfCreatedRows;
    }
    /**
     * Creates column at the right of the data array.
     *
     * @param {Number} [index] Visual index of the column before which the new column will be inserted
     * @param {Number} [amount=1] An amount of columns to add.
     * @param {String} [source] Source of method call.
     * @fires Hooks#afterCreateCol
     * @returns {Number} Returns number of created columns
     */

  }, {
    key: "createCol",
    value: function createCol(index) {
      var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var source = arguments.length > 2 ? arguments[2] : undefined;

      if (!this.instance.isColumnModificationAllowed()) {
        throw new Error('Cannot create new column. When data source in an object, ' + 'you can only have as much columns as defined in first data row, data schema or in the \'columns\' setting.' + 'If you want to be able to add new columns, you have to use array datasource.');
      }

      var rlen = this.instance.countSourceRows();
      var data = this.dataSource;
      var countColumns = this.instance.countCols();
      var columnIndex = typeof index !== 'number' || index >= countColumns ? countColumns : index;
      var numberOfCreatedCols = 0;
      var currentIndex;
      this.instance.runHooks('beforeCreateCol', columnIndex, amount, source);
      currentIndex = columnIndex;
      var maxCols = this.instance.getSettings().maxCols;

      while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) {
        var _constructor = (0, _setting.columnFactory)(this.GridSettings, this.priv.columnsSettingConflicts);

        if (typeof columnIndex !== 'number' || columnIndex >= this.instance.countCols()) {
          if (rlen > 0) {
            for (var r = 0; r < rlen; r++) {
              if (typeof data[r] === 'undefined') {
                data[r] = [];
              }

              data[r].push(null);
            }
          } else {
            data.push([null]);
          } // Add new column constructor


          this.priv.columnSettings.push(_constructor);
        } else {
          for (var row = 0; row < rlen; row++) {
            data[row].splice(currentIndex, 0, null);
          } // Add new column constructor at given index


          this.priv.columnSettings.splice(currentIndex, 0, _constructor);
        }

        numberOfCreatedCols += 1;
        currentIndex += 1;
      }

      this.instance.runHooks('afterCreateCol', columnIndex, numberOfCreatedCols, source);
      this.instance.forceFullRender = true; // used when data was changed

      return numberOfCreatedCols;
    }
    /**
     * Removes row from the data array.
     *
     * @param {Number} [index] Visual index of the row to be removed. If not provided, the last row will be removed
     * @param {Number} [amount=1] Amount of the rows to be removed. If not provided, one row will be removed
     * @param {String} [source] Source of method call.
     * @fires Hooks#beforeRemoveRow
     * @fires Hooks#afterRemoveRow
     */

  }, {
    key: "removeRow",
    value: function removeRow(index) {
      var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var source = arguments.length > 2 ? arguments[2] : undefined;
      var rowIndex = typeof index !== 'number' ? -amount : index;
      var rowsAmount = this.instance.runHooks('modifyRemovedAmount', amount, rowIndex);
      var sourceRowsLength = this.instance.countSourceRows();
      rowIndex = (sourceRowsLength + rowIndex) % sourceRowsLength;
      var logicRows = this.visualRowsToPhysical(rowIndex, rowsAmount);
      var actionWasNotCancelled = this.instance.runHooks('beforeRemoveRow', rowIndex, rowsAmount, logicRows, source);

      if (actionWasNotCancelled === false) {
        return;
      }

      var data = this.dataSource;
      var newData = this.filterData(rowIndex, rowsAmount);

      if (newData) {
        data.length = 0;
        Array.prototype.push.apply(data, newData);
      }

      this.instance.runHooks('afterRemoveRow', rowIndex, rowsAmount, logicRows, source);
      this.instance.forceFullRender = true; // used when data was changed
    }
    /**
     * Removes column from the data array.
     *
     * @param {Number} [index] Visual index of the column to be removed. If not provided, the last column will be removed
     * @param {Number} [amount=1] Amount of the columns to be removed. If not provided, one column will be removed
     * @param {String} [source] Source of method call.
     * @fires Hooks#beforeRemoveCol
     * @fires Hooks#afterRemoveCol
     */

  }, {
    key: "removeCol",
    value: function removeCol(index) {
      var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var source = arguments.length > 2 ? arguments[2] : undefined;

      if (this.instance.dataType === 'object' || this.instance.getSettings().columns) {
        throw new Error('cannot remove column with object data source or columns option specified');
      }

      var columnIndex = typeof index !== 'number' ? -amount : index;
      columnIndex = (this.instance.countCols() + columnIndex) % this.instance.countCols();
      var logicColumns = this.visualColumnsToPhysical(columnIndex, amount);
      var descendingLogicColumns = logicColumns.slice(0).sort(function (a, b) {
        return b - a;
      });
      var actionWasNotCancelled = this.instance.runHooks('beforeRemoveCol', columnIndex, amount, logicColumns, source);

      if (actionWasNotCancelled === false) {
        return;
      }

      var isTableUniform = true;
      var removedColumnsCount = descendingLogicColumns.length;
      var data = this.dataSource;

      for (var c = 0; c < removedColumnsCount; c++) {
        if (isTableUniform && logicColumns[0] !== logicColumns[c] - c) {
          isTableUniform = false;
        }
      }

      if (isTableUniform) {
        for (var r = 0, rlen = this.instance.countSourceRows(); r < rlen; r++) {
          data[r].splice(logicColumns[0], amount);
        }
      } else {
        for (var _r = 0, _rlen = this.instance.countSourceRows(); _r < _rlen; _r++) {
          for (var _c = 0; _c < removedColumnsCount; _c++) {
            data[_r].splice(descendingLogicColumns[_c], 1);
          }
        }

        for (var _c2 = 0; _c2 < removedColumnsCount; _c2++) {
          this.priv.columnSettings.splice(logicColumns[_c2], 1);
        }
      }

      this.instance.runHooks('afterRemoveCol', columnIndex, amount, logicColumns, source);
      this.instance.forceFullRender = true; // used when data was changed
    }
    /**
     * Add/Removes data from the column.
     *
     * @param {Number} col Physical index of column in which do you want to do splice
     * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
     * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
     * @param {Array} [elements]
     * @returns {Array} Returns removed portion of columns
     */

  }, {
    key: "spliceCol",
    value: function spliceCol(col, index, amount) {
      var colData = this.instance.getDataAtCol(col);
      var removed = colData.slice(index, index + amount);
      var after = colData.slice(index + amount);

      for (var _len = arguments.length, elements = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
        elements[_key - 3] = arguments[_key];
      }

      (0, _array.extendArray)(elements, after);
      var i = 0;

      while (i < amount) {
        elements.push(null); // add null in place of removed elements

        i += 1;
      }

      (0, _array.to2dArray)(elements);
      this.instance.populateFromArray(index, col, elements, null, null, 'spliceCol');
      return removed;
    }
    /**
     * Add/Removes data from the row.
     *
     * @param {Number} row Physical index of row in which do you want to do splice
     * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
     * @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
     * @param {Array} [elements]
     * @returns {Array} Returns removed portion of rows
     */

  }, {
    key: "spliceRow",
    value: function spliceRow(row, index, amount) {
      var rowData = this.instance.getSourceDataAtRow(row);
      var removed = rowData.slice(index, index + amount);
      var after = rowData.slice(index + amount);

      for (var _len2 = arguments.length, elements = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
        elements[_key2 - 3] = arguments[_key2];
      }

      (0, _array.extendArray)(elements, after);
      var i = 0;

      while (i < amount) {
        elements.push(null); // add null in place of removed elements

        i += 1;
      }

      this.instance.populateFromArray(row, index, [elements], null, null, 'spliceRow');
      return removed;
    }
    /**
     * Add/remove row(s) to/from the data source.
     *
     * @param {Number} index Physical index of the element to remove.
     * @param {Number} amount Number of rows to add/remove.
     * @param {Object} element Row to add.
     */

  }, {
    key: "spliceData",
    value: function spliceData(index, amount, element) {
      var continueSplicing = this.instance.runHooks('beforeDataSplice', index, amount, element);

      if (continueSplicing !== false) {
        this.dataSource.splice(index, amount, element);
      }
    }
    /**
     * Filter unwanted data elements from the data source.
     *
     * @param {Number} index Visual index of the element to remove.
     * @param {Number} amount Number of rows to add/remove.
     * @returns {Array}
     */

  }, {
    key: "filterData",
    value: function filterData(index, amount) {
      var physicalRows = this.visualRowsToPhysical(index, amount);
      var continueSplicing = this.instance.runHooks('beforeDataFilter', index, amount, physicalRows);

      if (continueSplicing !== false) {
        var newData = this.dataSource.filter(function (row, rowIndex) {
          return physicalRows.indexOf(rowIndex) === -1;
        });
        return newData;
      }
    }
    /**
     * Returns single value from the data array.
     *
     * @param {Number} row Visual row index.
     * @param {Number} prop
     * @returns {*}
     */

  }, {
    key: "get",
    value: function get(row, prop) {
      var physicalRow = this.instance.toPhysicalRow(row);
      var dataRow = this.dataSource[physicalRow]; // TODO: To remove, use 'modifyData' hook instead (see below)

      var modifiedRowData = this.instance.runHooks('modifyRowData', physicalRow);
      dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; //

      var value = null; // try to get value under property `prop` (includes dot)

      if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) {
        value = dataRow[prop];
      } else if (typeof prop === 'string' && prop.indexOf('.') > -1) {
        var sliced = prop.split('.');
        var out = dataRow;

        if (!out) {
          return null;
        }

        for (var i = 0, ilen = sliced.length; i < ilen; i++) {
          out = out[sliced[i]];

          if (typeof out === 'undefined') {
            return null;
          }
        }

        value = out;
      } else if (typeof prop === 'function') {
        /**
         *  allows for interacting with complex structures, for example
         *  d3/jQuery getter/setter properties:
         *
         *    {columns: [{
         *      data: function(row, value){
         *        if(arguments.length === 1){
         *          return row.property();
         *        }
         *        row.property(value);
         *      }
         *    }]}
         */
        value = prop(this.dataSource.slice(physicalRow, physicalRow + 1)[0]);
      }

      if (this.instance.hasHook('modifyData')) {
        var valueHolder = (0, _object.createObjectPropListener)(value);
        this.instance.runHooks('modifyData', physicalRow, this.propToCol(prop), valueHolder, 'get');

        if (valueHolder.isTouched()) {
          value = valueHolder.value;
        }
      }

      return value;
    }
    /**
     * Returns single value from the data array (intended for clipboard copy to an external application).
     *
     * @param {Number} row Physical row index.
     * @param {Number} prop
     * @returns {String}
     */

  }, {
    key: "getCopyable",
    value: function getCopyable(row, prop) {
      if (copyableLookup.call(this.instance, row, this.propToCol(prop))) {
        return this.get(row, prop);
      }

      return '';
    }
    /**
     * Saves single value to the data array.
     *
     * @param {Number} row Visual row index.
     * @param {Number} prop
     * @param {String} value
     * @param {String} [source] Source of hook runner.
     */

  }, {
    key: "set",
    value: function set(row, prop, value, source) {
      var physicalRow = this.instance.runHooks('modifyRow', row, source || 'datamapGet');
      var newValue = value;
      var dataRow = this.dataSource[physicalRow]; // TODO: To remove, use 'modifyData' hook instead (see below)

      var modifiedRowData = this.instance.runHooks('modifyRowData', physicalRow);
      dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow; //

      if (this.instance.hasHook('modifyData')) {
        var valueHolder = (0, _object.createObjectPropListener)(newValue);
        this.instance.runHooks('modifyData', physicalRow, this.propToCol(prop), valueHolder, 'set');

        if (valueHolder.isTouched()) {
          newValue = valueHolder.value;
        }
      } // try to set value under property `prop` (includes dot)


      if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) {
        dataRow[prop] = newValue;
      } else if (typeof prop === 'string' && prop.indexOf('.') > -1) {
        var sliced = prop.split('.');
        var out = dataRow;
        var i = 0;
        var ilen;

        for (i = 0, ilen = sliced.length - 1; i < ilen; i++) {
          if (typeof out[sliced[i]] === 'undefined') {
            out[sliced[i]] = {};
          }

          out = out[sliced[i]];
        }

        out[sliced[i]] = newValue;
      } else if (typeof prop === 'function') {
        /* see the `function` handler in `get` */
        prop(this.dataSource.slice(physicalRow, physicalRow + 1)[0], newValue);
      } else {
        dataRow[prop] = newValue;
      }
    }
    /**
     * This ridiculous piece of code maps rows Id that are present in table data to those displayed for user.
     * The trick is, the physical row id (stored in settings.data) is not necessary the same
     * as the visual (displayed) row id (e.g. when sorting is applied).
     *
     * @param {Number} index Visual row index.
     * @param {Number} amount
     * @fires Hooks#modifyRow
     * @returns {Number}
     */

  }, {
    key: "visualRowsToPhysical",
    value: function visualRowsToPhysical(index, amount) {
      var totalRows = this.instance.countSourceRows();
      var logicRows = [];
      var physicRow = (totalRows + index) % totalRows;
      var rowsToRemove = amount;
      var row;

      while (physicRow < totalRows && rowsToRemove) {
        row = this.instance.toPhysicalRow(physicRow);
        logicRows.push(row);
        rowsToRemove -= 1;
        physicRow += 1;
      }

      return logicRows;
    }
    /**
     *
     * @param index Visual column index.
     * @param amount
     * @returns {Array}
     */

  }, {
    key: "visualColumnsToPhysical",
    value: function visualColumnsToPhysical(index, amount) {
      var totalCols = this.instance.countCols();
      var visualCols = [];
      var physicalCol = (totalCols + index) % totalCols;
      var colsToRemove = amount;

      while (physicalCol < totalCols && colsToRemove) {
        var col = this.instance.toPhysicalColumn(physicalCol);
        visualCols.push(col);
        colsToRemove -= 1;
        physicalCol += 1;
      }

      return visualCols;
    }
    /**
     * Clears the data array.
     */

  }, {
    key: "clear",
    value: function clear() {
      for (var r = 0; r < this.instance.countSourceRows(); r++) {
        for (var c = 0; c < this.instance.countCols(); c++) {
          this.set(r, this.colToProp(c), '');
        }
      }
    }
    /**
     * Clear cached data length.
     */

  }, {
    key: "clearLengthCache",
    value: function clearLengthCache() {
      this.cachedLength = null;
    }
    /**
     * Get data length.
     *
     * @returns {Number}
     */

  }, {
    key: "getLength",
    value: function getLength() {
      var _this4 = this;

      var maxRowsFromSettings = this.instance.getSettings().maxRows;
      var maxRows;

      if (maxRowsFromSettings < 0 || maxRowsFromSettings === 0) {
        maxRows = 0;
      } else {
        maxRows = maxRowsFromSettings || Infinity;
      }

      var length = this.instance.countSourceRows();

      if (this.instance.hasHook('modifyRow')) {
        var reValidate = this.skipCache;
        this.interval.start();

        if (length !== this.latestSourceRowsCount) {
          reValidate = true;
        }

        this.latestSourceRowsCount = length;

        if (this.cachedLength === null || reValidate) {
          (0, _number.rangeEach)(length - 1, function (row) {
            var physicalRow = _this4.instance.toPhysicalRow(row);

            if (physicalRow === null) {
              length -= 1;
            }
          });
          this.cachedLength = length;
        } else {
          length = this.cachedLength;
        }
      } else {
        this.interval.stop();
      }

      return Math.min(length, maxRows);
    }
    /**
     * Returns the data array.
     *
     * @returns {Array}
     */

  }, {
    key: "getAll",
    value: function getAll() {
      var start = {
        row: 0,
        col: 0
      };
      var end = {
        row: Math.max(this.instance.countSourceRows() - 1, 0),
        col: Math.max(this.instance.countCols() - 1, 0)
      };

      if (start.row - end.row === 0 && !this.instance.countSourceRows()) {
        return [];
      }

      return this.getRange(start, end, DataMap.DESTINATION_RENDERER);
    }
    /**
     * Returns data range as array.
     *
     * @param {Object} [start] Start selection position. Visual indexes.
     * @param {Object} [end] End selection position. Visual indexes.
     * @param {Number} destination Destination of datamap.get
     * @returns {Array}
     */

  }, {
    key: "getRange",
    value: function getRange(start, end, destination) {
      var output = [];
      var r;
      var c;
      var row;
      var maxRows = this.instance.getSettings().maxRows;
      var maxCols = this.instance.getSettings().maxCols;

      if (maxRows === 0 || maxCols === 0) {
        return [];
      }

      var getFn = destination === DataMap.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get;
      var rlen = Math.min(Math.max(maxRows - 1, 0), Math.max(start.row, end.row));
      var clen = Math.min(Math.max(maxCols - 1, 0), Math.max(start.col, end.col));

      for (r = Math.min(start.row, end.row); r <= rlen; r++) {
        row = [];
        var physicalRow = this.instance.toPhysicalRow(r);

        for (c = Math.min(start.col, end.col); c <= clen; c++) {
          if (physicalRow === null) {
            break;
          }

          row.push(getFn.call(this, r, this.colToProp(c)));
        }

        if (physicalRow !== null) {
          output.push(row);
        }
      }

      return output;
    }
    /**
     * Return data as text (tab separated columns).
     *
     * @param {Object} [start] Start selection position. Visual indexes.
     * @param {Object} [end] End selection position. Visual indexes.
     * @returns {String}
     */

  }, {
    key: "getText",
    value: function getText(start, end) {
      return _SheetClip.default.stringify(this.getRange(start, end, DataMap.DESTINATION_RENDERER));
    }
    /**
     * Return data as copyable text (tab separated columns intended for clipboard copy to an external application).
     *
     * @param {Object} [start] Start selection position. Visual indexes.
     * @param {Object} [end] End selection position. Visual indexes.
     * @returns {String}
     */

  }, {
    key: "getCopyableText",
    value: function getCopyableText(start, end) {
      return _SheetClip.default.stringify(this.getRange(start, end, DataMap.DESTINATION_CLIPBOARD_GENERATOR));
    }
    /**
     * `skipLengthCache` callback.
     *
     * @private
     * @param {Number} delay Time of the delay in milliseconds.
     */

  }, {
    key: "onSkipLengthCache",
    value: function onSkipLengthCache(delay) {
      var _this5 = this;

      this.skipCache = true;
      setTimeout(function () {
        _this5.skipCache = false;
      }, delay);
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.interval.stop();
      this.interval = null;
      this.instance = null;
      this.priv = null;
      this.GridSettings = null;
      this.dataSource = null;
      this.cachedLength = null;
      this.duckSchema = null;
      this.colToPropCache.length = 0;
      this.propToColCache.clear();
      this.propToColCache = void 0;
    }
  }]);
  return DataMap;
}();

var _default = DataMap;
exports.default = _default;

/***/ }),
/* 572 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(37);

exports.__esModule = true;
exports.parseDelay = parseDelay;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _feature = __webpack_require__(73);

/**
 * @class Interval
 * @util
 */
var Interval =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(Interval, null, [{
    key: "create",
    value: function create(func, delay) {
      return new Interval(func, delay);
    }
  }]);

  function Interval(func, delay) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Interval);

    /**
     * Animation frame request id.
     *
     * @type {Number}
     */
    this.timer = null;
    /**
     * Function to invoke repeatedly.
     *
     * @type {Function}
     */

    this.func = func;
    /**
     * Number of milliseconds that function should wait before next call.
     */

    this.delay = parseDelay(delay);
    /**
     * Flag which indicates if interval object was stopped.
     *
     * @type {Boolean}
     * @default true
     */

    this.stopped = true;
    /**
     * Interval time (in milliseconds) of the last callback call.
     *
     * @private
     * @type {Number}
     */

    this._then = null;
    /**
     * Bounded function `func`.
     *
     * @private
     * @type {Function}
     */

    this._callback = function () {
      return _this.__callback();
    };
  }
  /**
   * Start loop.
   *
   * @returns {Interval}
   */


  (0, _createClass2.default)(Interval, [{
    key: "start",
    value: function start() {
      if (this.stopped) {
        this._then = Date.now();
        this.stopped = false;
        this.timer = (0, _feature.requestAnimationFrame)(this._callback);
      }

      return this;
    }
    /**
     * Stop looping.
     *
     * @returns {Interval}
     */

  }, {
    key: "stop",
    value: function stop() {
      if (!this.stopped) {
        this.stopped = true;
        (0, _feature.cancelAnimationFrame)(this.timer);
        this.timer = null;
      }

      return this;
    }
    /**
     * Loop callback, fired on every animation frame.
     *
     * @private
     */

  }, {
    key: "__callback",
    value: function __callback() {
      this.timer = (0, _feature.requestAnimationFrame)(this._callback);

      if (this.delay) {
        var now = Date.now();
        var elapsed = now - this._then;

        if (elapsed > this.delay) {
          this._then = now - elapsed % this.delay;
          this.func();
        }
      } else {
        this.func();
      }
    }
  }]);
  return Interval;
}();

var _default = Interval;
/**
 * Convert delay from string format to milliseconds.
 *
 * @param {Number|String} delay
 * @returns {Number}
 */

exports.default = _default;

function parseDelay(delay) {
  var result = delay;

  if (typeof result === 'string' && /fps$/.test(result)) {
    result = 1000 / parseInt(result.replace('fps', '') || 0, 10);
  }

  return result;
}

/***/ }),
/* 573 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _src = __webpack_require__(25);

var _unicode = __webpack_require__(50);

var _event = __webpack_require__(31);

var _editors = __webpack_require__(53);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _baseEditor = __webpack_require__(104);

var EditorManager =
/*#__PURE__*/
function () {
  /**
   * @param {Handsontable} instance
   * @param {GridSettings} priv
   * @param {Selection} selection
   */
  function EditorManager(instance, priv, selection) {
    var _this = this;

    (0, _classCallCheck2.default)(this, EditorManager);

    /**
     * Instance of {@link Handsontable}
     *
     * @private
     * @type {Handsontable}
     */
    this.instance = instance;
    /**
     * Reference to an instance's private GridSettings object.
     *
     * @private
     * @type {GridSettings}
     */

    this.priv = priv;
    /**
     * Instance of {@link Selection}
     *
     * @private
     * @type {Selection}
     */

    this.selection = selection;
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    this.eventManager = new _eventManager.default(instance);
    /**
     * Determines if EditorManager is destroyed.
     *
     * @private
     * @type {Boolean}
     */

    this.destroyed = false;
    /**
     * Determines if EditorManager is locked.
     *
     * @private
     * @type {Boolean}
     */

    this.lock = false;
    /**
     * A reference to an instance of the activeEditor.
     *
     * @private
     * @type {*}
     */

    this.activeEditor = void 0;
    this.instance.addHook('afterDocumentKeyDown', function (event) {
      return _this.onAfterDocumentKeyDown(event);
    });
    this.eventManager.addEventListener(this.instance.rootDocument.documentElement, 'keydown', function (event) {
      if (!_this.destroyed) {
        _this.instance.runHooks('afterDocumentKeyDown', event);
      }
    }); // Open editor when text composition is started (IME editor)

    this.eventManager.addEventListener(this.instance.rootDocument.documentElement, 'compositionstart', function (event) {
      if (!_this.destroyed && _this.activeEditor && !_this.activeEditor.isOpened() && _this.instance.isListening()) {
        _this.openEditor('', event);
      }
    });
    this.instance.view.wt.update('onCellDblClick', function (event, coords, elem) {
      return _this.onCellDblClick(event, coords, elem);
    });
  }
  /**
   * Lock the editor from being prepared and closed. Locking the editor prevents its closing and
   * reinitialized after selecting the new cell. This feature is necessary for a mobile editor.
   */


  (0, _createClass2.default)(EditorManager, [{
    key: "lockEditor",
    value: function lockEditor() {
      this.lock = true;
    }
    /**
     * Unlock the editor from being prepared and closed. This method restores the original behavior of
     * the editors where for every new selection its instances are closed.
     */

  }, {
    key: "unlockEditor",
    value: function unlockEditor() {
      this.lock = false;
    }
    /**
     * Destroy current editor, if exists.
     *
     * @param {Boolean} revertOriginal
     */

  }, {
    key: "destroyEditor",
    value: function destroyEditor(revertOriginal) {
      if (!this.lock) {
        this.closeEditor(revertOriginal);
      }
    }
    /**
     * Get active editor.
     *
     * @returns {*}
     */

  }, {
    key: "getActiveEditor",
    value: function getActiveEditor() {
      return this.activeEditor;
    }
    /**
     * Prepare text input to be displayed at given grid cell.
     */

  }, {
    key: "prepareEditor",
    value: function prepareEditor() {
      var _this2 = this;

      if (this.lock) {
        return;
      }

      if (this.activeEditor && this.activeEditor.isWaiting()) {
        this.closeEditor(false, false, function (dataSaved) {
          if (dataSaved) {
            _this2.prepareEditor();
          }
        });
        return;
      }

      var _this$instance$select = this.instance.selection.selectedRange.current().highlight,
          row = _this$instance$select.row,
          col = _this$instance$select.col;
      var prop = this.instance.colToProp(col);
      var td = this.instance.getCell(row, col);
      var originalValue = this.instance.getSourceDataAtCell(this.instance.runHooks('modifyRow', row), col);
      var cellProperties = this.instance.getCellMeta(row, col);
      var editorClass = this.instance.getCellEditor(cellProperties);

      if (editorClass) {
        this.activeEditor = (0, _editors.getEditorInstance)(editorClass, this.instance);
        this.activeEditor.prepare(row, col, prop, td, originalValue, cellProperties);
      } else {
        this.activeEditor = void 0;
      }
    }
    /**
     * Check is editor is opened/showed.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isEditorOpened",
    value: function isEditorOpened() {
      return this.activeEditor && this.activeEditor.isOpened();
    }
    /**
     * Open editor with initial value.
     *
     * @param {null|String} newInitialValue new value from which editor will start if handled property it's not the `null`.
     * @param {Event} event
     */

  }, {
    key: "openEditor",
    value: function openEditor(newInitialValue, event) {
      if (!this.activeEditor) {
        return;
      }

      var readOnly = this.activeEditor.cellProperties.readOnly;

      if (readOnly) {
        // move the selection after opening the editor with ENTER key
        if (event && event.keyCode === _unicode.KEY_CODES.ENTER) {
          this.moveSelectionAfterEnter();
        }
      } else {
        this.activeEditor.beginEditing(newInitialValue, event);
      }
    }
    /**
     * Close editor, finish editing cell.
     *
     * @param {Boolean} restoreOriginalValue
     * @param {Boolean} [isCtrlPressed]
     * @param {Function} [callback]
     */

  }, {
    key: "closeEditor",
    value: function closeEditor(restoreOriginalValue, isCtrlPressed, callback) {
      if (this.activeEditor) {
        this.activeEditor.finishEditing(restoreOriginalValue, isCtrlPressed, callback);
      } else if (callback) {
        callback(false);
      }
    }
    /**
     * Close editor and save changes.
     *
     * @param {Boolean} isCtrlPressed
     */

  }, {
    key: "closeEditorAndSaveChanges",
    value: function closeEditorAndSaveChanges(isCtrlPressed) {
      this.closeEditor(false, isCtrlPressed);
    }
    /**
     * Close editor and restore original value.
     *
     * @param {Boolean} isCtrlPressed
     */

  }, {
    key: "closeEditorAndRestoreOriginalValue",
    value: function closeEditorAndRestoreOriginalValue(isCtrlPressed) {
      return this.closeEditor(true, isCtrlPressed);
    }
    /**
     * Controls selection's behaviour after clicking `Enter`.
     *
     * @private
     * @param {Boolean} isShiftPressed
     */

  }, {
    key: "moveSelectionAfterEnter",
    value: function moveSelectionAfterEnter(isShiftPressed) {
      var enterMoves = typeof this.priv.settings.enterMoves === 'function' ? this.priv.settings.enterMoves(event) : this.priv.settings.enterMoves;

      if (isShiftPressed) {
        // move selection up
        this.selection.transformStart(-enterMoves.row, -enterMoves.col);
      } else {
        // move selection down (add a new row if needed)
        this.selection.transformStart(enterMoves.row, enterMoves.col, true);
      }
    }
    /**
     * Controls selection behaviour after clicking `arrow up`.
     *
     * @private
     * @param {Boolean} isShiftPressed
     */

  }, {
    key: "moveSelectionUp",
    value: function moveSelectionUp(isShiftPressed) {
      if (isShiftPressed) {
        this.selection.transformEnd(-1, 0);
      } else {
        this.selection.transformStart(-1, 0);
      }
    }
    /**
     * Controls selection's behaviour after clicking `arrow down`.
     *
     * @private
     * @param {Boolean} isShiftPressed
     */

  }, {
    key: "moveSelectionDown",
    value: function moveSelectionDown(isShiftPressed) {
      if (isShiftPressed) {
        // expanding selection down with shift
        this.selection.transformEnd(1, 0);
      } else {
        this.selection.transformStart(1, 0);
      }
    }
    /**
     * Controls selection's behaviour after clicking `arrow right`.
     *
     * @private
     * @param {Boolean} isShiftPressed
     */

  }, {
    key: "moveSelectionRight",
    value: function moveSelectionRight(isShiftPressed) {
      if (isShiftPressed) {
        this.selection.transformEnd(0, 1);
      } else {
        this.selection.transformStart(0, 1);
      }
    }
    /**
     * Controls selection's behaviour after clicking `arrow left`.
     *
     * @private
     * @param {Boolean} isShiftPressed
     */

  }, {
    key: "moveSelectionLeft",
    value: function moveSelectionLeft(isShiftPressed) {
      if (isShiftPressed) {
        this.selection.transformEnd(0, -1);
      } else {
        this.selection.transformStart(0, -1);
      }
    }
    /**
     * onAfterDocumentKeyDown callback.
     *
     * @private
     * @param {KeyboardEvent} event
     */

  }, {
    key: "onAfterDocumentKeyDown",
    value: function onAfterDocumentKeyDown(event) {
      if (!this.instance.isListening()) {
        return;
      }

      this.instance.runHooks('beforeKeyDown', event); // keyCode 229 aka 'uninitialized' doesn't take into account with editors. This key code is produced when unfinished
      // character is entering (using IME editor). It is fired mainly on linux (ubuntu) with installed ibus-pinyin package.

      if (this.destroyed || event.keyCode === 229) {
        return;
      }

      if ((0, _event.isImmediatePropagationStopped)(event)) {
        return;
      }

      this.priv.lastKeyCode = event.keyCode;

      if (!this.selection.isSelected()) {
        return;
      } // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)


      var isCtrlPressed = (event.ctrlKey || event.metaKey) && !event.altKey;

      if (this.activeEditor && !this.activeEditor.isWaiting()) {
        if (!(0, _unicode.isMetaKey)(event.keyCode) && !(0, _unicode.isCtrlMetaKey)(event.keyCode) && !isCtrlPressed && !this.isEditorOpened()) {
          this.openEditor('', event);
          return;
        }
      }

      var isShiftPressed = event.shiftKey;
      var rangeModifier = isShiftPressed ? this.selection.setRangeEnd : this.selection.setRangeStart;
      var tabMoves;

      switch (event.keyCode) {
        case _unicode.KEY_CODES.A:
          if (!this.isEditorOpened() && isCtrlPressed) {
            this.instance.selectAll();
            event.preventDefault();
            (0, _event.stopPropagation)(event);
          }

          break;

        case _unicode.KEY_CODES.ARROW_UP:
          if (this.isEditorOpened() && !this.activeEditor.isWaiting()) {
            this.closeEditorAndSaveChanges(isCtrlPressed);
          }

          this.moveSelectionUp(isShiftPressed);
          event.preventDefault();
          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.ARROW_DOWN:
          if (this.isEditorOpened() && !this.activeEditor.isWaiting()) {
            this.closeEditorAndSaveChanges(isCtrlPressed);
          }

          this.moveSelectionDown(isShiftPressed);
          event.preventDefault();
          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.ARROW_RIGHT:
          if (this.isEditorOpened() && !this.activeEditor.isWaiting()) {
            this.closeEditorAndSaveChanges(isCtrlPressed);
          }

          this.moveSelectionRight(isShiftPressed);
          event.preventDefault();
          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.ARROW_LEFT:
          if (this.isEditorOpened() && !this.activeEditor.isWaiting()) {
            this.closeEditorAndSaveChanges(isCtrlPressed);
          }

          this.moveSelectionLeft(isShiftPressed);
          event.preventDefault();
          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.TAB:
          tabMoves = typeof this.priv.settings.tabMoves === 'function' ? this.priv.settings.tabMoves(event) : this.priv.settings.tabMoves;

          if (isShiftPressed) {
            // move selection left
            this.selection.transformStart(-tabMoves.row, -tabMoves.col);
          } else {
            // move selection right (add a new column if needed)
            this.selection.transformStart(tabMoves.row, tabMoves.col, true);
          }

          event.preventDefault();
          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.BACKSPACE:
        case _unicode.KEY_CODES.DELETE:
          this.instance.emptySelectedCells();
          this.prepareEditor();
          event.preventDefault();
          break;

        case _unicode.KEY_CODES.F2:
          /* F2 */
          if (this.activeEditor) {
            this.activeEditor.enableFullEditMode();
          }

          this.openEditor(null, event);
          event.preventDefault(); // prevent Opera from opening 'Go to Page dialog'

          break;

        case _unicode.KEY_CODES.ENTER:
          /* return/enter */
          if (this.isEditorOpened()) {
            if (this.activeEditor && this.activeEditor.state !== _baseEditor.EditorState.WAITING) {
              this.closeEditorAndSaveChanges(isCtrlPressed);
            }

            this.moveSelectionAfterEnter(isShiftPressed);
          } else if (this.instance.getSettings().enterBeginsEditing) {
            if (this.activeEditor) {
              this.activeEditor.enableFullEditMode();
            }

            this.openEditor(null, event);
          } else {
            this.moveSelectionAfterEnter(isShiftPressed);
          }

          event.preventDefault(); // don't add newline to field

          (0, _event.stopImmediatePropagation)(event); // required by HandsontableEditor

          break;

        case _unicode.KEY_CODES.ESCAPE:
          if (this.isEditorOpened()) {
            this.closeEditorAndRestoreOriginalValue(isCtrlPressed);
            this.activeEditor.focus();
          }

          event.preventDefault();
          break;

        case _unicode.KEY_CODES.HOME:
          if (event.ctrlKey || event.metaKey) {
            rangeModifier.call(this.selection, new _src.CellCoords(0, this.selection.selectedRange.current().from.col));
          } else {
            rangeModifier.call(this.selection, new _src.CellCoords(this.selection.selectedRange.current().from.row, 0));
          }

          event.preventDefault(); // don't scroll the window

          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.END:
          if (event.ctrlKey || event.metaKey) {
            rangeModifier.call(this.selection, new _src.CellCoords(this.instance.countRows() - 1, this.selection.selectedRange.current().from.col));
          } else {
            rangeModifier.call(this.selection, new _src.CellCoords(this.selection.selectedRange.current().from.row, this.instance.countCols() - 1));
          }

          event.preventDefault(); // don't scroll the window

          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.PAGE_UP:
          this.selection.transformStart(-this.instance.countVisibleRows(), 0);
          event.preventDefault(); // don't page up the window

          (0, _event.stopPropagation)(event);
          break;

        case _unicode.KEY_CODES.PAGE_DOWN:
          this.selection.transformStart(this.instance.countVisibleRows(), 0);
          event.preventDefault(); // don't page down the window

          (0, _event.stopPropagation)(event);
          break;

        default:
          break;
      }
    }
    /**
     * onCellDblClick callback.
     *
     * @private
     * @param {MouseEvent} event
     * @param {Object} coords
     * @param {HTMLTableCellElement|HTMLTableHeaderCellElement} elem
     */

  }, {
    key: "onCellDblClick",
    value: function onCellDblClick(event, coords, elem) {
      // may be TD or TH
      if (elem.nodeName === 'TD') {
        if (this.activeEditor) {
          this.activeEditor.enableFullEditMode();
        }

        this.openEditor(null, event);
      }
    }
    /**
     * Destroy the instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.destroyed = true;
      this.eventManager.destroy();
    }
  }]);
  return EditorManager;
}();

var instances = new WeakMap();
/**
 * @param {Handsontable} hotInstance
 * @param {GridSettings} hotSettings
 * @param {Selection} selection
 * @param {DataMap} datamap
 */

EditorManager.getInstance = function (hotInstance, hotSettings, selection, datamap) {
  var editorManager = instances.get(hotInstance);

  if (!editorManager) {
    editorManager = new EditorManager(hotInstance, hotSettings, selection, datamap);
    instances.set(hotInstance, editorManager);
  }

  return editorManager;
};

var _default = EditorManager;
exports.default = _default;

/***/ }),
/* 574 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _event = __webpack_require__(31);

var _src = _interopRequireDefault(__webpack_require__(25));

var _mouseEventHandler = __webpack_require__(471);

var privatePool = new WeakMap();
/**
 * @class TableView
 * @private
 */

var TableView =
/*#__PURE__*/
function () {
  /**
   * @param {Hanstontable} instance Instance of {@link Handsontable}
   */
  function TableView(instance) {
    (0, _classCallCheck2.default)(this, TableView);

    /**
     * Instance of {@link Handsontable}
     *
     * @private
     * @type {Handsontable}
     */
    this.instance = instance;
    /**
     * Instance of {@link EventManager}
     *
     * @private
     * @type {EventManager}
     */

    this.eventManager = new _eventManager.default(instance);
    /**
     * Current Handsontable's GridSettings object.
     *
     * @private
     * @type {GridSettings}
     */

    this.settings = instance.getSettings();
    /**
     * Main <THEAD> element.
     *
     * @type {HTMLTableSectionElement}
     */

    this.THEAD = void 0;
    /**
     * Main <TBODY> element.
     *
     * @type {HTMLTableSectionElement}
     */

    this.TBODY = void 0;
    /**
     * Main Walkontable instance.
     *
     * @type {Walkontable}
     */

    this.wt = void 0;
    /**
     * Main Walkontable instance.
     *
     * @private
     * @type {Walkontable}
     */

    this.activeWt = void 0;
    privatePool.set(this, {
      /**
       * Defines if the text should be selected during mousemove.
       *
       * @private
       * @type {Boolean}
       */
      selectionMouseDown: false,

      /**
       * @private
       * @type {Boolean}
       */
      mouseDown: void 0,

      /**
       * Main <TABLE> element.
       *
       * @private
       * @type {HTMLTableElement}
       */
      table: void 0,

      /**
       * Cached width of the rootElement.
       *
       * @type {Number}
       */
      lastWidth: 0,

      /**
       * Cached height of the rootElement.
       *
       * @type {Number}
       */
      lastHeight: 0
    });
    this.createElements();
    this.registerEvents();
    this.initializeWalkontable();
  }
  /**
   * Renders WalkontableUI.
   */


  (0, _createClass2.default)(TableView, [{
    key: "render",
    value: function render() {
      this.wt.draw(!this.instance.forceFullRender);
      this.instance.forceFullRender = false;
      this.instance.renderCall = false;
    }
    /**
     * Returns td object given coordinates
     *
     * @param {CellCoords} coords
     * @param {Boolean} topmost
     * @returns {HTMLTableCellElement|null}
     */

  }, {
    key: "getCellAtCoords",
    value: function getCellAtCoords(coords, topmost) {
      var td = this.wt.getCell(coords, topmost);

      if (td < 0) {
        // there was an exit code (cell is out of bounds)
        return null;
      }

      return td;
    }
    /**
     * Scroll viewport to a cell.
     *
     * @param {CellCoords} coords
     * @param {Boolean} [snapToTop]
     * @param {Boolean} [snapToRight]
     * @param {Boolean} [snapToBottom]
     * @param {Boolean} [snapToLeft]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewport",
    value: function scrollViewport(coords, snapToTop, snapToRight, snapToBottom, snapToLeft) {
      return this.wt.scrollViewport(coords, snapToTop, snapToRight, snapToBottom, snapToLeft);
    }
    /**
     * Scroll viewport to a column.
     *
     * @param {Number} column Visual column index.
     * @param {Boolean} [snapToLeft]
     * @param {Boolean} [snapToRight]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportHorizontally",
    value: function scrollViewportHorizontally(column, snapToRight, snapToLeft) {
      return this.wt.scrollViewportHorizontally(column, snapToRight, snapToLeft);
    }
    /**
     * Scroll viewport to a row.
     *
     * @param {Number} row Visual row index.
     * @param {Boolean} [snapToTop]
     * @param {Boolean} [snapToBottom]
     * @returns {Boolean}
     */

  }, {
    key: "scrollViewportVertically",
    value: function scrollViewportVertically(row, snapToTop, snapToBottom) {
      return this.wt.scrollViewportVertically(row, snapToTop, snapToBottom);
    }
    /**
     * Updates header cell content.
     *
     * @since 0.15.0-beta4
     * @param {HTMLElement} element Element to update
     * @param {Number} index Row index or column index
     * @param {Function} content Function which should be returns content for this cell
     */

  }, {
    key: "updateCellHeader",
    value: function updateCellHeader(element, index, content) {
      var renderedIndex = index;
      var parentOverlay = this.wt.wtOverlays.getParentOverlay(element) || this.wt; // prevent wrong calculations from SampleGenerator

      if (element.parentNode) {
        if ((0, _element.hasClass)(element, 'colHeader')) {
          renderedIndex = parentOverlay.wtTable.columnFilter.sourceToRendered(index);
        } else if ((0, _element.hasClass)(element, 'rowHeader')) {
          renderedIndex = parentOverlay.wtTable.rowFilter.sourceToRendered(index);
        }
      }

      if (renderedIndex > -1) {
        (0, _element.fastInnerHTML)(element, content(index));
      } else {
        // workaround for https://github.com/handsontable/handsontable/issues/1946
        (0, _element.fastInnerText)(element, String.fromCharCode(160));
        (0, _element.addClass)(element, 'cornerHeader');
      }
    }
    /**
     * Prepares DOMElements and adds correct className to the root element.
     *
     * @private
     */

  }, {
    key: "createElements",
    value: function createElements() {
      var priv = privatePool.get(this);
      var _this$instance = this.instance,
          rootElement = _this$instance.rootElement,
          rootDocument = _this$instance.rootDocument;
      var originalStyle = rootElement.getAttribute('style');

      if (originalStyle) {
        rootElement.setAttribute('data-originalstyle', originalStyle); // needed to retrieve original style in jsFiddle link generator in HT examples. may be removed in future versions
      }

      (0, _element.addClass)(rootElement, 'handsontable');
      priv.table = rootDocument.createElement('TABLE');
      (0, _element.addClass)(priv.table, 'htCore');

      if (this.instance.getSettings().tableClassName) {
        (0, _element.addClass)(priv.table, this.instance.getSettings().tableClassName);
      }

      this.THEAD = rootDocument.createElement('THEAD');
      priv.table.appendChild(this.THEAD);
      this.TBODY = rootDocument.createElement('TBODY');
      priv.table.appendChild(this.TBODY);
      this.instance.table = priv.table;
      this.instance.container.insertBefore(priv.table, this.instance.container.firstChild);
    }
    /**
     * Attaches necessary listeners.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this = this;

      var priv = privatePool.get(this);
      var _this$instance2 = this.instance,
          rootElement = _this$instance2.rootElement,
          rootDocument = _this$instance2.rootDocument;
      var documentElement = rootDocument.documentElement;
      this.eventManager.addEventListener(rootElement, 'mousedown', function (event) {
        priv.selectionMouseDown = true;

        if (!_this.isTextSelectionAllowed(event.target)) {
          var rootWindow = _this.instance.rootWindow;
          (0, _element.clearTextSelection)(rootWindow);
          event.preventDefault();
          rootWindow.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
        }
      });
      this.eventManager.addEventListener(rootElement, 'mouseup', function () {
        priv.selectionMouseDown = false;
      });
      this.eventManager.addEventListener(rootElement, 'mousemove', function (event) {
        if (priv.selectionMouseDown && !_this.isTextSelectionAllowed(event.target)) {
          // Clear selection only when fragmentSelection is enabled, otherwise clearing selection breakes the IME editor.
          if (_this.settings.fragmentSelection) {
            (0, _element.clearTextSelection)(_this.instance.rootWindow);
          }

          event.preventDefault();
        }
      });
      this.eventManager.addEventListener(documentElement, 'keyup', function (event) {
        if (_this.instance.selection.isInProgress() && !event.shiftKey) {
          _this.instance.selection.finish();
        }
      });
      this.eventManager.addEventListener(documentElement, 'mouseup', function (event) {
        if (_this.instance.selection.isInProgress() && (0, _event.isLeftClick)(event)) {
          // is left mouse button
          _this.instance.selection.finish();
        }

        priv.mouseDown = false;

        if ((0, _element.isOutsideInput)(rootDocument.activeElement) || !_this.instance.selection.isSelected() && !(0, _event.isRightClick)(event)) {
          _this.instance.unlisten();
        }
      });
      this.eventManager.addEventListener(documentElement, 'contextmenu', function (event) {
        if (_this.instance.selection.isInProgress() && (0, _event.isRightClick)(event)) {
          _this.instance.selection.finish();

          priv.mouseDown = false;
        }
      });
      this.eventManager.addEventListener(documentElement, 'touchend', function () {
        if (_this.instance.selection.isInProgress()) {
          _this.instance.selection.finish();
        }

        priv.mouseDown = false;
      });
      this.eventManager.addEventListener(documentElement, 'mousedown', function (event) {
        var originalTarget = event.target;
        var eventX = event.x || event.clientX;
        var eventY = event.y || event.clientY;
        var next = event.target;

        if (priv.mouseDown || !rootElement || !_this.instance.view) {
          return; // it must have been started in a cell
        } // immediate click on "holder" means click on the right side of vertical scrollbar


        var holder = _this.instance.view.wt.wtTable.holder;

        if (next === holder) {
          var scrollbarWidth = (0, _element.getScrollbarWidth)(rootDocument);

          if (rootDocument.elementFromPoint(eventX + scrollbarWidth, eventY) !== holder || rootDocument.elementFromPoint(eventX, eventY + scrollbarWidth) !== holder) {
            return;
          }
        } else {
          while (next !== documentElement) {
            if (next === null) {
              if (event.isTargetWebComponent) {
                break;
              } // click on something that was a row but now is detached (possibly because your click triggered a rerender)


              return;
            }

            if (next === rootElement) {
              // click inside container
              return;
            }

            next = next.parentNode;
          }
        } // function did not return until here, we have an outside click!


        var outsideClickDeselects = typeof _this.settings.outsideClickDeselects === 'function' ? _this.settings.outsideClickDeselects(originalTarget) : _this.settings.outsideClickDeselects;

        if (outsideClickDeselects) {
          _this.instance.deselectCell();
        } else {
          _this.instance.destroyEditor(false, false);
        }
      });
      this.eventManager.addEventListener(priv.table, 'selectstart', function (event) {
        if (_this.settings.fragmentSelection || (0, _element.isInput)(event.target)) {
          return;
        } // https://github.com/handsontable/handsontable/issues/160
        // Prevent text from being selected when performing drag down.


        event.preventDefault();
      });
    }
    /**
     * Defines default configuration and initializes WalkOnTable intance.
     *
     * @private
     */

  }, {
    key: "initializeWalkontable",
    value: function initializeWalkontable() {
      var _this2 = this;

      var priv = privatePool.get(this);
      var walkontableConfig = {
        debug: function debug() {
          return _this2.settings.debug;
        },
        externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(),
        table: priv.table,
        preventOverflow: function preventOverflow() {
          return _this2.settings.preventOverflow;
        },
        stretchH: function stretchH() {
          return _this2.settings.stretchH;
        },
        data: this.instance.getDataAtCell,
        totalRows: function totalRows() {
          return _this2.instance.countRows();
        },
        totalColumns: function totalColumns() {
          return _this2.instance.countCols();
        },
        fixedColumnsLeft: function fixedColumnsLeft() {
          return _this2.settings.fixedColumnsLeft;
        },
        fixedRowsTop: function fixedRowsTop() {
          return _this2.settings.fixedRowsTop;
        },
        fixedRowsBottom: function fixedRowsBottom() {
          return _this2.settings.fixedRowsBottom;
        },
        minSpareRows: function minSpareRows() {
          return _this2.settings.minSpareRows;
        },
        renderAllRows: this.settings.renderAllRows,
        rowHeaders: function rowHeaders() {
          var headerRenderers = [];

          if (_this2.instance.hasRowHeaders()) {
            headerRenderers.push(function (row, TH) {
              return _this2.appendRowHeader(row, TH);
            });
          }

          _this2.instance.runHooks('afterGetRowHeaderRenderers', headerRenderers);

          return headerRenderers;
        },
        columnHeaders: function columnHeaders() {
          var headerRenderers = [];

          if (_this2.instance.hasColHeaders()) {
            headerRenderers.push(function (column, TH) {
              _this2.appendColHeader(column, TH);
            });
          }

          _this2.instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers);

          return headerRenderers;
        },
        columnWidth: this.instance.getColWidth,
        rowHeight: this.instance.getRowHeight,
        cellRenderer: function cellRenderer(row, col, TD) {
          var cellProperties = _this2.instance.getCellMeta(row, col);

          var prop = _this2.instance.colToProp(col);

          var value = _this2.instance.getDataAtRowProp(row, prop);

          if (_this2.instance.hasHook('beforeValueRender')) {
            value = _this2.instance.runHooks('beforeValueRender', value, cellProperties);
          }

          _this2.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties);

          _this2.instance.getCellRenderer(cellProperties)(_this2.instance, TD, row, col, prop, value, cellProperties);

          _this2.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties);
        },
        selections: this.instance.selection.highlight,
        hideBorderOnMouseDownOver: function hideBorderOnMouseDownOver() {
          return _this2.settings.fragmentSelection;
        },
        onWindowResize: function onWindowResize() {
          if (!_this2.instance || _this2.instance.isDestroyed) {
            return;
          }

          _this2.instance.refreshDimensions();
        },
        onCellMouseDown: function onCellMouseDown(event, coords, TD, wt) {
          var blockCalculations = {
            row: false,
            column: false,
            cell: false
          };

          _this2.instance.listen();

          _this2.activeWt = wt;
          priv.mouseDown = true;

          _this2.instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations);

          if ((0, _event.isImmediatePropagationStopped)(event)) {
            return;
          }

          (0, _mouseEventHandler.handleMouseEvent)(event, {
            coords: coords,
            selection: _this2.instance.selection,
            controller: blockCalculations
          });

          _this2.instance.runHooks('afterOnCellMouseDown', event, coords, TD);

          _this2.activeWt = _this2.wt;
        },
        onCellContextMenu: function onCellContextMenu(event, coords, TD, wt) {
          _this2.activeWt = wt;
          priv.mouseDown = false;

          if (_this2.instance.selection.isInProgress()) {
            _this2.instance.selection.finish();
          }

          _this2.instance.runHooks('beforeOnCellContextMenu', event, coords, TD);

          if ((0, _event.isImmediatePropagationStopped)(event)) {
            return;
          }

          _this2.instance.runHooks('afterOnCellContextMenu', event, coords, TD);

          _this2.activeWt = _this2.wt;
        },
        onCellMouseOut: function onCellMouseOut(event, coords, TD, wt) {
          _this2.activeWt = wt;

          _this2.instance.runHooks('beforeOnCellMouseOut', event, coords, TD);

          if ((0, _event.isImmediatePropagationStopped)(event)) {
            return;
          }

          _this2.instance.runHooks('afterOnCellMouseOut', event, coords, TD);

          _this2.activeWt = _this2.wt;
        },
        onCellMouseOver: function onCellMouseOver(event, coords, TD, wt) {
          var blockCalculations = {
            row: false,
            column: false,
            cell: false
          };
          _this2.activeWt = wt;

          _this2.instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations);

          if ((0, _event.isImmediatePropagationStopped)(event)) {
            return;
          }

          if (priv.mouseDown) {
            (0, _mouseEventHandler.handleMouseEvent)(event, {
              coords: coords,
              selection: _this2.instance.selection,
              controller: blockCalculations
            });
          }

          _this2.instance.runHooks('afterOnCellMouseOver', event, coords, TD);

          _this2.activeWt = _this2.wt;
        },
        onCellMouseUp: function onCellMouseUp(event, coords, TD, wt) {
          _this2.activeWt = wt;

          _this2.instance.runHooks('beforeOnCellMouseUp', event, coords, TD);

          _this2.instance.runHooks('afterOnCellMouseUp', event, coords, TD);

          _this2.activeWt = _this2.wt;
        },
        onCellCornerMouseDown: function onCellCornerMouseDown(event) {
          event.preventDefault();

          _this2.instance.runHooks('afterOnCellCornerMouseDown', event);
        },
        onCellCornerDblClick: function onCellCornerDblClick(event) {
          event.preventDefault();

          _this2.instance.runHooks('afterOnCellCornerDblClick', event);
        },
        beforeDraw: function beforeDraw(force, skipRender) {
          return _this2.beforeRender(force, skipRender);
        },
        onDraw: function onDraw(force) {
          return _this2.onDraw(force);
        },
        onScrollVertically: function onScrollVertically() {
          return _this2.instance.runHooks('afterScrollVertically');
        },
        onScrollHorizontally: function onScrollHorizontally() {
          return _this2.instance.runHooks('afterScrollHorizontally');
        },
        onBeforeRemoveCellClassNames: function onBeforeRemoveCellClassNames() {
          return _this2.instance.runHooks('beforeRemoveCellClassNames');
        },
        onAfterDrawSelection: function onAfterDrawSelection(currentRow, currentColumn, cornersOfSelection, layerLevel) {
          return _this2.instance.runHooks('afterDrawSelection', currentRow, currentColumn, cornersOfSelection, layerLevel);
        },
        onBeforeDrawBorders: function onBeforeDrawBorders(corners, borderClassName) {
          return _this2.instance.runHooks('beforeDrawBorders', corners, borderClassName);
        },
        onBeforeTouchScroll: function onBeforeTouchScroll() {
          return _this2.instance.runHooks('beforeTouchScroll');
        },
        onAfterMomentumScroll: function onAfterMomentumScroll() {
          return _this2.instance.runHooks('afterMomentumScroll');
        },
        onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(stretchedWidth, column) {
          return _this2.instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column);
        },
        onModifyRowHeaderWidth: function onModifyRowHeaderWidth(rowHeaderWidth) {
          return _this2.instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth);
        },
        onModifyGetCellCoords: function onModifyGetCellCoords(row, column, topmost) {
          return _this2.instance.runHooks('modifyGetCellCoords', row, column, topmost);
        },
        viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) {
          var rows = _this2.instance.countRows();

          var viewportOffset = _this2.settings.viewportRowRenderingOffset;

          if (viewportOffset === 'auto' && _this2.settings.fixedRowsTop) {
            viewportOffset = 10;
          }

          if (typeof viewportOffset === 'number') {
            calc.startRow = Math.max(calc.startRow - viewportOffset, 0);
            calc.endRow = Math.min(calc.endRow + viewportOffset, rows - 1);
          }

          if (viewportOffset === 'auto') {
            var center = calc.startRow + calc.endRow - calc.startRow;
            var offset = Math.ceil(center / rows * 12);
            calc.startRow = Math.max(calc.startRow - offset, 0);
            calc.endRow = Math.min(calc.endRow + offset, rows - 1);
          }

          _this2.instance.runHooks('afterViewportRowCalculatorOverride', calc);
        },
        viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) {
          var cols = _this2.instance.countCols();

          var viewportOffset = _this2.settings.viewportColumnRenderingOffset;

          if (viewportOffset === 'auto' && _this2.settings.fixedColumnsLeft) {
            viewportOffset = 10;
          }

          if (typeof viewportOffset === 'number') {
            calc.startColumn = Math.max(calc.startColumn - viewportOffset, 0);
            calc.endColumn = Math.min(calc.endColumn + viewportOffset, cols - 1);
          }

          if (viewportOffset === 'auto') {
            var center = calc.startColumn + calc.endColumn - calc.startColumn;
            var offset = Math.ceil(center / cols * 12);
            calc.startRow = Math.max(calc.startColumn - offset, 0);
            calc.endColumn = Math.min(calc.endColumn + offset, cols - 1);
          }

          _this2.instance.runHooks('afterViewportColumnCalculatorOverride', calc);
        },
        rowHeaderWidth: function rowHeaderWidth() {
          return _this2.settings.rowHeaderWidth;
        },
        columnHeaderHeight: function columnHeaderHeight() {
          var columnHeaderHeight = _this2.instance.runHooks('modifyColumnHeaderHeight');

          return _this2.settings.columnHeaderHeight || columnHeaderHeight;
        }
      };
      this.instance.runHooks('beforeInitWalkontable', walkontableConfig);
      this.wt = new _src.default(walkontableConfig);
      this.activeWt = this.wt;
      var spreader = this.wt.wtTable.spreader; // We have to cache width and height after Walkontable initialization.

      var _this$instance$rootEl = this.instance.rootElement.getBoundingClientRect(),
          width = _this$instance$rootEl.width,
          height = _this$instance$rootEl.height;

      this.setLastSize(width, height);
      this.eventManager.addEventListener(spreader, 'mousedown', function (event) {
        // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
        if (event.target === spreader && event.which === 3) {
          (0, _event.stopPropagation)(event);
        }
      });
      this.eventManager.addEventListener(spreader, 'contextmenu', function (event) {
        // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
        if (event.target === spreader && event.which === 3) {
          (0, _event.stopPropagation)(event);
        }
      });
      this.eventManager.addEventListener(this.instance.rootDocument.documentElement, 'click', function () {
        if (_this2.settings.observeDOMVisibility) {
          if (_this2.wt.drawInterrupted) {
            _this2.instance.forceFullRender = true;

            _this2.render();
          }
        }
      });
    }
    /**
     * Checks if it's possible to create text selection in element.
     *
     * @private
     * @param {HTMLElement} el
     * @returns {Boolean}
     */

  }, {
    key: "isTextSelectionAllowed",
    value: function isTextSelectionAllowed(el) {
      if ((0, _element.isInput)(el)) {
        return true;
      }

      var isChildOfTableBody = (0, _element.isChildOf)(el, this.instance.view.wt.wtTable.spreader);

      if (this.settings.fragmentSelection === true && isChildOfTableBody) {
        return true;
      }

      if (this.settings.fragmentSelection === 'cell' && this.isSelectedOnlyCell() && isChildOfTableBody) {
        return true;
      }

      if (!this.settings.fragmentSelection && this.isCellEdited() && this.isSelectedOnlyCell()) {
        return true;
      }

      return false;
    }
    /**
     * Checks if user's been called mousedown.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "isMouseDown",
    value: function isMouseDown() {
      return privatePool.get(this).mouseDown;
    }
    /**
     * Check if selected only one cell.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "isSelectedOnlyCell",
    value: function isSelectedOnlyCell() {
      var _ref = this.instance.getSelectedLast() || [],
          _ref2 = (0, _slicedToArray2.default)(_ref, 4),
          row = _ref2[0],
          col = _ref2[1],
          rowEnd = _ref2[2],
          colEnd = _ref2[3];

      return row !== void 0 && row === rowEnd && col === colEnd;
    }
    /**
     * Checks if active cell is editing.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "isCellEdited",
    value: function isCellEdited() {
      var activeEditor = this.instance.getActiveEditor();
      return activeEditor && activeEditor.isOpened();
    }
    /**
     * `beforeDraw` callback.
     *
     * @private
     * @param {Boolean} force
     * @param {Boolean} skipRender
     */

  }, {
    key: "beforeRender",
    value: function beforeRender(force, skipRender) {
      if (force) {
        // this.instance.forceFullRender = did Handsontable request full render?
        this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender);
      }
    }
    /**
     * `onDraw` callback.
     *
     * @private
     * @param {Boolean} force
     */

  }, {
    key: "onDraw",
    value: function onDraw(force) {
      if (force) {
        // this.instance.forceFullRender = did Handsontable request full render?
        this.instance.runHooks('afterRender', this.instance.forceFullRender);
      }
    }
    /**
     * Append row header to a TH element
     *
     * @private
     * @param row
     * @param TH
     */

  }, {
    key: "appendRowHeader",
    value: function appendRowHeader(row, TH) {
      if (TH.firstChild) {
        var container = TH.firstChild;

        if (!(0, _element.hasClass)(container, 'relative')) {
          (0, _element.empty)(TH);
          this.appendRowHeader(row, TH);
          return;
        }

        this.updateCellHeader(container.querySelector('.rowHeader'), row, this.instance.getRowHeader);
      } else {
        var _this$instance3 = this.instance,
            rootDocument = _this$instance3.rootDocument,
            getRowHeader = _this$instance3.getRowHeader;
        var div = rootDocument.createElement('div');
        var span = rootDocument.createElement('span');
        div.className = 'relative';
        span.className = 'rowHeader';
        this.updateCellHeader(span, row, getRowHeader);
        div.appendChild(span);
        TH.appendChild(div);
      }

      this.instance.runHooks('afterGetRowHeader', row, TH);
    }
    /**
     * Append column header to a TH element
     *
     * @private
     * @param col
     * @param TH
     */

  }, {
    key: "appendColHeader",
    value: function appendColHeader(col, TH) {
      if (TH.firstChild) {
        var container = TH.firstChild;

        if ((0, _element.hasClass)(container, 'relative')) {
          this.updateCellHeader(container.querySelector('.colHeader'), col, this.instance.getColHeader);
        } else {
          (0, _element.empty)(TH);
          this.appendColHeader(col, TH);
        }
      } else {
        var rootDocument = this.instance.rootDocument;
        var div = rootDocument.createElement('div');
        var span = rootDocument.createElement('span');
        div.className = 'relative';
        span.className = 'colHeader';
        this.updateCellHeader(span, col, this.instance.getColHeader);
        div.appendChild(span);
        TH.appendChild(div);
      }

      this.instance.runHooks('afterGetColHeader', col, TH);
    }
    /**
     * Given a element's left position relative to the viewport, returns maximum element width until the right
     * edge of the viewport (before scrollbar)
     *
     * @private
     * @param {Number} leftOffset
     * @return {Number}
     */

  }, {
    key: "maximumVisibleElementWidth",
    value: function maximumVisibleElementWidth(leftOffset) {
      var workspaceWidth = this.wt.wtViewport.getWorkspaceWidth();
      var maxWidth = workspaceWidth - leftOffset;
      return maxWidth > 0 ? maxWidth : 0;
    }
    /**
     * Given a element's top position relative to the viewport, returns maximum element height until the bottom
     * edge of the viewport (before scrollbar)
     *
     * @private
     * @param {Number} topOffset
     * @return {Number}
     */

  }, {
    key: "maximumVisibleElementHeight",
    value: function maximumVisibleElementHeight(topOffset) {
      var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight();
      var maxHeight = workspaceHeight - topOffset;
      return maxHeight > 0 ? maxHeight : 0;
    }
    /**
     * Sets new dimensions of the container.
     */

  }, {
    key: "setLastSize",
    value: function setLastSize(width, height) {
      var priv = privatePool.get(this);
      var _ref3 = [width, height];
      priv.lastWidth = _ref3[0];
      priv.lastHeight = _ref3[1];
    }
    /**
     * Returns cached dimensions.
     */

  }, {
    key: "getLastSize",
    value: function getLastSize() {
      var priv = privatePool.get(this);
      return {
        width: priv.lastWidth,
        height: priv.lastHeight
      };
    }
    /**
     * Checks if master overlay is active.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "mainViewIsActive",
    value: function mainViewIsActive() {
      return this.wt === this.activeWt;
    }
    /**
     * Destroyes internal WalkOnTable's instance. Detaches all of the bonded listeners.
     *
     * @private
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.wt.destroy();
      this.eventManager.destroy();
    }
  }]);
  return TableView;
}();

var _default = TableView;
exports.default = _default;

/***/ }),
/* 575 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(40);

__webpack_require__(76);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

/**
 * @class DataSource
 * @private
 */
var DataSource =
/*#__PURE__*/
function () {
  function DataSource(hotInstance) {
    var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    (0, _classCallCheck2.default)(this, DataSource);

    /**
     * Instance of Handsontable.
     *
     * @type {Handsontable}
     */
    this.hot = hotInstance;
    /**
     * Data source
     *
     * @type {Array}
     */

    this.data = dataSource;
    /**
     * Type of data source.
     *
     * @type {String}
     * @default 'array'
     */

    this.dataType = 'array';

    this.colToProp = function () {};

    this.propToCol = function () {};
  }
  /**
   * Get all data.
   *
   * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided
   *                                  in another format.
   * @returns {Array}
   */


  (0, _createClass2.default)(DataSource, [{
    key: "getData",
    value: function getData() {
      var toArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var result = this.data;

      if (toArray) {
        result = this.getByRange({
          row: 0,
          col: 0
        }, {
          row: Math.max(this.countRows() - 1, 0),
          col: Math.max(this.countColumns() - 1, 0)
        }, true);
      }

      return result;
    }
    /**
     * Set new data source.
     *
     * @param data {Array}
     */

  }, {
    key: "setData",
    value: function setData(data) {
      this.data = data;
    }
    /**
     * Returns array of column values from the data source. `column` is the index of the row in the data source.
     *
     * @param {Number} column Visual column index.
     * @returns {Array}
     */

  }, {
    key: "getAtColumn",
    value: function getAtColumn(column) {
      var _this = this;

      var result = [];
      (0, _array.arrayEach)(this.data, function (row) {
        var property = _this.colToProp(column);

        var value;

        if (typeof property === 'string') {
          value = (0, _object.getProperty)(row, property);
        } else if (typeof property === 'function') {
          value = property(row);
        } else {
          value = row[property];
        }

        result.push(value);
      });
      return result;
    }
    /**
     * Returns a single row of the data (array or object, depending on what you have). `row` is the index of the row in the data source.
     *
     * @param {Number} row Physical row index.
     * @returns {Array|Object}
     */

  }, {
    key: "getAtRow",
    value: function getAtRow(row) {
      return this.data[row];
    }
    /**
     * Returns a single value from the data.
     *
     * @param {Number} row Physical row index.
     * @param {Number} column Visual column index.
     * @returns {*}
     */

  }, {
    key: "getAtCell",
    value: function getAtCell(row, column) {
      var result = null;
      var modifyRowData = this.hot.runHooks('modifyRowData', row);
      var dataRow = isNaN(modifyRowData) ? modifyRowData : this.data[row];

      if (dataRow) {
        var prop = this.colToProp(column);

        if (typeof prop === 'string') {
          result = (0, _object.getProperty)(dataRow, prop);
        } else if (typeof prop === 'function') {
          result = prop(this.data.slice(row, row + 1)[0]);
        } else {
          result = dataRow[prop];
        }
      }

      return result;
    }
    /**
     * Returns source data by passed range.
     *
     * @param {Object} start Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects).
     * @param {Object} end Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects).
     * @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided
     *                                  in another format.
     * @returns {Array}
     */

  }, {
    key: "getByRange",
    value: function getByRange(start, end) {
      var _this2 = this;

      var toArray = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var startRow = Math.min(start.row, end.row);
      var startCol = Math.min(start.col, end.col);
      var endRow = Math.max(start.row, end.row);
      var endCol = Math.max(start.col, end.col);
      var result = [];
      (0, _number.rangeEach)(startRow, endRow, function (currentRow) {
        var row = _this2.getAtRow(currentRow);

        var newRow;

        if (_this2.dataType === 'array') {
          newRow = row.slice(startCol, endCol + 1);
        } else if (_this2.dataType === 'object') {
          newRow = toArray ? [] : {};
          (0, _number.rangeEach)(startCol, endCol, function (column) {
            var prop = _this2.colToProp(column);

            if (toArray) {
              newRow.push(row[prop]);
            } else {
              newRow[prop] = row[prop];
            }
          });
        }

        result.push(newRow);
      });
      return result;
    }
    /**
     * Count number of rows.
     *
     * @returns {Number}
     */

  }, {
    key: "countRows",
    value: function countRows() {
      return Array.isArray(this.data) ? this.data.length : 0;
    }
    /**
     * Count number of columns.
     *
     * @returns {Number}
     */

  }, {
    key: "countColumns",
    value: function countColumns() {
      var result = 0;

      if (Array.isArray(this.data)) {
        if (this.dataType === 'array') {
          result = this.data[0].length;
        } else if (this.dataType === 'object') {
          result = Object.keys(this.data[0]).length;
        }
      }

      return result;
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.data = null;
      this.hot = null;
    }
  }]);
  return DataSource;
}();

var _default = DataSource;
exports.default = _default;

/***/ }),
/* 576 */
/***/ (function(module, exports, __webpack_require__) {

var objectKeys = __webpack_require__(89);
var getOwnPropertySymbolsModule = __webpack_require__(119);
var propertyIsEnumerableModule = __webpack_require__(95);

// all enumerable object keys, includes symbols
module.exports = function (it) {
  var result = objectKeys(it);
  var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
  if (getOwnPropertySymbols) {
    var symbols = getOwnPropertySymbols(it);
    var propertyIsEnumerable = propertyIsEnumerableModule.f;
    var i = 0;
    var key;
    while (symbols.length > i) if (propertyIsEnumerable.call(it, key = symbols[i++])) result.push(key);
  } return result;
};


/***/ }),
/* 577 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var C = _interopRequireWildcard(__webpack_require__(11));

var _dictionary;

var dictionary = (_dictionary = {
  languageCode: 'en-US'
}, (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_NO_ITEMS, 'No available options'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ROW_ABOVE, 'Insert row above'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ROW_BELOW, 'Insert row below'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_INSERT_LEFT, 'Insert column left'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_INSERT_RIGHT, 'Insert column right'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_REMOVE_ROW, ['Remove row', 'Remove rows']), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_REMOVE_COLUMN, ['Remove column', 'Remove columns']), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_UNDO, 'Undo'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_REDO, 'Redo'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_READ_ONLY, 'Read only'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_CLEAR_COLUMN, 'Clear column'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT, 'Alignment'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT, 'Left'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER, 'Center'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT, 'Right'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY, 'Justify'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_TOP, 'Top'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE, 'Middle'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM, 'Bottom'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_FREEZE_COLUMN, 'Freeze column'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN, 'Unfreeze column'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_BORDERS, 'Borders'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_BORDERS_TOP, 'Top'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_BORDERS_RIGHT, 'Right'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_BORDERS_BOTTOM, 'Bottom'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_BORDERS_LEFT, 'Left'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_REMOVE_BORDERS, 'Remove border(s)'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_ADD_COMMENT, 'Add comment'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_EDIT_COMMENT, 'Edit comment'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_REMOVE_COMMENT, 'Delete comment'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT, 'Read-only comment'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_MERGE_CELLS, 'Merge cells'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_UNMERGE_CELLS, 'Unmerge cells'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_COPY, 'Copy'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_CUT, 'Cut'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD, 'Insert child row'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD, 'Detach from parent'), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_HIDE_COLUMN, ['Hide column', 'Hide columns']), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_SHOW_COLUMN, ['Show column', 'Show columns']), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_HIDE_ROW, ['Hide row', 'Hide rows']), (0, _defineProperty2.default)(_dictionary, C.CONTEXTMENU_ITEMS_SHOW_ROW, ['Show row', 'Show rows']), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_NONE, 'None'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_EMPTY, 'Is empty'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_NOT_EMPTY, 'Is not empty'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_EQUAL, 'Is equal to'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_NOT_EQUAL, 'Is not equal to'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_BEGINS_WITH, 'Begins with'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_ENDS_WITH, 'Ends with'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_CONTAINS, 'Contains'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_NOT_CONTAIN, 'Does not contain'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_GREATER_THAN, 'Greater than'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL, 'Greater than or equal to'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_LESS_THAN, 'Less than'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL, 'Less than or equal to'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_BETWEEN, 'Is between'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_NOT_BETWEEN, 'Is not between'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_AFTER, 'After'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_BEFORE, 'Before'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_TODAY, 'Today'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_TOMORROW, 'Tomorrow'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_CONDITIONS_YESTERDAY, 'Yesterday'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_VALUES_BLANK_CELLS, 'Blank cells'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_DIVS_FILTER_BY_CONDITION, 'Filter by condition'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_DIVS_FILTER_BY_VALUE, 'Filter by value'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_LABELS_CONJUNCTION, 'And'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_LABELS_DISJUNCTION, 'Or'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_SELECT_ALL, 'Select all'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_CLEAR, 'Clear'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_OK, 'OK'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_CANCEL, 'Cancel'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_PLACEHOLDER_SEARCH, 'Search'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_PLACEHOLDER_VALUE, 'Value'), (0, _defineProperty2.default)(_dictionary, C.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE, 'Second value'), _dictionary);
var _default = dictionary;
exports.default = _default;

/***/ }),
/* 578 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.registerPhraseFormatter = exports.register = register;
exports.getPhraseFormatters = exports.getAll = getAll;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _pluralize = _interopRequireDefault(__webpack_require__(579));

var _staticRegister = (0, _staticRegister2.default)('phraseFormatters'),
    registerGloballyPhraseFormatter = _staticRegister.register,
    getGlobalPhraseFormatters = _staticRegister.getValues;
/**
 * Register phrase formatter.
 *
 * @param {String} name Name of formatter.
 * @param {Function} formatterFn Function which will be applied on phrase propositions. It will transform them if it's possible.
 */


function register(name, formatterFn) {
  registerGloballyPhraseFormatter(name, formatterFn);
}
/**
 * Get all registered previously formatters.
 *
 * @returns {Array}
 */


function getAll() {
  return getGlobalPhraseFormatters();
}

register('pluralize', _pluralize.default);

/***/ }),
/* 579 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(80);

__webpack_require__(81);

exports.__esModule = true;
exports.default = pluralize;

/**
 * Try to choose plural form from available phrase propositions.
 *
 * @param {Array} phrasePropositions List of phrases propositions.
 * @param {number} pluralForm Number determining which phrase form should be used.
 *
 * @returns {String|Array} One particular phrase if it's possible, list of unchanged phrase propositions otherwise.
 */
function pluralize(phrasePropositions, pluralForm) {
  var isPluralizable = Array.isArray(phrasePropositions) && Number.isInteger(pluralForm);

  if (isPluralizable) {
    return phrasePropositions[pluralForm];
  }

  return phrasePropositions;
}

/***/ }),
/* 580 */
/***/ (function(module, exports, __webpack_require__) {

// `Array.prototype.fill` method
// https://tc39.github.io/ecma262/#sec-array.prototype.fill
__webpack_require__(22)({ target: 'Array', proto: true }, { fill: __webpack_require__(581) });

// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
__webpack_require__(121)('fill');


/***/ }),
/* 581 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toObject = __webpack_require__(62);
var toAbsoluteIndex = __webpack_require__(114);
var toLength = __webpack_require__(48);

// `Array.prototype.fill` method implementation
// https://tc39.github.io/ecma262/#sec-array.prototype.fill
module.exports = function fill(value /* , start = 0, end = @length */) {
  var O = toObject(this);
  var length = toLength(O.length);
  var argumentsLength = arguments.length;
  var index = toAbsoluteIndex(argumentsLength > 1 ? arguments[1] : undefined, length);
  var end = argumentsLength > 2 ? arguments[2] : undefined;
  var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
  while (endPos > index) O[index++] = value;
  return O;
};


/***/ }),
/* 582 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.createHighlight = createHighlight;

var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));

var _activeHeader = _interopRequireDefault(__webpack_require__(583));

var _area = _interopRequireDefault(__webpack_require__(584));

var _cell = _interopRequireDefault(__webpack_require__(585));

var _customSelection = _interopRequireDefault(__webpack_require__(586));

var _fill = _interopRequireDefault(__webpack_require__(587));

var _header = _interopRequireDefault(__webpack_require__(588));

/* eslint-disable import/prefer-default-export */
var _staticRegister = (0, _staticRegister2.default)('highlight/types'),
    register = _staticRegister.register,
    getItem = _staticRegister.getItem;

register('active-header', _activeHeader.default);
register('area', _area.default);
register('cell', _cell.default);
register('custom-selection', _customSelection.default);
register('fill', _fill.default);
register('header', _header.default);

function createHighlight(highlightType, options) {
  return getItem(highlightType)(options);
}

/***/ }),
/* 583 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * @return {Selection}
 */
function createHighlight(_ref) {
  var activeHeaderClassName = _ref.activeHeaderClassName;
  var s = new _src.Selection({
    highlightHeaderClassName: activeHeaderClassName
  });
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 584 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * Creates the new instance of Selection responsible for highlighting area of the selected multiple cells.
 *
 * @return {Selection}
 */
function createHighlight(_ref) {
  var layerLevel = _ref.layerLevel,
      areaCornerVisible = _ref.areaCornerVisible;
  var s = new _src.Selection({
    className: 'area',
    markIntersections: true,
    layerLevel: Math.min(layerLevel, 7),
    border: {
      width: 1,
      color: '#4b89ff',
      cornerVisible: areaCornerVisible
    }
  });
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 585 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * Creates the new instance of Selection responsible for highlighting currently selected cell. This type of selection
 * can present on the table only one at the time.
 *
 * @return {Selection}
 */
function createHighlight(_ref) {
  var cellCornerVisible = _ref.cellCornerVisible;
  var s = new _src.Selection({
    className: 'current',
    border: {
      width: 2,
      color: '#4b89ff',
      cornerVisible: cellCornerVisible
    }
  });
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 586 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * Creates the new instance of Selection responsible for highlighting currently selected cell. This type of selection
 * can present on the table only one at the time.
 *
 * @return {Selection}
 */
function createHighlight(_ref) {
  var border = _ref.border,
      cellRange = _ref.cellRange;
  var s = new _src.Selection(border, cellRange);
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 587 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * Creates the new instance of Selection, responsible for highlighting cells which are covered by fill handle
 * functionality. This type of selection can present on the table only one at the time.
 *
 * @return {Selection}
 */
function createHighlight() {
  var s = new _src.Selection({
    className: 'fill',
    border: {
      width: 1,
      color: '#ff0000'
    }
  });
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 588 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = void 0;

var _src = __webpack_require__(25);

/**
 * Creates the new instance of Selection, responsible for highlighting row and column headers. This type of selection
 * can occur multiple times.
 *
 * @return {Selection}
 */
function createHighlight(_ref) {
  var headerClassName = _ref.headerClassName,
      rowClassName = _ref.rowClassName,
      columnClassName = _ref.columnClassName;
  var s = new _src.Selection({
    className: 'highlight',
    highlightHeaderClassName: headerClassName,
    highlightRowClassName: rowClassName,
    highlightColumnClassName: columnClassName
  });
  return s;
}

var _default = createHighlight;
exports.default = _default;

/***/ }),
/* 589 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _highlight = _interopRequireWildcard(__webpack_require__(479));

var _range = _interopRequireDefault(__webpack_require__(590));

var _src = __webpack_require__(25);

var _keyStateObserver = __webpack_require__(136);

var _object = __webpack_require__(4);

var _mixed = __webpack_require__(27);

var _array = __webpack_require__(3);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _transformation = _interopRequireDefault(__webpack_require__(591));

var _utils = __webpack_require__(137);

var _templateLiteralTag = __webpack_require__(67);

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["Unsupported format of the selection ranges was passed. To select cells pass \n        the coordinates as an array of arrays ([[rowStart, columnStart/columnPropStart, rowEnd, columnEnd/columnPropEnd]]) \n        or as an array of CellRange objects."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * @class Selection
 * @util
 */
var Selection =
/*#__PURE__*/
function () {
  function Selection(settings, tableProps) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Selection);

    /**
     * Handsontable settings instance.
     *
     * @type {GridSettings}
     */
    this.settings = settings;
    /**
     * An additional object with dynamically defined properties which describes table state.
     *
     * @type {Object}
     */

    this.tableProps = tableProps;
    /**
     * The flag which determines if the selection is in progress.
     *
     * @type {Boolean}
     */

    this.inProgress = false;
    /**
     * The flag indicates that selection was performed by clicking the corner overlay.
     *
     * @type {Boolean}
     */

    this.selectedByCorner = false;
    /**
     * The collection of the selection layer levels where the whole row was selected using the row header.
     *
     * @type {Set.<Number>}
     */

    this.selectedByRowHeader = new Set();
    /**
     * The collection of the selection layer levels where the whole column was selected using the column header.
     *
     * @type {Set.<Number>}
     */

    this.selectedByColumnHeader = new Set();
    /**
     * Selection data layer.
     *
     * @type {SelectionRange}
     */

    this.selectedRange = new _range.default();
    /**
     * Visualization layer.
     *
     * @type {Highlight}
     */

    this.highlight = new _highlight.default({
      headerClassName: settings.currentHeaderClassName,
      activeHeaderClassName: settings.activeHeaderClassName,
      rowClassName: settings.currentRowClassName,
      columnClassName: settings.currentColClassName,
      disableHighlight: this.settings.disableVisualSelection,
      cellCornerVisible: function cellCornerVisible() {
        return _this.isCellCornerVisible.apply(_this, arguments);
      },
      areaCornerVisible: function areaCornerVisible() {
        return _this.isAreaCornerVisible.apply(_this, arguments);
      }
    });
    /**
     * The module for modifying coordinates.
     *
     * @type {Transformation}
     */

    this.transformation = new _transformation.default(this.selectedRange, {
      countRows: function countRows() {
        return _this.tableProps.countRows();
      },
      countCols: function countCols() {
        return _this.tableProps.countCols();
      },
      fixedRowsBottom: function fixedRowsBottom() {
        return settings.fixedRowsBottom;
      },
      minSpareRows: function minSpareRows() {
        return settings.minSpareRows;
      },
      minSpareCols: function minSpareCols() {
        return settings.minSpareCols;
      },
      autoWrapRow: function autoWrapRow() {
        return settings.autoWrapRow;
      },
      autoWrapCol: function autoWrapCol() {
        return settings.autoWrapCol;
      }
    });
    this.transformation.addLocalHook('beforeTransformStart', function () {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      return _this.runLocalHooks.apply(_this, ['beforeModifyTransformStart'].concat(args));
    });
    this.transformation.addLocalHook('afterTransformStart', function () {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }

      return _this.runLocalHooks.apply(_this, ['afterModifyTransformStart'].concat(args));
    });
    this.transformation.addLocalHook('beforeTransformEnd', function () {
      for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
        args[_key3] = arguments[_key3];
      }

      return _this.runLocalHooks.apply(_this, ['beforeModifyTransformEnd'].concat(args));
    });
    this.transformation.addLocalHook('afterTransformEnd', function () {
      for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
        args[_key4] = arguments[_key4];
      }

      return _this.runLocalHooks.apply(_this, ['afterModifyTransformEnd'].concat(args));
    });
    this.transformation.addLocalHook('insertRowRequire', function () {
      for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
        args[_key5] = arguments[_key5];
      }

      return _this.runLocalHooks.apply(_this, ['insertRowRequire'].concat(args));
    });
    this.transformation.addLocalHook('insertColRequire', function () {
      for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
        args[_key6] = arguments[_key6];
      }

      return _this.runLocalHooks.apply(_this, ['insertColRequire'].concat(args));
    });
  }
  /**
   * Get data layer for current selection.
   *
   * @return {SelectionRange}
   */


  (0, _createClass2.default)(Selection, [{
    key: "getSelectedRange",
    value: function getSelectedRange() {
      return this.selectedRange;
    }
    /**
     * Indicate that selection process began. It sets internaly `.inProgress` property to `true`.
     */

  }, {
    key: "begin",
    value: function begin() {
      this.inProgress = true;
    }
    /**
     * Indicate that selection process finished. It sets internaly `.inProgress` property to `false`.
     */

  }, {
    key: "finish",
    value: function finish() {
      this.runLocalHooks('afterSelectionFinished', Array.from(this.selectedRange));
      this.inProgress = false;
    }
    /**
     * Check if the process of selecting the cell/cells is in progress.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isInProgress",
    value: function isInProgress() {
      return this.inProgress;
    }
    /**
     * Starts selection range on given coordinate object.
     *
     * @param {CellCoords} coords Visual coords.
     * @param {Boolean} [multipleSelection] If `true`, selection will be worked in 'multiple' mode. This option works
     *                                      only when 'selectionMode' is set as 'multiple'. If the argument is not defined
     *                                      the default trigger will be used (isPressedCtrlKey() helper).
     * @param {Boolean} [fragment=false] If `true`, the selection will be treated as a partial selection where the
     *                                   `setRangeEnd` method won't be called on every `setRangeStart` call.
     */

  }, {
    key: "setRangeStart",
    value: function setRangeStart(coords, multipleSelection) {
      var fragment = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var isMultipleMode = this.settings.selectionMode === 'multiple';
      var isMultipleSelection = (0, _mixed.isUndefined)(multipleSelection) ? (0, _keyStateObserver.isPressedCtrlKey)() : multipleSelection;
      var isRowNegative = coords.row < 0;
      var isColumnNegative = coords.col < 0;
      var selectedByCorner = isRowNegative && isColumnNegative;

      if (isRowNegative) {
        coords.row = 0;
      }

      if (isColumnNegative) {
        coords.col = 0;
      }

      this.selectedByCorner = selectedByCorner;
      this.runLocalHooks("beforeSetRangeStart".concat(fragment ? 'Only' : ''), coords);

      if (!isMultipleMode || isMultipleMode && !isMultipleSelection && (0, _mixed.isUndefined)(multipleSelection)) {
        this.selectedRange.clear();
      }

      this.selectedRange.add(coords);

      if (this.getLayerLevel() === 0) {
        this.selectedByRowHeader.clear();
        this.selectedByColumnHeader.clear();
      }

      if (!selectedByCorner && isColumnNegative) {
        this.selectedByRowHeader.add(this.getLayerLevel());
      }

      if (!selectedByCorner && isRowNegative) {
        this.selectedByColumnHeader.add(this.getLayerLevel());
      }

      if (!fragment) {
        this.setRangeEnd(coords);
      }
    }
    /**
     * Starts selection range on given coordinate object.
     *
     * @param {CellCoords} coords Visual coords.
     * @param {Boolean} [multipleSelection] If `true`, selection will be worked in 'multiple' mode. This option works
     *                                      only when 'selectionMode' is set as 'multiple'. If the argument is not defined
     *                                      the default trigger will be used (isPressedCtrlKey() helper).
     */

  }, {
    key: "setRangeStartOnly",
    value: function setRangeStartOnly(coords, multipleSelection) {
      this.setRangeStart(coords, multipleSelection, true);
    }
    /**
     * Ends selection range on given coordinate object.
     *
     * @param {CellCoords} coords Visual coords.
     */

  }, {
    key: "setRangeEnd",
    value: function setRangeEnd(coords) {
      if (this.selectedRange.isEmpty()) {
        return;
      }

      this.runLocalHooks('beforeSetRangeEnd', coords);
      this.begin();
      var cellRange = this.selectedRange.current();

      if (this.settings.selectionMode !== 'single') {
        cellRange.setTo(new _src.CellCoords(coords.row, coords.col));
      } // Set up current selection.


      this.highlight.getCell().clear();

      if (this.highlight.isEnabledFor(_highlight.CELL_TYPE)) {
        this.highlight.getCell().add(this.selectedRange.current().highlight);
      }

      var layerLevel = this.getLayerLevel(); // If the next layer level is lower than previous then clear all area and header highlights. This is the
      // indication that the new selection is performing.

      if (layerLevel < this.highlight.layerLevel) {
        (0, _array.arrayEach)(this.highlight.getAreas(), function (highlight) {
          return void highlight.clear();
        });
        (0, _array.arrayEach)(this.highlight.getHeaders(), function (highlight) {
          return void highlight.clear();
        });
        (0, _array.arrayEach)(this.highlight.getActiveHeaders(), function (highlight) {
          return void highlight.clear();
        });
      }

      this.highlight.useLayerLevel(layerLevel);
      var areaHighlight = this.highlight.createOrGetArea();
      var headerHighlight = this.highlight.createOrGetHeader();
      var activeHeaderHighlight = this.highlight.createOrGetActiveHeader();
      areaHighlight.clear();
      headerHighlight.clear();
      activeHeaderHighlight.clear();

      if (this.highlight.isEnabledFor(_highlight.AREA_TYPE) && (this.isMultiple() || layerLevel >= 1)) {
        areaHighlight.add(cellRange.from).add(cellRange.to);

        if (layerLevel === 1) {
          // For single cell selection in the same layer, we do not create area selection to prevent blue background.
          // When non-consecutive selection is performed we have to add that missing area selection to the previous layer
          // based on previous coordinates. It only occurs when the previous selection wasn't select multiple cells.
          this.highlight.useLayerLevel(layerLevel - 1).createOrGetArea().add(this.selectedRange.previous().from);
          this.highlight.useLayerLevel(layerLevel);
        }
      }

      if (this.highlight.isEnabledFor(_highlight.HEADER_TYPE)) {
        if (this.settings.selectionMode === 'single') {
          headerHighlight.add(cellRange.highlight);
        } else {
          headerHighlight.add(cellRange.from).add(cellRange.to);
        }
      }

      if (this.isSelectedByRowHeader()) {
        var isRowSelected = this.tableProps.countCols() === cellRange.getWidth(); // Make sure that the whole row is selected (in case where selectionMode is set to 'single')

        if (isRowSelected) {
          activeHeaderHighlight.add(new _src.CellCoords(cellRange.from.row, -1)).add(new _src.CellCoords(cellRange.to.row, -1));
        }
      }

      if (this.isSelectedByColumnHeader()) {
        var isColumnSelected = this.tableProps.countRows() === cellRange.getHeight(); // Make sure that the whole column is selected (in case where selectionMode is set to 'single')

        if (isColumnSelected) {
          activeHeaderHighlight.add(new _src.CellCoords(-1, cellRange.from.col)).add(new _src.CellCoords(-1, cellRange.to.col));
        }
      }

      this.runLocalHooks('afterSetRangeEnd', coords);
    }
    /**
     * Returns information if we have a multiselection. This method check multiselection only on the latest layer of
     * the selection.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isMultiple",
    value: function isMultiple() {
      var isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
      this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
      return isMultipleListener.value;
    }
    /**
     * Selects cell relative to the current cell (if possible).
     *
     * @param {Number} rowDelta Rows number to move, value can be passed as negative number.
     * @param {Number} colDelta Columns number to move, value can be passed as negative number.
     * @param {Boolean} force If `true` the new rows/columns will be created if necessary. Otherwise, row/column will
     *                        be created according to `minSpareRows/minSpareCols` settings of Handsontable.
     */

  }, {
    key: "transformStart",
    value: function transformStart(rowDelta, colDelta, force) {
      this.setRangeStart(this.transformation.transformStart(rowDelta, colDelta, force));
    }
    /**
     * Sets selection end cell relative to the current selection end cell (if possible).
     *
     * @param {Number} rowDelta Rows number to move, value can be passed as negative number.
     * @param {Number} colDelta Columns number to move, value can be passed as negative number.
     */

  }, {
    key: "transformEnd",
    value: function transformEnd(rowDelta, colDelta) {
      this.setRangeEnd(this.transformation.transformEnd(rowDelta, colDelta));
    }
    /**
     * Returns currently used layer level.
     *
     * @return {Number} Returns layer level starting from 0. If no selection was added to the table -1 is returned.
     */

  }, {
    key: "getLayerLevel",
    value: function getLayerLevel() {
      return this.selectedRange.size() - 1;
    }
    /**
     * Returns `true` if currently there is a selection on the screen, `false` otherwise.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSelected",
    value: function isSelected() {
      return !this.selectedRange.isEmpty();
    }
    /**
     * Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
     * argument is passed then only that layer will be checked. Otherwise, it checks if any row header
     * was clicked on any selection layer level.
     *
     * @param {Number} [layerLevel=this.getLayerLevel()] Selection layer level to check.
     * @return {Boolean}
     */

  }, {
    key: "isSelectedByRowHeader",
    value: function isSelectedByRowHeader() {
      var layerLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getLayerLevel();
      return layerLevel === -1 ? this.selectedByRowHeader.size > 0 : this.selectedByRowHeader.has(layerLevel);
    }
    /**
     * Returns `true` if the selection was applied by clicking to the column header. If the `layerLevel`
     * argument is passed then only that layer will be checked. Otherwise, it checks if any column header
     * was clicked on any selection layer level.
     *
     * @param {Number} [layerLevel=this.getLayerLevel()] Selection layer level to check.
     * @return {Boolean}
     */

  }, {
    key: "isSelectedByColumnHeader",
    value: function isSelectedByColumnHeader() {
      var layerLevel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getLayerLevel();
      return layerLevel === -1 ? this.selectedByColumnHeader.size > 0 : this.selectedByColumnHeader.has(layerLevel);
    }
    /**
     * Returns `true` if the selection was applied by clicking on the row or column header on any layer level.
     *
     * @return {Boolean}
     */

  }, {
    key: "isSelectedByAnyHeader",
    value: function isSelectedByAnyHeader() {
      return this.isSelectedByRowHeader(-1) || this.isSelectedByColumnHeader(-1);
    }
    /**
     * Returns `true` if the selection was applied by clicking on the left-top corner overlay.
     *
     * @return {Boolean}
     */

  }, {
    key: "isSelectedByCorner",
    value: function isSelectedByCorner() {
      return this.selectedByCorner;
    }
    /**
     * Returns `true` if coords is within selection coords. This method iterates through all selection layers to check if
     * the coords object is within selection range.
     *
     * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
     * @returns {Boolean}
     */

  }, {
    key: "inInSelection",
    value: function inInSelection(coords) {
      return this.selectedRange.includes(coords);
    }
    /**
     * Returns `true` if the cell corner should be visible.
     *
     * @private
     * @return {Boolean} `true` if the corner element has to be visible, `false` otherwise.
     */

  }, {
    key: "isCellCornerVisible",
    value: function isCellCornerVisible() {
      return this.settings.fillHandle && !this.tableProps.isEditorOpened() && !this.isMultiple();
    }
    /**
     * Returns `true` if the area corner should be visible.
     *
     * @param {Number} layerLevel The layer level.
     * @return {Boolean} `true` if the corner element has to be visible, `false` otherwise.
     */

  }, {
    key: "isAreaCornerVisible",
    value: function isAreaCornerVisible(layerLevel) {
      if (Number.isInteger(layerLevel) && layerLevel !== this.getLayerLevel()) {
        return false;
      }

      return this.settings.fillHandle && !this.tableProps.isEditorOpened() && this.isMultiple();
    }
    /**
     * Clear the selection by resetting the collected ranges and highlights.
     */

  }, {
    key: "clear",
    value: function clear() {
      this.selectedRange.clear();
      this.highlight.clear();
    }
    /**
     * Deselects all selected cells.
     */

  }, {
    key: "deselect",
    value: function deselect() {
      if (!this.isSelected()) {
        return;
      }

      this.inProgress = false;
      this.clear();
      this.runLocalHooks('afterDeselect');
    }
    /**
     * Select all cells.
     */

  }, {
    key: "selectAll",
    value: function selectAll() {
      this.clear();
      this.setRangeStart(new _src.CellCoords(-1, -1));
      this.selectedByRowHeader.add(this.getLayerLevel());
      this.selectedByColumnHeader.add(this.getLayerLevel());
      this.setRangeEnd(new _src.CellCoords(this.tableProps.countRows() - 1, this.tableProps.countCols() - 1));
    }
    /**
     * Make multiple, non-contiguous selection specified by `row` and `column` values or a range of cells
     * finishing at `endRow`, `endColumn`. The method supports two input formats, first as an array of arrays such
     * as `[[rowStart, columnStart, rowEnd, columnEnd]]` and second format as an array of CellRange objects.
     * If the passed ranges have another format the exception will be thrown.
     *
     * @param {Array[]|CellRange[]} selectionRanges The coordinates which define what the cells should be selected.
     * @return {Boolean} Returns `true` if selection was successful, `false` otherwise.
     */

  }, {
    key: "selectCells",
    value: function selectCells(selectionRanges) {
      var _this2 = this;

      var selectionType = (0, _utils.detectSelectionType)(selectionRanges);

      if (selectionType === _utils.SELECTION_TYPE_EMPTY) {
        return false;
      } else if (selectionType === _utils.SELECTION_TYPE_UNRECOGNIZED) {
        throw new Error((0, _templateLiteralTag.toSingleLine)(_templateObject()));
      }

      var selectionSchemaNormalizer = (0, _utils.normalizeSelectionFactory)(selectionType, {
        propToCol: function propToCol(prop) {
          return _this2.tableProps.propToCol(prop);
        },
        keepDirection: true
      });
      var countRows = this.tableProps.countRows();
      var countCols = this.tableProps.countCols(); // Check if every layer of the coordinates are valid.

      var isValid = !selectionRanges.some(function (selection) {
        var _selectionSchemaNorma = selectionSchemaNormalizer(selection),
            _selectionSchemaNorma2 = (0, _slicedToArray2.default)(_selectionSchemaNorma, 4),
            rowStart = _selectionSchemaNorma2[0],
            columnStart = _selectionSchemaNorma2[1],
            rowEnd = _selectionSchemaNorma2[2],
            columnEnd = _selectionSchemaNorma2[3];

        var _isValid = (0, _utils.isValidCoord)(rowStart, countRows) && (0, _utils.isValidCoord)(columnStart, countCols) && (0, _utils.isValidCoord)(rowEnd, countRows) && (0, _utils.isValidCoord)(columnEnd, countCols);

        return !_isValid;
      });

      if (isValid) {
        this.clear();
        (0, _array.arrayEach)(selectionRanges, function (selection) {
          var _selectionSchemaNorma3 = selectionSchemaNormalizer(selection),
              _selectionSchemaNorma4 = (0, _slicedToArray2.default)(_selectionSchemaNorma3, 4),
              rowStart = _selectionSchemaNorma4[0],
              columnStart = _selectionSchemaNorma4[1],
              rowEnd = _selectionSchemaNorma4[2],
              columnEnd = _selectionSchemaNorma4[3];

          _this2.setRangeStartOnly(new _src.CellCoords(rowStart, columnStart), false);

          _this2.setRangeEnd(new _src.CellCoords(rowEnd, columnEnd));

          _this2.finish();
        });
      }

      return isValid;
    }
    /**
     * Select column specified by `startColumn` visual index or column property or a range of columns finishing at `endColumn`.
     *
     * @param {Number|String} startColumn Visual column index or column property from which the selection starts.
     * @param {Number|String} [endColumn] Visual column index or column property from to the selection finishes.
     * @returns {Boolean} Returns `true` if selection was successful, `false` otherwise.
     */

  }, {
    key: "selectColumns",
    value: function selectColumns(startColumn) {
      var endColumn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : startColumn;
      var start = typeof startColumn === 'string' ? this.tableProps.propToCol(startColumn) : startColumn;
      var end = typeof endColumn === 'string' ? this.tableProps.propToCol(endColumn) : endColumn;
      var countCols = this.tableProps.countCols();
      var isValid = (0, _utils.isValidCoord)(start, countCols) && (0, _utils.isValidCoord)(end, countCols);

      if (isValid) {
        this.setRangeStartOnly(new _src.CellCoords(-1, start));
        this.setRangeEnd(new _src.CellCoords(this.tableProps.countRows() - 1, end));
        this.finish();
      }

      return isValid;
    }
    /**
     * Select row specified by `startRow` visual index or a range of rows finishing at `endRow`.
     *
     * @param {Number} startRow Visual row index from which the selection starts.
     * @param {Number} [endRow] Visual row index from to the selection finishes.
     * @returns {Boolean} Returns `true` if selection was successful, `false` otherwise.
     */

  }, {
    key: "selectRows",
    value: function selectRows(startRow) {
      var endRow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : startRow;
      var countRows = this.tableProps.countRows();
      var isValid = (0, _utils.isValidCoord)(startRow, countRows) && (0, _utils.isValidCoord)(endRow, countRows);

      if (isValid) {
        this.setRangeStartOnly(new _src.CellCoords(startRow, -1));
        this.setRangeEnd(new _src.CellCoords(endRow, this.tableProps.countCols() - 1));
        this.finish();
      }

      return isValid;
    }
  }]);
  return Selection;
}();

(0, _object.mixin)(Selection, _localHooks.default);
var _default = Selection;
exports.default = _default;

/***/ }),
/* 590 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(133);

__webpack_require__(134);

__webpack_require__(480);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _src = __webpack_require__(25);

/**
 * The SelectionRange class is a simple CellRanges collection designed for easy manipulation of the multiple
 * consecutive and non-consecutive selections.
 *
 * @class SelectionRange
 * @util
 */
var SelectionRange =
/*#__PURE__*/
function () {
  function SelectionRange() {
    (0, _classCallCheck2.default)(this, SelectionRange);

    /**
     * List of all CellRanges added to the class instance.
     *
     * @type {CellRange[]}
     */
    this.ranges = [];
  }
  /**
   * Check if selected range is empty.
   *
   * @return {Boolean}
   */


  (0, _createClass2.default)(SelectionRange, [{
    key: "isEmpty",
    value: function isEmpty() {
      return this.size() === 0;
    }
    /**
     * Set coordinates to the class instance. It clears all previously added coordinates and push `coords`
     * to the collection.
     *
     * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
     * @returns {SelectionRange}
     */

  }, {
    key: "set",
    value: function set(coords) {
      this.clear();
      this.ranges.push(new _src.CellRange(coords));
      return this;
    }
    /**
     * Add coordinates to the class instance. The new coordinates are added to the end of the range collection.
     *
     * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
     * @returns {SelectionRange}
     */

  }, {
    key: "add",
    value: function add(coords) {
      this.ranges.push(new _src.CellRange(coords));
      return this;
    }
    /**
     * Get last added coordinates from ranges, it returns a CellRange instance.
     *
     * @return {CellRange|undefined}
     */

  }, {
    key: "current",
    value: function current() {
      return this.peekByIndex(0);
    }
    /**
     * Get previously added coordinates from ranges, it returns a CellRange instance.
     *
     * @return {CellRange|undefined}
     */

  }, {
    key: "previous",
    value: function previous() {
      return this.peekByIndex(-1);
    }
    /**
     * Returns `true` if coords is within selection coords. This method iterates through all selection layers to check if
     * the coords object is within selection range.
     *
     * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
     * @returns {Boolean}
     */

  }, {
    key: "includes",
    value: function includes(coords) {
      return this.ranges.some(function (cellRange) {
        return cellRange.includes(coords);
      });
    }
    /**
     * Clear collection.
     *
     * @return {SelectionRange}
     */

  }, {
    key: "clear",
    value: function clear() {
      this.ranges.length = 0;
      return this;
    }
    /**
     * Get count of added all coordinates added to the selection.
     *
     * @return {Number}
     */

  }, {
    key: "size",
    value: function size() {
      return this.ranges.length;
    }
    /**
     * Peek the coordinates based on the offset where that coordinate resides in the collection.
     *
     * @param {Number} [offset=0] An offset where the coordinate will be retrieved from.
     * @return {CellRange|undefined}
     */

  }, {
    key: "peekByIndex",
    value: function peekByIndex() {
      var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
      var rangeIndex = this.size() + offset - 1;
      var cellRange;

      if (rangeIndex >= 0) {
        cellRange = this.ranges[rangeIndex];
      }

      return cellRange;
    }
  }, {
    key: Symbol.iterator,
    value: function value() {
      return this.ranges[Symbol.iterator]();
    }
  }]);
  return SelectionRange;
}();

var _default = SelectionRange;
exports.default = _default;

/***/ }),
/* 591 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _src = __webpack_require__(25);

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

/**
 * The Transformation class implements algorithms for transforming coordinates based on current settings
 * passed to the Handsontable.
 *
 * Transformation is always applied relative to the current selection.
 *
 * @class Transformation
 * @util
 */
var Transformation =
/*#__PURE__*/
function () {
  function Transformation(range, options) {
    (0, _classCallCheck2.default)(this, Transformation);

    /**
     * Instance of the SelectionRange, holder for coordinates applied to the table.
     *
     * @type {SelectionRange}
     */
    this.range = range;
    /**
     * Additional options which define the state of the settings which can infer transformation.
     *
     * @type {Object}
     */

    this.options = options;
  }
  /**
   * Selects cell relative to current cell (if possible).
   *
   * @param {Number} rowDelta Rows number to move, value can be passed as negative number.
   * @param {Number} colDelta Columns number to move, value can be passed as negative number.
   * @param {Boolean} force If `true` the new rows/columns will be created if necessary. Otherwise, row/column will
   *                        be created according to `minSpareRows/minSpareCols` settings of Handsontable.
   * @returns {CellCoords}
   */


  (0, _createClass2.default)(Transformation, [{
    key: "transformStart",
    value: function transformStart(rowDelta, colDelta, force) {
      var delta = new _src.CellCoords(rowDelta, colDelta);
      this.runLocalHooks('beforeTransformStart', delta);
      var totalRows = this.options.countRows();
      var totalCols = this.options.countCols();
      var fixedRowsBottom = this.options.fixedRowsBottom();
      var minSpareRows = this.options.minSpareRows();
      var minSpareCols = this.options.minSpareCols();
      var autoWrapRow = this.options.autoWrapRow();
      var autoWrapCol = this.options.autoWrapCol();
      var highlightCoords = this.range.current().highlight;

      if (highlightCoords.row + rowDelta > totalRows - 1) {
        if (force && minSpareRows > 0 && !(fixedRowsBottom && highlightCoords.row >= totalRows - fixedRowsBottom - 1)) {
          this.runLocalHooks('insertRowRequire', totalRows);
          totalRows = this.options.countRows();
        } else if (autoWrapCol) {
          delta.row = 1 - totalRows;
          delta.col = highlightCoords.col + delta.col === totalCols - 1 ? 1 - totalCols : 1;
        }
      } else if (autoWrapCol && highlightCoords.row + delta.row < 0 && highlightCoords.col + delta.col >= 0) {
        delta.row = totalRows - 1;
        delta.col = highlightCoords.col + delta.col === 0 ? totalCols - 1 : -1;
      }

      if (highlightCoords.col + delta.col > totalCols - 1) {
        if (force && minSpareCols > 0) {
          this.runLocalHooks('insertColRequire', totalCols);
          totalCols = this.options.countCols();
        } else if (autoWrapRow) {
          delta.row = highlightCoords.row + delta.row === totalRows - 1 ? 1 - totalRows : 1;
          delta.col = 1 - totalCols;
        }
      } else if (autoWrapRow && highlightCoords.col + delta.col < 0 && highlightCoords.row + delta.row >= 0) {
        delta.row = highlightCoords.row + delta.row === 0 ? totalRows - 1 : -1;
        delta.col = totalCols - 1;
      }

      var coords = new _src.CellCoords(highlightCoords.row + delta.row, highlightCoords.col + delta.col);
      var rowTransformDir = 0;
      var colTransformDir = 0;

      if (coords.row < 0) {
        rowTransformDir = -1;
        coords.row = 0;
      } else if (coords.row > 0 && coords.row >= totalRows) {
        rowTransformDir = 1;
        coords.row = totalRows - 1;
      }

      if (coords.col < 0) {
        colTransformDir = -1;
        coords.col = 0;
      } else if (coords.col > 0 && coords.col >= totalCols) {
        colTransformDir = 1;
        coords.col = totalCols - 1;
      }

      this.runLocalHooks('afterTransformStart', coords, rowTransformDir, colTransformDir);
      return coords;
    }
    /**
     * Sets selection end cell relative to current selection end cell (if possible).
     *
     * @param {Number} rowDelta Rows number to move, value can be passed as negative number.
     * @param {Number} colDelta Columns number to move, value can be passed as negative number.
     * @returns {CellCoords}
     */

  }, {
    key: "transformEnd",
    value: function transformEnd(rowDelta, colDelta) {
      var delta = new _src.CellCoords(rowDelta, colDelta);
      this.runLocalHooks('beforeTransformEnd', delta);
      var totalRows = this.options.countRows();
      var totalCols = this.options.countCols();
      var cellRange = this.range.current();
      var coords = new _src.CellCoords(cellRange.to.row + delta.row, cellRange.to.col + delta.col);
      var rowTransformDir = 0;
      var colTransformDir = 0;

      if (coords.row < 0) {
        rowTransformDir = -1;
        coords.row = 0;
      } else if (coords.row > 0 && coords.row >= totalRows) {
        rowTransformDir = 1;
        coords.row = totalRows - 1;
      }

      if (coords.col < 0) {
        colTransformDir = -1;
        coords.col = 0;
      } else if (coords.col > 0 && coords.col >= totalCols) {
        colTransformDir = 1;
        coords.col = totalCols - 1;
      }

      this.runLocalHooks('afterTransformEnd', coords, rowTransformDir, colTransformDir);
      return coords;
    }
  }]);
  return Transformation;
}();

(0, _object.mixin)(Transformation, _localHooks.default);
var _default = Transformation;
exports.default = _default;

/***/ }),
/* 592 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

exports.__esModule = true;
exports.default = jQueryWrapper;

function jQueryWrapper(Handsontable) {
  // eslint-disable-next-line
  var jQuery = typeof window === 'undefined' ? false : window.jQuery;

  if (!jQuery) {
    return;
  }

  jQuery.fn.handsontable = function (action) {
    var $this = this.first(); // Use only first element from list

    var instance = $this.data('handsontable'); // Init case

    if (typeof action !== 'string') {
      var userSettings = action || {};

      if (instance) {
        instance.updateSettings(userSettings);
      } else {
        instance = new Handsontable.Core($this[0], userSettings);
        $this.data('handsontable', instance);
        instance.init();
      }

      return $this;
    }

    var output; // Action case

    if (instance) {
      if (typeof instance[action] !== 'undefined') {
        var _instance$action;

        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        output = (_instance$action = instance[action]).call.apply(_instance$action, [instance].concat(args));

        if (action === 'destroy') {
          $this.removeData();
        }
      } else {
        throw new Error("Handsontable do not provide action: ".concat(action));
      }
    }

    return output;
  };
}

/***/ }),
/* 593 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var nativeForEach = [].forEach;
var internalForEach = __webpack_require__(102)(0);

var SLOPPY_METHOD = __webpack_require__(126)('forEach');

// `Array.prototype.forEach` method implementation
// https://tc39.github.io/ecma262/#sec-array.prototype.foreach
module.exports = SLOPPY_METHOD ? function forEach(callbackfn /* , thisArg */) {
  return internalForEach(this, callbackfn, arguments[1]);
} : nativeForEach;


/***/ }),
/* 594 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;

var _persistentState = _interopRequireDefault(__webpack_require__(595));

exports.PersistentState = _persistentState.default;

var _autoColumnSize = _interopRequireDefault(__webpack_require__(597));

exports.AutoColumnSize = _autoColumnSize.default;

var _autofill = _interopRequireDefault(__webpack_require__(598));

exports.AutoFill = _autofill.default;

var _autoRowSize = _interopRequireDefault(__webpack_require__(600));

exports.AutoRowSize = _autoRowSize.default;

var _columnSorting = _interopRequireDefault(__webpack_require__(484));

exports.ColumnSorting = _columnSorting.default;

var _comments = _interopRequireDefault(__webpack_require__(614));

exports.Comments = _comments.default;

var _contextMenu = _interopRequireDefault(__webpack_require__(618));

exports.ContextMenu = _contextMenu.default;

var _copyPaste = _interopRequireDefault(__webpack_require__(633));

exports.CopyPaste = _copyPaste.default;

var _customBorders = _interopRequireDefault(__webpack_require__(642));

exports.CustomBorders = _customBorders.default;

var _dragToScroll = _interopRequireDefault(__webpack_require__(651));

exports.DragToScroll = _dragToScroll.default;

var _manualColumnFreeze = _interopRequireDefault(__webpack_require__(652));

exports.ManualColumnFreeze = _manualColumnFreeze.default;

var _manualColumnMove = _interopRequireDefault(__webpack_require__(656));

exports.ManualColumnMove = _manualColumnMove.default;

var _manualColumnResize = _interopRequireDefault(__webpack_require__(661));

exports.ManualColumnResize = _manualColumnResize.default;

var _manualRowMove = _interopRequireDefault(__webpack_require__(662));

exports.ManualRowMove = _manualRowMove.default;

var _manualRowResize = _interopRequireDefault(__webpack_require__(667));

exports.ManualRowResize = _manualRowResize.default;

var _mergeCells = _interopRequireDefault(__webpack_require__(668));

exports.MergeCells = _mergeCells.default;

var _multipleSelectionHandles = _interopRequireDefault(__webpack_require__(674));

exports.MultipleSelectionHandles = _multipleSelectionHandles.default;

var _observeChanges = _interopRequireDefault(__webpack_require__(675));

exports.ObserveChanges = _observeChanges.default;

var _search = _interopRequireDefault(__webpack_require__(679));

exports.Search = _search.default;

var _touchScroll = _interopRequireDefault(__webpack_require__(680));

exports.TouchScroll = _touchScroll.default;

var _undoRedo = _interopRequireDefault(__webpack_require__(681));

exports.UndoRedo = _undoRedo.default;

var _base = _interopRequireDefault(__webpack_require__(21));

exports.Base = _base.default;

var _bindRowsWithHeaders = _interopRequireDefault(__webpack_require__(682));

exports.BindRowsWithHeaders = _bindRowsWithHeaders.default;

var _collapsibleColumns = _interopRequireDefault(__webpack_require__(687));

exports.CollapsibleColumns = _collapsibleColumns.default;

var _columnSummary = _interopRequireDefault(__webpack_require__(688));

exports.ColumnSummary = _columnSummary.default;

var _dropdownMenu = _interopRequireDefault(__webpack_require__(692));

exports.DropdownMenu = _dropdownMenu.default;

var _exportFile = _interopRequireDefault(__webpack_require__(694));

exports.ExportFile = _exportFile.default;

var _multiColumnSorting = _interopRequireDefault(__webpack_require__(699));

exports.MultiColumnSorting = _multiColumnSorting.default;

var _filters = _interopRequireDefault(__webpack_require__(704));

exports.Filters = _filters.default;

var _formulas = _interopRequireDefault(__webpack_require__(737));

exports.Formulas = _formulas.default;

var _ganttChart = _interopRequireDefault(__webpack_require__(750));

exports.GanttChart = _ganttChart.default;

var _headerTooltips = _interopRequireDefault(__webpack_require__(754));

exports.HeaderTooltips = _headerTooltips.default;

var _nestedHeaders = _interopRequireDefault(__webpack_require__(755));

exports.NestedHeaders = _nestedHeaders.default;

var _nestedRows = _interopRequireDefault(__webpack_require__(758));

exports.NestedRows = _nestedRows.default;

var _hiddenColumns = _interopRequireDefault(__webpack_require__(763));

exports.HiddenColumns = _hiddenColumns.default;

var _hiddenRows = _interopRequireDefault(__webpack_require__(767));

exports.HiddenRows = _hiddenRows.default;

var _trimRows = _interopRequireDefault(__webpack_require__(771));

exports.TrimRows = _trimRows.default;

/***/ }),
/* 595 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _storage = _interopRequireDefault(__webpack_require__(596));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

_pluginHooks.default.getSingleton().register('persistentStateSave');

_pluginHooks.default.getSingleton().register('persistentStateLoad');

_pluginHooks.default.getSingleton().register('persistentStateReset');
/**
 * @plugin PersistentState
 *
 * @description
 * Save the state of column sorting, column positions and column sizes in local storage to preserve table state
 * between page reloads.
 *
 * In order to enable data storage mechanism, {@link Options#persistentState} option must be set to `true`.
 *
 * When persistentState is enabled it exposes 3 hooks:
 * - {@link Hooks#persistentStateSave} - Saves value under given key in browser local storage.
 * - {@link Hooks#persistentStateLoad} - Loads value, saved under given key, from browser local storage. The loaded
 * value will be saved in `saveTo.value`.
 * - {@link Hooks#persistentStateReset} - Clears the value saved under key. If no key is given, all values associated
 * with table will be cleared.
 */


var PersistentState =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(PersistentState, _BasePlugin);

  function PersistentState(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, PersistentState);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(PersistentState).call(this, hotInstance));
    /**
     * Instance of {@link Storage}.
     *
     * @private
     * @type {Storage}
     */

    _this.storage = void 0;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link PersistentState#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(PersistentState, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().persistentState;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      if (!this.storage) {
        this.storage = new _storage.default(this.hot.rootElement.id, this.hot.rootWindow);
      }

      this.addHook('persistentStateSave', function (key, value) {
        return _this2.saveValue(key, value);
      });
      this.addHook('persistentStateLoad', function (key, saveTo) {
        return _this2.loadValue(key, saveTo);
      });
      this.addHook('persistentStateReset', function () {
        return _this2.resetValue();
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(PersistentState.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.storage = void 0;
      (0, _get2.default)((0, _getPrototypeOf2.default)(PersistentState.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(PersistentState.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Loads the value from local storage.
     *
     * @param {String} key Storage key.
     * @param {Object} saveTo Saved value from local storage.
     */

  }, {
    key: "loadValue",
    value: function loadValue(key, saveTo) {
      saveTo.value = this.storage.loadValue(key);
    }
    /**
     * Saves the data to local storage.
     *
     * @param {String} key Storage key.
     * @param {Mixed} value Value to save.
     */

  }, {
    key: "saveValue",
    value: function saveValue(key, value) {
      this.storage.saveValue(key, value);
    }
    /**
     * Resets the data or all data from local storage.
     *
     * @param {String} key [optional] Storage key.
     */

  }, {
    key: "resetValue",
    value: function resetValue(key) {
      if (typeof key === 'undefined') {
        this.storage.resetAll();
      } else {
        this.storage.reset(key);
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(PersistentState.prototype), "destroy", this).call(this);
    }
  }]);
  return PersistentState;
}(_base.default);

(0, _plugins.registerPlugin)('persistentState', PersistentState);
var _default = PersistentState;
exports.default = _default;

/***/ }),
/* 596 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

/**
 * @class Storage
 * @plugin PersistentState
 */
var Storage =
/*#__PURE__*/
function () {
  // eslint-disable-next-line no-restricted-globals
  function Storage(prefix) {
    var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
    (0, _classCallCheck2.default)(this, Storage);

    /**
     * Reference to proper window.
     *
     * @type {Window}
     */
    this.rootWindow = rootWindow;
    /**
     * Prefix for key (id element).
     *
     * @type {String}
     */

    this.prefix = prefix;
    /**
     * Saved keys.
     *
     * @type {Array}
     */

    this.savedKeys = [];
    this.loadSavedKeys();
  }
  /**
   * Save data to localStorage.
   *
   * @param {String} key Key string.
   * @param {Mixed} value Value to save.
   */


  (0, _createClass2.default)(Storage, [{
    key: "saveValue",
    value: function saveValue(key, value) {
      this.rootWindow.localStorage.setItem("".concat(this.prefix, "_").concat(key), JSON.stringify(value));

      if (this.savedKeys.indexOf(key) === -1) {
        this.savedKeys.push(key);
        this.saveSavedKeys();
      }
    }
    /**
     * Load data from localStorage.
     *
     * @param {String} key Key string.
     * @param {Object} defaultValue Object containing the loaded data.
     *
     * @returns {}
     */

  }, {
    key: "loadValue",
    value: function loadValue(key, defaultValue) {
      var itemKey = typeof key === 'undefined' ? defaultValue : key;
      var value = this.rootWindow.localStorage.getItem("".concat(this.prefix, "_").concat(itemKey));
      return value === null ? void 0 : JSON.parse(value);
    }
    /**
     * Reset given data from localStorage.
     *
     * @param {String} key Key string.
     */

  }, {
    key: "reset",
    value: function reset(key) {
      this.rootWindow.localStorage.removeItem("".concat(this.prefix, "_").concat(key));
    }
    /**
     * Reset all data from localStorage.
     *
     */

  }, {
    key: "resetAll",
    value: function resetAll() {
      var _this = this;

      (0, _array.arrayEach)(this.savedKeys, function (value, index) {
        _this.rootWindow.localStorage.removeItem("".concat(_this.prefix, "_").concat(_this.savedKeys[index]));
      });
      this.clearSavedKeys();
    }
    /**
     * Load and save all keys from localStorage.
     *
     * @private
     */

  }, {
    key: "loadSavedKeys",
    value: function loadSavedKeys() {
      var keysJSON = this.rootWindow.localStorage.getItem("".concat(this.prefix, "__persistentStateKeys"));
      var keys = typeof keysJSON === 'string' ? JSON.parse(keysJSON) : void 0;
      this.savedKeys = keys || [];
    }
    /**
     * Save saved key in localStorage.
     *
     * @private
     */

  }, {
    key: "saveSavedKeys",
    value: function saveSavedKeys() {
      this.rootWindow.localStorage.setItem("".concat(this.prefix, "__persistentStateKeys"), JSON.stringify(this.savedKeys));
    }
    /**
     * Clear saved key from localStorage.
     *
     * @private
     */

  }, {
    key: "clearSavedKeys",
    value: function clearSavedKeys() {
      this.savedKeys.length = 0;
      this.saveSavedKeys();
    }
  }]);
  return Storage;
}();

var _default = Storage;
exports.default = _default;

/***/ }),
/* 597 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _array = __webpack_require__(3);

var _feature = __webpack_require__(73);

var _element = __webpack_require__(5);

var _ghostTable = _interopRequireDefault(__webpack_require__(163));

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

var _samplesGenerator = _interopRequireDefault(__webpack_require__(483));

var _string = __webpack_require__(68);

var _src = __webpack_require__(25);

var privatePool = new WeakMap();
/**
 * @plugin AutoColumnSize
 *
 * @description
 * This plugin allows to set column widths based on their widest cells.
 *
 * By default, the plugin is declared as `undefined`, which makes it enabled (same as if it was declared as `true`).
 * Enabling this plugin may decrease the overall table performance, as it needs to calculate the widths of all cells to
 * resize the columns accordingly.
 * If you experience problems with the performance, try turning this feature off and declaring the column widths manually.
 *
 * Column width calculations are divided into sync and async part. Each of this parts has their own advantages and
 * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous
 * operations don't block the browser UI.
 *
 * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object:
 * ```js
 * // as a number (300 columns in sync, rest async)
 * autoColumnSize: {syncLimit: 300},
 *
 * // as a string (percent)
 * autoColumnSize: {syncLimit: '40%'},
 * ```
 *
 * To configure this plugin see {@link Options#autoColumnSize}.
 *
 * @example
 * ```js
 * const hot = new Handsontable(document.getElementById('example'), {
 *   date: getData(),
 *   autoColumnSize: true
 * });
 * // Access to plugin instance:
 * const plugin = hot.getPlugin('autoColumnSize');
 *
 * plugin.getColumnWidth(4);
 *
 * if (plugin.isEnabled()) {
 *   // code...
 * }
 * ```
 */

var AutoColumnSize =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(AutoColumnSize, _BasePlugin);
  (0, _createClass2.default)(AutoColumnSize, null, [{
    key: "CALCULATION_STEP",
    get: function get() {
      return 50;
    }
  }, {
    key: "SYNC_CALCULATION_LIMIT",
    get: function get() {
      return 50;
    }
  }]);

  function AutoColumnSize(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, AutoColumnSize);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(AutoColumnSize).call(this, hotInstance));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      /**
       * Cached column header names. It is used to diff current column headers with previous state and detect which
       * columns width should be updated.
       *
       * @private
       * @type {Array}
       */
      cachedColumnHeaders: []
    });
    /**
     * Cached columns widths.
     *
     * @type {Number[]}
     */

    _this.widths = [];
    /**
     * Instance of {@link GhostTable} for rows and columns size calculations.
     *
     * @private
     * @type {GhostTable}
     */

    _this.ghostTable = new _ghostTable.default(_this.hot);
    /**
     * Instance of {@link SamplesGenerator} for generating samples necessary for columns width calculations.
     *
     * @private
     * @type {SamplesGenerator}
     */

    _this.samplesGenerator = new _samplesGenerator.default(function (row, column) {
      var cellMeta = _this.hot.getCellMeta(row, column);

      var cellValue = '';

      if (!cellMeta.spanned) {
        cellValue = _this.hot.getDataAtCell(row, column);
      }

      var bundleCountSeed = 0;

      if (cellMeta.label) {
        var _cellMeta$label = cellMeta.label,
            labelValue = _cellMeta$label.value,
            labelProperty = _cellMeta$label.property;
        var labelText = '';

        if (labelValue) {
          labelText = typeof labelValue === 'function' ? labelValue(row, column, _this.hot.colToProp(column), cellValue) : labelValue;
        } else if (labelProperty) {
          labelText = _this.hot.getDataAtRowProp(row, labelProperty);
        }

        bundleCountSeed = labelText.length;
      }

      return {
        value: cellValue,
        bundleCountSeed: bundleCountSeed
      };
    });
    /**
     * `true` only if the first calculation was performed
     *
     * @private
     * @type {Boolean}
     */

    _this.firstCalculation = true;
    /**
     * `true` if the size calculation is in progress.
     *
     * @type {Boolean}
     */

    _this.inProgress = false; // moved to constructor to allow auto-sizing the columns when the plugin is disabled

    _this.addHook('beforeColumnResize', function (col, size, isDblClick) {
      return _this.onBeforeColumnResize(col, size, isDblClick);
    });

    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link AutoColumnSize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(AutoColumnSize, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().autoColumnSize !== false && !this.hot.getSettings().colWidths;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var setting = this.hot.getSettings().autoColumnSize;

      if (setting && setting.useHeaders !== null && setting.useHeaders !== void 0) {
        this.ghostTable.setSetting('useHeaders', setting.useHeaders);
      }

      this.setSamplingOptions();
      this.addHook('afterLoadData', function () {
        return _this2.onAfterLoadData();
      });
      this.addHook('beforeChange', function (changes) {
        return _this2.onBeforeChange(changes);
      });
      this.addHook('beforeRender', function (force) {
        return _this2.onBeforeRender(force);
      });
      this.addHook('modifyColWidth', function (width, col) {
        return _this2.getColumnWidth(col, width);
      });
      this.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoColumnSize.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      var changedColumns = this.findColumnsWhereHeaderWasChanged();

      if (changedColumns.length) {
        this.clearCache(changedColumns);
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoColumnSize.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoColumnSize.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Calculates a columns width.
     *
     * @param {Number|Object} colRange Column index or an object with `from` and `to` indexes as a range.
     * @param {Number|Object} rowRange Row index or an object with `from` and `to` indexes as a range.
     * @param {Boolean} [force=false] If `true` the calculation will be processed regardless of whether the width exists in the cache.
     */

  }, {
    key: "calculateColumnsWidth",
    value: function calculateColumnsWidth() {
      var _this3 = this;

      var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        from: 0,
        to: this.hot.countCols() - 1
      };
      var rowRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        from: 0,
        to: this.hot.countRows() - 1
      };
      var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var columnsRange = typeof colRange === 'number' ? {
        from: colRange,
        to: colRange
      } : colRange;
      var rowsRange = typeof rowRange === 'number' ? {
        from: rowRange,
        to: rowRange
      } : rowRange;
      (0, _number.rangeEach)(columnsRange.from, columnsRange.to, function (col) {
        if (force || _this3.widths[col] === void 0 && !_this3.hot._getColWidthFromSettings(col)) {
          var samples = _this3.samplesGenerator.generateColumnSamples(col, rowsRange);

          (0, _array.arrayEach)(samples, function (_ref) {
            var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
                column = _ref2[0],
                sample = _ref2[1];

            return _this3.ghostTable.addColumn(column, sample);
          });
        }
      });

      if (this.ghostTable.columns.length) {
        this.ghostTable.getWidths(function (col, width) {
          _this3.widths[col] = width;
        });
        this.ghostTable.clean();
      }
    }
    /**
     * Calculates all columns width. The calculated column will be cached in the {@link AutoColumnSize#widths} property.
     * To retrieve width for specyfied column use {@link AutoColumnSize#getColumnWidth} method.
     *
     * @param {Object|Number} rowRange Row index or an object with `from` and `to` properties which define row range.
     */

  }, {
    key: "calculateAllColumnsWidth",
    value: function calculateAllColumnsWidth() {
      var _this4 = this;

      var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        from: 0,
        to: this.hot.countRows() - 1
      };
      var current = 0;
      var length = this.hot.countCols() - 1;
      var timer = null;
      this.inProgress = true;

      var loop = function loop() {
        // When hot was destroyed after calculating finished cancel frame
        if (!_this4.hot) {
          (0, _feature.cancelAnimationFrame)(timer);
          _this4.inProgress = false;
          return;
        }

        _this4.calculateColumnsWidth({
          from: current,
          to: Math.min(current + AutoColumnSize.CALCULATION_STEP, length)
        }, rowRange);

        current = current + AutoColumnSize.CALCULATION_STEP + 1;

        if (current < length) {
          timer = (0, _feature.requestAnimationFrame)(loop);
        } else {
          (0, _feature.cancelAnimationFrame)(timer);
          _this4.inProgress = false; // @TODO Should call once per render cycle, currently fired separately in different plugins

          _this4.hot.view.wt.wtOverlays.adjustElementsSize();
        }
      };

      var syncLimit = this.getSyncCalculationLimit(); // sync

      if (this.firstCalculation && syncLimit >= 0) {
        this.calculateColumnsWidth({
          from: 0,
          to: syncLimit
        }, rowRange);
        this.firstCalculation = false;
        current = syncLimit + 1;
      } // async


      if (current < length) {
        loop();
      } else {
        this.inProgress = false;
      }
    }
    /**
     * Sets the sampling options.
     *
     * @private
     */

  }, {
    key: "setSamplingOptions",
    value: function setSamplingOptions() {
      var setting = this.hot.getSettings().autoColumnSize;
      var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoColumnSize.samplingRatio : void 0;
      var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoColumnSize.allowSampleDuplicates : void 0;

      if (samplingRatio && !isNaN(samplingRatio)) {
        this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10));
      }

      if (allowSampleDuplicates) {
        this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates);
      }
    }
    /**
     * Recalculates all columns width (overwrite cache values).
     */

  }, {
    key: "recalculateAllColumnsWidth",
    value: function recalculateAllColumnsWidth() {
      if (this.hot.view && (0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) {
        this.clearCache();
        this.calculateAllColumnsWidth();
      }
    }
    /**
     * Gets value which tells how many columns should be calculated synchronously (rest of the columns will be calculated
     * asynchronously). The limit is calculated based on `syncLimit` set to `autoColumnSize` option (see {@link Options#autoColumnSize}).
     *
     * @returns {Number}
     */

  }, {
    key: "getSyncCalculationLimit",
    value: function getSyncCalculationLimit() {
      /* eslint-disable no-bitwise */
      var limit = AutoColumnSize.SYNC_CALCULATION_LIMIT;
      var colsLimit = this.hot.countCols() - 1;

      if ((0, _object.isObject)(this.hot.getSettings().autoColumnSize)) {
        limit = this.hot.getSettings().autoColumnSize.syncLimit;

        if ((0, _string.isPercentValue)(limit)) {
          limit = (0, _number.valueAccordingPercent)(colsLimit, limit);
        } else {
          // Force to Number
          limit >>= 0;
        }
      }

      return Math.min(limit, colsLimit);
    }
    /**
     * Gets the calculated column width.
     *
     * @param {Number} column Column index.
     * @param {Number} [defaultWidth] Default column width. It will be picked up if no calculated width found.
     * @param {Boolean} [keepMinimum=true] If `true` then returned value won't be smaller then 50 (default column width).
     * @returns {Number}
     */

  }, {
    key: "getColumnWidth",
    value: function getColumnWidth(column) {
      var defaultWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0;
      var keepMinimum = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      var width = defaultWidth;

      if (width === void 0) {
        width = this.widths[column];

        if (keepMinimum && typeof width === 'number') {
          width = Math.max(width, _src.ViewportColumnsCalculator.DEFAULT_WIDTH);
        }
      }

      return width;
    }
    /**
     * Gets the first visible column.
     *
     * @returns {Number|null} Returns column index, -1 if table is not rendered or null if there are no columns to base the the calculations on.
     */

  }, {
    key: "getFirstVisibleColumn",
    value: function getFirstVisibleColumn() {
      var wot = this.hot.view.wt;

      if (wot.wtViewport.columnsVisibleCalculator) {
        return wot.wtTable.getFirstVisibleColumn();
      }

      if (wot.wtViewport.columnsRenderCalculator) {
        return wot.wtTable.getFirstRenderedColumn();
      }

      return -1;
    }
    /**
     * Gets the last visible column.
     *
     * @returns {Number} Returns column index or -1 if table is not rendered.
     */

  }, {
    key: "getLastVisibleColumn",
    value: function getLastVisibleColumn() {
      var wot = this.hot.view.wt;

      if (wot.wtViewport.columnsVisibleCalculator) {
        return wot.wtTable.getLastVisibleColumn();
      }

      if (wot.wtViewport.columnsRenderCalculator) {
        return wot.wtTable.getLastRenderedColumn();
      }

      return -1;
    }
    /**
     * Collects all columns which titles has been changed in comparison to the previous state.
     *
     * @private
     * @returns {Array} It returns an array of physical column indexes.
     */

  }, {
    key: "findColumnsWhereHeaderWasChanged",
    value: function findColumnsWhereHeaderWasChanged() {
      var columnHeaders = this.hot.getColHeader();

      var _privatePool$get = privatePool.get(this),
          cachedColumnHeaders = _privatePool$get.cachedColumnHeaders;

      var changedColumns = (0, _array.arrayReduce)(columnHeaders, function (acc, columnTitle, physicalColumn) {
        var cachedColumnsLength = cachedColumnHeaders.length;

        if (cachedColumnsLength - 1 < physicalColumn || cachedColumnHeaders[physicalColumn] !== columnTitle) {
          acc.push(physicalColumn);
        }

        if (cachedColumnsLength - 1 < physicalColumn) {
          cachedColumnHeaders.push(columnTitle);
        } else {
          cachedColumnHeaders[physicalColumn] = columnTitle;
        }

        return acc;
      }, []);
      return changedColumns;
    }
    /**
     * Clears cache of calculated column widths. If you want to clear only selected columns pass an array with their indexes.
     * Otherwise whole cache will be cleared.
     *
     * @param {Number[]} [columns] List of physical column indexes to clear.
     */

  }, {
    key: "clearCache",
    value: function clearCache() {
      var _this5 = this;

      var columns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

      if (columns.length) {
        (0, _array.arrayEach)(columns, function (physicalIndex) {
          _this5.widths[physicalIndex] = void 0;
        });
      } else {
        this.widths.length = 0;
      }
    }
    /**
     * Checks if all widths were calculated. If not then return `true` (need recalculate).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isNeedRecalculate",
    value: function isNeedRecalculate() {
      return !!(0, _array.arrayFilter)(this.widths, function (item) {
        return item === void 0;
      }).length;
    }
    /**
     * On before render listener.
     *
     * @private
     */

  }, {
    key: "onBeforeRender",
    value: function onBeforeRender() {
      var force = this.hot.renderCall;
      var rowsCount = this.hot.countRows();
      var firstVisibleColumn = this.getFirstVisibleColumn();
      var lastVisibleColumn = this.getLastVisibleColumn();

      if (firstVisibleColumn === null || lastVisibleColumn === null) {
        return;
      } // Keep last column widths unchanged for situation when all rows was deleted or trimmed (pro #6)


      if (!rowsCount) {
        return;
      }

      this.calculateColumnsWidth({
        from: firstVisibleColumn,
        to: lastVisibleColumn
      }, void 0, force);

      if (this.isNeedRecalculate() && !this.inProgress) {
        this.calculateAllColumnsWidth();
      }
    }
    /**
     * On after load data listener.
     *
     * @private
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData() {
      var _this6 = this;

      if (this.hot.view) {
        this.recalculateAllColumnsWidth();
      } else {
        // first load - initialization
        setTimeout(function () {
          if (_this6.hot) {
            _this6.recalculateAllColumnsWidth();
          }
        }, 0);
      }
    }
    /**
     * On before change listener.
     *
     * @private
     * @param {Array} changes
     */

  }, {
    key: "onBeforeChange",
    value: function onBeforeChange(changes) {
      var _this7 = this;

      var changedColumns = (0, _array.arrayMap)(changes, function (_ref3) {
        var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
            column = _ref4[1];

        return _this7.hot.propToCol(column);
      });
      this.clearCache(changedColumns);
    }
    /**
     * On before column resize listener.
     *
     * @private
     * @param {Number} col
     * @param {Number} size
     * @param {Boolean} isDblClick
     * @returns {Number}
     */

  }, {
    key: "onBeforeColumnResize",
    value: function onBeforeColumnResize(col, size, isDblClick) {
      var newSize = size;

      if (isDblClick) {
        this.calculateColumnsWidth(col, void 0, true);
        newSize = this.getColumnWidth(col, void 0, false);
      }

      return newSize;
    }
    /**
     * On after Handsontable init fill plugin with all necessary values.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      privatePool.get(this).cachedColumnHeaders = this.hot.getColHeader();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.ghostTable.clean();
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoColumnSize.prototype), "destroy", this).call(this);
    }
  }]);
  return AutoColumnSize;
}(_base.default);

(0, _plugins.registerPlugin)('autoColumnSize', AutoColumnSize);
var _default = AutoColumnSize;
exports.default = _default;

/***/ }),
/* 598 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(39);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _src = __webpack_require__(25);

var _utils = __webpack_require__(599);

_pluginHooks.default.getSingleton().register('modifyAutofillRange');

_pluginHooks.default.getSingleton().register('beforeAutofill');

var INSERT_ROW_ALTER_ACTION_NAME = 'insert_row';
var INTERVAL_FOR_ADDING_ROW = 200;
/**
 * This plugin provides "drag-down" and "copy-down" functionalities, both operated using the small square in the right
 * bottom of the cell selection.
 *
 * "Drag-down" expands the value of the selected cells to the neighbouring cells when you drag the small square in the corner.
 *
 * "Copy-down" copies the value of the selection to all empty cells below when you double click the small square.
 *
 * @class Autofill
 * @plugin Autofill
 */

var Autofill =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(Autofill, _BasePlugin);

  function Autofill(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, Autofill);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Autofill).call(this, hotInstance));
    /**
     * Event manager instance.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Specifies if adding new row started.
     *
     * @private
     * @type {Boolean}
     */

    _this.addingStarted = false;
    /**
     * Specifies if there was mouse down on the cell corner.
     *
     * @private
     * @type {Boolean}
     */

    _this.mouseDownOnCellCorner = false;
    /**
     * Specifies if mouse was dragged outside Handsontable.
     *
     * @private
     * @type {Boolean}
     */

    _this.mouseDragOutside = false;
    /**
     * Specifies how many cell levels were dragged using the handle.
     *
     * @private
     * @type {Boolean}
     */

    _this.handleDraggedCells = 0;
    /**
     * Specifies allowed directions of drag (`'horizontal'` or '`vertical`').
     *
     * @private
     * @type {String[]}
     */

    _this.directions = [];
    /**
     * Specifies if can insert new rows if needed.
     *
     * @type {Boolean}
     */

    _this.autoInsertRow = false;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the Handsontable settings.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Autofill, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().fillHandle;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.mapSettings();
      this.registerEvents();
      this.addHook('afterOnCellCornerMouseDown', function (event) {
        return _this2.onAfterCellCornerMouseDown(event);
      });
      this.addHook('afterOnCellCornerDblClick', function (event) {
        return _this2.onCellCornerDblClick(event);
      });
      this.addHook('beforeOnCellMouseOver', function (event, coords) {
        return _this2.onBeforeCellMouseOver(coords);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(Autofill.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(Autofill.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.clearMappedSettings();
      (0, _get2.default)((0, _getPrototypeOf2.default)(Autofill.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Gets selection data
     *
     * @private
     * @returns {Array} Array with the data.
     */

  }, {
    key: "getSelectionData",
    value: function getSelectionData() {
      var selRange = {
        from: this.hot.getSelectedRangeLast().from,
        to: this.hot.getSelectedRangeLast().to
      };
      return this.hot.getData(selRange.from.row, selRange.from.col, selRange.to.row, selRange.to.col);
    }
    /**
     * Try to apply fill values to the area in fill border, omitting the selection border.
     *
     * @private
     * @returns {Boolean} reports if fill was applied.
     *
     * @fires Hooks#modifyAutofillRange
     * @fires Hooks#beforeAutofill
     */

  }, {
    key: "fillIn",
    value: function fillIn() {
      if (this.hot.selection.highlight.getFill().isEmpty()) {
        return false;
      }

      var cornersOfSelectionAndDragAreas = this.hot.selection.highlight.getFill().getCorners();
      this.resetSelectionOfDraggedArea();
      var cornersOfSelectedCells = this.getCornersOfSelectedCells();
      cornersOfSelectionAndDragAreas = this.hot.runHooks('modifyAutofillRange', cornersOfSelectionAndDragAreas, cornersOfSelectedCells);

      var _getDragDirectionAndR = (0, _utils.getDragDirectionAndRange)(cornersOfSelectedCells, cornersOfSelectionAndDragAreas),
          directionOfDrag = _getDragDirectionAndR.directionOfDrag,
          startOfDragCoords = _getDragDirectionAndR.startOfDragCoords,
          endOfDragCoords = _getDragDirectionAndR.endOfDragCoords;

      if (startOfDragCoords && startOfDragCoords.row > -1 && startOfDragCoords.col > -1) {
        var selectionData = this.getSelectionData();
        this.hot.runHooks('beforeAutofill', startOfDragCoords, endOfDragCoords, selectionData);
        var deltas = (0, _utils.getDeltas)(startOfDragCoords, endOfDragCoords, selectionData, directionOfDrag);
        var fillData = selectionData;

        if (['up', 'left'].indexOf(directionOfDrag) > -1) {
          fillData = [];
          var dragLength = null;
          var fillOffset = null;

          if (directionOfDrag === 'up') {
            dragLength = endOfDragCoords.row - startOfDragCoords.row + 1;
            fillOffset = dragLength % selectionData.length;

            for (var i = 0; i < dragLength; i++) {
              fillData.push(selectionData[(i + (selectionData.length - fillOffset)) % selectionData.length]);
            }
          } else {
            dragLength = endOfDragCoords.col - startOfDragCoords.col + 1;
            fillOffset = dragLength % selectionData[0].length;

            for (var _i = 0; _i < selectionData.length; _i++) {
              fillData.push([]);

              for (var j = 0; j < dragLength; j++) {
                fillData[_i].push(selectionData[_i][(j + (selectionData[_i].length - fillOffset)) % selectionData[_i].length]);
              }
            }
          }
        }

        this.hot.populateFromArray(startOfDragCoords.row, startOfDragCoords.col, fillData, endOfDragCoords.row, endOfDragCoords.col, "".concat(this.pluginName, ".fill"), null, directionOfDrag, deltas);
        this.setSelection(cornersOfSelectionAndDragAreas);
      } else {
        // reset to avoid some range bug
        this.hot._refreshBorders();
      }

      return true;
    }
    /**
     * Reduces the selection area if the handle was dragged outside of the table or on headers.
     *
     * @private
     * @param {CellCoords} coords indexes of selection corners.
     * @returns {CellCoords}
     */

  }, {
    key: "reduceSelectionAreaIfNeeded",
    value: function reduceSelectionAreaIfNeeded(coords) {
      if (coords.row < 0) {
        coords.row = 0;
      }

      if (coords.col < 0) {
        coords.col = 0;
      }

      return coords;
    }
    /**
     * Gets the coordinates of the drag & drop borders.
     *
     * @private
     * @param {CellCoords} coordsOfSelection `CellCoords` coord object.
     * @returns {Array}
     */

  }, {
    key: "getCoordsOfDragAndDropBorders",
    value: function getCoordsOfDragAndDropBorders(coordsOfSelection) {
      var topLeftCorner = this.hot.getSelectedRangeLast().getTopLeftCorner();
      var bottomRightCorner = this.hot.getSelectedRangeLast().getBottomRightCorner();
      var coords;

      if (this.directions.includes(_utils.DIRECTIONS.vertical) && (bottomRightCorner.row < coordsOfSelection.row || topLeftCorner.row > coordsOfSelection.row)) {
        coords = new _src.CellCoords(coordsOfSelection.row, bottomRightCorner.col);
      } else if (this.directions.includes(_utils.DIRECTIONS.horizontal)) {
        coords = new _src.CellCoords(bottomRightCorner.row, coordsOfSelection.col);
      } else {
        // wrong direction
        return;
      }

      return this.reduceSelectionAreaIfNeeded(coords);
    }
    /**
     * Show the fill border.
     *
     * @private
     * @param {CellCoords} coordsOfSelection `CellCoords` coord object.
     */

  }, {
    key: "showBorder",
    value: function showBorder(coordsOfSelection) {
      var coordsOfDragAndDropBorders = this.getCoordsOfDragAndDropBorders(coordsOfSelection);

      if (coordsOfDragAndDropBorders) {
        this.redrawBorders(coordsOfDragAndDropBorders);
      }
    }
    /**
     * Add new row
     *
     * @private
     */

  }, {
    key: "addRow",
    value: function addRow() {
      var _this3 = this;

      this.hot._registerTimeout(setTimeout(function () {
        _this3.hot.alter(INSERT_ROW_ALTER_ACTION_NAME, void 0, 1, "".concat(_this3.pluginName, ".fill"));

        _this3.addingStarted = false;
      }, INTERVAL_FOR_ADDING_ROW));
    }
    /**
     * Add new rows if they are needed to continue auto-filling values.
     *
     * @private
     */

  }, {
    key: "addNewRowIfNeeded",
    value: function addNewRowIfNeeded() {
      if (this.hot.selection.highlight.getFill().cellRange && this.addingStarted === false && this.autoInsertRow) {
        var cornersOfSelectedCells = this.hot.getSelectedLast();
        var cornersOfSelectedDragArea = this.hot.selection.highlight.getFill().getCorners();
        var nrOfTableRows = this.hot.countRows();

        if (cornersOfSelectedCells[2] < nrOfTableRows - 1 && cornersOfSelectedDragArea[2] === nrOfTableRows - 1) {
          this.addingStarted = true;
          this.addRow();
        }
      }
    }
    /**
     * Get corners of selected cells.
     *
     * @private
     * @returns {Array}
     */

  }, {
    key: "getCornersOfSelectedCells",
    value: function getCornersOfSelectedCells() {
      if (this.hot.selection.isMultiple()) {
        return this.hot.selection.highlight.createOrGetArea().getCorners();
      }

      return this.hot.selection.highlight.getCell().getCorners();
    }
    /**
     * Get index of last adjacent filled in row
     *
     * @private
     * @param {Array} cornersOfSelectedCells indexes of selection corners.
     * @returns {Number} gives number greater than or equal to zero when selection adjacent can be applied.
     * or -1 when selection adjacent can't be applied
     */

  }, {
    key: "getIndexOfLastAdjacentFilledInRow",
    value: function getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells) {
      var data = this.hot.getData();
      var nrOfTableRows = this.hot.countRows();
      var lastFilledInRowIndex;

      for (var rowIndex = cornersOfSelectedCells[2] + 1; rowIndex < nrOfTableRows; rowIndex++) {
        for (var columnIndex = cornersOfSelectedCells[1]; columnIndex <= cornersOfSelectedCells[3]; columnIndex++) {
          var dataInCell = data[rowIndex][columnIndex];

          if (dataInCell) {
            return -1;
          }
        }

        var dataInNextLeftCell = data[rowIndex][cornersOfSelectedCells[1] - 1];
        var dataInNextRightCell = data[rowIndex][cornersOfSelectedCells[3] + 1];

        if (!!dataInNextLeftCell || !!dataInNextRightCell) {
          lastFilledInRowIndex = rowIndex;
        }
      }

      return lastFilledInRowIndex;
    }
    /**
     * Adds a selection from the start area to the specific row index.
     *
     * @private
     * @param {Array} selectStartArea selection area from which we start to create more comprehensive selection.
     * @param {Number} rowIndex
     */

  }, {
    key: "addSelectionFromStartAreaToSpecificRowIndex",
    value: function addSelectionFromStartAreaToSpecificRowIndex(selectStartArea, rowIndex) {
      this.hot.selection.highlight.getFill().clear().add(new _src.CellCoords(selectStartArea[0], selectStartArea[1])).add(new _src.CellCoords(rowIndex, selectStartArea[3]));
    }
    /**
     * Sets selection based on passed corners.
     *
     * @private
     * @param {Array} cornersOfArea
     */

  }, {
    key: "setSelection",
    value: function setSelection(cornersOfArea) {
      var _this$hot;

      (_this$hot = this.hot).selectCell.apply(_this$hot, (0, _toConsumableArray2.default)(cornersOfArea).concat([false, false]));
    }
    /**
     * Try to select cells down to the last row in the left column and then returns if selection was applied.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "selectAdjacent",
    value: function selectAdjacent() {
      var cornersOfSelectedCells = this.getCornersOfSelectedCells();
      var lastFilledInRowIndex = this.getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells);

      if (lastFilledInRowIndex === -1 || lastFilledInRowIndex === void 0) {
        return false;
      }

      this.addSelectionFromStartAreaToSpecificRowIndex(cornersOfSelectedCells, lastFilledInRowIndex);
      return true;
    }
    /**
     * Resets selection of dragged area.
     *
     * @private
     */

  }, {
    key: "resetSelectionOfDraggedArea",
    value: function resetSelectionOfDraggedArea() {
      this.handleDraggedCells = 0;
      this.hot.selection.highlight.getFill().clear();
    }
    /**
     * Redraws borders.
     *
     * @private
     * @param {CellCoords} coords `CellCoords` coord object.
     */

  }, {
    key: "redrawBorders",
    value: function redrawBorders(coords) {
      this.hot.selection.highlight.getFill().clear().add(this.hot.getSelectedRangeLast().from).add(this.hot.getSelectedRangeLast().to).add(coords);
      this.hot.view.render();
    }
    /**
     * Get if mouse was dragged outside.
     *
     * @private
     * @param {MouseEvent} event `mousemove` event properties.
     * @returns {Boolean}
     */

  }, {
    key: "getIfMouseWasDraggedOutside",
    value: function getIfMouseWasDraggedOutside(event) {
      var documentElement = this.hot.rootDocument.documentElement;
      var tableBottom = (0, _element.offset)(this.hot.table).top - (this.hot.rootWindow.pageYOffset || documentElement.scrollTop) + (0, _element.outerHeight)(this.hot.table);
      var tableRight = (0, _element.offset)(this.hot.table).left - (this.hot.rootWindow.pageXOffset || documentElement.scrollLeft) + (0, _element.outerWidth)(this.hot.table);
      return event.clientY > tableBottom && event.clientX <= tableRight;
    }
    /**
     * Bind the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this4 = this;

      var documentElement = this.hot.rootDocument.documentElement;
      this.eventManager.addEventListener(documentElement, 'mouseup', function () {
        return _this4.onMouseUp();
      });
      this.eventManager.addEventListener(documentElement, 'mousemove', function (event) {
        return _this4.onMouseMove(event);
      });
    }
    /**
     * On cell corner double click callback.
     *
     * @private
     */

  }, {
    key: "onCellCornerDblClick",
    value: function onCellCornerDblClick() {
      var selectionApplied = this.selectAdjacent();

      if (selectionApplied) {
        this.fillIn();
      }
    }
    /**
     * On after cell corner mouse down listener.
     *
     * @private
     */

  }, {
    key: "onAfterCellCornerMouseDown",
    value: function onAfterCellCornerMouseDown() {
      this.handleDraggedCells = 1;
      this.mouseDownOnCellCorner = true;
    }
    /**
     * On before cell mouse over listener.
     *
     * @private
     * @param {CellCoords} coords `CellCoords` coord object.
     */

  }, {
    key: "onBeforeCellMouseOver",
    value: function onBeforeCellMouseOver(coords) {
      if (this.mouseDownOnCellCorner && !this.hot.view.isMouseDown() && this.handleDraggedCells) {
        this.handleDraggedCells += 1;
        this.showBorder(coords);
        this.addNewRowIfNeeded();
      }
    }
    /**
     * On mouse up listener.
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      if (this.handleDraggedCells) {
        if (this.handleDraggedCells > 1) {
          this.fillIn();
        }

        this.handleDraggedCells = 0;
        this.mouseDownOnCellCorner = false;
      }
    }
    /**
     * On mouse move listener.
     *
     * @private
     * @param {MouseEvent} event `mousemove` event properties.
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var mouseWasDraggedOutside = this.getIfMouseWasDraggedOutside(event);

      if (this.addingStarted === false && this.handleDraggedCells > 0 && mouseWasDraggedOutside) {
        this.mouseDragOutside = true;
        this.addingStarted = true;
      } else {
        this.mouseDragOutside = false;
      }

      if (this.mouseDragOutside && this.autoInsertRow) {
        this.addRow();
      }
    }
    /**
     * Clears mapped settings.
     *
     * @private
     */

  }, {
    key: "clearMappedSettings",
    value: function clearMappedSettings() {
      this.directions.length = 0;
      this.autoInsertRow = false;
    }
    /**
     * Map settings.
     *
     * @private
     */

  }, {
    key: "mapSettings",
    value: function mapSettings() {
      var mappedSettings = (0, _utils.getMappedFillHandleSetting)(this.hot.getSettings().fillHandle);
      this.directions = mappedSettings.directions;
      this.autoInsertRow = mappedSettings.autoInsertRow;
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(Autofill.prototype), "destroy", this).call(this);
    }
  }]);
  return Autofill;
}(_base.default);

(0, _plugins.registerPlugin)('autofill', Autofill);
var _default = Autofill;
exports.default = _default;

/***/ }),
/* 599 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(12);

__webpack_require__(76);

exports.__esModule = true;
exports.getDeltas = getDeltas;
exports.getDragDirectionAndRange = getDragDirectionAndRange;
exports.getMappedFillHandleSetting = getMappedFillHandleSetting;
exports.DIRECTIONS = void 0;

var _object = __webpack_require__(4);

var _mixed = __webpack_require__(27);

var _src = __webpack_require__(25);

var DIRECTIONS = {
  horizontal: 'horizontal',
  vertical: 'vertical'
};
/**
 * Get deltas array.
 *
 * @param {CellCoords} start
 * @param {CellCoords} end
 * @param {Array} data
 * @param {String} direction
 * @returns {Array}
 */

exports.DIRECTIONS = DIRECTIONS;

function getDeltas(start, end, data, direction) {
  var rowsLength = data.length;
  var columnsLength = data ? data[0].length : 0;
  var deltas = [];
  var diffRow = end.row - start.row;
  var diffCol = end.col - start.col;

  if (['down', 'up'].indexOf(direction) !== -1) {
    var arr = [];

    for (var col = 0; col <= diffCol; col++) {
      var startValue = parseInt(data[0][col], 10);
      var endValue = parseInt(data[rowsLength - 1][col], 10);
      var delta = (direction === 'down' ? endValue - startValue : startValue - endValue) / (rowsLength - 1) || 0;
      arr.push(delta);
    }

    deltas.push(arr);
  }

  if (['right', 'left'].indexOf(direction) !== -1) {
    for (var row = 0; row <= diffRow; row++) {
      var _startValue = parseInt(data[row][0], 10);

      var _endValue = parseInt(data[row][columnsLength - 1], 10);

      var _delta = (direction === 'right' ? _endValue - _startValue : _startValue - _endValue) / (columnsLength - 1) || 0;

      deltas.push([_delta]);
    }
  }

  return deltas;
}
/**
 * Get direction between positions and cords of selections difference (drag area)
 *
 * @param {Array} startSelection
 * @param {Array} endSelection
 * @returns {{direction: String, start: CellCoords, end: CellCoords}}
 */


function getDragDirectionAndRange(startSelection, endSelection) {
  var startOfDragCoords;
  var endOfDragCoords;
  var directionOfDrag;

  if (endSelection[0] === startSelection[0] && endSelection[1] < startSelection[1]) {
    directionOfDrag = 'left';
    startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]);
    endOfDragCoords = new _src.CellCoords(endSelection[2], startSelection[1] - 1);
  } else if (endSelection[2] === startSelection[2] && endSelection[0] === startSelection[0] && endSelection[3] > startSelection[3]) {
    directionOfDrag = 'right';
    startOfDragCoords = new _src.CellCoords(endSelection[0], startSelection[3] + 1);
    endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]);
  } else if (endSelection[0] < startSelection[0] && endSelection[1] === startSelection[1]) {
    directionOfDrag = 'up';
    startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]);
    endOfDragCoords = new _src.CellCoords(startSelection[0] - 1, endSelection[3]);
  } else if (endSelection[2] > startSelection[2] && endSelection[1] === startSelection[1]) {
    directionOfDrag = 'down';
    startOfDragCoords = new _src.CellCoords(startSelection[2] + 1, endSelection[1]);
    endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]);
  }

  return {
    directionOfDrag: directionOfDrag,
    startOfDragCoords: startOfDragCoords,
    endOfDragCoords: endOfDragCoords
  };
}
/**
 * Get mapped FillHandle setting containing information about
 * allowed FillHandle directions and if allowed is automatic insertion of rows on drag
 *
 * @param {Boolean|Object} fillHandle property of Handsontable settings
 * @returns {{directions: Array, autoInsertRow: Boolean}} object allowing access to information
 * about FillHandle in more useful way
 */


function getMappedFillHandleSetting(fillHandle) {
  var mappedSettings = {};

  if (fillHandle === true) {
    mappedSettings.directions = Object.keys(DIRECTIONS);
    mappedSettings.autoInsertRow = true;
  } else if ((0, _object.isObject)(fillHandle)) {
    if ((0, _mixed.isDefined)(fillHandle.autoInsertRow)) {
      // autoInsertRow for horizontal direction will be always false
      if (fillHandle.direction === DIRECTIONS.horizontal) {
        mappedSettings.autoInsertRow = false;
      } else {
        mappedSettings.autoInsertRow = fillHandle.autoInsertRow;
      }
    } else {
      mappedSettings.autoInsertRow = false;
    }

    if ((0, _mixed.isDefined)(fillHandle.direction)) {
      mappedSettings.directions = [fillHandle.direction];
    } else {
      mappedSettings.directions = Object.keys(DIRECTIONS);
    }
  } else if (typeof fillHandle === 'string') {
    mappedSettings.directions = [fillHandle];
    mappedSettings.autoInsertRow = true;
  } else {
    mappedSettings.directions = [];
    mappedSettings.autoInsertRow = false;
  }

  return mappedSettings;
}

/***/ }),
/* 600 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _array = __webpack_require__(3);

var _feature = __webpack_require__(73);

var _element = __webpack_require__(5);

var _ghostTable = _interopRequireDefault(__webpack_require__(163));

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

var _samplesGenerator = _interopRequireDefault(__webpack_require__(483));

var _string = __webpack_require__(68);

/**
 * @plugin AutoRowSize
 *
 * @description
 * This plugin allows to set row heights based on their highest cells.
 *
 * By default, the plugin is declared as `undefined`, which makes it disabled (same as if it was declared as `false`).
 * Enabling this plugin may decrease the overall table performance, as it needs to calculate the heights of all cells to
 * resize the rows accordingly.
 * If you experience problems with the performance, try turning this feature off and declaring the row heights manually.
 *
 * Row height calculations are divided into sync and async part. Each of this parts has their own advantages and
 * disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous
 * operations don't block the browser UI.
 *
 * To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object:
 * ```js
 * // as a number (300 columns in sync, rest async)
 * autoRowSize: {syncLimit: 300},
 *
 * // as a string (percent)
 * autoRowSize: {syncLimit: '40%'},
 *
 * // allow sample duplication
 * autoRowSize: {syncLimit: '40%', allowSampleDuplicates: true},
 * ```
 *
 * You can also use the `allowSampleDuplicates` option to allow sampling duplicate values when calculating the row
 * height. __Note__, that this might have a negative impact on performance.
 *
 * To configure this plugin see {@link Options#autoRowSize}.
 *
 * @example
 *
 * ```js
 * const hot = new Handsontable(document.getElementById('example'), {
 *   date: getData(),
 *   autoRowSize: true
 * });
 * // Access to plugin instance:
 * const plugin = hot.getPlugin('autoRowSize');
 *
 * plugin.getRowHeight(4);
 *
 * if (plugin.isEnabled()) {
 *   // code...
 * }
 * ```
 */
var AutoRowSize =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(AutoRowSize, _BasePlugin);
  (0, _createClass2.default)(AutoRowSize, null, [{
    key: "CALCULATION_STEP",
    get: function get() {
      return 50;
    }
  }, {
    key: "SYNC_CALCULATION_LIMIT",
    get: function get() {
      return 500;
    }
  }]);

  function AutoRowSize(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, AutoRowSize);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(AutoRowSize).call(this, hotInstance));
    /**
     * Cached rows heights.
     *
     * @type {Number[]}
     */

    _this.heights = [];
    /**
     * Instance of {@link GhostTable} for rows and columns size calculations.
     *
     * @private
     * @type {GhostTable}
     */

    _this.ghostTable = new _ghostTable.default(_this.hot);
    /**
     * Instance of {@link SamplesGenerator} for generating samples necessary for rows height calculations.
     *
     * @private
     * @type {SamplesGenerator}
     */

    _this.samplesGenerator = new _samplesGenerator.default(function (row, col) {
      var cellValue;

      if (row >= 0) {
        cellValue = _this.hot.getDataAtCell(row, col);
      } else if (row === -1) {
        cellValue = _this.hot.getColHeader(col);
      }

      return {
        value: cellValue
      };
    });
    /**
     * `true` if only the first calculation was performed.
     *
     * @private
     * @type {Boolean}
     */

    _this.firstCalculation = true;
    /**
     * `true` if the size calculation is in progress.
     *
     * @type {Boolean}
     */

    _this.inProgress = false; // moved to constructor to allow auto-sizing the rows when the plugin is disabled

    _this.addHook('beforeRowResize', function (row, size, isDblClick) {
      return _this.onBeforeRowResize(row, size, isDblClick);
    });

    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link AutoRowSize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(AutoRowSize, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().autoRowSize === true || (0, _object.isObject)(this.hot.getSettings().autoRowSize);
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.setSamplingOptions();
      this.addHook('afterLoadData', function () {
        return _this2.onAfterLoadData();
      });
      this.addHook('beforeChange', function (changes) {
        return _this2.onBeforeChange(changes);
      });
      this.addHook('beforeColumnMove', function () {
        return _this2.recalculateAllRowsHeight();
      });
      this.addHook('beforeColumnResize', function () {
        return _this2.recalculateAllRowsHeight();
      });
      this.addHook('beforeColumnSort', function () {
        return _this2.clearCache();
      });
      this.addHook('beforeRender', function (force) {
        return _this2.onBeforeRender(force);
      });
      this.addHook('beforeRowMove', function (rowStart, rowEnd) {
        return _this2.onBeforeRowMove(rowStart, rowEnd);
      });
      this.addHook('modifyRowHeight', function (height, row) {
        return _this2.getRowHeight(row, height);
      });
      this.addHook('modifyColumnHeaderHeight', function () {
        return _this2.getColumnHeaderHeight();
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoRowSize.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoRowSize.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Calculate a given rows height.
     *
     * @param {Number|Object} rowRange Row index or an object with `from` and `to` indexes as a range.
     * @param {Number|Object} colRange Column index or an object with `from` and `to` indexes as a range.
     * @param {Boolean} [force=false] If `true` the calculation will be processed regardless of whether the width exists in the cache.
     */

  }, {
    key: "calculateRowsHeight",
    value: function calculateRowsHeight() {
      var _this3 = this;

      var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        from: 0,
        to: this.hot.countRows() - 1
      };
      var colRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        from: 0,
        to: this.hot.countCols() - 1
      };
      var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var rowsRange = typeof rowRange === 'number' ? {
        from: rowRange,
        to: rowRange
      } : rowRange;
      var columnsRange = typeof colRange === 'number' ? {
        from: colRange,
        to: colRange
      } : colRange;

      if (this.hot.getColHeader(0) !== null) {
        var samples = this.samplesGenerator.generateRowSamples(-1, columnsRange);
        this.ghostTable.addColumnHeadersRow(samples.get(-1));
      }

      (0, _number.rangeEach)(rowsRange.from, rowsRange.to, function (row) {
        // For rows we must calculate row height even when user had set height value manually.
        // We can shrink column but cannot shrink rows!
        if (force || _this3.heights[row] === void 0) {
          var _samples = _this3.samplesGenerator.generateRowSamples(row, columnsRange);

          (0, _array.arrayEach)(_samples, function (_ref) {
            var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
                rowIndex = _ref2[0],
                sample = _ref2[1];

            return _this3.ghostTable.addRow(rowIndex, sample);
          });
        }
      });

      if (this.ghostTable.rows.length) {
        this.ghostTable.getHeights(function (row, height) {
          _this3.heights[row] = height;
        });
        this.ghostTable.clean();
      }
    }
    /**
     * Calculate all rows heights. The calculated row will be cached in the {@link AutoRowSize#heights} property.
     * To retrieve height for specyfied row use {@link AutoRowSize#getRowHeight} method.
     *
     * @param {Object|Number} rowRange Row index or an object with `from` and `to` properties which define row range.
     */

  }, {
    key: "calculateAllRowsHeight",
    value: function calculateAllRowsHeight() {
      var _this4 = this;

      var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        from: 0,
        to: this.hot.countCols() - 1
      };
      var current = 0;
      var length = this.hot.countRows() - 1;
      var timer = null;
      this.inProgress = true;

      var loop = function loop() {
        // When hot was destroyed after calculating finished cancel frame
        if (!_this4.hot) {
          (0, _feature.cancelAnimationFrame)(timer);
          _this4.inProgress = false;
          return;
        }

        _this4.calculateRowsHeight({
          from: current,
          to: Math.min(current + AutoRowSize.CALCULATION_STEP, length)
        }, colRange);

        current = current + AutoRowSize.CALCULATION_STEP + 1;

        if (current < length) {
          timer = (0, _feature.requestAnimationFrame)(loop);
        } else {
          (0, _feature.cancelAnimationFrame)(timer);
          _this4.inProgress = false; // @TODO Should call once per render cycle, currently fired separately in different plugins

          _this4.hot.view.wt.wtOverlays.adjustElementsSize(true); // tmp


          if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) {
            _this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw();
          }
        }
      };

      var syncLimit = this.getSyncCalculationLimit(); // sync

      if (this.firstCalculation && syncLimit >= 0) {
        this.calculateRowsHeight({
          from: 0,
          to: syncLimit
        }, colRange);
        this.firstCalculation = false;
        current = syncLimit + 1;
      } // async


      if (current < length) {
        loop();
      } else {
        this.inProgress = false;
        this.hot.view.wt.wtOverlays.adjustElementsSize(false);
      }
    }
    /**
     * Sets the sampling options.
     *
     * @private
     */

  }, {
    key: "setSamplingOptions",
    value: function setSamplingOptions() {
      var setting = this.hot.getSettings().autoRowSize;
      var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoRowSize.samplingRatio : void 0;
      var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoRowSize.allowSampleDuplicates : void 0;

      if (samplingRatio && !isNaN(samplingRatio)) {
        this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10));
      }

      if (allowSampleDuplicates) {
        this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates);
      }
    }
    /**
     * Recalculates all rows height (overwrite cache values).
     */

  }, {
    key: "recalculateAllRowsHeight",
    value: function recalculateAllRowsHeight() {
      if ((0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) {
        this.clearCache();
        this.calculateAllRowsHeight();
      }
    }
    /**
     * Gets value which tells how many rows should be calculated synchronously (rest of the rows will be calculated
     * asynchronously). The limit is calculated based on `syncLimit` set to autoRowSize option (see {@link Options#autoRowSize}).
     *
     * @returns {Number}
     */

  }, {
    key: "getSyncCalculationLimit",
    value: function getSyncCalculationLimit() {
      /* eslint-disable no-bitwise */
      var limit = AutoRowSize.SYNC_CALCULATION_LIMIT;
      var rowsLimit = this.hot.countRows() - 1;

      if ((0, _object.isObject)(this.hot.getSettings().autoRowSize)) {
        limit = this.hot.getSettings().autoRowSize.syncLimit;

        if ((0, _string.isPercentValue)(limit)) {
          limit = (0, _number.valueAccordingPercent)(rowsLimit, limit);
        } else {
          // Force to Number
          limit >>= 0;
        }
      }

      return Math.min(limit, rowsLimit);
    }
    /**
     * Gets the calculated row height.
     *
     * @param {Number} row Visual row index.
     * @param {Number} [defaultHeight] Default row height. It will be picked up if no calculated height found.
     * @returns {Number}
     */

  }, {
    key: "getRowHeight",
    value: function getRowHeight(row) {
      var defaultHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0;
      var height = defaultHeight;

      if (this.heights[row] !== void 0 && this.heights[row] > (defaultHeight || 0)) {
        height = this.heights[row];
      }

      return height;
    }
    /**
     * Get the calculated column header height.
     *
     * @returns {Number|undefined}
     */

  }, {
    key: "getColumnHeaderHeight",
    value: function getColumnHeaderHeight() {
      return this.heights[-1];
    }
    /**
     * Get the first visible row.
     *
     * @returns {Number|null} Returns row index, -1 if table is not rendered or null if there are no rows to base the the calculations on.
     */

  }, {
    key: "getFirstVisibleRow",
    value: function getFirstVisibleRow() {
      var wot = this.hot.view.wt;

      if (wot.wtViewport.rowsVisibleCalculator) {
        return wot.wtTable.getFirstVisibleRow();
      }

      if (wot.wtViewport.rowsRenderCalculator) {
        return wot.wtTable.getFirstRenderedRow();
      }

      return -1;
    }
    /**
     * Gets the last visible row.
     *
     * @returns {Number} Returns row index or -1 if table is not rendered.
     */

  }, {
    key: "getLastVisibleRow",
    value: function getLastVisibleRow() {
      var wot = this.hot.view.wt;

      if (wot.wtViewport.rowsVisibleCalculator) {
        return wot.wtTable.getLastVisibleRow();
      }

      if (wot.wtViewport.rowsRenderCalculator) {
        return wot.wtTable.getLastRenderedRow();
      }

      return -1;
    }
    /**
     * Clears cached heights.
     */

  }, {
    key: "clearCache",
    value: function clearCache() {
      this.heights.length = 0;
      this.heights[-1] = void 0;
    }
    /**
     * Clears cache by range.
     *
     * @param {Object|Number} range Row index or an object with `from` and `to` properties which define row range.
     */

  }, {
    key: "clearCacheByRange",
    value: function clearCacheByRange(range) {
      var _this5 = this;

      var _ref3 = typeof range === 'number' ? {
        from: range,
        to: range
      } : range,
          from = _ref3.from,
          to = _ref3.to;

      (0, _number.rangeEach)(Math.min(from, to), Math.max(from, to), function (row) {
        _this5.heights[row] = void 0;
      });
    }
    /**
     * Checks if all heights were calculated. If not then return `true` (need recalculate).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isNeedRecalculate",
    value: function isNeedRecalculate() {
      return !!(0, _array.arrayFilter)(this.heights, function (item) {
        return item === void 0;
      }).length;
    }
    /**
     * On before render listener.
     *
     * @private
     */

  }, {
    key: "onBeforeRender",
    value: function onBeforeRender() {
      var force = this.hot.renderCall;
      var fixedRowsBottom = this.hot.getSettings().fixedRowsBottom;
      var firstVisibleRow = this.getFirstVisibleRow();
      var lastVisibleRow = this.getLastVisibleRow();

      if (firstVisibleRow === null || lastVisibleRow === null) {
        return;
      }

      this.calculateRowsHeight({
        from: firstVisibleRow,
        to: lastVisibleRow
      }, void 0, force); // Calculate rows height synchronously for bottom overlay

      if (fixedRowsBottom) {
        var totalRows = this.hot.countRows() - 1;
        this.calculateRowsHeight({
          from: totalRows - fixedRowsBottom,
          to: totalRows
        });
      }

      if (this.isNeedRecalculate() && !this.inProgress) {
        this.calculateAllRowsHeight();
      }
    }
    /**
     * On before row move listener.
     *
     * @private
     * @param {Number} from Row index where was grabbed.
     * @param {Number} to Destination row index.
     */

  }, {
    key: "onBeforeRowMove",
    value: function onBeforeRowMove(from, to) {
      this.clearCacheByRange({
        from: from,
        to: to
      });
      this.calculateAllRowsHeight();
    }
    /**
     * On before row resize listener.
     *
     * @private
     * @param {Number} row
     * @param {Number} size
     * @param {Boolean} isDblClick
     * @returns {Number}
     */

  }, {
    key: "onBeforeRowResize",
    value: function onBeforeRowResize(row, size, isDblClick) {
      var newSize = size;

      if (isDblClick) {
        this.calculateRowsHeight(row, void 0, true);
        newSize = this.getRowHeight(row);
      }

      return newSize;
    }
    /**
     * On after load data listener.
     *
     * @private
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData() {
      var _this6 = this;

      if (this.hot.view) {
        this.recalculateAllRowsHeight();
      } else {
        // first load - initialization
        setTimeout(function () {
          if (_this6.hot) {
            _this6.recalculateAllRowsHeight();
          }
        }, 0);
      }
    }
    /**
     * On before change listener.
     *
     * @private
     * @param {Array} changes
     */

  }, {
    key: "onBeforeChange",
    value: function onBeforeChange(changes) {
      var range = null;

      if (changes.length === 1) {
        range = changes[0][0];
      } else if (changes.length > 1) {
        range = {
          from: changes[0][0],
          to: changes[changes.length - 1][0]
        };
      }

      if (range !== null) {
        this.clearCacheByRange(range);
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.ghostTable.clean();
      (0, _get2.default)((0, _getPrototypeOf2.default)(AutoRowSize.prototype), "destroy", this).call(this);
    }
  }]);
  return AutoRowSize;
}(_base.default);

(0, _plugins.registerPlugin)('autoRowSize', AutoRowSize);
var _default = AutoRowSize;
exports.default = _default;

/***/ }),
/* 601 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 19.1.2.1 Object.assign(target, source, ...)
var objectKeys = __webpack_require__(89);
var getOwnPropertySymbolsModule = __webpack_require__(119);
var propertyIsEnumerableModule = __webpack_require__(95);
var toObject = __webpack_require__(62);
var IndexedObject = __webpack_require__(113);
var nativeAssign = Object.assign;

// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !nativeAssign || __webpack_require__(29)(function () {
  var A = {};
  var B = {};
  // eslint-disable-next-line no-undef
  var symbol = Symbol();
  var alphabet = 'abcdefghijklmnopqrst';
  A[symbol] = 7;
  alphabet.split('').forEach(function (chr) { B[chr] = chr; });
  return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
  var T = toObject(target);
  var argumentsLength = arguments.length;
  var index = 1;
  var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
  var propertyIsEnumerable = propertyIsEnumerableModule.f;
  while (argumentsLength > index) {
    var S = IndexedObject(arguments[index++]);
    var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
    var length = keys.length;
    var j = 0;
    var key;
    while (length > j) if (propertyIsEnumerable.call(S, key = keys[j++])) T[key] = S[key];
  } return T;
} : nativeAssign;


/***/ }),
/* 602 */
/***/ (function(module, exports, __webpack_require__) {

var objectWithoutPropertiesLoose = __webpack_require__(603);

function _objectWithoutProperties(source, excluded) {
  if (source == null) return {};
  var target = objectWithoutPropertiesLoose(source, excluded);
  var key, i;

  if (Object.getOwnPropertySymbols) {
    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);

    for (i = 0; i < sourceSymbolKeys.length; i++) {
      key = sourceSymbolKeys[i];
      if (excluded.indexOf(key) >= 0) continue;
      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
      target[key] = source[key];
    }
  }

  return target;
}

module.exports = _objectWithoutProperties;

/***/ }),
/* 603 */
/***/ (function(module, exports) {

function _objectWithoutPropertiesLoose(source, excluded) {
  if (source == null) return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;

  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0) continue;
    target[key] = source[key];
  }

  return target;
}

module.exports = _objectWithoutPropertiesLoose;

/***/ }),
/* 604 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(159);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(39);

exports.__esModule = true;
exports.ColumnStatesManager = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var inheritedColumnProperties = ['sortEmptyCells', 'indicator', 'headerAction', 'compareFunctionFactory'];
var SORT_EMPTY_CELLS_DEFAULT = false;
var SHOW_SORT_INDICATOR_DEFAULT = true;
var HEADER_ACTION_DEFAULT = true;
/**
 * Store and manages states of sorted columns.
 *
 * @class ColumnStatesManager
 * @plugin ColumnSorting
 */
// eslint-disable-next-line import/prefer-default-export

var ColumnStatesManager =
/*#__PURE__*/
function () {
  function ColumnStatesManager() {
    (0, _classCallCheck2.default)(this, ColumnStatesManager);

    /**
     * Queue of sort states containing sorted columns and their orders (Array of objects containing `column` and `sortOrder` properties).
     *
     * @type {Array}
     */
    this.sortedColumnsStates = [];
    /**
     * Determines whether we should sort empty cells.
     *
     * @type {Boolean}
     */

    this.sortEmptyCells = SORT_EMPTY_CELLS_DEFAULT;
    /**
     * Determines whether indicator should be visible (for sorted columns).
     *
     * @type {Boolean}
     */

    this.indicator = SHOW_SORT_INDICATOR_DEFAULT;
    /**
     * Determines whether click on the header perform sorting.
     *
     * @type {Boolean}
     */

    this.headerAction = HEADER_ACTION_DEFAULT;
    /**
     * Determines compare function factory. Method get as parameters `sortOder` and `columnMeta` and return compare function.
     */

    this.compareFunctionFactory = void 0;
  }
  /**
   * Update column properties which affect the sorting result.
   *
   * **Note**: All column properties can be overwritten by [columns](https://docs.handsontable.com/pro/Options.html#columns) option.
   *
   * @param {Object} allSortSettings Column sorting plugin's configuration object.
   */


  (0, _createClass2.default)(ColumnStatesManager, [{
    key: "updateAllColumnsProperties",
    value: function updateAllColumnsProperties(allSortSettings) {
      var _this = this;

      if (!(0, _object.isObject)(allSortSettings)) {
        return;
      }

      (0, _object.objectEach)(allSortSettings, function (newValue, propertyName) {
        if (inheritedColumnProperties.includes(propertyName)) {
          _this[propertyName] = newValue;
        }
      });
    }
    /**
     * Get all column properties which affect the sorting result.
     *
     * @returns {Object}
     */

  }, {
    key: "getAllColumnsProperties",
    value: function getAllColumnsProperties() {
      var columnProperties = {
        sortEmptyCells: this.sortEmptyCells,
        indicator: this.indicator,
        headerAction: this.headerAction
      };

      if (typeof this.compareFunctionFactory === 'function') {
        columnProperties.compareFunctionFactory = this.compareFunctionFactory;
      }

      return columnProperties;
    }
    /**
     * Get index of first sorted column.
     *
     * @returns {Number|undefined}
     */

  }, {
    key: "getFirstSortedColumn",
    value: function getFirstSortedColumn() {
      var firstSortedColumn;

      if (this.getNumberOfSortedColumns() > 0) {
        firstSortedColumn = this.sortedColumnsStates[0].column;
      }

      return firstSortedColumn;
    }
    /**
     * Get sort order of column.
     *
     * @param {Number} searchedColumn Physical column index.
     * @returns {String|undefined} Sort order (`asc` for ascending, `desc` for descending and undefined for not sorted).
     */

  }, {
    key: "getSortOrderOfColumn",
    value: function getSortOrderOfColumn(searchedColumn) {
      var searchedState = this.sortedColumnsStates.find(function (_ref) {
        var column = _ref.column;
        return searchedColumn === column;
      });
      var sortOrder;

      if ((0, _object.isObject)(searchedState)) {
        sortOrder = searchedState.sortOrder;
      }

      return sortOrder;
    }
    /**
     * Get list of sorted columns.
     *
     * @returns {Array}
     */

  }, {
    key: "getSortedColumns",
    value: function getSortedColumns() {
      return (0, _array.arrayMap)(this.sortedColumnsStates, function (_ref2) {
        var column = _ref2.column;
        return column;
      });
    }
    /**
     * Get order of particular column in the states queue.
     *
     * @param {Number} column Physical column index.
     * @returns {Number}
     */

  }, {
    key: "getIndexOfColumnInSortQueue",
    value: function getIndexOfColumnInSortQueue(column) {
      return this.getSortedColumns().indexOf(column);
    }
    /**
     * Get number of sorted columns.
     *
     * @returns {Number}
     */

  }, {
    key: "getNumberOfSortedColumns",
    value: function getNumberOfSortedColumns() {
      return this.sortedColumnsStates.length;
    }
    /**
     * Get if list of sorted columns is empty.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isListOfSortedColumnsEmpty",
    value: function isListOfSortedColumnsEmpty() {
      return this.getNumberOfSortedColumns() === 0;
    }
    /**
     * Get if particular column is sorted.
     *
     * @param {Number} column Physical column index.
     * @returns {Boolean}
     */

  }, {
    key: "isColumnSorted",
    value: function isColumnSorted(column) {
      return this.getSortedColumns().includes(column);
    }
    /**
     * Get states for all sorted columns.
     *
     * @returns {Array}
     */

  }, {
    key: "getSortStates",
    value: function getSortStates() {
      return (0, _object.deepClone)(this.sortedColumnsStates);
    }
    /**
     * Get sort state for particular column. Object contains `column` and `sortOrder` properties.
     *
     * **Note**: Please keep in mind that returned objects expose **physical** column index under the `column` key.
     *
     * @param {Number} column Physical column index.
     * @returns {Object|undefined}
     */

  }, {
    key: "getColumnSortState",
    value: function getColumnSortState(column) {
      if (this.isColumnSorted(column)) {
        return (0, _object.deepClone)(this.sortedColumnsStates[this.getIndexOfColumnInSortQueue(column)]);
      }
    }
    /**
     * Set all sorted columns states.
     *
     * @param {Array} sortStates
     */

  }, {
    key: "setSortStates",
    value: function setSortStates(sortStates) {
      this.sortedColumnsStates = sortStates;
    }
    /**
     * Destroy the state manager.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.sortedColumnsStates.length = 0;
      this.sortedColumnsStates = null;
    }
  }]);
  return ColumnStatesManager;
}();

exports.ColumnStatesManager = ColumnStatesManager;

/***/ }),
/* 605 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(59);

__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.getClassesToAdd = getClassesToAdd;
exports.getClassedToRemove = getClassedToRemove;

var _utils = __webpack_require__(165);

/* eslint-disable import/prefer-default-export */
var HEADER_CLASS_ASC_SORT = 'ascending';
var HEADER_CLASS_DESC_SORT = 'descending';
var HEADER_CLASS_INDICATOR_DISABLED = 'indicatorDisabled';
var HEADER_SORT_CLASS = 'columnSorting';
var HEADER_ACTION_CLASS = 'sortAction';
var orderToCssClass = new Map([[_utils.ASC_SORT_STATE, HEADER_CLASS_ASC_SORT], [_utils.DESC_SORT_STATE, HEADER_CLASS_DESC_SORT]]);
/**
 * Get CSS classes which should be added to particular column header.
 * @param {Object} columnStatesManager Instance of column state manager.
 * @param {Number} column Physical column index.
 * @param {Boolean} showSortIndicator Indicates if indicator should be shown for the particular column.
 * @param {Boolean} headerAction Indicates if header click to sort should be possible.
 * @returns {Array} Array of CSS classes.
 */

function getClassesToAdd(columnStatesManager, column, showSortIndicator, headerAction) {
  var cssClasses = [HEADER_SORT_CLASS];

  if (headerAction) {
    cssClasses.push(HEADER_ACTION_CLASS);
  }

  if (showSortIndicator === false) {
    cssClasses.push(HEADER_CLASS_INDICATOR_DISABLED);
  } else if (columnStatesManager.isColumnSorted(column)) {
    var columnOrder = columnStatesManager.getSortOrderOfColumn(column);
    cssClasses.push(orderToCssClass.get(columnOrder));
  }

  return cssClasses;
}
/**
 * Get CSS classes which should be removed from column header.
 *
 * @returns {Array} Array of CSS classes.
 */


function getClassedToRemove() {
  return Array.from(orderToCssClass.values()).concat(HEADER_ACTION_CLASS, HEADER_CLASS_INDICATOR_DISABLED, HEADER_SORT_CLASS);
}

/***/ }),
/* 606 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

/**
 * @class RowsMapper
 */
var RowsMapper =
/*#__PURE__*/
function () {
  function RowsMapper() {
    (0, _classCallCheck2.default)(this, RowsMapper);
  }

  (0, _createClass2.default)(RowsMapper, [{
    key: "createMap",

    /**
     * Reset current map array and create new one.
     *
     * @param {Number} [length] Custom generated map length.
     */
    value: function createMap(length) {
      var _this = this;

      var originLength = length === void 0 ? this._arrayMap.length : length;
      this._arrayMap.length = 0;
      (0, _number.rangeEach)(originLength - 1, function (itemIndex) {
        _this._arrayMap[itemIndex] = itemIndex;
      });
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
  }]);
  return RowsMapper;
}();

(0, _object.mixin)(RowsMapper, _arrayMapper.default);
var _default = RowsMapper;
exports.default = _default;

/***/ }),
/* 607 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(40);

exports.__esModule = true;
exports.rootComparator = rootComparator;

var _toArray2 = _interopRequireDefault(__webpack_require__(486));

var _sortService = __webpack_require__(88);

/* eslint-disable import/prefer-default-export */

/**
 * Sort comparator handled by conventional sort algorithm.
 *
 * @param {Array} sortOrders Sort orders (`asc` for ascending, `desc` for descending).
 * @param {Array} columnMetas Column meta objects.
 * @returns {Function}
 */
function rootComparator(sortingOrders, columnMetas) {
  return function (rowIndexWithValues, nextRowIndexWithValues) {
    // We sort array of arrays. Single array is in form [rowIndex, ...values].
    // We compare just values, stored at second index of array.
    var _rowIndexWithValues = (0, _toArray2.default)(rowIndexWithValues),
        values = _rowIndexWithValues.slice(1);

    var _nextRowIndexWithValu = (0, _toArray2.default)(nextRowIndexWithValues),
        nextValues = _nextRowIndexWithValu.slice(1);

    return function getCompareResult(column) {
      var sortingOrder = sortingOrders[column];
      var columnMeta = columnMetas[column];
      var value = values[column];
      var nextValue = nextValues[column];
      var pluginSettings = columnMeta.columnSorting;
      var compareFunctionFactory = pluginSettings.compareFunctionFactory ? pluginSettings.compareFunctionFactory : (0, _sortService.getCompareFunctionFactory)(columnMeta.type);
      var compareResult = compareFunctionFactory(sortingOrder, columnMeta, pluginSettings)(value, nextValue); // DIFF - MultiColumnSorting & ColumnSorting: removed iteration through next sorted columns.

      return compareResult;
    }(0);
  };
}

/***/ }),
/* 608 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.compareFunctionFactory = compareFunctionFactory;
exports.COLUMN_DATA_TYPE = void 0;

var _mixed = __webpack_require__(27);

var _sortService = __webpack_require__(88);

/* eslint-disable import/prefer-default-export */

/**
 * Default sorting compare function factory. Method get as parameters `sortOrder` and `columnMeta` and return compare function.
 *
 * @param {String} sortOrder Sort order (`asc` for ascending, `desc` for descending).
 * @param {Object} columnMeta Column meta object.
 * @param {Object} columnPluginSettings Plugin settings for the column.
 * @returns {Function} The compare function.
 */
function compareFunctionFactory(sortOrder, columnMeta, columnPluginSettings) {
  return function (value, nextValue) {
    var sortEmptyCells = columnPluginSettings.sortEmptyCells;

    if (typeof value === 'string') {
      value = value.toLowerCase();
    }

    if (typeof nextValue === 'string') {
      nextValue = nextValue.toLowerCase();
    }

    if (value === nextValue) {
      return _sortService.DO_NOT_SWAP;
    }

    if ((0, _mixed.isEmpty)(value)) {
      if ((0, _mixed.isEmpty)(nextValue)) {
        return _sortService.DO_NOT_SWAP;
      } // Just fist value is empty and `sortEmptyCells` option was set


      if (sortEmptyCells) {
        return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
      }

      return _sortService.FIRST_AFTER_SECOND;
    }

    if ((0, _mixed.isEmpty)(nextValue)) {
      // Just second value is empty and `sortEmptyCells` option was set
      if (sortEmptyCells) {
        return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
      }

      return _sortService.FIRST_BEFORE_SECOND;
    }

    if (isNaN(value) && !isNaN(nextValue)) {
      return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
    } else if (!isNaN(value) && isNaN(nextValue)) {
      return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
    } else if (!(isNaN(value) || isNaN(nextValue))) {
      value = parseFloat(value);
      nextValue = parseFloat(nextValue);
    }

    if (value < nextValue) {
      return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
    }

    if (value > nextValue) {
      return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
    }

    return _sortService.DO_NOT_SWAP;
  };
}

var COLUMN_DATA_TYPE = 'default';
exports.COLUMN_DATA_TYPE = COLUMN_DATA_TYPE;

/***/ }),
/* 609 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.compareFunctionFactory = compareFunctionFactory;
exports.COLUMN_DATA_TYPE = void 0;

var _mixed = __webpack_require__(27);

var _sortService = __webpack_require__(88);

/* eslint-disable import/prefer-default-export */

/**
 * Numeric sorting compare function factory. Method get as parameters `sortOrder` and `columnMeta` and return compare function.
 *
 * @param {String} sortOrder Sort order (`asc` for ascending, `desc` for descending).
 * @param {Object} columnMeta Column meta object.
 * @param {Object} columnPluginSettings Plugin settings for the column.
 * @returns {Function} The compare function.
 */
function compareFunctionFactory(sortOrder, columnMeta, columnPluginSettings) {
  return function (value, nextValue) {
    var parsedFirstValue = parseFloat(value);
    var parsedSecondValue = parseFloat(nextValue);
    var sortEmptyCells = columnPluginSettings.sortEmptyCells; // Watch out when changing this part of code! Check below returns 0 (as expected) when comparing empty string, null, undefined

    if (parsedFirstValue === parsedSecondValue || isNaN(parsedFirstValue) && isNaN(parsedSecondValue)) {
      return _sortService.DO_NOT_SWAP;
    }

    if (sortEmptyCells) {
      if ((0, _mixed.isEmpty)(value)) {
        return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
      }

      if ((0, _mixed.isEmpty)(nextValue)) {
        return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
      }
    }

    if (isNaN(parsedFirstValue)) {
      return _sortService.FIRST_AFTER_SECOND;
    }

    if (isNaN(parsedSecondValue)) {
      return _sortService.FIRST_BEFORE_SECOND;
    }

    if (parsedFirstValue < parsedSecondValue) {
      return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
    } else if (parsedFirstValue > parsedSecondValue) {
      return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
    }

    return _sortService.DO_NOT_SWAP;
  };
}

var COLUMN_DATA_TYPE = 'numeric';
exports.COLUMN_DATA_TYPE = COLUMN_DATA_TYPE;

/***/ }),
/* 610 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.compareFunctionFactory = compareFunctionFactory;
exports.COLUMN_DATA_TYPE = void 0;

var _moment = _interopRequireDefault(__webpack_require__(63));

var _mixed = __webpack_require__(27);

var _sortService = __webpack_require__(88);

/* eslint-disable import/prefer-default-export */

/**
 * Date sorting compare function factory. Method get as parameters `sortOrder` and `columnMeta` and return compare function.
 *
 * @param {String} sortOrder Sort order (`asc` for ascending, `desc` for descending).
 * @param {Object} columnMeta Column meta object.
 * @param {Object} columnPluginSettings Plugin settings for the column.
 * @returns {Function} The compare function.
 */
function compareFunctionFactory(sortOrder, columnMeta, columnPluginSettings) {
  return function (value, nextValue) {
    var sortEmptyCells = columnPluginSettings.sortEmptyCells;

    if (value === nextValue) {
      return _sortService.DO_NOT_SWAP;
    }

    if ((0, _mixed.isEmpty)(value)) {
      if ((0, _mixed.isEmpty)(nextValue)) {
        return _sortService.DO_NOT_SWAP;
      } // Just fist value is empty and `sortEmptyCells` option was set


      if (sortEmptyCells) {
        return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
      }

      return _sortService.FIRST_AFTER_SECOND;
    }

    if ((0, _mixed.isEmpty)(nextValue)) {
      // Just second value is empty and `sortEmptyCells` option was set
      if (sortEmptyCells) {
        return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
      }

      return _sortService.FIRST_BEFORE_SECOND;
    }

    var dateFormat = columnMeta.dateFormat;
    var firstDate = (0, _moment.default)(value, dateFormat);
    var nextDate = (0, _moment.default)(nextValue, dateFormat);

    if (!firstDate.isValid()) {
      return _sortService.FIRST_AFTER_SECOND;
    }

    if (!nextDate.isValid()) {
      return _sortService.FIRST_BEFORE_SECOND;
    }

    if (nextDate.isAfter(firstDate)) {
      return sortOrder === 'asc' ? _sortService.FIRST_BEFORE_SECOND : _sortService.FIRST_AFTER_SECOND;
    }

    if (nextDate.isBefore(firstDate)) {
      return sortOrder === 'asc' ? _sortService.FIRST_AFTER_SECOND : _sortService.FIRST_BEFORE_SECOND;
    }

    return _sortService.DO_NOT_SWAP;
  };
}

var COLUMN_DATA_TYPE = 'date';
exports.COLUMN_DATA_TYPE = COLUMN_DATA_TYPE;

/***/ }),
/* 611 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(64);

exports.__esModule = true;
exports.sort = sort;
exports.FIRST_AFTER_SECOND = exports.FIRST_BEFORE_SECOND = exports.DO_NOT_SWAP = void 0;

var _mergeSort = _interopRequireDefault(__webpack_require__(612));

var _registry = __webpack_require__(487);

var DO_NOT_SWAP = 0;
exports.DO_NOT_SWAP = DO_NOT_SWAP;
var FIRST_BEFORE_SECOND = -1;
exports.FIRST_BEFORE_SECOND = FIRST_BEFORE_SECOND;
var FIRST_AFTER_SECOND = 1;
exports.FIRST_AFTER_SECOND = FIRST_AFTER_SECOND;

function sort(indexesWithData, rootComparatorId) {
  var rootComparator = (0, _registry.getRootComparator)(rootComparatorId);

  for (var _len = arguments.length, argsForRootComparator = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
    argsForRootComparator[_key - 2] = arguments[_key];
  }

  (0, _mergeSort.default)(indexesWithData, rootComparator.apply(void 0, argsForRootComparator));
}

/***/ }),
/* 612 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.default = mergeSort;

var _linkedList = _interopRequireDefault(__webpack_require__(613));

/**
 * Refactored implementation of mergeSort (part of javascript-algorithms project) by Github users:
 * mgechev, AndriiHeonia and lekkas (part of javascript-algorithms project - all project contributors
 * at repository website)
 *
 * Link to repository: https://github.com/mgechev/javascript-algorithms
 */

/**
 * Specifies a function that defines the sort order. The array is sorted according to each
 * character's Unicode code point value, according to the string conversion of each element.
 *
 * @param a {*} first compared element.
 * @param b {*} second compared element.
 * @returns {Number}
 */
var defaultCompareFunction = function defaultCompareFunction(a, b) {
  // sort lexically
  var firstValue = a.toString();
  var secondValue = b.toString();

  if (firstValue === secondValue) {
    return 0;
  } else if (firstValue < secondValue) {
    return -1;
  }

  return 1;
};
/**
 * Mergesort method which is recursively called for sorting the input array.
 *
 * @param {Array} array The array which should be sorted.
 * @param {Function} compareFunction Compares two items in an array. If compareFunction is not supplied,
 * elements are sorted by converting them to strings and comparing strings in Unicode code point order.
 * @param {Number} startIndex Left side of the subarray.
 * @param {Number} endIndex Right side of the subarray.
 * @returns {Array} Array with sorted subarray.
 */


function mergeSort(array) {
  var compareFunction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultCompareFunction;
  var startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  var endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length;

  if (Math.abs(endIndex - startIndex) <= 1) {
    return [];
  }

  var middleIndex = Math.ceil((startIndex + endIndex) / 2);
  mergeSort(array, compareFunction, startIndex, middleIndex);
  mergeSort(array, compareFunction, middleIndex, endIndex);
  return merge(array, compareFunction, startIndex, middleIndex, endIndex);
}
/**
 * Devides and sort merges two subarrays of given array
 *
 * @param {Array} array The array which subarrays should be sorted.
 * @param {Number} startIndex The start of the first subarray.
 *   This subarray is with end middle - 1.
 * @param {Number} middleIndex The start of the second array.
 * @param {Number} endIndex end - 1 is the end of the second array.
 * @returns {Array} The array with sorted subarray.
 */


function merge(array, compareFunction, startIndex, middleIndex, endIndex) {
  var leftElements = new _linkedList.default();
  var rightElements = new _linkedList.default();
  var leftSize = middleIndex - startIndex;
  var rightSize = endIndex - middleIndex;
  var maxSize = Math.max(leftSize, rightSize);
  var size = endIndex - startIndex;

  for (var _i = 0; _i < maxSize; _i += 1) {
    if (_i < leftSize) {
      leftElements.push(array[startIndex + _i]);
    }

    if (_i < rightSize) {
      rightElements.push(array[middleIndex + _i]);
    }
  }

  var i = 0;

  while (i < size) {
    if (leftElements.first && rightElements.first) {
      if (compareFunction(leftElements.first.data, rightElements.first.data) > 0) {
        array[startIndex + i] = rightElements.shift().data;
      } else {
        array[startIndex + i] = leftElements.shift().data;
      }
    } else if (leftElements.first) {
      array[startIndex + i] = leftElements.shift().data;
    } else {
      array[startIndex + i] = rightElements.shift().data;
    }

    i += 1;
  }

  return array;
}

/***/ }),
/* 613 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = exports.NodeStructure = void 0;

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

/**
 * Refactored implementation of LinkedList (part of javascript-algorithms project) by Github users:
 * mgechev, AndriiHeonia, Microfed and Jakeh (part of javascript-algorithms project - all project contributors
 * at repository website)
 *
 * Link to repository: https://github.com/mgechev/javascript-algorithms
 */

/**
 * Linked list node.
 *
 * @class NodeStructure
 * @util
 */
var NodeStructure = function NodeStructure(data) {
  (0, _classCallCheck2.default)(this, NodeStructure);

  /**
   * Data of the node.
   * @member {Object}
   */
  this.data = data;
  /**
   * Next node.
   * @member {NodeStructure}
   */

  this.next = null;
  /**
   * Previous node.
   * @member {NodeStructure}
   */

  this.prev = null;
};
/**
 * Linked list.
 *
 * @class LinkedList
 * @util
 */


exports.NodeStructure = NodeStructure;

var LinkedList =
/*#__PURE__*/
function () {
  function LinkedList() {
    (0, _classCallCheck2.default)(this, LinkedList);
    this.first = null;
    this.last = null;
  }
  /**
   * Add data to the end of linked list.
   *
   * @param {Object} data Data which should be added.
   */


  (0, _createClass2.default)(LinkedList, [{
    key: "push",
    value: function push(data) {
      var node = new NodeStructure(data);

      if (this.first === null) {
        this.first = node;
        this.last = node;
      } else {
        var temp = this.last;
        this.last = node;
        node.prev = temp;
        temp.next = node;
      }
    }
    /**
     * Add data to the beginning of linked list.
     *
     * @param {Object} data Data which should be added.
     */

  }, {
    key: "unshift",
    value: function unshift(data) {
      var node = new NodeStructure(data);

      if (this.first === null) {
        this.first = node;
        this.last = node;
      } else {
        var temp = this.first;
        this.first = node;
        node.next = temp;
        temp.prev = node;
      }
    }
    /**
     * In order traversal of the linked list.
     *
     * @param {Function} callback Callback which should be executed on each node.
     */

  }, {
    key: "inorder",
    value: function inorder(callback) {
      var temp = this.first;

      while (temp) {
        callback(temp);
        temp = temp.next;
      }
    }
    /**
     * Remove data from the linked list.
     *
     * @param {Object} data Data which should be removed.
     * @returns {Boolean} Returns true if data has been removed.
     */

  }, {
    key: "remove",
    value: function remove(data) {
      if (this.first === null) {
        return false;
      }

      var temp = this.first;
      var next;
      var prev;

      while (temp) {
        if (temp.data === data) {
          next = temp.next;
          prev = temp.prev;

          if (next) {
            next.prev = prev;
          }

          if (prev) {
            prev.next = next;
          }

          if (temp === this.first) {
            this.first = next;
          }

          if (temp === this.last) {
            this.last = prev;
          }

          return true;
        }

        temp = temp.next;
      }

      return false;
    }
    /**
     * Check if linked list contains cycle.
     *
     * @returns {Boolean} Returns true if linked list contains cycle.
     */

  }, {
    key: "hasCycle",
    value: function hasCycle() {
      var fast = this.first;
      var slow = this.first;

      while (true) {
        if (fast === null) {
          return false;
        }

        fast = fast.next;

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

        fast = fast.next;
        slow = slow.next;

        if (fast === slow) {
          return true;
        }
      }
    }
    /**
     * Return last node from the linked list.
     *
     * @returns {NodeStructure} Last node.
     */

  }, {
    key: "pop",
    value: function pop() {
      if (this.last === null) {
        return null;
      }

      var temp = this.last;
      this.last = this.last.prev;
      return temp;
    }
    /**
     * Return first node from the linked list.
     *
     * @returns {NodeStructure} First node.
     */

  }, {
    key: "shift",
    value: function shift() {
      if (this.first === null) {
        return null;
      }

      var temp = this.first;
      this.first = this.first.next;
      return temp;
    }
    /**
     * Reverses the linked list recursively
     */

  }, {
    key: "recursiveReverse",
    value: function recursiveReverse() {
      function inverse(current, next) {
        if (!next) {
          return;
        }

        inverse(next, next.next);
        next.next = current;
      }

      if (!this.first) {
        return;
      }

      inverse(this.first, this.first.next);
      this.first.next = null;
      var temp = this.first;
      this.first = this.last;
      this.last = temp;
    }
    /**
     * Reverses the linked list iteratively
     */

  }, {
    key: "reverse",
    value: function reverse() {
      if (!this.first || !this.first.next) {
        return;
      }

      var current = this.first.next;
      var prev = this.first;
      var temp;

      while (current) {
        temp = current.next;
        current.next = prev;
        prev.prev = current;
        prev = current;
        current = temp;
      }

      this.first.next = null;
      this.last.prev = null;
      temp = this.first;
      this.first = prev;
      this.last = temp;
    }
  }]);
  return LinkedList;
}();

var _default = LinkedList;
exports.default = _default;

/***/ }),
/* 614 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _src = __webpack_require__(25);

var _plugins = __webpack_require__(20);

var _base = _interopRequireDefault(__webpack_require__(21));

var _commentEditor = _interopRequireDefault(__webpack_require__(615));

var _utils = __webpack_require__(60);

var _displaySwitch = _interopRequireDefault(__webpack_require__(616));

var C = _interopRequireWildcard(__webpack_require__(11));

__webpack_require__(617);

var privatePool = new WeakMap();
var META_COMMENT = 'comment';
var META_COMMENT_VALUE = 'value';
var META_STYLE = 'style';
var META_READONLY = 'readOnly';
/**
 * @plugin Comments
 *
 * @description
 * This plugin allows setting and managing cell comments by either an option in the context menu or with the use of
 * the API.
 *
 * To enable the plugin, you'll need to set the comments property of the config object to `true`:
 * ```js
 * comments: true
 * ```
 *
 * or an object with extra predefined plugin config:
 *
 * ```js
 * comments: {
 *   displayDelay: 1000
 * }
 * ```
 *
 * To add comments at the table initialization, define the `comment` property in the `cell` config array as in an example below.
 *
 * @example
 *
 * ```js
 * const hot = new Handsontable(document.getElementById('example'), {
 *   date: getData(),
 *   comments: true,
 *   cell: [
 *     {row: 1, col: 1, comment: {value: 'Foo'}},
 *     {row: 2, col: 2, comment: {value: 'Bar'}}
 *   ]
 * });
 *
 * // Access to the Comments plugin instance:
 * const commentsPlugin = hot.getPlugin('comments');
 *
 * // Manage comments programmatically:
 * commentsPlugin.setCommentAtCell(1, 6, 'Comment contents');
 * commentsPlugin.showAtCell(1, 6);
 * commentsPlugin.removeCommentAtCell(1, 6);
 *
 * // You can also set range once and use proper methods:
 * commentsPlugin.setRange({from: {row: 1, col: 6}});
 * commentsPlugin.setComment('Comment contents');
 * commentsPlugin.show();
 * commentsPlugin.removeComment();
 * ```
 */

var Comments =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(Comments, _BasePlugin);

  function Comments(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, Comments);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Comments).call(this, hotInstance));
    /**
     * Instance of {@link CommentEditor}.
     *
     * @private
     * @type {CommentEditor}
     */

    _this.editor = null;
    /**
     * Instance of {@link DisplaySwitch}.
     *
     * @private
     * @type {DisplaySwitch}
     */

    _this.displaySwitch = null;
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = null;
    /**
     * Current cell range, an object with `from` property, with `row` and `col` properties (e.q. `{from: {row: 1, col: 6}}`).
     *
     * @type {Object}
     */

    _this.range = {};
    /**
     * @private
     * @type {Boolean}
     */

    _this.mouseDown = false;
    /**
     * @private
     * @type {Boolean}
     */

    _this.contextMenuEvent = false;
    /**
     * @private
     * @type {*}
     */

    _this.timer = null;
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      tempEditorDimensions: {},
      cellBelowCursor: null
    });
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link Comments#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Comments, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().comments;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      if (!this.editor) {
        this.editor = new _commentEditor.default(this.hot.rootDocument);
      }

      if (!this.eventManager) {
        this.eventManager = new _eventManager.default(this);
      }

      if (!this.displaySwitch) {
        this.displaySwitch = new _displaySwitch.default(this.getDisplayDelaySetting());
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.addToContextMenu(options);
      });
      this.addHook('afterRenderer', function (TD, row, col, prop, value, cellProperties) {
        return _this2.onAfterRenderer(TD, cellProperties);
      });
      this.addHook('afterScrollHorizontally', function () {
        return _this2.hide();
      });
      this.addHook('afterScrollVertically', function () {
        return _this2.hide();
      });
      this.addHook('afterBeginEditing', function () {
        return _this2.onAfterBeginEditing();
      });
      this.displaySwitch.addLocalHook('hide', function () {
        return _this2.hide();
      });
      this.displaySwitch.addLocalHook('show', function (row, col) {
        return _this2.showAtCell(row, col);
      });
      this.registerListeners();
      (0, _get2.default)((0, _getPrototypeOf2.default)(Comments.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(Comments.prototype), "updatePlugin", this).call(this);
      this.displaySwitch.updateDelay(this.getDisplayDelaySetting());
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(Comments.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Registers all necessary DOM listeners.
     *
     * @private
     */

  }, {
    key: "registerListeners",
    value: function registerListeners() {
      var _this3 = this;

      var rootDocument = this.hot.rootDocument;
      this.eventManager.addEventListener(rootDocument, 'mouseover', function (event) {
        return _this3.onMouseOver(event);
      });
      this.eventManager.addEventListener(rootDocument, 'mousedown', function (event) {
        return _this3.onMouseDown(event);
      });
      this.eventManager.addEventListener(rootDocument, 'mouseup', function () {
        return _this3.onMouseUp();
      });
      this.eventManager.addEventListener(this.editor.getInputElement(), 'blur', function () {
        return _this3.onEditorBlur();
      });
      this.eventManager.addEventListener(this.editor.getInputElement(), 'mousedown', function (event) {
        return _this3.onEditorMouseDown(event);
      });
      this.eventManager.addEventListener(this.editor.getInputElement(), 'mouseup', function (event) {
        return _this3.onEditorMouseUp(event);
      });
    }
    /**
     * Sets the current cell range to be able to use general methods like {@link Comments#setComment}, {@link Comments#removeComment}, {@link Comments#show}.
     *
     * @param {Object} range Object with `from` property, each with `row` and `col` properties.
     */

  }, {
    key: "setRange",
    value: function setRange(range) {
      this.range = range;
    }
    /**
     * Clears the currently selected cell.
     */

  }, {
    key: "clearRange",
    value: function clearRange() {
      this.range = {};
    }
    /**
     * Checks if the event target is a cell containing a comment.
     *
     * @private
     * @param {Event} event DOM event
     * @returns {Boolean}
     */

  }, {
    key: "targetIsCellWithComment",
    value: function targetIsCellWithComment(event) {
      var closestCell = (0, _element.closest)(event.target, 'TD', 'TBODY');
      return !!(closestCell && (0, _element.hasClass)(closestCell, 'htCommentCell') && (0, _element.closest)(closestCell, [this.hot.rootElement]));
    }
    /**
     * Checks if the event target is a comment textarea.
     *
     * @private
     * @param {Event} event DOM event.
     * @returns {Boolean}
     */

  }, {
    key: "targetIsCommentTextArea",
    value: function targetIsCommentTextArea(event) {
      return this.editor.getInputElement() === event.target;
    }
    /**
     * Sets a comment for a cell according to the previously set range (see {@link Comments#setRange}).
     *
     * @param {String} value Comment contents.
     */

  }, {
    key: "setComment",
    value: function setComment(value) {
      if (!this.range.from) {
        throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
      }

      var editorValue = this.editor.getValue();
      var comment = '';

      if (value !== null && value !== void 0) {
        comment = value;
      } else if (editorValue !== null && editorValue !== void 0) {
        comment = editorValue;
      }

      var row = this.range.from.row;
      var col = this.range.from.col;
      this.updateCommentMeta(row, col, (0, _defineProperty2.default)({}, META_COMMENT_VALUE, comment));
      this.hot.render();
    }
    /**
     * Sets a comment for a specified cell.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {String} value Comment contents.
     */

  }, {
    key: "setCommentAtCell",
    value: function setCommentAtCell(row, column, value) {
      this.setRange({
        from: new _src.CellCoords(row, column)
      });
      this.setComment(value);
    }
    /**
     * Removes a comment from a cell according to previously set range (see {@link Comments#setRange}).
     *
     * @param {Boolean} [forceRender=true] If set to `true`, the table will be re-rendered at the end of the operation.
     */

  }, {
    key: "removeComment",
    value: function removeComment() {
      var forceRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

      if (!this.range.from) {
        throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
      }

      this.hot.setCellMeta(this.range.from.row, this.range.from.col, META_COMMENT, void 0);

      if (forceRender) {
        this.hot.render();
      }

      this.hide();
    }
    /**
     * Removes a comment from a specified cell.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {Boolean} [forceRender=true] If `true`, the table will be re-rendered at the end of the operation.
     */

  }, {
    key: "removeCommentAtCell",
    value: function removeCommentAtCell(row, column) {
      var forceRender = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      this.setRange({
        from: new _src.CellCoords(row, column)
      });
      this.removeComment(forceRender);
    }
    /**
     * Gets comment from a cell according to previously set range (see {@link Comments#setRange}).
     *
     * @returns {String|undefined} Returns a content of the comment.
     */

  }, {
    key: "getComment",
    value: function getComment() {
      var row = this.range.from.row;
      var column = this.range.from.col;
      return this.getCommentMeta(row, column, META_COMMENT_VALUE);
    }
    /**
     * Gets comment from a cell at the provided coordinates.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @returns {String|undefined} Returns a content of the comment.
     */

  }, {
    key: "getCommentAtCell",
    value: function getCommentAtCell(row, column) {
      return this.getCommentMeta(row, column, META_COMMENT_VALUE);
    }
    /**
     * Shows the comment editor accordingly to the previously set range (see {@link Comments#setRange}).
     *
     * @returns {Boolean} Returns `true` if comment editor was shown.
     */

  }, {
    key: "show",
    value: function show() {
      if (!this.range.from) {
        throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
      }

      var meta = this.hot.getCellMeta(this.range.from.row, this.range.from.col);
      this.refreshEditor(true);
      this.editor.setValue(meta[META_COMMENT] ? meta[META_COMMENT][META_COMMENT_VALUE] :  false || '');

      if (this.editor.hidden) {
        this.editor.show();
      }

      return true;
    }
    /**
     * Shows comment editor according to cell coordinates.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @returns {Boolean} Returns `true` if comment editor was shown.
     */

  }, {
    key: "showAtCell",
    value: function showAtCell(row, column) {
      this.setRange({
        from: new _src.CellCoords(row, column)
      });
      return this.show();
    }
    /**
     * Hides the comment editor.
     */

  }, {
    key: "hide",
    value: function hide() {
      if (!this.editor.hidden) {
        this.editor.hide();
      }
    }
    /**
     * Refreshes comment editor position and styling.
     *
     * @param {Boolean} [force=false] If `true` then recalculation will be forced.
     */

  }, {
    key: "refreshEditor",
    value: function refreshEditor() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (!force && (!this.range.from || !this.editor.isVisible())) {
        return;
      }

      var rootWindow = this.hot.rootWindow;
      var _this$hot$view$wt = this.hot.view.wt,
          wtTable = _this$hot$view$wt.wtTable,
          wtOverlays = _this$hot$view$wt.wtOverlays,
          wtViewport = _this$hot$view$wt.wtViewport;
      var scrollableElement = wtOverlays.scrollableElement;
      var TD = wtTable.getCell(this.range.from);
      var row = this.range.from.row;
      var column = this.range.from.col;
      var cellOffset = (0, _element.offset)(TD);
      var lastColWidth = wtTable.getStretchedColumnWidth(column);
      var cellTopOffset = cellOffset.top < 0 ? 0 : cellOffset.top;
      var cellLeftOffset = cellOffset.left;

      if (wtViewport.hasVerticalScroll() && scrollableElement !== rootWindow) {
        cellTopOffset -= wtOverlays.topOverlay.getScrollPosition();
      }

      if (wtViewport.hasHorizontalScroll() && scrollableElement !== rootWindow) {
        cellLeftOffset -= wtOverlays.leftOverlay.getScrollPosition();
      }

      var x = cellLeftOffset + lastColWidth;
      var y = cellTopOffset;
      var commentStyle = this.getCommentMeta(row, column, META_STYLE);
      var readOnly = this.getCommentMeta(row, column, META_READONLY);

      if (commentStyle) {
        this.editor.setSize(commentStyle.width, commentStyle.height);
      } else {
        this.editor.resetSize();
      }

      this.editor.setReadOnlyState(readOnly);
      this.editor.setPosition(x, y);
    }
    /**
     * Checks if there is a comment for selected range.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "checkSelectionCommentsConsistency",
    value: function checkSelectionCommentsConsistency() {
      var selected = this.hot.getSelectedRangeLast();

      if (!selected) {
        return false;
      }

      var hasComment = false;
      var cell = selected.from; // IN EXCEL THERE IS COMMENT ONLY FOR TOP LEFT CELL IN SELECTION

      if (this.getCommentMeta(cell.row, cell.col, META_COMMENT_VALUE)) {
        hasComment = true;
      }

      return hasComment;
    }
    /**
     * Sets or update the comment-related cell meta.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {Object} metaObject Object defining all the comment-related meta information.
     */

  }, {
    key: "updateCommentMeta",
    value: function updateCommentMeta(row, column, metaObject) {
      var oldComment = this.hot.getCellMeta(row, column)[META_COMMENT];
      var newComment;

      if (oldComment) {
        newComment = (0, _object.deepClone)(oldComment);
        (0, _object.deepExtend)(newComment, metaObject);
      } else {
        newComment = metaObject;
      }

      this.hot.setCellMeta(row, column, META_COMMENT, newComment);
    }
    /**
     * Gets the comment related meta information.
     *
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {String} property Cell meta property.
     * @returns {Mixed}
     */

  }, {
    key: "getCommentMeta",
    value: function getCommentMeta(row, column, property) {
      var cellMeta = this.hot.getCellMeta(row, column);

      if (!cellMeta[META_COMMENT]) {
        return void 0;
      }

      return cellMeta[META_COMMENT][property];
    }
    /**
     * `mousedown` event callback.
     *
     * @private
     * @param {MouseEvent} event The `mousedown` event.
     */

  }, {
    key: "onMouseDown",
    value: function onMouseDown(event) {
      this.mouseDown = true;

      if (!this.hot.view || !this.hot.view.wt) {
        return;
      }

      if (!this.contextMenuEvent && !this.targetIsCommentTextArea(event)) {
        var eventCell = (0, _element.closest)(event.target, 'TD', 'TBODY');
        var coordinates = null;

        if (eventCell) {
          coordinates = this.hot.view.wt.wtTable.getCoords(eventCell);
        }

        if (!eventCell || this.range.from && coordinates && (this.range.from.row !== coordinates.row || this.range.from.col !== coordinates.col)) {
          this.hide();
        }
      }

      this.contextMenuEvent = false;
    }
    /**
     * `mouseover` event callback.
     *
     * @private
     * @param {MouseEvent} event The `mouseover` event.
     */

  }, {
    key: "onMouseOver",
    value: function onMouseOver(event) {

      var priv = privatePool.get(this);
      var rootDocument = this.hot.rootDocument;
      priv.cellBelowCursor = rootDocument.elementFromPoint(event.clientX, event.clientY);

      if (this.mouseDown || this.editor.isFocused() || (0, _element.hasClass)(event.target, 'wtBorder') || priv.cellBelowCursor !== event.target || !this.editor) {
        return;
      }

      if (this.targetIsCellWithComment(event)) {
        var coordinates = this.hot.view.wt.wtTable.getCoords(event.target);
        var range = {
          from: new _src.CellCoords(coordinates.row, coordinates.col)
        };
        this.displaySwitch.show(range);
      } else if ((0, _element.isChildOf)(event.target, rootDocument) && !this.targetIsCommentTextArea(event)) {
        this.displaySwitch.hide();
      }
    }
    /**
     * `mouseup` event callback.
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      this.mouseDown = false;
    }
    /** *
     * The `afterRenderer` hook callback..
     *
     * @private
     * @param {HTMLTableCellElement} TD The rendered `TD` element.
     * @param {Object} cellProperties The rendered cell's property object.
     */

  }, {
    key: "onAfterRenderer",
    value: function onAfterRenderer(TD, cellProperties) {
      if (cellProperties[META_COMMENT] && cellProperties[META_COMMENT][META_COMMENT_VALUE]) {
        (0, _element.addClass)(TD, cellProperties.commentedCellClassName);
      }
    }
    /**
     * `blur` event callback for the comment editor.
     *
     * @private
     */

  }, {
    key: "onEditorBlur",
    value: function onEditorBlur() {
      this.setComment();
    }
    /**
     * `mousedown` hook. Along with `onEditorMouseUp` used to simulate the textarea resizing event.
     *
     * @private
     * @param {MouseEvent} event The `mousedown` event.
     */

  }, {
    key: "onEditorMouseDown",
    value: function onEditorMouseDown(event) {
      var priv = privatePool.get(this);
      priv.tempEditorDimensions = {
        width: (0, _element.outerWidth)(event.target),
        height: (0, _element.outerHeight)(event.target)
      };
    }
    /**
     * `mouseup` hook. Along with `onEditorMouseDown` used to simulate the textarea resizing event.
     *
     * @private
     * @param {MouseEvent} event The `mouseup` event.
     */

  }, {
    key: "onEditorMouseUp",
    value: function onEditorMouseUp(event) {
      var priv = privatePool.get(this);
      var currentWidth = (0, _element.outerWidth)(event.target);
      var currentHeight = (0, _element.outerHeight)(event.target);

      if (currentWidth !== priv.tempEditorDimensions.width + 1 || currentHeight !== priv.tempEditorDimensions.height + 2) {
        this.updateCommentMeta(this.range.from.row, this.range.from.col, (0, _defineProperty2.default)({}, META_STYLE, {
          width: currentWidth,
          height: currentHeight
        }));
      }
    }
    /**
     * Context Menu's "Add comment" callback. Results in showing the comment editor.
     *
     * @private
     */

  }, {
    key: "onContextMenuAddComment",
    value: function onContextMenuAddComment() {
      var _this4 = this;

      this.displaySwitch.cancelHiding();
      var coords = this.hot.getSelectedRangeLast();
      this.contextMenuEvent = true;
      this.setRange({
        from: coords.from
      });
      this.show();
      setTimeout(function () {
        if (_this4.hot) {
          _this4.hot.deselectCell();

          _this4.editor.focus();
        }
      }, 10);
    }
    /**
     * Context Menu's "remove comment" callback.
     *
     * @private
     */

  }, {
    key: "onContextMenuRemoveComment",
    value: function onContextMenuRemoveComment() {
      var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
          from = _this$hot$getSelected.from,
          to = _this$hot$getSelected.to;

      this.contextMenuEvent = true;

      for (var i = from.row; i <= to.row; i++) {
        for (var j = from.col; j <= to.col; j++) {
          this.removeCommentAtCell(i, j, false);
        }
      }

      this.hot.render();
    }
    /**
     * Context Menu's "make comment read-only" callback.
     *
     * @private
     */

  }, {
    key: "onContextMenuMakeReadOnly",
    value: function onContextMenuMakeReadOnly() {
      var _this$hot$getSelected2 = this.hot.getSelectedRangeLast(),
          from = _this$hot$getSelected2.from,
          to = _this$hot$getSelected2.to;

      this.contextMenuEvent = true;

      for (var i = from.row; i <= to.row; i++) {
        for (var j = from.col; j <= to.col; j++) {
          var currentState = !!this.getCommentMeta(i, j, META_READONLY);
          this.updateCommentMeta(i, j, (0, _defineProperty2.default)({}, META_READONLY, !currentState));
        }
      }
    }
    /**
     * Add Comments plugin options to the Context Menu.
     *
     * @private
     * @param {Object} defaultOptions
     */

  }, {
    key: "addToContextMenu",
    value: function addToContextMenu(defaultOptions) {
      var _this5 = this;

      defaultOptions.items.push({
        name: '---------'
      }, {
        key: 'commentsAddEdit',
        name: function name() {
          if (_this5.checkSelectionCommentsConsistency()) {
            return _this5.hot.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_EDIT_COMMENT);
          }

          return _this5.hot.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ADD_COMMENT);
        },
        callback: function callback() {
          return _this5.onContextMenuAddComment();
        },
        disabled: function disabled() {
          return !(this.getSelectedLast() && !this.selection.isSelectedByCorner());
        }
      }, {
        key: 'commentsRemove',
        name: function name() {
          return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REMOVE_COMMENT);
        },
        callback: function callback() {
          return _this5.onContextMenuRemoveComment();
        },
        disabled: function disabled() {
          return _this5.hot.selection.isSelectedByCorner();
        }
      }, {
        key: 'commentsReadOnly',
        name: function name() {
          var _this6 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT);
          var hasProperty = (0, _utils.checkSelectionConsistency)(this.getSelectedRangeLast(), function (row, col) {
            var readOnlyProperty = _this6.getCellMeta(row, col)[META_COMMENT];

            if (readOnlyProperty) {
              readOnlyProperty = readOnlyProperty[META_READONLY];
            }

            if (readOnlyProperty) {
              return true;
            }
          });

          if (hasProperty) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          return _this5.onContextMenuMakeReadOnly();
        },
        disabled: function disabled() {
          return _this5.hot.selection.isSelectedByCorner() || !_this5.checkSelectionCommentsConsistency();
        }
      });
    }
    /**
     * Get `displayDelay` setting of comment plugin.
     *
     * @private
     * @returns {Number|undefined}
     */

  }, {
    key: "getDisplayDelaySetting",
    value: function getDisplayDelaySetting() {
      var commentSetting = this.hot.getSettings().comments;

      if ((0, _object.isObject)(commentSetting)) {
        return commentSetting.displayDelay;
      }

      return void 0;
    }
    /**
     * `afterBeginEditing` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterBeginEditing",
    value: function onAfterBeginEditing() {
      this.hide();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.editor) {
        this.editor.destroy();
      }

      if (this.displaySwitch) {
        this.displaySwitch.destroy();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(Comments.prototype), "destroy", this).call(this);
    }
  }]);
  return Comments;
}(_base.default);

(0, _plugins.registerPlugin)('comments', Comments);
var _default = Comments;
exports.default = _default;

/***/ }),
/* 615 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

/**
 * Comment editor for the Comments plugin.
 *
 * @class CommentEditor
 * @plugin Comments
 */
var CommentEditor =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(CommentEditor, null, [{
    key: "CLASS_EDITOR_CONTAINER",
    get: function get() {
      return 'htCommentsContainer';
    }
  }, {
    key: "CLASS_EDITOR",
    get: function get() {
      return 'htComments';
    }
  }, {
    key: "CLASS_INPUT",
    get: function get() {
      return 'htCommentTextArea';
    }
  }, {
    key: "CLASS_CELL",
    get: function get() {
      return 'htCommentCell';
    }
  }]);

  function CommentEditor(rootDocument) {
    (0, _classCallCheck2.default)(this, CommentEditor);
    this.rootDocument = rootDocument;
    this.editor = this.createEditor();
    this.editorStyle = this.editor.style;
    this.hidden = true;
    this.hide();
  }
  /**
   * Set position of the comments editor according to the  provided x and y coordinates.
   *
   * @param {Number} x X position (in pixels).
   * @param {Number} y Y position (in pixels).
   */


  (0, _createClass2.default)(CommentEditor, [{
    key: "setPosition",
    value: function setPosition(x, y) {
      this.editorStyle.left = "".concat(x, "px");
      this.editorStyle.top = "".concat(y, "px");
    }
    /**
     * Set the editor size according to the provided arguments.
     *
     * @param {Number} width Width in pixels.
     * @param {Number} height Height in pixels.
     */

  }, {
    key: "setSize",
    value: function setSize(width, height) {
      if (width && height) {
        var input = this.getInputElement();
        input.style.width = "".concat(width, "px");
        input.style.height = "".concat(height, "px");
      }
    }
    /**
     * Reset the editor size to its initial state.
     */

  }, {
    key: "resetSize",
    value: function resetSize() {
      var input = this.getInputElement();
      input.style.width = '';
      input.style.height = '';
    }
    /**
     * Set the read-only state for the comments editor.
     *
     * @param {Boolean} state The new read only state.
     */

  }, {
    key: "setReadOnlyState",
    value: function setReadOnlyState(state) {
      var input = this.getInputElement();
      input.readOnly = state;
    }
    /**
     * Show the comments editor.
     */

  }, {
    key: "show",
    value: function show() {
      this.editorStyle.display = 'block';
      this.hidden = false;
    }
    /**
     * Hide the comments editor.
     */

  }, {
    key: "hide",
    value: function hide() {
      this.editorStyle.display = 'none';
      this.hidden = true;
    }
    /**
     * Checks if the editor is visible.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isVisible",
    value: function isVisible() {
      return this.editorStyle.display === 'block';
    }
    /**
     * Set the comment value.
     *
     * @param {String} [value] The value to use.
     */

  }, {
    key: "setValue",
    value: function setValue() {
      var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
      var comment = value || '';
      this.getInputElement().value = comment;
    }
    /**
     * Get the comment value.
     *
     * @returns {String}
     */

  }, {
    key: "getValue",
    value: function getValue() {
      return this.getInputElement().value;
    }
    /**
     * Checks if the comment input element is focused.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isFocused",
    value: function isFocused() {
      return this.rootDocument.activeElement === this.getInputElement();
    }
    /**
     * Focus the comments input element.
     */

  }, {
    key: "focus",
    value: function focus() {
      this.getInputElement().focus();
    }
    /**
     * Create the `textarea` to be used as a comments editor.
     *
     * @returns {HTMLElement}
     */

  }, {
    key: "createEditor",
    value: function createEditor() {
      var editor = this.rootDocument.createElement('div');
      var textArea = this.rootDocument.createElement('textarea');
      var container = this.rootDocument.querySelector(".".concat(CommentEditor.CLASS_EDITOR_CONTAINER));

      if (!container) {
        container = this.rootDocument.createElement('div');
        (0, _element.addClass)(container, CommentEditor.CLASS_EDITOR_CONTAINER);
        this.rootDocument.body.appendChild(container);
      }

      (0, _element.addClass)(editor, CommentEditor.CLASS_EDITOR);
      (0, _element.addClass)(textArea, CommentEditor.CLASS_INPUT);
      editor.appendChild(textArea);
      container.appendChild(editor);
      return editor;
    }
    /**
     * Get the input element.
     *
     * @returns {HTMLElement}
     */

  }, {
    key: "getInputElement",
    value: function getInputElement() {
      return this.editor.querySelector(".".concat(CommentEditor.CLASS_INPUT));
    }
    /**
     * Destroy the comments editor.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.editor.parentNode.removeChild(this.editor);
      this.editor = null;
      this.editorStyle = null;
    }
  }]);
  return CommentEditor;
}();

var _default = CommentEditor;
exports.default = _default;

/***/ }),
/* 616 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _function = __webpack_require__(75);

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var DEFAULT_DISPLAY_DELAY = 250;
var DEFAULT_HIDE_DELAY = 250;
/**
 * Display switch for the Comments plugin. Manages the time of delayed displaying / hiding comments.
 *
 * @class DisplaySwitch
 * @plugin Comments
 */

var DisplaySwitch =
/*#__PURE__*/
function () {
  function DisplaySwitch(displayDelay) {
    (0, _classCallCheck2.default)(this, DisplaySwitch);

    /**
     * Flag to determine if comment can be showed or hidden. State `true` mean that last performed action
     * was an attempt to show comment element. State `false` mean that it was attempt to hide comment element.
     *
     * @type {Boolean}
     */
    this.wasLastActionShow = true;
    /**
     * Show comment after predefined delay. It keeps reference to immutable `debounce` function.
     *
     * @type {Function}
     */

    this.showDebounced = null;
    /**
     * Reference to timer, run by `setTimeout`, which is hiding comment
     *
     * @type {Number}
     */

    this.hidingTimer = null;
    this.updateDelay(displayDelay);
  }
  /**
   * Responsible for hiding comment after proper delay.
   */


  (0, _createClass2.default)(DisplaySwitch, [{
    key: "hide",
    value: function hide() {
      var _this = this;

      this.wasLastActionShow = false;
      this.hidingTimer = setTimeout(function () {
        if (_this.wasLastActionShow === false) {
          _this.runLocalHooks('hide');
        }
      }, DEFAULT_HIDE_DELAY);
    }
    /**
     * Responsible for showing comment after proper delay.
     *
     * @param {Object} range Coordinates of selected cell.
     */

  }, {
    key: "show",
    value: function show(range) {
      this.wasLastActionShow = true;
      this.showDebounced(range);
    }
    /**
     * Cancel hiding comment.
     */

  }, {
    key: "cancelHiding",
    value: function cancelHiding() {
      this.wasLastActionShow = true;
      clearTimeout(this.hidingTimer);
      this.hidingTimer = null;
    }
    /**
     * Update the switch settings.
     *
     * @param {Number} displayDelay Delay of showing the comments (in milliseconds).
     */

  }, {
    key: "updateDelay",
    value: function updateDelay() {
      var _this2 = this;

      var displayDelay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_DISPLAY_DELAY;
      this.showDebounced = (0, _function.debounce)(function (range) {
        if (_this2.wasLastActionShow) {
          _this2.runLocalHooks('show', range.from.row, range.from.col);
        }
      }, displayDelay);
    }
    /**
     * Destroy the switcher.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.clearLocalHooks();
    }
  }]);
  return DisplaySwitch;
}();

(0, _object.mixin)(DisplaySwitch, _localHooks.default);
var _default = DisplaySwitch;
exports.default = _default;

/***/ }),
/* 617 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 618 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _array = __webpack_require__(3);

var _commandExecutor = _interopRequireDefault(__webpack_require__(488));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _itemsFactory = _interopRequireDefault(__webpack_require__(489));

var _menu = _interopRequireDefault(__webpack_require__(167));

var _plugins = __webpack_require__(20);

var _event = __webpack_require__(31);

var _element = __webpack_require__(5);

var _predefinedItems = __webpack_require__(83);

__webpack_require__(632);

_pluginHooks.default.getSingleton().register('afterContextMenuDefaultOptions');

_pluginHooks.default.getSingleton().register('beforeContextMenuShow');

_pluginHooks.default.getSingleton().register('afterContextMenuShow');

_pluginHooks.default.getSingleton().register('afterContextMenuHide');

_pluginHooks.default.getSingleton().register('afterContextMenuExecute');
/**
 * @description
 * This plugin creates the Handsontable Context Menu. It allows to create a new row or column at any place in the
 * grid among [other features](https://handsontable.com/docs/demo-context-menu.html).
 * Possible values:
 * * `true` (to enable default options),
 * * `false` (to disable completely)
 *
 * or array of any available strings:
 * * `'row_above'`
 * * `'row_below'`
 * * `'col_left'`
 * * `'col_right'`
 * * `'remove_row'`
 * * `'remove_col'`
 * * `'undo'`
 * * `'redo'`
 * * `'make_read_only'`
 * * `'alignment'`
 * * `'---------'` (menu item separator)
 * * `'borders'` (with {@link Options#customBorders} turned on)
 * * `'commentsAddEdit'` (with {@link Options#comments} turned on)
 * * `'commentsRemove'` (with {@link Options#comments} turned on)
 *
 * See [the context menu demo](https://handsontable.com/docs/demo-context-menu.html) for examples.
 *
 * @example
 * ```js
 * // as a boolean
 * contextMenu: true
 * // as a array
 * contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo']
 * ```
 *
 * @plugin ContextMenu
 */


var ContextMenu =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ContextMenu, _BasePlugin);
  (0, _createClass2.default)(ContextMenu, null, [{
    key: "DEFAULT_ITEMS",

    /**
     * Context menu default items order when `contextMenu` options is set as `true`.
     *
     * @returns {String[]}
     */
    get: function get() {
      return [_predefinedItems.ROW_ABOVE, _predefinedItems.ROW_BELOW, _predefinedItems.SEPARATOR, _predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_ROW, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.UNDO, _predefinedItems.REDO, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT];
    }
  }]);

  function ContextMenu(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ContextMenu);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ContextMenu).call(this, hotInstance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Instance of {@link CommandExecutor}.
     *
     * @private
     * @type {CommandExecutor}
     */

    _this.commandExecutor = new _commandExecutor.default(_this.hot);
    /**
     * Instance of {@link ItemsFactory}.
     *
     * @private
     * @type {ItemsFactory}
     */

    _this.itemsFactory = null;
    /**
     * Instance of {@link Menu}.
     *
     * @private
     * @type {Menu}
     */

    _this.menu = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ContextMenu#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ContextMenu, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().contextMenu;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var settings = this.hot.getSettings().contextMenu;

      if (typeof settings.callback === 'function') {
        this.commandExecutor.setCommonCallback(settings.callback);
      }

      this.menu = new _menu.default(this.hot, {
        className: 'htContextMenu',
        keepInViewport: true
      });
      this.menu.addLocalHook('beforeOpen', function () {
        return _this2.onMenuBeforeOpen();
      });
      this.menu.addLocalHook('afterOpen', function () {
        return _this2.onMenuAfterOpen();
      });
      this.menu.addLocalHook('afterClose', function () {
        return _this2.onMenuAfterClose();
      });
      this.menu.addLocalHook('executeCommand', function () {
        var _this2$executeCommand;

        for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
          params[_key] = arguments[_key];
        }

        return (_this2$executeCommand = _this2.executeCommand).call.apply(_this2$executeCommand, [_this2].concat(params));
      });
      this.addHook('afterOnCellContextMenu', function (event) {
        return _this2.onAfterOnCellContextMenu(event);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(ContextMenu.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ContextMenu.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.close();

      if (this.menu) {
        this.menu.destroy();
        this.menu = null;
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(ContextMenu.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Opens menu and re-position it based on the passed coordinates.
     *
     * @param {Object|Event} position An object with `pageX` and `pageY` properties which contains values relative to
     *                                the top left of the fully rendered content area in the browser or with `clientX`
     *                                and `clientY`  properties which contains values relative to the upper left edge
     *                                of the content area (the viewport) of the browser window. This object is structurally
     *                                compatible with native mouse event so it can be used either.
     */

  }, {
    key: "open",
    value: function open(event) {
      if (!this.menu) {
        return;
      }

      this.prepareMenuItems();
      this.menu.open();

      if (!this.menu.isOpened()) {
        return;
      }

      this.menu.setPosition({
        top: parseInt((0, _event.pageY)(event), 10) - (0, _element.getWindowScrollTop)(this.hot.rootWindow),
        left: parseInt((0, _event.pageX)(event), 10) - (0, _element.getWindowScrollLeft)(this.hot.rootWindow)
      }); // ContextMenu is not detected HotTableEnv correctly because is injected outside hot-table

      this.menu.hotMenu.isHotTableEnv = this.hot.isHotTableEnv; // Handsontable.eventManager.isHotTableEnv = this.hot.isHotTableEnv;
    }
    /**
     * Closes the menu.
     */

  }, {
    key: "close",
    value: function close() {
      if (!this.menu) {
        return;
      }

      this.menu.close();
      this.itemsFactory = null;
    }
    /**
     * Execute context menu command.
     *
     * You can execute all predefined commands:
     *  * `'row_above'` - Insert row above
     *  * `'row_below'` - Insert row below
     *  * `'col_left'` - Insert column left
     *  * `'col_right'` - Insert column right
     *  * `'clear_column'` - Clear selected column
     *  * `'remove_row'` - Remove row
     *  * `'remove_col'` - Remove column
     *  * `'undo'` - Undo last action
     *  * `'redo'` - Redo last action
     *  * `'make_read_only'` - Make cell read only
     *  * `'alignment:left'` - Alignment to the left
     *  * `'alignment:top'` - Alignment to the top
     *  * `'alignment:right'` - Alignment to the right
     *  * `'alignment:bottom'` - Alignment to the bottom
     *  * `'alignment:middle'` - Alignment to the middle
     *  * `'alignment:center'` - Alignment to the center (justify)
     *
     * Or you can execute command registered in settings where `key` is your command name.
     *
     * @param {String} commandName The command name to be executed.
     * @param {...*} params
     */

  }, {
    key: "executeCommand",
    value: function executeCommand(commandName) {
      var _this$commandExecutor;

      if (this.itemsFactory === null) {
        this.prepareMenuItems();
      }

      for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        params[_key2 - 1] = arguments[_key2];
      }

      (_this$commandExecutor = this.commandExecutor).execute.apply(_this$commandExecutor, [commandName].concat(params));
    }
    /**
     * Prepares available contextMenu's items list and registers them in commandExecutor.
     *
     * @private
     * @fires Hooks#afterContextMenuDefaultOptions
     * @fires Hooks#beforeContextMenuSetItems
     */

  }, {
    key: "prepareMenuItems",
    value: function prepareMenuItems() {
      var _this3 = this;

      this.itemsFactory = new _itemsFactory.default(this.hot, ContextMenu.DEFAULT_ITEMS);
      var settings = this.hot.getSettings().contextMenu;
      var predefinedItems = {
        items: this.itemsFactory.getItems(settings)
      };
      this.hot.runHooks('afterContextMenuDefaultOptions', predefinedItems);
      this.itemsFactory.setPredefinedItems(predefinedItems.items);
      var menuItems = this.itemsFactory.getItems(settings);
      this.hot.runHooks('beforeContextMenuSetItems', menuItems);
      this.menu.setMenuItems(menuItems); // Register all commands. Predefined and added by user or by plugins

      (0, _array.arrayEach)(menuItems, function (command) {
        return _this3.commandExecutor.registerCommand(command.key, command);
      });
    }
    /**
     * On contextmenu listener.
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "onAfterOnCellContextMenu",
    value: function onAfterOnCellContextMenu(event) {
      var settings = this.hot.getSettings();
      var showRowHeaders = settings.rowHeaders;
      var showColHeaders = settings.colHeaders;

      function isValidElement(element) {
        return element.nodeName === 'TD' || element.parentNode.nodeName === 'TD';
      } // if event is from hot-table we must get web component element not element inside him


      var element = event.realTarget;
      this.close();

      if ((0, _element.hasClass)(element, 'handsontableInput')) {
        return;
      }

      event.preventDefault();
      (0, _event.stopPropagation)(event);

      if (!(showRowHeaders || showColHeaders)) {
        if (!isValidElement(element) && !((0, _element.hasClass)(element, 'current') && (0, _element.hasClass)(element, 'wtBorder'))) {
          return;
        }
      }

      this.open(event);
    }
    /**
     * On menu before open listener.
     *
     * @private
     */

  }, {
    key: "onMenuBeforeOpen",
    value: function onMenuBeforeOpen() {
      this.hot.runHooks('beforeContextMenuShow', this);
    }
    /**
     * On menu after open listener.
     *
     * @private
     */

  }, {
    key: "onMenuAfterOpen",
    value: function onMenuAfterOpen() {
      this.hot.runHooks('afterContextMenuShow', this);
    }
    /**
     * On menu after close listener.
     *
     * @private
     */

  }, {
    key: "onMenuAfterClose",
    value: function onMenuAfterClose() {
      this.hot.listen();
      this.hot.runHooks('afterContextMenuHide', this);
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.close();

      if (this.menu) {
        this.menu.destroy();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(ContextMenu.prototype), "destroy", this).call(this);
    }
  }]);
  return ContextMenu;
}(_base.default);

ContextMenu.SEPARATOR = {
  name: _predefinedItems.SEPARATOR
};
(0, _plugins.registerPlugin)('contextMenu', ContextMenu);
var _default = ContextMenu;
exports.default = _default;

/***/ }),
/* 619 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

__webpack_require__(12);

exports.__esModule = true;
exports.default = alignmentItem;
exports.KEY = void 0;

var _utils = __webpack_require__(60);

var _separator = __webpack_require__(166);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'alignment';
exports.KEY = KEY;

function alignmentItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT);
    },
    disabled: function disabled() {
      return !(this.getSelectedRange() && !this.selection.isSelectedByCorner());
    },
    submenu: {
      items: [{
        key: "".concat(KEY, ":left"),
        name: function name() {
          var _this = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this.getCellMeta(row, col).className;

            if (className && className.indexOf('htLeft') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this2 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this2.getCellMeta(row, col).className;
          });
          var type = 'horizontal';
          var alignment = 'htLeft';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this2.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this2.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        key: "".concat(KEY, ":center"),
        name: function name() {
          var _this3 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this3.getCellMeta(row, col).className;

            if (className && className.indexOf('htCenter') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this4 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this4.getCellMeta(row, col).className;
          });
          var type = 'horizontal';
          var alignment = 'htCenter';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this4.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this4.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        key: "".concat(KEY, ":right"),
        name: function name() {
          var _this5 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this5.getCellMeta(row, col).className;

            if (className && className.indexOf('htRight') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this6 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this6.getCellMeta(row, col).className;
          });
          var type = 'horizontal';
          var alignment = 'htRight';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this6.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this6.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        key: "".concat(KEY, ":justify"),
        name: function name() {
          var _this7 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this7.getCellMeta(row, col).className;

            if (className && className.indexOf('htJustify') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this8 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this8.getCellMeta(row, col).className;
          });
          var type = 'horizontal';
          var alignment = 'htJustify';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this8.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this8.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        name: _separator.KEY
      }, {
        key: "".concat(KEY, ":top"),
        name: function name() {
          var _this9 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_TOP);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this9.getCellMeta(row, col).className;

            if (className && className.indexOf('htTop') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this10 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this10.getCellMeta(row, col).className;
          });
          var type = 'vertical';
          var alignment = 'htTop';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this10.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this10.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        key: "".concat(KEY, ":middle"),
        name: function name() {
          var _this11 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this11.getCellMeta(row, col).className;

            if (className && className.indexOf('htMiddle') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this12 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this12.getCellMeta(row, col).className;
          });
          var type = 'vertical';
          var alignment = 'htMiddle';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this12.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this12.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }, {
        key: "".concat(KEY, ":bottom"),
        name: function name() {
          var _this13 = this;

          var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM);
          var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
            var className = _this13.getCellMeta(row, col).className;

            if (className && className.indexOf('htBottom') !== -1) {
              return true;
            }
          });

          if (hasClass) {
            label = (0, _utils.markLabelAsSelected)(label);
          }

          return label;
        },
        callback: function callback() {
          var _this14 = this;

          var selectedRange = this.getSelectedRange();
          var stateBefore = (0, _utils.getAlignmentClasses)(selectedRange, function (row, col) {
            return _this14.getCellMeta(row, col).className;
          });
          var type = 'vertical';
          var alignment = 'htBottom';
          this.runHooks('beforeCellAlignment', stateBefore, selectedRange, type, alignment);
          (0, _utils.align)(selectedRange, type, alignment, function (row, col) {
            return _this14.getCellMeta(row, col);
          }, function (row, col, key, value) {
            return _this14.setCellMeta(row, col, key, value);
          });
          this.render();
        },
        disabled: false
      }]
    }
  };
}

/***/ }),
/* 620 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(54);

exports.__esModule = true;
exports.default = clearColumnItem;
exports.KEY = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _utils = __webpack_require__(60);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'clear_column';
exports.KEY = KEY;

function clearColumnItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_CLEAR_COLUMN);
    },
    callback: function callback(key, selection) {
      var column = selection[0].start.col;

      if (this.countRows()) {
        this.populateFromArray(0, column, [[null]], Math.max(selection[0].start.row, selection[0].end.row), column, 'ContextMenu.clearColumn');
      }
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);

      if (!selected) {
        return true;
      }

      var _selected$ = (0, _slicedToArray2.default)(selected[0], 3),
          startRow = _selected$[0],
          startColumn = _selected$[1],
          endRow = _selected$[2];

      var entireRowSelection = [startRow, 0, endRow, this.countCols() - 1];
      var rowSelected = entireRowSelection.join(',') === selected.join(',');
      return startColumn < 0 || this.countCols() >= this.getSettings().maxCols || rowSelected;
    }
  };
}

/***/ }),
/* 621 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(54);

exports.__esModule = true;
exports.default = columnLeftItem;
exports.KEY = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _utils = __webpack_require__(60);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'col_left';
exports.KEY = KEY;

function columnLeftItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_INSERT_LEFT);
    },
    callback: function callback(key, normalizedSelection) {
      var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
      this.alter('insert_col', latestSelection.start.col, 1, 'ContextMenu.columnLeft');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);

      if (!selected) {
        return true;
      }

      if (!this.isColumnModificationAllowed()) {
        return true;
      }

      var _selected$ = (0, _slicedToArray2.default)(selected[0], 3),
          startRow = _selected$[0],
          startColumn = _selected$[1],
          endRow = _selected$[2];

      var entireRowSelection = [startRow, 0, endRow, this.countCols() - 1];
      var rowSelected = entireRowSelection.join(',') === selected.join(',');
      var onlyOneColumn = this.countCols() === 1;
      return startColumn < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
    },
    hidden: function hidden() {
      return !this.getSettings().allowInsertColumn;
    }
  };
}

/***/ }),
/* 622 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(54);

exports.__esModule = true;
exports.default = columnRightItem;
exports.KEY = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _utils = __webpack_require__(60);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'col_right';
exports.KEY = KEY;

function columnRightItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_INSERT_RIGHT);
    },
    callback: function callback(key, normalizedSelection) {
      var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
      this.alter('insert_col', latestSelection.end.col + 1, 1, 'ContextMenu.columnRight');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);

      if (!selected) {
        return true;
      }

      if (!this.isColumnModificationAllowed()) {
        return true;
      }

      var _selected$ = (0, _slicedToArray2.default)(selected[0], 3),
          startRow = _selected$[0],
          startColumn = _selected$[1],
          endRow = _selected$[2];

      var entireRowSelection = [startRow, 0, endRow, this.countCols() - 1];
      var rowSelected = entireRowSelection.join(',') === selected.join(',');
      var onlyOneColumn = this.countCols() === 1;
      return startColumn < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
    },
    hidden: function hidden() {
      return !this.getSettings().allowInsertColumn;
    }
  };
}

/***/ }),
/* 623 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = readOnlyItem;
exports.KEY = void 0;

var _utils = __webpack_require__(60);

var _array = __webpack_require__(3);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'make_read_only';
exports.KEY = KEY;

function readOnlyItem() {
  return {
    key: KEY,
    name: function name() {
      var _this = this;

      var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_READ_ONLY);
      var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
        return _this.getCellMeta(row, col).readOnly;
      });

      if (atLeastOneReadOnly) {
        label = (0, _utils.markLabelAsSelected)(label);
      }

      return label;
    },
    callback: function callback() {
      var _this2 = this;

      var ranges = this.getSelectedRange();
      var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(ranges, function (row, col) {
        return _this2.getCellMeta(row, col).readOnly;
      });
      (0, _array.arrayEach)(ranges, function (range) {
        range.forAll(function (row, col) {
          _this2.setCellMeta(row, col, 'readOnly', !atLeastOneReadOnly);
        });
      });
      this.render();
    },
    disabled: function disabled() {
      return !(this.getSelectedRange() && !this.selection.isSelectedByCorner());
    }
  };
}

/***/ }),
/* 624 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = redoItem;
exports.KEY = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'redo';
exports.KEY = KEY;

function redoItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REDO);
    },
    callback: function callback() {
      this.redo();
    },
    disabled: function disabled() {
      return this.undoRedo && !this.undoRedo.isRedoAvailable();
    }
  };
}

/***/ }),
/* 625 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = removeColumnItem;
exports.KEY = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _utils = __webpack_require__(60);

var _utils2 = __webpack_require__(137);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'remove_col';
exports.KEY = KEY;

function removeColumnItem() {
  return {
    key: KEY,
    name: function name() {
      var selection = this.getSelected();
      var pluralForm = 0;

      if (selection) {
        if (selection.length > 1) {
          pluralForm = 1;
        } else {
          var _selection$ = (0, _slicedToArray2.default)(selection[0], 4),
              fromColumn = _selection$[1],
              toColumn = _selection$[3];

          if (fromColumn - toColumn !== 0) {
            pluralForm = 1;
          }
        }
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REMOVE_COLUMN, pluralForm);
    },
    callback: function callback() {
      this.alter('remove_col', (0, _utils2.transformSelectionToColumnDistance)(this.getSelected()), null, 'ContextMenu.removeColumn');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);
      var totalColumns = this.countCols();

      if (!selected) {
        return true;
      }

      return this.selection.isSelectedByRowHeader() || this.selection.isSelectedByCorner() || !this.isColumnModificationAllowed() || !totalColumns;
    },
    hidden: function hidden() {
      return !this.getSettings().allowRemoveColumn;
    }
  };
}

/***/ }),
/* 626 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = removeRowItem;
exports.KEY = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _utils = __webpack_require__(60);

var _utils2 = __webpack_require__(137);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'remove_row';
exports.KEY = KEY;

function removeRowItem() {
  return {
    key: KEY,
    name: function name() {
      var selection = this.getSelected();
      var pluralForm = 0;

      if (selection) {
        if (selection.length > 1) {
          pluralForm = 1;
        } else {
          var _selection$ = (0, _slicedToArray2.default)(selection[0], 3),
              fromRow = _selection$[0],
              toRow = _selection$[2];

          if (fromRow - toRow !== 0) {
            pluralForm = 1;
          }
        }
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REMOVE_ROW, pluralForm);
    },
    callback: function callback() {
      // TODO: Please keep in mind that below `1` may be improper. The table's way of work, before change `f1747b3912ea3b21fe423fd102ca94c87db81379` was restored.
      // There is still problem when removing more than one row.
      this.alter('remove_row', (0, _utils2.transformSelectionToRowDistance)(this.getSelected()), 1, 'ContextMenu.removeRow');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);
      var totalRows = this.countRows();

      if (!selected) {
        return true;
      }

      return this.selection.isSelectedByColumnHeader() || this.selection.isSelectedByCorner() || !totalRows;
    },
    hidden: function hidden() {
      return !this.getSettings().allowRemoveRow;
    }
  };
}

/***/ }),
/* 627 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = rowAboveItem;
exports.KEY = void 0;

var _utils = __webpack_require__(60);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'row_above';
exports.KEY = KEY;

function rowAboveItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ROW_ABOVE);
    },
    callback: function callback(key, normalizedSelection) {
      var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
      this.alter('insert_row', latestSelection.start.row, 1, 'ContextMenu.rowAbove');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);

      if (!selected) {
        return true;
      }

      return this.selection.isSelectedByColumnHeader() || this.countRows() >= this.getSettings().maxRows;
    },
    hidden: function hidden() {
      return !this.getSettings().allowInsertRow;
    }
  };
}

/***/ }),
/* 628 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = rowBelowItem;
exports.KEY = void 0;

var _utils = __webpack_require__(60);

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'row_below';
exports.KEY = KEY;

function rowBelowItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_ROW_BELOW);
    },
    callback: function callback(key, normalizedSelection) {
      var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
      this.alter('insert_row', latestSelection.end.row + 1, 1, 'ContextMenu.rowBelow');
    },
    disabled: function disabled() {
      var selected = (0, _utils.getValidSelection)(this);

      if (!selected) {
        return true;
      }

      return this.selection.isSelectedByColumnHeader() || this.countRows() >= this.getSettings().maxRows;
    },
    hidden: function hidden() {
      return !this.getSettings().allowInsertRow;
    }
  };
}

/***/ }),
/* 629 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.default = noItemsItem;
exports.KEY = void 0;

var _constants = __webpack_require__(11);

var KEY = 'no_items';
exports.KEY = KEY;

function noItemsItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(_constants.CONTEXTMENU_ITEMS_NO_ITEMS);
    },
    disabled: true,
    isCommand: false
  };
}

/***/ }),
/* 630 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = undoItem;
exports.KEY = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var KEY = 'undo';
exports.KEY = KEY;

function undoItem() {
  return {
    key: KEY,
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_UNDO);
    },
    callback: function callback() {
      this.undo();
    },
    disabled: function disabled() {
      return this.undoRedo && !this.undoRedo.isUndoAvailable();
    }
  };
}

/***/ }),
/* 631 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

/**
 * Helper class for checking if element will fit at the desired side of cursor.
 *
 * @class Cursor
 * @plugin ContextMenu
 */
var Cursor =
/*#__PURE__*/
function () {
  function Cursor(object, rootWindow) {
    (0, _classCallCheck2.default)(this, Cursor);
    var windowScrollTop = (0, _element.getWindowScrollTop)(rootWindow);
    var windowScrollLeft = (0, _element.getWindowScrollLeft)(rootWindow);
    var top;
    var topRelative;
    var left;
    var leftRelative;
    var cellHeight;
    var cellWidth;
    this.rootWindow = rootWindow;
    this.type = this.getSourceType(object);

    if (this.type === 'literal') {
      top = parseInt(object.top, 10);
      left = parseInt(object.left, 10);
      cellHeight = object.height || 0;
      cellWidth = object.width || 0;
      topRelative = top;
      leftRelative = left;
      top += windowScrollTop;
      left += windowScrollLeft;
    } else if (this.type === 'event') {
      top = parseInt((0, _event.pageY)(object), 10);
      left = parseInt((0, _event.pageX)(object), 10);
      cellHeight = object.target.clientHeight;
      cellWidth = object.target.clientWidth;
      topRelative = top - windowScrollTop;
      leftRelative = left - windowScrollLeft;
    }

    this.top = top;
    this.topRelative = topRelative;
    this.left = left;
    this.leftRelative = leftRelative;
    this.scrollTop = windowScrollTop;
    this.scrollLeft = windowScrollLeft;
    this.cellHeight = cellHeight;
    this.cellWidth = cellWidth;
  }
  /**
   * Get source type name.
   *
   * @param {*} object Event or Object with coordinates.
   * @returns {String} Returns one of this values: `'literal'`, `'event'`.
   */


  (0, _createClass2.default)(Cursor, [{
    key: "getSourceType",
    value: function getSourceType(object) {
      var type = 'literal';

      if (object instanceof Event) {
        type = 'event';
      }

      return type;
    }
    /**
     * Checks if element can be placed above the cursor.
     *
     * @param {HTMLElement} element Element to check if it's size will fit above the cursor.
     * @returns {Boolean}
     */

  }, {
    key: "fitsAbove",
    value: function fitsAbove(element) {
      return this.topRelative >= element.offsetHeight;
    }
    /**
     * Checks if element can be placed below the cursor.
     *
     * @param {HTMLElement} element Element to check if it's size will fit below the cursor.
     * @param {Number} [viewportHeight] The viewport height.
     * @returns {Boolean}
     */

  }, {
    key: "fitsBelow",
    value: function fitsBelow(element) {
      var viewportHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.rootWindow.innerHeight;
      return this.topRelative + element.offsetHeight <= viewportHeight;
    }
    /**
     * Checks if element can be placed on the right of the cursor.
     *
     * @param {HTMLElement} element Element to check if it's size will fit on the right of the cursor.
     * @param {Number} [viewportWidth] The viewport width.
     * @returns {Boolean}
     */

  }, {
    key: "fitsOnRight",
    value: function fitsOnRight(element) {
      var viewportWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.rootWindow.innerWidth;
      return this.leftRelative + this.cellWidth + element.offsetWidth <= viewportWidth;
    }
    /**
     * Checks if element can be placed on the left on the cursor.
     *
     * @param {HTMLElement} element Element to check if it's size will fit on the left of the cursor.
     * @returns {Boolean}
     */

  }, {
    key: "fitsOnLeft",
    value: function fitsOnLeft(element) {
      return this.leftRelative >= element.offsetWidth;
    }
  }]);
  return Cursor;
}();

var _default = Cursor;
exports.default = _default;

/***/ }),
/* 632 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 633 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _SheetClip = _interopRequireDefault(__webpack_require__(469));

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _element = __webpack_require__(5);

var _plugins = __webpack_require__(20);

var _copy = _interopRequireDefault(__webpack_require__(634));

var _cut = _interopRequireDefault(__webpack_require__(635));

var _pasteEvent = _interopRequireDefault(__webpack_require__(636));

var _focusableElement = __webpack_require__(638);

var _utils = __webpack_require__(640);

__webpack_require__(641);

_pluginHooks.default.getSingleton().register('afterCopyLimit');

_pluginHooks.default.getSingleton().register('modifyCopyableRange');

_pluginHooks.default.getSingleton().register('beforeCut');

_pluginHooks.default.getSingleton().register('afterCut');

_pluginHooks.default.getSingleton().register('beforePaste');

_pluginHooks.default.getSingleton().register('afterPaste');

_pluginHooks.default.getSingleton().register('beforeCopy');

_pluginHooks.default.getSingleton().register('afterCopy');

var ROWS_LIMIT = 1000;
var COLUMNS_LIMIT = 1000;
var privatePool = new WeakMap();
/**
 * @description
 * This plugin enables the copy/paste functionality in the Handsontable. The functionality works for API, Context Menu,
 * using keyboard shortcuts and menu bar from the browser.
 * Possible values:
 * * `true` (to enable default options),
 * * `false` (to disable completely)
 *
 * or an object with values:
 * * `'columnsLimit'` (see {@link CopyPaste#columnsLimit})
 * * `'rowsLimit'` (see {@link CopyPaste#rowsLimit})
 * * `'pasteMode'` (see {@link CopyPaste#pasteMode})
 *
 * See [the copy/paste demo](https://docs.handsontable.com/demo-copy-paste.html) for examples.
 *
 * @example
 * ```js
 * // Enables the plugin with default values
 * copyPaste: true,
 * // Enables the plugin with custom values
 * copyPaste: {
 *   columnsLimit: 25,
 *   rowsLimit: 50,
 *   pasteMode: 'shift_down',
 * },
 * ```
 * @class CopyPaste
 * @plugin CopyPaste
 */

var CopyPaste =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(CopyPaste, _BasePlugin);

  function CopyPaste(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, CopyPaste);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CopyPaste).call(this, hotInstance));
    /**
     * Maximum number of columns than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
     *
     * @type {Number}
     * @default 1000
     */

    _this.columnsLimit = COLUMNS_LIMIT;
    /**
     * Ranges of the cells coordinates, which should be used to copy/cut/paste actions.
     *
     * @private
     * @type {Array}
     */

    _this.copyableRanges = [];
    /**
     * Defines paste (<kbd>CTRL</kbd> + <kbd>V</kbd>) behavior.
     * * Default value `"overwrite"` will paste clipboard value over current selection.
     * * When set to `"shift_down"`, clipboard data will be pasted in place of current selection, while all selected cells are moved down.
     * * When set to `"shift_right"`, clipboard data will be pasted in place of current selection, while all selected cells are moved right.
     *
     * @type {String}
     * @default 'overwrite'
     */

    _this.pasteMode = 'overwrite';
    /**
     * Maximum number of rows than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
     *
     * @type {Number}
     * @default 1000
     */

    _this.rowsLimit = ROWS_LIMIT;
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      isTriggeredByCopy: false,
      isTriggeredByCut: false,
      isBeginEditing: false,
      isFragmentSelectionEnabled: false
    });
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link CopyPaste#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(CopyPaste, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().copyPaste;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var settings = this.hot.getSettings();
      var priv = privatePool.get(this);
      priv.isFragmentSelectionEnabled = settings.fragmentSelection;

      if ((0, _typeof2.default)(settings.copyPaste) === 'object') {
        this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode;
        this.rowsLimit = settings.copyPaste.rowsLimit || this.rowsLimit;
        this.columnsLimit = settings.copyPaste.columnsLimit || this.columnsLimit;
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.onAfterContextMenuDefaultOptions(options);
      });
      this.addHook('afterOnCellMouseUp', function () {
        return _this2.onAfterOnCellMouseUp();
      });
      this.addHook('afterSelectionEnd', function () {
        return _this2.onAfterSelectionEnd();
      });
      this.addHook('beforeKeyDown', function () {
        return _this2.onBeforeKeyDown();
      });
      this.focusableElement = (0, _focusableElement.createElement)(this.hot.rootDocument);
      this.focusableElement.addLocalHook('copy', function (event) {
        return _this2.onCopy(event);
      }).addLocalHook('cut', function (event) {
        return _this2.onCut(event);
      }).addLocalHook('paste', function (event) {
        return _this2.onPaste(event);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(CopyPaste.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      this.getOrCreateFocusableElement();
      (0, _get2.default)((0, _getPrototypeOf2.default)(CopyPaste.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      if (this.focusableElement) {
        (0, _focusableElement.destroyElement)(this.focusableElement);
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(CopyPaste.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Copies the selected cell into the clipboard.
     */

  }, {
    key: "copy",
    value: function copy() {
      var priv = privatePool.get(this);
      priv.isTriggeredByCopy = true;
      this.getOrCreateFocusableElement();
      this.focusableElement.focus();
      this.hot.rootDocument.execCommand('copy');
    }
    /**
     * Cuts the selected cell into the clipboard.
     */

  }, {
    key: "cut",
    value: function cut() {
      var priv = privatePool.get(this);
      priv.isTriggeredByCut = true;
      this.getOrCreateFocusableElement();
      this.focusableElement.focus();
      this.hot.rootDocument.execCommand('cut');
    }
    /**
     * Creates copyable text releated to range objects.
     *
     * @param {Object[]} ranges Array of objects with properties `startRow`, `endRow`, `startCol` and `endCol`.
     * @returns {String} Returns string which will be copied into clipboard.
     */

  }, {
    key: "getRangedCopyableData",
    value: function getRangedCopyableData(ranges) {
      var _this3 = this;

      var dataSet = [];
      var copyableRows = [];
      var copyableColumns = []; // Count all copyable rows and columns

      (0, _array.arrayEach)(ranges, function (range) {
        (0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
          if (copyableRows.indexOf(row) === -1) {
            copyableRows.push(row);
          }
        });
        (0, _number.rangeEach)(range.startCol, range.endCol, function (column) {
          if (copyableColumns.indexOf(column) === -1) {
            copyableColumns.push(column);
          }
        });
      }); // Concat all rows and columns data defined in ranges into one copyable string

      (0, _array.arrayEach)(copyableRows, function (row) {
        var rowSet = [];
        (0, _array.arrayEach)(copyableColumns, function (column) {
          rowSet.push(_this3.hot.getCopyableData(row, column));
        });
        dataSet.push(rowSet);
      });
      return _SheetClip.default.stringify(dataSet);
    }
    /**
     * Creates copyable text releated to range objects.
     *
     * @param {Object[]} ranges Array of objects with properties `startRow`, `startCol`, `endRow` and `endCol`.
     * @returns {Array[]} Returns array of arrays which will be copied into clipboard.
     */

  }, {
    key: "getRangedData",
    value: function getRangedData(ranges) {
      var _this4 = this;

      var dataSet = [];
      var copyableRows = [];
      var copyableColumns = []; // Count all copyable rows and columns

      (0, _array.arrayEach)(ranges, function (range) {
        (0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
          if (copyableRows.indexOf(row) === -1) {
            copyableRows.push(row);
          }
        });
        (0, _number.rangeEach)(range.startCol, range.endCol, function (column) {
          if (copyableColumns.indexOf(column) === -1) {
            copyableColumns.push(column);
          }
        });
      }); // Concat all rows and columns data defined in ranges into one copyable string

      (0, _array.arrayEach)(copyableRows, function (row) {
        var rowSet = [];
        (0, _array.arrayEach)(copyableColumns, function (column) {
          rowSet.push(_this4.hot.getCopyableData(row, column));
        });
        dataSet.push(rowSet);
      });
      return dataSet;
    }
    /**
     * Simulates the paste action.
     *
     * @param {String} [value] Value to paste.
     */

  }, {
    key: "paste",
    value: function paste() {
      var pastableText = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
      var pastableHtml = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : pastableText;

      if (!pastableText && !pastableHtml) {
        return;
      }

      var pasteData = new _pasteEvent.default();

      if (pastableText) {
        pasteData.clipboardData.setData('text/plain', pastableText);
      }

      if (pastableHtml) {
        pasteData.clipboardData.setData('text/html', pastableHtml);
      }

      this.getOrCreateFocusableElement();
      this.onPaste(pasteData);
    }
    /**
     * Prepares copyable text from the cells selection in the invisible textarea.
     */

  }, {
    key: "setCopyableText",
    value: function setCopyableText() {
      var selRange = this.hot.getSelectedRangeLast();

      if (!selRange) {
        return;
      }

      var topLeft = selRange.getTopLeftCorner();
      var bottomRight = selRange.getBottomRightCorner();
      var startRow = topLeft.row;
      var startCol = topLeft.col;
      var endRow = bottomRight.row;
      var endCol = bottomRight.col;
      var finalEndRow = Math.min(endRow, startRow + this.rowsLimit - 1);
      var finalEndCol = Math.min(endCol, startCol + this.columnsLimit - 1);
      this.copyableRanges.length = 0;
      this.copyableRanges.push({
        startRow: startRow,
        startCol: startCol,
        endRow: finalEndRow,
        endCol: finalEndCol
      });
      this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges);

      if (endRow !== finalEndRow || endCol !== finalEndCol) {
        this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit);
      }
    }
    /**
     * Force focus on editable element.
     *
     * @private
     */

  }, {
    key: "getOrCreateFocusableElement",
    value: function getOrCreateFocusableElement() {
      var editor = this.hot.getActiveEditor();
      var editableElement = editor ? editor.TEXTAREA : void 0;

      if (editableElement) {
        this.focusableElement.setFocusableElement(editableElement);
      } else {
        this.focusableElement.useSecondaryElement();
      }
    }
    /**
     * Verifies if editor exists and is open.
     *
     * @private
     */

  }, {
    key: "isEditorOpened",
    value: function isEditorOpened() {
      var editor = this.hot.getActiveEditor();
      return editor && editor.isOpened();
    }
    /**
     * Prepares new values to populate them into datasource.
     *
     * @private
     * @param {Array} inputArray
     * @param {Array} selection
     * @returns {Array} Range coordinates after populate data
     */

  }, {
    key: "populateValues",
    value: function populateValues(inputArray) {
      var selection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.hot.getSelectedLast();

      if (!inputArray.length) {
        return;
      }

      var newValuesMaxRow = inputArray.length - 1;
      var newValuesMaxColumn = inputArray[0].length - 1;
      var startRow = Math.min(selection[0], selection[2]);
      var endRow = Math.max(selection[0], selection[2], newValuesMaxRow + startRow);
      var startColumn = Math.min(selection[1], selection[3]);
      var endColumn = Math.max(selection[1], selection[3], newValuesMaxColumn + startColumn);
      var newValues = [];

      for (var row = startRow, valuesRow = 0; row <= endRow; row += 1) {
        var newRow = [];

        for (var column = startColumn, valuesColumn = 0; column <= endColumn; column += 1) {
          newRow.push(inputArray[valuesRow][valuesColumn]);
          valuesColumn = valuesColumn === newValuesMaxColumn ? 0 : valuesColumn += 1;
        }

        newValues.push(newRow);
        valuesRow = valuesRow === newValuesMaxRow ? 0 : valuesRow += 1;
      }

      this.hot.populateFromArray(startRow, startColumn, newValues, void 0, void 0, 'CopyPaste.paste', this.pasteMode);
      return [startRow, startColumn, endRow, endColumn];
    }
    /**
     * `copy` event callback on textarea element.
     *
     * @param {Event} event ClipboardEvent.
     * @private
     */

  }, {
    key: "onCopy",
    value: function onCopy(event) {
      var priv = privatePool.get(this);

      if (!this.hot.isListening() && !priv.isTriggeredByCopy || this.isEditorOpened()) {
        return;
      }

      this.setCopyableText();
      priv.isTriggeredByCopy = false;
      var rangedData = this.getRangedData(this.copyableRanges);
      var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);

      if (allowCopying) {
        var textPlain = _SheetClip.default.stringify(rangedData);

        if (event && event.clipboardData) {
          var textHTML = (0, _utils.arrayToTable)(rangedData, this.hot.rootDocument);
          event.clipboardData.setData('text/plain', textPlain);
          event.clipboardData.setData('text/html', textHTML);
        } else if (typeof ClipboardEvent === 'undefined') {
          this.hot.rootWindow.clipboardData.setData('Text', textPlain);
        }

        this.hot.runHooks('afterCopy', rangedData, this.copyableRanges);
      }

      event.preventDefault();
    }
    /**
     * `cut` event callback on textarea element.
     *
     * @param {Event} event ClipboardEvent.
     * @private
     */

  }, {
    key: "onCut",
    value: function onCut(event) {
      var priv = privatePool.get(this);

      if (!this.hot.isListening() && !priv.isTriggeredByCut || this.isEditorOpened()) {
        return;
      }

      this.setCopyableText();
      priv.isTriggeredByCut = false;
      var rangedData = this.getRangedData(this.copyableRanges);
      var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);

      if (allowCuttingOut) {
        var textPlain = _SheetClip.default.stringify(rangedData);

        if (event && event.clipboardData) {
          var textHTML = (0, _utils.arrayToTable)(rangedData, this.hot.rootDocument);
          event.clipboardData.setData('text/plain', textPlain);
          event.clipboardData.setData('text/html', textHTML);
        } else if (typeof ClipboardEvent === 'undefined') {
          this.hot.rootWindow.clipboardData.setData('Text', textPlain);
        }

        this.hot.emptySelectedCells();
        this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
      }

      event.preventDefault();
    }
    /**
     * `paste` event callback on textarea element.
     *
     * @param {Event} event ClipboardEvent or pseudo ClipboardEvent, if paste was called manually.
     * @private
     */

  }, {
    key: "onPaste",
    value: function onPaste(event) {
      if (!this.hot.isListening() || this.isEditorOpened()) {
        return;
      }

      if (event && event.preventDefault) {
        event.preventDefault();
      }

      var pastedData;

      if (event && typeof event.clipboardData !== 'undefined') {
        var textHTML = event.clipboardData.getData('text/html');

        if (textHTML && /(<table)|(<TABLE)/.test(textHTML)) {
          pastedData = (0, _utils.tableToArray)(textHTML, this.hot.rootDocument);
        } else {
          pastedData = event.clipboardData.getData('text/plain');
        }
      } else if (typeof ClipboardEvent === 'undefined' && typeof this.hot.rootWindow.clipboardData !== 'undefined') {
        pastedData = this.hot.rootWindow.clipboardData.getData('Text');
      }

      var inputArray = typeof pastedData !== 'string' ? pastedData : _SheetClip.default.parse(pastedData);

      if (inputArray.length === 0) {
        return;
      }

      if (this.hot.runHooks('beforePaste', inputArray, this.copyableRanges) === false) {
        return;
      }

      var _this$populateValues = this.populateValues(inputArray),
          _this$populateValues2 = (0, _slicedToArray2.default)(_this$populateValues, 4),
          startRow = _this$populateValues2[0],
          startColumn = _this$populateValues2[1],
          endRow = _this$populateValues2[2],
          endColumn = _this$populateValues2[3];

      this.hot.selectCell(startRow, startColumn, Math.min(this.hot.countRows() - 1, endRow), Math.min(this.hot.countCols() - 1, endColumn));
      this.hot.runHooks('afterPaste', inputArray, this.copyableRanges);
    }
    /**
     * Add copy, cut and paste options to the Context Menu.
     *
     * @private
     * @param {Object} options Contains default added options of the Context Menu.
     */

  }, {
    key: "onAfterContextMenuDefaultOptions",
    value: function onAfterContextMenuDefaultOptions(options) {
      options.items.push({
        name: '---------'
      }, (0, _copy.default)(this), (0, _cut.default)(this));
    }
    /**
     * Force focus on focusableElement.
     *
     * @private
     */

  }, {
    key: "onAfterOnCellMouseUp",
    value: function onAfterOnCellMouseUp() {
      if (!this.hot.isListening() || this.isEditorOpened()) {
        return;
      }

      this.getOrCreateFocusableElement();
      this.focusableElement.focus();
    }
    /**
     * Force focus on focusableElement after end of the selection.
     *
     * @private
     */

  }, {
    key: "onAfterSelectionEnd",
    value: function onAfterSelectionEnd() {
      var _privatePool$get = privatePool.get(this),
          isFragmentSelectionEnabled = _privatePool$get.isFragmentSelectionEnabled;

      if (this.isEditorOpened()) {
        return;
      }

      this.getOrCreateFocusableElement();

      if (isFragmentSelectionEnabled && this.focusableElement.getFocusableElement() !== this.hot.rootDocument.activeElement && (0, _element.getSelectionText)()) {
        return;
      }

      this.setCopyableText();
      this.focusableElement.focus();
    }
    /**
     * `beforeKeyDown` listener to force focus of focusableElement.
     *
     * @private
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown() {
      if (!this.hot.isListening() || this.isEditorOpened()) {
        return;
      }

      var activeElement = this.hot.rootDocument.activeElement;
      var activeEditor = this.hot.getActiveEditor();

      if (!activeEditor || activeElement !== this.focusableElement.getFocusableElement() && activeElement !== activeEditor.select) {
        return;
      }

      this.getOrCreateFocusableElement();
      this.focusableElement.focus();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.focusableElement) {
        (0, _focusableElement.destroyElement)(this.focusableElement);
        this.focusableElement = null;
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(CopyPaste.prototype), "destroy", this).call(this);
    }
  }]);
  return CopyPaste;
}(_base.default);

(0, _plugins.registerPlugin)('CopyPaste', CopyPaste);
var _default = CopyPaste;
exports.default = _default;

/***/ }),
/* 634 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = copyItem;

var C = _interopRequireWildcard(__webpack_require__(11));

function copyItem(copyPastePlugin) {
  return {
    key: 'copy',
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_COPY);
    },
    callback: function callback() {
      copyPastePlugin.copy();
    },
    disabled: function disabled() {
      var selected = this.getSelected();

      if (!selected || selected.length > 1) {
        return true;
      }

      return false;
    },
    hidden: false
  };
}

/***/ }),
/* 635 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = cutItem;

var C = _interopRequireWildcard(__webpack_require__(11));

function cutItem(copyPastePlugin) {
  return {
    key: 'cut',
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_CUT);
    },
    callback: function callback() {
      copyPastePlugin.cut();
    },
    disabled: function disabled() {
      var selected = this.getSelected();

      if (!selected || selected.length > 1) {
        return true;
      }

      return false;
    },
    hidden: false
  };
}

/***/ }),
/* 636 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _clipboardData = _interopRequireDefault(__webpack_require__(637));

var PasteEvent = function PasteEvent() {
  (0, _classCallCheck2.default)(this, PasteEvent);
  this.clipboardData = new _clipboardData.default();
};

exports.default = PasteEvent;

/***/ }),
/* 637 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var ClipboardData =
/*#__PURE__*/
function () {
  function ClipboardData() {
    (0, _classCallCheck2.default)(this, ClipboardData);
    this.data = {};
  }

  (0, _createClass2.default)(ClipboardData, [{
    key: "setData",
    value: function setData(type, value) {
      this.data[type] = value;
    }
  }, {
    key: "getData",
    value: function getData(type) {
      return this.data[type] || void 0;
    }
  }]);
  return ClipboardData;
}();

exports.default = ClipboardData;

/***/ }),
/* 638 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(639);

__webpack_require__(17);

exports.__esModule = true;
exports.createElement = createElement;
exports.deactivateElement = deactivateElement;
exports.destroyElement = destroyElement;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _object = __webpack_require__(4);

var _browser = __webpack_require__(72);

var _element = __webpack_require__(5);

/**
 * @class FocusableWrapper
 *
 * @plugin CopyPaste
 */
var FocusableWrapper =
/*#__PURE__*/
function () {
  function FocusableWrapper(rootDocument) {
    (0, _classCallCheck2.default)(this, FocusableWrapper);
    this.rootDocument = rootDocument;
    /**
     * The main/operational focusable element.
     *
     * @type {HTMLElement}
     */

    this.mainElement = null;
    /**
     * Instance of EventManager.
     *
     * @type {EventManager}
     */

    this.eventManager = new _eventManager.default(this);
    /**
     * An object for tracking information about event listeners attached to the focusable element.
     *
     * @type {WeakSet}
     */

    this.listenersCount = new WeakSet();
  }
  /**
   * Switch to the secondary focusable element. Used when no any main focusable element is provided.
   */


  (0, _createClass2.default)(FocusableWrapper, [{
    key: "useSecondaryElement",
    value: function useSecondaryElement() {
      var el = createOrGetSecondaryElement(this.rootDocument);

      if (!this.listenersCount.has(el)) {
        this.listenersCount.add(el);
        forwardEventsToLocalHooks(this.eventManager, el, this);
      }

      this.mainElement = el;
    }
    /**
     * Switch to the main focusable element.
     */

  }, {
    key: "setFocusableElement",
    value: function setFocusableElement(element) {
      if (!this.listenersCount.has(element)) {
        this.listenersCount.add(element);
        forwardEventsToLocalHooks(this.eventManager, element, this);
      }

      this.mainElement = element;
    }
    /**
     * Get currently set focusable element.
     *
     * @return {HTMLElement}
     */

  }, {
    key: "getFocusableElement",
    value: function getFocusableElement() {
      return this.mainElement;
    }
    /**
     * Set focus to the focusable element.
     */

  }, {
    key: "focus",
    value: function focus() {
      // Add an empty space to texarea. It is necessary for safari to enable "copy" command from menu bar.
      this.mainElement.value = ' ';

      if (!(0, _browser.isMobileBrowser)()) {
        (0, _element.selectElementIfAllowed)(this.mainElement);
      }
    }
  }]);
  return FocusableWrapper;
}();

(0, _object.mixin)(FocusableWrapper, _localHooks.default);
var refCounter = 0;
/**
 * Create and return the FocusableWrapper instance.
 *
 * @return {FocusableWrapper}
 */

function createElement(rootDocument) {
  var focusableWrapper = new FocusableWrapper(rootDocument);
  refCounter += 1;
  return focusableWrapper;
}
/**
 * Deactivate the FocusableWrapper instance.
 *
 * @param {FocusableWrapper} wrapper
 */


function deactivateElement(wrapper) {
  wrapper.eventManager.clear();
}

var runLocalHooks = function runLocalHooks(eventName, subject) {
  return function (event) {
    return subject.runLocalHooks(eventName, event);
  };
};
/**
 * Register copy/cut/paste events and forward their actions to the subject local hooks system.
 *
 * @param {HTMLElement} element
 * @param {FocusableWrapper} subject
 */


function forwardEventsToLocalHooks(eventManager, element, subject) {
  eventManager.addEventListener(element, 'copy', runLocalHooks('copy', subject));
  eventManager.addEventListener(element, 'cut', runLocalHooks('cut', subject));
  eventManager.addEventListener(element, 'paste', runLocalHooks('paste', subject));
}

var secondaryElements = new WeakMap();
/**
 * Create and attach newly created focusable element to the DOM.
 *
 * @return {HTMLElement}
 */

function createOrGetSecondaryElement(rootDocument) {
  var secondaryElement = secondaryElements.get(rootDocument);

  if (secondaryElement) {
    if (!secondaryElement.parentElement) {
      this.rootDocument.body.appendChild(secondaryElement);
    }

    return secondaryElement;
  }

  var element = rootDocument.createElement('textarea');
  secondaryElements.set(rootDocument, element);
  element.id = 'HandsontableCopyPaste';
  element.className = 'copyPaste';
  element.tabIndex = -1;
  element.autocomplete = 'off';
  element.wrap = 'hard';
  element.value = ' ';
  rootDocument.body.appendChild(element);
  return element;
}
/**
 * Destroy the FocusableWrapper instance.
 *
 * @param {FocusableWrapper} wrapper
 */


function destroyElement(wrapper) {
  if (!(wrapper instanceof FocusableWrapper)) {
    return;
  }

  if (refCounter > 0) {
    refCounter -= 1;
  }

  deactivateElement(wrapper);

  if (refCounter <= 0) {
    refCounter = 0; // Detach secondary element from the DOM.

    var secondaryElement = secondaryElements.get(wrapper.rootDocument);

    if (secondaryElement && secondaryElement.parentNode) {
      secondaryElement.parentNode.removeChild(secondaryElement);
      secondaryElements.delete(wrapper.rootDocument);
    }

    wrapper.mainElement = null;
  }
}

/***/ }),
/* 639 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// `WeakSet` constructor
// https://tc39.github.io/ecma262/#sec-weakset-constructor
__webpack_require__(125)('WeakSet', function (get) {
  return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, __webpack_require__(186), false, true);


/***/ }),
/* 640 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(18);

__webpack_require__(54);

__webpack_require__(37);

__webpack_require__(105);

exports.__esModule = true;
exports.arrayToTable = arrayToTable;
exports.tableToArray = tableToArray;

var _mixed = __webpack_require__(27);

/**
 * Converts javascript array into HTMLTable.
 *
 * @param {Array} input Input array which will be converted to HTMLTable
 */
function arrayToTable(input, rootDocument) {
  var inputLen = input.length;
  var result = ['<table>'];
  var tempElement = rootDocument.createElement('div');
  rootDocument.documentElement.appendChild(tempElement);

  for (var row = 0; row < inputLen; row += 1) {
    var rowData = input[row];
    var columnsLen = rowData.length;
    var columnsResult = [];

    if (row === 0) {
      result.push('<tbody>');
    }

    for (var column = 0; column < columnsLen; column += 1) {
      tempElement.innerText = "".concat((0, _mixed.isEmpty)(rowData[column]) ? '' : rowData[column]);
      columnsResult.push("<td>".concat(tempElement.innerHTML, "</td>"));
    }

    result.push.apply(result, ['<tr>'].concat(columnsResult, ['</tr>']));

    if (row + 1 === inputLen) {
      result.push('</tbody>');
    }
  }

  rootDocument.documentElement.removeChild(tempElement);
  result.push('</table>');
  return result.join('');
}
/**
 * Helper to verify if DOM element is an HTMLTable element.
 *
 * @param {Element} element Node element to verify if it's an HTMLTable.
 */


function isHTMLTable(element) {
  return (element && element.nodeName || '').toLowerCase() === 'table';
}
/**
 * Converts HTMLTable or string into array.
 *
 * @param {Element|String} element Node element or string, which should contain `<table>...</table>`.
 */


function tableToArray(element, rootDocument) {
  var result = [];
  var checkElement = element;

  if (typeof checkElement === 'string') {
    var tempElem = rootDocument.createElement('div');
    tempElem.innerHTML = checkElement.replace(/\n/g, '');
    checkElement = tempElem.querySelector('table');
  }

  if (checkElement && isHTMLTable(checkElement)) {
    var rows = checkElement.rows;
    var rowsLen = rows && rows.length;
    var tempArray = [];

    for (var row = 0; row < rowsLen; row += 1) {
      var cells = rows[row].cells;
      var cellsLen = cells.length;
      var newRow = [];

      for (var column = 0; column < cellsLen; column += 1) {
        var cell = cells[column];
        cell.innerHTML = cell.innerHTML.trim().replace(/<br(.|)>(\n?)/, '\n');
        var cellText = cell.innerText;
        newRow.push(cellText);
      }

      tempArray.push(newRow);
    }

    result.push.apply(result, tempArray);
  }

  return result;
}

/***/ }),
/* 641 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 642 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(33);

__webpack_require__(485);

__webpack_require__(76);

__webpack_require__(643);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var _src = __webpack_require__(25);

var C = _interopRequireWildcard(__webpack_require__(11));

var _contextMenuItem = __webpack_require__(645);

var _utils = __webpack_require__(92);

var _selection = __webpack_require__(478);

/**
 * @class CustomBorders
 * @plugin CustomBorders
 *
 * @description
 * This plugin enables an option to apply custom borders through the context menu (configurable with context menu key
 * `borders`).
 *
 * To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form
 * of an array.
 *
 * See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for more examples.
 *
 * @example
 * ```js
 * customBorders: [
 *   {
 *    range: {
 *      from: {
 *        row: 1,
 *        col: 1
 *      },
 *      to: {
 *        row: 3,
 *        col: 4
 *      },
 *    },
 *    left: {},
 *    right: {},
 *    top: {},
 *    bottom: {},
 *   },
 * ],
 *
 * // or
 * customBorders: [
 *   { row: 2,
 *     col: 2,
 *     left: {
 *       width: 2,
 *       color: 'red',
 *     },
 *     right: {
 *       width: 1,
 *       color: 'green',
 *     },
 *     top: '',
 *     bottom: '',
 *   }
 * ],
 * ```
 */
var CustomBorders =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(CustomBorders, _BasePlugin);

  function CustomBorders(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, CustomBorders);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CustomBorders).call(this, hotInstance));
    /**
     * Saved borders.
     *
     * @private
     * @type {Array}
     */

    _this.savedBorders = [];
    return _this;
  }
  /**
  * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
  * hook and if it returns `true` than the {@link CustomBorders#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(CustomBorders, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().customBorders;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.onAfterContextMenuDefaultOptions(options);
      });
      this.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.hideBorders();
      (0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      this.changeBorderSettings();
      (0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "updatePlugin", this).call(this);
    }
    /**
      * Set custom borders.
      *
      * @example
      * ```js
      * const customBordersPlugin = hot.getPlugin('customBorders');
      *
      * // Using an array of arrays (produced by `.getSelected()` method).
      * customBordersPlugin.setBorders([[1, 1, 2, 2], [6, 2, 0, 2]], {left: {width: 2, color: 'blue'}});
      * // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
      * customBordersPlugin.setBorders(hot.getSelectedRange(), {left: {hide: false, width: 2, color: 'blue'}});
      * ```
      *
      * @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
      * @param {Object} borderObject Object with `top`, `right`, `bottom` and `left` properties.
      */

  }, {
    key: "setBorders",
    value: function setBorders(selectionRanges, borderObject) {
      var _this3 = this;

      var defaultBorderKeys = ['top', 'right', 'bottom', 'left'];
      var borderKeys = borderObject ? Object.keys(borderObject) : defaultBorderKeys;
      var selectionType = (0, _selection.detectSelectionType)(selectionRanges);
      var selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType);
      (0, _array.arrayEach)(selectionRanges, function (selection) {
        var _selectionSchemaNorma = selectionSchemaNormalizer(selection),
            _selectionSchemaNorma2 = (0, _slicedToArray2.default)(_selectionSchemaNorma, 4),
            rowStart = _selectionSchemaNorma2[0],
            columnStart = _selectionSchemaNorma2[1],
            rowEnd = _selectionSchemaNorma2[2],
            columnEnd = _selectionSchemaNorma2[3];

        var _loop = function _loop(row) {
          var _loop2 = function _loop2(col) {
            (0, _array.arrayEach)(borderKeys, function (borderKey) {
              _this3.prepareBorderFromCustomAdded(row, col, borderObject, borderKey);
            });
          };

          for (var col = columnStart; col <= columnEnd; col += 1) {
            _loop2(col);
          }
        };

        for (var row = rowStart; row <= rowEnd; row += 1) {
          _loop(row);
        }
      });
    }
    /**
      * Get custom borders.
      *
      * @example
      * ```js
      * const customBordersPlugin = hot.getPlugin('customBorders');
      *
      * // Using an array of arrays (produced by `.getSelected()` method).
      * customBordersPlugin.getBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
      * // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
      * customBordersPlugin.getBorders(hot.getSelectedRange());
      * // Using without param - return all customBorders.
      * customBordersPlugin.getBorders();
      * ```
      *
      * @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
      * @return {Object[]} Returns array of border objects.
      */

  }, {
    key: "getBorders",
    value: function getBorders(selectionRanges) {
      var _this4 = this;

      if (!Array.isArray(selectionRanges)) {
        return this.savedBorders;
      }

      var selectionType = (0, _selection.detectSelectionType)(selectionRanges);
      var selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType);
      var selectedBorders = [];
      (0, _array.arrayEach)(selectionRanges, function (selection) {
        var _selectionSchemaNorma3 = selectionSchemaNormalizer(selection),
            _selectionSchemaNorma4 = (0, _slicedToArray2.default)(_selectionSchemaNorma3, 4),
            rowStart = _selectionSchemaNorma4[0],
            columnStart = _selectionSchemaNorma4[1],
            rowEnd = _selectionSchemaNorma4[2],
            columnEnd = _selectionSchemaNorma4[3];

        var _loop3 = function _loop3(row) {
          var _loop4 = function _loop4(col) {
            (0, _array.arrayEach)(_this4.savedBorders, function (border) {
              if (border.row === row && border.col === col) {
                selectedBorders.push(border);
              }
            });
          };

          for (var col = columnStart; col <= columnEnd; col += 1) {
            _loop4(col);
          }
        };

        for (var row = rowStart; row <= rowEnd; row += 1) {
          _loop3(row);
        }
      });
      return selectedBorders;
    }
    /**
      * Clear custom borders.
      *
      * @example
      * ```js
      * const customBordersPlugin = hot.getPlugin('customBorders');
      *
      * // Using an array of arrays (produced by `.getSelected()` method).
      * customBordersPlugin.clearBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
      * // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
      * customBordersPlugin.clearBorders(hot.getSelectedRange());
      * // Using without param - clear all customBorders.
      * customBordersPlugin.clearBorders();
      * ```
      *
      * @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
      */

  }, {
    key: "clearBorders",
    value: function clearBorders(selectionRanges) {
      var _this5 = this;

      if (selectionRanges) {
        this.setBorders(selectionRanges);
      } else {
        (0, _array.arrayEach)(this.savedBorders, function (border) {
          _this5.clearBordersFromSelectionSettings(border.id);

          _this5.clearNullCellRange();

          _this5.hot.removeCellMeta(border.row, border.col, 'borders');
        });
        this.savedBorders.length = 0;
      }
    }
    /**
     * Insert WalkontableSelection instance into Walkontable settings.
     *
     * @private
     * @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
     * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
     */

  }, {
    key: "insertBorderIntoSettings",
    value: function insertBorderIntoSettings(border, place) {
      var hasSavedBorders = this.checkSavedBorders(border);

      if (!hasSavedBorders) {
        this.savedBorders.push(border);
      }

      var coordinates = {
        row: border.row,
        col: border.col
      };
      var cellRange = new _src.CellRange(coordinates, coordinates, coordinates);
      var hasCustomSelections = this.checkCustomSelections(border, cellRange, place);

      if (!hasCustomSelections) {
        this.hot.selection.highlight.addCustomSelection({
          border: border,
          cellRange: cellRange
        });
        this.hot.view.wt.draw(true);
      }
    }
    /**
     * Prepare borders from setting (single cell).
     *
     * @private
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {Object} borderDescriptor Object with `row` and `col`, `left`, `right`, `top` and `bottom` properties.
     * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
     */

  }, {
    key: "prepareBorderFromCustomAdded",
    value: function prepareBorderFromCustomAdded(row, column, borderDescriptor, place) {
      var border = (0, _utils.createEmptyBorders)(row, column);

      if (borderDescriptor) {
        border = (0, _utils.extendDefaultBorder)(border, borderDescriptor);
        (0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
          if (border.id === customSelection.settings.id) {
            Object.assign(customSelection.settings, borderDescriptor);
            border = customSelection.settings;
            return false; // breaks forAll
          }
        });
      }

      this.hot.setCellMeta(row, column, 'borders', border);
      this.insertBorderIntoSettings(border, place);
    }
    /**
     * Prepare borders from setting (object).
     *
     * @private
     * @param {Object} rowDecriptor Object with `range`, `left`, `right`, `top` and `bottom` properties.
     */

  }, {
    key: "prepareBorderFromCustomAddedRange",
    value: function prepareBorderFromCustomAddedRange(rowDecriptor) {
      var _this6 = this;

      var range = rowDecriptor.range;
      (0, _number.rangeEach)(range.from.row, range.to.row, function (rowIndex) {
        (0, _number.rangeEach)(range.from.col, range.to.col, function (colIndex) {
          var border = (0, _utils.createEmptyBorders)(rowIndex, colIndex);
          var add = 0;

          if (rowIndex === range.from.row) {
            add += 1;

            if ((0, _object.hasOwnProperty)(rowDecriptor, 'top')) {
              border.top = rowDecriptor.top;
            }
          }

          if (rowIndex === range.to.row) {
            add += 1;

            if ((0, _object.hasOwnProperty)(rowDecriptor, 'bottom')) {
              border.bottom = rowDecriptor.bottom;
            }
          }

          if (colIndex === range.from.col) {
            add += 1;

            if ((0, _object.hasOwnProperty)(rowDecriptor, 'left')) {
              border.left = rowDecriptor.left;
            }
          }

          if (colIndex === range.to.col) {
            add += 1;

            if ((0, _object.hasOwnProperty)(rowDecriptor, 'right')) {
              border.right = rowDecriptor.right;
            }
          }

          if (add > 0) {
            _this6.hot.setCellMeta(rowIndex, colIndex, 'borders', border);

            _this6.insertBorderIntoSettings(border);
          }
        });
      });
    }
    /**
     * Remove border (triggered from context menu).
     *
     * @private
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     */

  }, {
    key: "removeAllBorders",
    value: function removeAllBorders(row, column) {
      var borderId = (0, _utils.createId)(row, column);
      this.spliceBorder(borderId);
      this.clearBordersFromSelectionSettings(borderId);
      this.clearNullCellRange();
      this.hot.removeCellMeta(row, column, 'borders');
    }
    /**
     * Set borders for each cell re. to border position.
     *
     * @private
     * @param {Number} row Visual row index.
     * @param {Number} column Visual column index.
     * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
     * @param {Boolean} remove True when remove borders, and false when add borders.
     */

  }, {
    key: "setBorder",
    value: function setBorder(row, column, place, remove) {
      var bordersMeta = this.hot.getCellMeta(row, column).borders;

      if (!bordersMeta || bordersMeta.border === void 0) {
        bordersMeta = (0, _utils.createEmptyBorders)(row, column);
      }

      if (remove) {
        bordersMeta[place] = (0, _utils.createSingleEmptyBorder)();
        var hideCount = this.countHide(bordersMeta);

        if (hideCount === 4) {
          this.removeAllBorders(row, column);
        } else {
          var customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);

          if (!customSelectionsChecker) {
            this.insertBorderIntoSettings(bordersMeta);
          }

          this.hot.setCellMeta(row, column, 'borders', bordersMeta);
        }
      } else {
        bordersMeta[place] = (0, _utils.createDefaultCustomBorder)();

        var _customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);

        if (!_customSelectionsChecker) {
          this.insertBorderIntoSettings(bordersMeta);
        }

        this.hot.setCellMeta(row, column, 'borders', bordersMeta);
      }
    }
    /**
     * Prepare borders based on cell and border position.
     *
     * @private
     * @param {Object} selected
     * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
     * @param {Boolean} remove True when remove borders, and false when add borders.
     */

  }, {
    key: "prepareBorder",
    value: function prepareBorder(selected, place, remove) {
      var _this7 = this;

      (0, _array.arrayEach)(selected, function (_ref) {
        var start = _ref.start,
            end = _ref.end;

        if (start.row === end.row && start.col === end.col) {
          if (place === 'noBorders') {
            _this7.removeAllBorders(start.row, start.col);
          } else {
            _this7.setBorder(start.row, start.col, place, remove);
          }
        } else {
          switch (place) {
            case 'noBorders':
              (0, _number.rangeEach)(start.col, end.col, function (colIndex) {
                (0, _number.rangeEach)(start.row, end.row, function (rowIndex) {
                  _this7.removeAllBorders(rowIndex, colIndex);
                });
              });
              break;

            case 'top':
              (0, _number.rangeEach)(start.col, end.col, function (topCol) {
                _this7.setBorder(start.row, topCol, place, remove);
              });
              break;

            case 'right':
              (0, _number.rangeEach)(start.row, end.row, function (rowRight) {
                _this7.setBorder(rowRight, end.col, place, remove);
              });
              break;

            case 'bottom':
              (0, _number.rangeEach)(start.col, end.col, function (bottomCol) {
                _this7.setBorder(end.row, bottomCol, place, remove);
              });
              break;

            case 'left':
              (0, _number.rangeEach)(start.row, end.row, function (rowLeft) {
                _this7.setBorder(rowLeft, start.col, place, remove);
              });
              break;

            default:
              break;
          }
        }
      });
    }
    /**
     * Create borders from settings.
     *
     * @private
     * @param {Array} customBorders Object with `row` and `col`, `left`, `right`, `top` and `bottom` properties.
     */

  }, {
    key: "createCustomBorders",
    value: function createCustomBorders(customBorders) {
      var _this8 = this;

      (0, _array.arrayEach)(customBorders, function (customBorder) {
        if (customBorder.range) {
          _this8.prepareBorderFromCustomAddedRange(customBorder);
        } else {
          _this8.prepareBorderFromCustomAdded(customBorder.row, customBorder.col, customBorder);
        }
      });
    }
    /**
    * Count hide property in border object.
    *
    * @private
    * @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
    */

  }, {
    key: "countHide",
    value: function countHide(border) {
      var values = Object.values(border);
      return (0, _array.arrayReduce)(values, function (accumulator, value) {
        var result = accumulator;

        if (value.hide) {
          result += 1;
        }

        return result;
      }, 0);
    }
    /**
    * Clear borders settings from custom selections.
    *
    * @private
    * @param {String} borderId Border id name as string.
    */

  }, {
    key: "clearBordersFromSelectionSettings",
    value: function clearBordersFromSelectionSettings(borderId) {
      var index = (0, _array.arrayMap)(this.hot.selection.highlight.customSelections, function (customSelection) {
        return customSelection.settings.id;
      }).indexOf(borderId);

      if (index > -1) {
        this.hot.selection.highlight.customSelections[index].clear();
      }

      this.hot.view.wt.draw(true);
    }
    /**
    * Clear cellRange with null value.
    *
    * @private
    */

  }, {
    key: "clearNullCellRange",
    value: function clearNullCellRange() {
      var _this9 = this;

      (0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection, index) {
        if (customSelection.cellRange === null) {
          _this9.hot.selection.highlight.customSelections.splice(index, 1);

          return false; // breaks forAll
        }
      });
    }
    /**
      * Hide custom borders.
      *
      * @private
      */

  }, {
    key: "hideBorders",
    value: function hideBorders() {
      var _this10 = this;

      (0, _array.arrayEach)(this.savedBorders, function (border) {
        _this10.clearBordersFromSelectionSettings(border.id);
      });
    }
    /**
    * Splice border from savedBorders.
    *
    * @private
    * @param {String} borderId Border id name as string.
    */

  }, {
    key: "spliceBorder",
    value: function spliceBorder(borderId) {
      var index = (0, _array.arrayMap)(this.savedBorders, function (border) {
        return border.id;
      }).indexOf(borderId);

      if (index > -1) {
        this.savedBorders.splice(index, 1);
      }
    }
    /**
    * Check if an border already exists in the savedBorders array, and if true update border in savedBorders.
    *
    * @private
    * @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
    *
    * @return {Boolean}
    */

  }, {
    key: "checkSavedBorders",
    value: function checkSavedBorders(border) {
      var _this11 = this;

      var check = false;
      var hideCount = this.countHide(border);

      if (hideCount === 4) {
        this.spliceBorder(border.id);
        check = true;
      } else {
        (0, _array.arrayEach)(this.savedBorders, function (savedBorder, index) {
          if (border.id === savedBorder.id) {
            _this11.savedBorders[index] = border;
            check = true;
            return false; // breaks forAll
          }
        });
      }

      return check;
    }
    /**
    * Check if an border already exists in the customSelections, and if true call toggleHiddenClass method.
    *
    * @private
    * @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
    * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
    * @param {Boolean} remove True when remove borders, and false when add borders.
    *
    * @return {Boolean}
    */

  }, {
    key: "checkCustomSelectionsFromContextMenu",
    value: function checkCustomSelectionsFromContextMenu(border, place, remove) {
      var check = false;
      (0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
        if (border.id === customSelection.settings.id) {
          (0, _object.objectEach)(customSelection.instanceBorders, function (borderObject) {
            borderObject.toggleHiddenClass(place, remove);
          });
          check = true;
          return false; // breaks forAll
        }
      });
      return check;
    }
    /**
    * Check if an border already exists in the customSelections, and if true reset cellRange.
    *
    * @private
    * @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
    * @param {CellRange} cellRange
    * @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
    *
    * @return {Boolean}
    */

  }, {
    key: "checkCustomSelections",
    value: function checkCustomSelections(border, cellRange, place) {
      var hideCount = this.countHide(border);
      var check = false;

      if (hideCount === 4) {
        this.removeAllBorders(border.row, border.col);
        this.clearBordersFromSelectionSettings(border.id);
        this.clearNullCellRange();
        check = true;
      } else {
        (0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
          if (border.id === customSelection.settings.id) {
            customSelection.cellRange = cellRange;

            if (place) {
              (0, _object.objectEach)(customSelection.instanceBorders, function (borderObject) {
                borderObject.changeBorderStyle(place, border);
              });
            }

            check = true;
            return false; // breaks forAll
          }
        });
      }

      return check;
    }
    /**
     * Change borders from settings.
     *
     * @private
     */

  }, {
    key: "changeBorderSettings",
    value: function changeBorderSettings() {
      var customBorders = this.hot.getSettings().customBorders;

      if (Array.isArray(customBorders)) {
        if (!customBorders.length) {
          this.savedBorders = customBorders;
        }

        this.createCustomBorders(customBorders);
      } else if (customBorders !== void 0) {
        this.createCustomBorders(this.savedBorders);
      }
    }
    /**
    * Add border options to context menu.
    *
    * @private
    * @param {Object} defaultOptions Context menu items.
    */

  }, {
    key: "onAfterContextMenuDefaultOptions",
    value: function onAfterContextMenuDefaultOptions(defaultOptions) {
      if (!this.hot.getSettings().customBorders) {
        return;
      }

      defaultOptions.items.push({
        name: '---------'
      }, {
        key: 'borders',
        name: function name() {
          return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS);
        },
        disabled: function disabled() {
          return this.selection.isSelectedByCorner();
        },
        submenu: {
          items: [(0, _contextMenuItem.top)(this), (0, _contextMenuItem.right)(this), (0, _contextMenuItem.bottom)(this), (0, _contextMenuItem.left)(this), (0, _contextMenuItem.noBorders)(this)]
        }
      });
    }
    /**
     * `afterInit` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.changeBorderSettings();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "destroy", this).call(this);
    }
  }]);
  return CustomBorders;
}(_base.default);

(0, _plugins.registerPlugin)('customBorders', CustomBorders);
var _default = CustomBorders;
exports.default = _default;

/***/ }),
/* 643 */
/***/ (function(module, exports, __webpack_require__) {

var objectToArray = __webpack_require__(644);

// `Object.values` method
// https://tc39.github.io/ecma262/#sec-object.values
__webpack_require__(22)({ target: 'Object', stat: true }, {
  values: function values(O) {
    return objectToArray(O);
  }
});


/***/ }),
/* 644 */
/***/ (function(module, exports, __webpack_require__) {

var objectKeys = __webpack_require__(89);
var toIndexedObject = __webpack_require__(69);
var propertyIsEnumerable = __webpack_require__(95).f;

// TO_ENTRIES: true  -> Object.entries
// TO_ENTRIES: false -> Object.values
module.exports = function (it, TO_ENTRIES) {
  var O = toIndexedObject(it);
  var keys = objectKeys(O);
  var length = keys.length;
  var i = 0;
  var result = [];
  var key;
  while (length > i) if (propertyIsEnumerable.call(O, key = keys[i++])) {
    result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
  } return result;
};


/***/ }),
/* 645 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;

var _bottom = _interopRequireDefault(__webpack_require__(646));

exports.bottom = _bottom.default;

var _left = _interopRequireDefault(__webpack_require__(647));

exports.left = _left.default;

var _noBorders = _interopRequireDefault(__webpack_require__(648));

exports.noBorders = _noBorders.default;

var _right = _interopRequireDefault(__webpack_require__(649));

exports.right = _right.default;

var _top = _interopRequireDefault(__webpack_require__(650));

exports.top = _top.default;

/***/ }),
/* 646 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = bottom;

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(92);

function bottom(customBordersPlugin) {
  return {
    key: 'borders:bottom',
    name: function name() {
      var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_BOTTOM);
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'bottom');

      if (hasBorder) {
        label = (0, _utils.markSelected)(label);
      }

      return label;
    },
    callback: function callback(key, selected) {
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'bottom');
      customBordersPlugin.prepareBorder(selected, 'bottom', hasBorder);
    }
  };
}

/***/ }),
/* 647 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = left;

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(92);

function left(customBordersPlugin) {
  return {
    key: 'borders:left',
    name: function name() {
      var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_LEFT);
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'left');

      if (hasBorder) {
        label = (0, _utils.markSelected)(label);
      }

      return label;
    },
    callback: function callback(key, selected) {
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'left');
      customBordersPlugin.prepareBorder(selected, 'left', hasBorder);
    }
  };
}

/***/ }),
/* 648 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = noBorders;

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(92);

function noBorders(customBordersPlugin) {
  return {
    key: 'borders:no_borders',
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REMOVE_BORDERS);
    },
    callback: function callback(key, selected) {
      customBordersPlugin.prepareBorder(selected, 'noBorders');
    },
    disabled: function disabled() {
      return !(0, _utils.checkSelectionBorders)(this);
    }
  };
}

/***/ }),
/* 649 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = right;

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(92);

function right(customBordersPlugin) {
  return {
    key: 'borders:right',
    name: function name() {
      var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_RIGHT);
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'right');

      if (hasBorder) {
        label = (0, _utils.markSelected)(label);
      }

      return label;
    },
    callback: function callback(key, selected) {
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'right');
      customBordersPlugin.prepareBorder(selected, 'right', hasBorder);
    }
  };
}

/***/ }),
/* 650 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = top;

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(92);

function top(customBordersPlugin) {
  return {
    key: 'borders:top',
    name: function name() {
      var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_TOP);
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'top');

      if (hasBorder) {
        label = (0, _utils.markSelected)(label);
      }

      return label;
    },
    callback: function callback(key, selected) {
      var hasBorder = (0, _utils.checkSelectionBorders)(this, 'top');
      customBordersPlugin.prepareBorder(selected, 'top', hasBorder);
    }
  };
}

/***/ }),
/* 651 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

/**
 * @description
 * Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport.
 *
 *
 * @class DragToScroll
 * @plugin DragToScroll
 */
var DragToScroll =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(DragToScroll, _BasePlugin);

  function DragToScroll(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, DragToScroll);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DragToScroll).call(this, hotInstance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Size of an element and its position relative to the viewport,
     * e.g. {bottom: 449, height: 441, left: 8, right: 814, top: 8, width: 806, x: 8, y:8}.
     *
     * @type {DOMRect}
     */

    _this.boundaries = null;
    /**
     * Callback function.
     *
     * @private
     * @type {Function}
     */

    _this.callback = null;
    /**
     * Flag indicates mouseDown/mouseUp.
     *
     * @private
     * @type {Boolean}
     */

    _this.listening = false;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link DragToScroll#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(DragToScroll, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().dragToScroll;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('afterOnCellMouseDown', function () {
        return _this2.setupListening();
      });
      this.addHook('afterOnCellCornerMouseDown', function () {
        return _this2.setupListening();
      });
      this.registerEvents();
      (0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.unregisterEvents();
      (0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Sets the value of the visible element.
     *
     * @param boundaries {DOMRect} An object with coordinates compatible with DOMRect.
     */

  }, {
    key: "setBoundaries",
    value: function setBoundaries(boundaries) {
      this.boundaries = boundaries;
    }
    /**
     * Changes callback function.
     *
     * @param callback {Function}
     */

  }, {
    key: "setCallback",
    value: function setCallback(callback) {
      this.callback = callback;
    }
    /**
     * Checks if the mouse position (X, Y) is outside of the viewport and fires a callback with calculated X an Y diffs
     * between passed boundaries.
     *
     * @param {Number} x Mouse X coordinate to check.
     * @param {Number} y Mouse Y coordinate to check.
     */

  }, {
    key: "check",
    value: function check(x, y) {
      var diffX = 0;
      var diffY = 0;

      if (y < this.boundaries.top) {
        // y is less than top
        diffY = y - this.boundaries.top;
      } else if (y > this.boundaries.bottom) {
        // y is more than bottom
        diffY = y - this.boundaries.bottom;
      }

      if (x < this.boundaries.left) {
        // x is less than left
        diffX = x - this.boundaries.left;
      } else if (x > this.boundaries.right) {
        // x is more than right
        diffX = x - this.boundaries.right;
      }

      this.callback(diffX, diffY);
    }
    /**
     * Registers dom listeners.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this3 = this;

      var rootDocument = this.hot.rootDocument;
      this.eventManager.addEventListener(rootDocument, 'mouseup', function () {
        return _this3.onMouseUp();
      });
      this.eventManager.addEventListener(rootDocument, 'mousemove', function (event) {
        return _this3.onMouseMove(event);
      });
    }
    /**
     * Unbinds the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "unregisterEvents",
    value: function unregisterEvents() {
      this.eventManager.clear();
    }
    /**
     * On after on cell/cellCorner mouse down listener.
     *
     * @private
     */

  }, {
    key: "setupListening",
    value: function setupListening() {
      var scrollHandler = this.hot.view.wt.wtTable.holder; // native scroll

      if (scrollHandler === this.hot.rootWindow) {
        // not much we can do currently
        return;
      }

      this.setBoundaries(scrollHandler.getBoundingClientRect());
      this.setCallback(function (scrollX, scrollY) {
        if (scrollX < 0) {
          scrollHandler.scrollLeft -= 50;
        } else if (scrollX > 0) {
          scrollHandler.scrollLeft += 50;
        }

        if (scrollY < 0) {
          scrollHandler.scrollTop -= 20;
        } else if (scrollY > 0) {
          scrollHandler.scrollTop += 20;
        }
      });
      this.listening = true;
    }
    /**
     * 'mouseMove' event callback.
     *
     * @private
     * @param {MouseEvent} event `mousemove` event properties.
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      if (this.listening) {
        this.check(event.clientX, event.clientY);
      }
    }
    /**
     * `onMouseUp` hook callback.
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      this.listening = false;
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "destroy", this).call(this);
    }
  }]);
  return DragToScroll;
}(_base.default);

(0, _plugins.registerPlugin)('dragToScroll', DragToScroll);
var _default = DragToScroll;
exports.default = _default;

/***/ }),
/* 652 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _array = __webpack_require__(3);

var _freezeColumn = _interopRequireDefault(__webpack_require__(653));

var _unfreezeColumn = _interopRequireDefault(__webpack_require__(654));

__webpack_require__(655);

var privatePool = new WeakMap();
/**
 * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu or using API.
 * You can turn it on by setting a {@link Options#manualColumnFreeze} property to `true`.
 *
 * @example
 * ```js
 * // Enables the plugin
 * manualColumnFreeze: true,
 * ```
 *
 * @plugin ManualColumnFreeze
 * @dependencies ManualColumnMove
 */

var ManualColumnFreeze =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ManualColumnFreeze, _BasePlugin);

  function ManualColumnFreeze(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ManualColumnFreeze);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnFreeze).call(this, hotInstance));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      moveByFreeze: false,
      afterFirstUse: false
    });
    /**
     * Original column positions
     *
     * @private
     * @type {Array}
     */

    _this.frozenColumnsBasePositions = [];
    /**
     * Reference to the `ManualColumnMove` plugin.
     *
     * @private
     * @type {ManualColumnMove}
     */

    _this.manualColumnMovePlugin = void 0;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ManualColumnFreeze#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ManualColumnFreeze, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().manualColumnFreeze;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.addContextMenuEntry(options);
      });
      this.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      this.addHook('beforeColumnMove', function (rows, target) {
        return _this2.onBeforeColumnMove(rows, target);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      var priv = privatePool.get(this);
      priv.afterFirstUse = false;
      priv.moveByFreeze = false;
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Freezes the given column (add it to fixed columns).
     *
     * @param {Number} column Visual column index.
     */

  }, {
    key: "freezeColumn",
    value: function freezeColumn(column) {
      var priv = privatePool.get(this);
      var settings = this.hot.getSettings();

      if (!priv.afterFirstUse) {
        priv.afterFirstUse = true;
      }

      if (settings.fixedColumnsLeft === this.hot.countCols() || column <= settings.fixedColumnsLeft - 1) {
        return; // already fixed
      }

      priv.moveByFreeze = true;

      if (column !== this.getMovePlugin().columnsMapper.getValueByIndex(column)) {
        this.frozenColumnsBasePositions[settings.fixedColumnsLeft] = column;
      }

      this.getMovePlugin().moveColumn(column, settings.fixedColumnsLeft);
      settings.fixedColumnsLeft += 1;
    }
    /**
     * Unfreezes the given column (remove it from fixed columns and bring to it's previous position).
     *
     * @param {Number} column Visual column index.
     */

  }, {
    key: "unfreezeColumn",
    value: function unfreezeColumn(column) {
      var priv = privatePool.get(this);
      var settings = this.hot.getSettings();

      if (!priv.afterFirstUse) {
        priv.afterFirstUse = true;
      }

      if (settings.fixedColumnsLeft <= 0 || column > settings.fixedColumnsLeft - 1) {
        return; // not fixed
      }

      var returnCol = this.getBestColumnReturnPosition(column);
      priv.moveByFreeze = true;
      settings.fixedColumnsLeft -= 1;
      this.getMovePlugin().moveColumn(column, returnCol + 1);
    }
    /**
     * Gets the reference to the ManualColumnMove plugin.
     *
     * @private
     * @returns {Object}
     */

  }, {
    key: "getMovePlugin",
    value: function getMovePlugin() {
      if (!this.manualColumnMovePlugin) {
        this.manualColumnMovePlugin = this.hot.getPlugin('manualColumnMove');
      }

      return this.manualColumnMovePlugin;
    }
    /**
     * Estimates the most fitting return position for unfrozen column.
     *
     * @private
     * @param {Number} column Visual column index.
     */

  }, {
    key: "getBestColumnReturnPosition",
    value: function getBestColumnReturnPosition(column) {
      var movePlugin = this.getMovePlugin();
      var settings = this.hot.getSettings();
      var i = settings.fixedColumnsLeft;
      var j = movePlugin.columnsMapper.getValueByIndex(i);
      var initialCol;

      if (this.frozenColumnsBasePositions[column] === null || this.frozenColumnsBasePositions[column] === void 0) {
        initialCol = movePlugin.columnsMapper.getValueByIndex(column);

        while (j !== null && j <= initialCol) {
          i += 1;
          j = movePlugin.columnsMapper.getValueByIndex(i);
        }
      } else {
        initialCol = this.frozenColumnsBasePositions[column];
        this.frozenColumnsBasePositions[column] = void 0;

        while (j !== null && j <= initialCol) {
          i += 1;
          j = movePlugin.columnsMapper.getValueByIndex(i);
        }

        i = j;
      }

      return i - 1;
    }
    /**
     * Adds the manualColumnFreeze context menu entries.
     *
     * @private
     * @param {Object} options Context menu options.
     */

  }, {
    key: "addContextMenuEntry",
    value: function addContextMenuEntry(options) {
      options.items.push({
        name: '---------'
      }, (0, _freezeColumn.default)(this), (0, _unfreezeColumn.default)(this));
    }
    /**
     * Enables `manualColumnMove` plugin on `afterInit` hook.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      if (!this.getMovePlugin().isEnabled()) {
        this.getMovePlugin().enablePlugin();
      }
    }
    /**
     * Prevents moving the rows from/to fixed area.
     *
     * @private
     * @param {Array} rows
     * @param {Number} target
     */

  }, {
    key: "onBeforeColumnMove",
    value: function onBeforeColumnMove(rows, target) {
      var priv = privatePool.get(this);

      if (priv.afterFirstUse && !priv.moveByFreeze) {
        var frozenLen = this.hot.getSettings().fixedColumnsLeft;
        var disallowMoving = target < frozenLen;

        if (!disallowMoving) {
          (0, _array.arrayEach)(rows, function (value) {
            if (value < frozenLen) {
              disallowMoving = true;
              return false;
            }
          });
        }

        if (disallowMoving) {
          return false;
        }
      }

      if (priv.moveByFreeze) {
        priv.moveByFreeze = false;
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "destroy", this).call(this);
    }
  }]);
  return ManualColumnFreeze;
}(_base.default);

(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze);
var _default = ManualColumnFreeze;
exports.default = _default;

/***/ }),
/* 653 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = freezeColumnItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

function freezeColumnItem(manualColumnFreezePlugin) {
  return {
    key: 'freeze_column',
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_FREEZE_COLUMN);
    },
    callback: function callback(key, selected) {
      var _selected = (0, _slicedToArray2.default)(selected, 1),
          selectedColumn = _selected[0].start.col;

      manualColumnFreezePlugin.freezeColumn(selectedColumn);
      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    hidden: function hidden() {
      var selection = this.getSelectedRange();
      var hide = false;

      if (selection === void 0) {
        hide = true;
      } else if (selection.length > 1) {
        hide = true;
      } else if (selection[0].from.col !== selection[0].to.col || selection[0].from.col <= this.getSettings().fixedColumnsLeft - 1) {
        hide = true;
      }

      return hide;
    }
  };
}

/***/ }),
/* 654 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = unfreezeColumnItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

function unfreezeColumnItem(manualColumnFreezePlugin) {
  return {
    key: 'unfreeze_column',
    name: function name() {
      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN);
    },
    callback: function callback(key, selected) {
      var _selected = (0, _slicedToArray2.default)(selected, 1),
          selectedColumn = _selected[0].start.col;

      manualColumnFreezePlugin.unfreezeColumn(selectedColumn);
      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    hidden: function hidden() {
      var selection = this.getSelectedRange();
      var hide = false;

      if (selection === void 0) {
        hide = true;
      } else if (selection.length > 1) {
        hide = true;
      } else if (selection[0].from.col !== selection[0].to.col || selection[0].from.col >= this.getSettings().fixedColumnsLeft) {
        hide = true;
      }

      return hide;
    }
  };
}

/***/ }),
/* 655 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 656 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _array = __webpack_require__(3);

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _columnsMapper = _interopRequireDefault(__webpack_require__(657));

var _backlight = _interopRequireDefault(__webpack_require__(658));

var _guideline = _interopRequireDefault(__webpack_require__(659));

__webpack_require__(660);

_pluginHooks.default.getSingleton().register('beforeColumnMove');

_pluginHooks.default.getSingleton().register('afterColumnMove');

_pluginHooks.default.getSingleton().register('unmodifyCol');

var privatePool = new WeakMap();
var CSS_PLUGIN = 'ht__manualColumnMove';
var CSS_SHOW_UI = 'show-ui';
var CSS_ON_MOVING = 'on-moving--columns';
var CSS_AFTER_SELECTION = 'after-selection--columns';
/**
 * @plugin ManualColumnMove
 *
 * @description
 * This plugin allows to change columns order. To make columns order persistent the {@link Options#persistentState}
 * plugin should be enabled.
 *
 * API:
 * - moveColumn - move single column to the new position.
 * - moveColumns - move many columns (as an array of indexes) to the new position.
 *
 * If you want apply visual changes, you have to call manually the render() method on the instance of Handsontable.
 *
 * The plugin creates additional components to make moving possibly using user interface:
 * - backlight - highlight of selected columns.
 * - guideline - line which shows where rows has been moved.
 *
 * @class ManualColumnMove
 * @plugin ManualColumnMove
 */

var ManualColumnMove =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ManualColumnMove, _BasePlugin);

  function ManualColumnMove(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ManualColumnMove);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnMove).call(this, hotInstance));
    /**
     * Set up WeakMap of plugin to sharing private parameters;
     */

    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      columnsToMove: [],
      countCols: 0,
      fixedColumns: 0,
      pressed: void 0,
      disallowMoving: void 0,
      target: {
        eventPageX: void 0,
        coords: void 0,
        TD: void 0,
        col: void 0
      }
    });
    /**
     * List of last removed row indexes.
     *
     * @private
     * @type {Array}
     */

    _this.removedColumns = [];
    /**
     * Object containing visual row indexes mapped to data source indexes.
     *
     * @private
     * @type {RowsMapper}
     */

    _this.columnsMapper = new _columnsMapper.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Event Manager object.
     *
     * @private
     * @type {Object}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Backlight UI object.
     *
     * @private
     * @type {Object}
     */

    _this.backlight = new _backlight.default(hotInstance);
    /**
     * Guideline UI object.
     *
     * @private
     * @type {Object}
     */

    _this.guideline = new _guideline.default(hotInstance);
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ManualColumnMove#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ManualColumnMove, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().manualColumnMove;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) {
        return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations);
      });
      this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
        return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
      });
      this.addHook('afterScrollVertically', function () {
        return _this2.onAfterScrollVertically();
      });
      this.addHook('modifyCol', function (row, source) {
        return _this2.onModifyCol(row, source);
      });
      this.addHook('beforeRemoveCol', function (index, amount) {
        return _this2.onBeforeRemoveCol(index, amount);
      });
      this.addHook('afterRemoveCol', function () {
        return _this2.onAfterRemoveCol();
      });
      this.addHook('afterCreateCol', function (index, amount) {
        return _this2.onAfterCreateCol(index, amount);
      });
      this.addHook('afterLoadData', function () {
        return _this2.onAfterLoadData();
      });
      this.addHook('unmodifyCol', function (column) {
        return _this2.onUnmodifyCol(column);
      });
      this.registerEvents(); // TODO: move adding plugin classname to BasePlugin.

      (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN);
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      this.onAfterPluginsInitialized();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      var pluginSettings = this.hot.getSettings().manualColumnMove;

      if (Array.isArray(pluginSettings)) {
        this.columnsMapper.clearMap();
      }

      (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN);
      this.unregisterEvents();
      this.backlight.destroy();
      this.guideline.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Moves a single column.
     *
     * @param {Number} column Visual column index to be moved.
     * @param {Number} target Visual column index being a target for the moved column.
     * @fires Hooks#beforeColumnMove
     * @fires Hooks#afterColumnMove
     */

  }, {
    key: "moveColumn",
    value: function moveColumn(column, target) {
      this.moveColumns([column], target);
    }
    /**
     * Moves a multiple columns.
     *
     * @param {Array} columns Array of visual column indexes to be moved.
     * @param {Number} target Visual column index being a target for the moved columns.
     * @fires Hooks#beforeColumnMove
     * @fires Hooks#afterColumnMove
     */

  }, {
    key: "moveColumns",
    value: function moveColumns(columns, target) {
      var _this3 = this;

      var visualColumns = (0, _toConsumableArray2.default)(columns);
      var priv = privatePool.get(this);
      var beforeColumnHook = this.hot.runHooks('beforeColumnMove', visualColumns, target);
      priv.disallowMoving = !beforeColumnHook;

      if (beforeColumnHook !== false) {
        // first we need to rewrite an visual indexes to physical for save reference after move
        (0, _array.arrayEach)(columns, function (column, index, array) {
          array[index] = _this3.columnsMapper.getValueByIndex(column);
        }); // next, when we have got an physical indexes, we can move columns

        (0, _array.arrayEach)(columns, function (column, index) {
          var actualPosition = _this3.columnsMapper.getIndexByValue(column);

          if (actualPosition !== target) {
            _this3.columnsMapper.moveColumn(actualPosition, target + index);
          }
        }); // after moving we have to clear columnsMapper from null entries

        this.columnsMapper.clearNull();
      }

      this.hot.runHooks('afterColumnMove', visualColumns, target);
    }
    /**
     * Correct the cell selection after the move action. Fired only when action was made with a mouse.
     * That means that changing the column order using the API won't correct the selection.
     *
     * @private
     * @param {Number} startColumn Visual column index for the start of the selection.
     * @param {Number} endColumn Visual column index for the end of the selection.
     */

  }, {
    key: "changeSelection",
    value: function changeSelection(startColumn, endColumn) {
      this.hot.selectColumns(startColumn, endColumn);
    }
    /**
     * Gets the sum of the widths of columns in the provided range.
     *
     * @private
     * @param {Number} from Visual column index.
     * @param {Number} to Visual column index.
     * @returns {Number}
     */

  }, {
    key: "getColumnsWidth",
    value: function getColumnsWidth(from, to) {
      var width = 0;

      for (var i = from; i < to; i++) {
        var columnWidth = 0;

        if (i < 0) {
          columnWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth() || 0;
        } else {
          columnWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(i) || 0;
        }

        width += columnWidth;
      }

      return width;
    }
    /**
     * Loads initial settings when persistent state is saved or when plugin was initialized as an array.
     *
     * @private
     */

  }, {
    key: "initialSettings",
    value: function initialSettings() {
      var pluginSettings = this.hot.getSettings().manualColumnMove;

      if (Array.isArray(pluginSettings)) {
        this.moveColumns(pluginSettings, 0);
      } else if (pluginSettings !== void 0) {
        this.persistentStateLoad();
      }
    }
    /**
     * Checks if the provided column is in the fixedColumnsLeft section.
     *
     * @private
     * @param {Number} column Visual column index to check.
     * @returns {Boolean}
     */

  }, {
    key: "isFixedColumnsLeft",
    value: function isFixedColumnsLeft(column) {
      return column < this.hot.getSettings().fixedColumnsLeft;
    }
    /**
     * Saves the manual column positions to the persistent state (the {@link Options#persistentState} option has to be enabled).
     */

  }, {
    key: "persistentStateSave",
    value: function persistentStateSave() {
      this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap);
    }
    /**
     * Loads the manual column positions from the persistent state (the {@link Options#persistentState} option has to be enabled).
     */

  }, {
    key: "persistentStateLoad",
    value: function persistentStateLoad() {
      var storedState = {};
      this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState);

      if (storedState.value) {
        this.columnsMapper._arrayMap = storedState.value;
      }
    }
    /**
     * Prepares an array of indexes based on actual selection.
     *
     * @private
     * @returns {Array}
     */

  }, {
    key: "prepareColumnsToMoving",
    value: function prepareColumnsToMoving(start, end) {
      var selectedColumns = [];
      (0, _number.rangeEach)(start, end, function (i) {
        selectedColumns.push(i);
      });
      return selectedColumns;
    }
    /**
     * Updates the UI visual position.
     *
     * @private
     */

  }, {
    key: "refreshPositions",
    value: function refreshPositions() {
      var priv = privatePool.get(this);
      var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleColumn();
      var lastVisible = this.hot.view.wt.wtTable.getLastVisibleColumn();
      var wtTable = this.hot.view.wt.wtTable;
      var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement;
      var scrollLeft = typeof scrollableElement.scrollX === 'number' ? scrollableElement.scrollX : scrollableElement.scrollLeft;
      var tdOffsetLeft = this.hot.view.THEAD.offsetLeft + this.getColumnsWidth(0, priv.coordsColumn);
      var mouseOffsetLeft = priv.target.eventPageX - (priv.rootElementOffset - (scrollableElement.scrollX === void 0 ? scrollLeft : 0));
      var hiderWidth = wtTable.hider.offsetWidth;
      var tbodyOffsetLeft = wtTable.TBODY.offsetLeft;
      var backlightElemMarginLeft = this.backlight.getOffset().left;
      var backlightElemWidth = this.backlight.getSize().width;
      var rowHeaderWidth = 0;

      if (priv.rootElementOffset + wtTable.holder.offsetWidth + scrollLeft < priv.target.eventPageX) {
        if (priv.coordsColumn < priv.countCols) {
          priv.coordsColumn += 1;
        }
      }

      if (priv.hasRowHeaders) {
        rowHeaderWidth = this.hot.view.wt.wtOverlays.leftOverlay.clone.wtTable.getColumnHeader(-1).offsetWidth;
      }

      if (this.isFixedColumnsLeft(priv.coordsColumn)) {
        tdOffsetLeft += scrollLeft;
      }

      tdOffsetLeft += rowHeaderWidth;

      if (priv.coordsColumn < 0) {
        // if hover on rowHeader
        if (priv.fixedColumns > 0) {
          priv.target.col = 0;
        } else {
          priv.target.col = firstVisible > 0 ? firstVisible - 1 : firstVisible;
        }
      } else if (priv.target.TD.offsetWidth / 2 + tdOffsetLeft <= mouseOffsetLeft) {
        var newCoordsCol = priv.coordsColumn >= priv.countCols ? priv.countCols - 1 : priv.coordsColumn; // if hover on right part of TD

        priv.target.col = newCoordsCol + 1; // unfortunately first column is bigger than rest

        tdOffsetLeft += priv.target.TD.offsetWidth;

        if (priv.target.col > lastVisible && lastVisible < priv.countCols) {
          this.hot.scrollViewportTo(void 0, lastVisible + 1, void 0, true);
        }
      } else {
        // elsewhere on table
        priv.target.col = priv.coordsColumn;

        if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns && firstVisible > 0) {
          this.hot.scrollViewportTo(void 0, firstVisible - 1);
        }
      }

      if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns && firstVisible > 0) {
        this.hot.scrollViewportTo(void 0, firstVisible - 1);
      }

      var backlightLeft = mouseOffsetLeft;
      var guidelineLeft = tdOffsetLeft;

      if (mouseOffsetLeft + backlightElemWidth + backlightElemMarginLeft >= hiderWidth) {
        // prevent display backlight on the right side of the table
        backlightLeft = hiderWidth - backlightElemWidth - backlightElemMarginLeft;
      } else if (mouseOffsetLeft + backlightElemMarginLeft < tbodyOffsetLeft + rowHeaderWidth) {
        // prevent display backlight on the left side of the table
        backlightLeft = tbodyOffsetLeft + rowHeaderWidth + Math.abs(backlightElemMarginLeft);
      }

      if (tdOffsetLeft >= hiderWidth - 1) {
        // prevent display guideline outside the table
        guidelineLeft = hiderWidth - 1;
      } else if (guidelineLeft === 0) {
        // guideline has got `margin-left: -1px` as default
        guidelineLeft = 1;
      } else if (scrollableElement.scrollX !== void 0 && priv.coordsColumn < priv.fixedColumns) {
        guidelineLeft -= priv.rootElementOffset <= scrollableElement.scrollX ? priv.rootElementOffset : 0;
      }

      this.backlight.setPosition(null, backlightLeft);
      this.guideline.setPosition(null, guidelineLeft);
    }
    /**
     * This method checks arrayMap from columnsMapper and updates the columnsMapper if it's necessary.
     *
     * @private
     */

  }, {
    key: "updateColumnsMapper",
    value: function updateColumnsMapper() {
      var countCols = this.hot.countSourceCols();
      var columnsMapperLen = this.columnsMapper._arrayMap.length;

      if (columnsMapperLen === 0) {
        this.columnsMapper.createMap(countCols || this.hot.getSettings().startCols);
      } else if (columnsMapperLen < countCols) {
        var diff = countCols - columnsMapperLen;
        this.columnsMapper.insertItems(columnsMapperLen, diff);
      } else if (columnsMapperLen > countCols) {
        var maxIndex = countCols - 1;
        var columnsToRemove = [];
        (0, _array.arrayEach)(this.columnsMapper._arrayMap, function (value, index) {
          if (value > maxIndex) {
            columnsToRemove.push(index);
          }
        });
        this.columnsMapper.removeItems(columnsToRemove);
      }
    }
    /**
     * Binds the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this4 = this;

      var documentElement = this.hot.rootDocument.documentElement;
      this.eventManager.addEventListener(documentElement, 'mousemove', function (event) {
        return _this4.onMouseMove(event);
      });
      this.eventManager.addEventListener(documentElement, 'mouseup', function () {
        return _this4.onMouseUp();
      });
    }
    /**
     * Unbinds the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "unregisterEvents",
    value: function unregisterEvents() {
      this.eventManager.clear();
    }
    /**
     * Changes the behavior of selection / dragging.
     *
     * @private
     * @param {MouseEvent} event `mousedown` event properties.
     * @param {CellCoords} coords Visual cell coordinates where was fired event.
     * @param {HTMLElement} TD Cell represented as HTMLElement.
     * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells.
     */

  }, {
    key: "onBeforeOnCellMouseDown",
    value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) {
      var wtTable = this.hot.view.wt.wtTable;
      var isHeaderSelection = this.hot.selection.isSelectedByColumnHeader();
      var selection = this.hot.getSelectedRangeLast();
      var priv = privatePool.get(this); // This block action shouldn't be handled below.

      var isSortingElement = event.realTarget.className.indexOf('sortAction') > -1;

      if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0 || isSortingElement) {
        priv.pressed = false;
        priv.columnsToMove.length = 0;
        (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]);
        return;
      }

      var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended();
      var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended();

      if (guidelineIsNotReady && backlightIsNotReady) {
        this.guideline.appendTo(wtTable.hider);
        this.backlight.appendTo(wtTable.hider);
      }

      var from = selection.from,
          to = selection.to;
      var start = Math.min(from.col, to.col);
      var end = Math.max(from.col, to.col);

      if (coords.row < 0 && coords.col >= start && coords.col <= end) {
        blockCalculations.column = true;
        priv.pressed = true;
        priv.target.eventPageX = event.pageX;
        priv.coordsColumn = coords.col;
        priv.target.TD = TD;
        priv.target.col = coords.col;
        priv.columnsToMove = this.prepareColumnsToMoving(start, end);
        priv.hasRowHeaders = !!this.hot.getSettings().rowHeaders;
        priv.countCols = this.hot.countCols();
        priv.fixedColumns = this.hot.getSettings().fixedColumnsLeft;
        priv.rootElementOffset = (0, _element.offset)(this.hot.rootElement).left;
        var countColumnsFrom = priv.hasRowHeaders ? -1 : 0;
        var topPos = wtTable.holder.scrollTop + wtTable.getColumnHeaderHeight(0) + 1;
        var fixedColumns = coords.col < priv.fixedColumns;
        var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement;
        var wrapperIsWindow = scrollableElement.scrollX ? scrollableElement.scrollX - priv.rootElementOffset : 0;
        var mouseOffset = event.layerX - (fixedColumns ? wrapperIsWindow : 0);
        var leftOffset = Math.abs(this.getColumnsWidth(start, coords.col) + mouseOffset);
        this.backlight.setPosition(topPos, this.getColumnsWidth(countColumnsFrom, start) + leftOffset);
        this.backlight.setSize(this.getColumnsWidth(start, end + 1), wtTable.hider.offsetHeight - topPos);
        this.backlight.setOffset(null, leftOffset * -1);
        (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING);
      } else {
        (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
        priv.pressed = false;
        priv.columnsToMove.length = 0;
      }
    }
    /**
     * 'mouseMove' event callback. Fired when pointer move on document.documentElement.
     *
     * @private
     * @param {MouseEvent} event `mousemove` event properties.
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var priv = privatePool.get(this);

      if (!priv.pressed) {
        return;
      } // callback for browser which doesn't supports CSS pointer-event: none


      if (event.realTarget === this.backlight.element) {
        var width = this.backlight.getSize().width;
        this.backlight.setSize(0);
        setTimeout(function () {
          this.backlight.setPosition(width);
        });
      }

      priv.target.eventPageX = event.pageX;
      this.refreshPositions();
    }
    /**
     * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell.
     *
     * @private
     * @param {MouseEvent} event `mouseover` event properties.
     * @param {CellCoords} coords Visual cell coordinates where was fired event.
     * @param {HTMLElement} TD Cell represented as HTMLElement.
     * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells.
     */

  }, {
    key: "onBeforeOnCellMouseOver",
    value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
      var selectedRange = this.hot.getSelectedRangeLast();
      var priv = privatePool.get(this);

      if (!selectedRange || !priv.pressed) {
        return;
      }

      if (priv.columnsToMove.indexOf(coords.col) > -1) {
        (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI);
      } else {
        (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI);
      }

      blockCalculations.row = true;
      blockCalculations.column = true;
      blockCalculations.cell = true;
      priv.coordsColumn = coords.col;
      priv.target.TD = TD;
    }
    /**
     * `onMouseUp` hook callback.
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      var priv = privatePool.get(this);
      priv.coordsColumn = void 0;
      priv.pressed = false;
      priv.backlightWidth = 0;
      (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]);

      if (this.hot.selection.isSelectedByColumnHeader()) {
        (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
      }

      if (priv.columnsToMove.length < 1 || priv.target.col === void 0 || priv.columnsToMove.indexOf(priv.target.col) > -1) {
        return;
      }

      this.moveColumns(priv.columnsToMove, priv.target.col);
      this.persistentStateSave();
      this.hot.render();
      this.hot.view.wt.wtOverlays.adjustElementsSize(true);

      if (!priv.disallowMoving) {
        var selectionStart = this.columnsMapper.getIndexByValue(priv.columnsToMove[0]);
        var selectionEnd = this.columnsMapper.getIndexByValue(priv.columnsToMove[priv.columnsToMove.length - 1]);
        this.changeSelection(selectionStart, selectionEnd);
      }

      priv.columnsToMove.length = 0;
    }
    /**
     * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally.
     *
     * @private
     */

  }, {
    key: "onAfterScrollVertically",
    value: function onAfterScrollVertically() {
      var wtTable = this.hot.view.wt.wtTable;
      var headerHeight = wtTable.getColumnHeaderHeight(0) + 1;
      var scrollTop = wtTable.holder.scrollTop;
      var posTop = headerHeight + scrollTop;
      this.backlight.setPosition(posTop);
      this.backlight.setSize(null, wtTable.hider.offsetHeight - posTop);
    }
    /**
     * `afterCreateCol` hook callback.
     *
     * @private
     * @param {Number} index Visual index of the created column.
     * @param {Number} amount Amount of created columns.
     */

  }, {
    key: "onAfterCreateCol",
    value: function onAfterCreateCol(index, amount) {
      this.columnsMapper.shiftItems(index, amount);
    }
    /**
     * On before remove column listener.
     *
     * @private
     * @param {Number} index Visual column index.
     * @param {Number} amount Defines how many columns removed.
     */

  }, {
    key: "onBeforeRemoveCol",
    value: function onBeforeRemoveCol(index, amount) {
      var _this5 = this;

      this.removedColumns.length = 0;

      if (index !== false) {
        // Collect physical row index.
        (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
          _this5.removedColumns.push(_this5.hot.runHooks('modifyCol', removedIndex, _this5.pluginName));
        });
      }
    }
    /**
     * `afterRemoveCol` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveCol",
    value: function onAfterRemoveCol() {
      this.columnsMapper.unshiftItems(this.removedColumns);
    }
    /**
     * `afterLoadData` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData() {
      this.updateColumnsMapper();
    }
    /**
     * 'modifyRow' hook callback.
     *
     * @private
     * @param {Number} column Visual column index.
     * @returns {Number} Physical column index.
     */

  }, {
    key: "onModifyCol",
    value: function onModifyCol(column, source) {
      var physicalColumn = column;

      if (source !== this.pluginName) {
        // ugly fix for try to insert new, needed columns after pasting data
        var columnInMapper = this.columnsMapper.getValueByIndex(physicalColumn);
        physicalColumn = columnInMapper === null ? physicalColumn : columnInMapper;
      }

      return physicalColumn;
    }
    /**
     * 'unmodifyCol' hook callback.
     *
     * @private
     * @param {Number} column Physical column index.
     * @returns {Number} Visual column index.
     */

  }, {
    key: "onUnmodifyCol",
    value: function onUnmodifyCol(column) {
      var indexInMapper = this.columnsMapper.getIndexByValue(column);
      return indexInMapper === null ? column : indexInMapper;
    }
    /**
     * `afterPluginsInitialized` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterPluginsInitialized",
    value: function onAfterPluginsInitialized() {
      this.updateColumnsMapper();
      this.initialSettings();
      this.backlight.build();
      this.guideline.build();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.backlight.destroy();
      this.guideline.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "destroy", this).call(this);
    }
  }]);
  return ManualColumnMove;
}(_base.default);

(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove);
var _default = ManualColumnMove;
exports.default = _default;

/***/ }),
/* 657 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

/**
 * @class ColumnsMapper
 * @plugin ManualColumnMove
 */
var ColumnsMapper =
/*#__PURE__*/
function () {
  function ColumnsMapper(manualColumnMove) {
    (0, _classCallCheck2.default)(this, ColumnsMapper);

    /**
     * Instance of ManualColumnMove plugin.
     *
     * @type {ManualColumnMove}
     */
    this.manualColumnMove = manualColumnMove;
  }
  /**
   * Reset current map array and create new one.
   *
   * @param {Number} [length] Custom generated map length.
   */


  (0, _createClass2.default)(ColumnsMapper, [{
    key: "createMap",
    value: function createMap(length) {
      var _this = this;

      var originLength = length === void 0 ? this._arrayMap.length : length;
      this._arrayMap.length = 0;
      (0, _number.rangeEach)(originLength - 1, function (itemIndex) {
        _this._arrayMap[itemIndex] = itemIndex;
      });
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
    /**
     * Moving elements in columnsMapper.
     *
     * @param {Number} from Column index to move.
     * @param {Number} to Target index.
     */

  }, {
    key: "moveColumn",
    value: function moveColumn(from, to) {
      var indexToMove = this._arrayMap[from];
      this._arrayMap[from] = null;

      this._arrayMap.splice(to, 0, indexToMove);
    }
    /**
     * Clearing arrayMap from `null` entries.
     */

  }, {
    key: "clearNull",
    value: function clearNull() {
      this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) {
        return i !== null;
      });
    }
  }]);
  return ColumnsMapper;
}();

(0, _object.mixin)(ColumnsMapper, _arrayMapper.default);
var _default = ColumnsMapper;
exports.default = _default;

/***/ }),
/* 658 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(490));

var _element = __webpack_require__(5);

var CSS_CLASSNAME = 'ht__manualColumnMove--backlight';
/**
 * @class BacklightUI
 * @util
 */

var BacklightUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(BacklightUI, _BaseUI);

  function BacklightUI() {
    (0, _classCallCheck2.default)(this, BacklightUI);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BacklightUI).apply(this, arguments));
  }

  (0, _createClass2.default)(BacklightUI, [{
    key: "build",

    /**
     * Custom className on build process.
     */
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(BacklightUI.prototype), "build", this).call(this);
      (0, _element.addClass)(this._element, CSS_CLASSNAME);
    }
  }]);
  return BacklightUI;
}(_base.default);

var _default = BacklightUI;
exports.default = _default;

/***/ }),
/* 659 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(490));

var _element = __webpack_require__(5);

var CSS_CLASSNAME = 'ht__manualColumnMove--guideline';
/**
 * @class GuidelineUI
 * @util
 */

var GuidelineUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(GuidelineUI, _BaseUI);

  function GuidelineUI() {
    (0, _classCallCheck2.default)(this, GuidelineUI);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GuidelineUI).apply(this, arguments));
  }

  (0, _createClass2.default)(GuidelineUI, [{
    key: "build",

    /**
     * Custom className on build process.
     */
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(GuidelineUI.prototype), "build", this).call(this);
      (0, _element.addClass)(this._element, CSS_CLASSNAME);
    }
  }]);
  return GuidelineUI;
}(_base.default);

var _default = GuidelineUI;
exports.default = _default;

/***/ }),
/* 660 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 661 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _event = __webpack_require__(31);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js

/**
 * @description
 * This plugin allows to change columns width. To make columns width persistent the {@link Options#persistentState}
 * plugin should be enabled.
 *
 * The plugin creates additional components to make resizing possibly using user interface:
 * - handle - the draggable element that sets the desired width of the column.
 * - guide - the helper guide that shows the desired width as a vertical guide.
 *
 * @plugin ManualColumnResize
 */
var ManualColumnResize =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ManualColumnResize, _BasePlugin);

  function ManualColumnResize(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ManualColumnResize);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnResize).call(this, hotInstance));
    var rootDocument = _this.hot.rootDocument;
    _this.currentTH = null;
    _this.currentCol = null;
    _this.selectedCols = [];
    _this.currentWidth = null;
    _this.newSize = null;
    _this.startY = null;
    _this.startWidth = null;
    _this.startOffset = null;
    _this.handle = rootDocument.createElement('DIV');
    _this.guide = rootDocument.createElement('DIV');
    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    _this.pressed = null;
    _this.dblclick = 0;
    _this.autoresizeTimeout = null;
    _this.manualColumnWidths = [];
    (0, _element.addClass)(_this.handle, 'manualColumnResizer');
    (0, _element.addClass)(_this.guide, 'manualColumnResizerGuide');
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ManualColumnResize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ManualColumnResize, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().manualColumnResize;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.manualColumnWidths = [];
      var initialColumnWidth = this.hot.getSettings().manualColumnResize;
      var loadedManualColumnWidths = this.loadManualColumnWidths();
      this.addHook('modifyColWidth', function (width, col) {
        return _this2.onModifyColWidth(width, col);
      });
      this.addHook('beforeStretchingColumnWidth', function (stretchedWidth, column) {
        return _this2.onBeforeStretchingColumnWidth(stretchedWidth, column);
      });
      this.addHook('beforeColumnResize', function (currentColumn, newSize, isDoubleClick) {
        return _this2.onBeforeColumnResize(currentColumn, newSize, isDoubleClick);
      });

      if (typeof loadedManualColumnWidths !== 'undefined') {
        this.manualColumnWidths = loadedManualColumnWidths;
      } else if (Array.isArray(initialColumnWidth)) {
        this.manualColumnWidths = initialColumnWidth;
      } else {
        this.manualColumnWidths = [];
      } // Handsontable.hooks.register('beforeColumnResize');
      // Handsontable.hooks.register('afterColumnResize');


      this.bindEvents();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnResize.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      var initialColumnWidth = this.hot.getSettings().manualColumnResize;

      if (Array.isArray(initialColumnWidth)) {
        this.manualColumnWidths = initialColumnWidth;
      } else if (!initialColumnWidth) {
        this.manualColumnWidths = [];
      }
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnResize.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Saves the current sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
     */

  }, {
    key: "saveManualColumnWidths",
    value: function saveManualColumnWidths() {
      this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths);
    }
    /**
     * Loads the previously saved sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
     *
     * @returns {Array}
     *
     * @fires Hooks#persistentStateLoad
     * @fires Hooks#manualColumnWidths
     */

  }, {
    key: "loadManualColumnWidths",
    value: function loadManualColumnWidths() {
      var storedState = {};
      this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState);
      return storedState.value;
    }
    /**
     * Set the resize handle position.
     *
     * @private
     * @param {HTMLCellElement} TH TH HTML element.
     */

  }, {
    key: "setupHandlePosition",
    value: function setupHandlePosition(TH) {

      var _this3 = this;

      if (!TH.parentNode) {
        return false;
      }

      this.currentTH = TH;
      var cellCoords = this.hot.view.wt.wtTable.getCoords(this.currentTH);
      var col = cellCoords.col;
      var headerHeight = (0, _element.outerHeight)(this.currentTH);

      if (col >= 0) {
        // if col header
        var box = this.currentTH.getBoundingClientRect();
        var fixedColumn = col < this.hot.getSettings().fixedColumnsLeft;
        var parentOverlay = fixedColumn ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay : this.hot.view.wt.wtOverlays.topOverlay;
        var relativeHeaderPosition = parentOverlay.getRelativeCellPosition(this.currentTH, cellCoords.row, cellCoords.col); // If the TH is not a child of the top/top-left overlay, recalculate using the top-most header

        if (!relativeHeaderPosition) {
          var topMostHeader = parentOverlay.clone.wtTable.THEAD.lastChild.children[+!!this.hot.getSettings().rowHeaders + col];
          relativeHeaderPosition = parentOverlay.getRelativeCellPosition(topMostHeader, cellCoords.row, cellCoords.col);
        }

        this.currentCol = col;
        this.selectedCols = [];

        if (this.hot.selection.isSelected() && this.hot.selection.isSelectedByColumnHeader()) {
          var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
              from = _this$hot$getSelected.from,
              to = _this$hot$getSelected.to;

          var start = from.col;
          var end = to.col;

          if (start >= end) {
            start = to.col;
            end = from.col;
          }

          if (this.currentCol >= start && this.currentCol <= end) {
            (0, _number.rangeEach)(start, end, function (i) {
              return _this3.selectedCols.push(i);
            });
          } else {
            this.selectedCols.push(this.currentCol);
          }
        } else {
          this.selectedCols.push(this.currentCol);
        }

        this.startOffset = relativeHeaderPosition.left - 6;
        this.startWidth = parseInt(box.width, 10);
				/* OMNIDB */
				/*this.handle.style.top = "".concat(relativeHeaderPosition.top, "px");*/
				this.handle.style.top = "".concat(0, "px");
        this.handle.style.left = "".concat(this.startOffset + this.startWidth, "px");
        this.handle.style.height = "".concat(headerHeight, "px");
        this.hot.rootElement.appendChild(this.handle);
      }
    }
    /**
     * Refresh the resize handle position.
     *
     * @private
     */

  }, {
    key: "refreshHandlePosition",
    value: function refreshHandlePosition() {
      this.handle.style.left = "".concat(this.startOffset + this.currentWidth, "px");
    }
    /**
     * Sets the resize guide position.
     *
     * @private
     */

  }, {
    key: "setupGuidePosition",
    value: function setupGuidePosition() {
      var handleHeight = parseInt((0, _element.outerHeight)(this.handle), 10);
      var handleBottomPosition = parseInt(this.handle.style.top, 10) + handleHeight;
      var maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10);
      (0, _element.addClass)(this.handle, 'active');
      (0, _element.addClass)(this.guide, 'active');
      this.guide.style.top = "".concat(handleBottomPosition, "px");
      this.guide.style.left = this.handle.style.left;
      this.guide.style.height = "".concat(maximumVisibleElementHeight - handleHeight, "px");
      this.hot.rootElement.appendChild(this.guide);
    }
    /**
     * Refresh the resize guide position.
     *
     * @private
     */

  }, {
    key: "refreshGuidePosition",
    value: function refreshGuidePosition() {
      this.guide.style.left = this.handle.style.left;
    }
    /**
     * Hides both the resize handle and resize guide.
     *
     * @private
     */

  }, {
    key: "hideHandleAndGuide",
    value: function hideHandleAndGuide() {
      (0, _element.removeClass)(this.handle, 'active');
      (0, _element.removeClass)(this.guide, 'active');
    }
    /**
     * Checks if provided element is considered a column header.
     *
     * @private
     * @param {HTMLElement} element HTML element.
     * @returns {Boolean}
     */

  }, {
    key: "checkIfColumnHeader",
    value: function checkIfColumnHeader(element) {
      if (element !== this.hot.rootElement) {
        var parent = element.parentNode;

        if (parent.tagName === 'THEAD') {
          return true;
        }

        return this.checkIfColumnHeader(parent);
      }

      return false;
    }
    /**
     * Gets the TH element from the provided element.
     *
     * @private
     * @param {HTMLElement} element HTML element.
     * @returns {HTMLElement}
     */

  }, {
    key: "getTHFromTargetElement",
    value: function getTHFromTargetElement(element) {
      if (element.tagName !== 'TABLE') {
        if (element.tagName === 'TH') {
          return element;
        }

        return this.getTHFromTargetElement(element.parentNode);
      }

      return null;
    }
    /**
     * 'mouseover' event callback - set the handle position.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseOver",
    value: function onMouseOver(event) {

      if (this.checkIfColumnHeader(event.target)) {
        var th = this.getTHFromTargetElement(event.target);

        if (!th) {
          return;
        }

        var colspan = th.getAttribute('colspan');

        if (th && (colspan === null || colspan === 1)) {
          if (!this.pressed) {
            this.setupHandlePosition(th);
          }
        }
      }
    }
    /**
     * Auto-size row after doubleclick - callback.
     *
     * @private
     *
     * @fires Hooks#beforeColumnResize
     * @fires Hooks#afterColumnResize
     */

  }, {
    key: "afterMouseDownTimeout",
    value: function afterMouseDownTimeout() {
      var _this4 = this;

      var render = function render() {
        _this4.hot.forceFullRender = true;

        _this4.hot.view.render(); // updates all


        _this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
      };

      var resize = function resize(selectedCol, forceRender) {
        var hookNewSize = _this4.hot.runHooks('beforeColumnResize', selectedCol, _this4.newSize, true);

        if (hookNewSize !== void 0) {
          _this4.newSize = hookNewSize;
        }

        if (_this4.hot.getSettings().stretchH === 'all') {
          _this4.clearManualSize(selectedCol);
        } else {
          _this4.setManualSize(selectedCol, _this4.newSize); // double click sets by auto row size plugin

        }

        if (forceRender) {
          render();
        }

        _this4.saveManualColumnWidths();

        _this4.hot.runHooks('afterColumnResize', selectedCol, _this4.newSize, true);
      };

      if (this.dblclick >= 2) {
        var selectedColsLength = this.selectedCols.length;

        if (selectedColsLength > 1) {
          (0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
            resize(selectedCol);
          });
          render();
        } else {
          (0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
            resize(selectedCol, true);
          });
        }
      }

      this.dblclick = 0;
      this.autoresizeTimeout = null;
    }
    /**
     * 'mousedown' event callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseDown",
    value: function onMouseDown(event) {
      var _this5 = this;

      if ((0, _element.hasClass)(event.target, 'manualColumnResizer')) {
        this.setupGuidePosition();
        this.pressed = this.hot;

        if (this.autoresizeTimeout === null) {
          this.autoresizeTimeout = setTimeout(function () {
            return _this5.afterMouseDownTimeout();
          }, 500);

          this.hot._registerTimeout(this.autoresizeTimeout);
        }

        this.dblclick += 1;
        this.startX = (0, _event.pageX)(event);
        this.newSize = this.startWidth;
      }
    }
    /**
     * 'mousemove' event callback - refresh the handle and guide positions, cache the new column width.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var _this6 = this;

      if (this.pressed) {
        this.currentWidth = this.startWidth + ((0, _event.pageX)(event) - this.startX);
        (0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
          _this6.newSize = _this6.setManualSize(selectedCol, _this6.currentWidth);
        });
        this.refreshHandlePosition();
        this.refreshGuidePosition();
      }
    }
    /**
     * 'mouseup' event callback - apply the column resizing.
     *
     * @private
     *
     * @fires Hooks#beforeColumnResize
     * @fires Hooks#afterColumnResize
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      var _this7 = this;

      var render = function render() {
        _this7.hot.forceFullRender = true;

        _this7.hot.view.render(); // updates all


        _this7.hot.view.wt.wtOverlays.adjustElementsSize(true);
      };

      var resize = function resize(selectedCol, forceRender) {
        _this7.hot.runHooks('beforeColumnResize', selectedCol, _this7.newSize, false);

        if (forceRender) {
          render();
        }

        _this7.saveManualColumnWidths();

        _this7.hot.runHooks('afterColumnResize', selectedCol, _this7.newSize);
      };

      if (this.pressed) {
        this.hideHandleAndGuide();
        this.pressed = false;

        if (this.newSize !== this.startWidth) {
          var selectedColsLength = this.selectedCols.length;

          if (selectedColsLength > 1) {
            (0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
              resize(selectedCol);
            });
            render();
          } else {
            (0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
              resize(selectedCol, true);
            });
          }
        }

        this.setupHandlePosition(this.currentTH);
      }
    }
    /**
     * Binds the mouse events.
     *
     * @private
     */

  }, {
    key: "bindEvents",
    value: function bindEvents() {
      var _this8 = this;

      var _this$hot = this.hot,
          rootWindow = _this$hot.rootWindow,
          rootElement = _this$hot.rootElement;
      this.eventManager.addEventListener(rootElement, 'mouseover', function (e) {
        return _this8.onMouseOver(e);
      });
      this.eventManager.addEventListener(rootElement, 'mousedown', function (e) {
        return _this8.onMouseDown(e);
      });
      this.eventManager.addEventListener(rootWindow, 'mousemove', function (e) {
        return _this8.onMouseMove(e);
      });
      this.eventManager.addEventListener(rootWindow, 'mouseup', function () {
        return _this8.onMouseUp();
      });
    }
    /**
     * Sets the new width for specified column index.
     *
     * @param {Number} column Visual column index.
     * @param {Number} width Column width (no less than 20px).
     * @returns {Number} Returns new width.
     */

  }, {
    key: "setManualSize",
    value: function setManualSize(column, width) {
      var newWidth = Math.max(width, 20);
      /**
       *  We need to run col through modifyCol hook, in case the order of displayed columns is different than the order
       *  in data source. For instance, this order can be modified by manualColumnMove plugin.
       */

      var physicalColumn = this.hot.runHooks('modifyCol', column);
      this.manualColumnWidths[physicalColumn] = newWidth;
      return newWidth;
    }
    /**
     * Clears the cache for the specified column index.
     *
     * @param {Number} column Visual column index.
     */

  }, {
    key: "clearManualSize",
    value: function clearManualSize(column) {
      var physicalColumn = this.hot.runHooks('modifyCol', column);
      this.manualColumnWidths[physicalColumn] = void 0;
    }
    /**
     * Modifies the provided column width, based on the plugin settings
     *
     * @private
     * @param {Number} width Column width.
     * @param {Number} column Visual column index.
     * @returns {Number}
     */

  }, {
    key: "onModifyColWidth",
    value: function onModifyColWidth(width, column) {
      var newWidth = width;

      if (this.enabled) {
        var physicalColumn = this.hot.runHooks('modifyCol', column);
        var columnWidth = this.manualColumnWidths[physicalColumn];

        if (this.hot.getSettings().manualColumnResize && columnWidth) {
          newWidth = columnWidth;
        }
      }

      return newWidth;
    }
    /**
     * Modifies the provided column stretched width. This hook decides if specified column should be stretched or not.
     *
     * @private
     * @param {Number} stretchedWidth Stretched width.
     * @param {Number} column Physical column index.
     * @returns {Number}
     */

  }, {
    key: "onBeforeStretchingColumnWidth",
    value: function onBeforeStretchingColumnWidth(stretchedWidth, column) {
      var width = this.manualColumnWidths[column];

      if (width === void 0) {
        width = stretchedWidth;
      }

      return width;
    }
    /**
     * `beforeColumnResize` hook callback.
     *
     * @private
     */

  }, {
    key: "onBeforeColumnResize",
    value: function onBeforeColumnResize() {
      // clear the header height cache information
      this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {};
    }
  }]);
  return ManualColumnResize;
}(_base.default);

(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize);
var _default = ManualColumnResize;
exports.default = _default;

/***/ }),
/* 662 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _array = __webpack_require__(3);

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _rowsMapper = _interopRequireDefault(__webpack_require__(663));

var _backlight = _interopRequireDefault(__webpack_require__(664));

var _guideline = _interopRequireDefault(__webpack_require__(665));

__webpack_require__(666);

_pluginHooks.default.getSingleton().register('beforeRowMove');

_pluginHooks.default.getSingleton().register('afterRowMove');

_pluginHooks.default.getSingleton().register('unmodifyRow');

var privatePool = new WeakMap();
var CSS_PLUGIN = 'ht__manualRowMove';
var CSS_SHOW_UI = 'show-ui';
var CSS_ON_MOVING = 'on-moving--rows';
var CSS_AFTER_SELECTION = 'after-selection--rows';
/**
 * @plugin ManualRowMove
 *
 * @description
 * This plugin allows to change rows order. To make rows order persistent the {@link Options#persistentState}
 * plugin should be enabled.
 *
 * API:
 * - moveRow - move single row to the new position.
 * - moveRows - move many rows (as an array of indexes) to the new position.
 *
 * If you want apply visual changes, you have to call manually the render() method on the instance of handsontable.
 *
 * The plugin creates additional components to make moving possibly using user interface:
 * - backlight - highlight of selected rows.
 * - guideline - line which shows where rows has been moved.
 *
 * @class ManualRowMove
 * @plugin ManualRowMove
 */

var ManualRowMove =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ManualRowMove, _BasePlugin);

  function ManualRowMove(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ManualRowMove);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualRowMove).call(this, hotInstance));
    /**
     * Set up WeakMap of plugin to sharing private parameters;
     */

    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      rowsToMove: [],
      pressed: void 0,
      disallowMoving: void 0,
      target: {
        eventPageY: void 0,
        coords: void 0,
        TD: void 0,
        row: void 0
      }
    });
    /**
     * List of last removed row indexes.
     *
     * @private
     * @type {Array}
     */

    _this.removedRows = [];
    /**
     * Object containing visual row indexes mapped to data source indexes.
     *
     * @private
     * @type {RowsMapper}
     */

    _this.rowsMapper = new _rowsMapper.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Event Manager object.
     *
     * @private
     * @type {Object}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Backlight UI object.
     *
     * @private
     * @type {Object}
     */

    _this.backlight = new _backlight.default(hotInstance);
    /**
     * Guideline UI object.
     *
     * @private
     * @type {Object}
     */

    _this.guideline = new _guideline.default(hotInstance);
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ManualRowMove#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ManualRowMove, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().manualRowMove;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) {
        return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations);
      });
      this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
        return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
      });
      this.addHook('afterScrollHorizontally', function () {
        return _this2.onAfterScrollHorizontally();
      });
      this.addHook('modifyRow', function (row, source) {
        return _this2.onModifyRow(row, source);
      });
      this.addHook('beforeRemoveRow', function (index, amount) {
        return _this2.onBeforeRemoveRow(index, amount);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow();
      });
      this.addHook('afterCreateRow', function (index, amount) {
        return _this2.onAfterCreateRow(index, amount);
      });
      this.addHook('afterLoadData', function () {
        return _this2.onAfterLoadData();
      });
      this.addHook('beforeColumnSort', function (column, order) {
        return _this2.onBeforeColumnSort(column, order);
      });
      this.addHook('unmodifyRow', function (row) {
        return _this2.onUnmodifyRow(row);
      });
      this.registerEvents(); // TODO: move adding plugin classname to BasePlugin.

      (0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN);
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      this.onAfterPluginsInitialized();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      var pluginSettings = this.hot.getSettings().manualRowMove;

      if (Array.isArray(pluginSettings)) {
        this.rowsMapper.clearMap();
      }

      (0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN);
      this.unregisterEvents();
      this.backlight.destroy();
      this.guideline.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Moves a single row.
     *
     * @param {Number} row Visual row index to be moved.
     * @param {Number} target Visual row index being a target for the moved row.
     * @fires Hooks#beforeRowMove
     * @fires Hooks#afterRowMove
     */

  }, {
    key: "moveRow",
    value: function moveRow(row, target) {
      this.moveRows([row], target);
    }
    /**
     * Moves a multiple rows.
     *
     * @param {Array} rows Array of visual row indexes to be moved.
     * @param {Number} target Visual row index being a target for the moved rows.
     * @fires Hooks#beforeRowMove
     * @fires Hooks#afterRowMove
     */

  }, {
    key: "moveRows",
    value: function moveRows(rows, target) {
      var _this3 = this;

      var visualRows = (0, _toConsumableArray2.default)(rows);
      var priv = privatePool.get(this);
      var beforeMoveHook = this.hot.runHooks('beforeRowMove', visualRows, target);
      priv.disallowMoving = beforeMoveHook === false;

      if (!priv.disallowMoving) {
        // first we need to rewrite an visual indexes to physical for save reference after move
        (0, _array.arrayEach)(rows, function (row, index, array) {
          array[index] = _this3.rowsMapper.getValueByIndex(row);
        }); // next, when we have got an physical indexes, we can move rows

        (0, _array.arrayEach)(rows, function (row, index) {
          var actualPosition = _this3.rowsMapper.getIndexByValue(row);

          if (actualPosition !== target) {
            _this3.rowsMapper.moveRow(actualPosition, target + index);
          }
        }); // after moving we have to clear rowsMapper from null entries

        this.rowsMapper.clearNull();
      }

      this.hot.runHooks('afterRowMove', visualRows, target);
    }
    /**
     * Correct the cell selection after the move action. Fired only when action was made with a mouse.
     * That means that changing the row order using the API won't correct the selection.
     *
     * @private
     * @param {Number} startRow Visual row index for the start of the selection.
     * @param {Number} endRow Visual row index for the end of the selection.
     */

  }, {
    key: "changeSelection",
    value: function changeSelection(startRow, endRow) {
      this.hot.selectRows(startRow, endRow);
    }
    /**
     * Gets the sum of the heights of rows in the provided range.
     *
     * @private
     * @param {Number} from Visual row index.
     * @param {Number} to Visual row index.
     * @returns {Number}
     */

  }, {
    key: "getRowsHeight",
    value: function getRowsHeight(from, to) {
      var height = 0;

      for (var i = from; i < to; i++) {
        var rowHeight = this.hot.view.wt.wtTable.getRowHeight(i) || 23;
        height += rowHeight;
      }

      return height;
    }
    /**
     * Loads initial settings when persistent state is saved or when plugin was initialized as an array.
     *
     * @private
     */

  }, {
    key: "initialSettings",
    value: function initialSettings() {
      var pluginSettings = this.hot.getSettings().manualRowMove;

      if (Array.isArray(pluginSettings)) {
        this.moveRows(pluginSettings, 0);
      } else if (pluginSettings !== void 0) {
        var persistentState = this.persistentStateLoad();

        if (persistentState.length) {
          this.moveRows(persistentState, 0);
        }
      }
    }
    /**
     * Checks if the provided row is in the fixedRowsTop section.
     *
     * @private
     * @param {Number} row Visual row index to check.
     * @returns {Boolean}
     */

  }, {
    key: "isFixedRowTop",
    value: function isFixedRowTop(row) {
      return row < this.hot.getSettings().fixedRowsTop;
    }
    /**
     * Checks if the provided row is in the fixedRowsBottom section.
     *
     * @private
     * @param {Number} row Visual row index to check.
     * @returns {Boolean}
     */

  }, {
    key: "isFixedRowBottom",
    value: function isFixedRowBottom(row) {
      return row > this.hot.getSettings().fixedRowsBottom;
    }
    /**
     * Saves the manual row positions to the persistent state (the {@link Options#persistentState} option has to be enabled).
     *
     * @fires Hooks#persistentStateSave
     * @fires Hooks#manualRowMove
     */

  }, {
    key: "persistentStateSave",
    value: function persistentStateSave() {
      this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap);
    }
    /**
     * Loads the manual row positions from the persistent state (the {@link Options#persistentState} option has to be enabled).
     *
     * @returns {Array} Stored state.
     *
     * @fires Hooks#persistentStateLoad
     * @fires Hooks#manualRowMove
     */

  }, {
    key: "persistentStateLoad",
    value: function persistentStateLoad() {
      var storedState = {};
      this.hot.runHooks('persistentStateLoad', 'manualRowMove', storedState);
      return storedState.value ? storedState.value : [];
    }
    /**
     * Prepare array of indexes based on actual selection.
     *
     * @private
     * @returns {Array}
     */

  }, {
    key: "prepareRowsToMoving",
    value: function prepareRowsToMoving() {
      var selection = this.hot.getSelectedRangeLast();
      var selectedRows = [];

      if (!selection) {
        return selectedRows;
      }

      var from = selection.from,
          to = selection.to;
      var start = Math.min(from.row, to.row);
      var end = Math.max(from.row, to.row);
      (0, _number.rangeEach)(start, end, function (i) {
        selectedRows.push(i);
      });
      return selectedRows;
    }
    /**
     * Update the UI visual position.
     *
     * @private
     */

  }, {
    key: "refreshPositions",
    value: function refreshPositions() {
      var priv = privatePool.get(this);
      var coords = priv.target.coords;
      var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleRow();
      var lastVisible = this.hot.view.wt.wtTable.getLastVisibleRow();
      var fixedRows = this.hot.getSettings().fixedRowsTop;
      var countRows = this.hot.countRows();

      if (coords.row < fixedRows && firstVisible > 0) {
        this.hot.scrollViewportTo(firstVisible - 1);
      }

      if (coords.row >= lastVisible && lastVisible < countRows) {
        this.hot.scrollViewportTo(lastVisible + 1, undefined, true);
      }

      var wtTable = this.hot.view.wt.wtTable;
      var TD = priv.target.TD;
      var rootElementOffset = (0, _element.offset)(this.hot.rootElement);
      var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row);
      var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop;
      var hiderHeight = wtTable.hider.offsetHeight;
      var tbodyOffsetTop = wtTable.TBODY.offsetTop;
      var backlightElemMarginTop = this.backlight.getOffset().top;
      var backlightElemHeight = this.backlight.getSize().height;

      if (this.isFixedRowTop(coords.row)) {
        tdOffsetTop += wtTable.holder.scrollTop;
      } // todo: fixedRowsBottom
      // if (this.isFixedRowBottom(coords.row)) {
      //
      // }


      if (coords.row < 0) {
        // if hover on colHeader
        priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible;
      } else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) {
        // if hover on lower part of TD
        priv.target.row = coords.row + 1; // unfortunately first row is bigger than rest

        tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight;
      } else {
        // elsewhere on table
        priv.target.row = coords.row;
      }

      var backlightTop = mouseOffsetTop;
      var guidelineTop = tdOffsetTop;

      if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
        // prevent display backlight below table
        backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop;
      } else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) {
        // prevent display above below table
        backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop);
      }

      if (tdOffsetTop >= hiderHeight - 1) {
        // prevent display guideline below table
        guidelineTop = hiderHeight - 1;
      }

      var topOverlayHeight = 0;

      if (this.hot.view.wt.wtOverlays.topOverlay) {
        topOverlayHeight = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.TABLE.offsetHeight;
      }

      if (coords.row >= fixedRows && guidelineTop - wtTable.holder.scrollTop < topOverlayHeight) {
        this.hot.scrollViewportTo(coords.row);
      }

      this.backlight.setPosition(backlightTop);
      this.guideline.setPosition(guidelineTop);
    }
    /**
     * This method checks arrayMap from rowsMapper and updates the rowsMapper if it's necessary.
     *
     * @private
     */

  }, {
    key: "updateRowsMapper",
    value: function updateRowsMapper() {
      var countRows = this.hot.countSourceRows();
      var rowsMapperLen = this.rowsMapper._arrayMap.length;

      if (rowsMapperLen === 0) {
        this.rowsMapper.createMap(countRows || this.hot.getSettings().startRows);
      } else if (rowsMapperLen < countRows) {
        var diff = countRows - rowsMapperLen;
        this.rowsMapper.insertItems(rowsMapperLen, diff);
      } else if (rowsMapperLen > countRows) {
        var maxIndex = countRows - 1;
        var rowsToRemove = [];
        (0, _array.arrayEach)(this.rowsMapper._arrayMap, function (value, index) {
          if (value > maxIndex) {
            rowsToRemove.push(index);
          }
        });
        this.rowsMapper.removeItems(rowsToRemove);
      }
    }
    /**
     * Binds the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this4 = this;

      var documentElement = this.hot.rootDocument.documentElement;
      this.eventManager.addEventListener(documentElement, 'mousemove', function (event) {
        return _this4.onMouseMove(event);
      });
      this.eventManager.addEventListener(documentElement, 'mouseup', function () {
        return _this4.onMouseUp();
      });
    }
    /**
     * Unbinds the events used by the plugin.
     *
     * @private
     */

  }, {
    key: "unregisterEvents",
    value: function unregisterEvents() {
      this.eventManager.clear();
    }
    /**
     * `beforeColumnSort` hook callback. If user uses the sorting, manual row moving is disabled.
     *
     * @private
     * @param {Number} column Column index where soring is present
     * @param {*} order State of sorting. ASC/DESC/None
     */

  }, {
    key: "onBeforeColumnSort",
    value: function onBeforeColumnSort(column, order) {
      var priv = privatePool.get(this);
      priv.disallowMoving = order !== void 0;
    }
    /**
     * Changes the behavior of selection / dragging.
     *
     * @private
     * @param {MouseEvent} event
     * @param {CellCoords} coords Visual coordinates.
     * @param {HTMLElement} TD
     * @param {Object} blockCalculations
     */

  }, {
    key: "onBeforeOnCellMouseDown",
    value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) {
      var _this$hot$view$wt = this.hot.view.wt,
          wtTable = _this$hot$view$wt.wtTable,
          wtViewport = _this$hot$view$wt.wtViewport;
      var isHeaderSelection = this.hot.selection.isSelectedByRowHeader();
      var selection = this.hot.getSelectedRangeLast();
      var priv = privatePool.get(this);

      if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0) {
        priv.pressed = false;
        priv.rowsToMove.length = 0;
        (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]);
        return;
      }

      var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended();
      var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended();

      if (guidelineIsNotReady && backlightIsNotReady) {
        this.guideline.appendTo(wtTable.hider);
        this.backlight.appendTo(wtTable.hider);
      }

      var from = selection.from,
          to = selection.to;
      var start = Math.min(from.row, to.row);
      var end = Math.max(from.row, to.row);

      if (coords.col < 0 && coords.row >= start && coords.row <= end) {
        blockCalculations.row = true;
        priv.pressed = true;
        priv.target.eventPageY = event.pageY;
        priv.target.coords = coords;
        priv.target.TD = TD;
        priv.rowsToMove = this.prepareRowsToMoving();
        var leftPos = wtTable.holder.scrollLeft + wtViewport.getRowHeaderWidth();
        this.backlight.setPosition(null, leftPos);
        this.backlight.setSize(wtTable.hider.offsetWidth - leftPos, this.getRowsHeight(start, end + 1));
        this.backlight.setOffset((this.getRowsHeight(start, coords.row) + event.layerY) * -1, null);
        (0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING);
        this.refreshPositions();
      } else {
        (0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
        priv.pressed = false;
        priv.rowsToMove.length = 0;
      }
    }
    /**
     * 'mouseMove' event callback. Fired when pointer move on document.documentElement.
     *
     * @private
     * @param {MouseEvent} event `mousemove` event properties.
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var priv = privatePool.get(this);

      if (!priv.pressed) {
        return;
      } // callback for browser which doesn't supports CSS pointer-event: none


      if (event.realTarget === this.backlight.element) {
        var height = this.backlight.getSize().height;
        this.backlight.setSize(null, 0);
        setTimeout(function () {
          this.backlight.setPosition(null, height);
        });
      }

      priv.target.eventPageY = event.pageY;
      this.refreshPositions();
    }
    /**
     * 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell.
     *
     * @private
     * @param {MouseEvent} event `mouseover` event properties.
     * @param {CellCoords} coords Visual cell coordinates where was fired event.
     * @param {HTMLElement} TD Cell represented as HTMLElement.
     * @param {Object} blockCalculations Object which contains information about blockCalculation for row, column or cells.
     */

  }, {
    key: "onBeforeOnCellMouseOver",
    value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
      var selectedRange = this.hot.getSelectedRangeLast();
      var priv = privatePool.get(this);

      if (!selectedRange || !priv.pressed) {
        return;
      }

      if (priv.rowsToMove.indexOf(coords.row) > -1) {
        (0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI);
      } else {
        (0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI);
      }

      blockCalculations.row = true;
      blockCalculations.column = true;
      blockCalculations.cell = true;
      priv.target.coords = coords;
      priv.target.TD = TD;
    }
    /**
     * `onMouseUp` hook callback.
     *
     * @private
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      var priv = privatePool.get(this);
      var target = priv.target.row;
      var rowsLen = priv.rowsToMove.length;
      priv.pressed = false;
      priv.backlightHeight = 0;
      (0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]);

      if (this.hot.selection.isSelectedByRowHeader()) {
        (0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
      }

      if (rowsLen < 1 || target === void 0 || priv.rowsToMove.indexOf(target) > -1 || priv.rowsToMove[rowsLen - 1] === target - 1) {
        return;
      }

      this.moveRows(priv.rowsToMove, target);
      this.persistentStateSave();
      this.hot.render();

      if (!priv.disallowMoving) {
        var selectionStart = this.rowsMapper.getIndexByValue(priv.rowsToMove[0]);
        var selectionEnd = this.rowsMapper.getIndexByValue(priv.rowsToMove[rowsLen - 1]);
        this.changeSelection(selectionStart, selectionEnd);
      }

      priv.rowsToMove.length = 0;
    }
    /**
     * `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally.
     *
     * @private
     */

  }, {
    key: "onAfterScrollHorizontally",
    value: function onAfterScrollHorizontally() {
      var wtTable = this.hot.view.wt.wtTable;
      var headerWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth();
      var scrollLeft = wtTable.holder.scrollLeft;
      var posLeft = headerWidth + scrollLeft;
      this.backlight.setPosition(null, posLeft);
      this.backlight.setSize(wtTable.hider.offsetWidth - posLeft);
    }
    /**
     * `afterCreateRow` hook callback.
     *
     * @private
     * @param {Number} index Visual index of the created row.
     * @param {Number} amount Amount of created rows.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount) {
      this.rowsMapper.shiftItems(index, amount);
    }
    /**
     * On before remove row listener.
     *
     * @private
     * @param {Number} index Visual row index.
     * @param {Number} amount Defines how many rows removed.
     */

  }, {
    key: "onBeforeRemoveRow",
    value: function onBeforeRemoveRow(index, amount) {
      var _this5 = this;

      this.removedRows.length = 0;

      if (index !== false) {
        // Collect physical row index.
        (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
          _this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName));
        });
      }
    }
    /**
     * `afterRemoveRow` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow() {
      this.rowsMapper.unshiftItems(this.removedRows);
    }
    /**
     * `afterLoadData` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData() {
      this.updateRowsMapper();
    }
    /**
     * 'modifyRow' hook callback.
     *
     * @private
     * @param {Number} row Visual Row index.
     * @returns {Number} Physical row index.
     */

  }, {
    key: "onModifyRow",
    value: function onModifyRow(row, source) {
      var physicalRow = row;

      if (source !== this.pluginName) {
        var rowInMapper = this.rowsMapper.getValueByIndex(physicalRow);
        physicalRow = rowInMapper === null ? physicalRow : rowInMapper;
      }

      return physicalRow;
    }
    /**
     * 'unmodifyRow' hook callback.
     *
     * @private
     * @param {Number} row Physical row index.
     * @returns {Number} Visual row index.
     */

  }, {
    key: "onUnmodifyRow",
    value: function onUnmodifyRow(row) {
      var indexInMapper = this.rowsMapper.getIndexByValue(row);
      return indexInMapper === null ? row : indexInMapper;
    }
    /**
     * `afterPluginsInitialized` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterPluginsInitialized",
    value: function onAfterPluginsInitialized() {
      this.updateRowsMapper();
      this.initialSettings();
      this.backlight.build();
      this.guideline.build();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.backlight.destroy();
      this.guideline.destroy();
      this.rowsMapper.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "destroy", this).call(this);
    }
  }]);
  return ManualRowMove;
}(_base.default);

(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove);
var _default = ManualRowMove;
exports.default = _default;

/***/ }),
/* 663 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

/**
 * @class RowsMapper
 * @plugin ManualRowMove
 */
var RowsMapper =
/*#__PURE__*/
function () {
  function RowsMapper(manualRowMove) {
    (0, _classCallCheck2.default)(this, RowsMapper);

    /**
     * Instance of ManualRowMove plugin.
     *
     * @type {ManualRowMove}
     */
    this.manualRowMove = manualRowMove;
  }
  /**
   * Reset current map array and create new one.
   *
   * @param {Number} [length] Custom generated map length.
   */


  (0, _createClass2.default)(RowsMapper, [{
    key: "createMap",
    value: function createMap(length) {
      var _this = this;

      var originLength = length === void 0 ? this._arrayMap.length : length;
      this._arrayMap.length = 0;
      (0, _number.rangeEach)(originLength - 1, function (itemIndex) {
        _this._arrayMap[itemIndex] = itemIndex;
      });
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
    /**
     *
     * Moving elements in rowsMapper.
     * @param {Number} from Row index to move.
     * @param {Number} to Target index.
     */

  }, {
    key: "moveRow",
    value: function moveRow(from, to) {
      var indexToMove = this._arrayMap[from];
      this._arrayMap[from] = null;

      this._arrayMap.splice(to, 0, indexToMove);
    }
    /**
     * Clearing arrayMap from `null` entries.
     */

  }, {
    key: "clearNull",
    value: function clearNull() {
      this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) {
        return i !== null;
      });
    }
  }]);
  return RowsMapper;
}();

(0, _object.mixin)(RowsMapper, _arrayMapper.default);
var _default = RowsMapper;
exports.default = _default;

/***/ }),
/* 664 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(491));

var _element = __webpack_require__(5);

var CSS_CLASSNAME = 'ht__manualRowMove--backlight';
/**
 * @class BacklightUI
 * @util
 */

var BacklightUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(BacklightUI, _BaseUI);

  function BacklightUI() {
    (0, _classCallCheck2.default)(this, BacklightUI);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BacklightUI).apply(this, arguments));
  }

  (0, _createClass2.default)(BacklightUI, [{
    key: "build",

    /**
     * Custom className on build process.
     */
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(BacklightUI.prototype), "build", this).call(this);
      (0, _element.addClass)(this._element, CSS_CLASSNAME);
    }
  }]);
  return BacklightUI;
}(_base.default);

var _default = BacklightUI;
exports.default = _default;

/***/ }),
/* 665 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(491));

var _element = __webpack_require__(5);

var CSS_CLASSNAME = 'ht__manualRowMove--guideline';
/**
 * @class GuidelineUI
 * @util
 */

var GuidelineUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(GuidelineUI, _BaseUI);

  function GuidelineUI() {
    (0, _classCallCheck2.default)(this, GuidelineUI);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GuidelineUI).apply(this, arguments));
  }

  (0, _createClass2.default)(GuidelineUI, [{
    key: "build",

    /**
     * Custom className on build process.
     */
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(GuidelineUI.prototype), "build", this).call(this);
      (0, _element.addClass)(this._element, CSS_CLASSNAME);
    }
  }]);
  return GuidelineUI;
}(_base.default);

var _default = GuidelineUI;
exports.default = _default;

/***/ }),
/* 666 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 667 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _event = __webpack_require__(31);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js

/**
 * @description
 * This plugin allows to change rows height. To make rows height persistent the {@link Options#persistentState}
 * plugin should be enabled.
 *
 * The plugin creates additional components to make resizing possibly using user interface:
 * - handle - the draggable element that sets the desired height of the row.
 * - guide - the helper guide that shows the desired height as a horizontal guide.
 *
 * @plugin ManualRowResize
 */
var ManualRowResize =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ManualRowResize, _BasePlugin);

  function ManualRowResize(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ManualRowResize);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualRowResize).call(this, hotInstance));
    var rootDocument = _this.hot.rootDocument;
    _this.currentTH = null;
    _this.currentRow = null;
    _this.selectedRows = [];
    _this.currentHeight = null;
    _this.newSize = null;
    _this.startY = null;
    _this.startHeight = null;
    _this.startOffset = null;
    _this.handle = rootDocument.createElement('DIV');
    _this.guide = rootDocument.createElement('DIV');
    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    _this.pressed = null;
    _this.dblclick = 0;
    _this.autoresizeTimeout = null;
    _this.manualRowHeights = [];
    (0, _element.addClass)(_this.handle, 'manualRowResizer');
    (0, _element.addClass)(_this.guide, 'manualRowResizerGuide');
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ManualRowResize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ManualRowResize, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().manualRowResize;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.manualRowHeights = [];
      var initialRowHeights = this.hot.getSettings().manualRowResize;
      var loadedManualRowHeights = this.loadManualRowHeights();

      if (typeof loadedManualRowHeights !== 'undefined') {
        this.manualRowHeights = loadedManualRowHeights;
      } else if (Array.isArray(initialRowHeights)) {
        this.manualRowHeights = initialRowHeights;
      } else {
        this.manualRowHeights = [];
      }

      this.addHook('modifyRowHeight', function (height, row) {
        return _this2.onModifyRowHeight(height, row);
      }); // Handsontable.hooks.register('beforeRowResize');
      // Handsontable.hooks.register('afterRowResize');

      this.bindEvents();
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowResize.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      var initialRowHeights = this.hot.getSettings().manualRowResize;

      if (Array.isArray(initialRowHeights)) {
        this.manualRowHeights = initialRowHeights;
      } else if (!initialRowHeights) {
        this.manualRowHeights = [];
      }
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowResize.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Saves the current sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
     * @fires Hooks#persistentStateSave
     * @fires Hooks#manualRowHeights
     */

  }, {
    key: "saveManualRowHeights",
    value: function saveManualRowHeights() {
      this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights);
    }
    /**
     * Loads the previously saved sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
     *
     * @returns {Array}
     * @fires Hooks#persistentStateLoad
     * @fires Hooks#manualRowHeights
     */

  }, {
    key: "loadManualRowHeights",
    value: function loadManualRowHeights() {
      var storedState = {};
      this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState);
      return storedState.value;
    }
    /**
     * Sets the resize handle position.
     *
     * @private
     * @param {HTMLCellElement} TH TH HTML element.
     */

  }, {
    key: "setupHandlePosition",
    value: function setupHandlePosition(TH) {
      var _this3 = this;

      this.currentTH = TH;
      var cellCoords = this.hot.getCoords(this.currentTH);
      var row = cellCoords.row;
      var headerWidth = (0, _element.outerWidth)(this.currentTH);

      if (row >= 0) {
        // if not col header
        var box = this.currentTH.getBoundingClientRect();
        var fixedRowTop = row < this.hot.getSettings().fixedRowsTop;
        var fixedRowBottom = row >= this.hot.countRows() - this.hot.getSettings().fixedRowsBottom;
        var parentOverlay = this.hot.view.wt.wtOverlays.leftOverlay;

        if (fixedRowTop) {
          parentOverlay = this.hot.view.wt.wtOverlays.topLeftCornerOverlay;
        } else if (fixedRowBottom) {
          parentOverlay = this.hot.view.wt.wtOverlays.bottomLeftCornerOverlay;
        }

        var relativeHeaderPosition = parentOverlay.getRelativeCellPosition(this.currentTH, cellCoords.row, cellCoords.col); // If the TH is not a child of the left/top-left/bottom-left overlay, recalculate using the top-most header

        if (!relativeHeaderPosition) {
          var topMostHeader = parentOverlay.clone.wtTable.TBODY.children[+!!this.hot.getSettings().colHeaders + row].firstChild;
          relativeHeaderPosition = parentOverlay.getRelativeCellPosition(topMostHeader, cellCoords.row, cellCoords.col);
        }

        this.currentRow = row;
        this.selectedRows = [];

        if (this.hot.selection.isSelected() && this.hot.selection.isSelectedByRowHeader()) {
          var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
              from = _this$hot$getSelected.from,
              to = _this$hot$getSelected.to;

          var start = from.row;
          var end = to.row;

          if (start >= end) {
            start = to.row;
            end = from.row;
          }

          if (this.currentRow >= start && this.currentRow <= end) {
            (0, _number.rangeEach)(start, end, function (i) {
              return _this3.selectedRows.push(i);
            });
          } else {
            this.selectedRows.push(this.currentRow);
          }
        } else {
          this.selectedRows.push(this.currentRow);
        }

        this.startOffset = relativeHeaderPosition.top - 6;
        this.startHeight = parseInt(box.height, 10);
        this.handle.style.top = "".concat(this.startOffset + this.startHeight, "px");
        this.handle.style.left = "".concat(relativeHeaderPosition.left, "px");
        this.handle.style.width = "".concat(headerWidth, "px");
        this.hot.rootElement.appendChild(this.handle);
      }
    }
    /**
     * Refresh the resize handle position.
     *
     * @private
     */

  }, {
    key: "refreshHandlePosition",
    value: function refreshHandlePosition() {
      this.handle.style.top = "".concat(this.startOffset + this.currentHeight, "px");
    }
    /**
     * Sets the resize guide position.
     *
     * @private
     */

  }, {
    key: "setupGuidePosition",
    value: function setupGuidePosition() {
      var handleWidth = parseInt((0, _element.outerWidth)(this.handle), 10);
      var handleRightPosition = parseInt(this.handle.style.left, 10) + handleWidth;
      var maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10);
      (0, _element.addClass)(this.handle, 'active');
      (0, _element.addClass)(this.guide, 'active');
      this.guide.style.top = this.handle.style.top;
      this.guide.style.left = "".concat(handleRightPosition, "px");
      this.guide.style.width = "".concat(maximumVisibleElementWidth - handleWidth, "px");
      this.hot.rootElement.appendChild(this.guide);
    }
    /**
     * Refresh the resize guide position.
     *
     * @private
     */

  }, {
    key: "refreshGuidePosition",
    value: function refreshGuidePosition() {
      this.guide.style.top = this.handle.style.top;
    }
    /**
     * Hides both the resize handle and resize guide.
     *
     * @private
     */

  }, {
    key: "hideHandleAndGuide",
    value: function hideHandleAndGuide() {
      (0, _element.removeClass)(this.handle, 'active');
      (0, _element.removeClass)(this.guide, 'active');
    }
    /**
     * Checks if provided element is considered as a row header.
     *
     * @private
     * @param {HTMLElement} element HTML element.
     * @returns {Boolean}
     */

  }, {
    key: "checkIfRowHeader",
    value: function checkIfRowHeader(element) {
      if (element !== this.hot.rootElement) {
        var parent = element.parentNode;

        if (parent.tagName === 'TBODY') {
          return true;
        }

        return this.checkIfRowHeader(parent);
      }

      return false;
    }
    /**
     * Gets the TH element from the provided element.
     *
     * @private
     * @param {HTMLElement} element HTML element.
     * @returns {HTMLElement}
     */

  }, {
    key: "getTHFromTargetElement",
    value: function getTHFromTargetElement(element) {
      if (element.tagName !== 'TABLE') {
        if (element.tagName === 'TH') {
          return element;
        }

        return this.getTHFromTargetElement(element.parentNode);
      }

      return null;
    }
    /**
     * 'mouseover' event callback - set the handle position.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseOver",
    value: function onMouseOver(event) {
      if (this.checkIfRowHeader(event.target)) {
        var th = this.getTHFromTargetElement(event.target);

        if (th) {
          if (!this.pressed) {

            this.setupHandlePosition(th);
          }
        }
      }
    }
    /**
     * Auto-size row after doubleclick - callback.
     *
     * @private
     * @fires Hooks#beforeRowResize
     * @fires Hooks#afterRowResize
     */

  }, {
    key: "afterMouseDownTimeout",
    value: function afterMouseDownTimeout() {
      var _this4 = this;

      var render = function render() {
        _this4.hot.forceFullRender = true;

        _this4.hot.view.render(); // updates all


        _this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
      };

      var resize = function resize(selectedRow, forceRender) {
        var hookNewSize = _this4.hot.runHooks('beforeRowResize', selectedRow, _this4.newSize, true);

        if (hookNewSize !== void 0) {
          _this4.newSize = hookNewSize;
        }

        _this4.setManualSize(selectedRow, _this4.newSize); // double click sets auto row size


        if (forceRender) {
          render();
        }

        _this4.hot.runHooks('afterRowResize', selectedRow, _this4.newSize, true);
      };

      if (this.dblclick >= 2) {
        var selectedRowsLength = this.selectedRows.length;

        if (selectedRowsLength > 1) {
          (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
            resize(selectedRow);
          });
          render();
        } else {
          (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
            resize(selectedRow, true);
          });
        }
      }

      this.dblclick = 0;
      this.autoresizeTimeout = null;
    }
    /**
     * 'mousedown' event callback.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseDown",
    value: function onMouseDown(event) {
      var _this5 = this;

      if ((0, _element.hasClass)(event.target, 'manualRowResizer')) {
        this.setupGuidePosition();
        this.pressed = this.hot;

        if (this.autoresizeTimeout === null) {
          this.autoresizeTimeout = setTimeout(function () {
            return _this5.afterMouseDownTimeout();
          }, 500);

          this.hot._registerTimeout(this.autoresizeTimeout);
        }

        this.dblclick += 1;
        this.startY = (0, _event.pageY)(event);
        this.newSize = this.startHeight;
      }
    }
    /**
     * 'mousemove' event callback - refresh the handle and guide positions, cache the new row height.
     *
     * @private
     * @param {MouseEvent} event
     */

  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var _this6 = this;

      if (this.pressed) {
        this.currentHeight = this.startHeight + ((0, _event.pageY)(event) - this.startY);
        (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
          _this6.newSize = _this6.setManualSize(selectedRow, _this6.currentHeight);
        });
        this.refreshHandlePosition();
        this.refreshGuidePosition();
      }
    }
    /**
     * 'mouseup' event callback - apply the row resizing.
     *
     * @private
     *
     * @fires Hooks#beforeRowResize
     * @fires Hooks#afterRowResize
     */

  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      var _this7 = this;

      var render = function render() {
        _this7.hot.forceFullRender = true;

        _this7.hot.view.render(); // updates all


        _this7.hot.view.wt.wtOverlays.adjustElementsSize(true);
      };

      var runHooks = function runHooks(selectedRow, forceRender) {
        _this7.hot.runHooks('beforeRowResize', selectedRow, _this7.newSize);

        if (forceRender) {
          render();
        }

        _this7.saveManualRowHeights();

        _this7.hot.runHooks('afterRowResize', selectedRow, _this7.newSize, false);
      };

      if (this.pressed) {
        this.hideHandleAndGuide();
        this.pressed = false;

        if (this.newSize !== this.startHeight) {
          var selectedRowsLength = this.selectedRows.length;

          if (selectedRowsLength > 1) {
            (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
              runHooks(selectedRow);
            });
            render();
          } else {
            (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
              runHooks(selectedRow, true);
            });
          }
        }

        this.setupHandlePosition(this.currentTH);
      }
    }
    /**
     * Binds the mouse events.
     *
     * @private
     */

  }, {
    key: "bindEvents",
    value: function bindEvents() {
      var _this8 = this;

      var _this$hot = this.hot,
          rootElement = _this$hot.rootElement,
          rootWindow = _this$hot.rootWindow;
      this.eventManager.addEventListener(rootElement, 'mouseover', function (e) {
        return _this8.onMouseOver(e);
      });
      this.eventManager.addEventListener(rootElement, 'mousedown', function (e) {
        return _this8.onMouseDown(e);
      });
      this.eventManager.addEventListener(rootWindow, 'mousemove', function (e) {
        return _this8.onMouseMove(e);
      });
      this.eventManager.addEventListener(rootWindow, 'mouseup', function () {
        return _this8.onMouseUp();
      });
    }
    /**
     * Sets the new height for specified row index.
     *
     * @param {Number} row Visual row index.
     * @param {Number} height Row height.
     * @returns {Number} Returns new height.
     *
     * @fires Hooks#modifyRow
     */

  }, {
    key: "setManualSize",
    value: function setManualSize(row, height) {
      var physicalRow = this.hot.runHooks('modifyRow', row);
      this.manualRowHeights[physicalRow] = height;
      return height;
    }
    /**
     * Modifies the provided row height, based on the plugin settings.
     *
     * @private
     * @param {Number} height Row height.
     * @param {Number} row Visual row index.
     * @returns {Number}
     *
     * @fires Hooks#modifyRow
     */

  }, {
    key: "onModifyRowHeight",
    value: function onModifyRowHeight(height, row) {
      if (this.enabled) {
        var autoRowSizePlugin = this.hot.getPlugin('autoRowSize');
        var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null;
        var physicalRow = this.hot.runHooks('modifyRow', row);
        var manualRowHeight = this.manualRowHeights[physicalRow];

        if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) {
          return manualRowHeight;
        }
      }

      return height;
    }
  }]);
  return ManualRowResize;
}(_base.default);

(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize);
var _default = ManualRowResize;
exports.default = _default;

/***/ }),
/* 668 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(33);

__webpack_require__(10);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _plugins = __webpack_require__(20);

var _event = __webpack_require__(31);

var _src = __webpack_require__(25);

var _cellsCollection = _interopRequireDefault(__webpack_require__(669));

var _cellCoords = _interopRequireDefault(__webpack_require__(168));

var _autofill = _interopRequireDefault(__webpack_require__(670));

var _selection = _interopRequireDefault(__webpack_require__(671));

var _toggleMerge = _interopRequireDefault(__webpack_require__(672));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _console = __webpack_require__(55);

var _number = __webpack_require__(15);

var _utils = __webpack_require__(492);

__webpack_require__(673);

_pluginHooks.default.getSingleton().register('beforeMergeCells');

_pluginHooks.default.getSingleton().register('afterMergeCells');

_pluginHooks.default.getSingleton().register('beforeUnmergeCells');

_pluginHooks.default.getSingleton().register('afterUnmergeCells');

var privatePool = new WeakMap();
/**
 * @plugin MergeCells
 *
 * @description
 * Plugin, which allows merging cells in the table (using the initial configuration, API or context menu).
 *
 * @example
 *
 * ```js
 * const hot = new Handsontable(document.getElementById('example'), {
 *  data: getData(),
 *  mergeCells: [
 *    {row: 0, col: 3, rowspan: 3, colspan: 3},
 *    {row: 2, col: 6, rowspan: 2, colspan: 2},
 *    {row: 4, col: 8, rowspan: 3, colspan: 3}
 *  ],
 * ```
 */

var MergeCells =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(MergeCells, _BasePlugin);

  function MergeCells(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, MergeCells);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MergeCells).call(this, hotInstance));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      lastDesiredCoords: null
    });
    /**
     * A container for all the merged cells.
     *
     * @private
     * @type {MergedCellsCollection}
     */

    _this.mergedCellsCollection = null;
    /**
     * Instance of the class responsible for all the autofill-related calculations.
     *
     * @private
     * @type {AutofillCalculations}
     */

    _this.autofillCalculations = null;
    /**
     * Instance of the class responsible for the selection-related calculations.
     *
     * @private
     * @type {SelectionCalculations}
     */

    _this.selectionCalculations = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link MergeCells#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(MergeCells, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().mergeCells;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.mergedCellsCollection = new _cellsCollection.default(this);
      this.autofillCalculations = new _autofill.default(this);
      this.selectionCalculations = new _selection.default(this);
      this.addHook('afterInit', function () {
        return _this2.onAfterInit.apply(_this2, arguments);
      });
      this.addHook('beforeKeyDown', function () {
        return _this2.onBeforeKeyDown.apply(_this2, arguments);
      });
      this.addHook('modifyTransformStart', function () {
        return _this2.onModifyTransformStart.apply(_this2, arguments);
      });
      this.addHook('afterModifyTransformStart', function () {
        return _this2.onAfterModifyTransformStart.apply(_this2, arguments);
      });
      this.addHook('modifyTransformEnd', function () {
        return _this2.onModifyTransformEnd.apply(_this2, arguments);
      });
      this.addHook('modifyGetCellCoords', function () {
        return _this2.onModifyGetCellCoords.apply(_this2, arguments);
      });
      this.addHook('beforeSetRangeEnd', function () {
        return _this2.onBeforeSetRangeEnd.apply(_this2, arguments);
      });
      this.addHook('afterIsMultipleSelection', function () {
        return _this2.onAfterIsMultipleSelection.apply(_this2, arguments);
      });
      this.addHook('afterRenderer', function () {
        return _this2.onAfterRenderer.apply(_this2, arguments);
      });
      this.addHook('afterContextMenuDefaultOptions', function () {
        return _this2.addMergeActionsToContextMenu.apply(_this2, arguments);
      });
      this.addHook('afterGetCellMeta', function () {
        return _this2.onAfterGetCellMeta.apply(_this2, arguments);
      });
      this.addHook('afterViewportRowCalculatorOverride', function () {
        return _this2.onAfterViewportRowCalculatorOverride.apply(_this2, arguments);
      });
      this.addHook('afterViewportColumnCalculatorOverride', function () {
        return _this2.onAfterViewportColumnCalculatorOverride.apply(_this2, arguments);
      });
      this.addHook('modifyAutofillRange', function () {
        return _this2.onModifyAutofillRange.apply(_this2, arguments);
      });
      this.addHook('afterCreateCol', function () {
        return _this2.onAfterCreateCol.apply(_this2, arguments);
      });
      this.addHook('afterRemoveCol', function () {
        return _this2.onAfterRemoveCol.apply(_this2, arguments);
      });
      this.addHook('afterCreateRow', function () {
        return _this2.onAfterCreateRow.apply(_this2, arguments);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow.apply(_this2, arguments);
      });
      this.addHook('afterChange', function () {
        return _this2.onAfterChange.apply(_this2, arguments);
      });
      this.addHook('beforeDrawBorders', function () {
        return _this2.onBeforeDrawAreaBorders.apply(_this2, arguments);
      });
      this.addHook('afterDrawSelection', function () {
        return _this2.onAfterDrawSelection.apply(_this2, arguments);
      });
      this.addHook('beforeRemoveCellClassNames', function () {
        return _this2.onBeforeRemoveCellClassNames.apply(_this2, arguments);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.clearCollections();
      this.hot.render();
      (0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      var settings = this.hot.getSettings().mergeCells;
      this.disablePlugin();
      this.enablePlugin();
      this.generateFromSettings(settings);
      (0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Validates a single setting object, represented by a single merged cell information object.
     *
     * @private
     * @param {Object} setting An object with `row`, `col`, `rowspan` and `colspan` properties.
     * @return {Boolean}
     */

  }, {
    key: "validateSetting",
    value: function validateSetting(setting) {
      var valid = true;

      if (!setting) {
        return false;
      }

      if (_cellCoords.default.containsNegativeValues(setting)) {
        (0, _console.warn)(_cellCoords.default.NEGATIVE_VALUES_WARNING(setting));
        valid = false;
      } else if (_cellCoords.default.isOutOfBounds(setting, this.hot.countRows(), this.hot.countCols())) {
        (0, _console.warn)(_cellCoords.default.IS_OUT_OF_BOUNDS_WARNING(setting));
        valid = false;
      } else if (_cellCoords.default.isSingleCell(setting)) {
        (0, _console.warn)(_cellCoords.default.IS_SINGLE_CELL(setting));
        valid = false;
      } else if (_cellCoords.default.containsZeroSpan(setting)) {
        (0, _console.warn)(_cellCoords.default.ZERO_SPAN_WARNING(setting));
        valid = false;
      }

      return valid;
    }
    /**
     * Generates the merged cells from the settings provided to the plugin.
     *
     * @private
     * @param {Array|Boolean} settings The settings provided to the plugin.
     */

  }, {
    key: "generateFromSettings",
    value: function generateFromSettings(settings) {
      var _this3 = this;

      if (Array.isArray(settings)) {
        var _this$hot;

        var populationArgumentsList = [];
        (0, _array.arrayEach)(settings, function (setting) {
          if (!_this3.validateSetting(setting)) {
            return;
          }

          var highlight = new _src.CellCoords(setting.row, setting.col);
          var rangeEnd = new _src.CellCoords(setting.row + setting.rowspan - 1, setting.col + setting.colspan - 1);
          var mergeRange = new _src.CellRange(highlight, highlight, rangeEnd);
          populationArgumentsList.push(_this3.mergeRange(mergeRange, true, true));
        }); // remove 'empty' setting objects, caused by improper merge range declarations

        populationArgumentsList = populationArgumentsList.filter(function (value) {
          return value !== true;
        });
        var bulkPopulationData = this.getBulkCollectionData(populationArgumentsList);

        (_this$hot = this.hot).populateFromArray.apply(_this$hot, (0, _toConsumableArray2.default)(bulkPopulationData));
      }
    }
    /**
     * Generates a bulk set of all the data to be populated to fill the data "under" the added merged cells.
     *
     * @private
     * @param {Array} populationArgumentsList Array in a form of `[row, column, dataUnderCollection]`.
     * @return {Array} Array in a form of `[row, column, dataOfAllCollections]`.
     */

  }, {
    key: "getBulkCollectionData",
    value: function getBulkCollectionData(populationArgumentsList) {
      var _this$hot2;

      var populationDataRange = this.getBulkCollectionDataRange(populationArgumentsList);

      var dataAtRange = (_this$hot2 = this.hot).getData.apply(_this$hot2, (0, _toConsumableArray2.default)(populationDataRange));

      var newDataAtRange = dataAtRange.splice(0);
      (0, _array.arrayEach)(populationArgumentsList, function (mergedCellArguments) {
        var _mergedCellArguments = (0, _slicedToArray2.default)(mergedCellArguments, 3),
            mergedCellRowIndex = _mergedCellArguments[0],
            mergedCellColumnIndex = _mergedCellArguments[1],
            mergedCellData = _mergedCellArguments[2];

        (0, _array.arrayEach)(mergedCellData, function (mergedCellRow, rowIndex) {
          (0, _array.arrayEach)(mergedCellRow, function (mergedCellElement, columnIndex) {
            newDataAtRange[mergedCellRowIndex - populationDataRange[0] + rowIndex][mergedCellColumnIndex - populationDataRange[1] + columnIndex] = mergedCellElement;
          });
        });
      });
      return [populationDataRange[0], populationDataRange[1], newDataAtRange];
    }
    /**
     * Gets the range of combined data ranges provided in a form of an array of arrays ([row, column, dataUnderCollection])
     *
     * @private
     * @param {Array} populationArgumentsList Array containing argument lists for the `populateFromArray` method - row, column and data for population.
     * @return {Array[]} Start and end coordinates of the merged cell range. (in a form of [rowIndex, columnIndex])
     */

  }, {
    key: "getBulkCollectionDataRange",
    value: function getBulkCollectionDataRange(populationArgumentsList) {
      var start = [0, 0];
      var end = [0, 0];
      var mergedCellRow = null;
      var mergedCellColumn = null;
      var mergedCellData = null;
      (0, _array.arrayEach)(populationArgumentsList, function (mergedCellArguments) {
        mergedCellRow = mergedCellArguments[0];
        mergedCellColumn = mergedCellArguments[1];
        mergedCellData = mergedCellArguments[2];
        start[0] = Math.min(mergedCellRow, start[0]);
        start[1] = Math.min(mergedCellColumn, start[1]);
        end[0] = Math.max(mergedCellRow + mergedCellData.length - 1, end[0]);
        end[1] = Math.max(mergedCellColumn + mergedCellData[0].length - 1, end[1]);
      });
      return [].concat(start, end);
    }
    /**
     * Clears the merged cells from the merged cell container.
     */

  }, {
    key: "clearCollections",
    value: function clearCollections() {
      this.mergedCellsCollection.clear();
    }
    /**
     * Returns `true` if a range is mergeable.
     *
     * @private
     * @param {Object} newMergedCellInfo Merged cell information object to test.
     * @param {Boolean} [auto=false] `true` if triggered at initialization.
     * @returns {Boolean}
     */

  }, {
    key: "canMergeRange",
    value: function canMergeRange(newMergedCellInfo) {
      var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      return auto ? true : this.validateSetting(newMergedCellInfo);
    }
    /**
     * Merge or unmerge, based on last selected range.
     *
     * @private
     */

  }, {
    key: "toggleMergeOnSelection",
    value: function toggleMergeOnSelection() {
      var currentRange = this.hot.getSelectedRangeLast();

      if (!currentRange) {
        return;
      }

      currentRange.setDirection('NW-SE');
      var from = currentRange.from,
          to = currentRange.to;
      this.toggleMerge(currentRange);
      this.hot.selectCell(from.row, from.col, to.row, to.col, false);
    }
    /**
     * Merges the selection provided as a cell range.
     *
     * @param {CellRange} [cellRange] Selection cell range.
     */

  }, {
    key: "mergeSelection",
    value: function mergeSelection() {
      var cellRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.hot.getSelectedRangeLast();

      if (!cellRange) {
        return;
      }

      cellRange.setDirection('NW-SE');
      var from = cellRange.from,
          to = cellRange.to;
      this.unmergeRange(cellRange, true);
      this.mergeRange(cellRange);
      this.hot.selectCell(from.row, from.col, to.row, to.col, false);
    }
    /**
     * Unmerges the selection provided as a cell range.
     *
     * @param {CellRange} [cellRange] Selection cell range.
     */

  }, {
    key: "unmergeSelection",
    value: function unmergeSelection() {
      var cellRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.hot.getSelectedRangeLast();

      if (!cellRange) {
        return;
      }

      var from = cellRange.from,
          to = cellRange.to;
      this.unmergeRange(cellRange, true);
      this.hot.selectCell(from.row, from.col, to.row, to.col, false);
    }
    /**
     * Merges cells in the provided cell range.
     *
     * @private
     * @param {CellRange} cellRange Cell range to merge.
     * @param {Boolean} [auto=false] `true` if is called automatically, e.g. at initialization.
     * @param {Boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end, but rather return its arguments.
     * @returns {Array|Boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to true. If the the merging process went successful, it returns `true`, otherwise - `false`.
     * @fires Hooks#beforeMergeCells
     * @fires Hooks#afterMergeCells
     */

  }, {
    key: "mergeRange",
    value: function mergeRange(cellRange) {
      var _this4 = this;

      var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var preventPopulation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var topLeft = cellRange.getTopLeftCorner();
      var bottomRight = cellRange.getBottomRightCorner();
      var mergeParent = {
        row: topLeft.row,
        col: topLeft.col,
        rowspan: bottomRight.row - topLeft.row + 1,
        colspan: bottomRight.col - topLeft.col + 1
      };
      var clearedData = [];
      var populationInfo = null;

      if (!this.canMergeRange(mergeParent, auto)) {
        return false;
      }

      this.hot.runHooks('beforeMergeCells', cellRange, auto);
      (0, _number.rangeEach)(0, mergeParent.rowspan - 1, function (i) {
        (0, _number.rangeEach)(0, mergeParent.colspan - 1, function (j) {
          var clearedValue = null;

          if (!clearedData[i]) {
            clearedData[i] = [];
          }

          if (i === 0 && j === 0) {
            clearedValue = _this4.hot.getDataAtCell(mergeParent.row, mergeParent.col);
          } else {
            _this4.hot.setCellMeta(mergeParent.row + i, mergeParent.col + j, 'hidden', true);
          }

          clearedData[i][j] = clearedValue;
        });
      });
      this.hot.setCellMeta(mergeParent.row, mergeParent.col, 'spanned', true);
      var mergedCellAdded = this.mergedCellsCollection.add(mergeParent);

      if (mergedCellAdded) {
        if (preventPopulation) {
          populationInfo = [mergeParent.row, mergeParent.col, clearedData];
        } else {
          this.hot.populateFromArray(mergeParent.row, mergeParent.col, clearedData, void 0, void 0, this.pluginName);
        }

        this.hot.runHooks('afterMergeCells', cellRange, mergeParent, auto);
        return populationInfo;
      }

      return true;
    }
    /**
     * Unmerges the selection provided as a cell range. If no cell range is provided, it uses the current selection.
     *
     * @private
     * @param {CellRange} cellRange Selection cell range.
     * @param {Boolean} [auto=false] `true` if called automatically by the plugin.
     *
     * @fires Hooks#beforeUnmergeCells
     * @fires Hooks#afterUnmergeCells
     */

  }, {
    key: "unmergeRange",
    value: function unmergeRange(cellRange) {
      var _this5 = this;

      var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var mergedCells = this.mergedCellsCollection.getWithinRange(cellRange);

      if (!mergedCells) {
        return;
      }

      this.hot.runHooks('beforeUnmergeCells', cellRange, auto);
      (0, _array.arrayEach)(mergedCells, function (currentCollection) {
        _this5.mergedCellsCollection.remove(currentCollection.row, currentCollection.col);

        (0, _number.rangeEach)(0, currentCollection.rowspan - 1, function (i) {
          (0, _number.rangeEach)(0, currentCollection.colspan - 1, function (j) {
            _this5.hot.removeCellMeta(currentCollection.row + i, currentCollection.col + j, 'hidden');
          });
        });

        _this5.hot.removeCellMeta(currentCollection.row, currentCollection.col, 'spanned');
      });
      this.hot.render();
      this.hot.runHooks('afterUnmergeCells', cellRange, auto);
    }
    /**
     * Merges or unmerges, based on the cell range provided as `cellRange`.
     *
     * @private
     * @param {CellRange} cellRange The cell range to merge or unmerged.
     */

  }, {
    key: "toggleMerge",
    value: function toggleMerge(cellRange) {
      var mergedCell = this.mergedCellsCollection.get(cellRange.from.row, cellRange.from.col);
      var mergedCellCoversWholeRange = mergedCell.row === cellRange.from.row && mergedCell.col === cellRange.from.col && mergedCell.row + mergedCell.rowspan - 1 === cellRange.to.row && mergedCell.col + mergedCell.colspan - 1 === cellRange.to.col;

      if (mergedCellCoversWholeRange) {
        this.unmergeRange(cellRange);
      } else {
        this.mergeSelection(cellRange);
      }
    }
    /**
     * Merges the specified range.
     *
     * @param {Number} startRow Start row of the merged cell.
     * @param {Number} startColumn Start column of the merged cell.
     * @param {Number} endRow End row of the merged cell.
     * @param {Number} endColumn End column of the merged cell.
     * @fires Hooks#beforeMergeCells
     * @fires Hooks#afterMergeCells
     */

  }, {
    key: "merge",
    value: function merge(startRow, startColumn, endRow, endColumn) {
      var start = new _src.CellCoords(startRow, startColumn);
      var end = new _src.CellCoords(endRow, endColumn);
      this.mergeRange(new _src.CellRange(start, start, end));
    }
    /**
     * Unmerges the merged cell in the provided range.
     *
     * @param {Number} startRow Start row of the merged cell.
     * @param {Number} startColumn Start column of the merged cell.
     * @param {Number} endRow End row of the merged cell.
     * @param {Number} endColumn End column of the merged cell.
     * @fires Hooks#beforeUnmergeCells
     * @fires Hooks#afterUnmergeCells
     */

  }, {
    key: "unmerge",
    value: function unmerge(startRow, startColumn, endRow, endColumn) {
      var start = new _src.CellCoords(startRow, startColumn);
      var end = new _src.CellCoords(endRow, endColumn);
      this.unmergeRange(new _src.CellRange(start, start, end));
    }
    /**
     * `afterInit` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.generateFromSettings(this.hot.getSettings().mergeCells);
      this.hot.render();
    }
    /**
     * `beforeKeyDown` hook callback.
     *
     * @private
     * @param {KeyboardEvent} event The `keydown` event object.
     */

  }, {
    key: "onBeforeKeyDown",
    value: function onBeforeKeyDown(event) {
      var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;

      if (ctrlDown && event.keyCode === 77) {
        // CTRL + M
        this.toggleMerge(this.hot.getSelectedRangeLast());
        this.hot.render();
        (0, _event.stopImmediatePropagation)(event);
      }
    }
    /**
     * Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection` hook callback.
     *
     * @private
     * @param {Boolean} isMultiple
     * @returns {Boolean}
     */

  }, {
    key: "onAfterIsMultipleSelection",
    value: function onAfterIsMultipleSelection(isMultiple) {
      if (isMultiple) {
        var mergedCells = this.mergedCellsCollection.mergedCells;
        var selectionRange = this.hot.getSelectedRangeLast();

        for (var group = 0; group < mergedCells.length; group += 1) {
          if (selectionRange.highlight.row === mergedCells[group].row && selectionRange.highlight.col === mergedCells[group].col && selectionRange.to.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
            return false;
          }
        }
      }

      return isMultiple;
    }
    /**
     * `modifyTransformStart` hook callback.
     *
     * @private
     * @param {Object} delta The transformation delta.
     */

  }, {
    key: "onModifyTransformStart",
    value: function onModifyTransformStart(delta) {
      var priv = privatePool.get(this);
      var currentlySelectedRange = this.hot.getSelectedRangeLast();
      var newDelta = {
        row: delta.row,
        col: delta.col
      };
      var nextPosition = null;
      var currentPosition = new _src.CellCoords(currentlySelectedRange.highlight.row, currentlySelectedRange.highlight.col);
      var mergedParent = this.mergedCellsCollection.get(currentPosition.row, currentPosition.col);

      if (!priv.lastDesiredCoords) {
        priv.lastDesiredCoords = new _src.CellCoords(null, null);
      }

      if (mergedParent) {
        // only merge selected
        var mergeTopLeft = new _src.CellCoords(mergedParent.row, mergedParent.col);
        var mergeBottomRight = new _src.CellCoords(mergedParent.row + mergedParent.rowspan - 1, mergedParent.col + mergedParent.colspan - 1);
        var mergeRange = new _src.CellRange(mergeTopLeft, mergeTopLeft, mergeBottomRight);

        if (!mergeRange.includes(priv.lastDesiredCoords)) {
          priv.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords
        }

        newDelta.row = priv.lastDesiredCoords.row ? priv.lastDesiredCoords.row - currentPosition.row : newDelta.row;
        newDelta.col = priv.lastDesiredCoords.col ? priv.lastDesiredCoords.col - currentPosition.col : newDelta.col;

        if (delta.row > 0) {
          // moving down
          newDelta.row = mergedParent.row + mergedParent.rowspan - 1 - currentPosition.row + delta.row;
        } else if (delta.row < 0) {
          // moving up
          newDelta.row = currentPosition.row - mergedParent.row + delta.row;
        }

        if (delta.col > 0) {
          // moving right
          newDelta.col = mergedParent.col + mergedParent.colspan - 1 - currentPosition.col + delta.col;
        } else if (delta.col < 0) {
          // moving left
          newDelta.col = currentPosition.col - mergedParent.col + delta.col;
        }
      }

      nextPosition = new _src.CellCoords(currentlySelectedRange.highlight.row + newDelta.row, currentlySelectedRange.highlight.col + newDelta.col);
      var nextParentIsMerged = this.mergedCellsCollection.get(nextPosition.row, nextPosition.col);

      if (nextParentIsMerged) {
        // skipping the invisible cells in the merge range
        priv.lastDesiredCoords = nextPosition;
        newDelta = {
          row: nextParentIsMerged.row - currentPosition.row,
          col: nextParentIsMerged.col - currentPosition.col
        };
      }

      if (newDelta.row !== 0) {
        delta.row = newDelta.row;
      }

      if (newDelta.col !== 0) {
        delta.col = newDelta.col;
      }
    }
    /**
     * `modifyTransformEnd` hook callback. Needed to handle "jumping over" merged merged cells, while selecting.
     *
     * @private
     * @param {Object} delta The transformation delta.
     */

  }, {
    key: "onModifyTransformEnd",
    value: function onModifyTransformEnd(delta) {
      var _this6 = this;

      var currentSelectionRange = this.hot.getSelectedRangeLast();
      var newDelta = (0, _object.clone)(delta);
      var newSelectionRange = this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, delta);
      var tempDelta = (0, _object.clone)(newDelta);
      var mergedCellsWithinRange = this.mergedCellsCollection.getWithinRange(newSelectionRange, true);

      do {
        tempDelta = (0, _object.clone)(newDelta);
        this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, newDelta);
        (0, _array.arrayEach)(mergedCellsWithinRange, function (mergedCell) {
          _this6.selectionCalculations.snapDelta(newDelta, currentSelectionRange, mergedCell);
        });
      } while (newDelta.row !== tempDelta.row || newDelta.col !== tempDelta.col);

      delta.row = newDelta.row;
      delta.col = newDelta.col;
    }
    /**
     * `modifyGetCellCoords` hook callback. Swaps the `getCell` coords with the merged parent coords.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {Array}
     */

  }, {
    key: "onModifyGetCellCoords",
    value: function onModifyGetCellCoords(row, column) {
      var mergeParent = this.mergedCellsCollection.get(row, column);
      return mergeParent ? [mergeParent.row, mergeParent.col, mergeParent.row + mergeParent.rowspan - 1, mergeParent.col + mergeParent.colspan - 1] : void 0;
    }
    /**
     * `afterContextMenuDefaultOptions` hook callback.
     *
     * @private
     * @param {Object} defaultOptions The default context menu options.
     */

  }, {
    key: "addMergeActionsToContextMenu",
    value: function addMergeActionsToContextMenu(defaultOptions) {
      defaultOptions.items.push({
        name: '---------'
      }, (0, _toggleMerge.default)(this));
    }
    /**
     * `afterRenderer` hook callback.
     *
     * @private
     * @param {HTMLElement} TD The cell to be modified.
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     */

  }, {
    key: "onAfterRenderer",
    value: function onAfterRenderer(TD, row, col) {
      var mergedCell = this.mergedCellsCollection.get(row, col);
      (0, _utils.applySpanProperties)(TD, mergedCell, row, col);
    }
    /**
     * `beforeSetRangeEnd` hook callback.
     * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell
     *
     * @private
     * @param {Object} coords Cell coords.
     */

  }, {
    key: "onBeforeSetRangeEnd",
    value: function onBeforeSetRangeEnd(coords) {
      var selRange = this.hot.getSelectedRangeLast();
      selRange.highlight = new _src.CellCoords(selRange.highlight.row, selRange.highlight.col); // clone in case we will modify its reference

      selRange.to = coords;
      var rangeExpanded = false;

      if (this.hot.selection.isSelectedByColumnHeader() || this.hot.selection.isSelectedByRowHeader()) {
        return;
      }

      do {
        rangeExpanded = false;

        for (var i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
          var cellInfo = this.mergedCellsCollection.mergedCells[i];
          var mergedCellRange = cellInfo.getRange();

          if (selRange.expandByRange(mergedCellRange)) {
            coords.row = selRange.to.row;
            coords.col = selRange.to.col;
            rangeExpanded = true;
          }
        }
      } while (rangeExpanded);
    }
    /**
     * The `afterGetCellMeta` hook callback.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     * @param {Object} cellProperties The cell properties object.
     */

  }, {
    key: "onAfterGetCellMeta",
    value: function onAfterGetCellMeta(row, col, cellProperties) {
      var mergeParent = this.mergedCellsCollection.get(row, col);

      if (mergeParent && (mergeParent.row !== row || mergeParent.col !== col)) {
        cellProperties.copyable = false;
      }
    }
    /**
     * `afterViewportRowCalculatorOverride` hook callback.
     *
     * @private
     * @param {Object} calc The row calculator object.
     */

  }, {
    key: "onAfterViewportRowCalculatorOverride",
    value: function onAfterViewportRowCalculatorOverride(calc) {
      var _this7 = this;

      var colCount = this.hot.countCols();
      var mergeParent;
      (0, _number.rangeEach)(0, colCount - 1, function (c) {
        mergeParent = _this7.mergedCellsCollection.get(calc.startRow, c);

        if (mergeParent) {
          if (mergeParent.row < calc.startRow) {
            calc.startRow = mergeParent.row;
            return _this7.onAfterViewportRowCalculatorOverride.call(_this7, calc); // recursively search upwards
          }
        }

        mergeParent = _this7.mergedCellsCollection.get(calc.endRow, c);

        if (mergeParent) {
          var mergeEnd = mergeParent.row + mergeParent.rowspan - 1;

          if (mergeEnd > calc.endRow) {
            calc.endRow = mergeEnd;
            return _this7.onAfterViewportRowCalculatorOverride.call(_this7, calc); // recursively search upwards
          }
        }

        return true;
      });
    }
    /**
     * `afterViewportColumnCalculatorOverride` hook callback.
     *
     * @private
     * @param {Object} calc The column calculator object.
     */

  }, {
    key: "onAfterViewportColumnCalculatorOverride",
    value: function onAfterViewportColumnCalculatorOverride(calc) {
      var _this8 = this;

      var rowCount = this.hot.countRows();
      var mergeParent;
      (0, _number.rangeEach)(0, rowCount - 1, function (r) {
        mergeParent = _this8.mergedCellsCollection.get(r, calc.startColumn);

        if (mergeParent && mergeParent.col < calc.startColumn) {
          calc.startColumn = mergeParent.col;
          return _this8.onAfterViewportColumnCalculatorOverride.call(_this8, calc); // recursively search upwards
        }

        mergeParent = _this8.mergedCellsCollection.get(r, calc.endColumn);

        if (mergeParent) {
          var mergeEnd = mergeParent.col + mergeParent.colspan - 1;

          if (mergeEnd > calc.endColumn) {
            calc.endColumn = mergeEnd;
            return _this8.onAfterViewportColumnCalculatorOverride.call(_this8, calc); // recursively search upwards
          }
        }

        return true;
      });
    }
    /**
     * The `modifyAutofillRange` hook callback.
     *
     * @private
     * @param {Array} drag The drag area coordinates.
     * @param {Array} select The selection information.
     * @return {Array} The new drag area.
     */

  }, {
    key: "onModifyAutofillRange",
    value: function onModifyAutofillRange(drag, select) {
      this.autofillCalculations.correctSelectionAreaSize(select);
      var dragDirection = this.autofillCalculations.getDirection(select, drag);
      var dragArea = drag;

      if (this.autofillCalculations.dragAreaOverlapsCollections(select, dragArea, dragDirection)) {
        dragArea = select;
        return dragArea;
      }

      var mergedCellsWithinSelectionArea = this.mergedCellsCollection.getWithinRange({
        from: {
          row: select[0],
          col: select[1]
        },
        to: {
          row: select[2],
          col: select[3]
        }
      });

      if (!mergedCellsWithinSelectionArea) {
        return dragArea;
      }

      dragArea = this.autofillCalculations.snapDragArea(select, dragArea, dragDirection, mergedCellsWithinSelectionArea);
      return dragArea;
    }
    /**
     * `afterCreateCol` hook callback.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} count Number of created columns.
     */

  }, {
    key: "onAfterCreateCol",
    value: function onAfterCreateCol(column, count) {
      this.mergedCellsCollection.shiftCollections('right', column, count);
    }
    /**
     * `afterRemoveCol` hook callback.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} count Number of removed columns.
     */

  }, {
    key: "onAfterRemoveCol",
    value: function onAfterRemoveCol(column, count) {
      this.mergedCellsCollection.shiftCollections('left', column, count);
    }
    /**
     * `afterCreateRow` hook callback.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} count Number of created rows.
     * @param {String} source Source of change.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(row, count, source) {
      if (source === 'auto') {
        return;
      }

      this.mergedCellsCollection.shiftCollections('down', row, count);
    }
    /**
     * `afterRemoveRow` hook callback.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} count Number of removed rows.
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow(row, count) {
      this.mergedCellsCollection.shiftCollections('up', row, count);
    }
    /**
     * `afterChange` hook callback. Used to propagate merged cells after using Autofill.
     *
     * @private
     * @param {Array} changes The changes array.
     * @param {String} source Determines the source of the change.
     */

  }, {
    key: "onAfterChange",
    value: function onAfterChange(changes, source) {
      if (source !== 'Autofill.fill') {
        return;
      }

      this.autofillCalculations.recreateAfterDataPopulation(changes);
    }
    /**
     * `beforeDrawAreaBorders` hook callback.
     *
     * @private
     * @param {Array} corners Coordinates of the area corners.
     * @param {String} className Class name for the area.
     */

  }, {
    key: "onBeforeDrawAreaBorders",
    value: function onBeforeDrawAreaBorders(corners, className) {
      if (className && className === 'area') {
        var selectedRange = this.hot.getSelectedRangeLast();
        var mergedCellsWithinRange = this.mergedCellsCollection.getWithinRange(selectedRange);
        (0, _array.arrayEach)(mergedCellsWithinRange, function (mergedCell) {
          if (selectedRange.getBottomRightCorner().row === mergedCell.getLastRow() && selectedRange.getBottomRightCorner().col === mergedCell.getLastColumn()) {
            corners[2] = mergedCell.row;
            corners[3] = mergedCell.col;
          }
        });
      }
    }
    /**
     * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of the table
     * with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
     *
     * @private
     * @param {CellCoords} coords Coordinates of the to-be-selected cell.
     * @param {Number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value = down)
     * @param {Number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value = down)
     */

  }, {
    key: "onAfterModifyTransformStart",
    value: function onAfterModifyTransformStart(coords, rowTransformDir, colTransformDir) {
      if (!this.enabled) {
        return;
      }

      var mergedCellAtCoords = this.mergedCellsCollection.get(coords.row, coords.col);

      if (!mergedCellAtCoords) {
        return;
      }

      var goingDown = rowTransformDir > 0;
      var goingUp = rowTransformDir < 0;
      var goingLeft = colTransformDir < 0;
      var goingRight = colTransformDir > 0;
      var mergedCellOnBottomEdge = mergedCellAtCoords.row + mergedCellAtCoords.rowspan - 1 === this.hot.countRows() - 1;
      var mergedCellOnTopEdge = mergedCellAtCoords.row === 0;
      var mergedCellOnRightEdge = mergedCellAtCoords.col + mergedCellAtCoords.colspan - 1 === this.hot.countCols() - 1;
      var mergedCellOnLeftEdge = mergedCellAtCoords.col === 0;

      if (goingDown && mergedCellOnBottomEdge || goingUp && mergedCellOnTopEdge || goingRight && mergedCellOnRightEdge || goingLeft && mergedCellOnLeftEdge) {
        coords.row = mergedCellAtCoords.row;
        coords.col = mergedCellAtCoords.col;
      }
    }
    /**
     * `afterDrawSelection` hook callback. Used to add the additional class name for the entirely-selected merged cells.
     *
     * @private
     * @param {Number} currentRow Row index of the currently processed cell.
     * @param {Number} currentColumn Column index of the currently cell.
     * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
     * @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
     * @returns {String|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
     */

  }, {
    key: "onAfterDrawSelection",
    value: function onAfterDrawSelection(currentRow, currentColumn, cornersOfSelection, layerLevel) {
      return this.selectionCalculations.getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel);
    }
    /**
     * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
     *
     * @private
     * @returns {String[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
     */

  }, {
    key: "onBeforeRemoveCellClassNames",
    value: function onBeforeRemoveCellClassNames() {
      return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
    }
  }]);
  return MergeCells;
}(_base.default);

(0, _plugins.registerPlugin)('mergeCells', MergeCells);
var _default = MergeCells;
exports.default = _default;

/***/ }),
/* 669 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _cellCoords = _interopRequireDefault(__webpack_require__(168));

var _index = __webpack_require__(25);

var _number = __webpack_require__(15);

var _console = __webpack_require__(55);

var _array = __webpack_require__(3);

var _utils = __webpack_require__(492);

var _templateLiteralTag = __webpack_require__(67);

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared at [", ", ", "], overlaps with the other declared merged \n    cell. The overlapping merged cell was not added to the table, please fix your setup."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * Defines a container object for the merged cells.
 *
 * @class MergedCellsCollection
 * @plugin MergeCells
 */
var MergedCellsCollection =
/*#__PURE__*/
function () {
  function MergedCellsCollection(plugin) {
    (0, _classCallCheck2.default)(this, MergedCellsCollection);

    /**
     * Reference to the Merge Cells plugin.
     *
     * @type {MergeCells}
     */
    this.plugin = plugin;
    /**
     * Array of merged cells.
     *
     * @type {Array}
     */

    this.mergedCells = [];
    /**
     * The Handsontable instance.
     *
     * @type {Handsontable}
     */

    this.hot = plugin.hot;
  }
  /**
   * Get a warning message for when the declared merged cell data overlaps already existing merged cells.
   *
   * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
   * @return {String}
   */


  (0, _createClass2.default)(MergedCellsCollection, [{
    key: "get",

    /**
     * Get a merged cell from the container, based on the provided arguments. You can provide either the "starting coordinates"
     * of a merged cell, or any coordinates from the body of the merged cell.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {MergedCellCoords|Boolean} Returns a wanted merged cell on success and `false` on failure.
     */
    value: function get(row, column) {
      var mergedCells = this.mergedCells;
      var result = false;
      (0, _array.arrayEach)(mergedCells, function (mergedCell) {
        if (mergedCell.row <= row && mergedCell.row + mergedCell.rowspan - 1 >= row && mergedCell.col <= column && mergedCell.col + mergedCell.colspan - 1 >= column) {
          result = mergedCell;
          return false;
        }

        return true;
      });
      return result;
    }
    /**
     * Get a merged cell containing the provided range.
     *
     * @param {CellRange|Object} range The range to search merged cells for.
     * @return {MergedCellCoords|Boolean}
     */

  }, {
    key: "getByRange",
    value: function getByRange(range) {
      var mergedCells = this.mergedCells;
      var result = false;
      (0, _array.arrayEach)(mergedCells, function (mergedCell) {
        if (mergedCell.row <= range.from.row && mergedCell.row + mergedCell.rowspan - 1 >= range.to.row && mergedCell.col <= range.from.col && mergedCell.col + mergedCell.colspan - 1 >= range.to.col) {
          result = mergedCell;
          return result;
        }

        return true;
      });
      return result;
    }
    /**
     * Get a merged cell contained in the provided range.
     *
     * @param {CellRange|Object} range The range to search merged cells in.
     * @param [countPartials=false] If set to `true`, all the merged cells overlapping the range will be taken into calculation.
     * @return {Array|Boolean} Array of found merged cells of `false` if none were found.
     */

  }, {
    key: "getWithinRange",
    value: function getWithinRange(range) {
      var countPartials = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var mergedCells = this.mergedCells;
      var foundMergedCells = [];
      var testedRange = range;

      if (!testedRange.includesRange) {
        var from = new _index.CellCoords(testedRange.from.row, testedRange.from.col);
        var to = new _index.CellCoords(testedRange.to.row, testedRange.to.col);
        testedRange = new _index.CellRange(from, from, to);
      }

      (0, _array.arrayEach)(mergedCells, function (mergedCell) {
        var mergedCellTopLeft = new _index.CellCoords(mergedCell.row, mergedCell.col);
        var mergedCellBottomRight = new _index.CellCoords(mergedCell.row + mergedCell.rowspan - 1, mergedCell.col + mergedCell.colspan - 1);
        var mergedCellRange = new _index.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);

        if (countPartials) {
          if (testedRange.overlaps(mergedCellRange)) {
            foundMergedCells.push(mergedCell);
          }
        } else if (testedRange.includesRange(mergedCellRange)) {
          foundMergedCells.push(mergedCell);
        }
      });
      return foundMergedCells.length ? foundMergedCells : false;
    }
    /**
     * Add a merged cell to the container.
     *
     * @param {Object} mergedCellInfo The merged cell information object. Has to contain `row`, `col`, `colspan` and `rowspan` properties.
     * @return {MergedCellCoords|Boolean} Returns the new merged cell on success and `false` on failure.
     */

  }, {
    key: "add",
    value: function add(mergedCellInfo) {
      var mergedCells = this.mergedCells;
      var row = mergedCellInfo.row;
      var column = mergedCellInfo.col;
      var rowspan = mergedCellInfo.rowspan;
      var colspan = mergedCellInfo.colspan;
      var newMergedCell = new _cellCoords.default(row, column, rowspan, colspan);
      var alreadyExists = this.get(row, column);
      var isOverlapping = this.isOverlapping(newMergedCell);

      if (!alreadyExists && !isOverlapping) {
        if (this.hot) {
          newMergedCell.normalize(this.hot);
        }

        mergedCells.push(newMergedCell);
        return newMergedCell;
      }

      (0, _console.warn)(MergedCellsCollection.IS_OVERLAPPING_WARNING(newMergedCell));
      return false;
    }
    /**
     * Remove a merged cell from the container. You can provide either the "starting coordinates"
     * of a merged cell, or any coordinates from the body of the merged cell.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @return {MergedCellCoords|Boolean} Returns the removed merged cell on success and `false` on failure.
     */

  }, {
    key: "remove",
    value: function remove(row, column) {
      var mergedCells = this.mergedCells;
      var wantedCollection = this.get(row, column);
      var wantedCollectionIndex = wantedCollection ? this.mergedCells.indexOf(wantedCollection) : null;

      if (wantedCollection && wantedCollectionIndex !== false) {
        mergedCells.splice(wantedCollectionIndex, 1);
        return wantedCollection;
      }

      return false;
    }
    /**
     * Clear all the merged cells.
     */

  }, {
    key: "clear",
    value: function clear() {
      var _this = this;

      var mergedCells = this.mergedCells;
      var mergedCellParentsToClear = [];
      var hiddenCollectionElements = [];
      (0, _array.arrayEach)(mergedCells, function (mergedCell) {
        var TD = _this.hot.getCell(mergedCell.row, mergedCell.col);

        if (TD) {
          mergedCellParentsToClear.push([TD, _this.get(mergedCell.row, mergedCell.col), mergedCell.row, mergedCell.col]);
        }
      });
      this.mergedCells.length = 0;
      (0, _array.arrayEach)(mergedCellParentsToClear, function (mergedCell, i) {
        (0, _number.rangeEach)(0, mergedCell.rowspan - 1, function (j) {
          (0, _number.rangeEach)(0, mergedCell.colspan - 1, function (k) {
            if (k !== 0 || j !== 0) {
              var TD = _this.hot.getCell(mergedCell.row + j, mergedCell.col + k);

              if (TD) {
                hiddenCollectionElements.push([TD, null, null, null]);
              }
            }
          });
        });
        mergedCellParentsToClear[i][1] = null;
      });
      (0, _array.arrayEach)(mergedCellParentsToClear, function (mergedCellParents) {
        _utils.applySpanProperties.apply(void 0, (0, _toConsumableArray2.default)(mergedCellParents));
      });
      (0, _array.arrayEach)(hiddenCollectionElements, function (hiddenCollectionElement) {
        _utils.applySpanProperties.apply(void 0, (0, _toConsumableArray2.default)(hiddenCollectionElement));
      });
    }
    /**
     * Check if the provided merged cell overlaps with the others in the container.
     *
     * @param {MergedCellCoords} mergedCell The merged cell to check against all others in the container.
     * @return {Boolean} `true` if the provided merged cell overlaps with the others, `false` otherwise.
     */

  }, {
    key: "isOverlapping",
    value: function isOverlapping(mergedCell) {
      var mergedCellRange = new _index.CellRange(null, new _index.CellCoords(mergedCell.row, mergedCell.col), new _index.CellCoords(mergedCell.row + mergedCell.rowspan - 1, mergedCell.col + mergedCell.colspan - 1));
      var result = false;
      (0, _array.arrayEach)(this.mergedCells, function (col) {
        var currentRange = new _index.CellRange(null, new _index.CellCoords(col.row, col.col), new _index.CellCoords(col.row + col.rowspan - 1, col.col + col.colspan - 1));

        if (currentRange.overlaps(mergedCellRange)) {
          result = true;
          return false;
        }

        return true;
      });
      return result;
    }
    /**
     * Check whether the provided row/col coordinates direct to a merged parent.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @return {Boolean}
     */

  }, {
    key: "isMergedParent",
    value: function isMergedParent(row, column) {
      var mergedCells = this.mergedCells;
      var result = false;
      (0, _array.arrayEach)(mergedCells, function (mergedCell) {
        if (mergedCell.row === row && mergedCell.col === column) {
          result = true;
          return false;
        }

        return true;
      });
      return result;
    }
    /**
     * Shift the merged cell in the direction and by an offset defined in the arguments.
     *
     * @param {String} direction `right`, `left`, `up` or `down`.
     * @param {Number} index Index where the change, which caused the shifting took place.
     * @param {Number} count Number of rows/columns added/removed in the preceding action.
     */

  }, {
    key: "shiftCollections",
    value: function shiftCollections(direction, index, count) {
      var _this2 = this;

      var shiftVector = [0, 0];

      switch (direction) {
        case 'right':
          shiftVector[0] += count;
          break;

        case 'left':
          shiftVector[0] -= count;
          break;

        case 'down':
          shiftVector[1] += count;
          break;

        case 'up':
          shiftVector[1] -= count;
          break;

        default:
      }

      (0, _array.arrayEach)(this.mergedCells, function (currentMerge) {
        currentMerge.shift(shiftVector, index);
      });
      (0, _number.rangeEachReverse)(this.mergedCells.length - 1, 0, function (i) {
        var currentMerge = _this2.mergedCells[i];

        if (currentMerge && currentMerge.removed) {
          _this2.mergedCells.splice(_this2.mergedCells.indexOf(currentMerge), 1);
        }
      });
    }
  }], [{
    key: "IS_OVERLAPPING_WARNING",
    value: function IS_OVERLAPPING_WARNING(newMergedCell) {
      return (0, _templateLiteralTag.toSingleLine)(_templateObject(), newMergedCell.row, newMergedCell.col);
    }
  }]);
  return MergedCellsCollection;
}();

var _default = MergedCellsCollection;
exports.default = _default;

/***/ }),
/* 670 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(40);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _src = __webpack_require__(25);

var _array = __webpack_require__(3);

/**
 * Class responsible for all of the Autofill-related operations on merged cells.
 *
 * @class AutofillCalculations
 * @plugin MergeCells
 * @util
 */
var AutofillCalculations =
/*#__PURE__*/
function () {
  function AutofillCalculations(plugin) {
    (0, _classCallCheck2.default)(this, AutofillCalculations);

    /**
     * Reference to the Merge Cells plugin.
     *
     * @type {MergeCells}
     */
    this.plugin = plugin;
    /**
     * Reference to the MergedCellsCollection class instance.
     *
     * @type {MergedCellsCollection}
     */

    this.mergedCellsCollection = this.plugin.mergedCellsCollection;
    /**
     * Cache of the currently processed autofill data.
     *
     * @private
     * @type {Object}
     */

    this.currentFillData = null;
  }
  /**
   * Correct the provided selection area, so it's not selecting only a part of a merged cell.
   *
   * @param {Array} selectionArea
   */


  (0, _createClass2.default)(AutofillCalculations, [{
    key: "correctSelectionAreaSize",
    value: function correctSelectionAreaSize(selectionArea) {
      if (selectionArea[0] === selectionArea[2] && selectionArea[1] === selectionArea[3]) {
        var mergedCell = this.mergedCellsCollection.get(selectionArea[0], selectionArea[1]);

        if (mergedCell) {
          selectionArea[2] = selectionArea[0] + mergedCell.rowspan - 1;
          selectionArea[3] = selectionArea[1] + mergedCell.colspan - 1;
        }
      }
    }
    /**
     * Get the direction of the autofill process.
     *
     * @param {Array} selectionArea The selection area.
     * @param {Array} finalArea The final area (base + drag).
     * @return {String} `up`, `down`, `left` or `right`.
     */

  }, {
    key: "getDirection",
    value: function getDirection(selectionArea, finalArea) {
      var direction = null;

      if (finalArea[0] === selectionArea[0] && finalArea[1] === selectionArea[1] && finalArea[3] === selectionArea[3]) {
        direction = 'down';
      } else if (finalArea[2] === selectionArea[2] && finalArea[1] === selectionArea[1] && finalArea[3] === selectionArea[3]) {
        direction = 'up';
      } else if (finalArea[1] === selectionArea[1] && finalArea[2] === selectionArea[2]) {
        direction = 'right';
      } else {
        direction = 'left';
      }

      return direction;
    }
    /**
     * Snap the drag area to the farthest merged cell, so it won't clip any of the merged cells.
     *
     * @param {Array} baseArea The base selected area.
     * @param {Array} dragArea The drag area.
     * @param {String} dragDirection The autofill drag direction.
     * @param {Array} foundMergedCells MergeCellCoords found in the base selection area.
     * @return {Array} The new drag area
     */

  }, {
    key: "snapDragArea",
    value: function snapDragArea(baseArea, dragArea, dragDirection, foundMergedCells) {
      var newDragArea = dragArea.slice(0);
      var fillSize = this.getAutofillSize(baseArea, dragArea, dragDirection);

      var _baseArea = (0, _slicedToArray2.default)(baseArea, 4),
          baseAreaStartRow = _baseArea[0],
          baseAreaStartColumn = _baseArea[1],
          baseAreaEndRow = _baseArea[2],
          baseAreaEndColumn = _baseArea[3];

      var verticalDirection = ['up', 'down'].indexOf(dragDirection) > -1;
      var fullCycle = verticalDirection ? baseAreaEndRow - baseAreaStartRow + 1 : baseAreaEndColumn - baseAreaStartColumn + 1;
      var fulls = Math.floor(fillSize / fullCycle) * fullCycle;
      var partials = fillSize - fulls;
      var farthestCollection = this.getFarthestCollection(baseArea, dragArea, dragDirection, foundMergedCells);

      if (farthestCollection) {
        if (dragDirection === 'down') {
          var fill = farthestCollection.row + farthestCollection.rowspan - baseAreaStartRow - partials;
          var newLimit = newDragArea[2] + fill;

          if (newLimit >= this.plugin.hot.countRows()) {
            newDragArea[2] -= partials;
          } else {
            newDragArea[2] += partials ? fill : 0;
          }
        } else if (dragDirection === 'right') {
          var _fill = farthestCollection.col + farthestCollection.colspan - baseAreaStartColumn - partials;

          var _newLimit = newDragArea[3] + _fill;

          if (_newLimit >= this.plugin.hot.countCols()) {
            newDragArea[3] -= partials;
          } else {
            newDragArea[3] += partials ? _fill : 0;
          }
        } else if (dragDirection === 'up') {
          var _fill2 = baseAreaEndRow - partials - farthestCollection.row + 1;

          var _newLimit2 = newDragArea[0] + _fill2;

          if (_newLimit2 < 0) {
            newDragArea[0] += partials;
          } else {
            newDragArea[0] -= partials ? _fill2 : 0;
          }
        } else if (dragDirection === 'left') {
          var _fill3 = baseAreaEndColumn - partials - farthestCollection.col + 1;

          var _newLimit3 = newDragArea[1] + _fill3;

          if (_newLimit3 < 0) {
            newDragArea[1] += partials;
          } else {
            newDragArea[1] -= partials ? _fill3 : 0;
          }
        }
      }

      this.updateCurrentFillCache({
        baseArea: baseArea,
        dragDirection: dragDirection,
        foundMergedCells: foundMergedCells,
        fillSize: fillSize,
        dragArea: newDragArea,
        cycleLength: fullCycle
      });
      return newDragArea;
    }
    /**
     * Update the current fill cache with the provided object.
     *
     * @private
     * @param {Object} updateObject
     */

  }, {
    key: "updateCurrentFillCache",
    value: function updateCurrentFillCache(updateObject) {
      if (!this.currentFillData) {
        this.currentFillData = {};
      }

      (0, _object.extend)(this.currentFillData, updateObject);
    }
    /**
     * Get the "length" of the drag area.
     *
     * @private
     * @param {Array} baseArea The base selection area.
     * @param {Array} dragArea The drag area (containing the base area).
     * @param {String} direction The drag direction.
     * @return {Number|null} The "length" (height or width, depending on the direction) of the drag.
     */

  }, {
    key: "getAutofillSize",
    value: function getAutofillSize(baseArea, dragArea, direction) {
      var _baseArea2 = (0, _slicedToArray2.default)(baseArea, 4),
          baseAreaStartRow = _baseArea2[0],
          baseAreaStartColumn = _baseArea2[1],
          baseAreaEndRow = _baseArea2[2],
          baseAreaEndColumn = _baseArea2[3];

      var _dragArea = (0, _slicedToArray2.default)(dragArea, 4),
          dragAreaStartRow = _dragArea[0],
          dragAreaStartColumn = _dragArea[1],
          dragAreaEndRow = _dragArea[2],
          dragAreaEndColumn = _dragArea[3];

      switch (direction) {
        case 'up':
          return baseAreaStartRow - dragAreaStartRow;

        case 'down':
          return dragAreaEndRow - baseAreaEndRow;

        case 'left':
          return baseAreaStartColumn - dragAreaStartColumn;

        case 'right':
          return dragAreaEndColumn - baseAreaEndColumn;

        default:
          return null;
      }
    }
    /**
     * Trim the default drag area (containing the selection area) to the drag-only area.
     *
     * @private
     * @param {Array} baseArea The base selection area.
     * @param {Array} dragArea The base selection area extended by the drag area.
     * @param {String} direction Drag direction.
     * @return {Array|null} Array representing the drag area coordinates.
     */

  }, {
    key: "getDragArea",
    value: function getDragArea(baseArea, dragArea, direction) {
      var _baseArea3 = (0, _slicedToArray2.default)(baseArea, 4),
          baseAreaStartRow = _baseArea3[0],
          baseAreaStartColumn = _baseArea3[1],
          baseAreaEndRow = _baseArea3[2],
          baseAreaEndColumn = _baseArea3[3];

      var _dragArea2 = (0, _slicedToArray2.default)(dragArea, 4),
          dragAreaStartRow = _dragArea2[0],
          dragAreaStartColumn = _dragArea2[1],
          dragAreaEndRow = _dragArea2[2],
          dragAreaEndColumn = _dragArea2[3];

      switch (direction) {
        case 'up':
          return [dragAreaStartRow, dragAreaStartColumn, baseAreaStartRow - 1, baseAreaEndColumn];

        case 'down':
          return [baseAreaEndRow + 1, baseAreaStartColumn, dragAreaEndRow, baseAreaEndColumn];

        case 'left':
          return [dragAreaStartRow, dragAreaStartColumn, baseAreaEndRow, baseAreaStartColumn - 1];

        case 'right':
          return [baseAreaStartRow, baseAreaEndColumn + 1, dragAreaEndRow, dragAreaEndColumn];

        default:
          return null;
      }
    }
    /**
     * Get the to-be-farthest merged cell in the newly filled area.
     *
     * @private
     * @param {Array} baseArea The base selection area.
     * @param {Array} dragArea The drag area (containing the base area).
     * @param {String} direction The drag direction.
     * @param {Array} mergedCellArray Array of the merged cells found in the base area.
     * @return {MergedCellCoords|null}
     */

  }, {
    key: "getFarthestCollection",
    value: function getFarthestCollection(baseArea, dragArea, direction, mergedCellArray) {
      var _baseArea4 = (0, _slicedToArray2.default)(baseArea, 4),
          baseAreaStartRow = _baseArea4[0],
          baseAreaStartColumn = _baseArea4[1],
          baseAreaEndRow = _baseArea4[2],
          baseAreaEndColumn = _baseArea4[3];

      var verticalDirection = ['up', 'down'].indexOf(direction) > -1;
      var baseEnd = verticalDirection ? baseAreaEndRow : baseAreaEndColumn;
      var baseStart = verticalDirection ? baseAreaStartRow : baseAreaStartColumn;
      var fillSize = this.getAutofillSize(baseArea, dragArea, direction);
      var fullCycle = verticalDirection ? baseAreaEndRow - baseAreaStartRow + 1 : baseAreaEndColumn - baseAreaStartColumn + 1;
      var fulls = Math.floor(fillSize / fullCycle) * fullCycle;
      var partials = fillSize - fulls;
      var inclusionFunctionName = null;
      var farthestCollection = null;
      var endOfDragRecreationIndex = null;

      switch (direction) {
        case 'up':
          inclusionFunctionName = 'includesVertically';
          endOfDragRecreationIndex = baseEnd - partials + 1;
          break;

        case 'left':
          inclusionFunctionName = 'includesHorizontally';
          endOfDragRecreationIndex = baseEnd - partials + 1;
          break;

        case 'down':
          inclusionFunctionName = 'includesVertically';
          endOfDragRecreationIndex = baseStart + partials - 1;
          break;

        case 'right':
          inclusionFunctionName = 'includesHorizontally';
          endOfDragRecreationIndex = baseStart + partials - 1;
          break;

        default:
      }

      (0, _array.arrayEach)(mergedCellArray, function (currentCollection) {
        if (currentCollection[inclusionFunctionName](endOfDragRecreationIndex) && currentCollection.isFarther(farthestCollection, direction)) {
          farthestCollection = currentCollection;
        }
      });
      return farthestCollection;
    }
    /**
     * Recreate the merged cells after the autofill process.
     *
     * @param {Array} changes Changes made.
     */

  }, {
    key: "recreateAfterDataPopulation",
    value: function recreateAfterDataPopulation(changes) {
      if (!this.currentFillData) {
        return;
      }

      var fillRange = this.getRangeFromChanges(changes);
      var foundMergedCells = this.currentFillData.foundMergedCells;
      var dragDirection = this.currentFillData.dragDirection;

      var inBounds = function inBounds(current, offset) {
        switch (dragDirection) {
          case 'up':
            return current.row - offset >= fillRange.from.row;

          case 'down':
            return current.row + current.rowspan - 1 + offset <= fillRange.to.row;

          case 'left':
            return current.col - offset >= fillRange.from.column;

          case 'right':
            return current.col + current.colspan - 1 + offset <= fillRange.to.column;

          default:
            return null;
        }
      };

      var fillOffset = 0;
      var current = null;
      var multiplier = 1;

      do {
        for (var j = 0; j < foundMergedCells.length; j += 1) {
          current = foundMergedCells[j];
          fillOffset = multiplier * this.currentFillData.cycleLength;

          if (inBounds(current, fillOffset)) {
            switch (dragDirection) {
              case 'up':
                this.plugin.mergedCellsCollection.add({
                  row: current.row - fillOffset,
                  rowspan: current.rowspan,
                  col: current.col,
                  colspan: current.colspan
                });
                break;

              case 'down':
                this.plugin.mergedCellsCollection.add({
                  row: current.row + fillOffset,
                  rowspan: current.rowspan,
                  col: current.col,
                  colspan: current.colspan
                });
                break;

              case 'left':
                this.plugin.mergedCellsCollection.add({
                  row: current.row,
                  rowspan: current.rowspan,
                  col: current.col - fillOffset,
                  colspan: current.colspan
                });
                break;

              case 'right':
                this.plugin.mergedCellsCollection.add({
                  row: current.row,
                  rowspan: current.rowspan,
                  col: current.col + fillOffset,
                  colspan: current.colspan
                });
                break;

              default:
            }
          }

          if (j === foundMergedCells.length - 1) {
            multiplier += 1;
          }
        }
      } while (inBounds(current, fillOffset));

      this.currentFillData = null;
      this.plugin.hot.render();
    }
    /**
     * Get the drag range from the changes made.
     *
     * @private
     * @param {Array} changes The changes made.
     * @returns {Object} Object with `from` and `to` properties, both containing `row` and `column` keys.
     */

  }, {
    key: "getRangeFromChanges",
    value: function getRangeFromChanges(changes) {
      var _this = this;

      var rows = {
        min: null,
        max: null
      };
      var columns = {
        min: null,
        max: null
      };
      (0, _array.arrayEach)(changes, function (change) {
        var rowIndex = change[0];

        var columnIndex = _this.plugin.hot.propToCol(change[1]);

        if (rows.min === null || rowIndex < rows.min) {
          rows.min = rowIndex;
        }

        if (rows.max === null || rowIndex > rows.max) {
          rows.max = rowIndex;
        }

        if (columns.min === null || columnIndex < columns.min) {
          columns.min = columnIndex;
        }

        if (columns.max === null || columnIndex > columns.max) {
          columns.max = columnIndex;
        }
      });
      return {
        from: {
          row: rows.min,
          column: columns.min
        },
        to: {
          row: rows.max,
          column: columns.max
        }
      };
    }
    /**
     * Check if the drag area contains any merged cells.
     *
     * @param {Array} baseArea The base selection area.
     * @param {Array} fullArea The base area extended by the drag area.
     * @param {String} direction Drag direction.
     * @returns {Boolean}
     */

  }, {
    key: "dragAreaOverlapsCollections",
    value: function dragAreaOverlapsCollections(baseArea, fullArea, direction) {
      var dragArea = this.getDragArea(baseArea, fullArea, direction);

      var _dragArea3 = (0, _slicedToArray2.default)(dragArea, 4),
          dragAreaStartRow = _dragArea3[0],
          dragAreaStartColumn = _dragArea3[1],
          dragAreaEndRow = _dragArea3[2],
          dragAreaEndColumn = _dragArea3[3];

      var topLeft = new _src.CellCoords(dragAreaStartRow, dragAreaStartColumn);
      var bottomRight = new _src.CellCoords(dragAreaEndRow, dragAreaEndColumn);
      var dragRange = new _src.CellRange(topLeft, topLeft, bottomRight);
      return !!this.mergedCellsCollection.getWithinRange(dragRange, true);
    }
  }]);
  return AutofillCalculations;
}();

var _default = AutofillCalculations;
exports.default = _default;

/***/ }),
/* 671 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(34);

__webpack_require__(39);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _src = __webpack_require__(25);

/**
 * Class responsible for all of the Selection-related operations on merged cells.
 *
 * @class SelectionCalculations
 * @plugin MergeCells
 * @util
 */
var SelectionCalculations =
/*#__PURE__*/
function () {
  function SelectionCalculations(plugin) {
    (0, _classCallCheck2.default)(this, SelectionCalculations);

    /**
     * Reference to the Merge Cells plugin.
     *
     * @type {MergeCells}
     */
    this.plugin = plugin;
    /**
     * Class name used for fully selected merged cells.
     *
     * @type {String}
     */

    this.fullySelectedMergedCellClassName = 'fullySelectedMergedCell';
  }
  /**
   * "Snap" the delta value according to defined merged cells. (In other words, compensate the rowspan -
   * e.g. going up with `delta.row = -1` over a merged cell with `rowspan = 3`, `delta.row` should change to `-3`.)
   *
   * @param {Object} delta The delta object containing `row` and `col` properties.
   * @param {CellRange} selectionRange The selection range.
   * @param {Object} mergedCell A merged cell object.
   */


  (0, _createClass2.default)(SelectionCalculations, [{
    key: "snapDelta",
    value: function snapDelta(delta, selectionRange, mergedCell) {
      var cellCoords = selectionRange.to;
      var newRow = cellCoords.row + delta.row;
      var newColumn = cellCoords.col + delta.col;

      if (delta.row) {
        this.jumpOverMergedCell(delta, mergedCell, newRow);
      } else if (delta.col) {
        this.jumpOverMergedCell(delta, mergedCell, newColumn);
      }
    }
    /**
     * "Jump" over the merged cell (compensate for the indexes within the merged cell to get past it)
     *
     * @private
     * @param {Object} delta The delta object.
     * @param {MergedCellCoords} mergedCell The merge cell object.
     * @param {Number} newIndex New row/column index, created with the delta.
     */

  }, {
    key: "jumpOverMergedCell",
    value: function jumpOverMergedCell(delta, mergedCell, newIndex) {
      var flatDelta = delta.row || delta.col;
      var includesIndex = null;
      var firstIndex = null;
      var lastIndex = null;

      if (delta.row) {
        includesIndex = mergedCell.includesVertically(newIndex);
        firstIndex = mergedCell.row;
        lastIndex = mergedCell.getLastRow();
      } else if (delta.col) {
        includesIndex = mergedCell.includesHorizontally(newIndex);
        firstIndex = mergedCell.col;
        lastIndex = mergedCell.getLastColumn();
      }

      if (flatDelta === 0) {
        return;
      } else if (flatDelta > 0) {
        if (includesIndex && newIndex !== firstIndex) {
          flatDelta += lastIndex - newIndex + 1;
        }
      } else if (includesIndex && newIndex !== lastIndex) {
        flatDelta -= newIndex - firstIndex + 1;
      }

      if (delta.row) {
        delta.row = flatDelta;
      } else if (delta.col) {
        delta.col = flatDelta;
      }
    }
    /**
     * Get a selection range with `to` property incremented by the provided delta.
     *
     * @param {CellRange} oldSelectionRange The base selection range.
     * @param {Object} delta The delta object with `row` and `col` properties.
     * @returns {CellRange} A new `CellRange` object.
     */

  }, {
    key: "getUpdatedSelectionRange",
    value: function getUpdatedSelectionRange(oldSelectionRange, delta) {
      return new _src.CellRange(oldSelectionRange.highlight, oldSelectionRange.from, new _src.CellCoords(oldSelectionRange.to.row + delta.row, oldSelectionRange.to.col + delta.col));
    }
    /**
     * Generate an additional class name for the entirely-selected merged cells.
     *
     * @param {Number} currentRow Row index of the currently processed cell.
     * @param {Number} currentColumn Column index of the currently cell.
     * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
     * @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
     * @returns {String|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
     */

  }, {
    key: "getSelectedMergedCellClassName",
    value: function getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel) {
      var _cornersOfSelection = (0, _slicedToArray2.default)(cornersOfSelection, 4),
          startRow = _cornersOfSelection[0],
          startColumn = _cornersOfSelection[1],
          endRow = _cornersOfSelection[2],
          endColumn = _cornersOfSelection[3];

      if (layerLevel === void 0) {
        return;
      }

      if (currentRow >= startRow && currentRow <= endRow && currentColumn >= startColumn && currentColumn <= endColumn) {
        var isMergedCellParent = this.plugin.mergedCellsCollection.isMergedParent(currentRow, currentColumn);

        if (!isMergedCellParent) {
          return;
        }

        var mergedCell = this.plugin.mergedCellsCollection.get(currentRow, currentColumn);

        if (!mergedCell) {
          return;
        }

        if (mergedCell.row + mergedCell.rowspan - 1 <= endRow && mergedCell.col + mergedCell.colspan - 1 <= endColumn) {
          return "".concat(this.fullySelectedMergedCellClassName, "-").concat(layerLevel);
        } else if (this.plugin.selectionCalculations.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
          return "".concat(this.fullySelectedMergedCellClassName, "-multiple");
        }
      }
    }
    /**
     * Check if the provided merged cell is fully selected (by one or many layers of selection)
     *
     * @param {MergedCellCoords} mergedCell The merged cell to be processed.
     * @param {CellRange[]} selectionRangesArray Array of selection ranges.
     * @returns {Boolean}
     */

  }, {
    key: "isMergeCellFullySelected",
    value: function isMergeCellFullySelected(mergedCell, selectionRangesArray) {
      var mergedCellIndividualCoords = [];

      if (!selectionRangesArray || !mergedCell) {
        return false;
      }

      for (var r = 0; r < mergedCell.rowspan; r += 1) {
        for (var c = 0; c < mergedCell.colspan; c += 1) {
          mergedCellIndividualCoords.push(new _src.CellCoords(mergedCell.row + r, mergedCell.col + c));
        }
      }

      for (var i = 0; i < mergedCellIndividualCoords.length; i += 1) {
        var insideSelections = [];

        for (var s = 0; s < selectionRangesArray.length; s += 1) {
          insideSelections[s] = selectionRangesArray[s].includes(mergedCellIndividualCoords[i]);
        }

        if (!insideSelections.includes(true)) {
          return false;
        }
      }

      return true;
    }
    /**
     * Generate an array of the entirely-selected merged cells' class names.
     *
     * @returns {String[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
     */

  }, {
    key: "getSelectedMergedCellClassNameToRemove",
    value: function getSelectedMergedCellClassNameToRemove() {
      var classNames = [];

      for (var i = 0; i <= 7; i += 1) {
        classNames.push("".concat(this.fullySelectedMergedCellClassName, "-").concat(i));
      }

      classNames.push("".concat(this.fullySelectedMergedCellClassName, "-multiple"));
      return classNames;
    }
  }]);
  return SelectionCalculations;
}();

var _default = SelectionCalculations;
exports.default = _default;

/***/ }),
/* 672 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.default = toggleMergeItem;

var C = _interopRequireWildcard(__webpack_require__(11));

var _cellCoords = _interopRequireDefault(__webpack_require__(168));

function toggleMergeItem(plugin) {
  return {
    key: 'mergeCells',
    name: function name() {
      var sel = this.getSelectedLast();

      if (sel) {
        var info = plugin.mergedCellsCollection.get(sel[0], sel[1]);

        if (info.row === sel[0] && info.col === sel[1] && info.row + info.rowspan - 1 === sel[2] && info.col + info.colspan - 1 === sel[3]) {
          return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_UNMERGE_CELLS);
        }
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_MERGE_CELLS);
    },
    callback: function callback() {
      plugin.toggleMergeOnSelection();
    },
    disabled: function disabled() {
      var sel = this.getSelectedLast();

      if (!sel) {
        return true;
      }

      var isSingleCell = _cellCoords.default.isSingleCell({
        row: sel[0],
        col: sel[1],
        rowspan: sel[2] - sel[0] + 1,
        colspan: sel[3] - sel[1] + 1
      });

      return isSingleCell || this.selection.isSelectedByCorner();
    },
    hidden: false
  };
}

/***/ }),
/* 673 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 674 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(40);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _browser = __webpack_require__(72);

var _base = _interopRequireDefault(__webpack_require__(21));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _src = __webpack_require__(25);

/**
 * @private
 * @plugin MultipleSelectionHandles
 */
var MultipleSelectionHandles =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(MultipleSelectionHandles, _BasePlugin);

  /**
   * @param {Object} hotInstance
   */
  function MultipleSelectionHandles(hotInstance) {
    var _this2;

    (0, _classCallCheck2.default)(this, MultipleSelectionHandles);
    _this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultipleSelectionHandles).call(this, hotInstance));
    /**
     * @type {Array}
     */

    _this2.dragged = [];
    /**
     * Instance of EventManager.
     *
     * @type {EventManager}
     */

    _this2.eventManager = null;
    /**
     * @type {null}
     */

    _this2.lastSetCell = null;
    return _this2;
  }
  /**
   * Check if the plugin is enabled in the handsontable settings.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(MultipleSelectionHandles, [{
    key: "isEnabled",
    value: function isEnabled() {
      return (0, _browser.isMobileBrowser)();
    }
    /**
     * Enable plugin for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      if (this.enabled) {
        return;
      }

      if (!this.eventManager) {
        this.eventManager = new _eventManager.default(this);
      }

      this.registerListeners();
      (0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectionHandles.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Bind the touch events
     * @private
     */

  }, {
    key: "registerListeners",
    value: function registerListeners() {
      var _this3 = this;

      var _this = this;

      var rootElement = this.hot.rootElement;

      function removeFromDragged(query) {
        if (_this.dragged.length === 1) {
          // clear array
          _this.dragged.splice(0, _this.dragged.length);

          return true;
        }

        var entryPosition = _this.dragged.indexOf(query);

        if (entryPosition === -1) {
          return false;
        } else if (entryPosition === 0) {
          _this.dragged = _this.dragged.slice(0, 1);
        } else if (entryPosition === 1) {
          _this.dragged = _this.dragged.slice(-1);
        }
      }

      this.eventManager.addEventListener(rootElement, 'touchstart', function (event) {
        var selectedRange;

        if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
          selectedRange = _this.hot.getSelectedRangeLast();

          _this.dragged.push('topLeft');

          _this.touchStartRange = {
            width: selectedRange.getWidth(),
            height: selectedRange.getHeight(),
            direction: selectedRange.getDirection()
          };
          event.preventDefault();
          return false;
        } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) {
          selectedRange = _this.hot.getSelectedRangeLast();

          _this.dragged.push('bottomRight');

          _this.touchStartRange = {
            width: selectedRange.getWidth(),
            height: selectedRange.getHeight(),
            direction: selectedRange.getDirection()
          };
          event.preventDefault();
          return false;
        }
      });
      this.eventManager.addEventListener(rootElement, 'touchend', function (event) {
        if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
          removeFromDragged.call(_this, 'topLeft');
          _this.touchStartRange = void 0;
          event.preventDefault();
          return false;
        } else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) {
          removeFromDragged.call(_this, 'bottomRight');
          _this.touchStartRange = void 0;
          event.preventDefault();
          return false;
        }
      });
      this.eventManager.addEventListener(rootElement, 'touchmove', function (event) {
        var _this3$hot = _this3.hot,
            rootWindow = _this3$hot.rootWindow,
            rootDocument = _this3$hot.rootDocument;
        var scrollTop = (0, _element.getWindowScrollTop)(rootWindow);
        var scrollLeft = (0, _element.getWindowScrollLeft)(rootWindow);
        var targetCoords;
        var selectedRange;
        var rangeWidth;
        var rangeHeight;
        var rangeDirection;
        var newRangeCoords;

        if (_this.dragged.length === 0) {
          return;
        }

        var endTarget = rootDocument.elementFromPoint(event.touches[0].screenX - scrollLeft, event.touches[0].screenY - scrollTop);

        if (!endTarget || endTarget === _this.lastSetCell) {
          return;
        }

        if (endTarget.nodeName === 'TD' || endTarget.nodeName === 'TH') {
          targetCoords = _this.hot.getCoords(endTarget);

          if (targetCoords.col === -1) {
            targetCoords.col = 0;
          }

          selectedRange = _this.hot.getSelectedRangeLast();
          rangeWidth = selectedRange.getWidth();
          rangeHeight = selectedRange.getHeight();
          rangeDirection = selectedRange.getDirection();

          if (rangeWidth === 1 && rangeHeight === 1) {
            _this.hot.selection.setRangeEnd(targetCoords);
          }

          newRangeCoords = _this.getCurrentRangeCoords(selectedRange, targetCoords, _this.touchStartRange.direction, rangeDirection, _this.dragged[0]);

          if (newRangeCoords.start !== null) {
            _this.hot.selection.setRangeStart(newRangeCoords.start);
          }

          _this.hot.selection.setRangeEnd(newRangeCoords.end);

          _this.lastSetCell = endTarget;
        }

        event.preventDefault();
      });
    }
  }, {
    key: "getCurrentRangeCoords",
    value: function getCurrentRangeCoords(selectedRange, currentTouch, touchStartDirection, currentDirection, draggedHandle) {
      var topLeftCorner = selectedRange.getTopLeftCorner();
      var bottomRightCorner = selectedRange.getBottomRightCorner();
      var bottomLeftCorner = selectedRange.getBottomLeftCorner();
      var topRightCorner = selectedRange.getTopRightCorner();
      var newCoords = {
        start: null,
        end: null
      };

      switch (touchStartDirection) {
        case 'NE-SW':
          switch (currentDirection) {
            case 'NE-SW':
            case 'NW-SE':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: new _src.CellCoords(currentTouch.row, selectedRange.highlight.col),
                  end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col)
                };
              } else {
                newCoords = {
                  start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col),
                  end: new _src.CellCoords(currentTouch.row, topLeftCorner.col)
                };
              }

              break;

            case 'SE-NW':
              if (draggedHandle === 'bottomRight') {
                newCoords = {
                  start: new _src.CellCoords(bottomRightCorner.row, currentTouch.col),
                  end: new _src.CellCoords(currentTouch.row, topLeftCorner.col)
                };
              }

              break;

            default:
              break;
          }

          break;

        case 'NW-SE':
          switch (currentDirection) {
            case 'NE-SW':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: currentTouch,
                  end: bottomLeftCorner
                };
              } else {
                newCoords.end = currentTouch;
              }

              break;

            case 'NW-SE':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: currentTouch,
                  end: bottomRightCorner
                };
              } else {
                newCoords.end = currentTouch;
              }

              break;

            case 'SE-NW':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: currentTouch,
                  end: topLeftCorner
                };
              } else {
                newCoords.end = currentTouch;
              }

              break;

            case 'SW-NE':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: currentTouch,
                  end: topRightCorner
                };
              } else {
                newCoords.end = currentTouch;
              }

              break;

            default:
              break;
          }

          break;

        case 'SW-NE':
          switch (currentDirection) {
            case 'NW-SE':
              if (draggedHandle === 'bottomRight') {
                newCoords = {
                  start: new _src.CellCoords(currentTouch.row, topLeftCorner.col),
                  end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col)
                };
              } else {
                newCoords = {
                  start: new _src.CellCoords(topLeftCorner.row, currentTouch.col),
                  end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col)
                };
              }

              break;
            // case 'NE-SW':
            //
            //  break;

            case 'SW-NE':
              if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col),
                  end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col)
                };
              } else {
                newCoords = {
                  start: new _src.CellCoords(currentTouch.row, topLeftCorner.col),
                  end: new _src.CellCoords(topLeftCorner.row, currentTouch.col)
                };
              }

              break;

            case 'SE-NW':
              if (draggedHandle === 'bottomRight') {
                newCoords = {
                  start: new _src.CellCoords(currentTouch.row, topRightCorner.col),
                  end: new _src.CellCoords(topLeftCorner.row, currentTouch.col)
                };
              } else if (draggedHandle === 'topLeft') {
                newCoords = {
                  start: bottomLeftCorner,
                  end: currentTouch
                };
              }

              break;

            default:
              break;
          }

          break;

        case 'SE-NW':
          switch (currentDirection) {
            case 'NW-SE':
            case 'NE-SW':
            case 'SW-NE':
              if (draggedHandle === 'topLeft') {
                newCoords.end = currentTouch;
              }

              break;

            case 'SE-NW':
              if (draggedHandle === 'topLeft') {
                newCoords.end = currentTouch;
              } else {
                newCoords = {
                  start: currentTouch,
                  end: topLeftCorner
                };
              }

              break;

            default:
              break;
          }

          break;

        default:
          break;
      }

      return newCoords;
    }
    /**
     * Check if user is currently dragging the handle.
     *
     * @returns {boolean} Dragging state
     */

  }, {
    key: "isDragged",
    value: function isDragged() {
      return this.dragged.length > 0;
    }
  }]);
  return MultipleSelectionHandles;
}(_base.default);

(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles);
var _default = MultipleSelectionHandles;
exports.default = _default;

/***/ }),
/* 675 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _dataObserver = _interopRequireDefault(__webpack_require__(676));

var _array = __webpack_require__(3);

var _plugins = __webpack_require__(20);

// Handsontable.hooks.register('afterChangesObserved');

/**
 * @plugin ObserveChanges
 *
 * @description
 * This plugin allows to observe data source changes. By default, the plugin is declared as `undefined`, which makes it
 * disabled. Enabling this plugin switches the table into one-way data binding where changes are applied into the data
 * source (outside from the table) will be automatically reflected in the table.
 *
 * ```js
 * // as a boolean
 * observeChanges: true,
 * ```
 *
 * To configure this plugin see {@link Options#observeChanges}.
 */
var ObserveChanges =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ObserveChanges, _BasePlugin);

  function ObserveChanges(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ObserveChanges);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ObserveChanges).call(this, hotInstance));
    /**
     * Instance of {@link DataObserver}.
     *
     * @private
     * @type {DataObserver}
     */

    _this.observer = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ObserveChanges#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ObserveChanges, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().observeChanges;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      if (!this.observer) {
        this.observer = new _dataObserver.default(this.hot.getSourceData());

        this._exposePublicApi();
      }

      this.observer.addLocalHook('change', function (patches) {
        return _this2.onDataChange(patches);
      });
      this.addHook('afterCreateRow', function () {
        return _this2.onAfterTableAlter();
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterTableAlter();
      });
      this.addHook('afterCreateCol', function () {
        return _this2.onAfterTableAlter();
      });
      this.addHook('afterRemoveCol', function () {
        return _this2.onAfterTableAlter();
      });
      this.addHook('afterChange', function (changes, source) {
        return _this2.onAfterTableAlter(source);
      });
      this.addHook('afterLoadData', function (firstRun) {
        return _this2.onAfterLoadData(firstRun);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      if (this.observer) {
        this.observer.destroy();
        this.observer = null;

        this._deletePublicApi();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Data change observer.
     *
     * @private
     * @param {Array} patches An array of objects which every item defines coordinates where data was changed.
     */

  }, {
    key: "onDataChange",
    value: function onDataChange(patches) {
      var _this3 = this;

      if (!this.observer.isPaused()) {
        var sourceName = "".concat(this.pluginName, ".change");
        var actions = {
          add: function add(patch) {
            if (isNaN(patch.col)) {
              _this3.hot.runHooks('afterCreateRow', patch.row, 1, sourceName);
            } else {
              _this3.hot.runHooks('afterCreateCol', patch.col, 1, sourceName);
            }
          },
          remove: function remove(patch) {
            if (isNaN(patch.col)) {
              _this3.hot.runHooks('afterRemoveRow', patch.row, 1, sourceName);
            } else {
              _this3.hot.runHooks('afterRemoveCol', patch.col, 1, sourceName);
            }
          },
          replace: function replace(patch) {
            _this3.hot.runHooks('afterChange', [[patch.row, patch.col, null, patch.value]], sourceName);
          }
        };
        (0, _array.arrayEach)(patches, function (patch) {
          if (actions[patch.op]) {
            actions[patch.op](patch);
          }
        });
        this.hot.render();
      }

      this.hot.runHooks('afterChangesObserved');
    }
    /**
     * On after table alter listener. Prevents infinity loop between internal and external data changing.
     *
     * @private
     * @param source
     */

  }, {
    key: "onAfterTableAlter",
    value: function onAfterTableAlter(source) {
      var _this4 = this;

      if (source !== 'loadData') {
        this.observer.pause();
        this.hot.addHookOnce('afterChangesObserved', function () {
          return _this4.observer.resume();
        });
      }
    }
    /**
     * On after load data listener.
     *
     * @private
     * @param {Boolean} firstRun `true` if event was fired first time.
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData(firstRun) {
      if (!firstRun) {
        this.observer.setObservedData(this.hot.getSourceData());
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.observer) {
        this.observer.destroy();

        this._deletePublicApi();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "destroy", this).call(this);
    }
    /**
     * Expose plugins methods to the core.
     *
     * @private
     */

  }, {
    key: "_exposePublicApi",
    value: function _exposePublicApi() {
      var _this5 = this;

      var hot = this.hot;

      hot.pauseObservingChanges = function () {
        return _this5.observer.pause();
      };

      hot.resumeObservingChanges = function () {
        return _this5.observer.resume();
      };

      hot.isPausedObservingChanges = function () {
        return _this5.observer.isPaused();
      };
    }
    /**
     * Deletes all previously exposed methods.
     *
     * @private
     */

  }, {
    key: "_deletePublicApi",
    value: function _deletePublicApi() {
      var hot = this.hot;
      delete hot.pauseObservingChanges;
      delete hot.resumeObservingChanges;
      delete hot.isPausedObservingChanges;
    }
  }]);
  return ObserveChanges;
}(_base.default);

var _default = ObserveChanges;
exports.default = _default;
(0, _plugins.registerPlugin)('observeChanges', ObserveChanges);

/***/ }),
/* 676 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _jsonPatchDuplex = _interopRequireDefault(__webpack_require__(677));

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _object = __webpack_require__(4);

var _utils = __webpack_require__(678);

/**
 * @class DataObserver
 * @plugin ObserveChanges
 */
var DataObserver =
/*#__PURE__*/
function () {
  function DataObserver(observedData) {
    (0, _classCallCheck2.default)(this, DataObserver);

    /**
     * Observed source data.
     *
     * @type {Array}
     */
    this.observedData = null;
    /**
     * JsonPatch observer.
     *
     * @type {Object}
     */

    this.observer = null;
    /**
     * Flag which determines if observer is paused or not. Paused observer doesn't emit `change` hooks.
     *
     * @type {Boolean}
     * @default false
     */

    this.paused = false;
    this.setObservedData(observedData);
  }
  /**
   * Set data to observe.
   *
   * @param {*} observedData
   */


  (0, _createClass2.default)(DataObserver, [{
    key: "setObservedData",
    value: function setObservedData(observedData) {
      var _this = this;

      if (this.observer) {
        _jsonPatchDuplex.default.unobserve(this.observedData, this.observer);
      }

      this.observedData = observedData;
      this.observer = _jsonPatchDuplex.default.observe(this.observedData, function (patches) {
        return _this.onChange(patches);
      });
    }
    /**
     * Check if observer was paused.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isPaused",
    value: function isPaused() {
      return this.paused;
    }
    /**
     * Pause observer (stop emitting all detected changes).
     */

  }, {
    key: "pause",
    value: function pause() {
      this.paused = true;
    }
    /**
     * Resume observer (emit all detected changes).
     */

  }, {
    key: "resume",
    value: function resume() {
      this.paused = false;
    }
    /**
     * JsonPatch on change listener.
     *
     * @private
     * @param {Array} patches An array of object passed from jsonpatch.
     */

  }, {
    key: "onChange",
    value: function onChange(patches) {
      this.runLocalHooks('change', (0, _utils.cleanPatches)(patches));
    }
    /**
     * Destroy observer instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      _jsonPatchDuplex.default.unobserve(this.observedData, this.observer);

      this.observedData = null;
      this.observer = null;
    }
  }]);
  return DataObserver;
}();

(0, _object.mixin)(DataObserver, _localHooks.default);
var _default = DataObserver;
exports.default = _default;

/***/ }),
/* 677 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(54);

__webpack_require__(40);

__webpack_require__(33);

__webpack_require__(51);

__webpack_require__(76);

__webpack_require__(37);

__webpack_require__(46);

__webpack_require__(30);

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

/*!
 * https://github.com/Starcounter-Jack/JSON-Patch
 * json-patch-duplex.js version: 0.5.7
 * (c) 2013 Joachim Wester
 * MIT license
 */
var __extends = void 0 && (void 0).__extends || function (d, b) {
  for (var p in b) {
    if (b.hasOwnProperty(p)) d[p] = b[p];
  }

  function __() {
    this.constructor = d;
  }

  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

var OriginalError = Error;
var jsonpatch;

(function (jsonpatch) {
  var _objectKeys = function _objectKeys(obj) {
    if (_isArray(obj)) {
      var keys = new Array(obj.length);

      for (var k = 0; k < keys.length; k++) {
        keys[k] = "" + k;
      }

      return keys;
    }

    if (Object.keys) {
      return Object.keys(obj);
    }

    var keys = [];

    for (var i in obj) {
      if (obj.hasOwnProperty(i)) {
        keys.push(i);
      }
    }

    return keys;
  };

  function _equals(a, b) {
    switch ((0, _typeof2.default)(a)) {
      case 'undefined': //backward compatibility, but really I think we should return false

      case 'boolean':
      case 'string':
      case 'number':
        return a === b;

      case 'object':
        if (a === null) return b === null;

        if (_isArray(a)) {
          if (!_isArray(b) || a.length !== b.length) return false;

          for (var i = 0, l = a.length; i < l; i++) {
            if (!_equals(a[i], b[i])) return false;
          }

          return true;
        }

        var bKeys = _objectKeys(b);

        var bLength = bKeys.length;
        if (_objectKeys(a).length !== bLength) return false;

        for (var i = 0; i < bLength; i++) {
          if (!_equals(a[i], b[i])) return false;
        }

        return true;

      default:
        return false;
    }
  }
  /* We use a Javascript hash to store each
   function. Each hash entry (property) uses
   the operation identifiers specified in rfc6902.
   In this way, we can map each patch operation
   to its dedicated function in efficient way.
   */

  /* The operations applicable to an object */


  var objOps = {
    add: function add(obj, key) {
      obj[key] = this.value;
      return true;
    },
    remove: function remove(obj, key) {
      delete obj[key];
      return true;
    },
    replace: function replace(obj, key) {
      obj[key] = this.value;
      return true;
    },
    move: function move(obj, key, tree) {
      var temp = {
        op: "_get",
        path: this.from
      };
      apply(tree, [temp]);
      apply(tree, [{
        op: "remove",
        path: this.from
      }]);
      apply(tree, [{
        op: "add",
        path: this.path,
        value: temp.value
      }]);
      return true;
    },
    copy: function copy(obj, key, tree) {
      var temp = {
        op: "_get",
        path: this.from
      };
      apply(tree, [temp]);
      apply(tree, [{
        op: "add",
        path: this.path,
        value: temp.value
      }]);
      return true;
    },
    test: function test(obj, key) {
      return _equals(obj[key], this.value);
    },
    _get: function _get(obj, key) {
      this.value = obj[key];
    }
  };
  /* The operations applicable to an array. Many are the same as for the object */

  var arrOps = {
    add: function add(arr, i) {
      arr.splice(i, 0, this.value);
      return true;
    },
    remove: function remove(arr, i) {
      arr.splice(i, 1);
      return true;
    },
    replace: function replace(arr, i) {
      arr[i] = this.value;
      return true;
    },
    move: objOps.move,
    copy: objOps.copy,
    test: objOps.test,
    _get: objOps._get
  };
  /* The operations applicable to object root. Many are the same as for the object */

  var rootOps = {
    add: function add(obj) {
      rootOps.remove.call(this, obj);

      for (var key in this.value) {
        if (this.value.hasOwnProperty(key)) {
          obj[key] = this.value[key];
        }
      }

      return true;
    },
    remove: function remove(obj) {
      for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
          objOps.remove.call(this, obj, key);
        }
      }

      return true;
    },
    replace: function replace(obj) {
      apply(obj, [{
        op: "remove",
        path: this.path
      }]);
      apply(obj, [{
        op: "add",
        path: this.path,
        value: this.value
      }]);
      return true;
    },
    move: objOps.move,
    copy: objOps.copy,
    test: function test(obj) {
      return JSON.stringify(obj) === JSON.stringify(this.value);
    },
    _get: function _get(obj) {
      this.value = obj;
    }
  };
  var observeOps = {
    add: function add(patches, path) {
      var patch = {
        op: "add",
        path: path + escapePathComponent(this.name),
        value: this.object[this.name]
      };
      patches.push(patch);
    },
    'delete': function _delete(patches, path) {
      var patch = {
        op: "remove",
        path: path + escapePathComponent(this.name)
      };
      patches.push(patch);
    },
    update: function update(patches, path) {
      var patch = {
        op: "replace",
        path: path + escapePathComponent(this.name),
        value: this.object[this.name]
      };
      patches.push(patch);
    }
  };

  function escapePathComponent(str) {
    if (str.indexOf('/') === -1 && str.indexOf('~') === -1) return str;
    return str.replace(/~/g, '~0').replace(/\//g, '~1');
  }

  function _getPathRecursive(root, obj) {
    var found;

    for (var key in root) {
      if (root.hasOwnProperty(key)) {
        if (root[key] === obj) {
          return escapePathComponent(key) + '/';
        } else if ((0, _typeof2.default)(root[key]) === 'object') {
          found = _getPathRecursive(root[key], obj);

          if (found != '') {
            return escapePathComponent(key) + '/' + found;
          }
        }
      }
    }

    return '';
  }

  function getPath(root, obj) {
    if (root === obj) {
      return '/';
    }

    var path = _getPathRecursive(root, obj);

    if (path === '') {
      throw new OriginalError("Object not found in root");
    }

    return '/' + path;
  }

  var beforeDict = [];

  var Mirror = function () {
    function Mirror(obj) {
      this.observers = [];
      this.obj = obj;
    }

    return Mirror;
  }();

  var ObserverInfo = function () {
    function ObserverInfo(callback, observer) {
      this.callback = callback;
      this.observer = observer;
    }

    return ObserverInfo;
  }();

  function getMirror(obj) {
    for (var i = 0, ilen = beforeDict.length; i < ilen; i++) {
      if (beforeDict[i].obj === obj) {
        return beforeDict[i];
      }
    }
  }

  function getObserverFromMirror(mirror, callback) {
    for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) {
      if (mirror.observers[j].callback === callback) {
        return mirror.observers[j].observer;
      }
    }
  }

  function removeObserverFromMirror(mirror, observer) {
    for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) {
      if (mirror.observers[j].observer === observer) {
        mirror.observers.splice(j, 1);
        return;
      }
    }
  }

  function unobserve(root, observer) {
    observer.unobserve();
  }

  jsonpatch.unobserve = unobserve;

  function deepClone(obj) {
    if ((0, _typeof2.default)(obj) === "object") {
      return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
    } else {
      return obj; //no need to clone primitives
    }
  }

  function observe(obj, callback) {
    var patches = [];
    var root = obj;
    var observer;
    var mirror = getMirror(obj);

    if (!mirror) {
      mirror = new Mirror(obj);
      beforeDict.push(mirror);
    } else {
      observer = getObserverFromMirror(mirror, callback);
    }

    if (observer) {
      return observer;
    }

    observer = {};
    mirror.value = deepClone(obj);

    if (callback) {
      observer.callback = callback;
      observer.next = null;
      var intervals = this.intervals || [100, 1000, 10000, 60000];

      if (intervals.push === void 0) {
        throw new OriginalError("jsonpatch.intervals must be an array");
      }

      var currentInterval = 0;

      var dirtyCheck = function dirtyCheck() {
        generate(observer);
      };

      var fastCheck = function fastCheck() {
        clearTimeout(observer.next);
        observer.next = setTimeout(function () {
          dirtyCheck();
          currentInterval = 0;
          observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
        }, 0);
      };

      var slowCheck = function slowCheck() {
        dirtyCheck();
        if (currentInterval == intervals.length) currentInterval = intervals.length - 1;
        observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
      };

      if (typeof window !== 'undefined') {
        if (window.addEventListener) {
          window.addEventListener('mousedown', fastCheck);
          window.addEventListener('mouseup', fastCheck);
          window.addEventListener('keydown', fastCheck);
        } else {
          document.documentElement.attachEvent('onmousedown', fastCheck);
          document.documentElement.attachEvent('onmouseup', fastCheck);
          document.documentElement.attachEvent('onkeydown', fastCheck);
        }
      }

      observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
    }

    observer.patches = patches;
    observer.object = obj;

    observer.unobserve = function () {
      generate(observer);
      clearTimeout(observer.next);
      removeObserverFromMirror(mirror, observer);

      if (mirror.observers.length === 0) {
        beforeDict.splice(beforeDict.indexOf(mirror), 1);
      }

      if (typeof window !== 'undefined') {
        if (window.removeEventListener) {
          window.removeEventListener('mousedown', fastCheck);
          window.removeEventListener('mouseup', fastCheck);
          window.removeEventListener('keydown', fastCheck);
        } else {
          document.documentElement.detachEvent('onmousedown', fastCheck);
          document.documentElement.detachEvent('onmouseup', fastCheck);
          document.documentElement.detachEvent('onkeydown', fastCheck);
        }
      }
    };

    mirror.observers.push(new ObserverInfo(callback, observer));
    return observer;
  }

  jsonpatch.observe = observe;

  function generate(observer) {
    var mirror;

    for (var i = 0, ilen = beforeDict.length; i < ilen; i++) {
      if (beforeDict[i].obj === observer.object) {
        mirror = beforeDict[i];
        break;
      }
    }

    _generate(mirror.value, observer.object, observer.patches, "");

    if (observer.patches.length) {
      apply(mirror.value, observer.patches);
    }

    var temp = observer.patches;

    if (temp.length > 0) {
      observer.patches = [];

      if (observer.callback) {
        observer.callback(temp);
      }
    }

    return temp;
  }

  jsonpatch.generate = generate; // Dirty check if obj is different from mirror, generate patches and update mirror

  function _generate(mirror, obj, patches, path) {
    var newKeys = _objectKeys(obj);

    var oldKeys = _objectKeys(mirror);

    var changed = false;
    var deleted = false; //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"

    for (var t = oldKeys.length - 1; t >= 0; t--) {
      var key = oldKeys[t];
      var oldVal = mirror[key];

      if (obj.hasOwnProperty(key)) {
        var newVal = obj[key];

        if ((0, _typeof2.default)(oldVal) == "object" && oldVal != null && (0, _typeof2.default)(newVal) == "object" && newVal != null) {
          _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key));
        } else {
          if (oldVal != newVal) {
            changed = true;
            patches.push({
              op: "replace",
              path: path + "/" + escapePathComponent(key),
              value: deepClone(newVal)
            });
          }
        }
      } else {
        patches.push({
          op: "remove",
          path: path + "/" + escapePathComponent(key)
        });
        deleted = true; // property has been deleted
      }
    }

    if (!deleted && newKeys.length == oldKeys.length) {
      return;
    }

    for (var t = 0; t < newKeys.length; t++) {
      var key = newKeys[t];

      if (!mirror.hasOwnProperty(key)) {
        patches.push({
          op: "add",
          path: path + "/" + escapePathComponent(key),
          value: deepClone(obj[key])
        });
      }
    }
  }

  var _isArray;

  if (Array.isArray) {
    _isArray = Array.isArray;
  } else {
    _isArray = function _isArray(obj) {
      return obj.push && typeof obj.length === 'number';
    };
  } //3x faster than cached /^\d+$/.test(str)


  function isInteger(str) {
    var i = 0;
    var len = str.length;
    var charCode;

    while (i < len) {
      charCode = str.charCodeAt(i);

      if (charCode >= 48 && charCode <= 57) {
        i++;
        continue;
      }

      return false;
    }

    return true;
  } /// Apply a json-patch operation on an object tree


  function apply(tree, patches, validate) {
    var result = false,
        p = 0,
        plen = patches.length,
        patch,
        key;

    while (p < plen) {
      patch = patches[p];
      p++; // Find the object

      var path = patch.path || "";
      var keys = path.split('/');
      var obj = tree;
      var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift

      var len = keys.length;
      var existingPathFragment = undefined;

      while (true) {
        key = keys[t];

        if (validate) {
          if (existingPathFragment === undefined) {
            if (obj[key] === undefined) {
              existingPathFragment = keys.slice(0, t).join('/');
            } else if (t == len - 1) {
              existingPathFragment = patch.path;
            }

            if (existingPathFragment !== undefined) {
              this.validator(patch, p - 1, tree, existingPathFragment);
            }
          }
        }

        t++;

        if (key === undefined) {
          if (t >= len) {
            result = rootOps[patch.op].call(patch, obj, key, tree); // Apply patch

            break;
          }
        }

        if (_isArray(obj)) {
          if (key === '-') {
            key = obj.length;
          } else {
            if (validate && !isInteger(key)) {
              throw new JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", p - 1, patch.path, patch);
            }

            key = parseInt(key, 10);
          }

          if (t >= len) {
            if (validate && patch.op === "add" && key > obj.length) {
              throw new JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", p - 1, patch.path, patch);
            }

            result = arrOps[patch.op].call(patch, obj, key, tree); // Apply patch

            break;
          }
        } else {
          if (key && key.indexOf('~') != -1) key = key.replace(/~1/g, '/').replace(/~0/g, '~'); // escape chars

          if (t >= len) {
            result = objOps[patch.op].call(patch, obj, key, tree); // Apply patch

            break;
          }
        }

        obj = obj[key];
      }
    }

    return result;
  }

  jsonpatch.apply = apply;

  function compare(tree1, tree2) {
    var patches = [];

    _generate(tree1, tree2, patches, '');

    return patches;
  }

  jsonpatch.compare = compare;

  var JsonPatchError = function (_super) {
    __extends(JsonPatchError, _super);

    function JsonPatchError(message, name, index, operation, tree) {
      _super.call(this, message);

      this.message = message;
      this.name = name;
      this.index = index;
      this.operation = operation;
      this.tree = tree;
    }

    return JsonPatchError;
  }(OriginalError);

  jsonpatch.JsonPatchError = JsonPatchError;
  jsonpatch.Error = JsonPatchError;
  /**
   * Recursively checks whether an object has any undefined values inside.
   */

  function hasUndefined(obj) {
    if (obj === undefined) {
      return true;
    }

    if (typeof obj == "array" || (0, _typeof2.default)(obj) == "object") {
      for (var i in obj) {
        if (hasUndefined(obj[i])) {
          return true;
        }
      }
    }

    return false;
  }
  /**
   * Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
   * @param {object} operation - operation object (patch)
   * @param {number} index - index of operation in the sequence
   * @param {object} [tree] - object where the operation is supposed to be applied
   * @param {string} [existingPathFragment] - comes along with `tree`
   */


  function validator(operation, index, tree, existingPathFragment) {
    if ((0, _typeof2.default)(operation) !== 'object' || operation === null || _isArray(operation)) {
      throw new JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, tree);
    } else if (!objOps[operation.op]) {
      throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, tree);
    } else if (typeof operation.path !== 'string') {
      throw new JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, tree);
    } else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {
      throw new JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, tree);
    } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {
      throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, tree);
    } else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && hasUndefined(operation.value)) {
      throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, tree);
    } else if (tree) {
      if (operation.op == "add") {
        var pathLen = operation.path.split("/").length;
        var existingPathLen = existingPathFragment.split("/").length;

        if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
          throw new JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, tree);
        }
      } else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {
        if (operation.path !== existingPathFragment) {
          throw new JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, tree);
        }
      } else if (operation.op === 'move' || operation.op === 'copy') {
        var existingValue = {
          op: "_get",
          path: operation.from,
          value: undefined
        };
        var error = jsonpatch.validate([existingValue], tree);

        if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {
          throw new JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, tree);
        }
      }
    }
  }

  jsonpatch.validator = validator;
  /**
   * Validates a sequence of operations. If `tree` parameter is provided, the sequence is additionally validated against the object tree.
   * If error is encountered, returns a JsonPatchError object
   * @param sequence
   * @param tree
   * @returns {JsonPatchError|undefined}
   */

  function validate(sequence, tree) {
    try {
      if (!_isArray(sequence)) {
        throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
      }

      if (tree) {
        tree = JSON.parse(JSON.stringify(tree)); //clone tree so that we can safely try applying operations

        apply.call(this, tree, sequence, true);
      } else {
        for (var i = 0; i < sequence.length; i++) {
          this.validator(sequence[i], i);
        }
      }
    } catch (e) {
      if (e instanceof JsonPatchError) {
        return e;
      } else {
        throw e;
      }
    }
  }

  jsonpatch.validate = validate;
})(jsonpatch || (jsonpatch = {}));

if (true) {
  exports.apply = jsonpatch.apply;
  exports.observe = jsonpatch.observe;
  exports.unobserve = jsonpatch.unobserve;
  exports.generate = jsonpatch.generate;
  exports.compare = jsonpatch.compare;
  exports.validate = jsonpatch.validate;
  exports.validator = jsonpatch.validator;
  exports.JsonPatchError = jsonpatch.JsonPatchError;
  exports.Error = jsonpatch.Error;
}

/***/ }),
/* 678 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(131);

exports.__esModule = true;
exports.cleanPatches = cleanPatches;
exports.parsePath = parsePath;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _array = __webpack_require__(3);

/**
 * Clean and extend patches from jsonpatch observer.
 *
 * @param {Array} patches
 * @returns {Array}
 */
function cleanPatches(patches) {
  var newOrRemovedColumns = [];
  /**
   * If observeChanges uses native Object.observe method, then it produces patches for length property. Filter them.
   * If path can't be parsed. Filter it.
   */

  var cleanedPatches = (0, _array.arrayFilter)(patches, function (patch) {
    if (/[/]length/ig.test(patch.path)) {
      return false;
    }

    if (!parsePath(patch.path)) {
      return false;
    }

    return true;
  });
  /**
   * Extend patches with changed cells coords
   */

  cleanedPatches = (0, _array.arrayMap)(cleanedPatches, function (patch) {
    var coords = parsePath(patch.path);
    patch.row = coords.row;
    patch.col = coords.col;
    return patch;
  });
  /**
   * Removing or adding column will produce one patch for each table row.
   * Leaves only one patch for each column add/remove operation.
   */

  cleanedPatches = (0, _array.arrayFilter)(cleanedPatches, function (patch) {
    if (['add', 'remove'].indexOf(patch.op) !== -1 && !isNaN(patch.col)) {
      if (newOrRemovedColumns.indexOf(patch.col) !== -1) {
        return false;
      }

      newOrRemovedColumns.push(patch.col);
    }

    return true;
  });
  newOrRemovedColumns.length = 0;
  return cleanedPatches;
}
/**
 * Extract coordinates from path where data was changed.
 *
 * @param {String} path Path describing where data was changed.
 * @returns {Object|null} Returns an object with `row` and `col` properties or `null` if path doesn't have necessary information.
 */


function parsePath(path) {
  var match = path.match(/^\/(\d+)\/?(.*)?$/);

  if (!match) {
    return null;
  }

  var _match = (0, _slicedToArray2.default)(match, 3),
      row = _match[1],
      column = _match[2];

  return {
    row: parseInt(row, 10),
    col: /^\d*$/.test(column) ? parseInt(column, 10) : column
  };
}

/***/ }),
/* 679 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(54);

__webpack_require__(33);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(39);

__webpack_require__(467);

__webpack_require__(46);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

var _mixed = __webpack_require__(27);

var DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult';

var DEFAULT_CALLBACK = function DEFAULT_CALLBACK(instance, row, col, data, testResult) {
  instance.getCellMeta(row, col).isSearchResult = testResult;
};

var DEFAULT_QUERY_METHOD = function DEFAULT_QUERY_METHOD(query, value) {
  if ((0, _mixed.isUndefined)(query) || query === null || !query.toLowerCase || query.length === 0) {
    return false;
  }

  if ((0, _mixed.isUndefined)(value) || value === null) {
    return false;
  }

  return value.toString().toLowerCase().indexOf(query.toLowerCase()) !== -1;
};
/**
 * @plugin Search
 *
 * @description
 * The search plugin provides an easy interface to search data across Handsontable.
 *
 * In order to enable search mechanism, {@link Options#search} option must be set to `true`.
 *
 * @example
 * ```js
 * // as boolean
 * search: true
 * // as a object with one or more options
 * search: {
 *   callback: myNewCallbackFunction,
 *   queryMethod: myNewQueryMethod,
 *   searchResultClass: 'customClass'
 * }
 *
 * // Access to search plugin instance:
 * const searchPlugin = hot.getPlugin('search');
 *
 * // Set callback programmatically:
 * searchPlugin.setCallback(myNewCallbackFunction);
 * // Set query method programmatically:
 * searchPlugin.setQueryMethod(myNewQueryMethod);
 * // Set search result cells class programmatically:
 * searchPlugin.setSearchResultClass(customClass);
 * ```
 */


var Search =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(Search, _BasePlugin);

  function Search(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, Search);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Search).call(this, hotInstance));
    /**
     * Function called during querying for each cell from the {@link DataMap}.
     *
     * @private
     * @type {Function}
     */

    _this.callback = DEFAULT_CALLBACK;
    /**
     * Query function is responsible for determining whether a query matches the value stored in a cell.
     *
     * @private
     * @type {Function}
     */

    _this.queryMethod = DEFAULT_QUERY_METHOD;
    /**
     * Class name added to each cell that belongs to the searched query.
     *
     * @private
     * @type {String}
     */

    _this.searchResultClass = DEFAULT_SEARCH_RESULT_CLASS;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link AutoRowSize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Search, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().search;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var searchSettings = this.hot.getSettings().search;
      this.updatePluginSettings(searchSettings);
      this.addHook('beforeRenderer', function () {
        return _this2.onBeforeRenderer.apply(_this2, arguments);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      var _this3 = this;

      var beforeRendererCallback = function beforeRendererCallback() {
        return _this3.onBeforeRenderer.apply(_this3, arguments);
      };

      this.hot.addHook('beforeRenderer', beforeRendererCallback);
      this.hot.addHookOnce('afterRender', function () {
        _this3.hot.removeHook('beforeRenderer', beforeRendererCallback);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Makes the query.
     *
     * @param {String} queryStr Value to be search.
     * @param {Function} [callback] Callback function performed on cells with values which matches to the searched query.
     * @param {Function} [queryMethod] Query function responsible for determining whether a query matches the value stored in a cell.
     * @returns {Object[]} Return an array of objects with `row`, `col`, `data` properties or empty array.
     */

  }, {
    key: "query",
    value: function query(queryStr) {
      var _this4 = this;

      var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getCallback();
      var queryMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getQueryMethod();
      var rowCount = this.hot.countRows();
      var colCount = this.hot.countCols();
      var queryResult = [];
      var instance = this.hot;
      (0, _number.rangeEach)(0, rowCount - 1, function (rowIndex) {
        (0, _number.rangeEach)(0, colCount - 1, function (colIndex) {
          var cellData = _this4.hot.getDataAtCell(rowIndex, colIndex);

          var cellProperties = _this4.hot.getCellMeta(rowIndex, colIndex);

          var cellCallback = cellProperties.search.callback || callback;
          var cellQueryMethod = cellProperties.search.queryMethod || queryMethod;
          var testResult = cellQueryMethod(queryStr, cellData);

          if (testResult) {
            var singleResult = {
              row: rowIndex,
              col: colIndex,
              data: cellData
            };
            queryResult.push(singleResult);
          }

          if (cellCallback) {
            cellCallback(instance, rowIndex, colIndex, cellData, testResult);
          }
        });
      });
      return queryResult;
    }
    /**
     * Gets the callback function.
     *
     * @returns {Function} Return the callback function.
     */

  }, {
    key: "getCallback",
    value: function getCallback() {
      return this.callback;
    }
    /**
     * Sets the callback function. This function will be called during querying for each cell.
     *
     * @param {Function} newCallback
     */

  }, {
    key: "setCallback",
    value: function setCallback(newCallback) {
      this.callback = newCallback;
    }
    /**
     * Gets the query method function.
     *
     * @returns {Function} Return the query method.
     */

  }, {
    key: "getQueryMethod",
    value: function getQueryMethod() {
      return this.queryMethod;
    }
    /**
     * Sets the query method function. The function is responsible for determining whether a query matches the value stored in a cell.
     *
     * @param {Function} newQueryMethod
     */

  }, {
    key: "setQueryMethod",
    value: function setQueryMethod(newQueryMethod) {
      this.queryMethod = newQueryMethod;
    }
    /**
     * Gets search result cells class name.
     *
     * @returns {String} Return the cell class name.
     */

  }, {
    key: "getSearchResultClass",
    value: function getSearchResultClass() {
      return this.searchResultClass;
    }
    /**
     * Sets search result cells class name. This class name will be added to each cell that belongs to the searched query.
     *
     * @param {String} newElementClass
     */

  }, {
    key: "setSearchResultClass",
    value: function setSearchResultClass(newElementClass) {
      this.searchResultClass = newElementClass;
    }
    /**
     * Updates the settings of the plugin.
     *
     * @param {Object} searchSettings The plugin settings, taken from Handsontable configuration.
     * @private
     */

  }, {
    key: "updatePluginSettings",
    value: function updatePluginSettings(searchSettings) {
      if ((0, _object.isObject)(searchSettings)) {
        if (searchSettings.searchResultClass) {
          this.setSearchResultClass(searchSettings.searchResultClass);
        }

        if (searchSettings.queryMethod) {
          this.setQueryMethod(searchSettings.queryMethod);
        }

        if (searchSettings.callback) {
          this.setCallback(searchSettings.callback);
        }
      }
    }
    /** *
     * The `beforeRenderer` hook callback.
     *
     * @private
     * @param {HTMLTableCellElement} TD The rendered `TD` element.
     * @param {Number} row Visual row index.
     * @param {Number} col Visual column index.
     * @param {String | Number} prop Column property name or a column index, if datasource is an array of arrays.
     * @param {String} value Value of the rendered cell.
     * @param {Object} cellProperties Object containing the cell's properties.
     */

  }, {
    key: "onBeforeRenderer",
    value: function onBeforeRenderer(TD, row, col, prop, value, cellProperties) {
      // TODO: #4972
      var className = cellProperties.className || [];
      var classArray = [];

      if (typeof className === 'string') {
        classArray = className.split(' ');
      } else {
        var _classArray;

        (_classArray = classArray).push.apply(_classArray, (0, _toConsumableArray2.default)(className));
      }

      if (this.isEnabled() && cellProperties.isSearchResult) {
        if (!classArray.includes(this.searchResultClass)) {
          classArray.push("".concat(this.searchResultClass));
        }
      } else if (classArray.includes(this.searchResultClass)) {
        classArray.splice(classArray.indexOf(this.searchResultClass), 1);
      }

      cellProperties.className = classArray.join(' ');
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "destroy", this).call(this);
    }
  }]);
  return Search;
}(_base.default);

(0, _plugins.registerPlugin)('search', Search);
var _default = Search;
exports.default = _default;

/***/ }),
/* 680 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _feature = __webpack_require__(73);

/**
 * @private
 * @plugin TouchScroll
 * @class TouchScroll
 */
var TouchScroll =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(TouchScroll, _BasePlugin);

  function TouchScroll(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, TouchScroll);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TouchScroll).call(this, hotInstance));
    /**
     * Collection of scrollbars to update.
     *
     * @type {Array}
     */

    _this.scrollbars = [];
    /**
     * Collection of overlays to update.
     *
     * @type {Array}
     */

    _this.clones = [];
    /**
     * Flag which determines if collection of overlays should be refilled on every table render.
     *
     * @type {Boolean}
     * @default false
     */

    _this.lockedCollection = false;
    /**
     * Flag which determines if walkontable should freeze overlays while scrolling.
     *
     * @type {Boolean}
     * @default false
     */

    _this.freezeOverlays = false;
    return _this;
  }
  /**
   * Check if plugin is enabled.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(TouchScroll, [{
    key: "isEnabled",
    value: function isEnabled() {
      return (0, _feature.isTouchSupported)();
    }
    /**
     * Enable the plugin.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.addHook('afterRender', function () {
        return _this2.onAfterRender();
      });
      this.registerEvents();
      (0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin to use the latest options you have specified.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.lockedCollection = false;
      (0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disable plugin for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Register all necessary events.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this3 = this;

      this.addHook('beforeTouchScroll', function () {
        return _this3.onBeforeTouchScroll();
      });
      this.addHook('afterMomentumScroll', function () {
        return _this3.onAfterMomentumScroll();
      });
    }
    /**
     * After render listener.
     *
     * @private
     */

  }, {
    key: "onAfterRender",
    value: function onAfterRender() {
      if (this.lockedCollection) {
        return;
      }

      var _this$hot$view$wt$wtO = this.hot.view.wt.wtOverlays,
          topOverlay = _this$hot$view$wt$wtO.topOverlay,
          bottomOverlay = _this$hot$view$wt$wtO.bottomOverlay,
          leftOverlay = _this$hot$view$wt$wtO.leftOverlay,
          topLeftCornerOverlay = _this$hot$view$wt$wtO.topLeftCornerOverlay,
          bottomLeftCornerOverlay = _this$hot$view$wt$wtO.bottomLeftCornerOverlay;
      this.lockedCollection = true;
      this.scrollbars.length = 0;
      this.scrollbars.push(topOverlay);

      if (bottomOverlay.clone) {
        this.scrollbars.push(bottomOverlay);
      }

      this.scrollbars.push(leftOverlay);

      if (topLeftCornerOverlay) {
        this.scrollbars.push(topLeftCornerOverlay);
      }

      if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) {
        this.scrollbars.push(bottomLeftCornerOverlay);
      }

      this.clones.length = 0;

      if (topOverlay.needFullRender) {
        this.clones.push(topOverlay.clone.wtTable.holder.parentNode);
      }

      if (bottomOverlay.needFullRender) {
        this.clones.push(bottomOverlay.clone.wtTable.holder.parentNode);
      }

      if (leftOverlay.needFullRender) {
        this.clones.push(leftOverlay.clone.wtTable.holder.parentNode);
      }

      if (topLeftCornerOverlay) {
        this.clones.push(topLeftCornerOverlay.clone.wtTable.holder.parentNode);
      }

      if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) {
        this.clones.push(bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
      }
    }
    /**
     * Touch scroll listener.
     *
     * @private
     */

  }, {
    key: "onBeforeTouchScroll",
    value: function onBeforeTouchScroll() {
      this.freezeOverlays = true;
      (0, _array.arrayEach)(this.clones, function (clone) {
        (0, _element.addClass)(clone, 'hide-tween');
      });
    }
    /**
     * After momentum scroll listener.
     *
     * @private
     */

  }, {
    key: "onAfterMomentumScroll",
    value: function onAfterMomentumScroll() {
      var _this4 = this;

      this.freezeOverlays = false;
      (0, _array.arrayEach)(this.clones, function (clone) {
        (0, _element.removeClass)(clone, 'hide-tween');
        (0, _element.addClass)(clone, 'show-tween');
      });
      setTimeout(function () {
        (0, _array.arrayEach)(_this4.clones, function (clone) {
          (0, _element.removeClass)(clone, 'show-tween');
        });
      }, 400);
      (0, _array.arrayEach)(this.scrollbars, function (scrollbar) {
        scrollbar.refresh();
        scrollbar.resetFixedPosition();
      });
      this.hot.view.wt.wtOverlays.syncScrollWithMaster();
    }
  }]);
  return TouchScroll;
}(_base.default);

(0, _plugins.registerPlugin)('touchScroll', TouchScroll);
var _default = TouchScroll;
exports.default = _default;

/***/ }),
/* 681 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

__webpack_require__(12);

__webpack_require__(40);

__webpack_require__(64);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _object = __webpack_require__(4);

var _event = __webpack_require__(31);

var _utils = __webpack_require__(60);

/**
 * Handsontable UndoRedo class
 */

/**
 * @description
 * Handsontable UndoRedo plugin allows to undo and redo certain actions done in the table.
 *
 * __Note__, that not all actions are currently undo-able. The UndoRedo plugin is enabled by default.
 *
 * @example
 * ```js
 * undo: true
 * ```
 * @class UndoRedo
 * @plugin UndoRedo
 */
function UndoRedo(instance) {
  var plugin = this;
  this.instance = instance;
  this.doneActions = [];
  this.undoneActions = [];
  this.ignoreNewActions = false;
  instance.addHook('afterChange', function (changes, source) {
    if (changes && source !== 'UndoRedo.undo' && source !== 'UndoRedo.redo' && source !== 'MergeCells') {
      plugin.done(new UndoRedo.ChangeAction(changes));
    }
  });
  instance.addHook('afterCreateRow', function (index, amount, source) {
    if (source === 'UndoRedo.undo' || source === 'UndoRedo.undo' || source === 'auto') {
      return;
    }

    var action = new UndoRedo.CreateRowAction(index, amount);
    plugin.done(action);
  });
  instance.addHook('beforeRemoveRow', function (index, amount, logicRows, source) {
    if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
      return;
    }

    var originalData = plugin.instance.getSourceDataArray();
    var rowIndex = (originalData.length + index) % originalData.length;
    var physicalRowIndex = instance.toPhysicalRow(rowIndex);
    var removedData = (0, _object.deepClone)(originalData.slice(physicalRowIndex, physicalRowIndex + amount));
    plugin.done(new UndoRedo.RemoveRowAction(rowIndex, removedData));
  });
  instance.addHook('afterCreateCol', function (index, amount, source) {
    if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
      return;
    }

    plugin.done(new UndoRedo.CreateColumnAction(index, amount));
  });
  instance.addHook('beforeRemoveCol', function (index, amount, logicColumns, source) {
    if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
      return;
    }

    var originalData = plugin.instance.getSourceDataArray();
    var columnIndex = (plugin.instance.countCols() + index) % plugin.instance.countCols();
    var removedData = [];
    var headers = [];
    var indexes = [];
    (0, _number.rangeEach)(originalData.length - 1, function (i) {
      var column = [];
      var origRow = originalData[i];
      (0, _number.rangeEach)(columnIndex, columnIndex + (amount - 1), function (j) {
        column.push(origRow[instance.runHooks('modifyCol', j)]);
      });
      removedData.push(column);
    });
    (0, _number.rangeEach)(amount - 1, function (i) {
      indexes.push(instance.runHooks('modifyCol', columnIndex + i));
    });

    if (Array.isArray(instance.getSettings().colHeaders)) {
      (0, _number.rangeEach)(amount - 1, function (i) {
        headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', columnIndex + i)] || null);
      });
    }

    var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove');
    var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : [];
    var action = new UndoRedo.RemoveColumnAction(columnIndex, indexes, removedData, headers, columnsMap);
    plugin.done(action);
  });
  instance.addHook('beforeCellAlignment', function (stateBefore, range, type, alignment) {
    var action = new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment);
    plugin.done(action);
  });
  instance.addHook('beforeFilter', function (conditionsStack) {
    plugin.done(new UndoRedo.FiltersAction(conditionsStack));
  });
  instance.addHook('beforeRowMove', function (movedRows, target) {
    if (movedRows === false) {
      return;
    }

    plugin.done(new UndoRedo.RowMoveAction(movedRows, target));
  });
  instance.addHook('beforeMergeCells', function (cellRange, auto) {
    if (auto) {
      return;
    }

    plugin.done(new UndoRedo.MergeCellsAction(instance, cellRange));
  });
  instance.addHook('afterUnmergeCells', function (cellRange, auto) {
    if (auto) {
      return;
    }

    plugin.done(new UndoRedo.UnmergeCellsAction(instance, cellRange));
  });
}

UndoRedo.prototype.done = function (action) {
  if (!this.ignoreNewActions) {
    this.doneActions.push(action);
    this.undoneActions.length = 0;
  }
};
/**
 * Undo the last action performed to the table.
 *
 * @function undo
 * @memberof UndoRedo#
 * @fires Hooks#beforeUndo
 * @fires Hooks#afterUndo
 */


UndoRedo.prototype.undo = function () {
  if (this.isUndoAvailable()) {
    var action = this.doneActions.pop();
    var actionClone = (0, _object.deepClone)(action);
    var instance = this.instance;
    var continueAction = instance.runHooks('beforeUndo', actionClone);

    if (continueAction === false) {
      return;
    }

    this.ignoreNewActions = true;
    var that = this;
    action.undo(this.instance, function () {
      that.ignoreNewActions = false;
      that.undoneActions.push(action);
    });
    instance.runHooks('afterUndo', actionClone);
  }
};
/**
 * Redo the previous action performed to the table (used to reverse an undo).
 *
 * @function redo
 * @memberof UndoRedo#
 * @fires Hooks#beforeRedo
 * @fires Hooks#afterRedo
 */


UndoRedo.prototype.redo = function () {
  if (this.isRedoAvailable()) {
    var action = this.undoneActions.pop();
    var actionClone = (0, _object.deepClone)(action);
    var instance = this.instance;
    var continueAction = instance.runHooks('beforeRedo', actionClone);

    if (continueAction === false) {
      return;
    }

    this.ignoreNewActions = true;
    var that = this;
    action.redo(this.instance, function () {
      that.ignoreNewActions = false;
      that.doneActions.push(action);
    });
    instance.runHooks('afterRedo', actionClone);
  }
};
/**
 * Checks if undo action is available.
 *
 * @function isUndoAvailable
 * @memberof UndoRedo#
 * @return {Boolean} Return `true` if undo can be performed, `false` otherwise.
 */


UndoRedo.prototype.isUndoAvailable = function () {
  return this.doneActions.length > 0;
};
/**
 * Checks if redo action is available.
 *
 * @function isRedoAvailable
 * @memberof UndoRedo#
 * @return {Boolean} Return `true` if redo can be performed, `false` otherwise.
 */


UndoRedo.prototype.isRedoAvailable = function () {
  return this.undoneActions.length > 0;
};
/**
 * Clears undo history.
 *
 * @function clear
 * @memberof UndoRedo#
 */


UndoRedo.prototype.clear = function () {
  this.doneActions.length = 0;
  this.undoneActions.length = 0;
};

UndoRedo.Action = function () {};

UndoRedo.Action.prototype.undo = function () {};

UndoRedo.Action.prototype.redo = function () {};
/**
 * Change action.
 *
 * @private
 */


UndoRedo.ChangeAction = function (changes) {
  this.changes = changes;
  this.actionType = 'change';
};

(0, _object.inherit)(UndoRedo.ChangeAction, UndoRedo.Action);

UndoRedo.ChangeAction.prototype.undo = function (instance, undoneCallback) {
  var data = (0, _object.deepClone)(this.changes);
  var emptyRowsAtTheEnd = instance.countEmptyRows(true);
  var emptyColsAtTheEnd = instance.countEmptyCols(true);

  for (var i = 0, len = data.length; i < len; i++) {
    data[i].splice(3, 1);
  }

  instance.addHookOnce('afterChange', undoneCallback);
  instance.setDataAtRowProp(data, null, null, 'UndoRedo.undo');

  for (var _i = 0, _len = data.length; _i < _len; _i++) {
    if (instance.getSettings().minSpareRows && data[_i][0] + 1 + instance.getSettings().minSpareRows === instance.countRows() && emptyRowsAtTheEnd === instance.getSettings().minSpareRows) {
      instance.alter('remove_row', parseInt(data[_i][0] + 1, 10), instance.getSettings().minSpareRows);
      instance.undoRedo.doneActions.pop();
    }

    if (instance.getSettings().minSpareCols && data[_i][1] + 1 + instance.getSettings().minSpareCols === instance.countCols() && emptyColsAtTheEnd === instance.getSettings().minSpareCols) {
      instance.alter('remove_col', parseInt(data[_i][1] + 1, 10), instance.getSettings().minSpareCols);
      instance.undoRedo.doneActions.pop();
    }
  }
};

UndoRedo.ChangeAction.prototype.redo = function (instance, onFinishCallback) {
  var data = (0, _object.deepClone)(this.changes);

  for (var i = 0, len = data.length; i < len; i++) {
    data[i].splice(2, 1);
  }

  instance.addHookOnce('afterChange', onFinishCallback);
  instance.setDataAtRowProp(data, null, null, 'UndoRedo.redo');
};
/**
 * Create row action.
 *
 * @private
 */


UndoRedo.CreateRowAction = function (index, amount) {
  this.index = index;
  this.amount = amount;
  this.actionType = 'insert_row';
};

(0, _object.inherit)(UndoRedo.CreateRowAction, UndoRedo.Action);

UndoRedo.CreateRowAction.prototype.undo = function (instance, undoneCallback) {
  var rowCount = instance.countRows();
  var minSpareRows = instance.getSettings().minSpareRows;

  if (this.index >= rowCount && this.index - minSpareRows < rowCount) {
    this.index -= minSpareRows; // work around the situation where the needed row was removed due to an 'undo' of a made change
  }

  instance.addHookOnce('afterRemoveRow', undoneCallback);
  instance.alter('remove_row', this.index, this.amount, 'UndoRedo.undo');
};

UndoRedo.CreateRowAction.prototype.redo = function (instance, redoneCallback) {
  instance.addHookOnce('afterCreateRow', redoneCallback);
  instance.alter('insert_row', this.index, this.amount, 'UndoRedo.redo');
};
/**
 * Remove row action.
 *
 * @private
 */


UndoRedo.RemoveRowAction = function (index, data) {
  this.index = index;
  this.data = data;
  this.actionType = 'remove_row';
};

(0, _object.inherit)(UndoRedo.RemoveRowAction, UndoRedo.Action);

UndoRedo.RemoveRowAction.prototype.undo = function (instance, undoneCallback) {
  instance.alter('insert_row', this.index, this.data.length, 'UndoRedo.undo');
  instance.addHookOnce('afterRender', undoneCallback);
  instance.populateFromArray(this.index, 0, this.data, void 0, void 0, 'UndoRedo.undo');
};

UndoRedo.RemoveRowAction.prototype.redo = function (instance, redoneCallback) {
  instance.addHookOnce('afterRemoveRow', redoneCallback);
  instance.alter('remove_row', this.index, this.data.length, 'UndoRedo.redo');
};
/**
 * Create column action.
 *
 * @private
 */


UndoRedo.CreateColumnAction = function (index, amount) {
  this.index = index;
  this.amount = amount;
  this.actionType = 'insert_col';
};

(0, _object.inherit)(UndoRedo.CreateColumnAction, UndoRedo.Action);

UndoRedo.CreateColumnAction.prototype.undo = function (instance, undoneCallback) {
  instance.addHookOnce('afterRemoveCol', undoneCallback);
  instance.alter('remove_col', this.index, this.amount, 'UndoRedo.undo');
};

UndoRedo.CreateColumnAction.prototype.redo = function (instance, redoneCallback) {
  instance.addHookOnce('afterCreateCol', redoneCallback);
  instance.alter('insert_col', this.index, this.amount, 'UndoRedo.redo');
};
/**
 * Remove column action.
 *
 * @private
 */


UndoRedo.RemoveColumnAction = function (index, indexes, data, headers, columnPositions) {
  this.index = index;
  this.indexes = indexes;
  this.data = data;
  this.amount = this.data[0].length;
  this.headers = headers;
  this.columnPositions = columnPositions.slice(0);
  this.actionType = 'remove_col';
};

(0, _object.inherit)(UndoRedo.RemoveColumnAction, UndoRedo.Action);

UndoRedo.RemoveColumnAction.prototype.undo = function (instance, undoneCallback) {
  var _this = this;

  var row;
  var ascendingIndexes = this.indexes.slice(0).sort();

  var sortByIndexes = function sortByIndexes(elem, j, arr) {
    return arr[_this.indexes.indexOf(ascendingIndexes[j])];
  };

  var sortedData = [];
  (0, _number.rangeEach)(this.data.length - 1, function (i) {
    sortedData[i] = (0, _array.arrayMap)(_this.data[i], sortByIndexes);
  });
  var sortedHeaders = [];
  sortedHeaders = (0, _array.arrayMap)(this.headers, sortByIndexes);
  var changes = []; // TODO: Temporary hook for undo/redo mess

  instance.runHooks('beforeCreateCol', this.indexes[0], this.indexes.length, 'UndoRedo.undo');
  (0, _number.rangeEach)(this.data.length - 1, function (i) {
    row = instance.getSourceDataAtRow(i);
    (0, _number.rangeEach)(ascendingIndexes.length - 1, function (j) {
      row.splice(ascendingIndexes[j], 0, sortedData[i][j]);
      changes.push([i, ascendingIndexes[j], null, sortedData[i][j]]);
    });
  }); // TODO: Temporary hook for undo/redo mess

  if (instance.getPlugin('formulas')) {
    instance.getPlugin('formulas').onAfterSetDataAtCell(changes);
  }

  if (typeof this.headers !== 'undefined') {
    (0, _number.rangeEach)(sortedHeaders.length - 1, function (j) {
      instance.getSettings().colHeaders.splice(ascendingIndexes[j], 0, sortedHeaders[j]);
    });
  }

  if (instance.getPlugin('manualColumnMove')) {
    instance.getPlugin('manualColumnMove').columnsMapper.__arrayMap = this.columnPositions;
  }

  instance.addHookOnce('afterRender', undoneCallback); // TODO: Temporary hook for undo/redo mess

  instance.runHooks('afterCreateCol', this.indexes[0], this.indexes.length, 'UndoRedo.undo');

  if (instance.getPlugin('formulas')) {
    instance.getPlugin('formulas').recalculateFull();
  }

  instance.render();
};

UndoRedo.RemoveColumnAction.prototype.redo = function (instance, redoneCallback) {
  instance.addHookOnce('afterRemoveCol', redoneCallback);
  instance.alter('remove_col', this.index, this.amount, 'UndoRedo.redo');
};
/**
 * Cell alignment action.
 *
 * @private
 */


UndoRedo.CellAlignmentAction = function (stateBefore, range, type, alignment) {
  this.stateBefore = stateBefore;
  this.range = range;
  this.type = type;
  this.alignment = alignment;
};

UndoRedo.CellAlignmentAction.prototype.undo = function (instance, undoneCallback) {
  var _this2 = this;

  (0, _array.arrayEach)(this.range, function (_ref) {
    var from = _ref.from,
        to = _ref.to;

    for (var row = from.row; row <= to.row; row += 1) {
      for (var col = from.col; col <= to.col; col += 1) {
        instance.setCellMeta(row, col, 'className', _this2.stateBefore[row][col] || ' htLeft');
      }
    }
  });
  instance.addHookOnce('afterRender', undoneCallback);
  instance.render();
};

UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) {
  (0, _utils.align)(this.range, this.type, this.alignment, function (row, col) {
    return instance.getCellMeta(row, col);
  }, function (row, col, key, value) {
    return instance.setCellMeta(row, col, key, value);
  });
  instance.addHookOnce('afterRender', undoneCallback);
  instance.render();
};
/**
 * Filters action.
 *
 * @private
 */


UndoRedo.FiltersAction = function (conditionsStack) {
  this.conditionsStack = conditionsStack;
  this.actionType = 'filter';
};

(0, _object.inherit)(UndoRedo.FiltersAction, UndoRedo.Action);

UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
  var filters = instance.getPlugin('filters');
  instance.addHookOnce('afterRender', undoneCallback);
  filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1));
  filters.filter();
};

UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
  var filters = instance.getPlugin('filters');
  instance.addHookOnce('afterRender', redoneCallback);
  filters.conditionCollection.importAllConditions(this.conditionsStack);
  filters.filter();
};
/**
 * Merge Cells action.
 * @util
 */


var MergeCellsAction =
/*#__PURE__*/
function (_UndoRedo$Action) {
  (0, _inherits2.default)(MergeCellsAction, _UndoRedo$Action);

  function MergeCellsAction(instance, cellRange) {
    var _this3;

    (0, _classCallCheck2.default)(this, MergeCellsAction);
    _this3 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MergeCellsAction).call(this));
    _this3.cellRange = cellRange;
    _this3.rangeData = instance.getData(cellRange.from.row, cellRange.from.col, cellRange.to.row, cellRange.to.col);
    return _this3;
  }

  (0, _createClass2.default)(MergeCellsAction, [{
    key: "undo",
    value: function undo(instance, undoneCallback) {
      var mergeCellsPlugin = instance.getPlugin('mergeCells');
      instance.addHookOnce('afterRender', undoneCallback);
      mergeCellsPlugin.unmergeRange(this.cellRange, true);
      instance.populateFromArray(this.cellRange.from.row, this.cellRange.from.col, this.rangeData, void 0, void 0, 'MergeCells');
    }
  }, {
    key: "redo",
    value: function redo(instance, redoneCallback) {
      var mergeCellsPlugin = instance.getPlugin('mergeCells');
      instance.addHookOnce('afterRender', redoneCallback);
      mergeCellsPlugin.mergeRange(this.cellRange);
    }
  }]);
  return MergeCellsAction;
}(UndoRedo.Action);

UndoRedo.MergeCellsAction = MergeCellsAction;
/**
 * Unmerge Cells action.
 * @util
 */

var UnmergeCellsAction =
/*#__PURE__*/
function (_UndoRedo$Action2) {
  (0, _inherits2.default)(UnmergeCellsAction, _UndoRedo$Action2);

  function UnmergeCellsAction(instance, cellRange) {
    var _this4;

    (0, _classCallCheck2.default)(this, UnmergeCellsAction);
    _this4 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(UnmergeCellsAction).call(this));
    _this4.cellRange = cellRange;
    return _this4;
  }

  (0, _createClass2.default)(UnmergeCellsAction, [{
    key: "undo",
    value: function undo(instance, undoneCallback) {
      var mergeCellsPlugin = instance.getPlugin('mergeCells');
      instance.addHookOnce('afterRender', undoneCallback);
      mergeCellsPlugin.mergeRange(this.cellRange, true);
    }
  }, {
    key: "redo",
    value: function redo(instance, redoneCallback) {
      var mergeCellsPlugin = instance.getPlugin('mergeCells');
      instance.addHookOnce('afterRender', redoneCallback);
      mergeCellsPlugin.unmergeRange(this.cellRange, true);
      instance.render();
    }
  }]);
  return UnmergeCellsAction;
}(UndoRedo.Action);

UndoRedo.UnmergeCellsAction = UnmergeCellsAction;
/**
 * ManualRowMove action.
 *
 * @private
 * @TODO: removeRow undo should works on logical index
 */

UndoRedo.RowMoveAction = function (movedRows, target) {
  this.rows = movedRows.slice();
  this.target = target;
};

(0, _object.inherit)(UndoRedo.RowMoveAction, UndoRedo.Action);

UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
  var manualRowMove = instance.getPlugin('manualRowMove');
  instance.addHookOnce('afterRender', undoneCallback);
  var mod = this.rows[0] < this.target ? -1 * this.rows.length : 0;
  var newTarget = this.rows[0] > this.target ? this.rows[0] + this.rows.length : this.rows[0];
  var newRows = [];
  var rowsLen = this.rows.length + mod;

  for (var i = mod; i < rowsLen; i += 1) {
    newRows.push(this.target + i);
  }

  manualRowMove.moveRows(newRows.slice(), newTarget);
  instance.render();
  instance.selectCell(this.rows[0], 0, this.rows[this.rows.length - 1], instance.countCols() - 1, false, false);
};

UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) {
  var manualRowMove = instance.getPlugin('manualRowMove');
  instance.addHookOnce('afterRender', redoneCallback);
  manualRowMove.moveRows(this.rows.slice(), this.target);
  instance.render();
  var startSelection = this.rows[0] < this.target ? this.target - this.rows.length : this.target;
  instance.selectCell(startSelection, 0, startSelection + this.rows.length - 1, instance.countCols() - 1, false, false);
};

function init() {
  var instance = this;
  var pluginEnabled = typeof instance.getSettings().undo === 'undefined' || instance.getSettings().undo;

  if (pluginEnabled) {
    if (!instance.undoRedo) {
      /**
       * Instance of Handsontable.UndoRedo Plugin {@link Handsontable.UndoRedo}
       *
       * @alias undoRedo
       * @memberof! Handsontable.Core#
       * @type {UndoRedo}
       */
      instance.undoRedo = new UndoRedo(instance);
      exposeUndoRedoMethods(instance);
      instance.addHook('beforeKeyDown', onBeforeKeyDown);
      instance.addHook('afterChange', onAfterChange);
    }
  } else if (instance.undoRedo) {
    delete instance.undoRedo;
    removeExposedUndoRedoMethods(instance);
    instance.removeHook('beforeKeyDown', onBeforeKeyDown);
    instance.removeHook('afterChange', onAfterChange);
  }
}

function onBeforeKeyDown(event) {
  var instance = this;
  var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;

  if (ctrlDown) {
    if (event.keyCode === 89 || event.shiftKey && event.keyCode === 90) {
      // CTRL + Y or CTRL + SHIFT + Z
      instance.undoRedo.redo();
      (0, _event.stopImmediatePropagation)(event);
    } else if (event.keyCode === 90) {
      // CTRL + Z
      instance.undoRedo.undo();
      (0, _event.stopImmediatePropagation)(event);
    }
  }
}

function onAfterChange(changes, source) {
  var instance = this;

  if (source === 'loadData') {
    return instance.undoRedo.clear();
  }
}

function exposeUndoRedoMethods(instance) {
  /**
   * {@link UndoRedo#undo}
   * @alias undo
   * @memberof! Handsontable.Core#
   */
  instance.undo = function () {
    return instance.undoRedo.undo();
  };
  /**
   * {@link UndoRedo#redo}
   * @alias redo
   * @memberof! Handsontable.Core#
   */


  instance.redo = function () {
    return instance.undoRedo.redo();
  };
  /**
   * {@link UndoRedo#isUndoAvailable}
   * @alias isUndoAvailable
   * @memberof! Handsontable.Core#
   */


  instance.isUndoAvailable = function () {
    return instance.undoRedo.isUndoAvailable();
  };
  /**
   * {@link UndoRedo#isRedoAvailable}
   * @alias isRedoAvailable
   * @memberof! Handsontable.Core#
   */


  instance.isRedoAvailable = function () {
    return instance.undoRedo.isRedoAvailable();
  };
  /**
   * {@link UndoRedo#clear}
   * @alias clearUndo
   * @memberof! Handsontable.Core#
   */


  instance.clearUndo = function () {
    return instance.undoRedo.clear();
  };
}

function removeExposedUndoRedoMethods(instance) {
  delete instance.undo;
  delete instance.redo;
  delete instance.isUndoAvailable;
  delete instance.isRedoAvailable;
  delete instance.clearUndo;
}

var hook = _pluginHooks.default.getSingleton();

hook.add('afterInit', init);
hook.add('afterUpdateSettings', init);
hook.register('beforeUndo');
hook.register('afterUndo');
hook.register('beforeRedo');
hook.register('afterRedo');
var _default = UndoRedo;
exports.default = _default;

/***/ }),
/* 682 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

var _bindStrategy = _interopRequireDefault(__webpack_require__(683));

/**
 * @plugin BindRowsWithHeaders
 *
 * @description
 * Plugin allows binding the table rows with their headers.
 *
 * If the plugin is enabled, the table row headers will "stick" to the rows, when they are hidden/moved. Basically, if
 * at the initialization row 0 has a header titled "A", it will have it no matter what you do with the table.
 *
 * @example
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   // enable plugin
 *   bindRowsWithHeaders: true
 * });
 * ```
 */
var BindRowsWithHeaders =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(BindRowsWithHeaders, _BasePlugin);

  function BindRowsWithHeaders(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, BindRowsWithHeaders);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BindRowsWithHeaders).call(this, hotInstance));
    /**
     * Strategy object for binding rows with headers.
     *
     * @private
     * @type {BindStrategy}
     */

    _this.bindStrategy = new _bindStrategy.default();
    /**
     * List of last removed row indexes.
     *
     * @private
     * @type {Array}
     */

    _this.removedRows = [];
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link BindRowsWithHeaders#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(BindRowsWithHeaders, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().bindRowsWithHeaders;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var bindStrategy = this.hot.getSettings().bindRowsWithHeaders;

      if (typeof bindStrategy !== 'string') {
        bindStrategy = _bindStrategy.default.DEFAULT_STRATEGY;
      }

      this.bindStrategy.setStrategy(bindStrategy);
      this.bindStrategy.createMap(this.hot.countSourceRows());
      this.addHook('modifyRowHeader', function (row) {
        return _this2.onModifyRowHeader(row);
      });
      this.addHook('afterCreateRow', function (index, amount) {
        return _this2.onAfterCreateRow(index, amount);
      });
      this.addHook('beforeRemoveRow', function (index, amount) {
        return _this2.onBeforeRemoveRow(index, amount);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow();
      });
      this.addHook('afterLoadData', function (firstRun) {
        return _this2.onAfterLoadData(firstRun);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.removedRows.length = 0;
      this.bindStrategy.clearMap();
      (0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "disablePlugin", this).call(this);
    }
    /**
     * On modify row header listener.
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Number}
     *
     * @fires Hooks#modifyRow
     */

  }, {
    key: "onModifyRowHeader",
    value: function onModifyRowHeader(row) {
      return this.bindStrategy.translate(this.hot.runHooks('modifyRow', row));
    }
    /**
     * On after create row listener.
     *
     * @private
     * @param {Number} index Row index.
     * @param {Number} amount Defines how many rows removed.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount) {
      this.bindStrategy.createRow(index, amount);
    }
    /**
     * On before remove row listener.
     *
     * @private
     * @param {Number} index Row index.
     * @param {Number} amount Defines how many rows removed.
     *
     * @fires Hooks#modifyRow
     */

  }, {
    key: "onBeforeRemoveRow",
    value: function onBeforeRemoveRow(index, amount) {
      var _this3 = this;

      this.removedRows.length = 0;

      if (index !== false) {
        // Collect physical row index.
        (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
          _this3.removedRows.push(_this3.hot.runHooks('modifyRow', removedIndex));
        });
      }
    }
    /**
     * On after remove row listener.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow() {
      this.bindStrategy.removeRow(this.removedRows);
    }
    /**
     * On after load data listener.
     *
     * @private
     * @param {Boolean} firstRun Indicates if hook was fired while Handsontable initialization.
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData(firstRun) {
      if (!firstRun) {
        this.bindStrategy.createMap(this.hot.countSourceRows());
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.bindStrategy.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "destroy", this).call(this);
    }
  }]);
  return BindRowsWithHeaders;
}(_base.default);

(0, _plugins.registerPlugin)('bindRowsWithHeaders', BindRowsWithHeaders);
var _default = BindRowsWithHeaders;
exports.default = _default;

/***/ }),
/* 683 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _number = __webpack_require__(15);

var _string = __webpack_require__(68);

var strategies = _interopRequireWildcard(__webpack_require__(684));

/**
 * @class BindStrategy
 * @plugin BindRowsWithHeaders
 */
var BindStrategy =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(BindStrategy, null, [{
    key: "DEFAULT_STRATEGY",

    /**
     * Loose bind mode.
     *
     * @returns {String}
     */
    get: function get() {
      return 'loose';
    }
  }]);

  function BindStrategy() {
    (0, _classCallCheck2.default)(this, BindStrategy);
    this.strategy = null;
  }
  /**
   * Set strategy behaviors for binding rows with headers.
   *
   * @param name
   */


  (0, _createClass2.default)(BindStrategy, [{
    key: "setStrategy",
    value: function setStrategy(name) {
      var Strategy = strategies[(0, _string.toUpperCaseFirst)(name)];

      if (!Strategy) {
        throw new Error("Bind strategy \"".concat(name, "\" does not exist."));
      }

      this.strategy = new Strategy();
    }
    /**
     * Reset current map array and create a new one.
     *
     * @param {Number} [length] Custom generated map length.
     */

  }, {
    key: "createMap",
    value: function createMap(length) {
      var strategy = this.strategy;
      var originLength = length === void 0 ? strategy._arrayMap.length : length;
      strategy._arrayMap.length = 0;
      (0, _number.rangeEach)(originLength - 1, function (itemIndex) {
        strategy._arrayMap.push(itemIndex);
      });
    }
    /**
     * Alias for createRow of strategy class.
     *
     * @param {*} params
     */

  }, {
    key: "createRow",
    value: function createRow() {
      var _this$strategy;

      (_this$strategy = this.strategy).createRow.apply(_this$strategy, arguments);
    }
    /**
     * Alias for removeRow of strategy class.
     *
     * @param {*} params
     */

  }, {
    key: "removeRow",
    value: function removeRow() {
      var _this$strategy2;

      (_this$strategy2 = this.strategy).removeRow.apply(_this$strategy2, arguments);
    }
    /**
     * Alias for getValueByIndex of strategy class.
     *
     * @param {*} params
     */

  }, {
    key: "translate",
    value: function translate() {
      var _this$strategy3;

      return (_this$strategy3 = this.strategy).getValueByIndex.apply(_this$strategy3, arguments);
    }
    /**
     * Clear array map.
     */

  }, {
    key: "clearMap",
    value: function clearMap() {
      this.strategy.clearMap();
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.strategy) {
        this.strategy.destroy();
      }

      this.strategy = null;
    }
  }]);
  return BindStrategy;
}();

var _default = BindStrategy;
exports.default = _default;

/***/ }),
/* 684 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;

var _loose = _interopRequireDefault(__webpack_require__(685));

exports.Loose = _loose.default;

var _strict = _interopRequireDefault(__webpack_require__(686));

exports.Strict = _strict.default;

/***/ }),
/* 685 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _object = __webpack_require__(4);

/**
 * @private
 * @class LooseBindStrategy
 */
var LooseBindStrategy =
/*#__PURE__*/
function () {
  function LooseBindStrategy() {
    (0, _classCallCheck2.default)(this, LooseBindStrategy);
  }

  (0, _createClass2.default)(LooseBindStrategy, [{
    key: "createRow",

    /**
     * Strategy for the create row action.
     *
     * @param {Number} index Row index.
     * @param {Number} amount
     */
    value: function createRow(index, amount) {
      this.shiftItems(index, amount);
    }
    /**
     * Strategy for the remove row action.
     *
     * @param {Number|Array} index Row index or Array of row indexes.
     * @param {Number} amount
     */

  }, {
    key: "removeRow",
    value: function removeRow(index, amount) {
      this.unshiftItems(index, amount);
    }
    /**
     * Destroy strategy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
  }], [{
    key: "STRATEGY_NAME",

    /**
     * Loose bind mode.
     *
     * @returns {String}
     */
    get: function get() {
      return 'loose';
    }
  }]);
  return LooseBindStrategy;
}();

(0, _object.mixin)(LooseBindStrategy, _arrayMapper.default);
var _default = LooseBindStrategy;
exports.default = _default;

/***/ }),
/* 686 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _object = __webpack_require__(4);

/**
 * @private
 * @class StrictBindStrategy
 */
var StrictBindStrategy =
/*#__PURE__*/
function () {
  function StrictBindStrategy() {
    (0, _classCallCheck2.default)(this, StrictBindStrategy);
  }

  (0, _createClass2.default)(StrictBindStrategy, [{
    key: "createRow",

    /**
     * Strategy for the create row action.
     *
     * @param {Number} index Row index.
     * @param {Number} amount
     */
    value: function createRow(index, amount) {
      this.insertItems(index, amount);
    }
    /**
     * Strategy for the remove row action.
     *
     * @param {Number|Array} index Row index or Array of row indexes.
     * @param {Number} amount
     */

  }, {
    key: "removeRow",
    value: function removeRow(index, amount) {
      this.removeItems(index, amount);
    }
    /**
     * Destroy strategy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
  }], [{
    key: "STRATEGY_NAME",

    /**
     * Loose bind mode.
     *
     * @returns {String}
     */
    get: function get() {
      return 'strict';
    }
  }]);
  return StrictBindStrategy;
}();

(0, _object.mixin)(StrictBindStrategy, _arrayMapper.default);
var _default = StrictBindStrategy;
exports.default = _default;

/***/ }),
/* 687 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(33);

__webpack_require__(76);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _console = __webpack_require__(55);

var _element = __webpack_require__(5);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _event = __webpack_require__(31);

var _base = _interopRequireDefault(__webpack_require__(21));

/**
 * @plugin CollapsibleColumns
 * @dependencies NestedHeaders HiddenColumns
 *
 * @description
 * The {@link CollapsibleColumns} plugin allows collapsing of columns, covered by a header with the `colspan` property defined.
 *
 * Clicking the "collapse/expand" button collapses (or expands) all "child" headers except the first one.
 *
 * Setting the {@link Options#collapsibleColumns} property to `true` will display a "collapse/expand" button in every header
 * with a defined `colspan` property.
 *
 * To limit this functionality to a smaller group of headers, define the `collapsibleColumns` property as an array
 * of objects, as in the example below.
 *
 * @example
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: generateDataObj(),
 *   colHeaders: true,
 *   rowHeaders: true,
 *   // enable plugin
 *   collapsibleColumns: true,
 * });
 *
 * // or
 * const hot = new Handsontable(container, {
 *   data: generateDataObj(),
 *   colHeaders: true,
 *   rowHeaders: true,
 *   // enable and configure which columns can be collapsed
 *   collapsibleColumns: [
 *     {row: -4, col: 1, collapsible: true},
 *     {row: -3, col: 5, collapsible: true}
 *   ],
 * });
 * ```
 */
var CollapsibleColumns =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(CollapsibleColumns, _BasePlugin);

  function CollapsibleColumns(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, CollapsibleColumns);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CollapsibleColumns).call(this, hotInstance));
    /**
     * Cached plugin settings.
     *
     * @private
     * @type {Boolean|Array}
     */

    _this.settings = null;
    /**
     * Object listing headers with buttons enabled.
     *
     * @private
     * @type {Object}
     */

    _this.buttonEnabledList = {};
    /**
     * Cached reference to the HiddenColumns plugin.
     *
     * @private
     * @type {Object}
     */

    _this.hiddenColumnsPlugin = null;
    /**
     * Cached reference to the NestedHeaders plugin.
     *
     * @private
     * @type {Object}
     */

    _this.nestedHeadersPlugin = null;
    /**
     * Object listing the currently collapsed sections.
     *
     * @private
     * @type {Object}
     */

    _this.collapsedSections = {};
    /**
     * Number of column header levels.
     *
     * @private
     * @type {Number}
     */

    _this.columnHeaderLevelCount = null;
    /**
     * Event manager instance reference.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link CollapsibleColumns#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(CollapsibleColumns, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().collapsibleColumns;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.settings = this.hot.getSettings().collapsibleColumns;

      if (typeof this.settings !== 'boolean') {
        this.parseSettings();
      }

      this.hiddenColumnsPlugin = this.hot.getPlugin('hiddenColumns');
      this.nestedHeadersPlugin = this.hot.getPlugin('nestedHeaders');
      this.checkDependencies();
      this.addHook('afterRender', function () {
        return _this2.onAfterRender();
      });
      this.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      this.addHook('afterGetColHeader', function (col, TH) {
        return _this2.onAfterGetColHeader(col, TH);
      });
      this.addHook('beforeOnCellMouseDown', function (event, coords, TD) {
        return _this2.onBeforeOnCellMouseDown(event, coords, TD);
      });
      this.eventManager = new _eventManager.default(this.hot);
      (0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.settings = null;
      this.buttonEnabledList = {};
      this.hiddenColumnsPlugin = null;
      this.collapsedSections = {};
      this.clearButtons();
      (0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Clears the expand/collapse buttons.
     *
     * @private
     */

  }, {
    key: "clearButtons",
    value: function clearButtons() {
      if (!this.hot.view) {
        return;
      }

      var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
      var mainHeaders = this.hot.view.wt.wtTable.THEAD;
      var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
      var topLeftCornerHeaders = this.hot.view.wt.wtOverlays.topLeftCornerOverlay ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.THEAD : null;

      var removeButton = function removeButton(button) {
        if (button) {
          button.parentNode.removeChild(button);
        }
      };

      (0, _number.rangeEach)(0, headerLevels - 1, function (i) {
        var masterLevel = mainHeaders.childNodes[i];
        var topLevel = topHeaders.childNodes[i];
        var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;
        (0, _number.rangeEach)(0, masterLevel.childNodes.length - 1, function (j) {
          var button = masterLevel.childNodes[j].querySelector('.collapsibleIndicator');
          removeButton(button);

          if (topLevel && topLevel.childNodes[j]) {
            button = topLevel.childNodes[j].querySelector('.collapsibleIndicator');
            removeButton(button);
          }

          if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
            button = topLeftCornerLevel.childNodes[j].querySelector('.collapsibleIndicator');
            removeButton(button);
          }
        });
      }, true);
    }
    /**
     * Parses the plugin settings and create a button configuration array.
     *
     * @private
     */

  }, {
    key: "parseSettings",
    value: function parseSettings() {
      var _this3 = this;

      (0, _object.objectEach)(this.settings, function (val) {
        if (!_this3.buttonEnabledList[val.row]) {
          _this3.buttonEnabledList[val.row] = {};
        }

        _this3.buttonEnabledList[val.row][val.col] = val.collapsible;
      });
    }
    /**
     * Checks if plugin dependencies are met.
     *
     * @private
     * @returns {Boolean}
     */

  }, {
    key: "meetsDependencies",
    value: function meetsDependencies() {
      var settings = this.hot.getSettings();
      return settings.nestedHeaders && settings.hiddenColumns;
    }
    /**
     * Checks if all the required dependencies are enabled.
     *
     * @private
     */

  }, {
    key: "checkDependencies",
    value: function checkDependencies() {
      var settings = this.hot.getSettings();

      if (this.meetsDependencies()) {
        return;
      }

      if (!settings.nestedHeaders) {
        (0, _console.warn)('You need to configure the Nested Headers plugin in order to use collapsible headers.');
      }

      if (!settings.hiddenColumns) {
        (0, _console.warn)('You need to configure the Hidden Columns plugin in order to use collapsible headers.');
      }
    }
    /**
     * Generates the indicator element.
     *
     * @private
     * @param {Number} column Column index.
     * @param {HTMLElement} TH TH Element.
     * @returns {HTMLElement}
     */

  }, {
    key: "generateIndicator",
    value: function generateIndicator(column, TH) {
      var TR = TH.parentNode;
      var THEAD = TR.parentNode;
      var row = -1 * THEAD.childNodes.length + Array.prototype.indexOf.call(THEAD.childNodes, TR);

      if (Object.keys(this.buttonEnabledList).length > 0 && (!this.buttonEnabledList[row] || !this.buttonEnabledList[row][column])) {
        return null;
      }

      var divEl = this.hot.rootDocument.createElement('DIV');
      (0, _element.addClass)(divEl, 'collapsibleIndicator');

      if (this.collapsedSections[row] && this.collapsedSections[row][column] === true) {
        (0, _element.addClass)(divEl, 'collapsed');
        (0, _element.fastInnerText)(divEl, '+');
      } else {
        (0, _element.addClass)(divEl, 'expanded');
        (0, _element.fastInnerText)(divEl, '-');
      }

      return divEl;
    }
    /**
     * Marks (internally) a section as 'collapsed' or 'expanded' (optionally, also mark the 'child' headers).
     *
     * @private
     * @param {String} state State ('collapsed' or 'expanded').
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @param {Boolean} recursive If `true`, it will also attempt to mark the child sections.
     */

  }, {
    key: "markSectionAs",
    value: function markSectionAs(state, row, column, recursive) {
      if (!this.collapsedSections[row]) {
        this.collapsedSections[row] = {};
      }

      switch (state) {
        case 'collapsed':
          this.collapsedSections[row][column] = true;
          break;

        case 'expanded':
          this.collapsedSections[row][column] = void 0;
          break;

        default:
          break;
      }

      if (recursive) {
        var nestedHeadersColspans = this.nestedHeadersPlugin.colspanArray;
        var level = this.nestedHeadersPlugin.rowCoordsToLevel(row);
        var childHeaders = this.nestedHeadersPlugin.getChildHeaders(row, column);
        var childColspanLevel = nestedHeadersColspans[level + 1];

        for (var i = 1; i < childHeaders.length; i++) {
          if (childColspanLevel && childColspanLevel[childHeaders[i]].colspan > 1) {
            this.markSectionAs(state, row + 1, childHeaders[i], true);
          }
        }
      }
    }
    /**
     * Expands section at the provided coords.
     *
     * @param {Object} coords Contains coordinates information. (`coords.row`, `coords.col`)
     */

  }, {
    key: "expandSection",
    value: function expandSection(coords) {
      this.markSectionAs('expanded', coords.row, coords.col, true);
      this.toggleCollapsibleSection(coords, 'expand');
    }
    /**
     * Collapses section at the provided coords.
     *
     * @param {Object} coords Contains coordinates information. (`coords.row`, `coords.col`)
     */

  }, {
    key: "collapseSection",
    value: function collapseSection(coords) {
      this.markSectionAs('collapsed', coords.row, coords.col, true);
      this.toggleCollapsibleSection(coords, 'collapse');
    }
    /**
     * Collapses or expand all collapsible sections, depending on the action parameter.
     *
     * @param {String} action 'collapse' or 'expand'.
     */

  }, {
    key: "toggleAllCollapsibleSections",
    value: function toggleAllCollapsibleSections(action) {
      var _this4 = this;

      var nestedHeadersColspanArray = this.nestedHeadersPlugin.colspanArray;

      if (this.settings === true) {
        (0, _array.arrayEach)(nestedHeadersColspanArray, function (headerLevel, i) {
          (0, _array.arrayEach)(headerLevel, function (header, j) {
            if (header.colspan > 1) {
              var row = _this4.nestedHeadersPlugin.levelToRowCoords(parseInt(i, 10));

              var col = parseInt(j, 10);

              _this4.markSectionAs(action === 'collapse' ? 'collapsed' : 'expanded', row, col, true);

              _this4.toggleCollapsibleSection({
                row: row,
                col: col
              }, action);
            }
          });
        });
      } else {
        (0, _object.objectEach)(this.buttonEnabledList, function (headerRow, i) {
          (0, _object.objectEach)(headerRow, function (header, j) {
            var rowIndex = parseInt(i, 10);
            var columnIndex = parseInt(j, 10);

            _this4.markSectionAs(action === 'collapse' ? 'collapsed' : 'expanded', rowIndex, columnIndex, true);

            _this4.toggleCollapsibleSection({
              row: rowIndex,
              col: columnIndex
            }, action);
          });
        });
      }
    }
    /**
     * Collapses all collapsible sections.
     */

  }, {
    key: "collapseAll",
    value: function collapseAll() {
      this.toggleAllCollapsibleSections('collapse');
    }
    /**
     * Expands all collapsible sections.
     */

  }, {
    key: "expandAll",
    value: function expandAll() {
      this.toggleAllCollapsibleSections('expand');
    }
    /**
     * Collapses/Expands a section.
     *
     * @param {Object} coords Section coordinates.
     * @param {String} action Action definition ('collapse' or 'expand').
     */

  }, {
    key: "toggleCollapsibleSection",
    value: function toggleCollapsibleSection(coords, action) {
      var _this5 = this;

      if (coords.row) {
        coords.row = parseInt(coords.row, 10);
      }

      if (coords.col) {
        coords.col = parseInt(coords.col, 10);
      }

      var hiddenColumns = this.hiddenColumnsPlugin.hiddenColumns;
      var colspanArray = this.nestedHeadersPlugin.colspanArray;
      var level = this.nestedHeadersPlugin.rowCoordsToLevel(coords.row);
      var currentHeaderColspan = colspanArray[level][coords.col].colspan;
      var childHeaders = this.nestedHeadersPlugin.getChildHeaders(coords.row, coords.col);
      var nextLevel = level + 1;
      var childColspanLevel = colspanArray[nextLevel];
      var firstChildColspan = childColspanLevel ? childColspanLevel[childHeaders[0]].colspan || 1 : 1;

      while (firstChildColspan === currentHeaderColspan && nextLevel < this.columnHeaderLevelCount) {
        nextLevel += 1;
        childColspanLevel = colspanArray[nextLevel];
        firstChildColspan = childColspanLevel ? childColspanLevel[childHeaders[0]].colspan || 1 : 1;
      }

      (0, _number.rangeEach)(firstChildColspan, currentHeaderColspan - 1, function (i) {
        var colToHide = coords.col + i;

        switch (action) {
          case 'collapse':
            if (!_this5.hiddenColumnsPlugin.isHidden(colToHide)) {
              hiddenColumns.push(colToHide);
            }

            break;

          case 'expand':
            if (_this5.hiddenColumnsPlugin.isHidden(colToHide)) {
              hiddenColumns.splice(hiddenColumns.indexOf(colToHide), 1);
            }

            break;

          default:
            break;
        }
      });
      this.hot.render();
      this.hot.view.wt.wtOverlays.adjustElementsSize(true);
    }
    /**
     * Adds the indicator to the headers.
     *
     * @private
     * @param {Number} column Column index.
     * @param {HTMLElement} TH TH element.
     */

  }, {
    key: "onAfterGetColHeader",
    value: function onAfterGetColHeader(column, TH) {
      if (TH.hasAttribute('colspan') && TH.getAttribute('colspan') > 1 && column >= this.hot.getSettings().fixedColumnsLeft) {
        var button = this.generateIndicator(column, TH);

        if (button !== null) {
          TH.querySelector('div:first-child').appendChild(button);
        }
      }
    }
    /**
     * Indicator mouse event callback.
     *
     * @private
     * @param {Object} event Mouse event.
     * @param {Object} coords Event coordinates.
     */

  }, {
    key: "onBeforeOnCellMouseDown",
    value: function onBeforeOnCellMouseDown(event, coords) {
      if ((0, _element.hasClass)(event.target, 'collapsibleIndicator')) {
        if ((0, _element.hasClass)(event.target, 'expanded')) {
          // mark section as collapsed
          if (!this.collapsedSections[coords.row]) {
            this.collapsedSections[coords.row] = [];
          }

          this.markSectionAs('collapsed', coords.row, coords.col, true);
          this.eventManager.fireEvent(event.target, 'mouseup');
          this.toggleCollapsibleSection(coords, 'collapse');
        } else if ((0, _element.hasClass)(event.target, 'collapsed')) {
          this.markSectionAs('expanded', coords.row, coords.col, true);
          this.eventManager.fireEvent(event.target, 'mouseup');
          this.toggleCollapsibleSection(coords, 'expand');
        }

        (0, _event.stopImmediatePropagation)(event);
        return false;
      }
    }
    /**
     * AfterInit hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.columnHeaderLevelCount = this.hot.view.wt.getSetting('columnHeaders').length;
    }
    /**
     * AfterRender hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterRender",
    value: function onAfterRender() {
      if (!this.nestedHeadersPlugin.enabled || !this.hiddenColumnsPlugin.enabled) {
        this.disablePlugin();
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.settings = null;
      this.buttonEnabledList = null;
      this.hiddenColumnsPlugin = null;
      this.nestedHeadersPlugin = null;
      this.collapsedSections = null;
      this.columnHeaderLevelCount = null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "destroy", this).call(this);
    }
  }]);
  return CollapsibleColumns;
}(_base.default);

(0, _plugins.registerPlugin)('collapsibleColumns', CollapsibleColumns);
var _default = CollapsibleColumns;
exports.default = _default;

/***/ }),
/* 688 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

__webpack_require__(37);

__webpack_require__(46);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _object = __webpack_require__(4);

var _plugins = __webpack_require__(20);

var _endpoints = _interopRequireDefault(__webpack_require__(689));

/**
 * @plugin ColumnSummary
 *
 * @description
 * Allows making pre-defined calculations on the cell values and display the results within Handsontable.
 * [See the demo for more information](https://docs.handsontable.com/pro/demo-summary-calculations.html).
 *s
 * @example
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: getData(),
 *   colHeaders: true,
 *   rowHeaders: true,
 *   columnSummary: [
 *     {
 *       destinationRow: 4,
 *       destinationColumn: 1,
 *       type: 'min'
 *     },
 *     {
 *       destinationRow: 0,
 *       destinationColumn: 3,
 *       reversedRowCoords: true,
 *       type: 'max'
 *     },
 *     {
 *       destinationRow: 4,
 *       destinationColumn: 5,
 *       type: 'sum',
 *       forceNumeric: true
 *     }
 *   ]
 * });
 */
var ColumnSummary =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ColumnSummary, _BasePlugin);

  function ColumnSummary(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ColumnSummary);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ColumnSummary).call(this, hotInstance));
    /**
     * The Endpoints class instance. Used to make all endpoint-related operations.
     *
     * @private
     * @type {null|Endpoints}
     */

    _this.endpoints = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link ColumnSummary#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(ColumnSummary, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().columnSummary;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.settings = this.hot.getSettings().columnSummary;
      this.endpoints = new _endpoints.default(this, this.settings);
      this.addHook('afterInit', function () {
        return _this2.onAfterInit.apply(_this2, arguments);
      });
      this.addHook('afterChange', function () {
        return _this2.onAfterChange.apply(_this2, arguments);
      });
      this.addHook('beforeCreateRow', function (index, amount, source) {
        return _this2.endpoints.resetSetupBeforeStructureAlteration('insert_row', index, amount, null, source);
      });
      this.addHook('beforeCreateCol', function (index, amount, source) {
        return _this2.endpoints.resetSetupBeforeStructureAlteration('insert_col', index, amount, null, source);
      });
      this.addHook('beforeRemoveRow', function () {
        var _this2$endpoints;

        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        return (_this2$endpoints = _this2.endpoints).resetSetupBeforeStructureAlteration.apply(_this2$endpoints, ['remove_row'].concat(args));
      });
      this.addHook('beforeRemoveCol', function () {
        var _this2$endpoints2;

        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
          args[_key2] = arguments[_key2];
        }

        return (_this2$endpoints2 = _this2.endpoints).resetSetupBeforeStructureAlteration.apply(_this2$endpoints2, ['remove_col'].concat(args));
      });
      this.addHook('beforeRowMove', function () {
        return _this2.onBeforeRowMove.apply(_this2, arguments);
      });
      this.addHook('afterCreateRow', function (index, amount, source) {
        return _this2.endpoints.resetSetupAfterStructureAlteration('insert_row', index, amount, null, source);
      });
      this.addHook('afterCreateCol', function (index, amount, source) {
        return _this2.endpoints.resetSetupAfterStructureAlteration('insert_col', index, amount, null, source);
      });
      this.addHook('afterRemoveRow', function () {
        var _this2$endpoints3;

        for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
          args[_key3] = arguments[_key3];
        }

        return (_this2$endpoints3 = _this2.endpoints).resetSetupAfterStructureAlteration.apply(_this2$endpoints3, ['remove_row'].concat(args));
      });
      this.addHook('afterRemoveCol', function () {
        var _this2$endpoints4;

        for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
          args[_key4] = arguments[_key4];
        }

        return (_this2$endpoints4 = _this2.endpoints).resetSetupAfterStructureAlteration.apply(_this2$endpoints4, ['remove_col'].concat(args));
      });
      this.addHook('afterRowMove', function () {
        return _this2.onAfterRowMove.apply(_this2, arguments);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSummary.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.endpoints = null;
      this.settings = null;
      this.currentEndpoint = null;
    }
    /**
     * Calculates math for a single endpoint.
     *
     * @private
     * @param {Object} endpoint Contains information about the endpoint.
     */

  }, {
    key: "calculate",
    value: function calculate(endpoint) {
      switch (endpoint.type.toLowerCase()) {
        case 'sum':
          endpoint.result = this.calculateSum(endpoint);
          break;

        case 'min':
          endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
          break;

        case 'max':
          endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
          break;

        case 'count':
          endpoint.result = this.countEntries(endpoint);
          break;

        case 'average':
          endpoint.result = this.calculateAverage(endpoint);
          break;

        case 'custom':
          endpoint.result = endpoint.customFunction.call(this, endpoint);
          break;

        default:
          break;
      }
    }
    /**
     * Calculates sum of the values contained in ranges provided in the plugin config.
     *
     * @private
     * @param {Object} endpoint Contains the endpoint information.
     * @returns {Number} Sum for the selected range
     */

  }, {
    key: "calculateSum",
    value: function calculateSum(endpoint) {
      var _this3 = this;

      var sum = 0;
      (0, _object.objectEach)(endpoint.ranges, function (range) {
        sum += _this3.getPartialSum(range, endpoint.sourceColumn);
      });
      return sum;
    }
    /**
     * Returns partial sum of values from a single row range
     *
     * @private
     * @param {Array} rowRange Range for the sum.
     * @param {Number} col Column index.
     * @returns {Number} The partial sum.
     */

  }, {
    key: "getPartialSum",
    value: function getPartialSum(rowRange, col) {
      var sum = 0;
      var i = rowRange[1] || rowRange[0];
      var cellValue = null;
      var biggestDecimalPlacesCount = 0;

      do {
        cellValue = this.getCellValue(i, col) || 0;
        var decimalPlaces = ("".concat(cellValue).split('.')[1] || []).length || 1;

        if (decimalPlaces > biggestDecimalPlacesCount) {
          biggestDecimalPlacesCount = decimalPlaces;
        }

        sum += cellValue || 0;
        i -= 1;
      } while (i >= rowRange[0]); // Workaround for e.g. 802.2 + 1.1 = 803.3000000000001


      return Math.round(sum * Math.pow(10, biggestDecimalPlacesCount)) / Math.pow(10, biggestDecimalPlacesCount);
    }
    /**
     * Calculates the minimal value for the selected ranges
     *
     * @private
     * @param {Object} endpoint Contains the endpoint information.
     * @param {String} type `'min'` or `'max'`.
     * @returns {Number} Min or Max value.
     */

  }, {
    key: "calculateMinMax",
    value: function calculateMinMax(endpoint, type) {
      var _this4 = this;

      var result = null;
      (0, _object.objectEach)(endpoint.ranges, function (range) {
        var partialResult = _this4.getPartialMinMax(range, endpoint.sourceColumn, type);

        if (result === null && partialResult !== null) {
          result = partialResult;
        }

        if (partialResult !== null) {
          switch (type) {
            case 'min':
              result = Math.min(result, partialResult);
              break;

            case 'max':
              result = Math.max(result, partialResult);
              break;

            default:
              break;
          }
        }
      });
      return result === null ? 'Not enough data' : result;
    }
    /**
     * Returns a local minimum of the provided sub-range
     *
     * @private
     * @param {Array} rowRange Range for the calculation.
     * @param {Number} col Column index.
     * @param {String} type `'min'` or `'max'`
     * @returns {Number} Min or max value.
     */

  }, {
    key: "getPartialMinMax",
    value: function getPartialMinMax(rowRange, col, type) {
      var result = null;
      var i = rowRange[1] || rowRange[0];
      var cellValue;

      do {
        cellValue = this.getCellValue(i, col) || null;

        if (result === null) {
          result = cellValue;
        } else if (cellValue !== null) {
          switch (type) {
            case 'min':
              result = Math.min(result, cellValue);
              break;

            case 'max':
              result = Math.max(result, cellValue);
              break;

            default:
              break;
          }
        }

        i -= 1;
      } while (i >= rowRange[0]);

      return result;
    }
    /**
     * Counts empty cells in the provided row range.
     *
     * @private
     * @param {Array} rowRange Row range for the calculation.
     * @param {Number} col Column index.
     * @returns {Number} Empty cells count.
     */

  }, {
    key: "countEmpty",
    value: function countEmpty(rowRange, col) {
      var cellValue;
      var counter = 0;
      var i = rowRange[1] || rowRange[0];

      do {
        cellValue = this.getCellValue(i, col);

        if (!cellValue) {
          counter += 1;
        }

        i -= 1;
      } while (i >= rowRange[0]);

      return counter;
    }
    /**
     * Counts non-empty cells in the provided row range.
     *
     * @private
     * @param {Object} endpoint Contains the endpoint information.
     * @returns {Number} Entry count.
     */

  }, {
    key: "countEntries",
    value: function countEntries(endpoint) {
      var _this5 = this;

      var result = 0;
      var ranges = endpoint.ranges;
      (0, _object.objectEach)(ranges, function (range) {
        var partial = range[1] === void 0 ? 1 : range[1] - range[0] + 1;

        var emptyCount = _this5.countEmpty(range, endpoint.sourceColumn);

        result += partial;
        result -= emptyCount;
      });
      return result;
    }
    /**
     * Calculates the average value from the cells in the range.
     *
     * @private
     * @param {Object} endpoint Contains the endpoint information.
     * @returns {Number} Avarage value.
     */

  }, {
    key: "calculateAverage",
    value: function calculateAverage(endpoint) {
      var sum = this.calculateSum(endpoint);
      var entriesCount = this.countEntries(endpoint);
      return sum / entriesCount;
    }
    /**
     * Returns a cell value, taking into consideration a basic validation.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     * @returns {String} The cell value.
     */

  }, {
    key: "getCellValue",
    value: function getCellValue(row, col) {
      var visualRowIndex = this.endpoints.getVisualRowIndex(row);
      var visualColumnIndex = this.endpoints.getVisualColumnIndex(col);
      var cellValue = this.hot.getSourceDataAtCell(row, col);
      var cellClassName = this.hot.getCellMeta(visualRowIndex, visualColumnIndex).className || '';

      if (cellClassName.indexOf('columnSummaryResult') > -1) {
        return null;
      }

      if (this.endpoints.currentEndpoint.forceNumeric) {
        if (typeof cellValue === 'string') {
          cellValue = cellValue.replace(/,/, '.');
        }

        cellValue = parseFloat(cellValue);
      }

      if (isNaN(cellValue)) {
        if (!this.endpoints.currentEndpoint.suppressDataTypeErrors) {
          throw new Error("ColumnSummary plugin: cell at (".concat(row, ", ").concat(col, ") is not in a numeric format. Cannot do the calculation."));
        }
      }

      return cellValue;
    }
    /**
     * `afterInit` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.endpoints.endpoints = this.endpoints.parseSettings();
      this.endpoints.refreshAllEndpoints(true);
    }
    /**
     * `afterChange` hook callback.
     *
     * @private
     * @param {Array} changes
     * @param {String} source
     */

  }, {
    key: "onAfterChange",
    value: function onAfterChange(changes, source) {
      if (changes && source !== 'ColumnSummary.reset' && source !== 'ColumnSummary.set' && source !== 'loadData') {
        this.endpoints.refreshChangedEndpoints(changes);
      }
    }
    /**
     * `beforeRowMove` hook callback.
     *
     * @private
     * @param {Array} rows Array of logical rows to be moved.
     */

  }, {
    key: "onBeforeRowMove",
    value: function onBeforeRowMove(rows) {
      this.endpoints.resetSetupBeforeStructureAlteration('move_row', rows[0], rows.length, rows, this.pluginName);
    }
    /**
     * `afterRowMove` hook callback.
     *
     * @private
     * @param {Array} rows Array of logical rows that were moved.
     * @param {Number} target Index of the destination row.
     */

  }, {
    key: "onAfterRowMove",
    value: function onAfterRowMove(rows, target) {
      this.endpoints.resetSetupAfterStructureAlteration('move_row', target, rows.length, rows, this.pluginName);
    }
  }]);
  return ColumnSummary;
}(_base.default);

(0, _plugins.registerPlugin)('columnSummary', ColumnSummary);
var _default = ColumnSummary;
exports.default = _default;

/***/ }),
/* 689 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(690);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _console = __webpack_require__(55);

var _recordTranslator = __webpack_require__(90);

/**
 * Class used to make all endpoint-related operations.
 *
 * @class Endpoints
 * @plugin ColumnSummary
 */
var Endpoints =
/*#__PURE__*/
function () {
  function Endpoints(plugin, settings) {
    (0, _classCallCheck2.default)(this, Endpoints);

    /**
     * The main plugin instance.
     */
    this.plugin = plugin;
    /**
     * Handsontable instance.
     *
     * @type {Object}
     */

    this.hot = this.plugin.hot;
    /**
     * Array of declared plugin endpoints (calculation destination points).
     *
     * @type {Array}
     * @default {Array} Empty array.
     */

    this.endpoints = [];
    /**
     * The plugin settings, taken from Handsontable configuration.
     *
     * @type {Object|Function}
     * @default null
     */

    this.settings = settings;
    /**
     * Settings type. Can be either 'array' or 'function.
     *
     * @type {string}
     * @default {'array'}
     */

    this.settingsType = 'array';
    /**
     * The current endpoint (calculation destination point) in question.
     *
     * @type {Object}
     * @default null
     */

    this.currentEndpoint = null;
    /**
     * Array containing a list of changes to be applied.
     *
     * @private
     * @type {Array}
     * @default {[]}
     */

    this.cellsToSetCache = [];
    /**
     * A `recordTranslator` instance.
     * @private
     * @type {Object}
     */

    this.recordTranslator = (0, _recordTranslator.getTranslator)(this.hot);
  }
  /**
   * Get a single endpoint object.
   *
   * @param {Number} index Index of the endpoint.
   * @returns {Object}
   */


  (0, _createClass2.default)(Endpoints, [{
    key: "getEndpoint",
    value: function getEndpoint(index) {
      if (this.settingsType === 'function') {
        return this.fillMissingEndpointData(this.settings)[index];
      }

      return this.endpoints[index];
    }
    /**
     * Get an array with all the endpoints.
     *
     * @returns {Array}
     */

  }, {
    key: "getAllEndpoints",
    value: function getAllEndpoints() {
      if (this.settingsType === 'function') {
        return this.fillMissingEndpointData(this.settings);
      }

      return this.endpoints;
    }
    /**
     * Used to fill the blanks in the endpoint data provided by a settings function.
     *
     * @private
     * @param {Function} func Function provided in the HOT settings.
     * @returns {Array} An array of endpoints.
     */

  }, {
    key: "fillMissingEndpointData",
    value: function fillMissingEndpointData(func) {
      return this.parseSettings(func.call(this));
    }
    /**
     * Parse plugin's settings.
     *
     * @param {Array} settings The settings array.
     */

  }, {
    key: "parseSettings",
    value: function parseSettings(settings) {
      var _this = this;

      var endpointsArray = [];
      var settingsArray = settings;

      if (!settingsArray && typeof this.settings === 'function') {
        this.settingsType = 'function';
        return;
      }

      if (!settingsArray) {
        settingsArray = this.settings;
      }

      (0, _array.arrayEach)(settingsArray, function (val) {
        var newEndpoint = {};

        _this.assignSetting(val, newEndpoint, 'ranges', [[0, _this.hot.countRows() - 1]]);

        _this.assignSetting(val, newEndpoint, 'reversedRowCoords', false);

        _this.assignSetting(val, newEndpoint, 'destinationRow', new Error("\n        You must provide a destination row for the Column Summary plugin in order to work properly!\n      "));

        _this.assignSetting(val, newEndpoint, 'destinationColumn', new Error("\n        You must provide a destination column for the Column Summary plugin in order to work properly!\n      "));

        _this.assignSetting(val, newEndpoint, 'sourceColumn', val.destinationColumn);

        _this.assignSetting(val, newEndpoint, 'type', 'sum');

        _this.assignSetting(val, newEndpoint, 'forceNumeric', false);

        _this.assignSetting(val, newEndpoint, 'suppressDataTypeErrors', true);

        _this.assignSetting(val, newEndpoint, 'suppressDataTypeErrors', true);

        _this.assignSetting(val, newEndpoint, 'customFunction', null);

        _this.assignSetting(val, newEndpoint, 'readOnly', true);

        _this.assignSetting(val, newEndpoint, 'roundFloat', false);

        endpointsArray.push(newEndpoint);
      });
      return endpointsArray;
    }
    /**
     * Setter for the internal setting objects.
     *
     * @param {Object} settings Object with the settings.
     * @param {Object} endpoint Contains information about the endpoint for the the calculation.
     * @param {String} name Settings name.
     * @param defaultValue Default value for the settings.
     */

  }, {
    key: "assignSetting",
    value: function assignSetting(settings, endpoint, name, defaultValue) {
      if (name === 'ranges' && settings[name] === void 0) {
        endpoint[name] = defaultValue;
        return;
      } else if (name === 'ranges' && settings[name].length === 0) {
        return;
      }

      if (settings[name] === void 0) {
        if (defaultValue instanceof Error) {
          throw defaultValue;
        }

        endpoint[name] = defaultValue;
      } else {
        /* eslint-disable no-lonely-if */
        if (name === 'destinationRow' && endpoint.reversedRowCoords) {
          endpoint[name] = this.hot.countRows() - settings[name] - 1;
        } else {
          endpoint[name] = settings[name];
        }
      }
    }
    /**
     * Resets the endpoint setup before the structure alteration (like inserting or removing rows/columns). Used for settings provided as a function.
     *
     * @private
     * @param {String} action Type of the action performed.
     * @param {Number} index Row/column index.
     * @param {Number} number Number of rows/columns added/removed.
     */

  }, {
    key: "resetSetupBeforeStructureAlteration",
    value: function resetSetupBeforeStructureAlteration(action, index, number) {
      if (this.settingsType !== 'function') {
        return;
      }

      var type = action.indexOf('row') > -1 ? 'row' : 'col';
      var endpoints = this.getAllEndpoints();
      (0, _array.arrayEach)(endpoints, function (val) {
        if (type === 'row' && val.destinationRow >= index) {
          if (action === 'insert_row') {
            val.alterRowOffset = number;
          } else if (action === 'remove_row') {
            val.alterRowOffset = -1 * number;
          }
        }

        if (type === 'col' && val.destinationColumn >= index) {
          if (action === 'insert_col') {
            val.alterColumnOffset = number;
          } else if (action === 'remove_col') {
            val.alterColumnOffset = -1 * number;
          }
        }
      });
      this.resetAllEndpoints(endpoints, false);
    }
    /**
     * afterCreateRow/afterCreateRow/afterRemoveRow/afterRemoveCol hook callback. Reset and reenables the summary functionality
     * after changing the table structure.
     *
     * @private
     * @param {String} action Type of the action performed.
     * @param {Number} index Row/column index.
     * @param {Number} number Number of rows/columns added/removed.
     * @param {Array} [logicRows] Array of the logical indexes.
     * @param {String} [source] Source of change.
     * @param {Boolean} [forceRefresh] `true` of the endpoints should refresh after completing the function.
     */

  }, {
    key: "resetSetupAfterStructureAlteration",
    value: function resetSetupAfterStructureAlteration(action, index, number, logicRows, source) {
      var _this2 = this;

      var forceRefresh = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;

      if (this.settingsType === 'function') {
        // We need to run it on a next avaiable hook, because the TrimRows' `afterCreateRow` hook triggers after this one,
        // and it needs to be run to properly calculate the endpoint value.
        var beforeRenderCallback = function beforeRenderCallback() {
          _this2.hot.removeHook('beforeRender', beforeRenderCallback);

          return _this2.refreshAllEndpoints();
        };

        this.hot.addHookOnce('beforeRender', beforeRenderCallback);
        return;
      }

      var type = action.indexOf('row') > -1 ? 'row' : 'col';
      var multiplier = action.indexOf('remove') > -1 ? -1 : 1;
      var endpoints = this.getAllEndpoints();
      var rowMoving = action.indexOf('move_row') === 0;
      var placeOfAlteration = index;
      (0, _array.arrayEach)(endpoints, function (val) {
        if (type === 'row' && val.destinationRow >= placeOfAlteration) {
          val.alterRowOffset = multiplier * number;
        }

        if (type === 'col' && val.destinationColumn >= placeOfAlteration) {
          val.alterColumnOffset = multiplier * number;
        }
      });
      this.resetAllEndpoints(endpoints, !rowMoving);

      if (rowMoving) {
        (0, _array.arrayEach)(endpoints, function (endpoint) {
          _this2.extendEndpointRanges(endpoint, placeOfAlteration, logicRows[0], logicRows.length);

          _this2.recreatePhysicalRanges(endpoint);

          _this2.clearOffsetInformation(endpoint);
        });
      } else {
        (0, _array.arrayEach)(endpoints, function (endpoint) {
          _this2.shiftEndpointCoordinates(endpoint, placeOfAlteration);
        });
      }

      if (forceRefresh) {
        this.refreshAllEndpoints();
      }
    }
    /**
     * Clear the offset information from the endpoint object.
     *
     * @private
     * @param {Object} endpoint And endpoint object.
     */

  }, {
    key: "clearOffsetInformation",
    value: function clearOffsetInformation(endpoint) {
      endpoint.alterRowOffset = void 0;
      endpoint.alterColumnOffset = void 0;
    }
    /**
     * Extend the row ranges for the provided endpoint.
     *
     * @private
     * @param {Object} endpoint The endpoint object.
     * @param {Number} placeOfAlteration Index of the row where the alteration takes place.
     * @param {Number} previousPosition Previous endpoint result position.
     * @param {Number} offset Offset generated by the alteration.
     */

  }, {
    key: "extendEndpointRanges",
    value: function extendEndpointRanges(endpoint, placeOfAlteration, previousPosition, offset) {
      (0, _array.arrayEach)(endpoint.ranges, function (range) {
        // is a range, not a single row
        if (range[1]) {
          if (placeOfAlteration >= range[0] && placeOfAlteration <= range[1]) {
            if (previousPosition > range[1]) {
              range[1] += offset;
            } else if (previousPosition < range[0]) {
              range[0] -= offset;
            }
          } else if (previousPosition >= range[0] && previousPosition <= range[1]) {
            range[1] -= offset;

            if (placeOfAlteration <= range[0]) {
              range[0] += 1;
              range[1] += 1;
            }
          }
        }
      });
    }
    /**
     * Recreate the physical ranges for the provided endpoint. Used (for example) when a row gets moved and extends an existing range.
     *
     * @private
     * @param {Object} endpoint An endpoint object.
     */

  }, {
    key: "recreatePhysicalRanges",
    value: function recreatePhysicalRanges(endpoint) {
      var _this3 = this;

      var ranges = endpoint.ranges;
      var newRanges = [];
      var allIndexes = [];
      (0, _array.arrayEach)(ranges, function (range) {
        var newRange = [];

        if (range[1]) {
          for (var i = range[0]; i <= range[1]; i++) {
            newRange.push(_this3.recordTranslator.toPhysicalRow(i));
          }
        } else {
          newRange.push(_this3.recordTranslator.toPhysicalRow(range[0]));
        }

        allIndexes.push(newRange);
      });
      (0, _array.arrayEach)(allIndexes, function (range) {
        var newRange = [];
        (0, _array.arrayEach)(range, function (coord, index) {
          if (index === 0) {
            newRange.push(coord);
          } else if (range[index] !== range[index - 1] + 1) {
            newRange.push(range[index - 1]);
            newRanges.push(newRange);
            newRange = [];
            newRange.push(coord);
          }

          if (index === range.length - 1) {
            newRange.push(coord);
            newRanges.push(newRange);
          }
        });
      });
      endpoint.ranges = newRanges;
    }
    /**
     * Shifts the endpoint coordinates by the defined offset.
     *
     * @private
     * @param {Object} endpoint Endpoint object.
     * @param {Number} offsetStartIndex Index of the performed change (if the change is located after the endpoint, nothing about the endpoint has to be changed.
     */

  }, {
    key: "shiftEndpointCoordinates",
    value: function shiftEndpointCoordinates(endpoint, offsetStartIndex) {
      if (endpoint.alterRowOffset && endpoint.alterRowOffset !== 0) {
        endpoint.destinationRow += endpoint.alterRowOffset || 0;
        (0, _array.arrayEach)(endpoint.ranges, function (element) {
          (0, _array.arrayEach)(element, function (subElement, j) {
            if (subElement >= offsetStartIndex) {
              element[j] += endpoint.alterRowOffset || 0;
            }
          });
        });
      } else if (endpoint.alterColumnOffset && endpoint.alterColumnOffset !== 0) {
        endpoint.destinationColumn += endpoint.alterColumnOffset || 0;
        endpoint.sourceColumn += endpoint.alterColumnOffset || 0;
      }
    }
    /**
     * Resets (removes) the endpoints from the table.
     *
     * @param {Array} endpoints Array containing the endpoints.
     * @param {Boolean} [useOffset=true] Use the cell offset value.
     */

  }, {
    key: "resetAllEndpoints",
    value: function resetAllEndpoints(endpoints) {
      var _this4 = this;

      var useOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var endpointsArray = endpoints;
      this.cellsToSetCache = [];

      if (!endpointsArray) {
        endpointsArray = this.getAllEndpoints();
      }

      (0, _array.arrayEach)(endpointsArray, function (value) {
        _this4.resetEndpointValue(value, useOffset);
      });
      this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
      this.cellsToSetCache = [];
    }
    /**
     * Calculate and refresh all defined endpoints.
     */

  }, {
    key: "refreshAllEndpoints",
    value: function refreshAllEndpoints() {
      var _this5 = this;

      this.cellsToSetCache = [];
      (0, _array.arrayEach)(this.getAllEndpoints(), function (value) {
        _this5.currentEndpoint = value;

        _this5.plugin.calculate(value);

        _this5.setEndpointValue(value, 'init');
      });
      this.currentEndpoint = null;
      this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
      this.cellsToSetCache = [];
    }
    /**
     * Calculate and refresh endpoints only in the changed columns.
     *
     * @param {Array} changes Array of changes from the `afterChange` hook.
     */

  }, {
    key: "refreshChangedEndpoints",
    value: function refreshChangedEndpoints(changes) {
      var _this6 = this;

      var needToRefresh = [];
      this.cellsToSetCache = [];
      (0, _array.arrayEach)(changes, function (value, key, changesObj) {
        // if nothing changed, dont update anything
        if ("".concat(value[2] || '') === "".concat(value[3])) {
          return;
        }

        (0, _array.arrayEach)(_this6.getAllEndpoints(), function (endpoint, j) {
          if (_this6.hot.propToCol(changesObj[key][1]) === endpoint.sourceColumn && needToRefresh.indexOf(j) === -1) {
            needToRefresh.push(j);
          }
        });
      });
      (0, _array.arrayEach)(needToRefresh, function (value) {
        _this6.refreshEndpoint(_this6.getEndpoint(value));
      });
      this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
      this.cellsToSetCache = [];
    }
    /**
     * Calculate and refresh a single endpoint.
     *
     * @param {Object} endpoint Contains the endpoint information.
     */

  }, {
    key: "refreshEndpoint",
    value: function refreshEndpoint(endpoint) {
      this.currentEndpoint = endpoint;
      this.plugin.calculate(endpoint);
      this.setEndpointValue(endpoint);
      this.currentEndpoint = null;
    }
    /**
     * Reset the endpoint value.
     *
     * @param {Object} endpoint Contains the endpoint information.
     * @param {Boolean} [useOffset=true] Use the cell offset value.
     */

  }, {
    key: "resetEndpointValue",
    value: function resetEndpointValue(endpoint) {
      var useOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var alterRowOffset = endpoint.alterRowOffset || 0;
      var alterColOffset = endpoint.alterColumnOffset || 0;

      var _this$recordTranslato = this.recordTranslator.toVisual(endpoint.destinationRow, endpoint.destinationColumn),
          _this$recordTranslato2 = (0, _slicedToArray2.default)(_this$recordTranslato, 2),
          visualRowIndex = _this$recordTranslato2[0],
          visualColumnIndex = _this$recordTranslato2[1]; // Clear the meta on the "old" indexes


      var cellMeta = this.hot.getCellMeta(visualRowIndex, visualColumnIndex);
      cellMeta.readOnly = false;
      cellMeta.className = '';
      this.cellsToSetCache.push([this.recordTranslator.toVisualRow(endpoint.destinationRow + (useOffset ? alterRowOffset : 0)), this.recordTranslator.toVisualColumn(endpoint.destinationColumn + (useOffset ? alterColOffset : 0)), '']);
    }
    /**
     * Set the endpoint value.
     *
     * @param {Object} endpoint Contains the endpoint information.
     * @param {String} [source] Source of the call information.
     * @param {Boolean} [render=false] `true` if it needs to render the table afterwards.
     */

  }, {
    key: "setEndpointValue",
    value: function setEndpointValue(endpoint, source) {
      var render = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      // We'll need the reversed offset values, because cellMeta will be shifted AGAIN afterwards.
      var reverseRowOffset = -1 * endpoint.alterRowOffset || 0;
      var reverseColOffset = -1 * endpoint.alterColumnOffset || 0;
      var visualEndpointRowIndex = this.getVisualRowIndex(endpoint.destinationRow);
      var cellMeta = this.hot.getCellMeta(this.getVisualRowIndex(endpoint.destinationRow + reverseRowOffset), endpoint.destinationColumn + reverseColOffset);

      if (visualEndpointRowIndex > this.hot.countRows() || endpoint.destinationColumn > this.hot.countCols()) {
        this.throwOutOfBoundsWarning();
        return;
      }

      if (source === 'init' || cellMeta.readOnly !== endpoint.readOnly) {
        cellMeta.readOnly = endpoint.readOnly;
        cellMeta.className = 'columnSummaryResult';
      }

      if (endpoint.roundFloat && !isNaN(endpoint.result)) {
        endpoint.result = endpoint.result.toFixed(endpoint.roundFloat);
      }

      if (render) {
        this.hot.setDataAtCell(visualEndpointRowIndex, endpoint.destinationColumn, endpoint.result, 'ColumnSummary.set');
      } else {
        this.cellsToSetCache.push([visualEndpointRowIndex, endpoint.destinationColumn, endpoint.result]);
      }

      endpoint.alterRowOffset = void 0;
      endpoint.alterColumnOffset = void 0;
    }
    /**
     * Get the visual row index for the provided row. Uses the `umodifyRow` hook.
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Number}
     */

  }, {
    key: "getVisualRowIndex",
    value: function getVisualRowIndex(row) {
      return this.hot.runHooks('unmodifyRow', row, 'columnSummary');
    }
    /**
     * Get the visual column index for the provided column. Uses the `umodifyColumn` hook.
     *
     * @private
     * @param {Number} column Column index.
     * @returns {Number}
     */

  }, {
    key: "getVisualColumnIndex",
    value: function getVisualColumnIndex(column) {
      return this.hot.runHooks('unmodifyCol', column, 'columnSummary');
    }
    /**
     * Throw an error for the calculation range being out of boundaries.
     *
     * @private
     */

  }, {
    key: "throwOutOfBoundsWarning",
    value: function throwOutOfBoundsWarning() {
      (0, _console.warn)('One of the  Column Summary plugins\' destination points you provided is beyond the table boundaries!');
    }
  }]);
  return Endpoints;
}();

var _default = Endpoints;
exports.default = _default;

/***/ }),
/* 690 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toInteger = __webpack_require__(86);
var thisNumberValue = __webpack_require__(691);
var repeat = __webpack_require__(205);
var nativeToFixed = 1.0.toFixed;
var floor = Math.floor;
var data = [0, 0, 0, 0, 0, 0];

var multiply = function (n, c) {
  var i = -1;
  var c2 = c;
  while (++i < 6) {
    c2 += n * data[i];
    data[i] = c2 % 1e7;
    c2 = floor(c2 / 1e7);
  }
};

var divide = function (n) {
  var i = 6;
  var c = 0;
  while (--i >= 0) {
    c += data[i];
    data[i] = floor(c / n);
    c = (c % n) * 1e7;
  }
};

var numToString = function () {
  var i = 6;
  var s = '';
  while (--i >= 0) {
    if (s !== '' || i === 0 || data[i] !== 0) {
      var t = String(data[i]);
      s = s === '' ? t : s + repeat.call('0', 7 - t.length) + t;
    }
  } return s;
};

var pow = function (x, n, acc) {
  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};

var log = function (x) {
  var n = 0;
  var x2 = x;
  while (x2 >= 4096) {
    n += 12;
    x2 /= 4096;
  }
  while (x2 >= 2) {
    n += 1;
    x2 /= 2;
  } return n;
};

// `Number.prototype.toFixed` method
// https://tc39.github.io/ecma262/#sec-number.prototype.tofixed
__webpack_require__(22)({ target: 'Number', proto: true, forced: nativeToFixed && (
  0.00008.toFixed(3) !== '0.000' ||
  0.9.toFixed(0) !== '1' ||
  1.255.toFixed(2) !== '1.25' ||
  1000000000000000128.0.toFixed(0) !== '1000000000000000128'
) || !__webpack_require__(29)(function () {
  // V8 ~ Android 4.3-
  nativeToFixed.call({});
}) }, {
  toFixed: function toFixed(fractionDigits) {
    var x = thisNumberValue(this);
    var f = toInteger(fractionDigits);
    var s = '';
    var m = '0';
    var e, z, j, k;
    if (f < 0 || f > 20) throw RangeError('Incorrect fraction digits');
    // eslint-disable-next-line no-self-compare
    if (x != x) return 'NaN';
    if (x <= -1e21 || x >= 1e21) return String(x);
    if (x < 0) {
      s = '-';
      x = -x;
    }
    if (x > 1e-21) {
      e = log(x * pow(2, 69, 1)) - 69;
      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
      z *= 0x10000000000000;
      e = 52 - e;
      if (e > 0) {
        multiply(0, z);
        j = f;
        while (j >= 7) {
          multiply(1e7, 0);
          j -= 7;
        }
        multiply(pow(10, j, 1), 0);
        j = e - 1;
        while (j >= 23) {
          divide(1 << 23);
          j -= 23;
        }
        divide(1 << j);
        multiply(1, 1);
        divide(2);
        m = numToString();
      } else {
        multiply(0, z);
        multiply(1 << -e, 0);
        m = numToString() + repeat.call('0', f);
      }
    }
    if (f > 0) {
      k = m.length;
      m = s + (k <= f ? '0.' + repeat.call('0', f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
    } else {
      m = s + m;
    } return m;
  }
});


/***/ }),
/* 691 */
/***/ (function(module, exports, __webpack_require__) {

var classof = __webpack_require__(77);

// `thisNumberValue` abstract operation
// https://tc39.github.io/ecma262/#sec-thisnumbervalue
module.exports = function (value) {
  if (typeof value != 'number' && classof(value) != 'Number') {
    throw TypeError('Incorrect invocation');
  }
  return +value;
};


/***/ }),
/* 692 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _array = __webpack_require__(3);

var _commandExecutor = _interopRequireDefault(__webpack_require__(488));

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _element = __webpack_require__(5);

var _itemsFactory = _interopRequireDefault(__webpack_require__(489));

var _menu = _interopRequireDefault(__webpack_require__(167));

var _plugins = __webpack_require__(20);

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _event = __webpack_require__(31);

var _predefinedItems = __webpack_require__(83);

__webpack_require__(693);

_pluginHooks.default.getSingleton().register('afterDropdownMenuDefaultOptions');

_pluginHooks.default.getSingleton().register('beforeDropdownMenuShow');

_pluginHooks.default.getSingleton().register('afterDropdownMenuShow');

_pluginHooks.default.getSingleton().register('afterDropdownMenuHide');

_pluginHooks.default.getSingleton().register('afterDropdownMenuExecute');

var BUTTON_CLASS_NAME = 'changeType';
/**
 * @plugin DropdownMenu
 * @dependencies ContextMenu
 *
 * @description
 * This plugin creates the Handsontable Dropdown Menu. It allows to create a new row or column at any place in the grid
 * among [other features](http://docs.handsontable.com/demo-context-menu.html).
 * Possible values:
 * * `true` (to enable default options),
 * * `false` (to disable completely)
 *
 * or array of any available strings:
 * * `["row_above", "row_below", "col_left", "col_right",
 * "remove_row", "remove_col", "---------", "undo", "redo"]`.
 *
 * See [the dropdown menu demo](http://docs.handsontable.com/demo-dropdown-menu.html) for examples.
 *
 * @example
 * ```
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: data,
 *   colHeaders: true,
 *   // enable dropdown menu
 *   dropdownMenu: true
 * });
 *
 * // or
 * const hot = new Handsontable(container, {
 *   data: data,
 *   colHeaders: true,
 *   // enable and configure dropdown menu
 *   dropdownMenu: ['remove_col', '---------', 'make_read_only', 'alignment']
 * });
 * ```
 */

var DropdownMenu =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(DropdownMenu, _BasePlugin);
  (0, _createClass2.default)(DropdownMenu, null, [{
    key: "DEFAULT_ITEMS",

    /**
     * Default menu items order when `dropdownMenu` is enabled by setting the config item to `true`.
     *
     * @returns {Array}
     */
    get: function get() {
      return [_predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.CLEAR_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT];
    }
  }]);

  function DropdownMenu(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, DropdownMenu);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DropdownMenu).call(this, hotInstance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Instance of {@link CommandExecutor}.
     *
     * @private
     * @type {CommandExecutor}
     */

    _this.commandExecutor = new _commandExecutor.default(_this.hot);
    /**
     * Instance of {@link ItemsFactory}.
     *
     * @private
     * @type {ItemsFactory}
     */

    _this.itemsFactory = null;
    /**
     * Instance of {@link Menu}.
     *
     * @private
     * @type {Menu}
     */

    _this.menu = null; // One listener for enable/disable functionality

    _this.hot.addHook('afterGetColHeader', function (col, TH) {
      return _this.onAfterGetColHeader(col, TH);
    });

    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link DropdownMenu#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(DropdownMenu, [{
    key: "isEnabled",
    value: function isEnabled() {
      return this.hot.getSettings().dropdownMenu;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     *
     * @fires Hooks#afterDropdownMenuDefaultOptions
     * @fires Hooks#beforeDropdownMenuSetItems
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.itemsFactory = new _itemsFactory.default(this.hot, DropdownMenu.DEFAULT_ITEMS);
      var settings = this.hot.getSettings().dropdownMenu;
      var predefinedItems = {
        items: this.itemsFactory.getItems(settings)
      };
      this.registerEvents();

      if (typeof settings.callback === 'function') {
        this.commandExecutor.setCommonCallback(settings.callback);
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "enablePlugin", this).call(this);
      this.callOnPluginsReady(function () {
        _this2.hot.runHooks('afterDropdownMenuDefaultOptions', predefinedItems);

        _this2.itemsFactory.setPredefinedItems(predefinedItems.items);

        var menuItems = _this2.itemsFactory.getItems(settings);

        if (_this2.menu) {
          _this2.menu.destroy();
        }

        _this2.menu = new _menu.default(_this2.hot, {
          className: 'htDropdownMenu',
          keepInViewport: true
        });

        _this2.hot.runHooks('beforeDropdownMenuSetItems', menuItems);

        _this2.menu.setMenuItems(menuItems);

        _this2.menu.addLocalHook('beforeOpen', function () {
          return _this2.onMenuBeforeOpen();
        });

        _this2.menu.addLocalHook('afterOpen', function () {
          return _this2.onMenuAfterOpen();
        });

        _this2.menu.addLocalHook('afterClose', function () {
          return _this2.onMenuAfterClose();
        });

        _this2.menu.addLocalHook('executeCommand', function () {
          var _this2$executeCommand;

          for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
            params[_key] = arguments[_key];
          }

          return (_this2$executeCommand = _this2.executeCommand).call.apply(_this2$executeCommand, [_this2].concat(params));
        }); // Register all commands. Predefined and added by user or by plugins


        (0, _array.arrayEach)(menuItems, function (command) {
          return _this2.commandExecutor.registerCommand(command.key, command);
        });
      });
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.close();

      if (this.menu) {
        this.menu.destroy();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Registers the DOM listeners.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this3 = this;

      this.eventManager.addEventListener(this.hot.rootElement, 'click', function (event) {
        return _this3.onTableClick(event);
      });
    }
    /**
     * Opens menu and re-position it based on the passed coordinates.
     *
     * @param {Object|Event} position An object with `pageX` and `pageY` properties which contains values relative to
     *                                the top left of the fully rendered content area in the browser or with `clientX`
     *                                and `clientY`  properties which contains values relative to the upper left edge
     *                                of the content area (the viewport) of the browser window. This object is structurally
     *                                compatible with native mouse event so it can be used either.
     * @fires Hooks#beforeDropdownMenuShow
     * @fires Hooks#afterDropdownMenuShow
     */

  }, {
    key: "open",
    value: function open(position) {
      if (!this.menu) {
        return;
      }

      this.menu.open();

      if (position.width) {
        this.menu.setOffset('left', position.width);
      }

      this.menu.setPosition(position); // ContextMenu is not detected HotTableEnv correctly because is injected outside hot-table

      this.menu.hotMenu.isHotTableEnv = this.hot.isHotTableEnv; // Handsontable.eventManager.isHotTableEnv = this.hot.isHotTableEnv;
    }
    /**
     * Closes dropdown menu.
     */

  }, {
    key: "close",
    value: function close() {
      if (!this.menu) {
        return;
      }

      this.menu.close();
    }
    /**
     * Executes context menu command.
     *
     * You can execute all predefined commands:
     *  * `'row_above'` - Insert row above
     *  * `'row_below'` - Insert row below
     *  * `'col_left'` - Insert column left
     *  * `'col_right'` - Insert column right
     *  * `'clear_column'` - Clear selected column
     *  * `'remove_row'` - Remove row
     *  * `'remove_col'` - Remove column
     *  * `'undo'` - Undo last action
     *  * `'redo'` - Redo last action
     *  * `'make_read_only'` - Make cell read only
     *  * `'alignment:left'` - Alignment to the left
     *  * `'alignment:top'` - Alignment to the top
     *  * `'alignment:right'` - Alignment to the right
     *  * `'alignment:bottom'` - Alignment to the bottom
     *  * `'alignment:middle'` - Alignment to the middle
     *  * `'alignment:center'` - Alignment to the center (justify)
     *
     * Or you can execute command registered in settings where `key` is your command name.
     *
     * @param {String} commandName Command name to execute.
     * @param {*} params
     */

  }, {
    key: "executeCommand",
    value: function executeCommand(commandName) {
      var _this$commandExecutor;

      for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        params[_key2 - 1] = arguments[_key2];
      }

      (_this$commandExecutor = this.commandExecutor).execute.apply(_this$commandExecutor, [commandName].concat(params));
    }
    /**
     * Turns on / off listening on dropdown menu
     *
     * @private
     * @param {Boolean} listen Turn on listening when value is set to true, otherwise turn it off.
     */

  }, {
    key: "setListening",
    value: function setListening() {
      var listen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

      if (this.menu.isOpened()) {
        if (listen) {
          this.menu.hotMenu.listen();
        } else {
          this.menu.hotMenu.unlisten();
        }
      }
    }
    /**
     * Table click listener.
     *
     * @private
     * @param {Event} event
     */

  }, {
    key: "onTableClick",
    value: function onTableClick(event) {
      (0, _event.stopPropagation)(event);

      if ((0, _element.hasClass)(event.target, BUTTON_CLASS_NAME) && !this.menu.isOpened()) {
        var rect = event.target.getBoundingClientRect();
        this.open({
          left: rect.left,
          top: rect.top + event.target.offsetHeight + 3,
          width: rect.width,
          height: rect.height
        });
      }
    }
    /**
     * On after get column header listener.
     *
     * @private
     * @param {Number} col
     * @param {HTMLTableCellElement} TH
     */

  }, {
    key: "onAfterGetColHeader",
    value: function onAfterGetColHeader(col, TH) {
      // Corner or a higher-level header
      var headerRow = TH.parentNode;

      if (!headerRow) {
        return;
      }

      var headerRowList = headerRow.parentNode.childNodes;
      var level = Array.prototype.indexOf.call(headerRowList, headerRow);

      if (col < 0 || level !== headerRowList.length - 1) {
        return;
      }

      var existingButton = TH.querySelector(".".concat(BUTTON_CLASS_NAME)); // Plugin enabled and buttons already exists, return.

      if (this.enabled && existingButton) {
        return;
      } // Plugin disabled and buttons still exists, so remove them.


      if (!this.enabled) {
        if (existingButton) {
          existingButton.parentNode.removeChild(existingButton);
        }

        return;
      }

      var button = this.hot.rootDocument.createElement('button');
      button.className = BUTTON_CLASS_NAME; // prevent page reload on button click

      button.onclick = function () {
        return false;
      };

      TH.firstChild.insertBefore(button, TH.firstChild.firstChild);
    }
    /**
     * On menu before open listener.
     *
     * @private
     * @fires Hooks#beforeDropdownMenuShow
     */

  }, {
    key: "onMenuBeforeOpen",
    value: function onMenuBeforeOpen() {
      this.hot.runHooks('beforeDropdownMenuShow', this);
    }
    /**
     * On menu after open listener.
     *
     * @private
     * @fires Hooks#afterDropdownMenuShow
     */

  }, {
    key: "onMenuAfterOpen",
    value: function onMenuAfterOpen() {
      this.hot.runHooks('afterDropdownMenuShow', this);
    }
    /**
     * On menu after close listener.
     *
     * @private
     * @fires Hooks#afterDropdownMenuHide
     */

  }, {
    key: "onMenuAfterClose",
    value: function onMenuAfterClose() {
      this.hot.listen();
      this.hot.runHooks('afterDropdownMenuHide', this);
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.close();

      if (this.menu) {
        this.menu.destroy();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "destroy", this).call(this);
    }
  }]);
  return DropdownMenu;
}(_base.default);

DropdownMenu.SEPARATOR = {
  name: _predefinedItems.SEPARATOR
};
(0, _plugins.registerPlugin)('dropdownMenu', DropdownMenu);
var _default = DropdownMenu;
exports.default = _default;

/***/ }),
/* 693 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 694 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _dataProvider = _interopRequireDefault(__webpack_require__(695));

var _typeFactory = _interopRequireWildcard(__webpack_require__(696));

/**
 * @plugin ExportFile
 *
 * @description
 * The plugin enables exporting table data to file. It allows to export data as a string, blob or a downloadable file in
 * CSV format.
 *
 * See [the export file demo](https://docs.handsontable.com/demo-export-file.html) for examples.
 *
 * @example
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: getData()
 * });
 *
 * // access to exportFile plugin instance
 * const exportPlugin = hot.getPlugin('exportFile');
 *
 * // export as a string
 * exportPlugin.exportAsString('csv');
 *
 * // export as a blob object
 * exportPlugin.exportAsBlob('csv');
 *
 * // export to downloadable file (named: MyFile.csv)
 * exportPlugin.downloadFile('csv', {filename: 'MyFile'});
 *
 * // export as a string (with specified data range):
 * exportPlugin.exportAsString('csv', {
 *   exportHiddenRows: true,     // default false
 *   exportHiddenColumns: true,  // default false
 *   columnHeaders: true,        // default false
 *   rowHeaders: true,           // default false
 *   columnDelimiter: ';',       // default ','
 *   range: [1, 1, 6, 6]         // [startRow, endRow, startColumn, endColumn]
 * });
 * ```
 */
var ExportFile =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(ExportFile, _BasePlugin);

  function ExportFile() {
    (0, _classCallCheck2.default)(this, ExportFile);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ExportFile).apply(this, arguments));
  }

  (0, _createClass2.default)(ExportFile, [{
    key: "isEnabled",

    /**
     * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
     * hook and if it returns `true` than the {@link ExportFile#enablePlugin} method is called.
     *
     * @returns {Boolean}
     */
    value: function isEnabled() {
      return true;
    }
    /**
     * @typedef ExportOptions
     * @memberof ExportFile
     * @type {object}
     * @property {boolean} [exportHiddenRows=false] Include hidden rows in the exported file.
     * @property {boolean} [exportHiddenColumns=false] Include hidden columns in the exported file.
     * @property {boolean} [columnHeaders=false] Include column headers in the exported file.
     * @property {boolean} [rowHeaders=false] Include row headers in the exported file.
     * @property {string} [columnDelimiter=','] Column delimiter.
     * @property {string} [range=[]] Cell range that will be exported to file.
     */

    /**
     * Exports table data as a string.
     *
     * @param {String} format Export format type eq. `'csv'`.
     * @param {ExportOptions} options Export options.
    */

  }, {
    key: "exportAsString",
    value: function exportAsString(format) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      return this._createTypeFormatter(format, options).export();
    }
    /**
     * Exports table data as a blob object.
     *
     * @param {String} format Export format type eq. `'csv'`.
     * @param {ExportOptions} options Export options.
    */

  }, {
    key: "exportAsBlob",
    value: function exportAsBlob(format) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      return this._createBlob(this._createTypeFormatter(format, options));
    }
    /**
     * Exports table data as a downloadable file.
     *
     * @param {String} format Export format type eq. `'csv'`.
     * @param {ExportOptions} options Export options.
     */

  }, {
    key: "downloadFile",
    value: function downloadFile(format) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var _this$hot = this.hot,
          rootDocument = _this$hot.rootDocument,
          rootWindow = _this$hot.rootWindow;

      var formatter = this._createTypeFormatter(format, options);

      var blob = this._createBlob(formatter);

      var URL = rootWindow.URL || rootWindow.webkitURL;
      var a = rootDocument.createElement('a');
      var name = "".concat(formatter.options.filename, ".").concat(formatter.options.fileExtension);

      if (a.download !== void 0) {
        var url = URL.createObjectURL(blob);
        a.style.display = 'none';
        a.setAttribute('href', url);
        a.setAttribute('download', name);
        rootDocument.body.appendChild(a);
        a.dispatchEvent(new MouseEvent('click'));
        rootDocument.body.removeChild(a);
        setTimeout(function () {
          URL.revokeObjectURL(url);
        }, 100);
      } else if (navigator.msSaveOrOpenBlob) {
        // IE10+
        navigator.msSaveOrOpenBlob(blob, name);
      }
    }
    /**
     * Creates and returns class formatter for specified export type.
     *
     * @private
     * @param {String} format Export format type eq. `'csv'`.
     * @param {ExportOptions} options Export options.
     */

  }, {
    key: "_createTypeFormatter",
    value: function _createTypeFormatter(format) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

      if (!_typeFactory.EXPORT_TYPES[format]) {
        throw new Error("Export format type \"".concat(format, "\" is not supported."));
      }

      return (0, _typeFactory.default)(format, new _dataProvider.default(this.hot), options);
    }
    /**
     * Creates blob object based on provided type formatter class.
     *
     * @private
     * @param {BaseType} typeFormatter
     * @returns {Blob}
     */

  }, {
    key: "_createBlob",
    value: function _createBlob(typeFormatter) {
      var formatter = null;

      if (typeof Blob !== 'undefined') {
        formatter = new Blob([typeFormatter.export()], {
          type: "".concat(typeFormatter.options.mimeType, ";charset=").concat(typeFormatter.options.encoding)
        });
      }

      return formatter;
    }
  }]);
  return ExportFile;
}(_base.default);

(0, _plugins.registerPlugin)('exportFile', ExportFile);
var _default = ExportFile;
exports.default = _default;

/***/ }),
/* 695 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _number = __webpack_require__(15);

// Waiting for jshint >=2.9.0 where they added support for destructing
// jshint ignore: start

/**
 * @plugin ExportFile
 * @private
 */
var DataProvider =
/*#__PURE__*/
function () {
  function DataProvider(hotInstance) {
    (0, _classCallCheck2.default)(this, DataProvider);

    /**
     * Handsontable instance.
     *
     * @type {Core}
     */
    this.hot = hotInstance;
    /**
     * Format type class options.
     *
     * @type {Object}
     */

    this.options = {};
  }
  /**
   * Set options for data provider.
   *
   * @param {Object} options Object with specified options.
   */


  (0, _createClass2.default)(DataProvider, [{
    key: "setOptions",
    value: function setOptions(options) {
      this.options = options;
    }
    /**
     * Get table data based on provided settings to the class constructor.
     *
     * @returns {Array}
     */

  }, {
    key: "getData",
    value: function getData() {
      var _this = this;

      var _this$_getDataRange = this._getDataRange(),
          startRow = _this$_getDataRange.startRow,
          startCol = _this$_getDataRange.startCol,
          endRow = _this$_getDataRange.endRow,
          endCol = _this$_getDataRange.endCol;

      var options = this.options;
      var data = [];
      (0, _number.rangeEach)(startRow, endRow, function (rowIndex) {
        var row = [];

        if (!options.exportHiddenRows && _this._isHiddenRow(rowIndex)) {
          return;
        }

        (0, _number.rangeEach)(startCol, endCol, function (colIndex) {
          if (!options.exportHiddenColumns && _this._isHiddenColumn(colIndex)) {
            return;
          }

          row.push(_this.hot.getDataAtCell(rowIndex, colIndex));
        });
        data.push(row);
      });
      return data;
    }
    /**
     * Gets list of row headers.
     *
     * @return {Array}
     */

  }, {
    key: "getRowHeaders",
    value: function getRowHeaders() {
      var _this2 = this;

      var headers = [];

      if (this.options.rowHeaders) {
        var _this$_getDataRange2 = this._getDataRange(),
            startRow = _this$_getDataRange2.startRow,
            endRow = _this$_getDataRange2.endRow;

        var rowHeaders = this.hot.getRowHeader();
        (0, _number.rangeEach)(startRow, endRow, function (row) {
          if (!_this2.options.exportHiddenRows && _this2._isHiddenRow(row)) {
            return;
          }

          headers.push(rowHeaders[row]);
        });
      }

      return headers;
    }
    /**
     * Gets list of columns headers.
     *
     * @return {Array}
     */

  }, {
    key: "getColumnHeaders",
    value: function getColumnHeaders() {
      var _this3 = this;

      var headers = [];

      if (this.options.columnHeaders) {
        var _this$_getDataRange3 = this._getDataRange(),
            startCol = _this$_getDataRange3.startCol,
            endCol = _this$_getDataRange3.endCol;

        var colHeaders = this.hot.getColHeader();
        (0, _number.rangeEach)(startCol, endCol, function (column) {
          if (!_this3.options.exportHiddenColumns && _this3._isHiddenColumn(column)) {
            return;
          }

          headers.push(colHeaders[column]);
        });
      }

      return headers;
    }
    /**
     * Get data range object based on settings provided in the class constructor.
     *
     * @private
     * @returns {Object} Returns object with keys `startRow`, `startCol`, `endRow` and `endCol`.
     */

  }, {
    key: "_getDataRange",
    value: function _getDataRange() {
      var cols = this.hot.countCols() - 1;
      var rows = this.hot.countRows() - 1;

      var _this$options$range = (0, _slicedToArray2.default)(this.options.range, 4),
          _this$options$range$ = _this$options$range[0],
          startRow = _this$options$range$ === void 0 ? 0 : _this$options$range$,
          _this$options$range$2 = _this$options$range[1],
          startCol = _this$options$range$2 === void 0 ? 0 : _this$options$range$2,
          _this$options$range$3 = _this$options$range[2],
          endRow = _this$options$range$3 === void 0 ? rows : _this$options$range$3,
          _this$options$range$4 = _this$options$range[3],
          endCol = _this$options$range$4 === void 0 ? cols : _this$options$range$4;

      startRow = Math.max(startRow, 0);
      startCol = Math.max(startCol, 0);
      endRow = Math.min(endRow, rows);
      endCol = Math.min(endCol, cols);
      return {
        startRow: startRow,
        startCol: startCol,
        endRow: endRow,
        endCol: endCol
      };
    }
    /**
     * Check if row at specified row index is hidden.
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Boolean}
     */

  }, {
    key: "_isHiddenRow",
    value: function _isHiddenRow(row) {
      return this.hot.hasHook('hiddenRow') && this.hot.runHooks('hiddenRow', row);
    }
    /**
     * Check if column at specified column index is hidden.
     *
     * @private
     * @param {Number} column Column index.
     * @returns {Boolean}
     */

  }, {
    key: "_isHiddenColumn",
    value: function _isHiddenColumn(column) {
      return this.hot.hasHook('hiddenColumn') && this.hot.runHooks('hiddenColumn', column);
    }
  }]);
  return DataProvider;
}();

var _default = DataProvider;
exports.default = _default;

/***/ }),
/* 696 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = typeFactory;
exports.EXPORT_TYPES = exports.TYPE_PDF = exports.TYPE_EXCEL = exports.TYPE_CSV = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _csv = _interopRequireDefault(__webpack_require__(697));

var TYPE_CSV = 'csv';
exports.TYPE_CSV = TYPE_CSV;
var TYPE_EXCEL = 'excel'; // TODO

exports.TYPE_EXCEL = TYPE_EXCEL;
var TYPE_PDF = 'pdf'; // TODO

exports.TYPE_PDF = TYPE_PDF;
var EXPORT_TYPES = (0, _defineProperty2.default)({}, TYPE_CSV, _csv.default);
exports.EXPORT_TYPES = EXPORT_TYPES;

function typeFactory(type, dataProvider, options) {
  if (typeof EXPORT_TYPES[type] === 'function') {
    return new EXPORT_TYPES[type](dataProvider, options);
  }

  return null;
}

/***/ }),
/* 697 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(54);

__webpack_require__(164);

__webpack_require__(130);

__webpack_require__(36);

__webpack_require__(37);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _array = __webpack_require__(3);

var _mixed = __webpack_require__(27);

var _base = _interopRequireDefault(__webpack_require__(698));

var CHAR_CARRIAGE_RETURN = String.fromCharCode(13);
var CHAR_DOUBLE_QUOTES = String.fromCharCode(34);
var CHAR_LINE_FEED = String.fromCharCode(10);
/**
 * @plugin ExportFile
 * @private
 */

var Csv =
/*#__PURE__*/
function (_BaseType) {
  (0, _inherits2.default)(Csv, _BaseType);

  function Csv() {
    (0, _classCallCheck2.default)(this, Csv);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Csv).apply(this, arguments));
  }

  (0, _createClass2.default)(Csv, [{
    key: "export",

    /**
     * Create string body in desired format.
     *
     * @return {String}
    */
    value: function _export() {
      var _this = this;

      var options = this.options;
      var data = this.dataProvider.getData();
      var columnHeaders = this.dataProvider.getColumnHeaders();
      var hasColumnHeaders = columnHeaders.length > 0;
      var rowHeaders = this.dataProvider.getRowHeaders();
      var hasRowHeaders = rowHeaders.length > 0;
      var result = options.bom ? String.fromCharCode(0xFEFF) : '';

      if (hasColumnHeaders) {
        columnHeaders = (0, _array.arrayMap)(columnHeaders, function (value) {
          return _this._escapeCell(value, true);
        });

        if (hasRowHeaders) {
          result += options.columnDelimiter;
        }

        result += columnHeaders.join(options.columnDelimiter);
        result += options.rowDelimiter;
      }

      (0, _array.arrayEach)(data, function (value, index) {
        if (index > 0) {
          result += options.rowDelimiter;
        }

        if (hasRowHeaders) {
          result += _this._escapeCell(rowHeaders[index]) + options.columnDelimiter;
        }

        result += value.map(function (cellValue) {
          return _this._escapeCell(cellValue);
        }).join(options.columnDelimiter);
      });
      return result;
    }
    /**
     * Escape cell value.
     *
     * @param {*} value Cell value.
     * @param {Boolean} [force=false] Indicates if cell value will be escaped forcefully.
     * @return {String}
     */

  }, {
    key: "_escapeCell",
    value: function _escapeCell(value) {
      var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var escapedValue = (0, _mixed.stringify)(value);

      if (escapedValue !== '' && (force || escapedValue.indexOf(CHAR_CARRIAGE_RETURN) >= 0 || escapedValue.indexOf(CHAR_DOUBLE_QUOTES) >= 0 || escapedValue.indexOf(CHAR_LINE_FEED) >= 0 || escapedValue.indexOf(this.options.columnDelimiter) >= 0)) {
        escapedValue = escapedValue.replace(new RegExp('"', 'g'), '""');
        escapedValue = "\"".concat(escapedValue, "\"");
      }

      return escapedValue;
    }
  }], [{
    key: "DEFAULT_OPTIONS",

    /**
     * Default options for exporting CSV format.
     *
     * @returns {Object}
     */
    get: function get() {
      return {
        mimeType: 'text/csv',
        fileExtension: 'csv',
        bom: true,
        columnDelimiter: ',',
        rowDelimiter: '\r\n'
      };
    }
  }]);
  return Csv;
}(_base.default);

var _default = Csv;
exports.default = _default;

/***/ }),
/* 698 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(204);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _string = __webpack_require__(68);

/**
 * @plugin ExportFile
 * @private
 */
var BaseType =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(BaseType, null, [{
    key: "DEFAULT_OPTIONS",

    /**
     * Default options.
     *
     * @returns {Object}
     */
    get: function get() {
      return {
        mimeType: 'text/plain',
        fileExtension: 'txt',
        filename: 'Handsontable [YYYY]-[MM]-[DD]',
        encoding: 'utf-8',
        bom: false,
        columnHeaders: false,
        rowHeaders: false,
        exportHiddenColumns: false,
        exportHiddenRows: false,
        range: []
      };
    }
  }]);

  function BaseType(dataProvider, options) {
    (0, _classCallCheck2.default)(this, BaseType);

    /**
     * Data provider.
     *
     * @type {DataProvider}
     */
    this.dataProvider = dataProvider;
    /**
     * Format type class options.
     *
     * @type {Object}
     */

    this.options = this._mergeOptions(options);
    this.dataProvider.setOptions(this.options);
  }
  /**
   * Merge options provided by users with defaults.
   *
   * @return {Object} Returns new options object.
   */


  (0, _createClass2.default)(BaseType, [{
    key: "_mergeOptions",
    value: function _mergeOptions(options) {
      var _options = (0, _object.clone)(this.constructor.DEFAULT_OPTIONS);

      var date = new Date();
      _options = (0, _object.extend)((0, _object.clone)(BaseType.DEFAULT_OPTIONS), _options);
      _options = (0, _object.extend)(_options, options);
      _options.filename = (0, _string.substitute)(_options.filename, {
        YYYY: date.getFullYear(),
        MM: "".concat(date.getMonth() + 1).padStart(2, '0'),
        DD: "".concat(date.getDate()).padStart(2, '0')
      });
      return _options;
    }
  }]);
  return BaseType;
}();

var _default = BaseType;
exports.default = _default;

/***/ }),
/* 699 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(64);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get3 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _columnSorting = _interopRequireDefault(__webpack_require__(484));

var _sortService = __webpack_require__(88);

var _utils = __webpack_require__(165);

var _plugins = __webpack_require__(20);

var _keyStateObserver = __webpack_require__(136);

var _element = __webpack_require__(5);

var _rootComparator = __webpack_require__(700);

var _utils2 = __webpack_require__(701);

var _domHelpers = __webpack_require__(702);

__webpack_require__(703);

var APPEND_COLUMN_CONFIG_STRATEGY = 'append';
var PLUGIN_KEY = 'multiColumnSorting';
var CONFLICTED_PLUGIN_KEY = 'columnSorting';
(0, _sortService.registerRootComparator)(PLUGIN_KEY, _rootComparator.rootComparator);
/**
 * @plugin MultiColumnSorting
 * @dependencies ColumnSorting
 *
 * @description
 * This plugin sorts the view by columns (but does not sort the data source!). To enable the plugin, set the
 * {@link Options#multiColumnSorting} property to the correct value (see the examples below).
 *
 * @example
 * ```js
 * // as boolean
 * multiColumnSorting: true
 *
 * // as an object with initial sort config (sort ascending for column at index 1 and then sort descending for column at index 0)
 * multiColumnSorting: {
 *   initialConfig: [{
 *     column: 1,
 *     sortOrder: 'asc'
 *   }, {
 *     column: 0,
 *     sortOrder: 'desc'
 *   }]
 * }
 *
 * // as an object which define specific sorting options for all columns
 * multiColumnSorting: {
 *   sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table (by default)
 *   indicator: true, // true = shows indicator for all columns (by default), false = don't show indicator for columns
 *   headerAction: true, // true = allow to click on the headers to sort (by default), false = turn off possibility to click on the headers to sort
 *   compareFunctionFactory: function(sortOrder, columnMeta) {
 *     return function(value, nextValue) {
 *       // Some value comparisons which will return -1, 0 or 1...
 *     }
 *   }
 * }
 *
 * // as an object passed to the `column` property, allows specifying a custom options for the desired column.
 * // please take a look at documentation of `column` property: https://docs.handsontable.com/pro/Options.html#columns
 * columns: [{
 *   multiColumnSorting: {
 *     indicator: false, // disable indicator for the first column,
 *     sortEmptyCells: true,
 *     headerAction: false, // clicks on the first column won't sort
 *     compareFunctionFactory: function(sortOrder, columnMeta) {
 *       return function(value, nextValue) {
 *         return 0; // Custom compare function for the first column (don't sort)
 *       }
 *     }
 *   }
 * }]```
 *
 * @dependencies ObserveChanges
 */

var MultiColumnSorting =
/*#__PURE__*/
function (_ColumnSorting) {
  (0, _inherits2.default)(MultiColumnSorting, _ColumnSorting);

  function MultiColumnSorting(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, MultiColumnSorting);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultiColumnSorting).call(this, hotInstance));
    /**
     * Main settings key designed for the plugin.
     *
     * @private
     * @type {String}
     */

    _this.pluginKey = PLUGIN_KEY;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the Handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link MultiColumnSorting#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(MultiColumnSorting, [{
    key: "isEnabled",
    value: function isEnabled() {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "isEnabled", this).call(this);
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      if (!this.enabled && this.hot.getSettings()[this.pluginKey] && this.hot.getSettings()[CONFLICTED_PLUGIN_KEY]) {
        (0, _utils2.warnAboutPluginsConflict)();
      }

      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Sorts the table by chosen columns and orders.
     *
     * @param {undefined|Object|Array} sortConfig Single column sort configuration or full sort configuration (for all sorted columns).
     * The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
     * sort order (`asc` for ascending, `desc` for descending).
     *
     * **Note**: Please keep in mind that every call of `sort` function set an entirely new sort order. Previous sort configs aren't preserved.
     *
     * @example
     * ```js
     * // sort ascending first visual column
     * hot.getPlugin('multiColumnSorting').sort({ column: 0, sortOrder: 'asc' });
     *
     * // sort first two visual column in the defined sequence
     * hot.getPlugin('multiColumnSorting').sort([{
     *   column: 1, sortOrder: 'asc'
     * }, {
     *   column: 0, sortOrder: 'desc'
     * }]);
     * ```
     *
     * @fires Hooks#beforeColumnSort
     * @fires Hooks#afterColumnSort
     */

  }, {
    key: "sort",
    value: function sort(sortConfig) {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "sort", this).call(this, sortConfig);
    }
    /**
     * Clear the sort performed on the table.
     */

  }, {
    key: "clearSort",
    value: function clearSort() {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "clearSort", this).call(this);
    }
    /**
     * Checks if the table is sorted (any column have to be sorted).
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSorted",
    value: function isSorted() {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "isSorted", this).call(this);
    }
    /**
     * Get sort configuration for particular column or for all sorted columns. Objects contain `column` and `sortOrder` properties.
     *
     * **Note**: Please keep in mind that returned objects expose **visual** column index under the `column` key. They are handled by the `sort` function.
     *
     * @param {Number} [column] Visual column index.
     * @returns {undefined|Object|Array}
     */

  }, {
    key: "getSortConfig",
    value: function getSortConfig(column) {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "getSortConfig", this).call(this, column);
    }
    /**
     * @description
     * Warn: Useful mainly for providing server side sort implementation (see in the example below). It doesn't sort the data set. It just sets sort configuration for all sorted columns.
     * Note: Please keep in mind that this method doesn't re-render the table.
     *
     * @example
     * ```js
     * beforeColumnSort: function(currentSortConfig, destinationSortConfigs) {
     *   const columnSortPlugin = this.getPlugin('multiColumnSorting');
     *
     *   columnSortPlugin.setSortConfig(destinationSortConfigs);
     *
     *   // const newData = ... // Calculated data set, ie. from an AJAX call.
     *
     *   this.loadData(newData); // Load new data set and re-render the table.
     *
     *   return false; // The blockade for the default sort action.
     * }```
     *
     * @param {undefined|Object|Array} sortConfig Single column sort configuration or full sort configuration (for all sorted columns).
     * The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
     * sort order (`asc` for ascending, `desc` for descending).
     */

  }, {
    key: "setSortConfig",
    value: function setSortConfig(sortConfig) {
      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "setSortConfig", this).call(this, sortConfig);
    }
    /**
     * Get normalized sort configs.
     *
     * @private
     * @param {Object|Array} [sortConfig=[]] Single column sort configuration or full sort configuration (for all sorted columns).
     * The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
     * sort order (`asc` for ascending, `desc` for descending).
     * @returns {Array}
     */

  }, {
    key: "getNormalizedSortConfigs",
    value: function getNormalizedSortConfigs() {
      var sortConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

      if (Array.isArray(sortConfig)) {
        return sortConfig;
      }

      return [sortConfig];
    }
    /**
     * Update header classes.
     *
     * @private
     * @param {HTMLElement} headerSpanElement Header span element.
     * @param {...*} args Extra arguments for helpers.
     */

  }, {
    key: "updateHeaderClasses",
    value: function updateHeaderClasses(headerSpanElement) {
      var _get2;

      for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      (_get2 = (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "updateHeaderClasses", this)).call.apply(_get2, [this, headerSpanElement].concat(args));

      (0, _element.removeClass)(headerSpanElement, (0, _domHelpers.getClassedToRemove)(headerSpanElement));

      if (this.enabled !== false) {
        (0, _element.addClass)(headerSpanElement, _domHelpers.getClassesToAdd.apply(void 0, args));
      }
    }
    /**
     * Overwriting base plugin's `onUpdateSettings` method. Please keep in mind that `onAfterUpdateSettings` isn't called
     * for `updateSettings` in specific situations.
     *
     * @private
     * @param {Object} newSettings New settings object.
     */

  }, {
    key: "onUpdateSettings",
    value: function onUpdateSettings(newSettings) {
      if (this.hot.getSettings()[this.pluginKey] && this.hot.getSettings()[CONFLICTED_PLUGIN_KEY]) {
        (0, _utils2.warnAboutPluginsConflict)();
      }

      return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "onUpdateSettings", this).call(this, newSettings);
    }
    /**
     * Callback for the `onAfterOnCellMouseDown` hook.
     *
     * @private
     * @param {Event} event Event which are provided by hook.
     * @param {CellCoords} coords Visual coords of the selected cell.
     */

  }, {
    key: "onAfterOnCellMouseDown",
    value: function onAfterOnCellMouseDown(event, coords) {
      if ((0, _utils.wasHeaderClickedProperly)(coords.row, coords.col, event) === false) {
        return;
      }

      if (this.wasClickableHeaderClicked(event, coords.col)) {
        if ((0, _keyStateObserver.isPressedCtrlKey)()) {
          this.hot.deselectCell();
          this.hot.selectColumns(coords.col);
          this.sort(this.getNextSortConfig(coords.col, APPEND_COLUMN_CONFIG_STRATEGY));
        } else {
          this.sort(this.getColumnNextConfig(coords.col));
        }
      }
    }
  }]);
  return MultiColumnSorting;
}(_columnSorting.default);

(0, _plugins.registerPlugin)(PLUGIN_KEY, MultiColumnSorting);
var _default = MultiColumnSorting;
exports.default = _default;

/***/ }),
/* 700 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(40);

exports.__esModule = true;
exports.rootComparator = rootComparator;

var _toArray2 = _interopRequireDefault(__webpack_require__(486));

var _sortService = __webpack_require__(88);

/* eslint-disable import/prefer-default-export */

/**
 * Sort comparator handled by conventional sort algorithm.
 *
 * @param {Array} sortOrders Sort orders (`asc` for ascending, `desc` for descending).
 * @param {Array} columnMetas Column meta objects.
 * @returns {Function}
 */
function rootComparator(sortingOrders, columnMetas) {
  return function (rowIndexWithValues, nextRowIndexWithValues) {
    // We sort array of arrays. Single array is in form [rowIndex, ...values].
    // We compare just values, stored at second index of array.
    var _rowIndexWithValues = (0, _toArray2.default)(rowIndexWithValues),
        values = _rowIndexWithValues.slice(1);

    var _nextRowIndexWithValu = (0, _toArray2.default)(nextRowIndexWithValues),
        nextValues = _nextRowIndexWithValu.slice(1);

    return function getCompareResult(column) {
      var sortingOrder = sortingOrders[column];
      var columnMeta = columnMetas[column];
      var value = values[column];
      var nextValue = nextValues[column];
      var pluginSettings = columnMeta.multiColumnSorting;
      var compareFunctionFactory = pluginSettings.compareFunctionFactory ? pluginSettings.compareFunctionFactory : (0, _sortService.getCompareFunctionFactory)(columnMeta.type);
      var compareResult = compareFunctionFactory(sortingOrder, columnMeta, pluginSettings)(value, nextValue);

      if (compareResult === _sortService.DO_NOT_SWAP) {
        var nextSortedColumn = column + 1;

        if (typeof columnMetas[nextSortedColumn] !== 'undefined') {
          return getCompareResult(nextSortedColumn);
        }
      }

      return compareResult;
    }(0);
  };
}

/***/ }),
/* 701 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.warnAboutPluginsConflict = warnAboutPluginsConflict;

var _console = __webpack_require__(55);

/* eslint-disable import/prefer-default-export */

/**
 * Warn users about problems when using `columnSorting` and `multiColumnSorting` plugins simultaneously.
 */
function warnAboutPluginsConflict() {
  (0, _console.warn)('Plugins `columnSorting` and `multiColumnSorting` should not be enabled simultaneously.');
}

/***/ }),
/* 702 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


__webpack_require__(56);

__webpack_require__(130);

__webpack_require__(36);

__webpack_require__(46);

exports.__esModule = true;
exports.getClassesToAdd = getClassesToAdd;
exports.getClassedToRemove = getClassedToRemove;

/* eslint-disable import/prefer-default-export */
var COLUMN_ORDER_PREFIX = 'sort';
/**
 * Get CSS classes which should be added to particular column header.
 *
 * @param {Object} columnStatesManager Instance of column state manager.
 * @param {Number} column Physical column index.
 * @param {Boolean} showSortIndicator Indicates if indicator should be shown for the particular column.
 * @returns {Array} Array of CSS classes.
 */

function getClassesToAdd(columnStatesManager, column, showSortIndicator) {
  var cssClasses = [];

  if (showSortIndicator === false) {
    return cssClasses;
  }

  if (columnStatesManager.isColumnSorted(column) && columnStatesManager.getNumberOfSortedColumns() > 1) {
    cssClasses.push("".concat(COLUMN_ORDER_PREFIX, "-").concat(columnStatesManager.getIndexOfColumnInSortQueue(column) + 1));
  }

  return cssClasses;
}
/**
 * Get CSS classes which should be removed from column header.
 *
 * @param {HTMLElement} htmlElement
 * @returns {Array} Array of CSS classes.
 */


function getClassedToRemove(htmlElement) {
  var cssClasses = htmlElement.className.split(' ');
  var sortSequenceRegExp = new RegExp("^".concat(COLUMN_ORDER_PREFIX, "-[0-9]{1,2}$"));
  return cssClasses.filter(function (cssClass) {
    return sortSequenceRegExp.test(cssClass);
  });
}

/***/ }),
/* 703 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 704 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(33);

__webpack_require__(51);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(482);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _array = __webpack_require__(3);

var _templateLiteralTag = __webpack_require__(67);

var _console = __webpack_require__(55);

var _number = __webpack_require__(15);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _element = __webpack_require__(5);

var _plugins = __webpack_require__(20);

var _predefinedItems = __webpack_require__(83);

var constants = _interopRequireWildcard(__webpack_require__(11));

var _condition = _interopRequireDefault(__webpack_require__(705));

var _operators = _interopRequireDefault(__webpack_require__(726));

var _value = _interopRequireDefault(__webpack_require__(728));

var _actionBar = _interopRequireDefault(__webpack_require__(734));

var _conditionCollection = _interopRequireDefault(__webpack_require__(501));

var _dataFilter = _interopRequireDefault(__webpack_require__(502));

var _conditionUpdateObserver = _interopRequireDefault(__webpack_require__(735));

var _utils = __webpack_require__(108);

var _constants2 = __webpack_require__(169);

__webpack_require__(736);

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["The filter conditions have been applied properly, but couldn\u2019t be displayed visually.\n        The overall amount of conditions exceed the capability of the dropdown menu.\n        For more details see the documentation."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * @plugin Filters
 * @dependencies DropdownMenu TrimRows HiddenRows
 *
 * @description
 * The plugin allows filtering the table data either by the built-in component or with the API.
 *
 * See [the filtering demo](https://docs.handsontable.com/pro/demo-filtering.html) for examples.
 *
 * @example
 * ```
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   data: getData(),
 *   colHeaders: true,
 *   rowHeaders: true,
 *   dropdownMenu: true,
 *   filters: true
 * });
 * ```
 */
var Filters =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(Filters, _BasePlugin);

  function Filters(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, Filters);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Filters).call(this, hotInstance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Instance of {@link TrimRows}.
     *
     * @private
     * @type {TrimRows}
     */

    _this.trimRowsPlugin = null;
    /**
     * Instance of {@link DropdownMenu}.
     *
     * @private
     * @type {DropdownMenu}
     */

    _this.dropdownMenuPlugin = null;
    /**
     * Instance of {@link ConditionCollection}.
     *
     * @private
     * @type {ConditionCollection}
     */

    _this.conditionCollection = null;
    /**
     * Instance of {@link ConditionUpdateObserver}.
     *
     * @private
     * @type {ConditionUpdateObserver}
     */

    _this.conditionUpdateObserver = null;
    /**
     * Map, where key is component identifier and value represent `BaseComponent` element or it derivatives.
     *
     * @private
     * @type {Map}
     */

    _this.components = new Map([['filter_by_condition', null], ['filter_operators', null], ['filter_by_condition2', null], ['filter_by_value', null], ['filter_action_bar', null]]);
    /**
     * Object containing information about last selected column physical and visual index for added filter conditions.
     *
     * @private
     * @type {Object}
     * @default null
     */

    _this.lastSelectedColumn = null;
    /**
     * Hidden menu rows indexed by physical column index
     *
     * @private
     * @type {Map}
     */

    _this.hiddenRowsCache = new Map(); // One listener for the enable/disable functionality

    _this.hot.addHook('afterGetColHeader', function (col, TH) {
      return _this.onAfterGetColHeader(col, TH);
    });

    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link Filters#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Filters, [{
    key: "isEnabled",
    value: function isEnabled() {
      /* eslint-disable no-unneeded-ternary */
      return this.hot.getSettings().filters ? true : false;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.trimRowsPlugin = this.hot.getPlugin('trimRows');
      this.dropdownMenuPlugin = this.hot.getPlugin('dropdownMenu');

      var addConfirmationHooks = function addConfirmationHooks(component) {
        component.addLocalHook('accept', function () {
          return _this2.onActionBarSubmit('accept');
        });
        component.addLocalHook('cancel', function () {
          return _this2.onActionBarSubmit('cancel');
        });
        component.addLocalHook('change', function (command) {
          return _this2.onComponentChange(component, command);
        });
        return component;
      };

      var filterByConditionLabel = function filterByConditionLabel() {
        return "".concat(_this2.hot.getTranslatedPhrase(constants.FILTERS_DIVS_FILTER_BY_CONDITION), ":");
      };

      var filterValueLabel = function filterValueLabel() {
        return "".concat(_this2.hot.getTranslatedPhrase(constants.FILTERS_DIVS_FILTER_BY_VALUE), ":");
      };

      if (!this.components.get('filter_by_condition')) {
        var conditionComponent = new _condition.default(this.hot, {
          id: 'filter_by_condition',
          name: filterByConditionLabel,
          addSeparator: false
        });
        conditionComponent.addLocalHook('afterClose', function () {
          return _this2.onSelectUIClosed();
        });
        this.components.set('filter_by_condition', addConfirmationHooks(conditionComponent));
      }

      if (!this.components.get('filter_operators')) {
        this.components.set('filter_operators', new _operators.default(this.hot, {
          id: 'filter_operators',
          name: 'Operators'
        }));
      }

      if (!this.components.get('filter_by_condition2')) {
        var _conditionComponent = new _condition.default(this.hot, {
          id: 'filter_by_condition2',
          name: '',
          addSeparator: true
        });

        _conditionComponent.addLocalHook('afterClose', function () {
          return _this2.onSelectUIClosed();
        });

        this.components.set('filter_by_condition2', addConfirmationHooks(_conditionComponent));
      }

      if (!this.components.get('filter_by_value')) {
        this.components.set('filter_by_value', addConfirmationHooks(new _value.default(this.hot, {
          id: 'filter_by_value',
          name: filterValueLabel
        })));
      }

      if (!this.components.get('filter_action_bar')) {
        this.components.set('filter_action_bar', addConfirmationHooks(new _actionBar.default(this.hot, {
          id: 'filter_action_bar',
          name: 'Action bar'
        })));
      }

      if (!this.conditionCollection) {
        this.conditionCollection = new _conditionCollection.default();
      }

      if (!this.conditionUpdateObserver) {
        this.conditionUpdateObserver = new _conditionUpdateObserver.default(this.conditionCollection, function (column) {
          return _this2.getDataMapAtColumn(column);
        });
        this.conditionUpdateObserver.addLocalHook('update', function (conditionState) {
          return _this2.updateComponents(conditionState);
        });
      }

      this.components.forEach(function (component) {
        component.show();
      });
      this.registerEvents();
      this.addHook('beforeDropdownMenuSetItems', function (items) {
        return _this2.onBeforeDropdownMenuSetItems(items);
      });
      this.addHook('afterDropdownMenuDefaultOptions', function (defaultOptions) {
        return _this2.onAfterDropdownMenuDefaultOptions(defaultOptions);
      });
      this.addHook('afterDropdownMenuShow', function () {
        return _this2.onAfterDropdownMenuShow();
      });
      this.addHook('afterDropdownMenuHide', function () {
        return _this2.onAfterDropdownMenuHide();
      });
      this.addHook('afterChange', function (changes) {
        return _this2.onAfterChange(changes);
      }); // force to enable dependent plugins

      this.hot.getSettings().trimRows = true;
      this.trimRowsPlugin.enablePlugin(); // Temp. solution (extending menu items bug in contextMenu/dropdownMenu)

      if (this.hot.getSettings().dropdownMenu) {
        this.dropdownMenuPlugin.disablePlugin();
        this.dropdownMenuPlugin.enablePlugin();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Registers the DOM listeners.
     *
     * @private
     */

  }, {
    key: "registerEvents",
    value: function registerEvents() {
      var _this3 = this;

      this.eventManager.addEventListener(this.hot.rootElement, 'click', function (event) {
        return _this3.onTableClick(event);
      });
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      if (this.enabled) {
        if (this.dropdownMenuPlugin.enabled) {
          this.dropdownMenuPlugin.menu.clearLocalHooks();
        }

        this.components.forEach(function (component) {
          component.hide();
        });
        this.conditionCollection.clean();
        this.trimRowsPlugin.untrimAll();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "disablePlugin", this).call(this);
    }
    /**
     * @description
     * Adds condition to the conditions collection at specified column index.
     *
     * Possible predefined conditions:
     *  * `begins_with` - Begins with
     *  * `between` - Between
     *  * `by_value` - By value
     *  * `contains` - Contains
     *  * `empty` - Empty
     *  * `ends_with` - Ends with
     *  * `eq` - Equal
     *  * `gt` - Greater than
     *  * `gte` - Greater than or equal
     *  * `lt` - Less than
     *  * `lte` - Less than or equal
     *  * `none` - None (no filter)
     *  * `not_between` - Not between
     *  * `not_contains` - Not contains
     *  * `not_empty` - Not empty
     *  * `neq` - Not equal
     *
     * Possible operations on collection of conditions:
     *  * `conjunction` - [**Conjunction**](https://en.wikipedia.org/wiki/Logical_conjunction) on conditions collection (by default), i.e. for such operation: c1 AND c2 AND c3 AND c4 ... AND cn === TRUE, where c1 ... cn are conditions.
     *  * `disjunction` - [**Disjunction**](https://en.wikipedia.org/wiki/Logical_disjunction) on conditions collection, i.e. for such operation: `c1 OR c2 OR c3 OR c4 ... OR cn` === TRUE, where c1, c2, c3, c4 ... cn are conditions.
     *  * `disjunctionWithExtraCondition` - **Disjunction** on first `n - 1`\* conditions from collection with an extra requirement computed from the last condition, i.e. for such operation: `c1 OR c2 OR c3 OR c4 ... OR cn-1 AND cn` === TRUE, where c1, c2, c3, c4 ... cn are conditions.
     *
     * \* when `n` is collection size; it's used i.e. for one operation introduced from UI (when choosing from filter's drop-down menu two conditions with OR operator between them, mixed with choosing values from the multiple choice select)
     *
     * **Note**: Mind that you cannot mix different types of operations (for instance, if you use `conjunction`, use it consequently for a particular column).
     *
     * @example
     * ```js
     * const container = document.getElementById('example');
     * const hot = new Handsontable(container, {
     *   date: getData(),
     *   filters: true
     * });
     *
     * // access to filters plugin instance
     * const filtersPlugin = hot.getPlugin('filters');
     *
     * // add filter "Greater than" 95 to column at index 1
     * filtersPlugin.addCondition(1, 'gt', [95]);
     * filtersPlugin.filter();
     *
     * // add filter "By value" to column at index 1
     * // in this case all value's that don't match will be filtered.
     * filtersPlugin.addCondition(1, 'by_value', [['ing', 'ed', 'as', 'on']]);
     * filtersPlugin.filter();
     *
     * // add filter "Begins with" with value "de" AND "Not contains" with value "ing"
     * filtersPlugin.addCondition(1, 'begins_with', ['de'], 'conjunction');
     * filtersPlugin.addCondition(1, 'not_contains', ['ing'], 'conjunction');
     * filtersPlugin.filter();
     *
     * // add filter "Begins with" with value "de" OR "Not contains" with value "ing"
     * filtersPlugin.addCondition(1, 'begins_with', ['de'], 'disjunction');
     * filtersPlugin.addCondition(1, 'not_contains', ['ing'], 'disjunction');
     * filtersPlugin.filter();
     * ```
     * @param {Number} column Visual column index.
     * @param {String} name Condition short name.
     * @param {Array} args Condition arguments.
     * @param {String} operationId `id` of operation which is performed on the column
     */

  }, {
    key: "addCondition",
    value: function addCondition(column, name, args) {
      var operationId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _constants2.OPERATION_AND;
      var physicalColumn = this.t.toPhysicalColumn(column);
      this.conditionCollection.addCondition(physicalColumn, {
        command: {
          key: name
        },
        args: args
      }, operationId);
    }
    /**
     * Removes conditions at specified column index.
     *
     * @param {Number} column Visual column index.
     */

  }, {
    key: "removeConditions",
    value: function removeConditions(column) {
      var physicalColumn = this.t.toPhysicalColumn(column);
      this.conditionCollection.removeConditions(physicalColumn);
    }
    /**
     * Clears all conditions previously added to the collection for the specified column index or, if the column index
     * was not passed, clear the conditions for all columns.
     *
     * @param {Number} [column] Visual column index.
     */

  }, {
    key: "clearConditions",
    value: function clearConditions(column) {
      if (column === void 0) {
        this.conditionCollection.clean();
      } else {
        var physicalColumn = this.t.toPhysicalColumn(column);
        this.conditionCollection.clearConditions(physicalColumn);
      }
    }
    /**
     * Filters data based on added filter conditions.
     *
     * @fires Hooks#beforeFilter
     * @fires Hooks#afterFilter
     */

  }, {
    key: "filter",
    value: function filter() {
      var dataFilter = this._createDataFilter();

      var needToFilter = !this.conditionCollection.isEmpty();
      var visibleVisualRows = [];
      var conditions = this.conditionCollection.exportAllConditions();
      var allowFiltering = this.hot.runHooks('beforeFilter', conditions);

      if (allowFiltering !== false) {
        if (needToFilter) {
          var trimmedRows = [];
          this.trimRowsPlugin.trimmedRows.length = 0;
          visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), function (rowData) {
            return rowData.meta.visualRow;
          });
          var visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
          (0, _number.rangeEach)(this.hot.countSourceRows() - 1, function (row) {
            if (!visibleVisualRowsAssertion(row)) {
              trimmedRows.push(row);
            }
          });
          this.trimRowsPlugin.trimRows(trimmedRows);

          if (!visibleVisualRows.length) {
            this.hot.deselectCell();
          }
        } else {
          this.trimRowsPlugin.untrimAll();
        }
      }

      this.hot.view.wt.wtOverlays.adjustElementsSize(true);
      this.hot.render();
      this.clearColumnSelection();
      this.hot.runHooks('afterFilter', conditions);
    }
    /**
     * Gets last selected column index.
     *
     * @returns {Object|null} Return `null` when column isn't selected otherwise
     * object containing information about selected column with keys `visualIndex` and `physicalIndex`
     */

  }, {
    key: "getSelectedColumn",
    value: function getSelectedColumn() {
      return this.lastSelectedColumn;
    }
    /**
     * Clears column selection.
     *
     * @private
     */

  }, {
    key: "clearColumnSelection",
    value: function clearColumnSelection() {
      var _ref = this.hot.getSelectedLast() || [],
          _ref2 = (0, _slicedToArray2.default)(_ref, 2),
          row = _ref2[0],
          col = _ref2[1];

      if (row !== void 0 && col !== void 0) {
        this.hot.selectCell(row, col);
      }
    }
    /**
     * Returns handsontable source data with cell meta based on current selection.
     *
     * @param {Number} [column] Column index. By default column index accept the value of the selected column.
     * @returns {Array} Returns array of objects where keys as row index.
     */

  }, {
    key: "getDataMapAtColumn",
    value: function getDataMapAtColumn(column) {
      var _this4 = this;

      var visualIndex = this.t.toVisualColumn(column);
      var data = [];
      (0, _array.arrayEach)(this.hot.getSourceDataAtCol(visualIndex), function (value, rowIndex) {
        var _this4$hot$getCellMet = _this4.hot.getCellMeta(rowIndex, visualIndex),
            row = _this4$hot$getCellMet.row,
            col = _this4$hot$getCellMet.col,
            visualCol = _this4$hot$getCellMet.visualCol,
            visualRow = _this4$hot$getCellMet.visualRow,
            type = _this4$hot$getCellMet.type,
            instance = _this4$hot$getCellMet.instance,
            dateFormat = _this4$hot$getCellMet.dateFormat;

        data.push({
          meta: {
            row: row,
            col: col,
            visualCol: visualCol,
            visualRow: visualRow,
            type: type,
            instance: instance,
            dateFormat: dateFormat
          },
          value: (0, _utils.toEmptyString)(value)
        });
      });
      return data;
    }
    /**
     * `afterChange` listener.
     *
     * @private
     * @param {Array} changes Array of changes.
     */

  }, {
    key: "onAfterChange",
    value: function onAfterChange(changes) {
      var _this5 = this;

      if (changes) {
        (0, _array.arrayEach)(changes, function (change) {
          var _change = (0, _slicedToArray2.default)(change, 2),
              prop = _change[1];

          var columnIndex = _this5.hot.propToCol(prop);

          if (_this5.conditionCollection.hasConditions(columnIndex)) {
            _this5.updateValueComponentCondition(columnIndex);
          }
        });
      }
    }
    /**
     * Update condition of ValueComponent basing on handled changes
     *
     * @private
     * @param {Number} columnIndex Column index of handled ValueComponent condition
     */

  }, {
    key: "updateValueComponentCondition",
    value: function updateValueComponentCondition(columnIndex) {
      var dataAtCol = this.hot.getDataAtCol(columnIndex);
      var selectedValues = (0, _utils.unifyColumnValues)(dataAtCol);
      this.conditionUpdateObserver.updateStatesAtColumn(columnIndex, selectedValues);
    }
    /**
     * Restores components to their cached state.
     *
     * @private
     * @param {Array} components List of components.
     */

  }, {
    key: "restoreComponents",
    value: function restoreComponents(components) {
      var selectedColumn = this.getSelectedColumn();
      var physicalIndex = selectedColumn && selectedColumn.physicalIndex;
      components.forEach(function (component) {
        if (component.isHidden() === false) {
          component.restoreState(physicalIndex);
        }
      });
    }
    /**
     * After dropdown menu show listener.
     *
     * @private
     */

  }, {
    key: "onAfterDropdownMenuShow",
    value: function onAfterDropdownMenuShow() {
      this.restoreComponents([this.components.get('filter_by_condition'), this.components.get('filter_operators'), this.components.get('filter_by_condition2'), this.components.get('filter_by_value')]);
    }
    /**
     * After dropdown menu hide listener.
     *
     * @private
     */

  }, {
    key: "onAfterDropdownMenuHide",
    value: function onAfterDropdownMenuHide() {
      this.components.get('filter_by_condition').getSelectElement().closeOptions();
      this.components.get('filter_by_condition2').getSelectElement().closeOptions();
    }
    /**
     * Before dropdown menu set menu items listener.
     *
     * @private
     * @param {Array} items DropdownMenu items created based on predefined items and settings provided by user.
     */

  }, {
    key: "onBeforeDropdownMenuSetItems",
    value: function onBeforeDropdownMenuSetItems(items) {
      var menuKeys = (0, _array.arrayMap)(items, function (item) {
        return item.key;
      });
      this.components.forEach(function (component) {
        component[menuKeys.indexOf(component.getMenuItemDescriptor().key) === -1 ? 'hide' : 'show']();
      });
      this.initHiddenRowsCache();
    }
    /**
     * After dropdown menu default options listener.
     *
     * @private
     * @param {Object} defaultOptions ContextMenu default item options.
     */

  }, {
    key: "onAfterDropdownMenuDefaultOptions",
    value: function onAfterDropdownMenuDefaultOptions(defaultOptions) {
      defaultOptions.items.push({
        name: _predefinedItems.SEPARATOR
      });
      this.components.forEach(function (component) {
        defaultOptions.items.push(component.getMenuItemDescriptor());
      });
    }
    /**
     * Get operation basing on number and type of arguments (where arguments are states of components)
     *
     * @param {String} suggestedOperation operation which was chosen by user from UI
     * @param {Object} byConditionState1 state of first condition component
     * @param {Object} byConditionState2 state of second condition component
     * @param {Object} byValueState state of value component
     * @private
     * @returns {String}
     */

  }, {
    key: "getOperationBasedOnArguments",
    value: function getOperationBasedOnArguments(suggestedOperation, byConditionState1, byConditionState2, byValueState) {
      var operation = suggestedOperation;

      if (operation === _constants2.OPERATION_OR && byConditionState1.command.key !== _constants2.CONDITION_NONE && byConditionState2.command.key !== _constants2.CONDITION_NONE && byValueState.command.key !== _constants2.CONDITION_NONE) {
        operation = _constants2.OPERATION_OR_THEN_VARIABLE;
      } else if (byValueState.command.key !== _constants2.CONDITION_NONE) {
        if (byConditionState1.command.key === _constants2.CONDITION_NONE || byConditionState2.command.key === _constants2.CONDITION_NONE) {
          operation = _constants2.OPERATION_AND;
        }
      }

      return operation;
    }
    /**
     * On action bar submit listener.
     *
     * @private
     * @param {String} submitType
     */

  }, {
    key: "onActionBarSubmit",
    value: function onActionBarSubmit(submitType) {
      if (submitType === 'accept') {
        var selectedColumn = this.getSelectedColumn();
        var physicalIndex = selectedColumn && selectedColumn.physicalIndex;
        var byConditionState1 = this.components.get('filter_by_condition').getState();
        var byConditionState2 = this.components.get('filter_by_condition2').getState();
        var byValueState = this.components.get('filter_by_value').getState();
        var operation = this.getOperationBasedOnArguments(this.components.get('filter_operators').getActiveOperationId(), byConditionState1, byConditionState2, byValueState);
        this.conditionUpdateObserver.groupChanges();
        this.conditionCollection.clearConditions(physicalIndex);

        if (byConditionState1.command.key === _constants2.CONDITION_NONE && byConditionState2.command.key === _constants2.CONDITION_NONE && byValueState.command.key === _constants2.CONDITION_NONE) {
          this.conditionCollection.removeConditions(physicalIndex);
        } else {
          if (byConditionState1.command.key !== _constants2.CONDITION_NONE) {
            this.conditionCollection.addCondition(physicalIndex, byConditionState1, operation);

            if (byConditionState2.command.key !== _constants2.CONDITION_NONE) {
              this.conditionCollection.addCondition(physicalIndex, byConditionState2, operation);
            }
          }

          if (byValueState.command.key !== _constants2.CONDITION_NONE) {
            this.conditionCollection.addCondition(physicalIndex, byValueState, operation);
          }
        }

        this.conditionUpdateObserver.flush();
        this.components.get('filter_operators').saveState(physicalIndex);
        this.components.get('filter_by_value').saveState(physicalIndex);
        this.saveHiddenRowsCache(physicalIndex);
        this.trimRowsPlugin.trimmedRows.length = 0;
        this.filter();
      }

      this.dropdownMenuPlugin.close();
    }
    /**
     * On component change listener.
     *
     * @private
     * @param {BaseComponent} component Component inheriting BaseComponent
     * @param {Object} command Menu item object (command).
     */

  }, {
    key: "onComponentChange",
    value: function onComponentChange(component, command) {
      if (component === this.components.get('filter_by_condition')) {
        if (command.showOperators) {
          this.showComponents(this.components.get('filter_by_condition2'), this.components.get('filter_operators'));
        } else {
          this.hideComponents(this.components.get('filter_by_condition2'), this.components.get('filter_operators'));
        }
      }

      if (component.constructor === _condition.default && !command.inputsCount) {
        this.setListeningDropdownMenu();
      }
    }
    /**
     * On component SelectUI closed listener.
     *
     * @private
     */

  }, {
    key: "onSelectUIClosed",
    value: function onSelectUIClosed() {
      this.setListeningDropdownMenu();
    }
    /**
     * Listen to the keyboard input on document body and forward events to instance of Handsontable
     * created by DropdownMenu plugin
     *
     * @private
     */

  }, {
    key: "setListeningDropdownMenu",
    value: function setListeningDropdownMenu() {
      this.dropdownMenuPlugin.setListening();
    }
    /**
     * On after get column header listener.
     *
     * @private
     * @param {Number} col
     * @param {HTMLTableCellElement} TH
     */

  }, {
    key: "onAfterGetColHeader",
    value: function onAfterGetColHeader(col, TH) {
      var physicalColumn = this.t.toPhysicalColumn(col);

      if (this.enabled && this.conditionCollection.hasConditions(physicalColumn)) {
        (0, _element.addClass)(TH, 'htFiltersActive');
      } else {
        (0, _element.removeClass)(TH, 'htFiltersActive');
      }
    }
    /**
     * On table click listener.
     *
     * @private
     * @param {Event} event DOM Event.
     */

  }, {
    key: "onTableClick",
    value: function onTableClick(event) {
      var th = (0, _element.closest)(event.target, 'TH');

      if (th) {
        var visualIndex = this.hot.getCoords(th).col;
        var physicalIndex = this.t.toPhysicalColumn(visualIndex);
        this.lastSelectedColumn = {
          visualIndex: visualIndex,
          physicalIndex: physicalIndex
        };
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.enabled) {
        this.components.forEach(function (component) {
          component.destroy();
        });
        this.conditionCollection.destroy();
        this.conditionUpdateObserver.destroy();
        this.hiddenRowsCache.clear();
        this.trimRowsPlugin.disablePlugin();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "destroy", this).call(this);
    }
    /**
     * Creates DataFilter instance based on condition collection.
     *
     * @private
     * @param {ConditionCollection} conditionCollection Condition collection object.
     * @returns {DataFilter}
     */

  }, {
    key: "_createDataFilter",
    value: function _createDataFilter() {
      var _this6 = this;

      var conditionCollection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.conditionCollection;
      return new _dataFilter.default(conditionCollection, function (column) {
        return _this6.getDataMapAtColumn(column);
      });
    }
    /**
     * Updates components basing on conditions state.
     *
     * @private
     * @param {Object} conditionsState
     */

  }, {
    key: "updateComponents",
    value: function updateComponents(conditionsState) {
      if (!this.dropdownMenuPlugin.enabled) {
        return;
      }

      var conditions = conditionsState.editedConditionStack.conditions;
      var column = conditionsState.editedConditionStack.column;
      var conditionsByValue = conditions.filter(function (condition) {
        return condition.name === _constants2.CONDITION_BY_VALUE;
      });
      var conditionsWithoutByValue = conditions.filter(function (condition) {
        return condition.name !== _constants2.CONDITION_BY_VALUE;
      });
      var operationType = this.conditionCollection.columnTypes[column];

      if (conditionsByValue.length === 2 || conditionsWithoutByValue.length === 3) {
        (0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject()));
      } else {
        if (conditionsWithoutByValue.length > 0) {
          this.showComponentForParticularColumn(this.components.get('filter_operators'), column);
        }

        this.components.get('filter_by_condition').updateState(conditionsWithoutByValue[0], column);
        this.components.get('filter_by_condition2').updateState(conditionsWithoutByValue[1], column);
        this.components.get('filter_by_value').updateState(conditionsState);
        this.components.get('filter_operators').updateState(operationType, column);
      }
    }
    /**
     * Shows component for particular column.
     *
     * @private
     * @param {BaseComponent} component `BaseComponent` element or it derivatives.
     * @param {Number} column Physical column index.
     */

  }, {
    key: "showComponentForParticularColumn",
    value: function showComponentForParticularColumn(component, column) {
      if (!this.hiddenRowsCache.has(column)) {
        this.hiddenRowsCache.set(column, []);
      } else {
        var indexes = this.getIndexesOfComponents(component);
        this.removeIndexesFromHiddenRowsCache(column, indexes);
      }
    }
    /**
     * Removes specific rows from `hiddenRows` cache for particular column.
     *
     * @private
     * @param {Number} column Physical column index.
     * @param {Array} indexes Physical indexes of rows which will be removed from `hiddenRows` cache
     */

  }, {
    key: "removeIndexesFromHiddenRowsCache",
    value: function removeIndexesFromHiddenRowsCache(column, indexes) {
      var hiddenRowsForColumn = this.hiddenRowsCache.get(column);
      (0, _array.arrayEach)(indexes, function (index) {
        if (hiddenRowsForColumn.includes(index)) {
          hiddenRowsForColumn.splice(hiddenRowsForColumn.indexOf(index), 1);
        }
      });
    }
    /**
     * Returns indexes of passed components inside list of `dropdownMenu` items.
     *
     * @private
     * @param {...BaseComponent} components List of components.
     * @returns {Array}
     */

  }, {
    key: "getIndexesOfComponents",
    value: function getIndexesOfComponents() {
      var menu = this.dropdownMenuPlugin.menu;
      var indexes = [];

      for (var _len = arguments.length, components = new Array(_len), _key = 0; _key < _len; _key++) {
        components[_key] = arguments[_key];
      }

      (0, _array.arrayEach)(components, function (component) {
        (0, _array.arrayEach)(menu.menuItems, function (item, index) {
          if (item.key === component.getMenuItemDescriptor().key) {
            indexes.push(index);
          }
        });
      });
      return indexes;
    }
    /**
     * Changes visibility of component.
     *
     * @private
     * @param {Boolean} visible Determine if components should be visible.
     * @param {...BaseComponent} components List of components.
     */

  }, {
    key: "changeComponentsVisibility",
    value: function changeComponentsVisibility() {
      var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
      var menu = this.dropdownMenuPlugin.menu;
      var hotMenu = menu.hotMenu;
      var hiddenRows = hotMenu.getPlugin('hiddenRows');

      for (var _len2 = arguments.length, components = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        components[_key2 - 1] = arguments[_key2];
      }

      var indexes = this.getIndexesOfComponents.apply(this, components);

      if (visible) {
        hiddenRows.showRows(indexes);
      } else {
        hiddenRows.hideRows(indexes);
      }

      hotMenu.render();
    }
    /**
     * Initializes `hiddenRows` cache.
     *
     * @private
     */

  }, {
    key: "initHiddenRowsCache",
    value: function initHiddenRowsCache() {
      var _this7 = this;

      this.dropdownMenuPlugin.menu.addLocalHook('afterOpen', function () {
        var index = _this7.lastSelectedColumn.physicalIndex;

        if (!_this7.hiddenRowsCache.has(index)) {
          _this7.hiddenRowsCache.set(index, _this7.getIndexesOfComponents(_this7.components.get('filter_operators'), _this7.components.get('filter_by_condition2')));
        }

        _this7.dropdownMenuPlugin.menu.hotMenu.updateSettings({
          hiddenRows: {
            rows: _this7.hiddenRowsCache.get(index)
          }
        });
      });
    }
    /**
     * Saves `hiddenRows` cache for particular row.
     *
     * @private
     * @param rowIndex Physical row index
     */

  }, {
    key: "saveHiddenRowsCache",
    value: function saveHiddenRowsCache(rowIndex) {
      this.hiddenRowsCache.set(rowIndex, this.dropdownMenuPlugin.menu.hotMenu.getPlugin('hiddenRows').hiddenRows);
    }
    /**
     * Hides components of filters `dropdownMenu`.
     *
     * @private
     * @param {...BaseComponent} components List of components.
     */

  }, {
    key: "hideComponents",
    value: function hideComponents() {
      for (var _len3 = arguments.length, components = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
        components[_key3] = arguments[_key3];
      }

      this.changeComponentsVisibility.apply(this, [false].concat(components));
    }
    /**
     * Shows components of filters `dropdownMenu`.
     *
     * @private
     * @param {...BaseComponent} components List of components.
     */

  }, {
    key: "showComponents",
    value: function showComponents() {
      for (var _len4 = arguments.length, components = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
        components[_key4] = arguments[_key4];
      }

      this.changeComponentsVisibility.apply(this, [true].concat(components));
    }
  }]);
  return Filters;
}(_base.default);

(0, _plugins.registerPlugin)('filters', Filters);
var _default = Filters;
exports.default = _default;

/***/ }),
/* 705 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

__webpack_require__(51);

__webpack_require__(138);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

var _array = __webpack_require__(3);

var _unicode = __webpack_require__(50);

var _object = __webpack_require__(4);

var C = _interopRequireWildcard(__webpack_require__(11));

var _base = _interopRequireDefault(__webpack_require__(139));

var _constants2 = _interopRequireWildcard(__webpack_require__(169));

var _input = _interopRequireDefault(__webpack_require__(171));

var _select = _interopRequireDefault(__webpack_require__(725));

var _conditionRegisterer = __webpack_require__(28);

/**
 * @class ConditionComponent
 * @plugin Filters
 */
var ConditionComponent =
/*#__PURE__*/
function (_BaseComponent) {
  (0, _inherits2.default)(ConditionComponent, _BaseComponent);

  function ConditionComponent(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, ConditionComponent);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ConditionComponent).call(this, hotInstance));
    _this.id = options.id;
    _this.name = options.name;
    _this.addSeparator = options.addSeparator;

    _this.elements.push(new _select.default(_this.hot));

    _this.elements.push(new _input.default(_this.hot, {
      placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_VALUE
    }));

    _this.elements.push(new _input.default(_this.hot, {
      placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE
    }));

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   *
   * @private
   */


  (0, _createClass2.default)(ConditionComponent, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.getSelectElement().addLocalHook('select', function (command) {
        return _this2.onConditionSelect(command);
      });
      this.getSelectElement().addLocalHook('afterClose', function () {
        return _this2.onSelectUIClosed();
      });
      (0, _array.arrayEach)(this.getInputElements(), function (input) {
        input.addLocalHook('keydown', function (event) {
          return _this2.onInputKeyDown(event);
        });
      });
    }
    /**
     * Set state of the component.
     *
     * @param {Object} value State to restore.
     */

  }, {
    key: "setState",
    value: function setState(value) {
      var _this3 = this;

      this.reset();

      if (value) {
        var copyOfCommand = (0, _object.clone)(value.command);

        if (copyOfCommand.name.startsWith(C.FILTERS_CONDITIONS_NAMESPACE)) {
          copyOfCommand.name = this.hot.getTranslatedPhrase(copyOfCommand.name);
        }

        this.getSelectElement().setValue(copyOfCommand);
        (0, _array.arrayEach)(value.args, function (arg, index) {
          if (index > copyOfCommand.inputsCount - 1) {
            return false;
          }

          var element = _this3.getInputElement(index);

          element.setValue(arg);
          element[copyOfCommand.inputsCount > index ? 'show' : 'hide']();

          if (!index) {
            setTimeout(function () {
              return element.focus();
            }, 10);
          }
        });
      }
    }
    /**
     * Export state of the component (get selected filter and filter arguments).
     *
     * @returns {Object} Returns object where `command` key keeps used condition filter and `args` key its arguments.
     */

  }, {
    key: "getState",
    value: function getState() {
      var command = this.getSelectElement().getValue() || (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
      var args = [];
      (0, _array.arrayEach)(this.getInputElements(), function (element, index) {
        if (command.inputsCount > index) {
          args.push(element.getValue());
        }
      });
      return {
        command: command,
        args: args
      };
    }
    /**
     * Update state of component.
     * @param {Object} condition Object with keys:
     *  * `command` Object, Command object with condition name as `key` property.
     *  * `args` Array, Condition arguments.
     * @param column Physical column index.
     */

  }, {
    key: "updateState",
    value: function updateState(condition, column) {
      var command = condition ? (0, _conditionRegisterer.getConditionDescriptor)(condition.name) : (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
      this.setCachedState(column, {
        command: command,
        args: condition ? condition.args : []
      });

      if (!condition) {
        (0, _array.arrayEach)(this.getInputElements(), function (element) {
          return element.setValue(null);
        });
      }
    }
    /**
     * Get select element.
     *
     * @returns {SelectUI}
     */

  }, {
    key: "getSelectElement",
    value: function getSelectElement() {
      return this.elements.filter(function (element) {
        return element instanceof _select.default;
      })[0];
    }
    /**
     * Get input element.
     *
     * @param {Number} index Index an array of elements.
     * @returns {InputUI}
     */

  }, {
    key: "getInputElement",
    value: function getInputElement() {
      var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
      return this.getInputElements()[index];
    }
    /**
     * Get input elements.
     *
     * @returns {Array}
     */

  }, {
    key: "getInputElements",
    value: function getInputElements() {
      return this.elements.filter(function (element) {
        return element instanceof _input.default;
      });
    }
    /**
     * Get menu object descriptor.
     *
     * @returns {Object}
     */

  }, {
    key: "getMenuItemDescriptor",
    value: function getMenuItemDescriptor() {
      var _this4 = this;

      return {
        key: this.id,
        name: this.name,
        isCommand: false,
        disableSelection: true,
        hidden: function hidden() {
          return _this4.isHidden();
        },
        renderer: function renderer(hot, wrapper, row, col, prop, value) {
          (0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuCondition');

          if (_this4.addSeparator) {
            (0, _element.addClass)(wrapper.parentNode, 'border');
          }

          var label = _this4.hot.rootDocument.createElement('div');

          (0, _element.addClass)(label, 'htFiltersMenuLabel');
          label.textContent = value;
          wrapper.appendChild(label);

          if (!wrapper.parentNode.hasAttribute('ghost-table')) {
            (0, _array.arrayEach)(_this4.elements, function (ui) {
              return wrapper.appendChild(ui.element);
            });
          }

          return wrapper;
        }
      };
    }
    /**
     * Reset elements to their initial state.
     */

  }, {
    key: "reset",
    value: function reset() {
      var _this$hot;

      var lastSelectedColumn = this.hot.getPlugin('filters').getSelectedColumn();
      var visualIndex = lastSelectedColumn && lastSelectedColumn.visualIndex;

      var columnType = (_this$hot = this.hot).getDataType.apply(_this$hot, (0, _toConsumableArray2.default)(this.hot.getSelectedLast() || [0, visualIndex]));

      var items = (0, _constants2.default)(columnType);
      (0, _array.arrayEach)(this.getInputElements(), function (element) {
        return element.hide();
      });
      this.getSelectElement().setItems(items);
      (0, _get2.default)((0, _getPrototypeOf2.default)(ConditionComponent.prototype), "reset", this).call(this); // Select element as default 'None'

      this.getSelectElement().setValue(items[0]);
    }
    /**
     * On condition select listener.
     *
     * @private
     * @param {Object} command Menu item object (command).
     */

  }, {
    key: "onConditionSelect",
    value: function onConditionSelect(command) {
      (0, _array.arrayEach)(this.getInputElements(), function (element, index) {
        element[command.inputsCount > index ? 'show' : 'hide']();

        if (!index) {
          setTimeout(function () {
            return element.focus();
          }, 10);
        }
      });
      this.runLocalHooks('change', command);
    }
    /**
     * On component SelectUI closed listener.
     *
     * @private
     */

  }, {
    key: "onSelectUIClosed",
    value: function onSelectUIClosed() {
      this.runLocalHooks('afterClose');
    }
    /**
     * Key down listener.
     *
     * @private
     * @param {Event} event DOM event object.
     */

  }, {
    key: "onInputKeyDown",
    value: function onInputKeyDown(event) {
      if ((0, _unicode.isKey)(event.keyCode, 'ENTER')) {
        this.runLocalHooks('accept');
        (0, _event.stopImmediatePropagation)(event);
      } else if ((0, _unicode.isKey)(event.keyCode, 'ESCAPE')) {
        this.runLocalHooks('cancel');
        (0, _event.stopImmediatePropagation)(event);
      }
    }
  }]);
  return ConditionComponent;
}(_base.default);

var _default = ConditionComponent;
exports.default = _default;

/***/ }),
/* 706 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));

var _object = __webpack_require__(4);

var _stateSaver;

var MIXIN_NAME = 'stateSaver';
var STATE_PREFIX = 'state_';
var PROP_PREFIX = '_states';

var getState = function getState(object, stateId) {
  return object[PROP_PREFIX][STATE_PREFIX + stateId];
};

var setState = function setState(object, stateId, value) {
  object[PROP_PREFIX][STATE_PREFIX + stateId] = value;
};
/**
 * Mixin object to extend functionality for save/restore object state.
 *
 * @type {Object}
 */


var stateSaver = (_stateSaver = {}, (0, _defineProperty2.default)(_stateSaver, PROP_PREFIX, {}), (0, _defineProperty2.default)(_stateSaver, "getCachedState", function getCachedState(stateId) {
  return getState(this, stateId);
}), (0, _defineProperty2.default)(_stateSaver, "setCachedState", function setCachedState(stateId, value) {
  setState(this, stateId, value);
}), (0, _defineProperty2.default)(_stateSaver, "saveState", function saveState(stateId) {
  setState(this, stateId, this.getState());
}), (0, _defineProperty2.default)(_stateSaver, "restoreState", function restoreState(stateId) {
  this.setState(getState(this, stateId));
}), (0, _defineProperty2.default)(_stateSaver, "hasSavedState", function hasSavedState(stateId) {
  return getState(this, stateId) !== void 0;
}), (0, _defineProperty2.default)(_stateSaver, "clearState", function clearState(stateId) {
  setState(this, stateId);
}), (0, _defineProperty2.default)(_stateSaver, "clearStates", function clearStates() {
  this[PROP_PREFIX] = {};
}), _stateSaver);
(0, _object.defineGetter)(stateSaver, 'MIXIN_NAME', MIXIN_NAME, {
  writable: false,
  enumerable: false
});
var _default = stateSaver;
exports.default = _default;

/***/ }),
/* 707 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'none';
exports.CONDITION_NAME = CONDITION_NAME;

function condition() {
  return true;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_NONE,
  inputsCount: 0,
  showOperators: false
});

/***/ }),
/* 708 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var _empty = __webpack_require__(493);

var CONDITION_NAME = 'not_empty';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, inputValues) {
  return !(0, _conditionRegisterer.getCondition)(_empty.CONDITION_NAME, inputValues)(dataRow);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_NOT_EMPTY,
  inputsCount: 0,
  showOperators: true
});

/***/ }),
/* 709 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var _equal = __webpack_require__(494);

var CONDITION_NAME = 'neq';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, inputValues) {
  return !(0, _conditionRegisterer.getCondition)(_equal.CONDITION_NAME, inputValues)(dataRow);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_NOT_EQUAL,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 710 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'gt';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var conditionValue = value;

  if (dataRow.meta.type === 'numeric') {
    conditionValue = parseFloat(conditionValue, 10);
  }

  return dataRow.value > conditionValue;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_GREATER_THAN,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 711 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'gte';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var conditionValue = value;

  if (dataRow.meta.type === 'numeric') {
    conditionValue = parseFloat(conditionValue, 10);
  }

  return dataRow.value >= conditionValue;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 712 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'lt';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var conditionValue = value;

  if (dataRow.meta.type === 'numeric') {
    conditionValue = parseFloat(conditionValue, 10);
  }

  return dataRow.value < conditionValue;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_LESS_THAN,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 713 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'lte';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  var conditionValue = value;

  if (dataRow.meta.type === 'numeric') {
    conditionValue = parseFloat(conditionValue, 10);
  }

  return dataRow.value <= conditionValue;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 714 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var _between = __webpack_require__(495);

var CONDITION_NAME = 'not_between';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, inputValues) {
  return !(0, _conditionRegisterer.getCondition)(_between.CONDITION_NAME, inputValues)(dataRow);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_NOT_BETWEEN,
  inputsCount: 2,
  showOperators: true
});

/***/ }),
/* 715 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(138);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _mixed = __webpack_require__(27);

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'begins_with';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  return (0, _mixed.stringify)(dataRow.value).toLowerCase().startsWith((0, _mixed.stringify)(value));
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_BEGINS_WITH,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 716 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(717);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var C = _interopRequireWildcard(__webpack_require__(11));

var _mixed = __webpack_require__(27);

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'ends_with';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  return (0, _mixed.stringify)(dataRow.value).toLowerCase().endsWith((0, _mixed.stringify)(value));
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_ENDS_WITH,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 717 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toLength = __webpack_require__(48);
var validateArguments = __webpack_require__(157);
var ENDS_WITH = 'endsWith';
var nativeEndsWith = ''[ENDS_WITH];
var min = Math.min;

var CORRECT_IS_REGEXP_LOGIC = __webpack_require__(158)(ENDS_WITH);

// `String.prototype.endsWith` method
// https://tc39.github.io/ecma262/#sec-string.prototype.endswith
__webpack_require__(22)({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, {
  endsWith: function endsWith(searchString /* , endPosition = @length */) {
    var that = validateArguments(this, searchString, ENDS_WITH);
    var endPosition = arguments.length > 1 ? arguments[1] : undefined;
    var len = toLength(that.length);
    var end = endPosition === undefined ? len : min(toLength(endPosition), len);
    var search = String(searchString);
    return nativeEndsWith
      ? nativeEndsWith.call(that, search, end)
      : that.slice(end - search.length, end) === search;
  }
});


/***/ }),
/* 718 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var _contains = __webpack_require__(498);

var CONDITION_NAME = 'not_contains';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, inputValues) {
  return !(0, _conditionRegisterer.getCondition)(_contains.CONDITION_NAME, inputValues)(dataRow);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_NOT_CONTAIN,
  inputsCount: 1,
  showOperators: true
});

/***/ }),
/* 719 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _moment = _interopRequireDefault(__webpack_require__(63));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'date_tomorrow';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow) {
  var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);

  if (!date.isValid()) {
    return false;
  }

  return date.isSame((0, _moment.default)().subtract(-1, 'days').startOf('day'), 'd');
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_TOMORROW,
  inputsCount: 0
});

/***/ }),
/* 720 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _moment = _interopRequireDefault(__webpack_require__(63));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'date_today';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow) {
  var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);

  if (!date.isValid()) {
    return false;
  }

  return date.isSame((0, _moment.default)().startOf('day'), 'd');
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_TODAY,
  inputsCount: 0
});

/***/ }),
/* 721 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _moment = _interopRequireDefault(__webpack_require__(63));

var C = _interopRequireWildcard(__webpack_require__(11));

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'date_yesterday';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow) {
  var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);

  if (!date.isValid()) {
    return false;
  }

  return date.isSame((0, _moment.default)().subtract(1, 'days').startOf('day'), 'd');
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: C.FILTERS_CONDITIONS_YESTERDAY,
  inputsCount: 0
});

/***/ }),
/* 722 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _conditionRegisterer = __webpack_require__(28);

var _utils = __webpack_require__(108);

var CONDITION_NAME = 'by_value';
exports.CONDITION_NAME = CONDITION_NAME;

function condition(dataRow, _ref) {
  var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
      value = _ref2[0];

  return value(dataRow.value);
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: 'By value',
  inputsCount: 0,
  inputValuesDecorator: function inputValuesDecorator(_ref3) {
    var _ref4 = (0, _slicedToArray2.default)(_ref3, 1),
        data = _ref4[0];

    return [(0, _utils.createArrayAssertion)(data)];
  },
  showOperators: false
});

/***/ }),
/* 723 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'true';
exports.CONDITION_NAME = CONDITION_NAME;

function condition() {
  return true;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: 'True'
});

/***/ }),
/* 724 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;

var _conditionRegisterer = __webpack_require__(28);

var CONDITION_NAME = 'false';
exports.CONDITION_NAME = CONDITION_NAME;

function condition() {
  return false;
}

(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
  name: 'False'
});

/***/ }),
/* 725 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(51);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _menu = _interopRequireDefault(__webpack_require__(167));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var C = _interopRequireWildcard(__webpack_require__(11));

var _predefinedItems = __webpack_require__(83);

var _base = _interopRequireDefault(__webpack_require__(110));

var privatePool = new WeakMap();
/**
 * @class SelectUI
 * @util
 */

var SelectUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(SelectUI, _BaseUI);
  (0, _createClass2.default)(SelectUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        className: 'htUISelect',
        wrapIt: false
      });
    }
  }]);

  function SelectUI(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, SelectUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(SelectUI).call(this, hotInstance, (0, _object.extend)(SelectUI.DEFAULTS, options)));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {});
    /**
     * Instance of {@link Menu}.
     *
     * @type {Menu}
     */

    _this.menu = null;
    /**
     * List of available select options.
     *
     * @type {Array}
     */

    _this.items = [];

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   */


  (0, _createClass2.default)(SelectUI, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.addLocalHook('click', function () {
        return _this2.onClick();
      });
    }
    /**
     * Set options which can be selected in the list.
     *
     * @param {Array} items Array of objects with required keys `key` and `name`.
     */

  }, {
    key: "setItems",
    value: function setItems(items) {
      this.items = this.translateNames(items);

      if (this.menu) {
        this.menu.setMenuItems(this.items);
      }
    }
    /**
     * Translate names of menu items.
     *
     * @param {Array} items Array of objects with required keys `key` and `name`.
     * @returns {Array} Items with translated `name` keys.
     */

  }, {
    key: "translateNames",
    value: function translateNames(items) {
      var _this3 = this;

      (0, _array.arrayEach)(items, function (item) {
        item.name = _this3.translateIfPossible(item.name);
      });
      return items;
    }
    /**
     * Build DOM structure.
     */

  }, {
    key: "build",
    value: function build() {
      var _this4 = this;

      (0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "build", this).call(this);
      this.menu = new _menu.default(this.hot, {
        className: 'htSelectUI htFiltersConditionsMenu',
        keepInViewport: false,
        standalone: true
      });
      this.menu.setMenuItems(this.items);
      var caption = new _base.default(this.hot, {
        className: 'htUISelectCaption'
      });
      var dropdown = new _base.default(this.hot, {
        className: 'htUISelectDropdown'
      });
      var priv = privatePool.get(this);
      priv.caption = caption;
      priv.captionElement = caption.element;
      priv.dropdown = dropdown;
      (0, _array.arrayEach)([caption, dropdown], function (element) {
        return _this4._element.appendChild(element.element);
      });
      this.menu.addLocalHook('select', function (command) {
        return _this4.onMenuSelect(command);
      });
      this.menu.addLocalHook('afterClose', function () {
        return _this4.onMenuClosed();
      });
      this.update();
    }
    /**
     * Update DOM structure.
     */

  }, {
    key: "update",
    value: function update() {
      if (!this.isBuilt()) {
        return;
      }

      var conditionName;

      if (this.options.value) {
        conditionName = this.options.value.name;
      } else {
        conditionName = this.menu.hot.getTranslatedPhrase(C.FILTERS_CONDITIONS_NONE);
      }

      privatePool.get(this).captionElement.textContent = conditionName;
      (0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "update", this).call(this);
    }
    /**
     * Open select dropdown menu with available options.
     */

  }, {
    key: "openOptions",
    value: function openOptions() {
      var rect = this.element.getBoundingClientRect();

      if (this.menu) {
        this.menu.open();
        this.menu.setPosition({
          left: rect.left - 5,
          top: rect.top,
          width: rect.width,
          height: rect.height
        });
      }
    }
    /**
     * Close select dropdown menu.
     */

  }, {
    key: "closeOptions",
    value: function closeOptions() {
      if (this.menu) {
        this.menu.close();
      }
    }
    /**
     * On menu selected listener.
     *
     * @private
     * @param {Object} command Selected item
     */

  }, {
    key: "onMenuSelect",
    value: function onMenuSelect(command) {
      if (command.name !== _predefinedItems.SEPARATOR) {
        this.options.value = command;
        this.closeOptions();
        this.update();
        this.runLocalHooks('select', this.options.value);
      }
    }
    /**
     * On menu closed listener.
     *
     * @private
     */

  }, {
    key: "onMenuClosed",
    value: function onMenuClosed() {
      this.runLocalHooks('afterClose');
    }
    /**
     * On element click listener.
     *
     * @private
     */

  }, {
    key: "onClick",
    value: function onClick() {
      this.openOptions();
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.menu) {
        this.menu.destroy();
        this.menu = null;
      }

      var _privatePool$get = privatePool.get(this),
          caption = _privatePool$get.caption,
          dropdown = _privatePool$get.dropdown;

      if (caption) {
        caption.destroy();
      }

      if (dropdown) {
        dropdown.destroy();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "destroy", this).call(this);
    }
  }]);
  return SelectUI;
}(_base.default);

var _default = SelectUI;
exports.default = _default;

/***/ }),
/* 726 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(159);

__webpack_require__(51);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var _templateLiteralTag = __webpack_require__(67);

var _base = _interopRequireDefault(__webpack_require__(139));

var _logicalOperationRegisterer = __webpack_require__(109);

var _conjunction = __webpack_require__(170);

var _disjunction = __webpack_require__(499);

var _disjunctionWithExtraCondition = __webpack_require__(500);

var _radioInput = _interopRequireDefault(__webpack_require__(727));

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["Radio button with index ", " doesn't exist."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

var SELECTED_AT_START_ELEMENT_INDEX = 0;
/**
 * @class OperatorsComponent
 * @plugin Filters
 */

var OperatorsComponent =
/*#__PURE__*/
function (_BaseComponent) {
  (0, _inherits2.default)(OperatorsComponent, _BaseComponent);

  function OperatorsComponent(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, OperatorsComponent);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(OperatorsComponent).call(this, hotInstance));
    _this.id = options.id;
    _this.name = options.name;

    _this.buildOperatorsElement();

    return _this;
  }
  /**
   * Get menu object descriptor.
   *
   * @returns {Object}
   */


  (0, _createClass2.default)(OperatorsComponent, [{
    key: "getMenuItemDescriptor",
    value: function getMenuItemDescriptor() {
      var _this2 = this;

      return {
        key: this.id,
        name: this.name,
        isCommand: false,
        disableSelection: true,
        hidden: function hidden() {
          return _this2.isHidden();
        },
        renderer: function renderer(hot, wrapper) {
          (0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuOperators');

          if (!wrapper.parentNode.hasAttribute('ghost-table')) {
            (0, _array.arrayEach)(_this2.elements, function (ui) {
              return wrapper.appendChild(ui.element);
            });
          }

          return wrapper;
        }
      };
    }
    /**
     * Add RadioInputUI elements to component
     *
     * @private
     */

  }, {
    key: "buildOperatorsElement",
    value: function buildOperatorsElement() {
      var _this3 = this;

      var operationKeys = [_conjunction.OPERATION_ID, _disjunction.OPERATION_ID];
      (0, _array.arrayEach)(operationKeys, function (operation) {
        var radioInput = new _radioInput.default(_this3.hot, {
          name: 'operator',
          label: {
            htmlFor: operation,
            textContent: (0, _logicalOperationRegisterer.getOperationName)(operation)
          },
          value: operation,
          checked: operation === operationKeys[SELECTED_AT_START_ELEMENT_INDEX],
          id: operation
        });
        radioInput.addLocalHook('change', function (event) {
          return _this3.onRadioInputChange(event);
        });

        _this3.elements.push(radioInput);
      });
    }
    /**
     * Set state of operators component to check radio input at specific `index`.
     *
     * @param searchedIndex Index of radio input to check.
     */

  }, {
    key: "setChecked",
    value: function setChecked(searchedIndex) {
      if (this.elements.length < searchedIndex) {
        throw Error((0, _templateLiteralTag.toSingleLine)(_templateObject(), searchedIndex));
      }

      (0, _array.arrayEach)(this.elements, function (element, index) {
        element.setChecked(index === searchedIndex);
      });
    }
    /**
     * Get `id` of active operator
     *
     * @returns {String}
     */

  }, {
    key: "getActiveOperationId",
    value: function getActiveOperationId() {
      var operationElement = this.elements.find(function (element) {
        return element instanceof _radioInput.default && element.isChecked();
      });

      if (operationElement) {
        return operationElement.getValue();
      }

      return _conjunction.OPERATION_ID;
    }
    /**
     * Export state of the component (get selected operator).
     *
     * @returns {String} Returns `id` of selected operator.
     */

  }, {
    key: "getState",
    value: function getState() {
      return this.getActiveOperationId();
    }
    /**
     * Set state of the component.
     *
     * @param {Object} value State to restore.
     */

  }, {
    key: "setState",
    value: function setState(value) {
      this.reset();

      if (value && this.getActiveOperationId() !== value) {
        (0, _array.arrayEach)(this.elements, function (element) {
          element.setChecked(element.getValue() === value);
        });
      }
    }
    /**
     * Update state of component.
     * @param [operationId='conjunction'] Id of selected operation.
     * @param column Physical column index.
     */

  }, {
    key: "updateState",
    value: function updateState() {
      var operationId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _conjunction.OPERATION_ID;
      var column = arguments.length > 1 ? arguments[1] : undefined;
      var selectedOperationId = operationId;

      if (selectedOperationId === _disjunctionWithExtraCondition.OPERATION_ID) {
        selectedOperationId = _disjunction.OPERATION_ID;
      }

      this.setCachedState(column, selectedOperationId);
    }
    /**
     * Reset elements to their initial state.
     */

  }, {
    key: "reset",
    value: function reset() {
      this.setChecked(SELECTED_AT_START_ELEMENT_INDEX);
    }
    /**
     * OnChange listener.
     *
     * @private
     * @param {Event} event DOM event
     */

  }, {
    key: "onRadioInputChange",
    value: function onRadioInputChange(event) {
      this.setState(event.realTarget.value);
    }
  }]);
  return OperatorsComponent;
}(_base.default);

var _default = OperatorsComponent;
exports.default = _default;

/***/ }),
/* 727 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _object = __webpack_require__(4);

var _base = _interopRequireDefault(__webpack_require__(110));

var privatePool = new WeakMap();
/**
 * @class RadioInputUI
 * @util
 */

var RadioInputUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(RadioInputUI, _BaseUI);
  (0, _createClass2.default)(RadioInputUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        type: 'radio',
        tagName: 'input',
        className: 'htUIRadio',
        label: {}
      });
    }
  }]);

  function RadioInputUI(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, RadioInputUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(RadioInputUI).call(this, hotInstance, (0, _object.extend)(RadioInputUI.DEFAULTS, options)));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {});
    return _this;
  }
  /**
   * Build DOM structure.
   */


  (0, _createClass2.default)(RadioInputUI, [{
    key: "build",
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(RadioInputUI.prototype), "build", this).call(this);
      var priv = privatePool.get(this);
      priv.input = this._element.firstChild;
      var label = this.hot.rootDocument.createElement('label');
      label.textContent = this.translateIfPossible(this.options.label.textContent);
      label.htmlFor = this.translateIfPossible(this.options.label.htmlFor);
      priv.label = label;

      this._element.appendChild(label);

      this.update();
    }
    /**
     * Update element.
     */

  }, {
    key: "update",
    value: function update() {
      if (!this.isBuilt()) {
        return;
      }

      var priv = privatePool.get(this);
      priv.input.checked = this.options.checked;
      priv.label.textContent = this.translateIfPossible(this.options.label.textContent);
    }
    /**
     * Check if radio button is checked.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isChecked",
    value: function isChecked() {
      return this.options.checked;
    }
    /**
     * Set input checked attribute
     *
     * @param value {Boolean} value
     */

  }, {
    key: "setChecked",
    value: function setChecked() {
      var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
      this.options.checked = value;
      this.update();
    }
    /**
     * Focus element.
     */

  }, {
    key: "focus",
    value: function focus() {
      if (this.isBuilt()) {
        privatePool.get(this).input.focus();
      }
    }
  }]);
  return RadioInputUI;
}(_base.default);

var _default = RadioInputUI;
exports.default = _default;

/***/ }),
/* 728 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(56);

__webpack_require__(51);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _event = __webpack_require__(31);

var _array = __webpack_require__(3);

var _unicode = __webpack_require__(50);

var C = _interopRequireWildcard(__webpack_require__(11));

var _utils = __webpack_require__(108);

var _base = _interopRequireDefault(__webpack_require__(139));

var _multipleSelect = _interopRequireDefault(__webpack_require__(729));

var _constants2 = __webpack_require__(169);

var _conditionRegisterer = __webpack_require__(28);

/**
 * @class ValueComponent
 * @plugin Filters
 */
var ValueComponent =
/*#__PURE__*/
function (_BaseComponent) {
  (0, _inherits2.default)(ValueComponent, _BaseComponent);

  function ValueComponent(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, ValueComponent);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ValueComponent).call(this, hotInstance));
    _this.id = options.id;
    _this.name = options.name;

    _this.elements.push(new _multipleSelect.default(_this.hot));

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   *
   * @private
   */


  (0, _createClass2.default)(ValueComponent, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.getMultipleSelectElement().addLocalHook('keydown', function (event) {
        return _this2.onInputKeyDown(event);
      });
    }
    /**
     * Set state of the component.
     *
     * @param {Object} value
     */

  }, {
    key: "setState",
    value: function setState(value) {
      this.reset();

      if (value && value.command.key === _constants2.CONDITION_BY_VALUE) {
        var select = this.getMultipleSelectElement();
        select.setItems(value.itemsSnapshot);
        select.setValue(value.args[0]);
      }
    }
    /**
     * Export state of the component (get selected filter and filter arguments).
     *
     * @returns {Object} Returns object where `command` key keeps used condition filter and `args` key its arguments.
     */

  }, {
    key: "getState",
    value: function getState() {
      var select = this.getMultipleSelectElement();
      var availableItems = select.getItems();
      return {
        command: {
          key: select.isSelectedAllValues() || !availableItems.length ? _constants2.CONDITION_NONE : _constants2.CONDITION_BY_VALUE
        },
        args: [select.getValue()],
        itemsSnapshot: availableItems
      };
    }
    /**
     * Update state of component.
     *
     * @param {Object} stateInfo Information about state containing stack of edited column,
     * stack of dependent conditions, data factory and optional condition arguments change. It's described by object containing keys:
     * `editedConditionStack`, `dependentConditionStacks`, `visibleDataFactory` and `conditionArgsChange`.
     */

  }, {
    key: "updateState",
    value: function updateState(stateInfo) {
      var _this3 = this;

      var updateColumnState = function updateColumnState(column, conditions, conditionArgsChange, filteredRowsFactory, conditionsStack) {
        var _arrayFilter = (0, _array.arrayFilter)(conditions, function (condition) {
          return condition.name === _constants2.CONDITION_BY_VALUE;
        }),
            _arrayFilter2 = (0, _slicedToArray2.default)(_arrayFilter, 1),
            firstByValueCondition = _arrayFilter2[0];

        var state = {};

        var defaultBlankCellValue = _this3.hot.getTranslatedPhrase(C.FILTERS_VALUES_BLANK_CELLS);

        if (firstByValueCondition) {
          var rowValues = (0, _array.arrayMap)(filteredRowsFactory(column, conditionsStack), function (row) {
            return row.value;
          });
          rowValues = (0, _utils.unifyColumnValues)(rowValues);

          if (conditionArgsChange) {
            firstByValueCondition.args[0] = conditionArgsChange;
          }

          var selectedValues = [];
          var itemsSnapshot = (0, _utils.intersectValues)(rowValues, firstByValueCondition.args[0], defaultBlankCellValue, function (item) {
            if (item.checked) {
              selectedValues.push(item.value);
            }
          });
          state.args = [selectedValues];
          state.command = (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_BY_VALUE);
          state.itemsSnapshot = itemsSnapshot;
        } else {
          state.args = [];
          state.command = (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
        }

        _this3.setCachedState(column, state);
      };

      updateColumnState(stateInfo.editedConditionStack.column, stateInfo.editedConditionStack.conditions, stateInfo.conditionArgsChange, stateInfo.filteredRowsFactory); // Shallow deep update of component state

      if (stateInfo.dependentConditionStacks.length) {
        updateColumnState(stateInfo.dependentConditionStacks[0].column, stateInfo.dependentConditionStacks[0].conditions, stateInfo.conditionArgsChange, stateInfo.filteredRowsFactory, stateInfo.editedConditionStack);
      }
    }
    /**
     * Get multiple select element.
     *
     * @returns {MultipleSelectUI}
     */

  }, {
    key: "getMultipleSelectElement",
    value: function getMultipleSelectElement() {
      return this.elements.filter(function (element) {
        return element instanceof _multipleSelect.default;
      })[0];
    }
    /**
     * Get object descriptor for menu item entry.
     *
     * @returns {Object}
     */

  }, {
    key: "getMenuItemDescriptor",
    value: function getMenuItemDescriptor() {
      var _this4 = this;

      return {
        key: this.id,
        name: this.name,
        isCommand: false,
        disableSelection: true,
        hidden: function hidden() {
          return _this4.isHidden();
        },
        renderer: function renderer(hot, wrapper, row, col, prop, value) {
          (0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuValue');

          var label = _this4.hot.rootDocument.createElement('div');

          (0, _element.addClass)(label, 'htFiltersMenuLabel');
          label.textContent = value;
          wrapper.appendChild(label);

          if (!wrapper.parentNode.hasAttribute('ghost-table')) {
            (0, _array.arrayEach)(_this4.elements, function (ui) {
              return wrapper.appendChild(ui.element);
            });
          }

          return wrapper;
        }
      };
    }
    /**
     * Reset elements to their initial state.
     */

  }, {
    key: "reset",
    value: function reset() {
      var defaultBlankCellValue = this.hot.getTranslatedPhrase(C.FILTERS_VALUES_BLANK_CELLS);
      var values = (0, _utils.unifyColumnValues)(this._getColumnVisibleValues());
      var items = (0, _utils.intersectValues)(values, values, defaultBlankCellValue);
      this.getMultipleSelectElement().setItems(items);
      (0, _get2.default)((0, _getPrototypeOf2.default)(ValueComponent.prototype), "reset", this).call(this);
      this.getMultipleSelectElement().setValue(values);
    }
    /**
     * Key down listener.
     *
     * @private
     * @param {Event} event DOM event object.
     */

  }, {
    key: "onInputKeyDown",
    value: function onInputKeyDown(event) {
      if ((0, _unicode.isKey)(event.keyCode, 'ESCAPE')) {
        this.runLocalHooks('cancel');
        (0, _event.stopImmediatePropagation)(event);
      }
    }
    /**
     * Get data for currently selected column.
     *
     * @returns {Array}
     * @private
     */

  }, {
    key: "_getColumnVisibleValues",
    value: function _getColumnVisibleValues() {
      var lastSelectedColumn = this.hot.getPlugin('filters').getSelectedColumn();
      var visualIndex = lastSelectedColumn && lastSelectedColumn.visualIndex;
      return (0, _array.arrayMap)(this.hot.getDataAtCol(visualIndex), function (v) {
        return (0, _utils.toEmptyString)(v);
      });
    }
  }]);
  return ValueComponent;
}(_base.default);

var _default = ValueComponent;
exports.default = _default;

/***/ }),
/* 729 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _unicode = __webpack_require__(50);

var _function = __webpack_require__(75);

var C = _interopRequireWildcard(__webpack_require__(11));

var _event = __webpack_require__(31);

var _base = _interopRequireDefault(__webpack_require__(110));

var _input = _interopRequireDefault(__webpack_require__(171));

var _link = _interopRequireDefault(__webpack_require__(730));

var _utils = __webpack_require__(108);

var privatePool = new WeakMap();
/**
 * @class MultipleSelectUI
 * @util
 */

var MultipleSelectUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(MultipleSelectUI, _BaseUI);
  (0, _createClass2.default)(MultipleSelectUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        className: 'htUIMultipleSelect',
        value: []
      });
    }
  }]);

  function MultipleSelectUI(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, MultipleSelectUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultipleSelectUI).call(this, hotInstance, (0, _object.extend)(MultipleSelectUI.DEFAULTS, options)));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {});
    /**
     * Input element.
     *
     * @type {InputUI}
     */

    _this.searchInput = new _input.default(_this.hot, {
      placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_SEARCH,
      className: 'htUIMultipleSelectSearch'
    });
    /**
     * "Select all" UI element.
     *
     * @type {BaseUI}
     */

    _this.selectAllUI = new _link.default(_this.hot, {
      textContent: C.FILTERS_BUTTONS_SELECT_ALL,
      className: 'htUISelectAll'
    });
    /**
     * "Clear" UI element.
     *
     * @type {BaseUI}
     */

    _this.clearAllUI = new _link.default(_this.hot, {
      textContent: C.FILTERS_BUTTONS_CLEAR,
      className: 'htUIClearAll'
    });
    /**
     * List of available select options.
     *
     * @type {Array}
     */

    _this.items = [];
    /**
     * Handsontable instance used as items list element.
     *
     * @type {Handsontable}
     */

    _this.itemsBox = null;

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   */


  (0, _createClass2.default)(MultipleSelectUI, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      this.searchInput.addLocalHook('keydown', function (event) {
        return _this2.onInputKeyDown(event);
      });
      this.searchInput.addLocalHook('input', function (event) {
        return _this2.onInput(event);
      });
      this.selectAllUI.addLocalHook('click', function (event) {
        return _this2.onSelectAllClick(event);
      });
      this.clearAllUI.addLocalHook('click', function (event) {
        return _this2.onClearAllClick(event);
      });
    }
    /**
     * Set available options.
     *
     * @param {Array} items Array of objects with `checked` and `label` property.
     */

  }, {
    key: "setItems",
    value: function setItems(items) {
      this.items = items;

      if (this.itemsBox) {
        this.itemsBox.loadData(this.items);
      }
    }
    /**
     * Get all available options.
     *
     * @returns {Array}
     */

  }, {
    key: "getItems",
    value: function getItems() {
      return (0, _toConsumableArray2.default)(this.items);
    }
    /**
     * Get element value.
     *
     * @returns {Array} Array of selected values.
     */

  }, {
    key: "getValue",
    value: function getValue() {
      return itemsToValue(this.items);
    }
    /**
     * Check if all values listed in element are selected.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isSelectedAllValues",
    value: function isSelectedAllValues() {
      return this.items.length === this.getValue().length;
    }
    /**
     * Build DOM structure.
     */

  }, {
    key: "build",
    value: function build() {
      var _this3 = this;

      (0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "build", this).call(this);
      var rootDocument = this.hot.rootDocument;
      var itemsBoxWrapper = rootDocument.createElement('div');
      var selectionControl = new _base.default(this.hot, {
        className: 'htUISelectionControls',
        children: [this.selectAllUI, this.clearAllUI]
      });

      this._element.appendChild(this.searchInput.element);

      this._element.appendChild(selectionControl.element);

      this._element.appendChild(itemsBoxWrapper);

      var hotInitializer = function hotInitializer(wrapper) {
        if (!_this3._element) {
          return;
        }

        if (_this3.itemsBox) {
          _this3.itemsBox.destroy();
        }

        (0, _element.addClass)(wrapper, 'htUIMultipleSelectHot'); // Construct and initialise a new Handsontable

        _this3.itemsBox = new _this3.hot.constructor(wrapper, {
          data: _this3.items,
          columns: [{
            data: 'checked',
            type: 'checkbox',
            label: {
              property: 'visualValue',
              position: 'after'
            }
          }],
          beforeRenderer: function beforeRenderer(TD, row, col, prop, value, cellProperties) {
            TD.title = cellProperties.instance.getDataAtRowProp(row, cellProperties.label.property);
          },
          autoWrapCol: true,
          height: 110,
          // Workaround for #151.
          colWidths: function colWidths() {
            return _this3.itemsBox.container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument);
          },
          copyPaste: false,
          disableVisualSelection: 'area',
          fillHandle: false,
          fragmentSelection: 'cell',
          tabMoves: {
            row: 1,
            col: 0
          },
          beforeKeyDown: function beforeKeyDown(event) {
            return _this3.onItemsBoxBeforeKeyDown(event);
          }
        });

        _this3.itemsBox.init();
      };

      hotInitializer(itemsBoxWrapper);
      setTimeout(function () {
        return hotInitializer(itemsBoxWrapper);
      }, 100);
    }
    /**
     * Reset DOM structure.
     */

  }, {
    key: "reset",
    value: function reset() {
      this.searchInput.reset();
      this.selectAllUI.reset();
      this.clearAllUI.reset();
    }
    /**
     * Update DOM structure.
     */

  }, {
    key: "update",
    value: function update() {
      if (!this.isBuilt()) {
        return;
      }

      this.itemsBox.loadData(valueToItems(this.items, this.options.value));
      (0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "update", this).call(this);
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.itemsBox) {
        this.itemsBox.destroy();
      }

      this.searchInput.destroy();
      this.clearAllUI.destroy();
      this.selectAllUI.destroy();
      this.searchInput = null;
      this.clearAllUI = null;
      this.selectAllUI = null;
      this.itemsBox = null;
      this.items = null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "destroy", this).call(this);
    }
    /**
     * 'input' event listener for input element.
     *
     * @private
     * @param {Event} event DOM event.
     */

  }, {
    key: "onInput",
    value: function onInput(event) {
      var value = event.target.value.toLowerCase();
      var filteredItems;

      if (value === '') {
        filteredItems = (0, _toConsumableArray2.default)(this.items);
      } else {
        filteredItems = (0, _array.arrayFilter)(this.items, function (item) {
          return "".concat(item.value).toLowerCase().indexOf(value) >= 0;
        });
      }

      this.itemsBox.loadData(filteredItems);
    }
    /**
     * 'keydown' event listener for input element.
     *
     * @private
     * @param {Event} event DOM event.
     */

  }, {
    key: "onInputKeyDown",
    value: function onInputKeyDown(event) {
      this.runLocalHooks('keydown', event, this);
      var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);

      if (isKeyCode('ARROW_DOWN|TAB') && !this.itemsBox.isListening()) {
        (0, _event.stopImmediatePropagation)(event);
        this.itemsBox.listen();
        this.itemsBox.selectCell(0, 0);
      }
    }
    /**
     * On before key down listener (internal Handsontable).
     *
     * @private
     * @param {Event} event DOM event.
     */

  }, {
    key: "onItemsBoxBeforeKeyDown",
    value: function onItemsBoxBeforeKeyDown(event) {
      var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);

      if (isKeyCode('ESCAPE')) {
        this.runLocalHooks('keydown', event, this);
      } // for keys different than below, unfocus Handsontable and focus search input


      if (!isKeyCode('ARROW_UP|ARROW_DOWN|ARROW_LEFT|ARROW_RIGHT|TAB|SPACE|ENTER')) {
        (0, _event.stopImmediatePropagation)(event);
        this.itemsBox.unlisten();
        this.itemsBox.deselectCell();
        this.searchInput.focus();
      }
    }
    /**
     * On click listener for "Select all" link.
     *
     * @private
     * @param {DOMEvent} event
     */

  }, {
    key: "onSelectAllClick",
    value: function onSelectAllClick(event) {
      event.preventDefault();
      (0, _array.arrayEach)(this.itemsBox.getSourceData(), function (row) {
        row.checked = true;
      });
      this.itemsBox.render();
    }
    /**
     * On click listener for "Clear" link.
     *
     * @private
     * @param {DOMEvent} event
     */

  }, {
    key: "onClearAllClick",
    value: function onClearAllClick(event) {
      event.preventDefault();
      (0, _array.arrayEach)(this.itemsBox.getSourceData(), function (row) {
        row.checked = false;
      });
      this.itemsBox.render();
    }
  }]);
  return MultipleSelectUI;
}(_base.default);

var _default = MultipleSelectUI;
/**
 * Pick up object items based on selected values.
 *
 * @param {Array} availableItems Base collection to compare values.
 * @param selectedValue Flat array with selected values.
 * @returns {Array}
 */

exports.default = _default;

function valueToItems(availableItems, selectedValue) {
  var arrayAssertion = (0, _utils.createArrayAssertion)(selectedValue);
  return (0, _array.arrayMap)(availableItems, function (item) {
    item.checked = arrayAssertion(item.value);
    return item;
  });
}
/**
 * Convert all checked items into flat array.
 *
 * @param {Array} availableItems Base collection.
 * @returns {Array}
 */


function itemsToValue(availableItems) {
  var items = [];
  (0, _array.arrayEach)(availableItems, function (item) {
    if (item.checked) {
      items.push(item.value);
    }
  });
  return items;
}

/***/ }),
/* 730 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(731);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _object = __webpack_require__(4);

var _base = _interopRequireDefault(__webpack_require__(110));

var privatePool = new WeakMap();
/**
 * @class LinkUI
 * @util
 */

var LinkUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(LinkUI, _BaseUI);
  (0, _createClass2.default)(LinkUI, null, [{
    key: "DEFAULTS",
    get: function get() {
      return (0, _object.clone)({
        href: '#',
        tagName: 'a'
      });
    }
  }]);

  function LinkUI(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, LinkUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(LinkUI).call(this, hotInstance, (0, _object.extend)(LinkUI.DEFAULTS, options)));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {});
    return _this;
  }
  /**
   * Build DOM structure.
   */


  (0, _createClass2.default)(LinkUI, [{
    key: "build",
    value: function build() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(LinkUI.prototype), "build", this).call(this);
      var priv = privatePool.get(this);
      priv.link = this._element.firstChild;
    }
    /**
     * Update element.
     */

  }, {
    key: "update",
    value: function update() {
      if (!this.isBuilt()) {
        return;
      }

      privatePool.get(this).link.textContent = this.translateIfPossible(this.options.textContent);
    }
  }]);
  return LinkUI;
}(_base.default);

var _default = LinkUI;
exports.default = _default;

/***/ }),
/* 731 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var createHTML = __webpack_require__(732);
var FORCED = __webpack_require__(733)('link');

// `String.prototype.link` method
// https://tc39.github.io/ecma262/#sec-string.prototype.link
__webpack_require__(22)({ target: 'String', proto: true, forced: FORCED }, {
  link: function link(url) {
    return createHTML(this, 'a', 'href', url);
  }
});


/***/ }),
/* 732 */
/***/ (function(module, exports, __webpack_require__) {

var requireObjectCoercible = __webpack_require__(58);
var quot = /"/g;

// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
// https://tc39.github.io/ecma262/#sec-createhtml
module.exports = function (string, tag, attribute, value) {
  var S = String(requireObjectCoercible(string));
  var p1 = '<' + tag;
  if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
  return p1 + '>' + S + '</' + tag + '>';
};


/***/ }),
/* 733 */
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__(29);

// check the existence of a method, lowercase
// of a tag and escaping quotes in arguments
module.exports = function (METHOD_NAME) {
  return fails(function () {
    var test = ''[METHOD_NAME]('"');
    return test !== test.toLowerCase() || test.split('"').length > 3;
  });
};


/***/ }),
/* 734 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(51);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _array = __webpack_require__(3);

var C = _interopRequireWildcard(__webpack_require__(11));

var _base = _interopRequireDefault(__webpack_require__(139));

var _input = _interopRequireDefault(__webpack_require__(171));

/**
 * @class ActionBarComponent
 * @plugin Filters
 */
var ActionBarComponent =
/*#__PURE__*/
function (_BaseComponent) {
  (0, _inherits2.default)(ActionBarComponent, _BaseComponent);
  (0, _createClass2.default)(ActionBarComponent, null, [{
    key: "BUTTON_OK",
    get: function get() {
      return 'ok';
    }
  }, {
    key: "BUTTON_CANCEL",
    get: function get() {
      return 'cancel';
    }
  }]);

  function ActionBarComponent(hotInstance, options) {
    var _this;

    (0, _classCallCheck2.default)(this, ActionBarComponent);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ActionBarComponent).call(this, hotInstance));
    _this.id = options.id;
    _this.name = options.name;

    _this.elements.push(new _input.default(_this.hot, {
      type: 'button',
      value: C.FILTERS_BUTTONS_OK,
      className: 'htUIButton htUIButtonOK',
      identifier: ActionBarComponent.BUTTON_OK
    }));

    _this.elements.push(new _input.default(_this.hot, {
      type: 'button',
      value: C.FILTERS_BUTTONS_CANCEL,
      className: 'htUIButton htUIButtonCancel',
      identifier: ActionBarComponent.BUTTON_CANCEL
    }));

    _this.registerHooks();

    return _this;
  }
  /**
   * Register all necessary hooks.
   *
   * @private
   */


  (0, _createClass2.default)(ActionBarComponent, [{
    key: "registerHooks",
    value: function registerHooks() {
      var _this2 = this;

      (0, _array.arrayEach)(this.elements, function (element) {
        element.addLocalHook('click', function (event, button) {
          return _this2.onButtonClick(event, button);
        });
      });
    }
    /**
     * Get menu object descriptor.
     *
     * @returns {Object}
     */

  }, {
    key: "getMenuItemDescriptor",
    value: function getMenuItemDescriptor() {
      var _this3 = this;

      return {
        key: this.id,
        name: this.name,
        isCommand: false,
        disableSelection: true,
        hidden: function hidden() {
          return _this3.isHidden();
        },
        renderer: function renderer(hot, wrapper) {
          (0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuActionBar');

          if (!wrapper.parentNode.hasAttribute('ghost-table')) {
            (0, _array.arrayEach)(_this3.elements, function (ui) {
              return wrapper.appendChild(ui.element);
            });
          }

          return wrapper;
        }
      };
    }
    /**
     * Fire accept event.
     */

  }, {
    key: "accept",
    value: function accept() {
      this.runLocalHooks('accept');
    }
    /**
     * Fire cancel event.
     */

  }, {
    key: "cancel",
    value: function cancel() {
      this.runLocalHooks('cancel');
    }
    /**
     * On button click listener.
     *
     * @private
     * @param {Event} event DOM event
     * @param {InputUI} button InputUI object.
     */

  }, {
    key: "onButtonClick",
    value: function onButtonClick(event, button) {
      if (button.options.identifier === ActionBarComponent.BUTTON_OK) {
        this.accept();
      } else {
        this.cancel();
      }
    }
  }]);
  return ActionBarComponent;
}(_base.default);

var _default = ActionBarComponent;
exports.default = _default;

/***/ }),
/* 735 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(12);

__webpack_require__(40);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _function = __webpack_require__(75);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _conditionCollection = _interopRequireDefault(__webpack_require__(501));

var _dataFilter = _interopRequireDefault(__webpack_require__(502));

var _utils = __webpack_require__(108);

/**
 * Class which is designed for observing changes in condition collection. When condition is changed by user at specified
 * column it's necessary to update all conditions defined after this edited one.
 *
 * Object fires `update` hook for every column conditions change.
 *
 * @class ConditionUpdateObserver
 * @plugin Filters
 */
var ConditionUpdateObserver =
/*#__PURE__*/
function () {
  function ConditionUpdateObserver(conditionCollection) {
    var _this = this;

    var columnDataFactory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
      return [];
    };
    (0, _classCallCheck2.default)(this, ConditionUpdateObserver);

    /**
     * Reference to the instance of {@link ConditionCollection}.
     *
     * @type {ConditionCollection}
     */
    this.conditionCollection = conditionCollection;
    /**
     * Function which provide source data factory for specified column.
     *
     * @type {Function}
     */

    this.columnDataFactory = columnDataFactory;
    /**
     * Collected changes when grouping is enabled.
     *
     * @type {Array}
     * @default []
     */

    this.changes = [];
    /**
     * Flag which determines if grouping events is enabled.
     *
     * @type {Boolean}
     */

    this.grouping = false;
    /**
     * The latest known position of edited conditions at specified column index.
     *
     * @type {Number}
     * @default -1
     */

    this.latestEditedColumnPosition = -1;
    /**
     * The latest known order of conditions stack.
     *
     * @type {Array}
     */

    this.latestOrderStack = [];
    this.conditionCollection.addLocalHook('beforeRemove', function (column) {
      return _this._onConditionBeforeModify(column);
    });
    this.conditionCollection.addLocalHook('afterAdd', function (column) {
      return _this.updateStatesAtColumn(column);
    });
    this.conditionCollection.addLocalHook('afterClear', function (column) {
      return _this.updateStatesAtColumn(column);
    });
    this.conditionCollection.addLocalHook('beforeClean', function () {
      return _this._onConditionBeforeClean();
    });
    this.conditionCollection.addLocalHook('afterClean', function () {
      return _this._onConditionAfterClean();
    });
  }
  /**
   * Enable grouping changes. Grouping is helpful in situations when a lot of conditions is added in one moment. Instead of
   * trigger `update` hook for every condition by adding/removing you can group this changes and call `flush` method to trigger
   * it once.
   */


  (0, _createClass2.default)(ConditionUpdateObserver, [{
    key: "groupChanges",
    value: function groupChanges() {
      this.grouping = true;
    }
    /**
     * Flush all collected changes. This trigger `update` hook for every previously collected change from condition collection.
     */

  }, {
    key: "flush",
    value: function flush() {
      var _this2 = this;

      this.grouping = false;
      (0, _array.arrayEach)(this.changes, function (column) {
        _this2.updateStatesAtColumn(column);
      });
      this.changes.length = 0;
    }
    /**
     * On before modify condition (add or remove from collection),
     *
     * @param {Number} column Column index.
     * @private
     */

  }, {
    key: "_onConditionBeforeModify",
    value: function _onConditionBeforeModify(column) {
      this.latestEditedColumnPosition = this.conditionCollection.orderStack.indexOf(column);
    }
    /**
     * Update all related states which should be changed after invoking changes applied to current column.
     *
     * @param column
     * @param {Object} conditionArgsChange Object describing condition changes which can be handled by filters on `update` hook.
     * It contains keys `conditionKey` and `conditionValue` which refers to change specified key of condition to specified value
     * based on referred keys.
     */

  }, {
    key: "updateStatesAtColumn",
    value: function updateStatesAtColumn(column, conditionArgsChange) {
      var _this3 = this;

      if (this.grouping) {
        if (this.changes.indexOf(column) === -1) {
          this.changes.push(column);
        }

        return;
      }

      var allConditions = this.conditionCollection.exportAllConditions();
      var editedColumnPosition = this.conditionCollection.orderStack.indexOf(column);

      if (editedColumnPosition === -1) {
        editedColumnPosition = this.latestEditedColumnPosition;
      } // Collection of all conditions defined before currently edited `column` (without edited one)


      var conditionsBefore = allConditions.slice(0, editedColumnPosition); // Collection of all conditions defined after currently edited `column` (without edited one)

      var conditionsAfter = allConditions.slice(editedColumnPosition); // Make sure that conditionAfter doesn't contain edited column conditions

      if (conditionsAfter.length && conditionsAfter[0].column === column) {
        conditionsAfter.shift();
      }

      var visibleDataFactory = (0, _function.curry)(function (curriedConditionsBefore, curriedColumn) {
        var conditionsStack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
        var splitConditionCollection = new _conditionCollection.default();
        var curriedConditionsBeforeArray = [].concat(curriedConditionsBefore, conditionsStack); // Create new condition collection to determine what rows should be visible in "filter by value" box in the next conditions in the chain

        splitConditionCollection.importAllConditions(curriedConditionsBeforeArray);

        var allRows = _this3.columnDataFactory(curriedColumn);

        var visibleRows;

        if (splitConditionCollection.isEmpty()) {
          visibleRows = allRows;
        } else {
          visibleRows = new _dataFilter.default(splitConditionCollection, function (columnData) {
            return _this3.columnDataFactory(columnData);
          }).filter();
        }

        visibleRows = (0, _array.arrayMap)(visibleRows, function (rowData) {
          return rowData.meta.visualRow;
        });
        var visibleRowsAssertion = (0, _utils.createArrayAssertion)(visibleRows);
        return (0, _array.arrayFilter)(allRows, function (rowData) {
          return visibleRowsAssertion(rowData.meta.visualRow);
        });
      })(conditionsBefore);
      var editedConditions = [].concat(this.conditionCollection.getConditions(column));
      this.runLocalHooks('update', {
        editedConditionStack: {
          column: column,
          conditions: editedConditions
        },
        dependentConditionStacks: conditionsAfter,
        filteredRowsFactory: visibleDataFactory,
        conditionArgsChange: conditionArgsChange
      });
    }
    /**
     * On before conditions clean listener.
     *
     * @private
     */

  }, {
    key: "_onConditionBeforeClean",
    value: function _onConditionBeforeClean() {
      this.latestOrderStack = [].concat(this.conditionCollection.orderStack);
    }
    /**
     * On after conditions clean listener.
     *
     * @private
     */

  }, {
    key: "_onConditionAfterClean",
    value: function _onConditionAfterClean() {
      var _this4 = this;

      (0, _array.arrayEach)(this.latestOrderStack, function (column) {
        _this4.updateStatesAtColumn(column);
      });
    }
    /**
     * Destroy instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      var _this5 = this;

      this.clearLocalHooks();
      (0, _object.objectEach)(this, function (value, property) {
        _this5[property] = null;
      });
    }
  }]);
  return ConditionUpdateObserver;
}();

(0, _object.mixin)(ConditionUpdateObserver, _localHooks.default);
var _default = ConditionUpdateObserver;
exports.default = _default;

/***/ }),
/* 736 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 737 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _eventManager = _interopRequireDefault(__webpack_require__(23));

var _plugins = __webpack_require__(20);

var _utils = __webpack_require__(84);

var _sheet = _interopRequireDefault(__webpack_require__(738));

var _dataProvider = _interopRequireDefault(__webpack_require__(747));

var _undoRedoSnapshot = _interopRequireDefault(__webpack_require__(748));

/**
 * The formulas plugin.
 *
 * @plugin Formulas
 * @experimental
 */
var Formulas =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(Formulas, _BasePlugin);

  function Formulas(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, Formulas);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Formulas).call(this, hotInstance));
    /**
     * Instance of {@link EventManager}.
     *
     * @private
     * @type {EventManager}
     */

    _this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
    /**
     * Instance of {@link DataProvider}.
     *
     * @private
     * @type {DataProvider}
     */

    _this.dataProvider = new _dataProvider.default(_this.hot);
    /**
     * Instance of {@link Sheet}.
     *
     * @private
     * @type {Sheet}
     */

    _this.sheet = new _sheet.default(_this.hot, _this.dataProvider);
    /**
     * Instance of {@link UndoRedoSnapshot}.
     *
     * @private
     * @type {UndoRedoSnapshot}
     */

    _this.undoRedoSnapshot = new _undoRedoSnapshot.default(_this.sheet);
    /**
     * Flag which indicates if table should be re-render after sheet recalculations.
     *
     * @type {Boolean}
     * @default false
     * @private
     */

    _this._skipRendering = false;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link Formulas#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(Formulas, [{
    key: "isEnabled",
    value: function isEnabled() {
      /* eslint-disable no-unneeded-ternary */
      return this.hot.getSettings().formulas ? true : false;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var settings = this.hot.getSettings().formulas;

      if ((0, _object.isObject)(settings)) {
        if ((0, _object.isObject)(settings.variables)) {
          (0, _object.objectEach)(settings.variables, function (value, name) {
            return _this2.setVariable(name, value);
          });
        }
      }

      this.addHook('afterColumnSort', function () {
        return _this2.onAfterColumnSort.apply(_this2, arguments);
      });
      this.addHook('afterCreateCol', function () {
        return _this2.onAfterCreateCol.apply(_this2, arguments);
      });
      this.addHook('afterCreateRow', function () {
        return _this2.onAfterCreateRow.apply(_this2, arguments);
      });
      this.addHook('afterLoadData', function () {
        return _this2.onAfterLoadData();
      });
      this.addHook('afterRemoveCol', function () {
        return _this2.onAfterRemoveCol.apply(_this2, arguments);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow.apply(_this2, arguments);
      });
      this.addHook('afterSetDataAtCell', function () {
        return _this2.onAfterSetDataAtCell.apply(_this2, arguments);
      });
      this.addHook('afterSetDataAtRowProp', function () {
        return _this2.onAfterSetDataAtCell.apply(_this2, arguments);
      });
      this.addHook('beforeColumnSort', function () {
        return _this2.onBeforeColumnSort.apply(_this2, arguments);
      });
      this.addHook('beforeCreateCol', function () {
        return _this2.onBeforeCreateCol.apply(_this2, arguments);
      });
      this.addHook('beforeCreateRow', function () {
        return _this2.onBeforeCreateRow.apply(_this2, arguments);
      });
      this.addHook('beforeRemoveCol', function () {
        return _this2.onBeforeRemoveCol.apply(_this2, arguments);
      });
      this.addHook('beforeRemoveRow', function () {
        return _this2.onBeforeRemoveRow.apply(_this2, arguments);
      });
      this.addHook('beforeValidate', function () {
        return _this2.onBeforeValidate.apply(_this2, arguments);
      });
      this.addHook('beforeValueRender', function () {
        return _this2.onBeforeValueRender.apply(_this2, arguments);
      });
      this.addHook('modifyData', function () {
        return _this2.onModifyData.apply(_this2, arguments);
      });
      this.sheet.addLocalHook('afterRecalculate', function () {
        return _this2.onSheetAfterRecalculate.apply(_this2, arguments);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Returns cell value (evaluated from formula expression) at specified cell coords.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {*}
     */

  }, {
    key: "getCellValue",
    value: function getCellValue(row, column) {
      var cell = this.sheet.getCellAt(row, column);
      return cell ? cell.getError() || cell.getValue() : void 0;
    }
    /**
     * Checks if there are any formula evaluations made under specific cell coords.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {Boolean}
     */

  }, {
    key: "hasComputedCellValue",
    value: function hasComputedCellValue(row, column) {
      return this.sheet.getCellAt(row, column) !== null;
    }
    /**
     * Recalculates all formulas (an algorithm will choose the best method of calculation).
     */

  }, {
    key: "recalculate",
    value: function recalculate() {
      this.sheet.recalculate();
    }
    /**
     * Recalculates all formulas (rebuild dependencies from scratch - slow approach).
     */

  }, {
    key: "recalculateFull",
    value: function recalculateFull() {
      this.sheet.recalculateFull();
    }
    /**
     * Recalculates all formulas (recalculate only changed cells - fast approach).
     */

  }, {
    key: "recalculateOptimized",
    value: function recalculateOptimized() {
      this.sheet.recalculateOptimized();
    }
    /**
     * Sets predefined variable name which can be visible while parsing formula expression.
     *
     * @param {String} name Variable name.
     * @param {*} value Variable value.
     */

  }, {
    key: "setVariable",
    value: function setVariable(name, value) {
      this.sheet.setVariable(name, value);
    }
    /**
     * Returns variable name.
     *
     * @param {String} name Variable name.
     * @returns {*}
     */

  }, {
    key: "getVariable",
    value: function getVariable(name) {
      return this.sheet.getVariable(name);
    }
    /**
     * Local hook listener for after sheet recalculation.
     *
     * @private
     * @param {Array} cells An array of recalculated/changed cells.
     */

  }, {
    key: "onSheetAfterRecalculate",
    value: function onSheetAfterRecalculate(cells) {
      if (this._skipRendering) {
        this._skipRendering = false;
        return;
      }

      var hot = this.hot;
      (0, _array.arrayEach)(cells, function (_ref) {
        var row = _ref.row,
            column = _ref.column;
        hot.validateCell(hot.getDataAtCell(row, column), hot.getCellMeta(row, column), function () {});
      });
      hot.render();
    }
    /**
     * On modify row data listener. It overwrites raw values into calculated ones and force upper case all formula expressions.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @param {Object} valueHolder Value holder as an object to change value by reference.
     * @param {String} ioMode IO operation (`get` or `set`).
     * @returns {Array|undefined} Returns modified row data.
     */

  }, {
    key: "onModifyData",
    value: function onModifyData(row, column, valueHolder, ioMode) {
      if (ioMode === 'get' && this.hasComputedCellValue(row, column)) {
        valueHolder.value = this.getCellValue(row, column);
      } else if (ioMode === 'set' && (0, _utils.isFormulaExpression)(valueHolder.value)) {
        valueHolder.value = (0, _utils.toUpperCaseFormula)(valueHolder.value);
      }
    }
    /**
     * On before value render listener.
     *
     * @private
     * @param {*} value Value to render.
     * @returns {*}
     */

  }, {
    key: "onBeforeValueRender",
    value: function onBeforeValueRender(value) {
      var renderValue = value;

      if ((0, _utils.isFormulaExpressionEscaped)(renderValue)) {
        renderValue = (0, _utils.unescapeFormulaExpression)(renderValue);
      }

      return renderValue;
    }
    /**
     * On before validate listener.
     *
     * @private
     * @param {*} value Value to validate.
     * @param {Number} row Row index.
     * @param {Number} prop Column property.
     */

  }, {
    key: "onBeforeValidate",
    value: function onBeforeValidate(value, row, prop) {
      var column = this.hot.propToCol(prop);
      var validateValue = value;

      if (this.hasComputedCellValue(row, column)) {
        validateValue = this.getCellValue(row, column);
      }

      return validateValue;
    }
    /**
     * `afterSetDataAtCell` listener.
     *
     * @private
     * @param {Array} changes Array of changes.
     * @param {String} [source] Source of changes.
     */

  }, {
    key: "onAfterSetDataAtCell",
    value: function onAfterSetDataAtCell(changes, source) {
      var _this3 = this;

      if (source === 'loadData') {
        return;
      }

      this.dataProvider.clearChanges();
      (0, _array.arrayEach)(changes, function (_ref2) {
        var _ref3 = (0, _slicedToArray2.default)(_ref2, 4),
            row = _ref3[0],
            column = _ref3[1],
            oldValue = _ref3[2],
            newValue = _ref3[3];

        var physicalColumn = _this3.hot.propToCol(column);

        var physicalRow = _this3.t.toPhysicalRow(row);

        var value = newValue;

        if ((0, _utils.isFormulaExpression)(value)) {
          value = (0, _utils.toUpperCaseFormula)(value);
        }

        _this3.dataProvider.collectChanges(physicalRow, physicalColumn, value);

        if (oldValue !== value) {
          _this3.sheet.applyChanges(physicalRow, physicalColumn, value);
        }
      });
      this.recalculate();
    }
    /**
     * On before create row listener.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} amount An amount of removed rows.
     * @param {String} source Source of method call.
     */

  }, {
    key: "onBeforeCreateRow",
    value: function onBeforeCreateRow(row, amount, source) {
      if (source === 'UndoRedo.undo') {
        this.undoRedoSnapshot.restore();
      }
    }
    /**
     * On after create row listener.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} amount An amount of created rows.
     * @param {String} source Source of method call.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(row, amount, source) {
      this.sheet.alterManager.triggerAlter('insert_row', row, amount, source !== 'UndoRedo.undo');
    }
    /**
     * On before remove row listener.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} amount An amount of removed rows.
     */

  }, {
    key: "onBeforeRemoveRow",
    value: function onBeforeRemoveRow(row, amount) {
      this.undoRedoSnapshot.save('row', row, amount);
    }
    /**
     * On after remove row listener.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} amount An amount of removed rows.
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow(row, amount) {
      this.sheet.alterManager.triggerAlter('remove_row', row, amount);
    }
    /**
     * On before create column listener.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} amount An amount of removed columns.
     * @param {String} source Source of method call.
     */

  }, {
    key: "onBeforeCreateCol",
    value: function onBeforeCreateCol(column, amount, source) {
      if (source === 'UndoRedo.undo') {
        this.undoRedoSnapshot.restore();
      }
    }
    /**
     * On after create column listener.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} amount An amount of created columns.
     * @param {String} source Source of method call.
     */

  }, {
    key: "onAfterCreateCol",
    value: function onAfterCreateCol(column, amount, source) {
      this.sheet.alterManager.triggerAlter('insert_column', column, amount, source !== 'UndoRedo.undo');
    }
    /**
     * On before remove column listener.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} amount An amount of removed columns.
     */

  }, {
    key: "onBeforeRemoveCol",
    value: function onBeforeRemoveCol(column, amount) {
      this.undoRedoSnapshot.save('column', column, amount);
    }
    /**
     * On after remove column listener.
     *
     * @private
     * @param {Number} column Column index.
     * @param {Number} amount An amount of created columns.
     */

  }, {
    key: "onAfterRemoveCol",
    value: function onAfterRemoveCol(column, amount) {
      this.sheet.alterManager.triggerAlter('remove_column', column, amount);
    }
    /**
     * On before column sorting listener.
     *
     * @private
     * @param {Number} column Sorted column index.
     * @param {Boolean} order Order type.
     */

  }, {
    key: "onBeforeColumnSort",
    value: function onBeforeColumnSort(column, order) {
      this.sheet.alterManager.prepareAlter('column_sorting', column, order);
    }
    /**
     * On after column sorting listener.
     *
     * @private
     * @param {Number} column Sorted column index.
     * @param {Boolean} order Order type.
     */

  }, {
    key: "onAfterColumnSort",
    value: function onAfterColumnSort(column, order) {
      this.sheet.alterManager.triggerAlter('column_sorting', column, order);
    }
    /**
     * On after load data listener.
     *
     * @private
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData() {
      this._skipRendering = true;
      this.recalculateFull();
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.dataProvider.destroy();
      this.dataProvider = null;
      this.sheet.destroy();
      this.sheet = null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "destroy", this).call(this);
    }
  }]);
  return Formulas;
}(_base.default);

(0, _plugins.registerPlugin)('formulas', Formulas);
var _default = Formulas;
exports.default = _default;

/***/ }),
/* 738 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _hotFormulaParser = __webpack_require__(111);

var _array = __webpack_require__(3);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var _recordTranslator = __webpack_require__(90);

var _object = __webpack_require__(4);

var _value = _interopRequireDefault(__webpack_require__(85));

var _reference = _interopRequireDefault(__webpack_require__(739));

var _utils = __webpack_require__(84);

var _matrix = _interopRequireDefault(__webpack_require__(740));

var _alterManager = _interopRequireDefault(__webpack_require__(741));

var STATE_UP_TO_DATE = 1;
var STATE_NEED_REBUILD = 2;
var STATE_NEED_FULL_REBUILD = 3;
/**
 * Sheet component responsible for whole spreadsheet calculations.
 *
 * @class Sheet
 * @util
 */

var Sheet =
/*#__PURE__*/
function () {
  function Sheet(hot, dataProvider) {
    var _this = this;

    (0, _classCallCheck2.default)(this, Sheet);

    /**
     * Handsontable instance.
     *
     * @type {Core}
     */
    this.hot = hot;
    /**
     * Record translator for translating visual records into psychical and vice versa.
     *
     * @type {RecordTranslator}
     */

    this.t = (0, _recordTranslator.getTranslator)(this.hot);
    /**
     * Data provider for sheet calculations.
     *
     * @type {DataProvider}
     */

    this.dataProvider = dataProvider;
    /**
     * Instance of {@link https://github.com/handsontable/formula-parser}.
     *
     * @type {Parser}
     */

    this.parser = new _hotFormulaParser.Parser();
    /**
     * Instance of {@link Matrix}.
     *
     * @type {Matrix}
     */

    this.matrix = new _matrix.default(this.t);
    /**
     * Instance of {@link AlterManager}.
     *
     * @type {AlterManager}
     */

    this.alterManager = new _alterManager.default(this);
    /**
     * Cell object which indicates which cell is currently processing.
     *
     * @private
     * @type {null}
     */

    this._processingCell = null;
    /**
     * State of the sheet.
     *
     * @type {Number}
     * @private
     */

    this._state = STATE_NEED_FULL_REBUILD;
    this.parser.on('callCellValue', function () {
      return _this._onCallCellValue.apply(_this, arguments);
    });
    this.parser.on('callRangeValue', function () {
      return _this._onCallRangeValue.apply(_this, arguments);
    });
    this.alterManager.addLocalHook('afterAlter', function () {
      return _this._onAfterAlter.apply(_this, arguments);
    });
  }
  /**
   * Recalculate sheet.
   */


  (0, _createClass2.default)(Sheet, [{
    key: "recalculate",
    value: function recalculate() {
      switch (this._state) {
        case STATE_NEED_FULL_REBUILD:
          this.recalculateFull();
          break;

        case STATE_NEED_REBUILD:
          this.recalculateOptimized();
          break;

        default:
          break;
      }
    }
    /**
     * Recalculate sheet using optimized methods (fast recalculation).
     */

  }, {
    key: "recalculateOptimized",
    value: function recalculateOptimized() {
      var _this2 = this;

      var cells = this.matrix.getOutOfDateCells();
      (0, _array.arrayEach)(cells, function (cellValue) {
        var value = _this2.dataProvider.getSourceDataAtCell(cellValue.row, cellValue.column);

        if ((0, _utils.isFormulaExpression)(value)) {
          _this2.parseExpression(cellValue, value.substr(1));
        }
      });
      this._state = STATE_UP_TO_DATE;
      this.runLocalHooks('afterRecalculate', cells, 'optimized');
    }
    /**
     * Recalculate whole table by building dependencies from scratch (slow recalculation).
     */

  }, {
    key: "recalculateFull",
    value: function recalculateFull() {
      var _this3 = this;

      var cells = this.dataProvider.getSourceDataByRange();
      this.matrix.reset();
      (0, _array.arrayEach)(cells, function (rowData, row) {
        (0, _array.arrayEach)(rowData, function (value, column) {
          if ((0, _utils.isFormulaExpression)(value)) {
            _this3.parseExpression(new _value.default(row, column), value.substr(1));
          }
        });
      });
      this._state = STATE_UP_TO_DATE;
      this.runLocalHooks('afterRecalculate', cells, 'full');
    }
    /**
     * Set predefined variable name which can be visible while parsing formula expression.
     *
     * @param {String} name Variable name.
     * @param {*} value Variable value.
     */

  }, {
    key: "setVariable",
    value: function setVariable(name, value) {
      this.parser.setVariable(name, value);
    }
    /**
     * Get variable name.
     *
     * @param {String} name Variable name.
     * @returns {*}
     */

  }, {
    key: "getVariable",
    value: function getVariable(name) {
      return this.parser.getVariable(name);
    }
    /**
     * Apply changes to the sheet.
     *
     * @param {Number} row Physical row index.
     * @param {Number} column Physical column index.
     * @param {*} newValue Current cell value.
     */

  }, {
    key: "applyChanges",
    value: function applyChanges(row, column, newValue) {
      // Remove formula description for old expression
      // TODO: Move this to recalculate()
      this.matrix.remove({
        row: row,
        column: column
      }); // TODO: Move this to recalculate()

      if ((0, _utils.isFormulaExpression)(newValue)) {
        // ...and create new for new changed formula expression
        this.parseExpression(new _value.default(row, column), newValue.substr(1));
      }

      var deps = this.getCellDependencies.apply(this, (0, _toConsumableArray2.default)(this.t.toVisual(row, column)));
      (0, _array.arrayEach)(deps, function (cellValue) {
        cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
      });
      this._state = STATE_NEED_REBUILD;
    }
    /**
     * Parse and evaluate formula for provided cell.
     *
     * @param {CellValue|Object} cellValue Cell value object.
     * @param {String} formula Value to evaluate.
     */

  }, {
    key: "parseExpression",
    value: function parseExpression(cellValue, formula) {
      cellValue.setState(_value.default.STATE_COMPUTING);
      this._processingCell = cellValue;

      var _this$parser$parse = this.parser.parse((0, _utils.toUpperCaseFormula)(formula)),
          error = _this$parser$parse.error,
          result = _this$parser$parse.result;

      if ((0, _utils.isFormulaExpression)(result)) {
        this.parseExpression(cellValue, result.substr(1));
      } else {
        cellValue.setValue(result);
        cellValue.setError(error);
        cellValue.setState(_value.default.STATE_UP_TO_DATE);
      }

      this.matrix.add(cellValue);
      this._processingCell = null;
    }
    /**
     * Get cell value object at specified physical coordinates.
     *
     * @param {Number} row Physical row index.
     * @param {Number} column Physical column index.
     * @returns {CellValue|undefined}
     */

  }, {
    key: "getCellAt",
    value: function getCellAt(row, column) {
      return this.matrix.getCellAt(row, column);
    }
    /**
     * Get cell dependencies at specified physical coordinates.
     *
     * @param {Number} row Physical row index.
     * @param {Number} column Physical column index.
     * @returns {Array}
     */

  }, {
    key: "getCellDependencies",
    value: function getCellDependencies(row, column) {
      return this.matrix.getDependencies({
        row: row,
        column: column
      });
    }
    /**
     * Listener for parser cell value.
     *
     * @private
     * @param {Object} cellCoords Cell coordinates.
     * @param {Function} done Function to call with valid cell value.
     */

  }, {
    key: "_onCallCellValue",
    value: function _onCallCellValue(_ref, done) {
      var row = _ref.row,
          column = _ref.column;
      var cell = new _reference.default(row, column);

      if (!this.dataProvider.isInDataRange(cell.row, cell.column)) {
        throw Error(_hotFormulaParser.ERROR_REF);
      }

      this.matrix.registerCellRef(cell);

      this._processingCell.addPrecedent(cell);

      var cellValue = this.dataProvider.getRawDataAtCell(row.index, column.index);

      if ((0, _hotFormulaParser.error)(cellValue)) {
        var computedCell = this.matrix.getCellAt(row.index, column.index);

        if (computedCell && computedCell.hasError()) {
          throw Error(cellValue);
        }
      }

      if ((0, _utils.isFormulaExpression)(cellValue)) {
        var _this$parser$parse2 = this.parser.parse(cellValue.substr(1)),
            error = _this$parser$parse2.error,
            result = _this$parser$parse2.result;

        if (error) {
          throw Error(error);
        }

        done(result);
      } else {
        done(cellValue);
      }
    }
    /**
     * Listener for parser cells (range) value.
     *
     * @private
     * @param {Object} startCell Cell coordinates (top-left corner coordinate).
     * @param {Object} endCell Cell coordinates (bottom-right corner coordinate).
     * @param {Function} done Function to call with valid cells values.
     */

  }, {
    key: "_onCallRangeValue",
    value: function _onCallRangeValue(_ref2, _ref3, done) {
      var _this4 = this;

      var startRow = _ref2.row,
          startColumn = _ref2.column;
      var endRow = _ref3.row,
          endColumn = _ref3.column;
      var cellValues = this.dataProvider.getRawDataByRange(startRow.index, startColumn.index, endRow.index, endColumn.index);

      var mapRowData = function mapRowData(rowData, rowIndex) {
        return (0, _array.arrayMap)(rowData, function (cellData, columnIndex) {
          var rowCellCoord = startRow.index + rowIndex;
          var columnCellCoord = startColumn.index + columnIndex;
          var cell = new _reference.default(rowCellCoord, columnCellCoord);

          if (!_this4.dataProvider.isInDataRange(cell.row, cell.column)) {
            throw Error(_hotFormulaParser.ERROR_REF);
          }

          _this4.matrix.registerCellRef(cell);

          _this4._processingCell.addPrecedent(cell);

          var newCellData = cellData;

          if ((0, _hotFormulaParser.error)(newCellData)) {
            var computedCell = _this4.matrix.getCellAt(cell.row, cell.column);

            if (computedCell && computedCell.hasError()) {
              throw Error(newCellData);
            }
          }

          if ((0, _utils.isFormulaExpression)(newCellData)) {
            var _this4$parser$parse = _this4.parser.parse(newCellData.substr(1)),
                error = _this4$parser$parse.error,
                result = _this4$parser$parse.result;

            if (error) {
              throw Error(error);
            }

            newCellData = result;
          }

          return newCellData;
        });
      };

      var calculatedCellValues = (0, _array.arrayMap)(cellValues, function (rowData, rowIndex) {
        return mapRowData(rowData, rowIndex);
      });
      done(calculatedCellValues);
    }
    /**
     * On after alter sheet listener.
     *
     * @private
     */

  }, {
    key: "_onAfterAlter",
    value: function _onAfterAlter() {
      this.recalculateOptimized();
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.hot = null;
      this.t = null;
      this.dataProvider.destroy();
      this.dataProvider = null;
      this.alterManager.destroy();
      this.alterManager = null;
      this.parser = null;
      this.matrix.reset();
      this.matrix = null;
    }
  }]);
  return Sheet;
}();

(0, _object.mixin)(Sheet, _localHooks.default);
var _default = Sheet;
exports.default = _default;

/***/ }),
/* 739 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _hotFormulaParser = __webpack_require__(111);

var _base = _interopRequireDefault(__webpack_require__(503));

/**
 * Class which indicates formula expression precedents cells at specified cell
 * coordinates (CellValue). This object uses visual cell coordinates.
 *
 * @class CellReference
 * @util
 */
var CellReference =
/*#__PURE__*/
function (_BaseCell) {
  (0, _inherits2.default)(CellReference, _BaseCell);

  function CellReference() {
    (0, _classCallCheck2.default)(this, CellReference);
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CellReference).apply(this, arguments));
  }

  (0, _createClass2.default)(CellReference, [{
    key: "toString",

    /**
     * Stringify object.
     *
     * @returns {String}
     */
    value: function toString() {
      return (0, _hotFormulaParser.toLabel)({
        index: this.row,
        isAbsolute: false
      }, {
        index: this.column,
        isAbsolute: false
      });
    }
  }]);
  return CellReference;
}(_base.default);

var _default = CellReference;
exports.default = _default;

/***/ }),
/* 740 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _value = _interopRequireDefault(__webpack_require__(85));

/**
 * This component is responsible for storing all calculated cells which contain formula expressions (CellValue) and
 * register for all cell references (CellReference).
 *
 * CellValue is an object which represents a formula expression. It contains a calculated value of that formula,
 * an error if applied and cell references. Cell references are CellReference object instances which represent a cell
 * in a spreadsheet. One CellReference can be assigned to multiple CellValues as a precedent cell. Each cell
 * modification triggers a search through CellValues that are dependent of the CellReference. After
 * the match, the cells are marked as 'out of date'. In the next render cycle, all CellValues marked with
 * that state are recalculated.
 *
 * @class Matrix
 * @util
 */
var Matrix =
/*#__PURE__*/
function () {
  function Matrix(recordTranslator) {
    (0, _classCallCheck2.default)(this, Matrix);

    /**
     * Record translator for translating visual records into psychical and vice versa.
     *
     * @type {RecordTranslator}
     */
    this.t = recordTranslator;
    /**
     * List of all cell values with theirs precedents.
     *
     * @type {Array}
     */

    this.data = [];
    /**
     * List of all created and registered cell references.
     *
     * @type {Array}
     */

    this.cellReferences = [];
  }
  /**
   * Get cell value at given row and column index.
   *
   * @param {Number} row Physical row index.
   * @param {Number} column Physical column index.
   * @returns {CellValue|null} Returns CellValue instance or `null` if cell not found.
   */


  (0, _createClass2.default)(Matrix, [{
    key: "getCellAt",
    value: function getCellAt(row, column) {
      var result = null;
      (0, _array.arrayEach)(this.data, function (cell) {
        if (cell.row === row && cell.column === column) {
          result = cell;
          return false;
        }
      });
      return result;
    }
    /**
     * Get all out of date cells.
     *
     * @returns {Array}
     */

  }, {
    key: "getOutOfDateCells",
    value: function getOutOfDateCells() {
      return (0, _array.arrayFilter)(this.data, function (cell) {
        return cell.isState(_value.default.STATE_OUT_OFF_DATE);
      });
    }
    /**
     * Add cell value to the collection.
     *
     * @param {CellValue|Object} cellValue Cell value object.
     */

  }, {
    key: "add",
    value: function add(cellValue) {
      if (!(0, _array.arrayFilter)(this.data, function (cell) {
        return cell.isEqual(cellValue);
      }).length) {
        this.data.push(cellValue);
      }
    }
    /**
     * Remove cell value from the collection.
     *
     * @param {CellValue|Object|Array} cellValue Cell value object.
     */

  }, {
    key: "remove",
    value: function remove(cellValue) {
      var isArray = Array.isArray(cellValue);

      var isEqual = function isEqual(cell, values) {
        var result = false;

        if (isArray) {
          (0, _array.arrayEach)(values, function (value) {
            if (cell.isEqual(value)) {
              result = true;
              return false;
            }
          });
        } else {
          result = cell.isEqual(values);
        }

        return result;
      };

      this.data = (0, _array.arrayFilter)(this.data, function (cell) {
        return !isEqual(cell, cellValue);
      });
    }
    /**
     * Get cell dependencies using visual coordinates.
     *
     * @param {Object} cellCoord Visual cell coordinates object.
     */

  }, {
    key: "getDependencies",
    value: function getDependencies(cellCoord) {
      var _this = this;

      /* eslint-disable arrow-body-style */
      var getDependencies = function getDependencies(cell) {
        return (0, _array.arrayReduce)(_this.data, function (acc, cellValue) {
          if (cellValue.hasPrecedent(cell) && acc.indexOf(cellValue) === -1) {
            acc.push(cellValue);
          }

          return acc;
        }, []);
      };

      var getTotalDependencies = function getTotalDependencies(cell) {
        var deps = getDependencies(cell);

        if (deps.length) {
          (0, _array.arrayEach)(deps, function (cellValue) {
            if (cellValue.hasPrecedents()) {
              deps = deps.concat(getTotalDependencies(_this.t.toVisual(cellValue)));
            }
          });
        }

        return deps;
      };

      return getTotalDependencies(cellCoord);
    }
    /**
     * Register cell reference to the collection.
     *
     * @param {CellReference|Object} cellReference Cell reference object.
     */

  }, {
    key: "registerCellRef",
    value: function registerCellRef(cellReference) {
      if (!(0, _array.arrayFilter)(this.cellReferences, function (cell) {
        return cell.isEqual(cellReference);
      }).length) {
        this.cellReferences.push(cellReference);
      }
    }
    /**
     * Remove cell references from the collection.
     *
     * @param {Object} start Start visual coordinate.
     * @param {Object} end End visual coordinate.
     * @returns {Array} Returns removed cell references.
     */

  }, {
    key: "removeCellRefsAtRange",
    value: function removeCellRefsAtRange(_ref, _ref2) {
      var startRow = _ref.row,
          startColumn = _ref.column;
      var endRow = _ref2.row,
          endColumn = _ref2.column;
      var removed = [];

      var rowMatch = function rowMatch(cell) {
        return startRow === void 0 ? true : cell.row >= startRow && cell.row <= endRow;
      };

      var colMatch = function colMatch(cell) {
        return startColumn === void 0 ? true : cell.column >= startColumn && cell.column <= endColumn;
      };

      this.cellReferences = (0, _array.arrayFilter)(this.cellReferences, function (cell) {
        if (rowMatch(cell) && colMatch(cell)) {
          removed.push(cell);
          return false;
        }

        return true;
      });
      return removed;
    }
    /**
     * Reset matrix data.
     */

  }, {
    key: "reset",
    value: function reset() {
      this.data.length = 0;
      this.cellReferences.length = 0;
    }
  }]);
  return Matrix;
}();

var _default = Matrix;
exports.default = _default;

/***/ }),
/* 741 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(16);

__webpack_require__(70);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.registerOperation = registerOperation;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _localHooks = _interopRequireDefault(__webpack_require__(57));

var columnSorting = _interopRequireWildcard(__webpack_require__(742));

var insertColumn = _interopRequireWildcard(__webpack_require__(743));

var insertRow = _interopRequireWildcard(__webpack_require__(744));

var removeColumn = _interopRequireWildcard(__webpack_require__(745));

var removeRow = _interopRequireWildcard(__webpack_require__(746));

var operations = new Map();
registerOperation(columnSorting.OPERATION_NAME, columnSorting);
registerOperation(insertColumn.OPERATION_NAME, insertColumn);
registerOperation(insertRow.OPERATION_NAME, insertRow);
registerOperation(removeColumn.OPERATION_NAME, removeColumn);
registerOperation(removeRow.OPERATION_NAME, removeRow);
/**
 * Alter Manager is a service that is responsible for changing the formula expressions (especially cell coordinates)
 * based on specific alter operation applied into the table.
 *
 * For example, when a user adds a new row the algorithm that moves all the cells below the added row down by one row
 * should be triggered (eq: cell A5 become A6 etc).
 *
 * All alter operations are defined in the "alterOperation/" directory.
 *
 * @class AlterManager
 * @util
 */

var AlterManager =
/*#__PURE__*/
function () {
  function AlterManager(sheet) {
    (0, _classCallCheck2.default)(this, AlterManager);

    /**
     * Instance of {@link Sheet}.
     *
     * @type {Sheet}
     */
    this.sheet = sheet;
    /**
     * Handsontable instance.
     *
     * @type {Core}
     */

    this.hot = sheet.hot;
    /**
     * Instance of {@link DataProvider}.
     *
     * @type {DataProvider}
     */

    this.dataProvider = sheet.dataProvider;
    /**
     * Instance of {@link Matrix}.
     *
     * @type {Matrix}
     */

    this.matrix = sheet.matrix;
  }
  /**
   * Prepare to execute an alter algorithm. This preparation can be useful for collecting some variables and
   * states before specific algorithm will be executed.
   *
   * @param  {String} action One of the action defined in alterOperation.
   * @param  {*} args Arguments pass to alter operation.
   */


  (0, _createClass2.default)(AlterManager, [{
    key: "prepareAlter",
    value: function prepareAlter(action) {
      if (!operations.has(action)) {
        throw Error("Alter operation \"".concat(action, "\" not exist."));
      }

      for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      operations.get(action).prepare.apply(this, args);
    }
    /**
     * Trigger an alter algorithm and after executing code trigger local hook ("afterAlter").
     *
     * @param {String} action One of the action defined in alterOperation.
     * @param {*} args Arguments pass to alter operation.
     */

  }, {
    key: "triggerAlter",
    value: function triggerAlter(action) {
      if (!operations.has(action)) {
        throw Error("Alter operation \"".concat(action, "\" not exist."));
      }

      for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        args[_key2 - 1] = arguments[_key2];
      }

      operations.get(action).operate.apply(this, args);
      this.runLocalHooks.apply(this, ['afterAlter'].concat(args));
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.sheet = null;
      this.hot = null;
      this.dataProvider = null;
      this.matrix = null;
    }
  }]);
  return AlterManager;
}();

(0, _object.mixin)(AlterManager, _localHooks.default);
var _default = AlterManager;
exports.default = _default;

var empty = function empty() {};

function registerOperation(name, descriptor) {
  if (!operations.has(name)) {
    operations.set(name, {
      prepare: descriptor.prepare || empty,
      operate: descriptor.operate || empty
    });
  }
}

/***/ }),
/* 742 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.prepare = prepare;
exports.operate = operate;
exports.OPERATION_NAME = void 0;

var _array = __webpack_require__(3);

var _utils = __webpack_require__(84);

var _value = _interopRequireDefault(__webpack_require__(85));

var _expressionModifier = _interopRequireDefault(__webpack_require__(112));

/**
 * When "column_sorting" is triggered the following operations must be performed:
 *
 * - All formulas which contain cell coordinates must be updated and saved into source data - Column must be changed
 *   (decreased or increased) depends on new target position - previous position.
 * - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
 */
var OPERATION_NAME = 'column_sorting';
exports.OPERATION_NAME = OPERATION_NAME;
var visualRows;
/**
 * Collect all previous visual rows from CellValues.
 */

function prepare() {
  var matrix = this.matrix,
      dataProvider = this.dataProvider;
  visualRows = new WeakMap();
  (0, _array.arrayEach)(matrix.data, function (cell) {
    visualRows.set(cell, dataProvider.t.toVisualRow(cell.row));
  });
}
/**
 * Translate all CellValues depends on previous position.
 */


function operate() {
  var matrix = this.matrix,
      dataProvider = this.dataProvider;
  matrix.cellReferences.length = 0;
  (0, _array.arrayEach)(matrix.data, function (cell) {
    cell.setState(_value.default.STATE_OUT_OFF_DATE);
    cell.clearPrecedents();
    var row = cell.row,
        column = cell.column;
    var value = dataProvider.getSourceDataAtCell(row, column);

    if ((0, _utils.isFormulaExpression)(value)) {
      var prevRow = visualRows.get(cell);
      var expModifier = new _expressionModifier.default(value);
      expModifier.translate({
        row: dataProvider.t.toVisualRow(row) - prevRow
      });
      dataProvider.updateSourceData(row, column, expModifier.toString());
    }
  });
  visualRows = null;
}

/***/ }),
/* 743 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;

var _array = __webpack_require__(3);

var _utils = __webpack_require__(84);

var _value = _interopRequireDefault(__webpack_require__(85));

var _expressionModifier = _interopRequireDefault(__webpack_require__(112));

/**
 * When "inser_column" is triggered the following operations must be performed:
 *
 * - All formulas which contain cell coordinates must be updated and saved into source data - Column must be increased
 *   by "amount" of times (eq: D4 to E4, $F$5 to $G$5);
 * - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
 */
var OPERATION_NAME = 'insert_column';
/**
 * Execute changes.
 *
 * @param {Number} start Index column from which the operation starts.
 * @param {Number} amount Count of columns to be inserted.
 * @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
 *                                       `false` value is used by UndoRedo plugin which saves snapshoots before alter
 *                                       operation so it doesn't have to modify formulas if "undo" action was triggered.
 */

exports.OPERATION_NAME = OPERATION_NAME;

function operate(start, amount) {
  var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  var matrix = this.matrix,
      dataProvider = this.dataProvider;
  var translate = [0, amount];
  (0, _array.arrayEach)(matrix.cellReferences, function (cell) {
    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
    }
  });
  (0, _array.arrayEach)(matrix.data, function (cell) {
    var origRow = cell.row,
        origColumn = cell.column;

    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
    }

    if (modifyFormula) {
      var row = cell.row,
          column = cell.column;
      var value = dataProvider.getSourceDataAtCell(row, column);

      if ((0, _utils.isFormulaExpression)(value)) {
        var startCoord = (0, _utils.cellCoordFactory)('column', start);
        var expModifier = new _expressionModifier.default(value);
        expModifier.useCustomModifier(customTranslateModifier);
        expModifier.translate({
          column: amount
        }, startCoord({
          row: origRow,
          column: origColumn
        }));
        dataProvider.updateSourceData(row, column, expModifier.toString());
      }
    }
  });
}

function customTranslateModifier(cell, axis, delta, startFromIndex) {
  var start = cell.start,
      end = cell.end;
  var startIndex = start[axis].index;
  var endIndex = end[axis].index;
  var deltaStart = delta;
  var deltaEnd = delta; // Do not translate cells above inserted row or on the left of inserted column

  if (startFromIndex > startIndex) {
    deltaStart = 0;
  }

  if (startFromIndex > endIndex) {
    deltaEnd = 0;
  }

  return [deltaStart, deltaEnd, false];
}

/***/ }),
/* 744 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;

var _array = __webpack_require__(3);

var _utils = __webpack_require__(84);

var _value = _interopRequireDefault(__webpack_require__(85));

var _expressionModifier = _interopRequireDefault(__webpack_require__(112));

/**
 * When "insert_row" is triggered the following operations must be performed:
 *
 * - All formulas which contain cell coordinates must be updated and saved into source data - Row must be increased
 *   by "amount" of times (eq: D4 to D5, $F$5 to $F$6);
 * - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
 */
var OPERATION_NAME = 'insert_row';
/**
 * Execute changes.
 *
 * @param {Number} start Index row from which the operation starts.
 * @param {Number} amount Count of rows to be inserted.
 * @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
 *                                       `false` value is used by UndoRedo plugin which saves snapshoots before alter
 *                                       operation so it doesn't modify formulas if undo action is triggered.
 */

exports.OPERATION_NAME = OPERATION_NAME;

function operate(start, amount) {
  var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  var matrix = this.matrix,
      dataProvider = this.dataProvider;
  var translate = [amount, 0];
  (0, _array.arrayEach)(matrix.cellReferences, function (cell) {
    if (cell.row >= start) {
      cell.translateTo.apply(cell, translate);
    }
  });
  (0, _array.arrayEach)(matrix.data, function (cell) {
    var origRow = cell.row,
        origColumn = cell.column;

    if (cell.row >= start) {
      cell.translateTo.apply(cell, translate);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
    }

    if (modifyFormula) {
      var row = cell.row,
          column = cell.column;
      var value = dataProvider.getSourceDataAtCell(row, column);

      if ((0, _utils.isFormulaExpression)(value)) {
        var startCoord = (0, _utils.cellCoordFactory)('row', start);
        var expModifier = new _expressionModifier.default(value);
        expModifier.useCustomModifier(customTranslateModifier);
        expModifier.translate({
          row: amount
        }, startCoord({
          row: origRow,
          column: origColumn
        }));
        dataProvider.updateSourceData(row, column, expModifier.toString());
      }
    }
  });
}

function customTranslateModifier(cell, axis, delta, startFromIndex) {
  var start = cell.start,
      end = cell.end;
  var startIndex = start[axis].index;
  var endIndex = end[axis].index;
  var deltaStart = delta;
  var deltaEnd = delta; // Do not translate cells above inserted row or on the left of inserted column

  if (startFromIndex > startIndex) {
    deltaStart = 0;
  }

  if (startFromIndex > endIndex) {
    deltaEnd = 0;
  }

  return [deltaStart, deltaEnd, false];
}

/***/ }),
/* 745 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;

var _array = __webpack_require__(3);

var _utils = __webpack_require__(84);

var _value = _interopRequireDefault(__webpack_require__(85));

var _expressionModifier = _interopRequireDefault(__webpack_require__(112));

/**
 * When "remove_column" is triggered the following operations must be performed:
 *
 * - All formulas which contain cell coordinates must be updated and saved into source data - Column must be decreased
 *   by "amount" of times (eq: D4 to C4, $F$5 to $E$5);
 * - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
 */
var OPERATION_NAME = 'remove_column';
/**
 * Execute changes.
 *
 * @param {Number} start Index column from which the operation starts.
 * @param {Number} amount Count of columns to be removed.
 * @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
 *                                       `false` value is used by UndoRedo plugin which saves snapshoots before alter
 *                                       operation so it doesn't modify formulas if undo action is triggered.
 */

exports.OPERATION_NAME = OPERATION_NAME;

function operate(start, amount) {
  var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  var columnsAmount = -amount;
  var matrix = this.matrix,
      dataProvider = this.dataProvider,
      sheet = this.sheet;
  var translate = [0, columnsAmount];
  var indexOffset = Math.abs(columnsAmount) - 1;
  var removedCellRef = matrix.removeCellRefsAtRange({
    column: start
  }, {
    column: start + indexOffset
  });
  var toRemove = [];
  (0, _array.arrayEach)(matrix.data, function (cell) {
    (0, _array.arrayEach)(removedCellRef, function (cellRef) {
      if (!cell.hasPrecedent(cellRef)) {
        return;
      }

      cell.removePrecedent(cellRef);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
      (0, _array.arrayEach)(sheet.getCellDependencies(cell.row, cell.column), function (cellValue) {
        cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
      });
    });

    if (cell.column >= start && cell.column <= start + indexOffset) {
      toRemove.push(cell);
    }
  });
  matrix.remove(toRemove);
  (0, _array.arrayEach)(matrix.cellReferences, function (cell) {
    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
    }
  });
  (0, _array.arrayEach)(matrix.data, function (cell) {
    var origRow = cell.row,
        origColumn = cell.column;

    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
    }

    if (modifyFormula) {
      var row = cell.row,
          column = cell.column;
      var value = dataProvider.getSourceDataAtCell(row, column);

      if ((0, _utils.isFormulaExpression)(value)) {
        var startCoord = (0, _utils.cellCoordFactory)('column', start);
        var expModifier = new _expressionModifier.default(value);
        expModifier.useCustomModifier(customTranslateModifier);
        expModifier.translate({
          column: columnsAmount
        }, startCoord({
          row: origRow,
          column: origColumn
        }));
        dataProvider.updateSourceData(row, column, expModifier.toString());
      }
    }
  });
}

function customTranslateModifier(cell, axis, delta, startFromIndex) {
  var start = cell.start,
      end = cell.end,
      type = cell.type;
  var startIndex = start[axis].index;
  var endIndex = end[axis].index;
  var indexOffset = Math.abs(delta) - 1;
  var deltaStart = delta;
  var deltaEnd = delta;
  var refError = false; // Mark all cells as #REF! which refer to removed cells between startFromIndex and startFromIndex + delta

  if (startIndex >= startFromIndex && endIndex <= startFromIndex + indexOffset) {
    refError = true;
  } // Decrement all cells below startFromIndex


  if (!refError && type === 'cell') {
    if (startFromIndex >= startIndex) {
      deltaStart = 0;
      deltaEnd = 0;
    }
  }

  if (!refError && type === 'range') {
    if (startFromIndex >= startIndex) {
      deltaStart = 0;
    }

    if (startFromIndex > endIndex) {
      deltaEnd = 0;
    } else if (endIndex <= startFromIndex + indexOffset) {
      deltaEnd -= Math.min(endIndex - (startFromIndex + indexOffset), 0);
    }
  }

  if (startIndex + deltaStart < 0) {
    deltaStart -= startIndex + deltaStart;
  }

  return [deltaStart, deltaEnd, refError];
}

/***/ }),
/* 746 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(10);

__webpack_require__(36);

exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;

var _array = __webpack_require__(3);

var _utils = __webpack_require__(84);

var _value = _interopRequireDefault(__webpack_require__(85));

var _expressionModifier = _interopRequireDefault(__webpack_require__(112));

/**
 * When "remove_row" is triggered the following operations must be performed:
 *
 * - All formulas which contain cell coordinates must be updated and saved into source data - Row must be decreased
 *   by "amount" of times (eq: D4 to D3, $F$5 to $F$4);
 * - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
 */
var OPERATION_NAME = 'remove_row';
/**
 * Execute changes.
 *
 * @param {Number} start Index row from which the operation starts.
 * @param {Number} amount Count of rows to be removed.
 * @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
 *                                       `false` value is used by UndoRedo plugin which saves snapshoots before alter
 *                                       operation so it doesn't modify formulas if undo action is triggered.
 */

exports.OPERATION_NAME = OPERATION_NAME;

function operate(start, amount) {
  var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  var rowsAmount = -amount;
  var matrix = this.matrix,
      dataProvider = this.dataProvider,
      sheet = this.sheet;
  var translate = [rowsAmount, 0];
  var indexOffset = Math.abs(rowsAmount) - 1;
  var removedCellRef = matrix.removeCellRefsAtRange({
    row: start
  }, {
    row: start + indexOffset
  });
  var toRemove = [];
  (0, _array.arrayEach)(matrix.data, function (cell) {
    (0, _array.arrayEach)(removedCellRef, function (cellRef) {
      if (!cell.hasPrecedent(cellRef)) {
        return;
      }

      cell.removePrecedent(cellRef);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
      (0, _array.arrayEach)(sheet.getCellDependencies(cell.row, cell.column), function (cellValue) {
        cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
      });
    });

    if (cell.row >= start && cell.row <= start + indexOffset) {
      toRemove.push(cell);
    }
  });
  matrix.remove(toRemove);
  (0, _array.arrayEach)(matrix.cellReferences, function (cell) {
    if (cell.row >= start) {
      cell.translateTo.apply(cell, translate);
    }
  });
  (0, _array.arrayEach)(matrix.data, function (cell) {
    var origRow = cell.row,
        origColumn = cell.column;

    if (cell.row >= start) {
      cell.translateTo.apply(cell, translate);
      cell.setState(_value.default.STATE_OUT_OFF_DATE);
    }

    if (modifyFormula) {
      var row = cell.row,
          column = cell.column;
      var value = dataProvider.getSourceDataAtCell(row, column);

      if ((0, _utils.isFormulaExpression)(value)) {
        var startCoord = (0, _utils.cellCoordFactory)('row', start);
        var expModifier = new _expressionModifier.default(value);
        expModifier.useCustomModifier(customTranslateModifier);
        expModifier.translate({
          row: rowsAmount
        }, startCoord({
          row: origRow,
          column: origColumn
        }));
        dataProvider.updateSourceData(row, column, expModifier.toString());
      }
    }
  });
}

function customTranslateModifier(cell, axis, delta, startFromIndex) {
  var start = cell.start,
      end = cell.end,
      type = cell.type;
  var startIndex = start[axis].index;
  var endIndex = end[axis].index;
  var indexOffset = Math.abs(delta) - 1;
  var deltaStart = delta;
  var deltaEnd = delta;
  var refError = false; // Mark all cells as #REF! which refer to removed cells between startFromIndex and startFromIndex + delta

  if (startIndex >= startFromIndex && endIndex <= startFromIndex + indexOffset) {
    refError = true;
  } // Decrement all cells below startFromIndex


  if (!refError && type === 'cell') {
    if (startFromIndex >= startIndex) {
      deltaStart = 0;
      deltaEnd = 0;
    }
  }

  if (!refError && type === 'range') {
    if (startFromIndex >= startIndex) {
      deltaStart = 0;
    }

    if (startFromIndex > endIndex) {
      deltaEnd = 0;
    } else if (endIndex <= startFromIndex + indexOffset) {
      deltaEnd -= Math.min(endIndex - (startFromIndex + indexOffset), 0);
    }
  }

  if (startIndex + deltaStart < 0) {
    deltaStart -= startIndex + deltaStart;
  }

  return [deltaStart, deltaEnd, refError];
}

/***/ }),
/* 747 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _object = __webpack_require__(4);

var _recordTranslator = __webpack_require__(90);

/**
 * Data class provider responsible for providing a set of range data types, necessary for calculating formulas.
 * Those methods strongly using hot.getData and hot.getSourceData methods with some changes. Data provider additionally
 * collects all changes added to the data source to make them available faster than by using
 * hot.getData and hot.getSourceData methods.
 *
 * @class DataProvider
 * @util
 */
var DataProvider =
/*#__PURE__*/
function () {
  function DataProvider(hot) {
    (0, _classCallCheck2.default)(this, DataProvider);

    /**
     * Handsontable instance.
     *
     * @type {Core}
     */
    this.hot = hot;
    /**
     * Collected changes applied into editors or by calling public Handsontable API. This is require to provide
     * fresh data applied into spreadsheet before they will be available from the public API.
     *
     * @type {Object}
     */

    this.changes = {};
    /**
     * Record translator for translating visual records into psychical and vice versa.
     *
     * @type {RecordTranslator}
     */

    this.t = (0, _recordTranslator.getTranslator)(this.hot);
  }
  /**
   * Collect all data changes applied to the Handsontable to make them available later.
   *
   * @param {Number} row Physical row index.
   * @param {Number} column Physical column index.
   * @param {*} value Value to store.
   */


  (0, _createClass2.default)(DataProvider, [{
    key: "collectChanges",
    value: function collectChanges(row, column, value) {
      this.changes[this._coordId(row, column)] = value;
    }
    /**
     * Clear all collected changes.
     */

  }, {
    key: "clearChanges",
    value: function clearChanges() {
      this.changes = {};
    }
    /**
     * Check if provided coordinates match to the table range data.
     *
     * @param {Number} visualRow Visual row index.
     * @param {Number} visualColumn Visual row index.
     * @returns {Boolean}
     */

  }, {
    key: "isInDataRange",
    value: function isInDataRange(visualRow, visualColumn) {
      return visualRow >= 0 && visualRow < this.hot.countRows() && visualColumn >= 0 && visualColumn < this.hot.countCols();
    }
    /**
     * Get calculated data at specified cell.
     *
     * @param {Number} visualRow Visual row index.
     * @param {Number} visualColumn Visual column index.
     * @returns {*}
     */

  }, {
    key: "getDataAtCell",
    value: function getDataAtCell(visualRow, visualColumn) {
      var id = this._coordId.apply(this, (0, _toConsumableArray2.default)(this.t.toPhysical(visualRow, visualColumn)));

      var result;

      if ((0, _object.hasOwnProperty)(this.changes, id)) {
        result = this.changes[id];
      } else {
        result = this.hot.getDataAtCell(visualRow, visualColumn);
      }

      return result;
    }
    /**
     * Get calculated data at specified range.
     *
     * @param {Number} [visualRow1] Visual row index.
     * @param {Number} [visualColumn1] Visual column index.
     * @param {Number} [visualRow2] Visual row index.
     * @param {Number} [visualColumn2] Visual column index.
     * @returns {Array}
     */

  }, {
    key: "getDataByRange",
    value: function getDataByRange(visualRow1, visualColumn1, visualRow2, visualColumn2) {
      var _this = this;

      var result = this.hot.getData(visualRow1, visualColumn1, visualRow2, visualColumn2);
      (0, _array.arrayEach)(result, function (rowData, rowIndex) {
        (0, _array.arrayEach)(rowData, function (value, columnIndex) {
          var id = _this._coordId.apply(_this, (0, _toConsumableArray2.default)(_this.t.toPhysical(rowIndex + visualRow1, columnIndex + visualColumn1)));

          if ((0, _object.hasOwnProperty)(_this.changes, id)) {
            result[rowIndex][columnIndex] = _this.changes[id];
          }
        });
      });
      return result;
    }
    /**
     * Get source data at specified physical cell.
     *
     * @param {Number} physicalRow Physical row index.
     * @param {Number} physicalColumn Physical column index.
     * @returns {*}
     */

  }, {
    key: "getSourceDataAtCell",
    value: function getSourceDataAtCell(physicalRow, physicalColumn) {
      var id = this._coordId(physicalRow, physicalColumn);

      var result;

      if ((0, _object.hasOwnProperty)(this.changes, id)) {
        result = this.changes[id];
      } else {
        result = this.hot.getSourceDataAtCell(physicalRow, physicalColumn);
      }

      return result;
    }
    /**
     * Get source data at specified physical range.
     *
     * @param {Number} [physicalRow1] Physical row index.
     * @param {Number} [physicalColumn1] Physical column index.
     * @param {Number} [physicalRow2] Physical row index.
     * @param {Number} [physicalColumn2] Physical column index.
     * @returns {Array}
     */

  }, {
    key: "getSourceDataByRange",
    value: function getSourceDataByRange(physicalRow1, physicalColumn1, physicalRow2, physicalColumn2) {
      return this.hot.getSourceDataArray(physicalRow1, physicalColumn1, physicalRow2, physicalColumn2);
    }
    /**
     * Get source data at specified visual cell.
     *
     * @param {Number} visualRow Visual row index.
     * @param {Number} visualColumn Visual column index.
     * @returns {*}
     */

  }, {
    key: "getRawDataAtCell",
    value: function getRawDataAtCell(visualRow, visualColumn) {
      return this.getSourceDataAtCell.apply(this, (0, _toConsumableArray2.default)(this.t.toPhysical(visualRow, visualColumn)));
    }
    /**
     * Get source data at specified visual range.
     *
     * @param {Number} [visualRow1] Visual row index.
     * @param {Number} [visualColumn1] Visual column index.
     * @param {Number} [visualRow2] Visual row index.
     * @param {Number} [visualColumn2] Visual column index.
     * @returns {Array}
     */

  }, {
    key: "getRawDataByRange",
    value: function getRawDataByRange(visualRow1, visualColumn1, visualRow2, visualColumn2) {
      var _this2 = this;

      var data = [];
      (0, _number.rangeEach)(visualRow1, visualRow2, function (visualRow) {
        var row = [];
        (0, _number.rangeEach)(visualColumn1, visualColumn2, function (visualColumn) {
          var _this2$t$toPhysical = _this2.t.toPhysical(visualRow, visualColumn),
              _this2$t$toPhysical2 = (0, _slicedToArray2.default)(_this2$t$toPhysical, 2),
              physicalRow = _this2$t$toPhysical2[0],
              physicalColumn = _this2$t$toPhysical2[1];

          var id = _this2._coordId(physicalRow, physicalColumn);

          if ((0, _object.hasOwnProperty)(_this2.changes, id)) {
            row.push(_this2.changes[id]);
          } else {
            row.push(_this2.getSourceDataAtCell(physicalRow, physicalColumn));
          }
        });
        data.push(row);
      });
      return data;
    }
    /**
     * Update source data.
     *
     * @param {Number} physicalRow Physical row index.
     * @param {Number} physicalColumn Physical row index.
     * @param {*} value Value to update.
     */

  }, {
    key: "updateSourceData",
    value: function updateSourceData(physicalRow, physicalColumn, value) {
      this.hot.getSourceData()[physicalRow][this.hot.colToProp(physicalColumn)] = value;
    }
    /**
     * Generate cell coordinates id where the data changes will be stored.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {String}
     * @private
     */

  }, {
    key: "_coordId",
    value: function _coordId(row, column) {
      return "".concat(row, ":").concat(column);
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.hot = null;
      this.changes = null;
      this.t = null;
    }
  }]);
  return DataProvider;
}();

var _default = DataProvider;
exports.default = _default;

/***/ }),
/* 748 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _stack = _interopRequireDefault(__webpack_require__(749));

var _value = _interopRequireDefault(__webpack_require__(85));

/**
 * This components is a simple workaround to make Undo/Redo functionality work.
 *
 * @class UndoRedoSnapshot
 * @util
 */
var UndoRedoSnapshot =
/*#__PURE__*/
function () {
  function UndoRedoSnapshot(sheet) {
    (0, _classCallCheck2.default)(this, UndoRedoSnapshot);

    /**
     * Instance of {@link Sheet}.
     *
     * @type {Sheet}
     */
    this.sheet = sheet;
    /**
     * Stack instance for collecting undo/redo changes.
     *
     * @type {Stack}
     */

    this.stack = new _stack.default();
  }
  /**
   * Save snapshot for specified action.
   *
   * @param {String} axis Alter action which triggers snapshot.
   * @param {Number} index Alter operation stared at.
   * @param {Number} amount Amount of items to operate.
   */


  (0, _createClass2.default)(UndoRedoSnapshot, [{
    key: "save",
    value: function save(axis, index, amount) {
      var _this$sheet = this.sheet,
          matrix = _this$sheet.matrix,
          dataProvider = _this$sheet.dataProvider;
      var changes = [];
      (0, _array.arrayEach)(matrix.data, function (cellValue) {
        var row = cellValue.row,
            column = cellValue.column;

        if (cellValue[axis] < index || cellValue[axis] > index + (amount - 1)) {
          var value = dataProvider.getSourceDataAtCell(row, column);
          changes.push({
            row: row,
            column: column,
            value: value
          });
        }
      });
      this.stack.push({
        axis: axis,
        index: index,
        amount: amount,
        changes: changes
      });
    }
    /**
     * Restore state to the previous one.
     */

  }, {
    key: "restore",
    value: function restore() {
      var _this$sheet2 = this.sheet,
          matrix = _this$sheet2.matrix,
          dataProvider = _this$sheet2.dataProvider;

      var _this$stack$pop = this.stack.pop(),
          axis = _this$stack$pop.axis,
          index = _this$stack$pop.index,
          amount = _this$stack$pop.amount,
          changes = _this$stack$pop.changes;

      if (changes) {
        (0, _array.arrayEach)(changes, function (change) {
          if (change[axis] > index + (amount - 1)) {
            change[axis] -= amount;
          }

          var row = change.row,
              column = change.column,
              value = change.value;
          var rawValue = dataProvider.getSourceDataAtCell(row, column);

          if (rawValue !== value) {
            dataProvider.updateSourceData(row, column, value);
            matrix.getCellAt(row, column).setState(_value.default.STATE_OUT_OFF_DATE);
          }
        });
      }
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.sheet = null;
      this.stack = null;
    }
  }]);
  return UndoRedoSnapshot;
}();

var _default = UndoRedoSnapshot;
exports.default = _default;

/***/ }),
/* 749 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

/**
 * @class Stack
 * @util
 */
var Stack =
/*#__PURE__*/
function () {
  function Stack() {
    var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
    (0, _classCallCheck2.default)(this, Stack);

    /**
     * Items collection.
     *
     * @type {Array}
     */
    this.items = initial;
  }
  /**
   * Add new item or items at the back of the stack.
   *
   * @param {*} items An item to add.
   */


  (0, _createClass2.default)(Stack, [{
    key: "push",
    value: function push() {
      var _this$items;

      (_this$items = this.items).push.apply(_this$items, arguments);
    }
    /**
     * Remove the last element from the stack and returns it.
     *
     * @returns {*}
     */

  }, {
    key: "pop",
    value: function pop() {
      return this.items.pop();
    }
    /**
     * Return the last element from the stack (without modification stack).
     *
     * @returns {*}
     */

  }, {
    key: "peek",
    value: function peek() {
      return this.isEmpty() ? void 0 : this.items[this.items.length - 1];
    }
    /**
     * Check if the stack is empty.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isEmpty",
    value: function isEmpty() {
      return !this.size();
    }
    /**
     * Return number of elements in the stack.
     *
     * @returns {Number}
     */

  }, {
    key: "size",
    value: function size() {
      return this.items.length;
    }
  }]);
  return Stack;
}();

var _default = Stack;
exports.default = _default;

/***/ }),
/* 750 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(40);

__webpack_require__(37);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var _console = __webpack_require__(55);

var _data = __webpack_require__(132);

var _plugins = __webpack_require__(20);

var _utils = __webpack_require__(172);

var _dateCalculator = _interopRequireDefault(__webpack_require__(751));

var _ganttChartDataFeed = _interopRequireDefault(__webpack_require__(752));

__webpack_require__(753);

/**
 * @plugin GanttChart
 * @experimental
 * @dependencies CollapsibleColumns
 *
 * @description
 * GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance.
 * In this case, the whole table becomes read-only.
 *
 * @example
 * ```js
 * ganttChart: {
 *     dataSource: data,
 *     firstWeekDay: 'monday', // Sets the first day of the week to either 'monday' or 'sunday'.
 *     startYear: 2015 // Sets the displayed year to the provided value.
 *     weekHeaderGenerator: function(start, end) { return start + ' - ' + end; } // sets the label on the week column headers (optional). The `start` and `end` arguments are numbers representing the beginning and end day of the week.
 *     allowSplitWeeks: true, // If set to `true` (default), will allow splitting week columns between months. If not, plugin will generate "mixed" months, like "Jan/Feb".
 *     hideDaysBeforeFullWeeks: false, // If set to `true`, the plugin won't render the incomplete weeks before the "full" weeks inside months.
 *     hideDaysAfterFullWeeks: false, // If set to `true`, the plugin won't render the incomplete weeks after the "full" weeks inside months.
 *   }
 *
 * // Where data can be either an data object or an object containing information about another Handsontable instance, which
 * // would feed the chart-enabled instance with data.
 * // For example:
 *
 * // Handsontable-binding information
 * var data = {
 *   instance: source, // reference to another Handsontable instance
 *   startDateColumn: 4, // index of a column, which contains information about start dates of data ranges
 *   endDateColumn: 5, // index of a column, which contains information about end dates of data ranges
 *   additionalData: { // information about additional data passed to the chart, in this example example:
 *     label: 0, // labels are stored in the first column
 *     quantity: 1 // quantity information is stored in the second column
 *   },
 *   asyncUpdates: true // if set to true, the updates from the source instance with be asynchronous. Defaults to false.
 * }
 *
 * // Data object
 * var data = [
 *   {
 *     additionalData: {label: 'Example label.', quantity: 'Four packs.'},
 *     startDate: '1/5/2015',
 *     endDate: '1/20/2015'
 *   },
 *   {
 *     additionalData: {label: 'Another label.', quantity: 'One pack.'},
 *     startDate: '1/11/2015',
 *     endDate: '1/29/2015'
 *   }
 * ];
 * ```
 */
var GanttChart =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(GanttChart, _BasePlugin);

  function GanttChart(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, GanttChart);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GanttChart).call(this, hotInstance));
    /**
     * Cached plugin settings.
     *
     * @private
     * @type {Object}
     */

    _this.settings = {};
    /**
     * Date Calculator object.
     *
     * @private
     * @type {DateCalculator}
     */

    _this.dateCalculator = null;
    /**
     * Currently loaded year.
     *
     * @private
     * @type {Number}
     */

    _this.currentYear = null;
    /**
     * List of months and their corresponding day counts.
     *
     * @private
     * @type {Array}
     */

    _this.monthList = [];
    /**
     * Array of data for the month headers.
     *
     * @private
     * @type {Array}
     */

    _this.monthHeadersArray = [];
    /**
     * Array of data for the week headers.
     *
     * @private
     * @type {Array}
     */

    _this.weekHeadersArray = [];
    /**
     * Object containing the currently created range bars, along with their corresponding parameters.
     *
     * @private
     * @type {Object}
     */

    _this.rangeBars = {};
    /**
     * Object containing the currently created ranges with coordinates to their range bars.
     * It's structure is categorized by years, so to get range bar information for a year, one must use `this.rangeList[year]`.
     *
     * @private
     * @type {Object}
     */

    _this.rangeList = {};
    /**
     * Reference to the Nested Headers plugin.
     *
     * @private
     * @type {NestedHeaders}
     */

    _this.nestedHeadersPlugin = null;
    /**
     * Object containing properties of the source Handsontable instance (the data source).
     *
     * @private
     * @type {Object}
     */

    _this.hotSource = null;
    /**
     * Number of week 'blocks' in the nested headers.
     *
     * @private
     * @type {Number}
     */

    _this.overallWeekSectionCount = null;
    /**
     * Initial instance settings - used to rollback the gantt-specific settings during the disabling of the plugin.
     *
     * @private
     * @type {Object}
     */

    _this.initialSettings = null;
    /**
     * Data feed controller for this plugin.
     *
     * @private
     * @type {GanttChartDataFeed}
     */

    _this.dataFeed = null;
    /**
     * Color information set after applying colors to the chart.
     *
     * @private
     * @type {Object}
     */

    _this.colorData = {};
    /**
     * Metadata of the range bars, used to re-apply meta after updating HOT settings.
     *
     * @private
     * @type {Object}
     */

    _this.rangeBarMeta = Object.create(null);
    return _this;
  }
  /**
   * Check if the dependencies are met, if not, throws a warning.
   */


  (0, _createClass2.default)(GanttChart, [{
    key: "checkDependencies",
    value: function checkDependencies() {
      if (!this.hot.getSettings().colHeaders) {
        (0, _console.warn)('You need to enable the colHeaders property in your Gantt Chart Handsontable in order for it to work properly.');
      }
    }
    /**
     * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
     * hook and if it returns `true` than the {@link GanttChart#enablePlugin} method is called.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().ganttChart;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.checkDependencies();
      this.parseSettings();
      this.currentYear = this.settings.startYear || new Date().getFullYear();
      this.dateCalculator = new _dateCalculator.default({
        year: this.currentYear,
        allowSplitWeeks: this.settings.allowSplitWeeks,
        hideDaysBeforeFullWeeks: this.settings.hideDaysBeforeFullWeeks,
        hideDaysAfterFullWeeks: this.settings.hideDaysAfterFullWeeks
      });
      this.dateCalculator.setFirstWeekDay(this.settings.firstWeekDay);
      this.monthList = this.dateCalculator.getMonthList();
      this.monthHeadersArray = this.generateMonthHeaders();
      this.weekHeadersArray = this.generateWeekHeaders();
      this.overallWeekSectionCount = this.dateCalculator.countWeekSections();
      this.assignGanttSettings();

      if (this.nestedHeadersPlugin) {
        this.applyDataSource();

        if (this.colorData) {
          this.setRangeBarColors(this.colorData);
        }
      }

      this.addHook('afterInit', function () {
        return _this2.onAfterInit();
      });
      (0, _element.addClass)(this.hot.rootElement, 'ganttChart');
      (0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      if (this.internalUpdateSettings) {
        return;
      }

      if (this.dataFeed && this.dataFeed.hotSource) {
        this.dataFeed.removeSourceHotHooks(this.dataFeed.hotSource);
      }

      this.settings = {};
      this.dataFeed = {};
      this.currentYear = null;
      this.monthList = [];
      this.rangeBars = {};
      this.rangeList = {};
      this.rangeBarMeta = {};
      this.hotSource = null;
      this.deassignGanttSettings();
      (0, _element.removeClass)(this.hot.rootElement, 'ganttChart');
      (0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Parses the plugin settings.
     *
     * @private
     */

  }, {
    key: "parseSettings",
    value: function parseSettings() {
      this.settings = this.hot.getSettings().ganttChart;

      if (typeof this.settings === 'boolean') {
        this.settings = {};
      }

      if (!this.settings.firstWeekDay) {
        this.settings.firstWeekDay = 'monday';
      }

      if (this.settings.allowSplitWeeks === void 0) {
        this.settings.allowSplitWeeks = true;
      }

      if (typeof this.settings.weekHeaderGenerator !== 'function') {
        this.settings.weekHeaderGenerator = null;
      }
    }
    /**
     * Applies the data source provided in the plugin settings.
     *
     * @private
     */

  }, {
    key: "applyDataSource",
    value: function applyDataSource() {
      if (this.settings.dataSource) {
        var source = this.settings.dataSource;

        if (source.instance) {
          this.loadData(source.instance, source.startDateColumn, source.endDateColumn, source.additionalData, source.asyncUpdates);
        } else {
          this.loadData(source);
        }
      }
    }
    /**
     * Loads chart data to the Handsontable instance.
     *
     * @private
     * @param {Array|Object} data Array of objects containing the range data OR another Handsontable instance, to be used as the data feed
     * @param {Number} [startDateColumn] Index of the start date column (Needed only if the data argument is a HOT instance).
     * @param {Number} [endDateColumn] Index of the end date column (Needed only if the data argument is a HOT instance).
     * @param {Object} [additionalData] Object containing additional data labels and their corresponding column indexes (Needed only if the data argument is a HOT instance).
     *
     */

  }, {
    key: "loadData",
    value: function loadData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
      this.dataFeed = new _ganttChartDataFeed.default(this.hot, data, startDateColumn, endDateColumn, additionalData, asyncUpdates);
      this.hot.render();
    }
    /**
     * Clears the range bars list.
     *
     * @private
     */

  }, {
    key: "clearRangeBars",
    value: function clearRangeBars() {
      this.rangeBars = {};
    }
    /**
     * Clears the range list.
     *
     * @private
     */

  }, {
    key: "clearRangeList",
    value: function clearRangeList() {
      this.rangeList = {};
    }
    /**
     * Returns a range bar coordinates by the provided row.
     *
     * @param {Number} row Range bar's row.
     * @returns {Object}
     */

  }, {
    key: "getRangeBarCoordinates",
    value: function getRangeBarCoordinates(row) {
      return this.rangeList[row];
    }
    /**
     * Generates the month header structure.
     *
     * @private
     */

  }, {
    key: "generateMonthHeaders",
    value: function generateMonthHeaders() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentYear;
      return this.dateCalculator.generateHeaderSet('months', this.settings.weekHeaderGenerator, year);
    }
    /**
     * Generates the week header structure.
     *
     * @private
     */

  }, {
    key: "generateWeekHeaders",
    value: function generateWeekHeaders() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentYear;
      return this.dateCalculator.generateHeaderSet('weeks', this.settings.weekHeaderGenerator, year);
    }
    /**
     * Assigns the settings needed for the Gantt Chart plugin into the Handsontable instance.
     *
     * @private
     */

  }, {
    key: "assignGanttSettings",
    value: function assignGanttSettings() {
      var _this3 = this;

      // TODO: commented out temporarily, to be fixed in #68, there's a problem with re-enabling the gantt settings after resetting them
      // this.initialSettings = {
      //   data: this.hot.getSettings().data,
      //   readOnly: this.hot.getSettings().readOnly,
      //   renderer: this.hot.getSettings().renderer,
      //   colWidths: this.hot.getSettings().colWidths,
      //   hiddenColumns: this.hot.getSettings().hiddenColumns,
      //   nestedHeaders: this.hot.getSettings().nestedHeaders,
      //   collapsibleColumns: this.hot.getSettings().collapsibleColumns,
      //   columnSorting: this.hot.getSettings().columnSorting,
      // };
      this.initialSettings = (0, _object.deepClone)(this.hot.getSettings());
      var additionalSettings = {
        data: (0, _data.createEmptySpreadsheetData)(1, this.overallWeekSectionCount),
        readOnly: true,
        renderer: function renderer(instance, TD, row, col, prop, value, cellProperties) {
          return _this3.uniformBackgroundRenderer(instance, TD, row, col, prop, value, cellProperties);
        },
        colWidths: 60,
        hiddenColumns: this.hot.getSettings().hiddenColumns ? this.hot.getSettings().hiddenColumns : true,
        nestedHeaders: [this.monthHeadersArray.slice(), this.weekHeadersArray.slice()],
        collapsibleColumns: this.hot.getSettings().collapsibleColumns ? this.hot.getSettings().collapsibleColumns : true,
        columnSorting: false,
        copyPaste: false
      };
      this.internalUpdateSettings = true;
      this.hot.updateSettings(additionalSettings);
      this.internalUpdateSettings = void 0;
    }
    /**
     * Deassigns the Gantt Chart plugin settings (revert to initial settings).
     *
     * @private
     */

  }, {
    key: "deassignGanttSettings",
    value: function deassignGanttSettings() {
      this.internalUpdateSettings = true;

      if (this.initialSettings) {
        this.hot.updateSettings(this.initialSettings);
      }

      this.internalUpdateSettings = void 0;
    }
    /**
     * Add rangebar meta data to the cache.
     *
     * @param {Number} row
     * @param {Number} col
     * @param {String} key
     * @param {String|Number|Object|Array} value
     */

  }, {
    key: "cacheRangeBarMeta",
    value: function cacheRangeBarMeta(row, col, key, value) {
      if (!this.rangeBarMeta[row]) {
        this.rangeBarMeta[row] = {};
      }

      if (!this.rangeBarMeta[row][col]) {
        this.rangeBarMeta[row][col] = {};
      }

      this.rangeBarMeta[row][col][key] = value;
    }
    /**
     * Applies the cached cell meta.
     *
     * @private
     */

  }, {
    key: "applyRangeBarMetaCache",
    value: function applyRangeBarMetaCache() {
      var _this4 = this;

      (0, _object.objectEach)(this.rangeBarMeta, function (rowArr, row) {
        (0, _object.objectEach)(rowArr, function (cell, col) {
          (0, _object.objectEach)(cell, function (value, key) {
            _this4.hot.setCellMeta(row, col, key, value);
          });
        });
      });
    }
    /**
     * Get the column index of the adjacent week.
     *
     * @private
     * @param {Date|String} date The date object/string.
     * @param {Boolean} following `true` if the following week is needed.
     * @param {Boolean} previous `true` if the previous week is needed.
     */

  }, {
    key: "getAdjacentWeekColumn",
    value: function getAdjacentWeekColumn(date, following, previous) {
      var convertedDate = (0, _utils.parseDate)(date);
      var delta = previous === true ? -7 : 7;
      var adjacentWeek = convertedDate.setDate(convertedDate.getDate() + delta);
      return this.dateCalculator.dateToColumn(adjacentWeek);
    }
    /**
     * Create a new range bar.
     *
     * @param {Number} row Row index.
     * @param {Date|String} startDate Start date object/string.
     * @param {Date|String} endDate End date object/string.
     * @param {Object} additionalData Additional range data.
     * @returns {Array|Boolean} Array of the bar's row and column.
     */

  }, {
    key: "addRangeBar",
    value: function addRangeBar(row, startDate, endDate, additionalData) {
      var _this5 = this;

      if (startDate !== null && endDate !== null) {
        this.prepareDaysInColumnsInfo((0, _utils.parseDate)(startDate), (0, _utils.parseDate)(endDate));
      }

      var startDateColumn = this.dateCalculator.dateToColumn(startDate);
      var endDateColumn = this.dateCalculator.dateToColumn(endDate);
      var year = (0, _utils.getDateYear)(startDate); // every range bar should not exceed the limits of one year

      var startMoved = false;
      var endMoved = false;

      if (startDateColumn === null && this.settings.hideDaysBeforeFullWeeks) {
        startDateColumn = this.getAdjacentWeekColumn(startDate, true, false);

        if (startDateColumn !== false) {
          startMoved = true;
        }
      }

      if (endDateColumn === null && this.settings.hideDaysAfterFullWeeks) {
        endDateColumn = this.getAdjacentWeekColumn(endDate, false, true);

        if (endDateColumn !== false) {
          endMoved = true;
        }
      }

      if (!this.dateCalculator.isValidRangeBarData(startDate, endDate) || startDateColumn === false || endDateColumn === false) {
        return false;
      }

      if (!this.rangeBars[year]) {
        this.rangeBars[year] = {};
      }

      if (!this.rangeBars[year][row]) {
        this.rangeBars[year][row] = {};
      }

      this.rangeBars[year][row][startDateColumn] = {
        barLength: endDateColumn - startDateColumn + 1,
        partialStart: startMoved ? false : !this.dateCalculator.isOnTheEdgeOfWeek(startDate)[0],
        partialEnd: endMoved ? false : !this.dateCalculator.isOnTheEdgeOfWeek(endDate)[1],
        additionalData: {}
      };
      (0, _object.objectEach)(additionalData, function (prop, i) {
        _this5.rangeBars[year][row][startDateColumn].additionalData[i] = prop;
      });

      if (year === this.dateCalculator.getYear()) {
        if (this.colorData[row]) {
          this.rangeBars[year][row][startDateColumn].colors = this.colorData[row];
        }

        this.rangeList[row] = [row, startDateColumn];
        this.renderRangeBar(row, startDateColumn, endDateColumn, additionalData);
      }

      return [row, startDateColumn];
    }
    /**
     * Generates the information about which date is represented in which column.
     *
     * @private
     * @param {Date} startDate Start date.
     * @param {Date} endDate End Date.
     */

  }, {
    key: "prepareDaysInColumnsInfo",
    value: function prepareDaysInColumnsInfo(startDate, endDate) {
      for (var i = startDate.getFullYear(); i <= endDate.getFullYear(); i++) {
        if (this.dateCalculator.daysInColumns[i] === void 0) {
          this.dateCalculator.calculateWeekStructure(i);
          this.dateCalculator.generateHeaderSet('weeks', null, i);
        }
      }
    }
    /**
     * Returns the range bar data of the provided row and column.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {Object|Boolean} Returns false if no bar is found.
     */

  }, {
    key: "getRangeBarData",
    value: function getRangeBarData(row, column) {
      var year = this.dateCalculator.getYear();
      var rangeBarCoords = this.getRangeBarCoordinates(row);

      if (!rangeBarCoords) {
        return false;
      }

      var rangeBarData = this.rangeBars[year][rangeBarCoords[0]][rangeBarCoords[1]];

      if (rangeBarData && row === rangeBarCoords[0] && (column === rangeBarCoords[1] || column > rangeBarCoords[1] && column < rangeBarCoords[1] + rangeBarData.barLength)) {
        return rangeBarData;
      }

      return false;
    }
    /**
     * Updates the range bar data by the provided object.
     *
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @param {Object} data Object with the updated data.
     */

  }, {
    key: "updateRangeBarData",
    value: function updateRangeBarData(row, column, data) {
      var rangeBar = this.getRangeBarData(row, column);
      (0, _object.objectEach)(data, function (val, prop) {
        if (rangeBar[prop] !== val) {
          rangeBar[prop] = val;
        }
      });
    }
    /**
     * Adds a range bar to the table.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} startDateColumn Start column index.
     * @param {Number} endDateColumn End column index.
     */

  }, {
    key: "renderRangeBar",
    value: function renderRangeBar(row, startDateColumn, endDateColumn) {
      var year = this.dateCalculator.getYear();
      var currentBar = this.rangeBars[year][row][startDateColumn];

      for (var i = startDateColumn; i <= endDateColumn; i++) {
        var cellMeta = this.hot.getCellMeta(row, i);
        var newClassName = "".concat(cellMeta.className || '', " rangeBar");

        if (i === startDateColumn && currentBar.partialStart || i === endDateColumn && currentBar.partialEnd) {
          newClassName += ' partial';
        }

        if (i === endDateColumn) {
          newClassName += ' last';
        }

        this.hot.setCellMeta(row, i, 'originalClassName', cellMeta.className);
        this.hot.setCellMeta(row, i, 'className', newClassName);
        this.hot.setCellMeta(row, i, 'additionalData', currentBar.additionalData); // cache cell meta, used for updateSettings, related with a cell meta bug

        this.cacheRangeBarMeta(row, i, 'originalClassName', cellMeta.className);
        this.cacheRangeBarMeta(row, i, 'className', newClassName);
        this.cacheRangeBarMeta(row, i, 'additionalData', currentBar.additionalData);
      }
    }
    /**
     * Removes a range bar of the provided start date and row.
     *
     * @param {Number} row Row index.
     * @param {Date|String} startDate Start date.
     */

  }, {
    key: "removeRangeBarByDate",
    value: function removeRangeBarByDate(row, startDate) {
      var startDateColumn = this.dateCalculator.dateToColumn(startDate);
      this.removeRangeBarByColumn(row, startDateColumn);
    }
    /**
     * Removes a range bar of the provided row and start column.
     *
     * @param {Number} row Row index.
     * @param {Number} startDateColumn Column index.
     */

  }, {
    key: "removeRangeBarByColumn",
    value: function removeRangeBarByColumn(row, startDateColumn) {
      var _this6 = this;

      var year = this.dateCalculator.getYear();
      var rangeBar = this.rangeBars[year][row][startDateColumn];

      if (!rangeBar) {
        return;
      }

      this.unrenderRangeBar(row, startDateColumn, startDateColumn + rangeBar.barLength - 1);
      this.rangeBars[year][row][startDateColumn] = null;
      (0, _object.objectEach)(this.rangeList, function (prop, i) {
        var id = parseInt(i, 10);

        if (JSON.stringify(prop) === JSON.stringify([row, startDateColumn])) {
          _this6.rangeList[id] = null;
        }
      });
    }
    /**
     * Removes all range bars from the chart-enabled Handsontable instance.
     */

  }, {
    key: "removeAllRangeBars",
    value: function removeAllRangeBars() {
      var _this7 = this;

      (0, _object.objectEach)(this.rangeBars, function (row, i) {
        (0, _object.objectEach)(row, function (bar, j) {
          _this7.removeRangeBarByColumn(i, j);
        });
      });
    }
    /**
     * Removes a range bar from the table.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} startDateColumn Start column index.
     * @param {Number} endDateColumn End column index.
     */

  }, {
    key: "unrenderRangeBar",
    value: function unrenderRangeBar(row, startDateColumn, endDateColumn) {
      for (var i = startDateColumn; i <= endDateColumn; i++) {
        var cellMeta = this.hot.getCellMeta(row, i);
        this.hot.setCellMeta(row, i, 'className', cellMeta.originalClassName);
        this.hot.setCellMeta(row, i, 'originalClassName', void 0);
        this.cacheRangeBarMeta(row, i, 'className', cellMeta.originalClassName);
        this.cacheRangeBarMeta(row, i, 'originalClassName', void 0);
      }

      this.hot.render();
    }
    /**
     * A default renderer of the range bars.
     *
     * @private
     * @param {Object} instance HOT instance.
     * @param {HTMLElement} TD TD element.
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     * @param {String|Number} prop Object data property.
     * @param {String|Number} value Value to pass to the cell.
     * @param {Object} cellProperties Current cell properties.
     */

  }, {
    key: "uniformBackgroundRenderer",
    value: function uniformBackgroundRenderer(instance, TD, row, col, prop, value, cellProperties) {
      var rangeBarInfo = this.getRangeBarData(row, col);
      var rangeBarCoords = this.getRangeBarCoordinates(row);
      TD.innerHTML = '';

      if (cellProperties.className) {
        TD.className = cellProperties.className;
      }

      var titleValue = '';
      (0, _object.objectEach)(cellProperties.additionalData, function (cellMeta, i) {
        titleValue += "".concat(i, ": ").concat(cellMeta, "\n");
      });
      titleValue = titleValue.replace(/\n$/, '');
      TD.title = titleValue;

      if (rangeBarInfo && rangeBarInfo.colors) {
        if (col === rangeBarCoords[1] && rangeBarInfo.partialStart || col === rangeBarCoords[1] + rangeBarInfo.barLength - 1 && rangeBarInfo.partialEnd) {
          TD.style.background = rangeBarInfo.colors[1];
        } else {
          TD.style.background = rangeBarInfo.colors[0];
        }
      } else {
        TD.style.background = '';
      }
    }
    /**
     * Sets range bar colors.
     *
     * @param {Object} rows Object containing row color data, see example.
     * @example
     * ```js
     *  hot.getPlugin('ganttChart').setRangeBarColors({
     *    0: ['blue', 'lightblue'] // paints the bar in the first row blue, with partial sections colored light blue
      *   2: ['#2A74D0', '#588DD0'] // paints the bar in the thrid row with #2A74D0, with partial sections colored with #588DD0
     *  });
     * ```
     */

  }, {
    key: "setRangeBarColors",
    value: function setRangeBarColors(rows) {
      var _this8 = this;

      this.colorData = rows;
      (0, _object.objectEach)(rows, function (colors, i) {
        var barCoords = _this8.getRangeBarCoordinates(i);

        if (barCoords) {
          _this8.updateRangeBarData(barCoords[0], barCoords[1], {
            colors: colors
          });
        }
      });
      this.hot.render();
    }
    /**
     * Updates the chart with a new year.
     *
     * @param {Number} year New chart year.
     */

  }, {
    key: "setYear",
    value: function setYear(year) {
      var newSettings = (0, _object.extend)(this.hot.getSettings().ganttChart, {
        startYear: year
      });
      this.hot.updateSettings({
        ganttChart: newSettings
      });
    }
    /**
     * AfterInit hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.nestedHeadersPlugin = this.hot.getPlugin('nestedHeaders');
      this.applyDataSource();
    }
    /**
     * Prevents update settings loop when assigning the additional internal settings.
     *
     * @private
     */

  }, {
    key: "onUpdateSettings",
    value: function onUpdateSettings() {
      if (this.internalUpdateSettings) {
        this.applyRangeBarMetaCache();
        return;
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "onUpdateSettings", this).call(this);
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      if (this.hotSource) {
        this.dataFeed.removeSourceHotHooks(this.hotSource);
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "destroy", this).call(this);
    }
  }]);
  return GanttChart;
}(_base.default);

(0, _plugins.registerPlugin)('ganttChart', GanttChart);
var _default = GanttChart;
exports.default = _default;

/***/ }),
/* 751 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

__webpack_require__(40);

__webpack_require__(33);

__webpack_require__(51);

__webpack_require__(76);

exports.__esModule = true;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _console = __webpack_require__(55);

var _utils = __webpack_require__(172);

/**
 * This class handles the date-related calculations for the GanttChart plugin.
 *
 * @plugin GanttChart
 */
var DateCalculator =
/*#__PURE__*/
function () {
  function DateCalculator(_ref) {
    var year = _ref.year,
        _ref$allowSplitWeeks = _ref.allowSplitWeeks,
        allowSplitWeeks = _ref$allowSplitWeeks === void 0 ? true : _ref$allowSplitWeeks,
        _ref$hideDaysBeforeFu = _ref.hideDaysBeforeFullWeeks,
        hideDaysBeforeFullWeeks = _ref$hideDaysBeforeFu === void 0 ? false : _ref$hideDaysBeforeFu,
        _ref$hideDaysAfterFul = _ref.hideDaysAfterFullWeeks,
        hideDaysAfterFullWeeks = _ref$hideDaysAfterFul === void 0 ? false : _ref$hideDaysAfterFul;
    (0, _classCallCheck2.default)(this, DateCalculator);

    /**
     * Year to base calculations on.
     *
     * @type {Number}
     */
    this.year = year;
    /**
     * First day of the week.
     *
     * @type {String}
     */

    this.firstWeekDay = 'monday';
    /**
     * The current `allowSplitWeeks` option state.
     */

    this.allowSplitWeeks = allowSplitWeeks;
    /**
     * The current `hideDaysBeforeFullWeeks` option state.
     */

    this.hideDaysBeforeFullWeeks = hideDaysBeforeFullWeeks;
    /**
     * The current `hideDaysAfterFullWeeks` option state.
     */

    this.hideDaysAfterFullWeeks = hideDaysAfterFullWeeks;
    /**
     * Number of week sections (full weeks + incomplete week blocks in months).
     *
     * @type {Number}
     */

    this.weekSectionCount = 0;
    /**
     * Cache of lists of months and their week/day related information.
     * It's categorized by year, so month information for a certain year is stored under `this.monthListCache[year]`.
     *
     * @type {Object}
     */

    this.monthListCache = {};
    /**
     * Object containing references to the year days and their corresponding columns.
     *
     * @type {Object}
     */

    this.daysInColumns = {};
    this.calculateWeekStructure();
  }
  /**
   * Set the year as a base for calculations.
   *
   * @param {Number} year
   */


  (0, _createClass2.default)(DateCalculator, [{
    key: "setYear",
    value: function setYear(year) {
      this.year = year;
      this.monthListCache[year] = this.calculateMonthData(year);
      this.calculateWeekStructure(year);
    }
    /**
     * Set the first week day.
     *
     * @param {String} day Day of the week. Available options: 'monday' or 'sunday'.
     */

  }, {
    key: "setFirstWeekDay",
    value: function setFirstWeekDay(day) {
      var lowercaseDay = day.toLowerCase();

      if (lowercaseDay !== 'monday' && lowercaseDay !== 'sunday') {
        (0, _console.warn)('First day of the week must be set to either Monday or Sunday');
      }

      this.firstWeekDay = lowercaseDay;
      this.calculateWeekStructure();
    }
    /**
     * Count week sections (full weeks + incomplete weeks in the months).
     *
     * @returns {Number} Week section count.
     */

  }, {
    key: "countWeekSections",
    value: function countWeekSections() {
      return this.weekSectionCount;
    }
    /**
     * Get the first week day.
     *
     * @returns {String}
     */

  }, {
    key: "getFirstWeekDay",
    value: function getFirstWeekDay() {
      return this.firstWeekDay;
    }
    /**
     * Get the currently applied year.
     *
     * @returns {Number}
     */

  }, {
    key: "getYear",
    value: function getYear() {
      return this.year;
    }
    /**
     * Get month list along with the month information.
     *
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getMonthList",
    value: function getMonthList() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;

      if (!this.monthListCache[year]) {
        this.monthListCache[year] = this.calculateMonthData(year);
      }

      return this.monthListCache[year];
    }
    /**
     * Get month lists for all years declared in the range bars.
     *
     * @returns {Object}
     */

  }, {
    key: "getFullMonthList",
    value: function getFullMonthList() {
      return this.monthListCache;
    }
    /**
     * Convert a date to a column number.
     *
     * @param {String|Date} date
     * @returns {Number|Boolean}
     */

  }, {
    key: "dateToColumn",
    value: function dateToColumn(date) {
      var convertedDate = (0, _utils.parseDate)(date);

      if (!convertedDate) {
        return false;
      }

      var month = convertedDate.getMonth();
      var day = convertedDate.getDate() - 1;
      var year = convertedDate.getFullYear();
      return this.getWeekColumn(day, month, year);
    }
    /**
     * Get the column index for the provided day and month indexes.
     *
     * @private
     * @param {Number} dayIndex The index of the day.
     * @param {Number} monthIndex The index of the month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Number} Returns the column index.
     */

  }, {
    key: "getWeekColumn",
    value: function getWeekColumn(dayIndex, monthIndex) {
      var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getYear();
      var resultColumn = null;
      var monthCacheArray = this.getMonthCacheArray(monthIndex, year);
      (0, _array.arrayEach)(monthCacheArray, function (monthCache) {
        (0, _object.objectEach)(monthCache, function (column, index) {
          if (column.indexOf(dayIndex + 1) > -1) {
            resultColumn = parseInt(index, 10);
            return false;
          }
        });

        if (resultColumn) {
          return false;
        }
      });
      return resultColumn;
    }
    /**
     * Get the cached day array for the provided month.
     *
     * @private
     * @param {Number} monthIndex Index of the Month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getMonthCacheArray",
    value: function getMonthCacheArray(monthIndex) {
      var _this = this;

      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      var monthList = this.getMonthList(year);
      var resultArray = [];

      if (this.allowSplitWeeks) {
        resultArray.push(this.daysInColumns[year][monthIndex]);
      } else {
        var fullMonthCount = -1;
        (0, _object.objectEach)(this.daysInColumns[year], function (month, i) {
          var monthObject = monthList[i];

          if (Object.keys(month).length > 1) {
            fullMonthCount += 1;
          }

          if (fullMonthCount === monthIndex) {
            if (monthObject.daysBeforeFullWeeks > 0) {
              resultArray.push(_this.daysInColumns[year][parseInt(i, 10) - 1]);
            }

            resultArray.push(month);

            if (monthObject.daysAfterFullWeeks > 0) {
              resultArray.push(_this.daysInColumns[year][parseInt(i, 10) + 1]);
            }

            return false;
          }
        });
      }

      return resultArray;
    }
    /**
     * Convert a column index to a certain date.
     *
     * @param {Number} column Column index.
     * @param {Number} [year] Year to be used.
     * @returns {Object} Object in a form of {start: startDate, end: endDate}
     */

  }, {
    key: "columnToDate",
    value: function columnToDate(column) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      var month = null;
      (0, _object.objectEach)(this.daysInColumns[year], function (monthCache, index) {
        if (monthCache[column]) {
          month = index;
          return false;
        }
      });
      var monthSection = this.daysInColumns[year][month][column];

      if (monthSection.length === 1) {
        var resultingDate = new Date(year, month, monthSection[0]);
        return {
          start: resultingDate,
          end: resultingDate
        };
      }

      return {
        start: new Date(year, month, monthSection[0]),
        end: new Date(year, month, monthSection[monthSection.length - 1])
      };
    }
    /**
     * Check if the provided date is a starting or an ending day of a week.
     *
     * @private
     * @param {Date|String} date
     * @returns {Array|Boolean} Returns null, if an invalid date was provided or an array of results ( [1,0] => is on the beginning of the week, [0,1] => is on the end of the week).
     */

  }, {
    key: "isOnTheEdgeOfWeek",
    value: function isOnTheEdgeOfWeek(date) {
      var _this2 = this;

      var convertedDate = (0, _utils.parseDate)(date);

      if (!convertedDate) {
        return null;
      }

      var month = convertedDate.getMonth();
      var day = convertedDate.getDate() - 1;
      var year = convertedDate.getFullYear();
      var monthCacheArray = this.getMonthCacheArray(month, year);
      var isOnTheEdgeOfWeek = false;
      (0, _array.arrayEach)(monthCacheArray, function (monthCache) {
        (0, _object.objectEach)(monthCache, function (column) {
          if (!_this2.allowSplitWeeks && column.length !== 7) {
            if (day === 0 || day === new Date(convertedDate.getYear(), convertedDate.getMonth() + 1, 0).getDate() - 1) {
              return true;
            }
          }

          var indexOfDay = column.indexOf(day + 1);

          if (indexOfDay === 0) {
            isOnTheEdgeOfWeek = [1, 0];
            return false;
          } else if (indexOfDay === column.length - 1) {
            isOnTheEdgeOfWeek = [0, 1];
            return false;
          }
        }); // break the iteration

        if (isOnTheEdgeOfWeek) {
          return false;
        }
      });
      return isOnTheEdgeOfWeek;
    }
    /**
     * Generate headers for the year structure.
     *
     * @private
     * @param {String} type Granulation type ('months'/'weeks'/'days')
     * @param {Function|null} weekHeaderGenerator Function generating the looks of the week headers.
     * @param {Number} [year=this.year] The year for the calculation.
     * @returns {Array} The header array
     */

  }, {
    key: "generateHeaderSet",
    value: function generateHeaderSet(type, weekHeaderGenerator) {
      var _this3 = this;

      var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.year;
      var monthList = this.getMonthList(year);
      var headers = [];
      (0, _object.objectEach)(monthList, function (month, index) {
        var areDaysBeforeFullWeeks = month.daysBeforeFullWeeks > 0 ? 1 : 0;
        var areDaysAfterFullWeeks = month.daysAfterFullWeeks > 0 ? 1 : 0;
        var areDaysBeforeFullWeeksVisible = _this3.hideDaysBeforeFullWeeks ? 0 : areDaysBeforeFullWeeks;
        var areDaysAfterFullWeeksVisible = _this3.hideDaysAfterFullWeeks ? 0 : areDaysAfterFullWeeks;
        var headerCount = month.fullWeeks + (_this3.allowSplitWeeks ? areDaysBeforeFullWeeksVisible + areDaysAfterFullWeeksVisible : 0);
        var monthNumber = parseInt(index, 10);
        var headerLabel = '';

        if (type === 'months') {
          headers.push({
            label: month.name,
            colspan: headerCount
          });
        } else if (type === 'weeks') {
          for (var i = 0; i < headerCount; i++) {
            var start = null;
            var end = null; // Mixed month's only column

            if (!_this3.allowSplitWeeks && month.fullWeeks === 1) {
              var _this3$getWeekColumnR = _this3.getWeekColumnRange({
                monthObject: month,
                monthNumber: monthNumber,
                headerIndex: i,
                headerCount: headerCount,
                areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
                areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
                mixedMonth: true,
                year: year
              });

              var _this3$getWeekColumnR2 = (0, _slicedToArray2.default)(_this3$getWeekColumnR, 2);

              start = _this3$getWeekColumnR2[0];
              end = _this3$getWeekColumnR2[1];
            } else {
              var _this3$getWeekColumnR3 = _this3.getWeekColumnRange({
                monthObject: month,
                monthNumber: monthNumber,
                headerIndex: i,
                areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
                areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
                headerCount: headerCount,
                year: year
              });

              var _this3$getWeekColumnR4 = (0, _slicedToArray2.default)(_this3$getWeekColumnR3, 2);

              start = _this3$getWeekColumnR4[0];
              end = _this3$getWeekColumnR4[1];
            }

            if (start === end) {
              headerLabel = "".concat(start);
            } else {
              headerLabel = "".concat(start, " -  ").concat(end);
            }

            headers.push(weekHeaderGenerator ? weekHeaderGenerator.call(_this3, start, end) : headerLabel);

            _this3.addDaysToCache(monthNumber, headers.length - 1, start, end, year);
          }
        }
      });
      return headers;
    }
    /**
     * Get the week column range.
     *
     * @private
     * @param {Object} options The options object.
     * @param {Object} options.monthObject The month object.
     * @param {Number} options.monthNumber Index of the month.
     * @param {Number} options.headerIndex Index of the header.
     * @param {Boolean} options.areDaysBeforeFullWeeksVisible `true` if the days before full weeks are to be visible.
     * @param {Boolean} options.areDaysAfterFullWeeksVisible `true` if the days after full weeks are to be visible.
     * @param {Number} options.headerCount Number of headers to be generated for the provided month.
     * @param {Boolean} [options.mixedMonth=false] `true` if the header is the single header of a mixed month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getWeekColumnRange",
    value: function getWeekColumnRange(_ref2) {
      var monthObject = _ref2.monthObject,
          monthNumber = _ref2.monthNumber,
          headerIndex = _ref2.headerIndex,
          headerCount = _ref2.headerCount,
          areDaysBeforeFullWeeksVisible = _ref2.areDaysBeforeFullWeeksVisible,
          areDaysAfterFullWeeksVisible = _ref2.areDaysAfterFullWeeksVisible,
          _ref2$mixedMonth = _ref2.mixedMonth,
          mixedMonth = _ref2$mixedMonth === void 0 ? false : _ref2$mixedMonth,
          _ref2$year = _ref2.year,
          year = _ref2$year === void 0 ? this.year : _ref2$year;
      var monthList = this.getMonthList(year);
      var allowSplitWeeks = this.allowSplitWeeks;
      var start = null;
      var end = null;

      if (mixedMonth) {
        if (monthNumber === 0) {
          end = monthList[monthNumber + 1].daysBeforeFullWeeks;
          start = _utils.DEC_LENGTH - (_utils.WEEK_LENGTH - end) + 1;
        } else if (monthNumber === monthList.length - 1) {
          end = _utils.WEEK_LENGTH - monthList[monthNumber - 1].daysAfterFullWeeks;
          start = monthList[monthNumber - 1].days - monthList[monthNumber - 1].daysAfterFullWeeks + 1;
        } else {
          end = monthList[monthNumber + 1].daysBeforeFullWeeks;
          start = monthList[monthNumber - 1].days - (_utils.WEEK_LENGTH - end) + 1;
        }
      } else if (allowSplitWeeks && areDaysBeforeFullWeeksVisible && headerIndex === 0) {
        start = headerIndex + 1;
        end = monthObject.daysBeforeFullWeeks;
      } else if (allowSplitWeeks && areDaysAfterFullWeeksVisible && headerIndex === headerCount - 1) {
        start = monthObject.days - monthObject.daysAfterFullWeeks + 1;
        end = monthObject.days;
      } else {
        start = null;

        if (allowSplitWeeks) {
          start = monthObject.daysBeforeFullWeeks + (headerIndex - areDaysBeforeFullWeeksVisible) * _utils.WEEK_LENGTH + 1;
        } else {
          start = monthObject.daysBeforeFullWeeks + headerIndex * _utils.WEEK_LENGTH + 1;
        }

        end = start + _utils.WEEK_LENGTH - 1;
      }

      return [start, end];
    }
    /**
     * Add days to the column/day cache.
     *
     * @private
     * @param {Number} monthNumber Index of the month.
     * @param {Number} columnNumber Index of the column.
     * @param {Number} start First day in the column.
     * @param {Number} end Last day in the column.
     * @param {Number} [year] Year to process.
     */

  }, {
    key: "addDaysToCache",
    value: function addDaysToCache(monthNumber, columnNumber, start, end) {
      var year = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getYear();

      if (!this.daysInColumns[year]) {
        this.daysInColumns[year] = {};
      }

      if (!this.daysInColumns[year][monthNumber]) {
        this.daysInColumns[year][monthNumber] = {};
      }

      if (!this.daysInColumns[year][monthNumber][columnNumber]) {
        this.daysInColumns[year][monthNumber][columnNumber] = [];
      }

      if (start <= end) {
        for (var dayIndex = start; dayIndex <= end; dayIndex++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(dayIndex);
        }
      } else {
        var previousMonthDaysCount = monthNumber - 1 >= 0 ? this.countMonthDays(monthNumber) : 31;

        for (var _dayIndex = start; _dayIndex <= previousMonthDaysCount; _dayIndex++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex);
        }

        for (var _dayIndex2 = 1; _dayIndex2 <= end; _dayIndex2++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex2);
        }
      }
    }
    /**
     * Check if the provided dates can be used in a range bar.
     *
     * @param {Date|String} startDate Range start date.
     * @param {Date|String} endDate Range end date.
     * @returns {Boolean}
     */

  }, {
    key: "isValidRangeBarData",
    value: function isValidRangeBarData(startDate, endDate) {
      var startDateParsed = (0, _utils.parseDate)(startDate);
      var endDateParsed = (0, _utils.parseDate)(endDate);
      return startDateParsed && endDateParsed && startDateParsed.getTime() <= endDateParsed.getTime();
    }
    /**
     * Calculate the month/day related information.
     *
     * @param {Number} [year] Year to be used.
     * @returns {Array}
     */

  }, {
    key: "calculateMonthData",
    value: function calculateMonthData() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;
      return [{
        name: 'January',
        days: 31
      }, {
        name: 'February',
        days: new Date(year, 2, 0).getDate()
      }, {
        name: 'March',
        days: 31
      }, {
        name: 'April',
        days: 30
      }, {
        name: 'May',
        days: 31
      }, {
        name: 'June',
        days: 30
      }, {
        name: 'July',
        days: 31
      }, {
        name: 'August',
        days: 31
      }, {
        name: 'September',
        days: 30
      }, {
        name: 'October',
        days: 31
      }, {
        name: 'November',
        days: 30
      }, {
        name: 'December',
        days: 31
      }].slice(0);
    }
    /**
     * Count the number of months.
     *
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonths",
    value: function countMonths() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
      return this.monthListCache[year].length;
    }
    /**
     * Count days in a month.
     *
     * @param {Number} month Month index, where January = 1, February = 2, etc.
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonthDays",
    value: function countMonthDays(month) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      return this.monthListCache[year][month - 1].days;
    }
    /**
     * Count full weeks in a month.
     *
     * @param {Number} month Month index, where January = 1, February = 2, etc.
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonthFullWeeks",
    value: function countMonthFullWeeks(month) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      return this.monthListCache[year][month - 1].fullWeeks;
    }
    /**
     * Calculate week structure within defined months.
     *
     * @private
     * @param {Number} [year] Year for the calculation.
     */

  }, {
    key: "calculateWeekStructure",
    value: function calculateWeekStructure() {
      var _this4 = this;

      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
      this.monthListCache[year] = this.calculateMonthData(year);
      var firstWeekDay = this.getFirstWeekDay();
      var monthList = this.getMonthList(year);
      var mixedMonthToAdd = [];
      var daysBeforeFullWeeksRatio = this.hideDaysBeforeFullWeeks ? 0 : 1;
      var daysAfterFullWeeksRatio = this.hideDaysAfterFullWeeks ? 0 : 1;
      var weekOffset = 0;
      var weekSectionCount = 0;

      if (firstWeekDay === 'monday') {
        weekOffset = 1;
      }

      (0, _array.arrayEach)(monthList, function (currentMonth, monthIndex) {
        var firstMonthDay = new Date(year, monthIndex, 1).getDay();
        var mixedMonthsAdded = 0;
        currentMonth.daysBeforeFullWeeks = (7 - firstMonthDay + weekOffset) % 7;

        if (!_this4.allowSplitWeeks && currentMonth.daysBeforeFullWeeks) {
          mixedMonthToAdd.push((0, _utils.getMixedMonthObject)((0, _utils.getMixedMonthName)(monthIndex, monthList), monthIndex));
          mixedMonthsAdded += 1;
        }

        currentMonth.fullWeeks = Math.floor((currentMonth.days - currentMonth.daysBeforeFullWeeks) / 7);
        currentMonth.daysAfterFullWeeks = currentMonth.days - currentMonth.daysBeforeFullWeeks - 7 * currentMonth.fullWeeks;

        if (!_this4.allowSplitWeeks) {
          if (monthIndex === monthList.length - 1 && currentMonth.daysAfterFullWeeks) {
            mixedMonthToAdd.push((0, _utils.getMixedMonthObject)((0, _utils.getMixedMonthName)(monthIndex, monthList), null));
            mixedMonthsAdded += 1;
          }

          weekSectionCount += currentMonth.fullWeeks + mixedMonthsAdded;
        } else {
          var numberOfPartialWeeksBefore = daysBeforeFullWeeksRatio * (currentMonth.daysBeforeFullWeeks ? 1 : 0);
          var numberOfPartialWeeksAfter = daysAfterFullWeeksRatio * (currentMonth.daysAfterFullWeeks ? 1 : 0);
          weekSectionCount += currentMonth.fullWeeks + numberOfPartialWeeksBefore + numberOfPartialWeeksAfter;
        }
      });
      (0, _array.arrayEach)(mixedMonthToAdd, function (monthObject, monthIndex) {
        var index = monthObject.index;
        delete monthObject.index;

        _this4.addMixedMonth(index === null ? index : monthIndex + index, monthObject, year);
      });

      if (year === this.getYear()) {
        this.weekSectionCount = weekSectionCount;
      }
    }
    /**
     * Add a mixed (e.g. 'Jan/Feb') month to the month list.
     *
     * @private
     * @param {Number} index Index for the month.
     * @param {Object} monthObject The month object.
     * @param {Number} [year] Year for the calculation.
     */

  }, {
    key: "addMixedMonth",
    value: function addMixedMonth(index, monthObject, year) {
      if (index === null) {
        this.monthListCache[year].push(monthObject);
      } else {
        this.monthListCache[year].splice(index, 0, monthObject);
      }
    }
  }]);
  return DateCalculator;
}();

var _default = DateCalculator;
exports.default = _default;

/***/ }),
/* 752 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(10);

__webpack_require__(36);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _utils = __webpack_require__(172);

/**
 * This class handles the data-related calculations for the GanttChart plugin.
 *
 * @plugin GanttChart
 */
var GanttChartDataFeed =
/*#__PURE__*/
function () {
  function GanttChartDataFeed(chartInstance, data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
    (0, _classCallCheck2.default)(this, GanttChartDataFeed);
    this.data = data;
    this.chartInstance = chartInstance;
    this.chartPlugin = this.chartInstance.getPlugin('ganttChart');
    this.hotSource = null;
    this.sourceHooks = {};
    this.ongoingAsync = false;
    this.applyData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates || false);
  }
  /**
   * Parse data accordingly to it's type (HOT instance / data object).
   *
   * @param {Object} data The source Handsontable instance or a data object.
   * @param {Number} startDateColumn Index of the column containing the start dates.
   * @param {Number} endDateColumn Index of the column containing the end dates.
   * @param {Object} additionalData Object containing column and label information about additional data passed to the Gantt Plugin.
   * @param {Boolean} asyncUpdates If set to true, the source instance updates will be applied asynchronously.
   */


  (0, _createClass2.default)(GanttChartDataFeed, [{
    key: "applyData",
    value: function applyData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
      if (Object.prototype.toString.call(data) === '[object Array]') {
        if (data.length > 1) {
          this.chartInstance.alter('insert_row', 0, data.length - 1, "".concat(this.pluginName, ".loadData"));
        }

        this.loadData(data);
      } else if (data instanceof this.chartInstance.constructor) {
        var sourceRowCount = data.countRows();

        if (sourceRowCount > 1) {
          this.chartInstance.alter('insert_row', 0, sourceRowCount - 1, "".concat(this.pluginName, ".loadData"));
        }

        this.bindWithHotInstance(data, startDateColumn, endDateColumn, additionalData, asyncUpdates);
      }
    }
    /**
     * Make another Handsontable instance be a live feed for the gantt chart.
     *
     * @param {Object} instance The source Handsontable instance.
     * @param {Number} startDateColumn Index of the column containing the start dates.
     * @param {Number} endDateColumn Index of the column containing the end dates.
     * @param {Object} additionalData Object containing column and label information about additional data passed to the
     * Gantt Plugin. See the example for more details.
     * @param {Boolean} asyncUpdates If set to true, the source instance updates will be applied asynchronously.
     *
     * @example
     * ```js
     * hot.getPlugin('ganttChart').bindWithHotInstance(sourceInstance, 4, 5, {
     *  vendor: 0, // data labeled 'vendor' is stored in the first sourceInstance column.
     *  format: 1, // data labeled 'format' is stored in the second sourceInstance column.
     *  market: 2 // data labeled 'market' is stored in the third sourceInstance column.
     * });
     * ```
     */

  }, {
    key: "bindWithHotInstance",
    value: function bindWithHotInstance(instance, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
      this.hotSource = {
        instance: instance,
        startColumn: startDateColumn,
        endColumn: endDateColumn,
        additionalData: additionalData,
        asyncUpdates: asyncUpdates
      };
      this.addSourceHotHooks();
      this.asyncCall(this.updateFromSource);
    }
    /**
     * Run the provided function asynchronously.
     *
     * @param {Function} func
     */

  }, {
    key: "asyncCall",
    value: function asyncCall(func) {
      var _this = this;

      if (!this.hotSource.asyncUpdates) {
        func.call(this);
        return;
      }

      this.asyncStart();
      setTimeout(function () {
        func.call(_this);

        _this.asyncEnd();
      }, 0);
    }
  }, {
    key: "asyncStart",
    value: function asyncStart() {
      this.ongoingAsync = true;
    }
  }, {
    key: "asyncEnd",
    value: function asyncEnd() {
      this.ongoingAsync = false;
    }
    /**
     * Add hooks to the source Handsontable instance.
     *
     * @private
     */

  }, {
    key: "addSourceHotHooks",
    value: function addSourceHotHooks() {
      var _this2 = this;

      this.sourceHooks = {
        afterLoadData: function afterLoadData() {
          return _this2.onAfterSourceLoadData();
        },
        afterChange: function afterChange(changes) {
          return _this2.onAfterSourceChange(changes);
        },
        afterColumnSort: function afterColumnSort() {
          return _this2.onAfterColumnSort();
        }
      };
      this.hotSource.instance.addHook('afterLoadData', this.sourceHooks.afterLoadData);
      this.hotSource.instance.addHook('afterChange', this.sourceHooks.afterChange);
      this.hotSource.instance.addHook('afterColumnSort', this.sourceHooks.afterColumnSort);
    }
    /**
     * Remove hooks from the source Handsontable instance.
     *
     * @private
     * @param {Object} hotSource The source Handsontable instance object.
     */

  }, {
    key: "removeSourceHotHooks",
    value: function removeSourceHotHooks(hotSource) {
      if (this.sourceHooks.afterLoadData) {
        hotSource.instance.removeHook('afterLoadData', this.sourceHooks.afterLoadData);
      }

      if (this.sourceHooks.afterChange) {
        hotSource.instance.removeHook('afterChange', this.sourceHooks.afterChange);
      }

      if (this.sourceHooks.afterColumnSort) {
        hotSource.instance.removeHook('afterColumnSort', this.sourceHooks.afterColumnSort);
      }
    }
    /**
     * Get data from the source Handsontable instance.
     *
     * @param {Number} [row] Source Handsontable instance row.
     * @returns {Array}
     */

  }, {
    key: "getDataFromSource",
    value: function getDataFromSource(row) {
      var additionalObjectData = {};
      var hotSource = this.hotSource;
      var sourceHotRows;
      var rangeBarData = [];

      if (row === void 0) {
        sourceHotRows = hotSource.instance.getData(0, 0, hotSource.instance.countRows() - 1, hotSource.instance.countCols() - 1);
      } else {
        sourceHotRows = [];
        sourceHotRows[row] = hotSource.instance.getDataAtRow(row);
      }

      var _loop = function _loop(i, dataLength) {
        additionalObjectData = {};
        var currentRow = sourceHotRows[i];

        if (currentRow[hotSource.startColumn] === null || currentRow[hotSource.startColumn] === '') {
          /* eslint-disable no-continue */
          return "continue";
        }
        /* eslint-disable no-loop-func */


        (0, _object.objectEach)(hotSource.additionalData, function (prop, j) {
          additionalObjectData[j] = currentRow[prop];
        });
        rangeBarData.push([i, currentRow[hotSource.startColumn], currentRow[hotSource.endColumn], additionalObjectData, i]);
      };

      for (var i = row || 0, dataLength = sourceHotRows.length; i < (row ? row + 1 : dataLength); i++) {
        var _ret = _loop(i, dataLength);

        if (_ret === "continue") continue;
      }

      return rangeBarData;
    }
    /**
     * Update the Gantt Chart-enabled Handsontable instance with the data from the source Handsontable instance.
     *
     * @param {Number} [row] Index of the row which needs updating.
     */

  }, {
    key: "updateFromSource",
    value: function updateFromSource(row) {
      var dataFromSource = this.getDataFromSource(row);

      if (!row && isNaN(row)) {
        this.chartPlugin.clearRangeBars();
        this.chartPlugin.clearRangeList();
      }

      this.loadData(dataFromSource);
      this.chartInstance.render();
    }
    /**
     * Load chart data to the Handsontable instance.
     *
     * @param {Array} data Array of objects containing the range data.
     *
     * @example
     * ```js
     * [
     *  {
     *    additionalData: {vendor: 'Vendor One', format: 'Posters', market: 'New York, NY'},
     *    startDate: '1/5/2015',
     *    endDate: '1/20/2015'
     *  },
     *  {
     *    additionalData: {vendor: 'Vendor Two', format: 'Malls', market: 'Los Angeles, CA'},
     *    startDate: '1/11/2015',
     *    endDate: '1/29/2015'
     *  }
     * ]
     * ```
     */

  }, {
    key: "loadData",
    value: function loadData(data) {
      var _this3 = this;

      var allBars = [];
      (0, _array.arrayEach)(data, function (bar, i) {
        bar.row = i;

        var bars = _this3.splitRangeIfNeeded(bar);

        allBars = allBars.concat(bars);
      });
      (0, _array.arrayEach)(allBars, function (bar) {
        _this3.chartPlugin.addRangeBar(bar.row, (0, _utils.getStartDate)(bar), (0, _utils.getEndDate)(bar), (0, _utils.getAdditionalData)(bar));

        delete bar.row;
      });
    }
    /**
     * Split the provided range into maximum-year-long chunks.
     *
     * @param {Object} bar The range bar object.
     * @returns {Array} An array of slip chunks (or a single-element array, if no splicing occured)
     */

  }, {
    key: "splitRangeIfNeeded",
    value: function splitRangeIfNeeded(bar) {
      var splitBars = [];
      var startDate = new Date((0, _utils.getStartDate)(bar));
      var endDate = new Date((0, _utils.getEndDate)(bar));

      if (typeof startDate === 'string' || typeof endDate === 'string') {
        return false;
      }

      var startYear = startDate.getFullYear();
      var endYear = endDate.getFullYear();

      if (startYear === endYear) {
        return [bar];
      }

      (0, _number.rangeEach)(startYear, endYear, function (year) {
        var newBar = (0, _object.clone)(bar);

        if (year !== startYear) {
          (0, _utils.setStartDate)(newBar, "01/01/".concat(year));
        }

        if (year !== endYear) {
          (0, _utils.setEndDate)(newBar, "12/31/".concat(year));
        }

        splitBars.push(newBar);
      });
      return splitBars;
    }
    /**
     * afterChange hook callback for the source Handsontable instance.
     *
     * @private
     * @param {Array} changes List of changes.
     */

  }, {
    key: "onAfterSourceChange",
    value: function onAfterSourceChange(changes) {
      var _this4 = this;

      this.asyncCall(function () {
        if (!changes) {
          return;
        }

        var changesByRows = {};

        for (var i = 0, changesLength = changes.length; i < changesLength; i++) {
          var currentChange = changes[i];
          var row = parseInt(currentChange[0], 10);
          var col = parseInt(currentChange[1], 10);

          if (!changesByRows[row]) {
            changesByRows[row] = {};
          }

          changesByRows[row][col] = [currentChange[2], currentChange[3]];
        }

        (0, _object.objectEach)(changesByRows, function (prop, i) {
          var row = parseInt(i, 10);

          if (_this4.chartPlugin.getRangeBarCoordinates(row)) {
            _this4.chartPlugin.removeRangeBarByColumn(row, _this4.chartPlugin.rangeList[row][1]);
          }

          _this4.updateFromSource(i);
        });
      });
    }
    /**
     * afterLoadData hook callback for the source Handsontable instance.
     *
     * @private
     */

  }, {
    key: "onAfterSourceLoadData",
    value: function onAfterSourceLoadData() {
      var _this5 = this;

      this.asyncCall(function () {
        _this5.chartPlugin.removeAllRangeBars();

        _this5.updateFromSource();
      });
    }
    /**
     * afterColumnSort hook callback for the source Handsontable instance.
     *
     * @private
     */

  }, {
    key: "onAfterColumnSort",
    value: function onAfterColumnSort() {
      var _this6 = this;

      this.asyncCall(function () {
        _this6.chartPlugin.removeAllRangeBars();

        _this6.updateFromSource();
      });
    }
  }]);
  return GanttChartDataFeed;
}();

var _default = GanttChartDataFeed;
exports.default = _default;

/***/ }),
/* 753 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 754 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _plugins = __webpack_require__(20);

var _number = __webpack_require__(15);

var _base = _interopRequireDefault(__webpack_require__(21));

/**
 * @plugin HeaderTooltips
 *
 * @description
 * Allows to add a tooltip to the table headers.
 *
 * Available options:
 * * the `rows` property defines if tooltips should be added to row headers,
 * * the `columns` property defines if tooltips should be added to column headers,
 * * the `onlyTrimmed` property defines if tooltips should be added only to headers, which content is trimmed by the header itself (the content being wider then the header).
 *
 * @example
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   // enable and configure header tooltips
 *   headerTooltips: {
 *     rows: true,
 *     columns: true,
 *     onlyTrimmed: false
 *   }
 * });
 * ```
 */
var HeaderTooltips =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(HeaderTooltips, _BasePlugin);

  function HeaderTooltips(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, HeaderTooltips);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HeaderTooltips).call(this, hotInstance));
    /**
     * Cached plugin settings.
     *
     * @private
     * @type {Boolean|Object}
     */

    _this.settings = null;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link HeaderTooltips#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(HeaderTooltips, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().headerTooltips;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      this.settings = this.hot.getSettings().headerTooltips;
      this.parseSettings();
      this.addHook('afterGetColHeader', function (col, TH) {
        return _this2.onAfterGetHeader(col, TH);
      });
      this.addHook('afterGetRowHeader', function (col, TH) {
        return _this2.onAfterGetHeader(col, TH);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.settings = null;
      this.clearTitleAttributes();
      (0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Parses the plugin settings.
     *
     * @private
     */

  }, {
    key: "parseSettings",
    value: function parseSettings() {
      if (typeof this.settings === 'boolean') {
        this.settings = {
          rows: true,
          columns: true,
          onlyTrimmed: false
        };
      }
    }
    /**
     * Clears the previously assigned title attributes.
     *
     * @private
     */

  }, {
    key: "clearTitleAttributes",
    value: function clearTitleAttributes() {
      var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
      var mainHeaders = this.hot.view.wt.wtTable.THEAD;
      var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
      var topLeftCornerOverlay = this.hot.view.wt.wtOverlays.topLeftCornerOverlay;
      var topLeftCornerHeaders = topLeftCornerOverlay ? topLeftCornerOverlay.clone.wtTable.THEAD : null;
      (0, _number.rangeEach)(0, headerLevels - 1, function (i) {
        var masterLevel = mainHeaders.childNodes[i];
        var topLevel = topHeaders.childNodes[i];
        var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;
        (0, _number.rangeEach)(0, masterLevel.childNodes.length - 1, function (j) {
          masterLevel.childNodes[j].removeAttribute('title');

          if (topLevel && topLevel.childNodes[j]) {
            topLevel.childNodes[j].removeAttribute('title');
          }

          if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
            topLeftCornerLevel.childNodes[j].removeAttribute('title');
          }
        });
      }, true);
    }
    /**
     * Adds a tooltip to the headers.
     *
     * @private
     * @param {Number} index
     * @param {HTMLElement} TH
     */

  }, {
    key: "onAfterGetHeader",
    value: function onAfterGetHeader(index, TH) {
      var innerSpan = TH.querySelector('span');
      var isColHeader = TH.parentNode.parentNode.nodeName === 'THEAD';

      if (isColHeader && this.settings.columns || !isColHeader && this.settings.rows) {
        if (this.settings.onlyTrimmed) {
          if ((0, _element.outerWidth)(innerSpan) >= (0, _element.outerWidth)(TH) && (0, _element.outerWidth)(innerSpan) !== 0) {
            TH.setAttribute('title', innerSpan.textContent);
          }
        } else {
          TH.setAttribute('title', innerSpan.textContent);
        }
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.settings = null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "destroy", this).call(this);
    }
  }]);
  return HeaderTooltips;
}(_base.default);

(0, _plugins.registerPlugin)('headerTooltips', HeaderTooltips);
var _default = HeaderTooltips;
exports.default = _default;

/***/ }),
/* 755 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(66));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var _object = __webpack_require__(4);

var _templateLiteralTag = __webpack_require__(67);

var _console = __webpack_require__(55);

var _plugins = __webpack_require__(20);

var _base = _interopRequireDefault(__webpack_require__(21));

var _src = __webpack_require__(25);

var _ghostTable = _interopRequireDefault(__webpack_require__(756));

__webpack_require__(757);

function _templateObject2() {
  var data = (0, _taggedTemplateLiteral2.default)(["Your Nested Headers plugin setup contains overlapping headers. This kind of configuration\n                is currently not supported and might result in glitches."]);

  _templateObject2 = function _templateObject2() {
    return data;
  };

  return data;
}

function _templateObject() {
  var data = (0, _taggedTemplateLiteral2.default)(["You have declared a Nested Header overlapping the Fixed Columns section - it may lead to visual\n          glitches. To prevent that kind of problems, split the nested headers between the fixed and non-fixed columns."]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

/**
 * @plugin NestedHeaders
 * @description
 * The plugin allows to create a nested header structure, using the HTML's colspan attribute.
 *
 * To make any header wider (covering multiple table columns), it's corresponding configuration array element should be
 * provided as an object with `label` and `colspan` properties. The `label` property defines the header's label,
 * while the `colspan` property defines a number of columns that the header should cover.
 *
 * __Note__ that the plugin supports a *nested* structure, which means, any header cannot be wider than it's "parent". In
 * other words, headers cannot overlap each other.
 * @example
 *
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   nestedHeaders: [
 *           ['A', {label: 'B', colspan: 8}, 'C'],
 *           ['D', {label: 'E', colspan: 4}, {label: 'F', colspan: 4}, 'G'],
 *           ['H', {label: 'I', colspan: 2}, {label: 'J', colspan: 2}, {label: 'K', colspan: 2}, {label: 'L', colspan: 2}, 'M'],
 *           ['N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W']
 *  ],
 * ```
 */
var NestedHeaders =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(NestedHeaders, _BasePlugin);

  function NestedHeaders(hotInstance) {
    var _this2;

    (0, _classCallCheck2.default)(this, NestedHeaders);
    _this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NestedHeaders).call(this, hotInstance));
    /**
     * Nasted headers cached settings.
     *
     * @private
     * @type {Object}
     */

    _this2.settings = [];
    /**
     * Cached number of column header levels.
     *
     * @private
     * @type {Number}
     */

    _this2.columnHeaderLevelCount = 0;
    /**
     * Array of nested headers' colspans.
     *
     * @private
     * @type {Array}
     */

    _this2.colspanArray = [];
    /**
     * Custom helper for getting widths of the nested headers.
     * @TODO This should be changed after refactor handsontable/utils/ghostTable.
     *
     * @private
     * @type {GhostTable}
     */

    _this2.ghostTable = new _ghostTable.default((0, _assertThisInitialized2.default)(_this2));
    return _this2;
  }
  /**
   * Check if plugin is enabled
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(NestedHeaders, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().nestedHeaders;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this3 = this;

      if (this.enabled) {
        return;
      }

      this.settings = this.hot.getSettings().nestedHeaders;
      this.addHook('afterGetColumnHeaderRenderers', function (array) {
        return _this3.onAfterGetColumnHeaderRenderers(array);
      });
      this.addHook('afterInit', function () {
        return _this3.onAfterInit();
      });
      this.addHook('afterOnCellMouseDown', function (event, coords) {
        return _this3.onAfterOnCellMouseDown(event, coords);
      });
      this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
        return _this3.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
      });
      this.addHook('afterViewportColumnCalculatorOverride', function (calc) {
        return _this3.onAfterViewportColumnCalculatorOverride(calc);
      });
      this.addHook('modifyColWidth', function (width, column) {
        return _this3.onModifyColWidth(width, column);
      });
      this.setupColspanArray();
      this.checkForFixedColumnsCollision();
      this.columnHeaderLevelCount = this.hot.view ? this.hot.view.wt.getSetting('columnHeaders').length : 0;
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.clearColspans();
      this.settings = [];
      this.columnHeaderLevelCount = 0;
      this.colspanArray = [];
      this.ghostTable.clear();
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "updatePlugin", this).call(this);
      this.ghostTable.buildWidthsMapper();
    }
    /**
     * Clear the colspans remaining after plugin usage.
     *
     * @private
     */

  }, {
    key: "clearColspans",
    value: function clearColspans() {
      if (!this.hot.view) {
        return;
      }

      var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
      var mainHeaders = this.hot.view.wt.wtTable.THEAD;
      var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
      var topLeftCornerHeaders = this.hot.view.wt.wtOverlays.topLeftCornerOverlay ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.THEAD : null;

      for (var i = 0; i < headerLevels; i++) {
        var masterLevel = mainHeaders.childNodes[i];

        if (!masterLevel) {
          break;
        }

        var topLevel = topHeaders.childNodes[i];
        var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;

        for (var j = 0, masterNodes = masterLevel.childNodes.length; j < masterNodes; j++) {
          masterLevel.childNodes[j].removeAttribute('colspan');

          if (topLevel && topLevel.childNodes[j]) {
            topLevel.childNodes[j].removeAttribute('colspan');
          }

          if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
            topLeftCornerLevel.childNodes[j].removeAttribute('colspan');
          }
        }
      }
    }
    /**
     * Check if the nested headers overlap the fixed columns overlay, if so - display a warning.
     *
     * @private
     */

  }, {
    key: "checkForFixedColumnsCollision",
    value: function checkForFixedColumnsCollision() {
      var _this4 = this;

      var fixedColumnsLeft = this.hot.getSettings().fixedColumnsLeft;
      (0, _array.arrayEach)(this.colspanArray, function (value, i) {
        if (_this4.getNestedParent(i, fixedColumnsLeft) !== fixedColumnsLeft) {
          (0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject()));
        }
      });
    }
    /**
     * Check if the configuration contains overlapping headers.
     *
     * @private
     */

  }, {
    key: "checkForOverlappingHeaders",
    value: function checkForOverlappingHeaders() {
      var _this5 = this;

      (0, _array.arrayEach)(this.colspanArray, function (level, i) {
        (0, _array.arrayEach)(_this5.colspanArray[i], function (header, j) {
          if (header.colspan > 1) {
            var row = _this5.levelToRowCoords(i);

            var childHeaders = _this5.getChildHeaders(row, j);

            if (childHeaders.length > 0) {
              var childColspanSum = 0;
              (0, _array.arrayEach)(childHeaders, function (col) {
                childColspanSum += _this5.getColspan(row + 1, col);
              });

              if (childColspanSum > header.colspan) {
                (0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject2()));
              }

              return false;
            }
          }
        });
      });
    }
    /**
     * Create an internal array containing information of the headers with a colspan attribute.
     *
     * @private
     */

  }, {
    key: "setupColspanArray",
    value: function setupColspanArray() {
      var _this6 = this;

      function checkIfExists(array, index) {
        if (!array[index]) {
          array[index] = [];
        }
      }

      (0, _object.objectEach)(this.settings, function (levelValues, level) {
        (0, _object.objectEach)(levelValues, function (val, col, levelValue) {
          checkIfExists(_this6.colspanArray, level);

          if (levelValue[col].colspan === void 0) {
            _this6.colspanArray[level].push({
              label: levelValue[col] || '',
              colspan: 1,
              hidden: false
            });
          } else {
            var colspan = levelValue[col].colspan || 1;

            _this6.colspanArray[level].push({
              label: levelValue[col].label || '',
              colspan: colspan,
              hidden: false
            });

            _this6.fillColspanArrayWithDummies(colspan, level);
          }
        });
      });
    }
    /**
     * Fill the "colspan array" with default data for the dummy hidden headers.
     *
     * @private
     * @param {Number} colspan The colspan value.
     * @param {Number} level Header level.
     */

  }, {
    key: "fillColspanArrayWithDummies",
    value: function fillColspanArrayWithDummies(colspan, level) {
      var _this7 = this;

      (0, _number.rangeEach)(0, colspan - 2, function () {
        _this7.colspanArray[level].push({
          label: '',
          colspan: 1,
          hidden: true
        });
      });
    }
    /**
     * Generates the appropriate header renderer for a header row.
     *
     * @private
     * @param {Number} headerRow The header row.
     * @returns {Function}
     *
     * @fires Hooks#afterGetColHeader
     */

  }, {
    key: "headerRendererFactory",
    value: function headerRendererFactory(headerRow) {
      var _this = this;

      return function (index, TH) {
        var rootDocument = _this.hot.rootDocument;
        TH.removeAttribute('colspan');
        (0, _element.removeClass)(TH, 'hiddenHeader'); // header row is the index of header row counting from the top (=> positive values)

        if (_this.colspanArray[headerRow][index] && _this.colspanArray[headerRow][index].colspan) {
          var colspan = _this.colspanArray[headerRow][index].colspan;
          var fixedColumnsLeft = _this.hot.getSettings().fixedColumnsLeft || 0;
          var _this$hot$view$wt$wtO = _this.hot.view.wt.wtOverlays,
              leftOverlay = _this$hot$view$wt$wtO.leftOverlay,
              topLeftCornerOverlay = _this$hot$view$wt$wtO.topLeftCornerOverlay;
          var isInTopLeftCornerOverlay = topLeftCornerOverlay ? topLeftCornerOverlay.clone.wtTable.THEAD.contains(TH) : false;
          var isInLeftOverlay = leftOverlay ? leftOverlay.clone.wtTable.THEAD.contains(TH) : false;

          if (colspan > 1) {
            TH.setAttribute('colspan', isInTopLeftCornerOverlay || isInLeftOverlay ? Math.min(colspan, fixedColumnsLeft - index) : colspan);
          }

          if (isInTopLeftCornerOverlay || isInLeftOverlay && index === fixedColumnsLeft - 1) {
            (0, _element.addClass)(TH, 'overlayEdge');
          }
        }

        if (_this.colspanArray[headerRow][index] && _this.colspanArray[headerRow][index].hidden) {
          (0, _element.addClass)(TH, 'hiddenHeader');
        }

        (0, _element.empty)(TH);
        var divEl = rootDocument.createElement('DIV');
        (0, _element.addClass)(divEl, 'relative');
        var spanEl = rootDocument.createElement('SPAN');
        (0, _element.addClass)(spanEl, 'colHeader');
        (0, _element.fastInnerHTML)(spanEl, _this.colspanArray[headerRow][index] ? _this.colspanArray[headerRow][index].label || '' : '');
        divEl.appendChild(spanEl);
        TH.appendChild(divEl);

        _this.hot.runHooks('afterGetColHeader', index, TH);
      };
    }
    /**
     * Returns the colspan for the provided coordinates.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {Number}
     */

  }, {
    key: "getColspan",
    value: function getColspan(row, column) {
      var header = this.colspanArray[this.rowCoordsToLevel(row)][column];
      return header ? header.colspan : 1;
    }
    /**
     * Translates the level value (header row index from the top) to the row value (negative index).
     *
     * @private
     * @param {Number} level Header level.
     * @returns {Number}
     */

  }, {
    key: "levelToRowCoords",
    value: function levelToRowCoords(level) {
      return level - this.columnHeaderLevelCount;
    }
    /**
     * Translates the row value (negative index) to the level value (header row index from the top).
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Number}
     */

  }, {
    key: "rowCoordsToLevel",
    value: function rowCoordsToLevel(row) {
      return row + this.columnHeaderLevelCount;
    }
    /**
     * Returns the column index of the "parent" nested header.
     *
     * @private
     * @param {Number} level Header level.
     * @param {Number} column Column index.
     * @returns {*}
     */

  }, {
    key: "getNestedParent",
    value: function getNestedParent(level, column) {
      if (level < 0) {
        return false;
      }

      var colspan = this.colspanArray[level][column] ? this.colspanArray[level][column].colspan : 1;
      var hidden = this.colspanArray[level][column] ? this.colspanArray[level][column].hidden : false;

      if (colspan > 1 || colspan === 1 && hidden === false) {
        return column;
      }

      var parentCol = column - 1;

      do {
        if (this.colspanArray[level][parentCol].colspan > 1) {
          break;
        }

        parentCol -= 1;
      } while (column >= 0);

      return parentCol;
    }
    /**
     * Returns (physical) indexes of headers below the header with provided coordinates.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} column Column index.
     * @returns {Number[]}
     */

  }, {
    key: "getChildHeaders",
    value: function getChildHeaders(row, column) {
      var level = this.rowCoordsToLevel(row);
      var childColspanLevel = this.colspanArray[level + 1];
      var nestedParentCol = this.getNestedParent(level, column);
      var colspan = this.colspanArray[level][column].colspan;
      var childHeaderRange = [];

      if (!childColspanLevel) {
        return childHeaderRange;
      }

      (0, _number.rangeEach)(nestedParentCol, nestedParentCol + colspan - 1, function (i) {
        if (childColspanLevel[i] && childColspanLevel[i].colspan > 1) {
          colspan -= childColspanLevel[i].colspan - 1;
        }

        if (childColspanLevel[i] && !childColspanLevel[i].hidden && childHeaderRange.indexOf(i) === -1) {
          childHeaderRange.push(i);
        }
      });
      return childHeaderRange;
    }
    /**
     * Fill the remaining colspanArray entries for the undeclared column headers.
     *
     * @private
     */

  }, {
    key: "fillTheRemainingColspans",
    value: function fillTheRemainingColspans() {
      var _this8 = this;

      (0, _object.objectEach)(this.settings, function (levelValue, level) {
        (0, _number.rangeEach)(_this8.colspanArray[level].length - 1, _this8.hot.countCols() - 1, function (col) {
          _this8.colspanArray[level].push({
            label: levelValue[col] || '',
            colspan: 1,
            hidden: false
          });
        }, true);
      });
    }
    /**
     * Updates headers highlight in nested structure.
     *
     * @private
     */

  }, {
    key: "updateHeadersHighlight",
    value: function updateHeadersHighlight() {
      var _this9 = this;

      var selection = this.hot.getSelectedLast();

      if (selection === void 0) {
        return;
      }

      var wtOverlays = this.hot.view.wt.wtOverlays;
      var selectionByHeader = this.hot.selection.isSelectedByColumnHeader();
      var from = Math.min(selection[1], selection[3]);
      var to = Math.max(selection[1], selection[3]);
      var levelLimit = selectionByHeader ? -1 : this.columnHeaderLevelCount - 1;
      var changes = [];

      var classNameModifier = function classNameModifier(className) {
        return function (TH, modifier) {
          return function () {
            return modifier(TH, className);
          };
        };
      };

      var highlightHeader = classNameModifier('ht__highlight');
      var activeHeader = classNameModifier('ht__active_highlight');
      (0, _number.rangeEach)(from, to, function (column) {
        var _loop = function _loop(level) {
          var visibleColumnIndex = _this9.getNestedParent(level, column);

          var topTH = wtOverlays.topOverlay ? wtOverlays.topOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
          var topLeftTH = wtOverlays.topLeftCornerOverlay ? wtOverlays.topLeftCornerOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
          var listTH = [topTH, topLeftTH];

          var colspanLen = _this9.getColspan(level - _this9.columnHeaderLevelCount, visibleColumnIndex);

          var isInSelection = visibleColumnIndex >= from && visibleColumnIndex + colspanLen - 1 <= to;
          (0, _array.arrayEach)(listTH, function (TH) {
            if (TH === void 0) {
              return false;
            }

            if (!selectionByHeader && level < levelLimit || selectionByHeader && !isInSelection) {
              changes.push(highlightHeader(TH, _element.removeClass));

              if (selectionByHeader) {
                changes.push(activeHeader(TH, _element.removeClass));
              }
            } else {
              changes.push(highlightHeader(TH, _element.addClass));

              if (selectionByHeader) {
                changes.push(activeHeader(TH, _element.addClass));
              }
            }
          });
        };

        for (var level = _this9.columnHeaderLevelCount - 1; level > -1; level--) {
          _loop(level);
        }
      });
      (0, _array.arrayEach)(changes, function (fn) {
        return void fn();
      });
      changes.length = 0;
    }
    /**
     * Make the renderer render the first nested column in its entirety.
     *
     * @private
     * @param {Object} calc Viewport column calculator.
     */

  }, {
    key: "onAfterViewportColumnCalculatorOverride",
    value: function onAfterViewportColumnCalculatorOverride(calc) {
      var _this10 = this;

      var newStartColumn = calc.startColumn;
      (0, _number.rangeEach)(0, Math.max(this.columnHeaderLevelCount - 1, 0), function (l) {
        var startColumnNestedParent = _this10.getNestedParent(l, calc.startColumn);

        if (startColumnNestedParent < calc.startColumn) {
          newStartColumn = Math.min(newStartColumn, startColumnNestedParent);
        }
      });
      calc.startColumn = newStartColumn;
    }
    /**
     * Select all nested headers of clicked cell.
     *
     * @private
     * @param {MouseEvent} event Mouse event.
     * @param {Object} coords Clicked cell coords.
     */

  }, {
    key: "onAfterOnCellMouseDown",
    value: function onAfterOnCellMouseDown(event, coords) {
      if (coords.row < 0) {
        var colspan = this.getColspan(coords.row, coords.col);
        var lastColIndex = coords.col + colspan - 1;

        if (colspan > 1) {
          var lastRowIndex = this.hot.countRows() - 1;
          this.hot.selection.setRangeEnd(new _src.CellCoords(lastRowIndex, lastColIndex));
        }
      }
    }
    /**
     * Make the header-selection properly select the nested headers.
     *
     * @private
     * @param {MouseEvent} event Mouse event.
     * @param {Object} coords Clicked cell coords.
     * @param {HTMLElement} TD
     */

  }, {
    key: "onBeforeOnCellMouseOver",
    value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
      if (coords.row >= 0 || coords.col < 0 || !this.hot.view.isMouseDown()) {
        return;
      }

      var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
          from = _this$hot$getSelected.from,
          to = _this$hot$getSelected.to;

      var colspan = this.getColspan(coords.row, coords.col);
      var lastColIndex = coords.col + colspan - 1;
      var changeDirection = false;

      if (from.col <= to.col) {
        if (coords.col < from.col && lastColIndex === to.col || coords.col < from.col && lastColIndex < from.col || coords.col < from.col && lastColIndex >= from.col && lastColIndex < to.col) {
          changeDirection = true;
        }
      } else if (coords.col < to.col && lastColIndex > from.col || coords.col > from.col || coords.col <= to.col && lastColIndex > from.col || coords.col > to.col && lastColIndex > from.col) {
        changeDirection = true;
      }

      if (changeDirection) {
        var _ref = [to.col, from.col];
        from.col = _ref[0];
        to.col = _ref[1];
      }

      if (colspan > 1) {
        var _this$hot;

        blockCalculations.column = true;
        blockCalculations.cell = true;
        var columnRange = [];

        if (from.col === to.col) {
          if (lastColIndex <= from.col && coords.col < from.col) {
            columnRange.push(to.col, coords.col);
          } else {
            columnRange.push(coords.col < from.col ? coords.col : from.col, lastColIndex > to.col ? lastColIndex : to.col);
          }
        }

        if (from.col < to.col) {
          columnRange.push(coords.col < from.col ? coords.col : from.col, lastColIndex);
        }

        if (from.col > to.col) {
          columnRange.push(from.col, coords.col);
        }

        (_this$hot = this.hot).selectColumns.apply(_this$hot, columnRange);
      }
    }
    /**
     * Cache column header count.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      this.columnHeaderLevelCount = this.hot.view.wt.getSetting('columnHeaders').length;
      this.fillTheRemainingColspans();
      this.checkForOverlappingHeaders();
      this.ghostTable.buildWidthsMapper();
    }
    /**
     * `afterGetColumnHeader` hook callback - prepares the header structure.
     *
     * @private
     * @param {Array} renderersArray Array of renderers.
     */

  }, {
    key: "onAfterGetColumnHeaderRenderers",
    value: function onAfterGetColumnHeaderRenderers(renderersArray) {
      if (renderersArray) {
        renderersArray.length = 0;

        for (var headersCount = this.colspanArray.length, i = headersCount - 1; i >= 0; i--) {
          renderersArray.push(this.headerRendererFactory(i));
        }

        renderersArray.reverse();
      }

      this.updateHeadersHighlight();
    }
    /**
     * `modifyColWidth` hook callback - returns width from cache, when is greater than incoming from hook.
     *
     * @private
     * @param width Width from hook.
     * @param column Visual index of an column.
     * @returns {Number}
     */

  }, {
    key: "onModifyColWidth",
    value: function onModifyColWidth(width, column) {
      var cachedWidth = this.ghostTable.widthsCache[column];
      return width > cachedWidth ? width : cachedWidth;
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.settings = null;
      this.columnHeaderLevelCount = null;
      this.colspanArray = null;
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "destroy", this).call(this);
    }
  }]);
  return NestedHeaders;
}(_base.default);

(0, _plugins.registerPlugin)('nestedHeaders', NestedHeaders);
var _default = NestedHeaders;
exports.default = _default;

/***/ }),
/* 756 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _element = __webpack_require__(5);

var _object = __webpack_require__(4);

var GhostTable =
/*#__PURE__*/
function () {
  function GhostTable(plugin) {
    (0, _classCallCheck2.default)(this, GhostTable);

    /**
     * Reference to NestedHeaders plugin.
     *
     * @type {NestedHeaders}
     */
    this.nestedHeaders = plugin;
    /**
     * Temporary element created to get minimal headers widths.
     *
     * @type {*}
     */

    this.container = void 0;
    /**
     * Cached the headers widths.
     *
     * @type {Array}
     */

    this.widthsCache = [];
  }
  /**
   * Build cache of the headers widths.
   *
   * @private
   */


  (0, _createClass2.default)(GhostTable, [{
    key: "buildWidthsMapper",
    value: function buildWidthsMapper() {
      this.container = this.nestedHeaders.hot.rootDocument.createElement('div');
      this.buildGhostTable(this.container);
      this.nestedHeaders.hot.rootElement.appendChild(this.container);
      var columns = this.container.querySelectorAll('tr:last-of-type th');
      var maxColumns = columns.length;

      for (var i = 0; i < maxColumns; i++) {
        this.widthsCache.push(columns[i].offsetWidth);
      }

      this.container.parentNode.removeChild(this.container);
      this.container = null;
      this.nestedHeaders.hot.render();
    }
    /**
     * Build temporary table for getting minimal columns widths.
     *
     * @private
     * @param {HTMLElement} container
     */

  }, {
    key: "buildGhostTable",
    value: function buildGhostTable(container) {
      var rootDocument = this.nestedHeaders.hot.rootDocument;
      var fragment = rootDocument.createDocumentFragment();
      var table = rootDocument.createElement('table');
      var lastRowColspan = false;
      var isDropdownEnabled = !!this.nestedHeaders.hot.getSettings().dropdownMenu;
      var maxRows = this.nestedHeaders.colspanArray.length;
      var maxCols = this.nestedHeaders.hot.countCols();
      var lastRowIndex = maxRows - 1;

      for (var row = 0; row < maxRows; row++) {
        var tr = rootDocument.createElement('tr');
        lastRowColspan = false;

        for (var col = 0; col < maxCols; col++) {
          var td = rootDocument.createElement('th');
          var headerObj = (0, _object.clone)(this.nestedHeaders.colspanArray[row][col]);

          if (headerObj && !headerObj.hidden) {
            if (row === lastRowIndex) {
              if (headerObj.colspan > 1) {
                lastRowColspan = true;
              }

              if (isDropdownEnabled) {
                headerObj.label += '<button class="changeType"></button>';
              }
            }

            (0, _element.fastInnerHTML)(td, headerObj.label);
            td.colSpan = headerObj.colspan;
            tr.appendChild(td);
          }
        }

        table.appendChild(tr);
      } // We have to be sure the last row contains only the single columns.


      if (lastRowColspan) {
        {
          var _tr = rootDocument.createElement('tr');

          for (var _col = 0; _col < maxCols; _col++) {
            var _td = rootDocument.createElement('th');

            _tr.appendChild(_td);
          }

          table.appendChild(_tr);
        }
      }

      fragment.appendChild(table);
      container.appendChild(fragment);
    }
    /**
     * Clear the widths cache.
     */

  }, {
    key: "clear",
    value: function clear() {
      this.container = null;
      this.widthsCache.length = 0;
    }
  }]);
  return GhostTable;
}();

var _default = GhostTable;
exports.default = _default;

/***/ }),
/* 757 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 758 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

__webpack_require__(30);

exports.__esModule = true;
exports.default = void 0;

var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _plugins = __webpack_require__(20);

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var _src = __webpack_require__(25);

var _dataManager = _interopRequireDefault(__webpack_require__(759));

var _collapsing = _interopRequireDefault(__webpack_require__(760));

var _headers = _interopRequireDefault(__webpack_require__(504));

var _contextMenu = _interopRequireDefault(__webpack_require__(761));

__webpack_require__(762);

var privatePool = new WeakMap();
/**
 * @plugin NestedRows
 * @experimental
 *
 * @description
 * Plugin responsible for displaying and operating on data sources with nested structures.
 *
 * @dependencies TrimRows BindRowsWithHeaders
 */

var NestedRows =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(NestedRows, _BasePlugin);

  function NestedRows(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, NestedRows);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NestedRows).call(this, hotInstance));
    /**
     * Source data object.
     *
     * @private
     * @type {Object}
     */

    _this.sourceData = null;
    /**
     * Reference to the Trim Rows plugin.
     *
     * @private
     * @type {Object}
     */

    _this.trimRowsPlugin = null;
    /**
     * Reference to the BindRowsWithHeaders plugin.
     *
     * @private
     * @type {Object}
     */

    _this.bindRowsWithHeadersPlugin = null;
    /**
     * Reference to the DataManager instance.
     *
     * @private
     * @type {Object}
     */

    _this.dataManager = null;
    /**
     * Reference to the HeadersUI instance.
     *
     * @private
     * @type {Object}
     */

    _this.headersUI = null;
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      changeSelection: false,
      movedToFirstChild: false,
      movedToCollapsed: false,
      skipRender: null
    });
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link NestedRows#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(NestedRows, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().nestedRows;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      this.sourceData = this.hot.getSourceData();
      this.trimRowsPlugin = this.hot.getPlugin('trimRows');
      this.manualRowMovePlugin = this.hot.getPlugin('manualRowMove');
      this.bindRowsWithHeadersPlugin = this.hot.getPlugin('bindRowsWithHeaders');
      this.dataManager = new _dataManager.default(this, this.hot, this.sourceData);
      this.collapsingUI = new _collapsing.default(this, this.hot, this.trimRowsPlugin);
      this.headersUI = new _headers.default(this, this.hot);
      this.contextMenuUI = new _contextMenu.default(this, this.hot);
      this.dataManager.rewriteCache();
      this.addHook('afterInit', function () {
        return _this2.onAfterInit.apply(_this2, arguments);
      });
      this.addHook('beforeRender', function () {
        return _this2.onBeforeRender.apply(_this2, arguments);
      });
      this.addHook('modifyRowData', function () {
        return _this2.onModifyRowData.apply(_this2, arguments);
      });
      this.addHook('modifySourceLength', function () {
        return _this2.onModifySourceLength.apply(_this2, arguments);
      });
      this.addHook('beforeDataSplice', function () {
        return _this2.onBeforeDataSplice.apply(_this2, arguments);
      });
      this.addHook('beforeDataFilter', function () {
        return _this2.onBeforeDataFilter.apply(_this2, arguments);
      });
      this.addHook('afterContextMenuDefaultOptions', function () {
        return _this2.onAfterContextMenuDefaultOptions.apply(_this2, arguments);
      });
      this.addHook('afterGetRowHeader', function () {
        return _this2.onAfterGetRowHeader.apply(_this2, arguments);
      });
      this.addHook('beforeOnCellMouseDown', function () {
        return _this2.onBeforeOnCellMouseDown.apply(_this2, arguments);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow.apply(_this2, arguments);
      });
      this.addHook('modifyRemovedAmount', function () {
        return _this2.onModifyRemovedAmount.apply(_this2, arguments);
      });
      this.addHook('beforeAddChild', function () {
        return _this2.onBeforeAddChild.apply(_this2, arguments);
      });
      this.addHook('afterAddChild', function () {
        return _this2.onAfterAddChild.apply(_this2, arguments);
      });
      this.addHook('beforeDetachChild', function () {
        return _this2.onBeforeDetachChild.apply(_this2, arguments);
      });
      this.addHook('afterDetachChild', function () {
        return _this2.onAfterDetachChild.apply(_this2, arguments);
      });
      this.addHook('modifyRowHeaderWidth', function () {
        return _this2.onModifyRowHeaderWidth.apply(_this2, arguments);
      });
      this.addHook('afterCreateRow', function () {
        return _this2.onAfterCreateRow.apply(_this2, arguments);
      });
      this.addHook('beforeRowMove', function () {
        return _this2.onBeforeRowMove.apply(_this2, arguments);
      });
      this.addHook('afterRowMove', function () {
        return _this2.onAfterRowMove.apply(_this2, arguments);
      });

      if (!this.trimRowsPlugin.isEnabled()) {
        // Workaround to prevent calling updateSetttings in the enablePlugin method, which causes many problems.
        this.trimRowsPlugin.enablePlugin();
        this.hot.getSettings().trimRows = true;
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "updatePlugin", this).call(this);
    }
    /**
     * `beforeRowMove` hook callback.
     *
     * @private
     * @param {Array} rows Array of row indexes to be moved.
     * @param {Number} target Index of the target row.
     */

  }, {
    key: "onBeforeRowMove",
    value: function onBeforeRowMove(rows, target) {
      var priv = privatePool.get(this);
      var rowsLen = rows.length;
      var translatedStartIndexes = [];
      var translatedTargetIndex = this.dataManager.translateTrimmedRow(target);
      var allowMove = true;
      var i;
      var fromParent = null;
      var toParent = null;
      var sameParent = null;

      for (i = 0; i < rowsLen; i++) {
        translatedStartIndexes.push(this.dataManager.translateTrimmedRow(rows[i]));

        if (this.dataManager.isParent(translatedStartIndexes[i])) {
          allowMove = false;
        }
      }

      if (translatedStartIndexes.indexOf(translatedTargetIndex) > -1 || !allowMove) {
        return false;
      }

      fromParent = this.dataManager.getRowParent(translatedStartIndexes[0]);
      toParent = this.dataManager.getRowParent(translatedTargetIndex);

      if (toParent === null || toParent === void 0) {
        toParent = this.dataManager.getRowParent(translatedTargetIndex - 1);
      }

      if (toParent === null || toParent === void 0) {
        toParent = this.dataManager.getDataObject(translatedTargetIndex - 1);
        priv.movedToFirstChild = true;
      }

      if (!toParent) {
        return false;
      }

      sameParent = fromParent === toParent;
      priv.movedToCollapsed = this.collapsingUI.areChildrenCollapsed(toParent);
      this.collapsingUI.collapsedRowsStash.stash();

      if (!sameParent) {
        if (Math.max.apply(Math, translatedStartIndexes) <= translatedTargetIndex) {
          this.collapsingUI.collapsedRowsStash.shiftStash(translatedStartIndexes[0], -1 * rows.length);
        } else {
          this.collapsingUI.collapsedRowsStash.shiftStash(translatedTargetIndex, rows.length);
        }
      }

      priv.changeSelection = true;

      if (translatedStartIndexes[rowsLen - 1] <= translatedTargetIndex && sameParent || priv.movedToFirstChild === true) {
        rows.reverse();
        translatedStartIndexes.reverse();

        if (priv.movedToFirstChild !== true) {
          translatedTargetIndex -= 1;
        }
      }

      for (i = 0; i < rowsLen; i++) {
        this.dataManager.moveRow(translatedStartIndexes[i], translatedTargetIndex);
      }

      var movingDown = translatedStartIndexes[translatedStartIndexes.length - 1] < translatedTargetIndex;

      if (movingDown) {
        for (i = rowsLen - 1; i >= 0; i--) {
          this.dataManager.moveCellMeta(translatedStartIndexes[i], translatedTargetIndex);
        }
      } else {
        for (i = 0; i < rowsLen; i++) {
          this.dataManager.moveCellMeta(translatedStartIndexes[i], translatedTargetIndex);
        }
      }

      if (translatedStartIndexes[rowsLen - 1] <= translatedTargetIndex && sameParent || this.dataManager.isParent(translatedTargetIndex)) {
        rows.reverse();
      }

      this.dataManager.rewriteCache();
      return false;
    }
    /**
     * `afterRowMove` hook callback.
     *
     * @private
     * @param {Array} rows Array of row indexes to be moved.
     * @param {Number} target Index of the target row.
     */

  }, {
    key: "onAfterRowMove",
    value: function onAfterRowMove(rows, target) {
      var priv = privatePool.get(this);

      if (!priv.changeSelection) {
        return;
      }

      var rowsLen = rows.length;
      var startRow = 0;
      var endRow = 0;
      var translatedTargetIndex = null;
      var selection = null;
      var lastColIndex = null;
      this.collapsingUI.collapsedRowsStash.applyStash();
      translatedTargetIndex = this.dataManager.translateTrimmedRow(target);

      if (priv.movedToFirstChild) {
        priv.movedToFirstChild = false;
        startRow = target;
        endRow = target + rowsLen - 1;

        if (target >= Math.max.apply(Math, (0, _toConsumableArray2.default)(rows))) {
          startRow -= rowsLen;
          endRow -= rowsLen;
        }
      } else if (priv.movedToCollapsed) {
        var parentObject = this.dataManager.getRowParent(translatedTargetIndex - 1);

        if (parentObject === null || parentObject === void 0) {
          parentObject = this.dataManager.getDataObject(translatedTargetIndex - 1);
        }

        var parentIndex = this.dataManager.getRowIndex(parentObject);
        startRow = parentIndex;
        endRow = startRow;
      } else if (rows[rowsLen - 1] < target) {
        endRow = target - 1;
        startRow = endRow - rowsLen + 1;
      } else {
        startRow = target;
        endRow = startRow + rowsLen - 1;
      }

      selection = this.hot.selection;
      lastColIndex = this.hot.countCols() - 1;
      selection.setRangeStart(new _src.CellCoords(startRow, 0));
      selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), true);
      priv.changeSelection = false;
    }
    /**
     * `beforeOnCellMousedown` hook callback.
     *
     * @private
     * @param {MouseEvent} event Mousedown event.
     * @param {Object} coords Cell coords.
     * @param {HTMLElement} TD clicked cell.
     */

  }, {
    key: "onBeforeOnCellMouseDown",
    value: function onBeforeOnCellMouseDown(event, coords, TD) {
      this.collapsingUI.toggleState(event, coords, TD);
    }
    /**
     * The modifyRowData hook callback.
     *
     * @private
     * @param {Number} row Visual row index.
     */

  }, {
    key: "onModifyRowData",
    value: function onModifyRowData(row) {
      return this.dataManager.getDataObject(row);
    }
    /**
     * Modify the source data length to match the length of the nested structure.
     *
     * @private
     * @returns {Number}
     */

  }, {
    key: "onModifySourceLength",
    value: function onModifySourceLength() {
      return this.dataManager.countAllRows();
    }
    /**
     * @private
     * @param {Number} index
     * @param {Number} amount
     * @param {Object} element
     * @returns {Boolean}
     */

  }, {
    key: "onBeforeDataSplice",
    value: function onBeforeDataSplice(index, amount, element) {
      this.dataManager.spliceData(index, amount, element);
      return false;
    }
    /**
     * Called before the source data filtering. Returning `false` stops the native filtering.
     *
     * @private
     * @param {Number} index
     * @param {Number} amount
     * @returns {Boolean}
     */

  }, {
    key: "onBeforeDataFilter",
    value: function onBeforeDataFilter(index, amount) {
      var realLogicRows = [];
      var startIndex = this.dataManager.translateTrimmedRow(index);
      var priv = privatePool.get(this);
      (0, _number.rangeEach)(startIndex, startIndex + amount - 1, function (i) {
        realLogicRows.push(i);
      });
      this.collapsingUI.collapsedRowsStash.stash();
      this.collapsingUI.collapsedRowsStash.trimStash(startIndex, amount);
      this.collapsingUI.collapsedRowsStash.shiftStash(startIndex, -1 * amount);
      this.dataManager.filterData(index, amount, realLogicRows);
      priv.skipRender = true;
      return false;
    }
    /**
     * `afterContextMenuDefaultOptions` hook callback.
     *
     * @private
     * @param {Object} defaultOptions
     */

  }, {
    key: "onAfterContextMenuDefaultOptions",
    value: function onAfterContextMenuDefaultOptions(defaultOptions) {
      return this.contextMenuUI.appendOptions(defaultOptions);
    }
    /**
     * `afterGetRowHeader` hook callback.
     *
     * @private
     * @param {Number} row Row index.
     * @param {HTMLElement} TH row header element.
     */

  }, {
    key: "onAfterGetRowHeader",
    value: function onAfterGetRowHeader(row, TH) {
      this.headersUI.appendLevelIndicators(row, TH);
    }
    /**
     * `modifyRowHeaderWidth` hook callback.
     *
     * @private
     * @param {Number} rowHeaderWidth The initial row header width(s).
     * @returns {Number}
     */

  }, {
    key: "onModifyRowHeaderWidth",
    value: function onModifyRowHeaderWidth(rowHeaderWidth) {
      return this.headersUI.rowHeaderWidthCache || rowHeaderWidth;
    }
    /**
     * `onAfterRemoveRow` hook callback.
     *
     * @private
     * @param {Number} index Removed row.
     * @param {Number} amount Amount of removed rows.
     * @param {Array} logicRows
     * @param {String} source Source of action.
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow(index, amount, logicRows, source) {
      var _this3 = this;

      if (source === this.pluginName) {
        return;
      }

      var priv = privatePool.get(this);
      setTimeout(function () {
        priv.skipRender = null;

        _this3.headersUI.updateRowHeaderWidth();

        _this3.collapsingUI.collapsedRowsStash.applyStash();
      }, 0);
    }
    /**
     * `modifyRemovedAmount` hook callback.
     *
     * @private
     * @param {Number} amount Initial amount.
     * @param {Number} index Index of the starting row.
     * @returns {Number} Modified amount.
     */

  }, {
    key: "onModifyRemovedAmount",
    value: function onModifyRemovedAmount(amount, index) {
      var _this4 = this;

      var lastParents = [];
      var childrenCount = 0;
      (0, _number.rangeEach)(index, index + amount - 1, function (i) {
        var isChild = false;

        var translated = _this4.collapsingUI.translateTrimmedRow(i);

        var currentDataObj = _this4.dataManager.getDataObject(translated);

        if (_this4.dataManager.hasChildren(currentDataObj)) {
          lastParents.push(currentDataObj);
          (0, _array.arrayEach)(lastParents, function (elem) {
            if (elem.__children.indexOf(currentDataObj) > -1) {
              isChild = true;
              return false;
            }
          });

          if (!isChild) {
            childrenCount += _this4.dataManager.countChildren(currentDataObj);
          }
        }

        isChild = false;
        (0, _array.arrayEach)(lastParents, function (elem) {
          if (elem.__children.indexOf(currentDataObj) > -1) {
            isChild = true;
            return false;
          }
        });

        if (isChild) {
          childrenCount -= 1;
        }
      });
      return amount + childrenCount;
    }
    /**
     * `beforeAddChild` hook callback.
     *
     * @private
     */

  }, {
    key: "onBeforeAddChild",
    value: function onBeforeAddChild() {
      this.collapsingUI.collapsedRowsStash.stash();
    }
    /**
     * `afterAddChild` hook callback.
     *
     * @private
     * @param {Object} parent Parent element.
     * @param {Object} element New child element.
     */

  }, {
    key: "onAfterAddChild",
    value: function onAfterAddChild(parent, element) {
      this.collapsingUI.collapsedRowsStash.shiftStash(this.dataManager.getRowIndex(element));
      this.collapsingUI.collapsedRowsStash.applyStash();
      this.headersUI.updateRowHeaderWidth();
    }
    /**
     * `beforeDetachChild` hook callback.
     *
     * @private
     */

  }, {
    key: "onBeforeDetachChild",
    value: function onBeforeDetachChild() {
      this.collapsingUI.collapsedRowsStash.stash();
    }
    /**
     * `afterDetachChild` hook callback.
     *
     * @private
     * @param {Object} parent Parent element.
     * @param {Object} element New child element.
     */

  }, {
    key: "onAfterDetachChild",
    value: function onAfterDetachChild(parent, element) {
      this.collapsingUI.collapsedRowsStash.shiftStash(this.dataManager.getRowIndex(element));
      this.collapsingUI.collapsedRowsStash.applyStash();
      this.headersUI.updateRowHeaderWidth();
    }
    /**
     * `afterCreateRow` hook callback.
     *
     * @private
     * @param {Number} index
     * @param {Number} amount
     * @param {String} source
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount, source) {
      if (source === this.pluginName) {
        return;
      }

      this.dataManager.rewriteCache();
    }
    /**
     * `afterInit` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterInit",
    value: function onAfterInit() {
      // Workaround to fix an issue caused by the 'bindRowsWithHeaders' plugin loading before this one.
      if (this.bindRowsWithHeadersPlugin.bindStrategy.strategy) {
        this.bindRowsWithHeadersPlugin.bindStrategy.createMap(this.hot.countSourceRows());
      }

      var deepestLevel = Math.max.apply(Math, (0, _toConsumableArray2.default)(this.dataManager.cache.levels));

      if (deepestLevel > 0) {
        this.headersUI.updateRowHeaderWidth(deepestLevel);
      }
    }
    /**
     * `beforeRender` hook callback.
     *
     * @param {Boolean} force
     * @param {Object} skipRender
     * @private
     */

  }, {
    key: "onBeforeRender",
    value: function onBeforeRender(force, skipRender) {
      var priv = privatePool.get(this);

      if (priv.skipRender) {
        skipRender.skipRender = true;
      }
    }
  }]);
  return NestedRows;
}(_base.default);

(0, _plugins.registerPlugin)('nestedRows', NestedRows);
var _default = NestedRows;
exports.default = _default;

/***/ }),
/* 759 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(40);

__webpack_require__(33);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _number = __webpack_require__(15);

var _object = __webpack_require__(4);

var _array = __webpack_require__(3);

var _recordTranslator = __webpack_require__(90);

/**
 * Class responsible for making data operations.
 *
 * @class
 * @private
 */
var DataManager =
/*#__PURE__*/
function () {
  function DataManager(nestedRowsPlugin, hotInstance, sourceData) {
    (0, _classCallCheck2.default)(this, DataManager);

    /**
     * Main Handsontable instance reference.
     *
     * @type {Object}
     */
    this.hot = hotInstance;
    /**
     * Reference to the source data object.
     *
     * @type {Object}
     */

    this.data = sourceData;
    /**
     * Reference to the NestedRows plugin.
     *
     * @type {Object}
     */

    this.plugin = nestedRowsPlugin;
    /**
     * Map of row object parents.
     *
     * @type {WeakMap}
     */

    this.parentReference = new WeakMap();
    /**
     * Nested structure cache.
     *
     * @type {Object}
     */

    this.cache = {
      levels: [],
      levelCount: 0,
      rows: [],
      nodeInfo: new WeakMap()
    };
    /**
     * A `recordTranslator` instance.
     *
     * @private
     * @type {Object}
     */

    this.recordTranslator = (0, _recordTranslator.getTranslator)(this.hot);
  }
  /**
   * Rewrite the nested structure cache.
   *
   * @private
   */


  (0, _createClass2.default)(DataManager, [{
    key: "rewriteCache",
    value: function rewriteCache() {
      var _this = this;

      this.cache = {
        levels: [],
        levelCount: 0,
        rows: [],
        nodeInfo: new WeakMap()
      };
      (0, _number.rangeEach)(0, this.data.length - 1, function (i) {
        _this.cacheNode(_this.data[i], 0, null);
      });
    }
    /**
     * Cache a data node.
     *
     * @private
     * @param {Object} node Node to cache.
     * @param {Number} level Level of the node.
     * @param {Object} parent Parent of the node.
     */

  }, {
    key: "cacheNode",
    value: function cacheNode(node, level, parent) {
      var _this2 = this;

      if (!this.cache.levels[level]) {
        this.cache.levels[level] = [];
        this.cache.levelCount += 1;
      }

      this.cache.levels[level].push(node);
      this.cache.rows.push(node);
      this.cache.nodeInfo.set(node, {
        parent: parent,
        row: this.cache.rows.length - 1,
        level: level
      });

      if (this.hasChildren(node)) {
        (0, _array.arrayEach)(node.__children, function (elem) {
          _this2.cacheNode(elem, level + 1, node);
        });
      }
    }
    /**
     * Get the date for the provided visual row number.
     *
     * @param {Number} row Row index.
     */

  }, {
    key: "getDataObject",
    value: function getDataObject(row) {
      return row === null || row === void 0 ? null : this.cache.rows[row];
    }
    /**
     * Read the row tree in search for a specific row index or row object.
     *
     * @private
     * @param {Object} parent The initial parent object.
     * @param {Number} readCount Number of read nodes.
     * @param {Number} neededIndex The row index we search for.
     * @param {Object} neededObject The row object we search for.
     * @returns {Number|Object}
     */

  }, {
    key: "readTreeNodes",
    value: function readTreeNodes(parent, readCount, neededIndex, neededObject) {
      var _this3 = this;

      var rootLevel = false;
      var readedNodesCount = readCount;

      if (isNaN(readedNodesCount) && readedNodesCount.end) {
        return readedNodesCount;
      }

      var parentObj = parent;

      if (!parentObj) {
        parentObj = {
          __children: this.data
        };
        rootLevel = true;
        readedNodesCount -= 1;
      }

      if (neededIndex !== null && neededIndex !== void 0 && readedNodesCount === neededIndex) {
        return {
          result: parentObj,
          end: true
        };
      }

      if (neededObject !== null && neededObject !== void 0 && parentObj === neededObject) {
        return {
          result: readedNodesCount,
          end: true
        };
      }

      readedNodesCount += 1;

      if (parentObj.__children) {
        (0, _array.arrayEach)(parentObj.__children, function (val) {
          _this3.parentReference.set(val, rootLevel ? null : parentObj);

          readedNodesCount = _this3.readTreeNodes(val, readedNodesCount, neededIndex, neededObject);

          if (isNaN(readedNodesCount) && readedNodesCount.end) {
            return false;
          }
        });
      }

      return readedNodesCount;
    }
    /**
     * Update the parent reference map.
     *
     * @private
     */

  }, {
    key: "updateParentReference",
    value: function updateParentReference() {
      this.readTreeNodes({
        __children: this.data
      }, 0, this.hot.countRows());
    }
    /**
     * Mock a parent node.
     *
     * @private
     * @returns {*}
     */

  }, {
    key: "mockParent",
    value: function mockParent() {
      var fakeParent = this.mockNode();
      fakeParent.__children = this.data;
      return fakeParent;
    }
    /**
     * Mock a data node.
     *
     * @private
     * @returns {{}}
     */

  }, {
    key: "mockNode",
    value: function mockNode() {
      var fakeNode = {};
      (0, _object.objectEach)(this.data[0], function (val, key) {
        fakeNode[key] = null;
      });
      return fakeNode;
    }
    /**
     * Get the row index for the provided row object.
     *
     * @param {Object} rowObj The row object.
     * @returns {Number} Row index.
     */

  }, {
    key: "getRowIndex",
    value: function getRowIndex(rowObj) {
      return rowObj === null || rowObj === void 0 ? null : this.cache.nodeInfo.get(rowObj).row;
    }
    /**
     * Get the index of the provided row index/row object within its parent.
     *
     * @param {Number|Object} row Row index / row object.
     * @returns {Number}
     */

  }, {
    key: "getRowIndexWithinParent",
    value: function getRowIndexWithinParent(row) {
      var rowObj = null;

      if (isNaN(row)) {
        rowObj = row;
      } else {
        rowObj = this.getDataObject(row);
      }

      var parent = this.getRowParent(row);

      if (parent === null || parent === void 0) {
        return this.data.indexOf(rowObj);
      }

      return parent.__children.indexOf(rowObj);
    }
    /**
     * Count all rows (including all parents and children).
     */

  }, {
    key: "countAllRows",
    value: function countAllRows() {
      var rootNodeMock = {
        __children: this.data
      };
      return this.countChildren(rootNodeMock);
    }
    /**
     * Count children of the provided parent.
     *
     * @param {Object|Number} parent Parent node.
     * @returns {Number} Children count.
     */

  }, {
    key: "countChildren",
    value: function countChildren(parent) {
      var _this4 = this;

      var rowCount = 0;
      var parentNode = parent;

      if (!isNaN(parentNode)) {
        parentNode = this.getDataObject(parentNode);
      }

      if (!parentNode || !parentNode.__children) {
        return 0;
      }

      (0, _array.arrayEach)(parentNode.__children, function (elem) {
        rowCount += 1;

        if (elem.__children) {
          rowCount += _this4.countChildren(elem);
        }
      });
      return rowCount;
    }
    /**
     * Get the parent of the row at the provided index.
     *
     * @param {Number|Object} row Row index.
     */

  }, {
    key: "getRowParent",
    value: function getRowParent(row) {
      var rowObject;

      if (isNaN(row)) {
        rowObject = row;
      } else {
        rowObject = this.getDataObject(row);
      }

      return this.getRowObjectParent(rowObject);
    }
    /**
     * Get the parent of the provided row object.
     *
     * @private
     * @param {Object} rowObject The row object (tree node).
     */

  }, {
    key: "getRowObjectParent",
    value: function getRowObjectParent(rowObject) {
      if ((0, _typeof2.default)(rowObject) !== 'object') {
        return null;
      }

      return this.cache.nodeInfo.get(rowObject).parent;
    }
    /**
     * Get the nesting level for the row with the provided row index.
     *
     * @param {Number} row Row index.
     * @returns {Number|null} Row level or null, when row doesn't exist.
     */

  }, {
    key: "getRowLevel",
    value: function getRowLevel(row) {
      var rowObject = null;

      if (isNaN(row)) {
        rowObject = row;
      } else {
        rowObject = this.getDataObject(row);
      }

      return rowObject ? this.getRowObjectLevel(rowObject) : null;
    }
    /**
     * Get the nesting level for the row with the provided row index.
     *
     * @private
     * @param {Object} rowObject Row object.
     * @returns {Number} Row level.
     */

  }, {
    key: "getRowObjectLevel",
    value: function getRowObjectLevel(rowObject) {
      return rowObject === null || rowObject === void 0 ? null : this.cache.nodeInfo.get(rowObject).level;
    }
    /**
     * Check if the provided row/row element has children.
     *
     * @param {Number|Object} row Row number or row element.
     * @returns {Boolean}
     */

  }, {
    key: "hasChildren",
    value: function hasChildren(row) {
      var rowObj = row;

      if (!isNaN(rowObj)) {
        rowObj = this.getDataObject(rowObj);
      }

      return !!(rowObj.__children && rowObj.__children.length);
    }
  }, {
    key: "isParent",
    value: function isParent(row) {
      var rowObj = row;

      if (!isNaN(rowObj)) {
        rowObj = this.getDataObject(rowObj);
      }

      return !!(0, _object.hasOwnProperty)(rowObj, '__children');
    }
    /**
     * Add a child to the provided parent. It's optional to add a row object as the "element"
     *
     * @param {Object} parent The parent row object.
     * @param {Object} [element] The element to add as a child.
     */

  }, {
    key: "addChild",
    value: function addChild(parent, element) {
      var childElement = element;
      this.hot.runHooks('beforeAddChild', parent, childElement);
      var parentIndex = null;

      if (parent) {
        parentIndex = this.getRowIndex(parent);
      }

      this.hot.runHooks('beforeCreateRow', parentIndex + this.countChildren(parent) + 1, 1);
      var functionalParent = parent;

      if (!parent) {
        functionalParent = this.mockParent();
      }

      if (!functionalParent.__children) {
        functionalParent.__children = [];
      }

      if (!childElement) {
        childElement = this.mockNode();
      }

      functionalParent.__children.push(childElement);

      this.rewriteCache();
      var newRowIndex = this.getRowIndex(childElement);
      this.hot.runHooks('afterCreateRow', newRowIndex, 1);
      this.hot.runHooks('afterAddChild', parent, childElement);
    }
    /**
     * Add a child node to the provided parent at a specified index.
     *
     * @param {Object} parent Parent node.
     * @param {Number} index Index to insert the child element at.
     * @param {Object} [element] Element (node) to insert.
     * @param {Number} [globalIndex] Global index of the inserted row.
     */

  }, {
    key: "addChildAtIndex",
    value: function addChildAtIndex(parent, index, element, globalIndex) {
      var childElement = element;
      this.hot.runHooks('beforeAddChild', parent, childElement, index);
      this.hot.runHooks('beforeCreateRow', globalIndex + 1, 1);
      var functionalParent = parent;

      if (!parent) {
        functionalParent = this.mockParent();
      }

      if (!functionalParent.__children) {
        functionalParent.__children = [];
      }

      if (!childElement) {
        childElement = this.mockNode();
      }

      functionalParent.__children.splice(index, null, childElement);

      this.rewriteCache();
      this.hot.runHooks('afterCreateRow', globalIndex + 1, 1);
      this.hot.runHooks('afterAddChild', parent, childElement, index);
    }
    /**
     * Add a sibling element at the specified index.
     *
     * @param {Number} index New element sibling's index.
     * @param {('above'|'below')} where Direction in which the sibling is to be created.
     */

  }, {
    key: "addSibling",
    value: function addSibling(index) {
      var where = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'below';
      var translatedIndex = this.translateTrimmedRow(index);
      var parent = this.getRowParent(translatedIndex);
      var indexWithinParent = this.getRowIndexWithinParent(translatedIndex);

      switch (where) {
        case 'below':
          this.addChildAtIndex(parent, indexWithinParent + 1, null, index);
          break;

        case 'above':
          this.addChildAtIndex(parent, indexWithinParent, null, index);
          break;

        default:
          break;
      }
    }
    /**
     * Detach the provided element from its parent and add it right after it.
     *
     * @param {Object|Array} elements Row object or an array of selected coordinates.
     * @param {Boolean} [forceRender=true] If true (default), it triggers render after finished.
     */

  }, {
    key: "detachFromParent",
    value: function detachFromParent(elements) {
      var _this5 = this;

      var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var element = null;
      var rowObjects = [];

      if (Array.isArray(elements)) {
        (0, _number.rangeEach)(elements[0], elements[2], function (i) {
          var translatedIndex = _this5.translateTrimmedRow(i);

          rowObjects.push(_this5.getDataObject(translatedIndex));
        });
        (0, _number.rangeEach)(0, rowObjects.length - 2, function (i) {
          _this5.detachFromParent(rowObjects[i], false);
        });
        element = rowObjects[rowObjects.length - 1];
      } else {
        element = elements;
      }

      var childRowIndex = this.getRowIndex(element);
      var indexWithinParent = this.getRowIndexWithinParent(element);
      var parent = this.getRowParent(element);
      var grandparent = this.getRowParent(parent);
      var grandparentRowIndex = this.getRowIndex(grandparent);
      var movedElementRowIndex = null;
      this.hot.runHooks('beforeDetachChild', parent, element);

      if (indexWithinParent !== null && indexWithinParent !== void 0) {
        this.hot.runHooks('beforeRemoveRow', childRowIndex, 1, [childRowIndex], this.plugin.pluginName);

        parent.__children.splice(indexWithinParent, 1);

        this.rewriteCache();
        this.hot.runHooks('afterRemoveRow', childRowIndex, 1, [childRowIndex], this.plugin.pluginName);

        if (grandparent) {
          movedElementRowIndex = grandparentRowIndex + this.countChildren(grandparent);
          this.hot.runHooks('beforeCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);

          grandparent.__children.push(element);
        } else {
          movedElementRowIndex = this.hot.countRows() + 1;
          this.hot.runHooks('beforeCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);
          this.data.push(element);
        }
      }

      this.rewriteCache();
      this.hot.runHooks('afterCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);

      if (forceRender) {
        this.hot.render();
      }

      this.hot.runHooks('afterDetachChild', parent, element);
    }
    /**
     * Filter the data by the `logicRows` array.
     *
     * @private
     * @param {Number} index Index of the first row to remove.
     * @param {Number} amount Number of elements to remove.
     * @param {Array} logicRows Array of indexes to remove.
     */

  }, {
    key: "filterData",
    value: function filterData(index, amount, logicRows) {
      var _this6 = this;

      var elementsToRemove = [];
      (0, _array.arrayEach)(logicRows, function (elem) {
        elementsToRemove.push(_this6.getDataObject(elem));
      });
      (0, _array.arrayEach)(elementsToRemove, function (elem) {
        var indexWithinParent = _this6.getRowIndexWithinParent(elem);

        var tempParent = _this6.getRowParent(elem);

        if (tempParent === null) {
          _this6.data.splice(indexWithinParent, 1);
        } else {
          tempParent.__children.splice(indexWithinParent, 1);
        }
      });
      this.rewriteCache();
    }
    /**
     * Used to splice the source data. Needed to properly modify the nested structure, which wouldn't work with the default script.
     *
     * @private
     * @param {Number} index Index of the element at the splice beginning.
     * @param {Number} amount Number of elements to be removed.
     * @param {Object} element Row to add.
     */

  }, {
    key: "spliceData",
    value: function spliceData(index, amount, element) {
      var elementIndex = this.translateTrimmedRow(index);

      if (elementIndex === null || elementIndex === void 0) {
        return;
      }

      var previousElement = this.getDataObject(elementIndex - 1);
      var newRowParent = null;
      var indexWithinParent = null;

      if (previousElement && previousElement.__children && previousElement.__children.length === 0) {
        newRowParent = previousElement;
        indexWithinParent = 0;
      } else {
        newRowParent = this.getRowParent(elementIndex);
        indexWithinParent = this.getRowIndexWithinParent(elementIndex);
      }

      if (newRowParent) {
        if (element) {
          newRowParent.__children.splice(indexWithinParent, amount, element);
        } else {
          newRowParent.__children.splice(indexWithinParent, amount);
        }
      } else if (element) {
        this.data.splice(indexWithinParent, amount, element);
      } else {
        this.data.splice(indexWithinParent, amount);
      }

      this.rewriteCache();
    }
    /**
     * Move a single row.
     *
     * @param {Number} fromIndex Index of the row to be moved.
     * @param {Number} toIndex Index of the destination.
     */

  }, {
    key: "moveRow",
    value: function moveRow(fromIndex, toIndex) {
      var targetIsParent = this.isParent(toIndex);
      var fromParent = this.getRowParent(fromIndex);
      var indexInFromParent = this.getRowIndexWithinParent(fromIndex);
      var toParent = this.getRowParent(toIndex);

      if (toParent === null || toParent === void 0) {
        toParent = this.getRowParent(toIndex - 1);
      }

      if (toParent === null || toParent === void 0) {
        toParent = this.getDataObject(toIndex - 1);
      }

      if (!toParent) {
        toParent = this.getDataObject(toIndex);
        toParent.__children = [];
      } else if (!toParent.__children) {
        toParent.__children = [];
      }

      var previousToTargetParent = this.getRowParent(toIndex - 1);
      var indexInToParent = targetIsParent ? this.countChildren(previousToTargetParent) : this.getRowIndexWithinParent(toIndex);

      var elemToMove = fromParent.__children.slice(indexInFromParent, indexInFromParent + 1);

      fromParent.__children.splice(indexInFromParent, 1);

      toParent.__children.splice(indexInToParent, 0, elemToMove[0]);
    }
    /**
     * Move the cell meta
     *
     * @private
     * @param {Number} fromIndex Index of the starting row.
     * @param {Number} toIndex Index of the ending row.
     */

  }, {
    key: "moveCellMeta",
    value: function moveCellMeta(fromIndex, toIndex) {
      var rowOfMeta = this.hot.getCellMetaAtRow(fromIndex);
      this.hot.spliceCellsMeta(toIndex, 0, rowOfMeta);
      this.hot.spliceCellsMeta(fromIndex + (fromIndex < toIndex ? 0 : 1), 1);
    }
    /**
     * Translate the row index according to the `TrimRows` plugin.
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Number}
     */

  }, {
    key: "translateTrimmedRow",
    value: function translateTrimmedRow(row) {
      if (this.plugin.collapsingUI) {
        return this.plugin.collapsingUI.translateTrimmedRow(row);
      }

      return row;
    }
  }]);
  return DataManager;
}();

var _default = DataManager;
exports.default = _default;

/***/ }),
/* 760 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(12);

__webpack_require__(40);

__webpack_require__(33);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _event = __webpack_require__(31);

var _array = __webpack_require__(3);

var _number = __webpack_require__(15);

var _element = __webpack_require__(5);

var _base = _interopRequireDefault(__webpack_require__(173));

var _headers = _interopRequireDefault(__webpack_require__(504));

/**
 * Class responsible for the UI for collapsing and expanding groups.
 *
 * @class
 * @util
 * @extends BaseUI
 */
var CollapsingUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(CollapsingUI, _BaseUI);

  function CollapsingUI(nestedRowsPlugin, hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, CollapsingUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CollapsingUI).call(this, nestedRowsPlugin, hotInstance));
    /**
     * Reference to the Trim Rows plugin.
     */

    _this.trimRowsPlugin = nestedRowsPlugin.trimRowsPlugin;
    _this.dataManager = _this.plugin.dataManager;
    _this.collapsedRows = [];
    _this.collapsedRowsStash = {
      stash: function stash() {
        _this.lastCollapsedRows = _this.collapsedRows.slice(0); // Workaround for wrong indexes being set in the trimRows plugin

        _this.expandMultipleChildren(_this.lastCollapsedRows, false);
      },
      shiftStash: function shiftStash(index) {
        var delta = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;

        var elementIndex = _this.translateTrimmedRow(index);

        (0, _array.arrayEach)(_this.lastCollapsedRows, function (elem, i) {
          if (elem > elementIndex - 1) {
            _this.lastCollapsedRows[i] = elem + delta;
          }
        });
      },
      applyStash: function applyStash() {
        // Workaround for wrong indexes being set in the trimRows plugin
        _this.hot.runHooks('skipLengthCache', 100);

        _this.collapseMultipleChildren(_this.lastCollapsedRows, true);

        _this.lastCollapsedRows = void 0;
      },
      trimStash: function trimStash(realElementIndex, amount) {
        (0, _number.rangeEach)(realElementIndex, realElementIndex + amount - 1, function (i) {
          var indexOfElement = _this.lastCollapsedRows.indexOf(i);

          if (indexOfElement > -1) {
            _this.lastCollapsedRows.splice(indexOfElement, 1);
          }
        });
      }
    };
    return _this;
  }
  /**
   * Collapse the children of the row passed as an argument.
   *
   * @param {Number|Object} row The parent row.
   * @param {Boolean} [forceRender=true] Whether to render the table after the function ends.
   */


  (0, _createClass2.default)(CollapsingUI, [{
    key: "collapseChildren",
    value: function collapseChildren(row) {
      var _this2 = this;

      var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      var rowsToCollapse = [];
      var rowObject = null;
      var rowIndex = null;
      var rowsToTrim = null;

      if (isNaN(row)) {
        rowObject = row;
        rowIndex = this.dataManager.getRowIndex(rowObject);
      } else {
        rowObject = this.dataManager.getDataObject(row);
        rowIndex = row;
      }

      if (this.dataManager.hasChildren(rowObject)) {
        (0, _array.arrayEach)(rowObject.__children, function (elem) {
          rowsToCollapse.push(_this2.dataManager.getRowIndex(elem));
        });
      }

      rowsToTrim = this.collapseRows(rowsToCollapse, true, false);

      if (doTrimming) {
        this.trimRowsPlugin.trimRows(rowsToTrim);
      }

      if (forceRender) {
        this.renderAndAdjust();
      }

      if (this.collapsedRows.indexOf(rowIndex) === -1) {
        this.collapsedRows.push(rowIndex);
      }

      return rowsToTrim;
    }
    /**
     * Collapse multiple children.
     *
     * @param {Array} rows Rows to collapse (including their children)
     * @param {Boolean} [forceRender = true] `true` if the table should be rendered after finishing the function.
     * @param {Boolean} [doTrimming = true] `true` if the table should trim the provided rows.
     */

  }, {
    key: "collapseMultipleChildren",
    value: function collapseMultipleChildren(rows) {
      var _this3 = this;

      var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      var rowsToTrim = [];
      (0, _array.arrayEach)(rows, function (elem) {
        rowsToTrim = rowsToTrim.concat(_this3.collapseChildren(elem, false, false));
      });

      if (doTrimming) {
        this.trimRowsPlugin.trimRows(rowsToTrim);
      }

      if (forceRender) {
        this.renderAndAdjust();
      }
    }
    /**
     * Collapse a single row.
     *
     * @param {Number} rowIndex Index of the row to collapse.
     * @param {Boolean} [recursive = true] `true` if it should collapse the row's children.
     */

  }, {
    key: "collapseRow",
    value: function collapseRow(rowIndex) {
      var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      this.collapseRows([rowIndex], recursive);
    }
    /**
     * Collapse multiple rows.
     *
     * @param {Array} rowIndexes Array of row indexes to collapse.
     * @param {Boolean} [recursive = true] `true` if it should collapse the rows' children.
     * @param {Boolean} [doTrimming = false] `true` if the provided rows should be collapsed.
     * @returns {Array} Rows prepared for trimming (or trimmed, if doTrimming == true)
     */

  }, {
    key: "collapseRows",
    value: function collapseRows(rowIndexes) {
      var _this4 = this;

      var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var rowsToTrim = [];
      (0, _array.arrayEach)(rowIndexes, function (elem) {
        rowsToTrim.push(elem);

        if (recursive) {
          _this4.collapseChildRows(elem, rowsToTrim);
        }
      });

      if (doTrimming) {
        this.trimRowsPlugin.trimRows(rowsToTrim);
      }

      return rowsToTrim;
    }
    /**
     * Collapse child rows of the row at the provided index.
     *
     * @param {Number} parentIndex Index of the parent node.
     * @param {Array} [rowsToTrim = []] Array of rows to trim. Defaults to an empty array.
     * @param {Boolean} [recursive] `true` if the collapsing process should be recursive.
     * @param {Boolean} [doTrimming = false] `true` if rows should be trimmed.
     */

  }, {
    key: "collapseChildRows",
    value: function collapseChildRows(parentIndex) {
      var _this5 = this;

      var rowsToTrim = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var recursive = arguments.length > 2 ? arguments[2] : undefined;
      var doTrimming = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

      if (this.dataManager.hasChildren(parentIndex)) {
        var parentObject = this.dataManager.getDataObject(parentIndex);
        (0, _array.arrayEach)(parentObject.__children, function (elem) {
          var elemIndex = _this5.dataManager.getRowIndex(elem);

          rowsToTrim.push(elemIndex);

          _this5.collapseChildRows(elemIndex, rowsToTrim);
        });
      }

      if (doTrimming) {
        this.trimRowsPlugin.trimRows(rowsToTrim);
      }
    }
    /**
     * Expand a single row.
     *
     * @param {Number} rowIndex Index of the row to expand.
     * @param {Boolean} [recursive = true] `true` if it should expand the row's children recursively.
     */

  }, {
    key: "expandRow",
    value: function expandRow(rowIndex) {
      var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      this.expandRows([rowIndex], recursive);
    }
    /**
     * Expand multiple rows.
     *
     * @param {Array} rowIndexes Array of indexes of the rows to expand.
     * @param {Boolean} [recursive = true] `true` if it should expand the rows' children recursively.
     * @param {Boolean} [doTrimming = false] `true` if rows should be untrimmed.
     * @returns {Array} Array of row indexes to be untrimmed.
     */

  }, {
    key: "expandRows",
    value: function expandRows(rowIndexes) {
      var _this6 = this;

      var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var rowsToUntrim = [];
      (0, _array.arrayEach)(rowIndexes, function (elem) {
        rowsToUntrim.push(elem);

        if (recursive) {
          _this6.expandChildRows(elem, rowsToUntrim);
        }
      });

      if (doTrimming) {
        this.trimRowsPlugin.untrimRows(rowsToUntrim);
      }

      return rowsToUntrim;
    }
    /**
     * Expand child rows of the provided index.
     *
     * @param {Number} parentIndex Index of the parent row.
     * @param {Array} [rowsToUntrim = []] Array of the rows to be untrimmed.
     * @param {Boolean} [recursive] `true` if it should expand the rows' children recursively.
     * @param {Boolean} [doTrimming = false] `true` if rows should be untrimmed.
     */

  }, {
    key: "expandChildRows",
    value: function expandChildRows(parentIndex) {
      var _this7 = this;

      var rowsToUntrim = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var recursive = arguments.length > 2 ? arguments[2] : undefined;
      var doTrimming = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

      if (this.dataManager.hasChildren(parentIndex)) {
        var parentObject = this.dataManager.getDataObject(parentIndex);
        (0, _array.arrayEach)(parentObject.__children, function (elem) {
          if (!_this7.isAnyParentCollapsed(elem)) {
            var elemIndex = _this7.dataManager.getRowIndex(elem);

            rowsToUntrim.push(elemIndex);

            _this7.expandChildRows(elemIndex, rowsToUntrim);
          }
        });
      }

      if (doTrimming) {
        this.trimRowsPlugin.untrimRows(rowsToUntrim);
      }
    }
    /**
     * Expand the children of the row passed as an argument.
     *
     * @param {Number|Object} row Parent row.
     * @param {Boolean} [forceRender=true] Whether to render the table after the function ends.
     * @param {Boolean} [doTrimming=true] If set to `true`, the trimming will be applied when the function finishes.
     */

  }, {
    key: "expandChildren",
    value: function expandChildren(row) {
      var _this8 = this;

      var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      var rowsToExpand = [];
      var rowObject = null;
      var rowIndex = null;
      var rowsToUntrim = null;

      if (isNaN(row)) {
        rowObject = row;
        rowIndex = this.dataManager.getRowIndex(row);
      } else {
        rowObject = this.dataManager.getDataObject(row);
        rowIndex = row;
      }

      this.collapsedRows.splice(this.collapsedRows.indexOf(rowIndex), 1);

      if (this.dataManager.hasChildren(rowObject)) {
        (0, _array.arrayEach)(rowObject.__children, function (elem) {
          var childIndex = _this8.dataManager.getRowIndex(elem);

          rowsToExpand.push(childIndex);
        });
      }

      rowsToUntrim = this.expandRows(rowsToExpand, true, false);

      if (doTrimming) {
        this.trimRowsPlugin.untrimRows(rowsToUntrim);
      }

      if (forceRender) {
        this.renderAndAdjust();
      }

      return rowsToUntrim;
    }
    /**
     * Expand multiple rows' children.
     *
     * @param {Array} rows Array of rows which children are about to be expanded.
     * @param {Boolean} [forceRender = true] `true` if the table should render after finishing the function.
     * @param {Boolean} [doTrimming = true] `true` if the rows should be untrimmed after finishing the function.
     */

  }, {
    key: "expandMultipleChildren",
    value: function expandMultipleChildren(rows) {
      var _this9 = this;

      var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
      var rowsToUntrim = [];
      (0, _array.arrayEach)(rows, function (elem) {
        rowsToUntrim = rowsToUntrim.concat(_this9.expandChildren(elem, false, false));
      });

      if (doTrimming) {
        this.trimRowsPlugin.untrimRows(rowsToUntrim);
      }

      if (forceRender) {
        this.renderAndAdjust();
      }
    }
    /**
     * Collapse all collapsable rows.
     */

  }, {
    key: "collapseAll",
    value: function collapseAll() {
      var _this10 = this;

      var sourceData = this.hot.getSourceData();
      var parentsToCollapse = [];
      (0, _array.arrayEach)(sourceData, function (elem) {
        if (_this10.dataManager.hasChildren(elem)) {
          parentsToCollapse.push(elem);
        }
      });
      this.collapseMultipleChildren(parentsToCollapse);
      this.renderAndAdjust();
    }
    /**
     * Expand all collapsable rows.
     */

  }, {
    key: "expandAll",
    value: function expandAll() {
      var _this11 = this;

      var sourceData = this.hot.getSourceData();
      var parentsToExpand = [];
      (0, _array.arrayEach)(sourceData, function (elem) {
        if (_this11.dataManager.hasChildren(elem)) {
          parentsToExpand.push(elem);
        }
      });
      this.expandMultipleChildren(parentsToExpand);
      this.renderAndAdjust();
    }
    /**
     * Check if all child rows are collapsed.
     *
     * @param {Number|Object} row The parent row.
     * @private
     */

  }, {
    key: "areChildrenCollapsed",
    value: function areChildrenCollapsed(row) {
      var _this12 = this;

      var rowObj = null;
      var allCollapsed = true;

      if (isNaN(row)) {
        rowObj = row;
      } else {
        rowObj = this.dataManager.getDataObject(row);
      }

      if (this.dataManager.hasChildren(rowObj)) {
        (0, _array.arrayEach)(rowObj.__children, function (elem) {
          var rowIndex = _this12.dataManager.getRowIndex(elem);

          if (!_this12.trimRowsPlugin.isTrimmed(rowIndex)) {
            allCollapsed = false;
            return false;
          }
        });
      }

      return allCollapsed;
    }
    /**
     * Check if any of the row object parents are collapsed.
     *
     * @private
     * @param {Object} rowObj Row object.
     * @returns {Boolean}
     */

  }, {
    key: "isAnyParentCollapsed",
    value: function isAnyParentCollapsed(rowObj) {
      var parent = rowObj;

      while (parent !== null) {
        parent = this.dataManager.getRowParent(parent);
        var parentIndex = this.dataManager.getRowIndex(parent);

        if (this.collapsedRows.indexOf(parentIndex) > -1) {
          return true;
        }
      }

      return false;
    }
    /**
     * Toggle collapsed state. Callback for the `beforeOnCellMousedown` hook.
     *
     * @private
     * @param {MouseEvent} event `mousedown` event
     * @param {Object} coords Coordinates of the clicked cell/header.
     */

  }, {
    key: "toggleState",
    value: function toggleState(event, coords) {
      if (coords.col >= 0) {
        return;
      }

      var row = this.translateTrimmedRow(coords.row);

      if ((0, _element.hasClass)(event.target, _headers.default.CSS_CLASSES.button)) {
        if (this.areChildrenCollapsed(row)) {
          this.expandChildren(row);
        } else {
          this.collapseChildren(row);
        }

        (0, _event.stopImmediatePropagation)(event);
      }
    }
    /**
     * Translate physical row after trimming to physical base row index.
     *
     * @private
     * @param {Number} row Row index.
     * @returns {Number} Base row index.
     */

  }, {
    key: "translateTrimmedRow",
    value: function translateTrimmedRow(row) {
      return this.trimRowsPlugin.rowsMapper.getValueByIndex(row);
    }
    /**
     * Helper function to render the table and call the `adjustElementsSize` method.
     *
     * @private
     */

  }, {
    key: "renderAndAdjust",
    value: function renderAndAdjust() {
      this.hot.render(); // Dirty workaround to prevent scroll height not adjusting to the table height. Needs refactoring in the future.

      this.hot.view.wt.wtOverlays.adjustElementsSize();
    }
  }]);
  return CollapsingUI;
}(_base.default);

var _default = CollapsingUI;
exports.default = _default;

/***/ }),
/* 761 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(16);

__webpack_require__(33);

__webpack_require__(10);

__webpack_require__(14);

__webpack_require__(24);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var C = _interopRequireWildcard(__webpack_require__(11));

var _base = _interopRequireDefault(__webpack_require__(173));

var privatePool = new WeakMap();
/**
 * Class responsible for the Context Menu entries for the Nested Rows plugin.
 *
 * @class ContextMenuUI
 * @util
 * @extends BaseUI
 */

var ContextMenuUI =
/*#__PURE__*/
function (_BaseUI) {
  (0, _inherits2.default)(ContextMenuUI, _BaseUI);

  function ContextMenuUI(nestedRowsPlugin, hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, ContextMenuUI);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ContextMenuUI).call(this, nestedRowsPlugin, hotInstance));
    privatePool.set((0, _assertThisInitialized2.default)(_this), {
      row_above: function row_above(key, selection) {
        _this.dataManager.addSibling(selection.start.row, 'above');
      },
      row_below: function row_below(key, selection) {
        _this.dataManager.addSibling(selection.start.row, 'below');
      }
    });
    /**
     * Reference to the DataManager instance connected with the Nested Rows plugin.
     *
     * @type {DataManager}
     */

    _this.dataManager = _this.plugin.dataManager;
    return _this;
  }
  /**
   * Append options to the context menu. (Propagated from the `afterContextMenuDefaultOptions` hook callback)
   * f
   * @private
   * @param {Object} defaultOptions Default context menu options.
   * @returns {*}
   */


  (0, _createClass2.default)(ContextMenuUI, [{
    key: "appendOptions",
    value: function appendOptions(defaultOptions) {
      var _this2 = this;

      var newEntries = [{
        key: 'add_child',
        name: function name() {
          return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD);
        },
        callback: function callback() {
          var translatedRowIndex = _this2.dataManager.translateTrimmedRow(_this2.hot.getSelectedLast()[0]);

          var parent = _this2.dataManager.getDataObject(translatedRowIndex);

          _this2.dataManager.addChild(parent);
        },
        disabled: function disabled() {
          var selected = _this2.hot.getSelectedLast();

          return !selected || selected[0] < 0 || _this2.hot.selection.isSelectedByColumnHeader() || _this2.hot.countRows() >= _this2.hot.getSettings().maxRows;
        }
      }, {
        key: 'detach_from_parent',
        name: function name() {
          return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD);
        },
        callback: function callback() {
          _this2.dataManager.detachFromParent(_this2.hot.getSelectedLast());
        },
        disabled: function disabled() {
          var selected = _this2.hot.getSelectedLast();

          var translatedRowIndex = _this2.dataManager.translateTrimmedRow(selected[0]);

          var parent = _this2.dataManager.getRowParent(translatedRowIndex);

          return !parent || !selected || selected[0] < 0 || _this2.hot.selection.isSelectedByColumnHeader() || _this2.hot.countRows() >= _this2.hot.getSettings().maxRows;
        }
      }, {
        name: '---------'
      }];
      (0, _number.rangeEach)(0, defaultOptions.items.length - 1, function (i) {
        if (i === 0) {
          (0, _array.arrayEach)(newEntries, function (val, j) {
            defaultOptions.items.splice(i + j, 0, val);
          });
          return false;
        }
      });
      return this.modifyRowInsertingOptions(defaultOptions);
    }
    /**
     * Modify how the row inserting options work.
     *
     * @private
     * @param {Object} defaultOptions Default context menu items.
     * @returns {*}
     */

  }, {
    key: "modifyRowInsertingOptions",
    value: function modifyRowInsertingOptions(defaultOptions) {
      var priv = privatePool.get(this);
      (0, _number.rangeEach)(0, defaultOptions.items.length - 1, function (i) {
        var option = priv[defaultOptions.items[i].key];

        if (option !== null && option !== void 0) {
          defaultOptions.items[i].callback = option;
        }
      });
      return defaultOptions;
    }
  }]);
  return ContextMenuUI;
}(_base.default);

var _default = ContextMenuUI;
exports.default = _default;

/***/ }),
/* 762 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 763 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(54);

__webpack_require__(33);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(46);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var _plugins = __webpack_require__(20);

var _predefinedItems = __webpack_require__(83);

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _hideColumn = _interopRequireDefault(__webpack_require__(764));

var _showColumn = _interopRequireDefault(__webpack_require__(765));

__webpack_require__(766);

_pluginHooks.default.getSingleton().register('beforeHideColumns');

_pluginHooks.default.getSingleton().register('afterHideColumns');

_pluginHooks.default.getSingleton().register('beforeUnhideColumns');

_pluginHooks.default.getSingleton().register('afterUnhideColumns');
/**
 * @plugin HiddenColumns
 *
 * @description
 * Plugin allows to hide certain columns. The hiding is achieved by rendering the columns with width set as 0px.
 * The plugin not modifies the source data and do not participate in data transformation (the shape of data returned
 * by `getData*` methods stays intact).
 *
 * Possible plugin settings:
 *  * `copyPasteEnabled` as `Boolean` (default `true`)
 *  * `columns` as `Array`
 *  * `indicators` as `Boolean` (default `false`)
 *
 * @example
 *
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   hiddenColumns: {
 *     copyPasteEnabled: true,
 *     indicators: true,
 *     columns: [1, 2, 5]
 *   }
 * });
 *
 * // access to hiddenColumns plugin instance:
 * const hiddenColumnsPlugin = hot.getPlugin('hiddenColumns');
 *
 * // show single row
 * hiddenColumnsPlugin.showColumn(1);
 *
 * // show multiple columns
 * hiddenColumnsPlugin.showColumn(1, 2, 9);
 *
 * // or as an array
 * hiddenColumnsPlugin.showColumns([1, 2, 9]);
 *
 * // hide single row
 * hiddenColumnsPlugin.hideColumn(1);
 *
 * // hide multiple columns
 * hiddenColumnsPlugin.hideColumn(1, 2, 9);
 *
 * // or as an array
 * hiddenColumnsPlugin.hideColumns([1, 2, 9]);
 *
 * // rerender the table to see all changes
 * hot.render();
 * ```
 */


var HiddenColumns =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(HiddenColumns, _BasePlugin);

  function HiddenColumns(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, HiddenColumns);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HiddenColumns).call(this, hotInstance));
    /**
     * Cached plugin settings.
     *
     * @private
     * @type {Object}
     */

    _this.settings = {};
    /**
     * List of currently hidden columns
     *
     * @private
     * @type {Number[]}
     */

    _this.hiddenColumns = [];
    /**
     * Last selected column index.
     *
     * @private
     * @type {Number}
     * @default -1
     */

    _this.lastSelectedColumn = -1;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link HiddenColumns#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(HiddenColumns, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().hiddenColumns;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      if (this.hot.hasColHeaders()) {
        this.addHook('afterGetColHeader', function (col, TH) {
          return _this2.onAfterGetColHeader(col, TH);
        });
      } else {
        this.addHook('afterRenderer', function (TD, row, col) {
          return _this2.onAfterGetColHeader(col, TD);
        });
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.onAfterContextMenuDefaultOptions(options);
      });
      this.addHook('afterGetCellMeta', function (row, col, cellProperties) {
        return _this2.onAfterGetCellMeta(row, col, cellProperties);
      });
      this.addHook('modifyColWidth', function (width, col) {
        return _this2.onModifyColWidth(width, col);
      });
      this.addHook('beforeSetRangeStartOnly', function (coords) {
        return _this2.onBeforeSetRangeStart(coords);
      });
      this.addHook('beforeSetRangeEnd', function (coords) {
        return _this2.onBeforeSetRangeEnd(coords);
      });
      this.addHook('hiddenColumn', function (column) {
        return _this2.isHidden(column);
      });
      this.addHook('beforeStretchingColumnWidth', function (width, column) {
        return _this2.onBeforeStretchingColumnWidth(width, column);
      });
      this.addHook('afterCreateCol', function (index, amount) {
        return _this2.onAfterCreateCol(index, amount);
      });
      this.addHook('afterRemoveCol', function (index, amount) {
        return _this2.onAfterRemoveCol(index, amount);
      });
      this.addHook('init', function () {
        return _this2.onInit();
      }); // Dirty workaround - the section below runs only if the HOT instance is already prepared.

      if (this.hot.view) {
        this.onInit();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.settings = {};
      this.hiddenColumns = [];
      this.lastSelectedColumn = -1;
      this.hot.render();
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "disablePlugin", this).call(this);
      this.resetCellsMeta();
    }
    /**
     * Shows the provided columns.
     *
     * @param {Number[]} columns Array of column indexes.
     */

  }, {
    key: "showColumns",
    value: function showColumns(columns) {
      var currentHideConfig = this.hiddenColumns;
      var validColumns = this.isColumnDataValid(columns);
      var destinationHideConfig = currentHideConfig;

      if (validColumns) {
        destinationHideConfig = this.hiddenColumns.filter(function (hiddenColumn) {
          return columns.includes(hiddenColumn) === false;
        });
      }

      var continueHiding = this.hot.runHooks('beforeUnhideColumns', currentHideConfig, destinationHideConfig, validColumns);

      if (continueHiding === false) {
        return;
      }

      if (validColumns) {
        this.hiddenColumns = destinationHideConfig;
      }

      this.hot.runHooks('afterUnhideColumns', currentHideConfig, destinationHideConfig, validColumns, validColumns && destinationHideConfig.length < currentHideConfig.length);
    }
    /**
     * Shows a single column.
     *
     * @param {...Number} column Visual column index.
     */

  }, {
    key: "showColumn",
    value: function showColumn() {
      for (var _len = arguments.length, column = new Array(_len), _key = 0; _key < _len; _key++) {
        column[_key] = arguments[_key];
      }

      this.showColumns(column);
    }
    /**
     * Hides the columns provided in the array.
     *
     * @param {Number[]} columns Array of visual column indexes.
     */

  }, {
    key: "hideColumns",
    value: function hideColumns(columns) {
      var currentHideConfig = this.hiddenColumns;
      var validColumns = this.isColumnDataValid(columns);
      var destinationHideConfig = currentHideConfig;

      if (validColumns) {
        destinationHideConfig = Array.from(new Set(currentHideConfig.concat(columns)));
      }

      var continueHiding = this.hot.runHooks('beforeHideColumns', currentHideConfig, destinationHideConfig, validColumns);

      if (continueHiding === false) {
        return;
      }

      if (validColumns) {
        this.hiddenColumns = destinationHideConfig;
      }

      this.hot.runHooks('afterHideColumns', currentHideConfig, destinationHideConfig, validColumns, validColumns && destinationHideConfig.length > currentHideConfig.length);
    }
    /**
     * Hides a single column.
     *
     * @param {...Number} column Visual column index.
     */

  }, {
    key: "hideColumn",
    value: function hideColumn() {
      for (var _len2 = arguments.length, column = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        column[_key2] = arguments[_key2];
      }

      this.hideColumns(column);
    }
    /**
     * Checks if the provided column is hidden.
     *
     * @param {Number} column Column index.
     * @param {Boolean} isPhysicalIndex flag which determines type of index.
     * @returns {Boolean}
     */

  }, {
    key: "isHidden",
    value: function isHidden(column) {
      var isPhysicalIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var physicalColumn = column;

      if (!isPhysicalIndex) {
        physicalColumn = this.hot.toPhysicalColumn(column);
      }

      return this.hiddenColumns.includes(physicalColumn);
    }
    /**
     * Check whether all of the provided column indexes are within the bounds of the table.
     *
     * @param {Array} columns Array of column indexes.
     */

  }, {
    key: "isColumnDataValid",
    value: function isColumnDataValid(columns) {
      var _this3 = this;

      return columns.every(function (column) {
        return Number.isInteger(column) && column >= 0 && column < _this3.hot.countCols();
      });
    }
    /**
     * Reset all rendered cells meta.
     *
     * @private
     */

  }, {
    key: "resetCellsMeta",
    value: function resetCellsMeta() {
      (0, _array.arrayEach)(this.hot.getCellsMeta(), function (meta) {
        if (meta) {
          meta.skipColumnOnPaste = false;

          if (meta.baseRenderer !== null) {
            meta.renderer = meta.baseRenderer;
            meta.baseRenderer = null;
          }
        }
      });
    }
    /**
     * Sets width hidden columns on 0
     *
     * @private
     * @param {Number} width Column width.
     * @param {Number} column Column index.
     * @returns {Number}
     */

  }, {
    key: "onBeforeStretchingColumnWidth",
    value: function onBeforeStretchingColumnWidth(width, column) {
      var stretchedWidth = width;

      if (this.isHidden(column)) {
        stretchedWidth = 0;
      }

      return stretchedWidth;
    }
    /**
     * Adds the additional column width for the hidden column indicators.
     *
     * @private
     * @param {Number} width
     * @param {Number} col
     * @returns {Number}
     */

  }, {
    key: "onModifyColWidth",
    value: function onModifyColWidth(width, col) {
      if (this.isHidden(col)) {
        return 0.1;
      } else if (this.settings.indicators && (this.isHidden(col + 1) || this.isHidden(col - 1))) {
        // add additional space for hidden column indicator
        return width + (this.hot.hasColHeaders() ? 15 : 0);
      }
    }
    /**
     * Sets the copy-related cell meta.
     *
     * @private
     * @param {Number} row
     * @param {Number} col
     * @param {Object} cellProperties
     *
     * @fires Hooks#unmodifyCol
     */

  }, {
    key: "onAfterGetCellMeta",
    value: function onAfterGetCellMeta(row, col, cellProperties) {
      var colIndex = this.hot.runHooks('unmodifyCol', col);

      if (this.settings.copyPasteEnabled === false && this.isHidden(col)) {
        cellProperties.skipColumnOnPaste = true;
      }

      if (this.isHidden(colIndex)) {
        if (cellProperties.renderer !== hiddenRenderer) {
          cellProperties.baseRenderer = cellProperties.renderer;
        }

        cellProperties.renderer = hiddenRenderer;
      } else if (cellProperties.baseRenderer !== null) {
        // We must pass undefined value too (for the purposes of inheritance cell/column settings).
        cellProperties.renderer = cellProperties.baseRenderer;
        cellProperties.baseRenderer = null;
      }

      if (this.isHidden(cellProperties.visualCol - 1)) {
        var firstSectionHidden = true;
        var i = cellProperties.visualCol - 1;
        cellProperties.className = cellProperties.className || '';

        if (cellProperties.className.indexOf('afterHiddenColumn') === -1) {
          cellProperties.className += ' afterHiddenColumn';
        }

        do {
          if (!this.isHidden(i)) {
            firstSectionHidden = false;
            break;
          }

          i -= 1;
        } while (i >= 0);

        if (firstSectionHidden && cellProperties.className.indexOf('firstVisibleColumn') === -1) {
          cellProperties.className += ' firstVisibleColumn';
        }
      } else if (cellProperties.className) {
        var classArr = cellProperties.className.split(' ');

        if (classArr.length) {
          var containAfterHiddenColumn = classArr.indexOf('afterHiddenColumn');

          if (containAfterHiddenColumn > -1) {
            classArr.splice(containAfterHiddenColumn, 1);
          }

          var containFirstVisible = classArr.indexOf('firstVisibleColumn');

          if (containFirstVisible > -1) {
            classArr.splice(containFirstVisible, 1);
          }

          cellProperties.className = classArr.join(' ');
        }
      }
    }
    /**
     * Modifies the copyable range, accordingly to the provided config.
     *
     * @private
     * @param {Array} ranges
     * @returns {Array}
     */

  }, {
    key: "onModifyCopyableRange",
    value: function onModifyCopyableRange(ranges) {
      var _this4 = this;

      var newRanges = [];

      var pushRange = function pushRange(startRow, endRow, startCol, endCol) {
        newRanges.push({
          startRow: startRow,
          endRow: endRow,
          startCol: startCol,
          endCol: endCol
        });
      };

      (0, _array.arrayEach)(ranges, function (range) {
        var isHidden = true;
        var rangeStart = 0;
        (0, _number.rangeEach)(range.startCol, range.endCol, function (col) {
          if (_this4.isHidden(col)) {
            if (!isHidden) {
              pushRange(range.startRow, range.endRow, rangeStart, col - 1);
            }

            isHidden = true;
          } else {
            if (isHidden) {
              rangeStart = col;
            }

            if (col === range.endCol) {
              pushRange(range.startRow, range.endRow, rangeStart, col);
            }

            isHidden = false;
          }
        });
      });
      return newRanges;
    }
    /**
     * Adds the needed classes to the headers.
     *
     * @private
     * @param {Number} column
     * @param {HTMLElement} TH
     */

  }, {
    key: "onAfterGetColHeader",
    value: function onAfterGetColHeader(column, TH) {
      if (this.isHidden(column)) {
        return;
      }

      var firstSectionHidden = true;
      var i = column - 1;

      do {
        if (!this.isHidden(i)) {
          firstSectionHidden = false;
          break;
        }

        i -= 1;
      } while (i >= 0);

      if (firstSectionHidden) {
        (0, _element.addClass)(TH, 'firstVisibleColumn');
      }

      if (!this.settings.indicators) {
        return;
      }

      if (this.isHidden(column - 1)) {
        (0, _element.addClass)(TH, 'afterHiddenColumn');
      }

      if (this.isHidden(column + 1) && column > -1) {
        (0, _element.addClass)(TH, 'beforeHiddenColumn');
      }
    }
    /**
     * On before set range start listener.
     *
     * @private
     * @param {Object} coords Object with `row` and `col` properties.
     */

  }, {
    key: "onBeforeSetRangeStart",
    value: function onBeforeSetRangeStart(coords) {
      var _this5 = this;

      if (coords.col > 0) {
        return;
      }

      coords.col = 0;

      var getNextColumn = function getNextColumn(col) {
        var visualColumn = col;

        var physicalColumn = _this5.hot.toPhysicalColumn(visualColumn);

        if (_this5.isHidden(physicalColumn, true)) {
          visualColumn += 1;
          visualColumn = getNextColumn(visualColumn);
        }

        return visualColumn;
      };

      coords.col = getNextColumn(coords.col);
    }
    /**
     * On before set range end listener.
     *
     * @private
     * @param {Object} coords Object with `row` and `col` properties.
     */

  }, {
    key: "onBeforeSetRangeEnd",
    value: function onBeforeSetRangeEnd(coords) {
      var _this6 = this;

      var columnCount = this.hot.countCols();

      var getNextColumn = function getNextColumn(col) {
        var visualColumn = col;

        var physicalColumn = _this6.hot.toPhysicalColumn(visualColumn);

        if (_this6.isHidden(physicalColumn, true)) {
          if (_this6.lastSelectedColumn > visualColumn || coords.col === columnCount - 1) {
            if (visualColumn > 0) {
              visualColumn -= 1;
              visualColumn = getNextColumn(visualColumn);
            } else {
              (0, _number.rangeEach)(0, _this6.lastSelectedColumn, function (i) {
                if (!_this6.isHidden(i)) {
                  visualColumn = i;
                  return false;
                }
              });
            }
          } else {
            visualColumn += 1;
            visualColumn = getNextColumn(visualColumn);
          }
        }

        return visualColumn;
      };

      coords.col = getNextColumn(coords.col);
      this.lastSelectedColumn = coords.col;
    }
    /**
     * Add Show-hide columns to context menu.
     *
     * @private
     * @param {Object} options
     */

  }, {
    key: "onAfterContextMenuDefaultOptions",
    value: function onAfterContextMenuDefaultOptions(options) {
      options.items.push({
        name: _predefinedItems.SEPARATOR
      }, (0, _hideColumn.default)(this), (0, _showColumn.default)(this));
    }
    /**
     * `onAfterCreateCol` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterCreateCol",
    value: function onAfterCreateCol(index, amount) {
      var tempHidden = [];
      (0, _array.arrayEach)(this.hiddenColumns, function (col) {
        var visualColumn = col;

        if (visualColumn >= index) {
          visualColumn += amount;
        }

        tempHidden.push(visualColumn);
      });
      this.hiddenColumns = tempHidden;
    }
    /**
     * `onAfterRemoveCol` hook callback.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveCol",
    value: function onAfterRemoveCol(index, amount) {
      var tempHidden = [];
      (0, _array.arrayEach)(this.hiddenColumns, function (col) {
        var visualColumn = col;

        if (visualColumn >= index) {
          visualColumn -= amount;
        }

        tempHidden.push(visualColumn);
      });
      this.hiddenColumns = tempHidden;
    }
    /**
     * `afterPluginsInitialized` hook callback.
     *
     * @private
     */

  }, {
    key: "onInit",
    value: function onInit() {
      var _this7 = this;

      var settings = this.hot.getSettings().hiddenColumns;

      if ((0, _typeof2.default)(settings) === 'object') {
        this.settings = settings;

        if (settings.copyPasteEnabled === void 0) {
          settings.copyPasteEnabled = true;
        }

        if (Array.isArray(settings.columns)) {
          this.hideColumns(settings.columns);
        }

        if (!settings.copyPasteEnabled) {
          this.addHook('modifyCopyableRange', function (ranges) {
            return _this7.onModifyCopyableRange(ranges);
          });
        }
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "destroy", this).call(this);
    }
  }]);
  return HiddenColumns;
}(_base.default);

function hiddenRenderer(hotInstance, td) {
  td.textContent = '';
}

(0, _plugins.registerPlugin)('hiddenColumns', HiddenColumns);
var _default = HiddenColumns;
exports.default = _default;

/***/ }),
/* 764 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = hideColumnItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _number = __webpack_require__(15);

var C = _interopRequireWildcard(__webpack_require__(11));

function hideColumnItem(hiddenColumnsPlugin) {
  return {
    key: 'hidden_columns_hide',
    name: function name() {
      var selection = this.getSelectedLast();
      var pluralForm = 0;

      if (Array.isArray(selection)) {
        var _selection = (0, _slicedToArray2.default)(selection, 4),
            fromColumn = _selection[1],
            toColumn = _selection[3];

        if (fromColumn - toColumn !== 0) {
          pluralForm = 1;
        }
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_HIDE_COLUMN, pluralForm);
    },
    callback: function callback() {
      var _this$getSelectedRang = this.getSelectedRangeLast(),
          from = _this$getSelectedRang.from,
          to = _this$getSelectedRang.to;

      var start = Math.min(from.col, to.col);
      var end = Math.max(from.col, to.col);
      (0, _number.rangeEach)(start, end, function (column) {
        return hiddenColumnsPlugin.hideColumn(column);
      });
      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    disabled: false,
    hidden: function hidden() {
      return !this.selection.isSelectedByColumnHeader();
    }
  };
}

/***/ }),
/* 765 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = showColumnItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _number = __webpack_require__(15);

var C = _interopRequireWildcard(__webpack_require__(11));

function showColumnItem(hiddenColumnsPlugin) {
  var beforeHiddenColumns = [];
  var afterHiddenColumns = [];
  return {
    key: 'hidden_columns_show',
    name: function name() {
      var selection = this.getSelectedLast();
      var pluralForm = 0;

      if (Array.isArray(selection)) {
        var _selection = (0, _slicedToArray2.default)(selection, 4),
            fromColumn = _selection[1],
            toColumn = _selection[3];

        if (fromColumn > toColumn) {
          var _ref = [toColumn, fromColumn];
          fromColumn = _ref[0];
          toColumn = _ref[1];
        }

        var hiddenColumns = 0;

        if (fromColumn === toColumn) {
          hiddenColumns = beforeHiddenColumns.length + afterHiddenColumns.length;
        } else {
          (0, _number.rangeEach)(fromColumn, toColumn, function (column) {
            if (hiddenColumnsPlugin.isHidden(column)) {
              hiddenColumns += 1;
            }
          });
        }

        pluralForm = hiddenColumns <= 1 ? 0 : 1;
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_SHOW_COLUMN, pluralForm);
    },
    callback: function callback() {
      var _this$getSelectedRang = this.getSelectedRangeLast(),
          from = _this$getSelectedRang.from,
          to = _this$getSelectedRang.to;

      var start = Math.min(from.col, to.col);
      var end = Math.max(from.col, to.col);

      if (start === end) {
        if (beforeHiddenColumns.length === start) {
          hiddenColumnsPlugin.showColumns(beforeHiddenColumns);
          beforeHiddenColumns.length = 0;
        }

        if (afterHiddenColumns.length === this.countSourceCols() - (start + 1)) {
          hiddenColumnsPlugin.showColumns(afterHiddenColumns);
          afterHiddenColumns.length = 0;
        }
      } else {
        (0, _number.rangeEach)(start, end, function (column) {
          return hiddenColumnsPlugin.showColumn(column);
        });
      }

      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    disabled: false,
    hidden: function hidden() {
      if (!hiddenColumnsPlugin.hiddenColumns.length || !this.selection.isSelectedByColumnHeader()) {
        return true;
      }

      beforeHiddenColumns.length = 0;
      afterHiddenColumns.length = 0;

      var _this$getSelectedRang2 = this.getSelectedRangeLast(),
          from = _this$getSelectedRang2.from,
          to = _this$getSelectedRang2.to;

      var start = Math.min(from.col, to.col);
      var end = Math.max(from.col, to.col);
      var hiddenInSelection = false;

      if (start === end) {
        var totalColumnLength = this.countSourceCols();
        (0, _number.rangeEach)(0, totalColumnLength, function (column) {
          var partedHiddenLength = beforeHiddenColumns.length + afterHiddenColumns.length;

          if (partedHiddenLength === hiddenColumnsPlugin.hiddenColumns.length) {
            return false;
          }

          if (column < start && hiddenColumnsPlugin.isHidden(column)) {
            beforeHiddenColumns.push(column);
          } else if (hiddenColumnsPlugin.isHidden(column)) {
            afterHiddenColumns.push(column);
          }
        });
        totalColumnLength -= 1;

        if (beforeHiddenColumns.length === start && start > 0 || afterHiddenColumns.length === totalColumnLength - start && start < totalColumnLength) {
          hiddenInSelection = true;
        }
      } else {
        (0, _number.rangeEach)(start, end, function (column) {
          if (hiddenColumnsPlugin.isHidden(column)) {
            hiddenInSelection = true;
            return false;
          }
        });
      }

      return !hiddenInSelection;
    }
  };
}

/***/ }),
/* 766 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 767 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(12);

__webpack_require__(16);

__webpack_require__(54);

__webpack_require__(33);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(46);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _typeof2 = _interopRequireDefault(__webpack_require__(44));

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _element = __webpack_require__(5);

var _number = __webpack_require__(15);

var _array = __webpack_require__(3);

var _plugins = __webpack_require__(20);

var _pluginHooks = _interopRequireDefault(__webpack_require__(43));

var _hideRow = _interopRequireDefault(__webpack_require__(768));

var _showRow = _interopRequireDefault(__webpack_require__(769));

__webpack_require__(770);

_pluginHooks.default.getSingleton().register('beforeHideRows');

_pluginHooks.default.getSingleton().register('afterHideRows');

_pluginHooks.default.getSingleton().register('beforeUnhideRows');

_pluginHooks.default.getSingleton().register('afterUnhideRows');
/**
 * @plugin HiddenRows
 *
 * @description
 * Plugin allows to hide certain rows. The hiding is achieved by rendering the rows with height set as 0px.
 * The plugin not modifies the source data and do not participate in data transformation (the shape of data returned
 * by `getData*` methods stays intact).
 *
 * Possible plugin settings:
 *  * `copyPasteEnabled` as `Boolean` (default `true`)
 *  * `rows` as `Array`
 *  * `indicators` as `Boolean` (default `false`)
 *
 * @example
 *
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   hiddenRows: {
 *     copyPasteEnabled: true,
 *     indicators: true,
 *     rows: [1, 2, 5]
 *   }
 * });
 *
 * // access to hiddenRows plugin instance
 * const hiddenRowsPlugin = hot.getPlugin('hiddenRows');
 *
 * // show single row
 * hiddenRowsPlugin.showRow(1);
 *
 * // show multiple rows
 * hiddenRowsPlugin.showRow(1, 2, 9);
 *
 * // or as an array
 * hiddenRowsPlugin.showRows([1, 2, 9]);
 *
 * // hide single row
 * hiddenRowsPlugin.hideRow(1);
 *
 * // hide multiple rows
 * hiddenRowsPlugin.hideRow(1, 2, 9);
 *
 * // or as an array
 * hiddenRowsPlugin.hideRows([1, 2, 9]);
 *
 * // rerender the table to see all changes
 * hot.render();
 * ```
 */


var HiddenRows =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(HiddenRows, _BasePlugin);

  function HiddenRows(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, HiddenRows);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HiddenRows).call(this, hotInstance));
    /**
     * Cached settings from Handsontable settings.
     *
     * @private
     * @type {Object}
     */

    _this.settings = {};
    /**
     * List of hidden rows indexes.
     *
     * @private
     * @type {Number[]}
     */

    _this.hiddenRows = [];
    /**
     * Last selected row index.
     *
     * @private
     * @type {Number}
     * @default -1
     */

    _this.lastSelectedRow = -1;
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link HiddenRows#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(HiddenRows, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().hiddenRows;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      if (this.hot.hasRowHeaders()) {
        this.addHook('afterGetRowHeader', function (row, TH) {
          return _this2.onAfterGetRowHeader(row, TH);
        });
      } else {
        this.addHook('afterRenderer', function (TD, row) {
          return _this2.onAfterGetRowHeader(row, TD);
        });
      }

      this.addHook('afterContextMenuDefaultOptions', function (options) {
        return _this2.onAfterContextMenuDefaultOptions(options);
      });
      this.addHook('afterGetCellMeta', function (row, col, cellProperties) {
        return _this2.onAfterGetCellMeta(row, col, cellProperties);
      });
      this.addHook('modifyRowHeight', function (height, row) {
        return _this2.onModifyRowHeight(height, row);
      });
      this.addHook('beforeSetRangeStartOnly', function (coords) {
        return _this2.onBeforeSetRangeStartOnly(coords);
      });
      this.addHook('beforeSetRangeStart', function (coords) {
        return _this2.onBeforeSetRangeStart(coords);
      });
      this.addHook('beforeSetRangeEnd', function (coords) {
        return _this2.onBeforeSetRangeEnd(coords);
      });
      this.addHook('hiddenRow', function (row) {
        return _this2.isHidden(row);
      });
      this.addHook('afterCreateRow', function (index, amount) {
        return _this2.onAfterCreateRow(index, amount);
      });
      this.addHook('afterRemoveRow', function (index, amount) {
        return _this2.onAfterRemoveRow(index, amount);
      });
      this.addHook('init', function () {
        return _this2.onInit();
      }); // Dirty workaround - the section below runs only if the HOT instance is already prepared.

      if (this.hot.view) {
        this.onInit();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      this.disablePlugin();
      this.enablePlugin();
      this.onInit();
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.settings = {};
      this.hiddenRows = [];
      this.lastSelectedRow = -1;
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "disablePlugin", this).call(this);
      this.resetCellsMeta();
    }
    /**
     * Shows the rows provided in the array.
     *
     * @param {Number[]} rows Array of visual row indexes.
     */

  }, {
    key: "showRows",
    value: function showRows(rows) {
      var _this3 = this;

      var currentHideConfig = this.hiddenRows;
      var validRows = this.isRowDataValid(rows);
      var physicalRows = (0, _array.arrayMap)(rows, function (visualRowIndex) {
        return _this3.hot.toPhysicalRow(visualRowIndex);
      });
      var destinationHideConfig = currentHideConfig;

      if (validRows) {
        destinationHideConfig = this.hiddenRows.filter(function (hiddenRow) {
          return physicalRows.includes(hiddenRow) === false;
        });
      }

      var continueHiding = this.hot.runHooks('beforeUnhideRows', currentHideConfig, destinationHideConfig, validRows);

      if (continueHiding === false) {
        return;
      }

      if (validRows) {
        this.hiddenRows = destinationHideConfig;
      }

      this.hot.runHooks('afterUnhideRows', currentHideConfig, destinationHideConfig, validRows, validRows && destinationHideConfig.length < currentHideConfig.length);
    }
    /**
     * Shows the row provided as row index (counting from 0).
     *
     * @param {...Number} row Visual row index.
     */

  }, {
    key: "showRow",
    value: function showRow() {
      for (var _len = arguments.length, row = new Array(_len), _key = 0; _key < _len; _key++) {
        row[_key] = arguments[_key];
      }

      this.showRows(row);
    }
    /**
     * Hides the rows provided in the array.
     *
     * @param {Number[]} rows Array of visual row indexes.
     */

  }, {
    key: "hideRows",
    value: function hideRows(rows) {
      var _this4 = this;

      var currentHideConfig = this.hiddenRows;
      var validRows = this.isRowDataValid(rows);
      var physicalRows = (0, _array.arrayMap)(rows, function (visualRowIndex) {
        return _this4.hot.toPhysicalRow(visualRowIndex);
      });
      var destinationHideConfig = currentHideConfig;

      if (validRows) {
        // Creating unique list of indexes.
        destinationHideConfig = Array.from(new Set(currentHideConfig.concat(physicalRows)));
      }

      var continueHiding = this.hot.runHooks('beforeHideRows', currentHideConfig, destinationHideConfig, validRows);

      if (continueHiding === false) {
        return;
      }

      if (validRows) {
        this.hiddenRows = destinationHideConfig;
      }

      this.hot.runHooks('afterHideRows', currentHideConfig, destinationHideConfig, validRows, validRows && destinationHideConfig.length > currentHideConfig.length);
    }
    /**
     * Hides the row provided as row index (counting from 0).
     *
     * @param {...Number} row Visual row index.
     */

  }, {
    key: "hideRow",
    value: function hideRow() {
      for (var _len2 = arguments.length, row = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        row[_key2] = arguments[_key2];
      }

      this.hideRows(row);
    }
    /**
     * Checks if given row is hidden.
     *
     * @param {Number} row Row index.
     * @param {Boolean} isPhysicalIndex flag which determines type of index.
     * @returns {Boolean}
     */

  }, {
    key: "isHidden",
    value: function isHidden(row) {
      var isPhysicalIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
      var physicalRow = row;

      if (!isPhysicalIndex) {
        physicalRow = this.hot.toPhysicalRow(row);
      }

      return this.hiddenRows.includes(physicalRow);
    }
    /**
     * Check whether all of the provided row indexes are within the bounds of the table.
     *
     * @param {Array} rows Array of visual row indexes.
     */

  }, {
    key: "isRowDataValid",
    value: function isRowDataValid(rows) {
      var _this5 = this;

      return rows.every(function (row) {
        return Number.isInteger(row) && row >= 0 && row < _this5.hot.countRows();
      });
    }
    /**
     * Resets all rendered cells meta.
     *
     * @private
     */

  }, {
    key: "resetCellsMeta",
    value: function resetCellsMeta() {
      (0, _array.arrayEach)(this.hot.getCellsMeta(), function (meta) {
        if (meta) {
          meta.skipRowOnPaste = false;
        }
      });
    }
    /**
     * Sets the copy-related cell meta.
     *
     * @private
     * @param {Number} row Row index.
     * @param {Number} col Column index.
     * @param {Object} cellProperties Cell meta object properties.
     *
     * @fires Hooks#unmodifyRow
     */

  }, {
    key: "onAfterGetCellMeta",
    value: function onAfterGetCellMeta(row, col, cellProperties) {
      var visualRow = this.hot.runHooks('unmodifyRow', row);

      if (this.settings.copyPasteEnabled === false && this.isHidden(visualRow)) {
        cellProperties.skipRowOnPaste = true;
      } else {
        cellProperties.skipRowOnPaste = false;
      }

      if (this.isHidden(visualRow - 1)) {
        var firstSectionHidden = true;
        var i = visualRow - 1;
        cellProperties.className = cellProperties.className || '';

        if (cellProperties.className.indexOf('afterHiddenRow') === -1) {
          cellProperties.className += ' afterHiddenRow';
        }

        do {
          if (!this.isHidden(i)) {
            firstSectionHidden = false;
            break;
          }

          i -= 1;
        } while (i >= 0);

        if (firstSectionHidden && cellProperties.className.indexOf('firstVisibleRow') === -1) {
          cellProperties.className += ' firstVisibleRow';
        }
      } else if (cellProperties.className) {
        var classArr = cellProperties.className.split(' ');

        if (classArr.length) {
          var containAfterHiddenColumn = classArr.indexOf('afterHiddenRow');

          if (containAfterHiddenColumn > -1) {
            classArr.splice(containAfterHiddenColumn, 1);
          }

          var containFirstVisible = classArr.indexOf('firstVisibleRow');

          if (containFirstVisible > -1) {
            classArr.splice(containFirstVisible, 1);
          }

          cellProperties.className = classArr.join(' ');
        }
      }
    }
    /**
     * Adds the needed classes to the headers.
     *
     * @private
     * @param {Number} row Row index.
     * @param {HTMLElement} th Table header element.
     */

  }, {
    key: "onAfterGetRowHeader",
    value: function onAfterGetRowHeader(row, th) {
      var tr = th.parentNode;

      if (tr) {
        if (this.isHidden(row)) {
          (0, _element.addClass)(tr, 'hide');
        } else {
          (0, _element.removeClass)(tr, 'hide');
        }
      }

      var firstSectionHidden = true;
      var i = row - 1;

      do {
        if (!this.isHidden(i)) {
          firstSectionHidden = false;
          break;
        }

        i -= 1;
      } while (i >= 0);

      if (firstSectionHidden) {
        (0, _element.addClass)(th, 'firstVisibleRow');
      }

      if (this.settings.indicators && this.hot.hasRowHeaders()) {
        if (this.isHidden(row - 1)) {
          (0, _element.addClass)(th, 'afterHiddenRow');
        }

        if (this.isHidden(row + 1)) {
          (0, _element.addClass)(th, 'beforeHiddenRow');
        }
      }
    }
    /**
     * Adds the additional row height for the hidden row indicators.
     *
     * @private
     * @param {Number} height Row height.
     * @param {Number} row Row index.
     * @returns {Number}
     */

  }, {
    key: "onModifyRowHeight",
    value: function onModifyRowHeight(height, row) {
      if (this.isHidden(row)) {
        return 0.1;
      }

      return height;
    }
    /**
     * On modify copyable range listener.
     *
     * @private
     * @param {Array} ranges Array of selected copyable text.
     * @returns {Array} Returns modyfied range.
     */

  }, {
    key: "onModifyCopyableRange",
    value: function onModifyCopyableRange(ranges) {
      var _this6 = this;

      var newRanges = [];

      var pushRange = function pushRange(startRow, endRow, startCol, endCol) {
        newRanges.push({
          startRow: startRow,
          endRow: endRow,
          startCol: startCol,
          endCol: endCol
        });
      };

      (0, _array.arrayEach)(ranges, function (range) {
        var isHidden = true;
        var rangeStart = 0;
        (0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
          if (_this6.isHidden(row)) {
            if (!isHidden) {
              pushRange(rangeStart, row - 1, range.startCol, range.endCol);
            }

            isHidden = true;
          } else {
            if (isHidden) {
              rangeStart = row;
            }

            if (row === range.endRow) {
              pushRange(rangeStart, row, range.startCol, range.endCol);
            }

            isHidden = false;
          }
        });
      });
      return newRanges;
    }
    /**
     * On before set range start listener, when selection was triggered by the cell.
     *
     * @private
     * @param {Object} coords Object with `row` and `col` properties.
     */

  }, {
    key: "onBeforeSetRangeStart",
    value: function onBeforeSetRangeStart(coords) {
      var _this7 = this;

      var actualSelection = this.hot.getSelectedLast() || false;
      var lastPossibleIndex = this.hot.countRows() - 1;

      var getNextRow = function getNextRow(row) {
        var direction = 0;
        var visualRow = row;

        if (actualSelection) {
          direction = visualRow > actualSelection[0] ? 1 : -1;
          _this7.lastSelectedRow = actualSelection[0];
        }

        if (lastPossibleIndex < visualRow || visualRow < 0) {
          return _this7.lastSelectedRow;
        }

        if (_this7.isHidden(visualRow)) {
          visualRow = getNextRow(visualRow + direction);
        }

        return visualRow;
      };

      coords.row = getNextRow(coords.row);
    }
    /**
     * On before set range start listener, when selection was triggered by the headers.
     *
     * @private
     * @param {Object} coords Object with `row` and `col` properties.
     */

  }, {
    key: "onBeforeSetRangeStartOnly",
    value: function onBeforeSetRangeStartOnly(coords) {
      var _this8 = this;

      if (coords.row > 0) {
        return;
      }

      coords.row = 0;

      var getNextRow = function getNextRow(row) {
        var visualRow = row;

        if (_this8.isHidden(visualRow)) {
          visualRow += 1;
          visualRow = getNextRow(visualRow);
        }

        return visualRow;
      };

      coords.row = getNextRow(coords.row);
    }
    /**
     * On before set range end listener.
     *
     * @private
     * @param {Object} coords Object with `row` and `col` properties.
     */

  }, {
    key: "onBeforeSetRangeEnd",
    value: function onBeforeSetRangeEnd(coords) {
      var _this9 = this;

      var rowCount = this.hot.countRows();

      var getNextRow = function getNextRow(row) {
        var visualRow = row;

        if (_this9.isHidden(visualRow)) {
          if (_this9.lastSelectedRow > visualRow || coords.row === rowCount - 1) {
            if (visualRow > 0) {
              visualRow -= 1;
              visualRow = getNextRow(visualRow);
            } else {
              (0, _number.rangeEach)(0, _this9.lastSelectedRow, function (i) {
                if (!_this9.isHidden(i)) {
                  visualRow = i;
                  return false;
                }
              });
            }
          } else {
            visualRow += 1;
            visualRow = getNextRow(visualRow);
          }
        }

        return visualRow;
      };

      coords.row = getNextRow(coords.row);
      this.lastSelectedRow = coords.row;
    }
    /**
     * Adds Show-hide columns to context menu.
     *
     * @private
     * @param {Object} options
     */

  }, {
    key: "onAfterContextMenuDefaultOptions",
    value: function onAfterContextMenuDefaultOptions(options) {
      options.items.push({
        name: '---------'
      }, (0, _hideRow.default)(this), (0, _showRow.default)(this));
    }
    /**
     * Recalculates index of hidden rows after add row action
     *
     * @private
     * @param {Number} index
     * @param {Number} amount
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount) {
      var tempHidden = [];
      (0, _array.arrayEach)(this.hiddenRows, function (row) {
        var visualRow = row;

        if (visualRow >= index) {
          visualRow += amount;
        }

        tempHidden.push(visualRow);
      });
      this.hiddenRows = tempHidden;
    }
    /**
     * Recalculates index of hidden rows after remove row action
     *
     * @private
     * @param {Number} index
     * @param {Number} amount
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow(index, amount) {
      var tempHidden = [];
      (0, _array.arrayEach)(this.hiddenRows, function (row) {
        var visualRow = row;

        if (visualRow >= index) {
          visualRow -= amount;
        }

        tempHidden.push(visualRow);
      });
      this.hiddenRows = tempHidden;
    }
    /**
     * `afterPluginsInitialized` hook callback.
     *
     * @private
     */

  }, {
    key: "onInit",
    value: function onInit() {
      var _this10 = this;

      var settings = this.hot.getSettings().hiddenRows;

      if ((0, _typeof2.default)(settings) === 'object') {
        this.settings = settings;

        if (settings.copyPasteEnabled === void 0) {
          settings.copyPasteEnabled = true;
        }

        if (Array.isArray(settings.rows)) {
          this.hideRows(settings.rows);
        }

        if (!settings.copyPasteEnabled) {
          this.addHook('modifyCopyableRange', function (ranges) {
            return _this10.onModifyCopyableRange(ranges);
          });
        }
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      (0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "destroy", this).call(this);
    }
  }]);
  return HiddenRows;
}(_base.default);

(0, _plugins.registerPlugin)('hiddenRows', HiddenRows);
var _default = HiddenRows;
exports.default = _default;

/***/ }),
/* 768 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = hideRowItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _number = __webpack_require__(15);

var C = _interopRequireWildcard(__webpack_require__(11));

function hideRowItem(hiddenRowsPlugin) {
  return {
    key: 'hidden_rows_hide',
    name: function name() {
      var selection = this.getSelectedLast();
      var pluralForm = 0;

      if (Array.isArray(selection)) {
        var _selection = (0, _slicedToArray2.default)(selection, 3),
            fromRow = _selection[0],
            toRow = _selection[2];

        if (fromRow - toRow !== 0) {
          pluralForm = 1;
        }
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_HIDE_ROW, pluralForm);
    },
    callback: function callback() {
      var _this$getSelectedRang = this.getSelectedRangeLast(),
          from = _this$getSelectedRang.from,
          to = _this$getSelectedRang.to;

      var start = Math.min(from.row, to.row);
      var end = Math.max(from.row, to.row);
      (0, _number.rangeEach)(start, end, function (row) {
        return hiddenRowsPlugin.hideRow(row);
      });
      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    disabled: false,
    hidden: function hidden() {
      return !this.selection.isSelectedByRowHeader();
    }
  };
}

/***/ }),
/* 769 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireWildcard = __webpack_require__(9);

var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = showRowItem;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));

var _number = __webpack_require__(15);

var C = _interopRequireWildcard(__webpack_require__(11));

function showRowItem(hiddenRowsPlugin) {
  var beforeHiddenRows = [];
  var afterHiddenRows = [];
  return {
    key: 'hidden_rows_show',
    name: function name() {
      var selection = this.getSelectedLast();
      var pluralForm = 0;

      if (Array.isArray(selection)) {
        var _selection = (0, _slicedToArray2.default)(selection, 3),
            fromRow = _selection[0],
            toRow = _selection[2];

        if (fromRow > toRow) {
          var _ref = [toRow, fromRow];
          fromRow = _ref[0];
          toRow = _ref[1];
        }

        var hiddenRows = 0;

        if (fromRow === toRow) {
          hiddenRows = beforeHiddenRows.length + afterHiddenRows.length;
        } else {
          (0, _number.rangeEach)(fromRow, toRow, function (column) {
            if (hiddenRowsPlugin.isHidden(column)) {
              hiddenRows += 1;
            }
          });
        }

        pluralForm = hiddenRows <= 1 ? 0 : 1;
      }

      return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_SHOW_ROW, pluralForm);
    },
    callback: function callback() {
      var _this$getSelectedRang = this.getSelectedRangeLast(),
          from = _this$getSelectedRang.from,
          to = _this$getSelectedRang.to;

      var start = Math.min(from.row, to.row);
      var end = Math.max(from.row, to.row);

      if (start === end) {
        if (beforeHiddenRows.length === start) {
          hiddenRowsPlugin.showRows(beforeHiddenRows);
          beforeHiddenRows.length = 0;
        }

        if (afterHiddenRows.length === this.countSourceRows() - (start + 1)) {
          hiddenRowsPlugin.showRows(afterHiddenRows);
          afterHiddenRows.length = 0;
        }
      } else {
        (0, _number.rangeEach)(start, end, function (row) {
          return hiddenRowsPlugin.showRow(row);
        });
      }

      this.render();
      this.view.wt.wtOverlays.adjustElementsSize(true);
    },
    disabled: false,
    hidden: function hidden() {
      if (!hiddenRowsPlugin.hiddenRows.length || !this.selection.isSelectedByRowHeader()) {
        return true;
      }

      beforeHiddenRows.length = 0;
      afterHiddenRows.length = 0;

      var _this$getSelectedRang2 = this.getSelectedRangeLast(),
          from = _this$getSelectedRang2.from,
          to = _this$getSelectedRang2.to;

      var start = Math.min(from.row, to.row);
      var end = Math.max(from.row, to.row);
      var hiddenInSelection = false;

      if (start === end) {
        var totalRowsLength = this.countSourceRows();
        (0, _number.rangeEach)(0, totalRowsLength, function (i) {
          var partedHiddenLength = beforeHiddenRows.length + afterHiddenRows.length;

          if (partedHiddenLength === hiddenRowsPlugin.hiddenRows.length) {
            return false;
          }

          if (i < start) {
            if (hiddenRowsPlugin.isHidden(i)) {
              beforeHiddenRows.push(i);
            }
          } else if (hiddenRowsPlugin.isHidden(i)) {
            afterHiddenRows.push(i);
          }
        });
        totalRowsLength -= 1;

        if (beforeHiddenRows.length === start && start > 0 || afterHiddenRows.length === totalRowsLength - start && start < totalRowsLength) {
          hiddenInSelection = true;
        }
      } else {
        (0, _number.rangeEach)(start, end, function (i) {
          if (hiddenRowsPlugin.isHidden(i)) {
            hiddenInSelection = true;
            return false;
          }
        });
      }

      return !hiddenInSelection;
    }
  };
}

/***/ }),
/* 770 */
/***/ (function(module, exports, __webpack_require__) {

// extracted by mini-css-extract-plugin

/***/ }),
/* 771 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

__webpack_require__(18);

__webpack_require__(56);

__webpack_require__(59);

__webpack_require__(34);

__webpack_require__(16);

__webpack_require__(80);

__webpack_require__(81);

__webpack_require__(10);

__webpack_require__(82);

__webpack_require__(39);

__webpack_require__(14);

__webpack_require__(17);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));

var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));

var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));

var _get2 = _interopRequireDefault(__webpack_require__(13));

var _inherits2 = _interopRequireDefault(__webpack_require__(8));

var _base = _interopRequireDefault(__webpack_require__(21));

var _number = __webpack_require__(15);

var _plugins = __webpack_require__(20);

var _rowsMapper = _interopRequireDefault(__webpack_require__(772));

var _array = __webpack_require__(3);

/**
 * @plugin TrimRows
 *
 * @description
 * The plugin allows to trim certain rows. The trimming is achieved by applying the transformation algorithm to the data
 * transformation. In this case, when the row is trimmed it is not accessible using `getData*` methods thus the trimmed
 * data is not visible to other plugins.
 *
 * @example
 * ```js
 * const container = document.getElementById('example');
 * const hot = new Handsontable(container, {
 *   date: getData(),
 *   // hide selected rows on table initialization
 *   trimRows: [1, 2, 5]
 * });
 *
 * // access the trimRows plugin instance
 * const trimRowsPlugin = hot.getPlugin('trimRows');
 *
 * // hide single row
 * trimRowsPlugin.trimRow(1);
 *
 * // hide multiple rows
 * trimRowsPlugin.trimRow(1, 2, 9);
 *
 * // or as an array
 * trimRowsPlugin.trimRows([1, 2, 9]);
 *
 * // show single row
 * trimRowsPlugin.untrimRow(1);
 *
 * // show multiple rows
 * trimRowsPlugin.untrimRow(1, 2, 9);
 *
 * // or as an array
 * trimRowsPlugin.untrimRows([1, 2, 9]);
 *
 * // rerender table to see the changes
 * hot.render();
 * ```
 */
var TrimRows =
/*#__PURE__*/
function (_BasePlugin) {
  (0, _inherits2.default)(TrimRows, _BasePlugin);

  function TrimRows(hotInstance) {
    var _this;

    (0, _classCallCheck2.default)(this, TrimRows);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TrimRows).call(this, hotInstance));
    /**
     * List of trimmed row indexes.
     *
     * @private
     * @type {Array}
     */

    _this.trimmedRows = [];
    /**
     * List of last removed row indexes.
     *
     * @private
     * @type {Array}
     */

    _this.removedRows = [];
    /**
     * Object containing visual row indexes mapped to data source indexes.
     *
     * @private
     * @type {RowsMapper}
     */

    _this.rowsMapper = new _rowsMapper.default((0, _assertThisInitialized2.default)(_this));
    return _this;
  }
  /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` than the {@link AutoRowSize#enablePlugin} method is called.
   *
   * @returns {Boolean}
   */


  (0, _createClass2.default)(TrimRows, [{
    key: "isEnabled",
    value: function isEnabled() {
      return !!this.hot.getSettings().trimRows;
    }
    /**
     * Enables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "enablePlugin",
    value: function enablePlugin() {
      var _this2 = this;

      if (this.enabled) {
        return;
      }

      var settings = this.hot.getSettings().trimRows;

      if (Array.isArray(settings)) {
        this.trimmedRows = settings;
      }

      this.rowsMapper.createMap(this.hot.countSourceRows());
      this.addHook('modifyRow', function (row, source) {
        return _this2.onModifyRow(row, source);
      });
      this.addHook('unmodifyRow', function (row, source) {
        return _this2.onUnmodifyRow(row, source);
      });
      this.addHook('beforeCreateRow', function (index, amount, source) {
        return _this2.onBeforeCreateRow(index, amount, source);
      });
      this.addHook('afterCreateRow', function (index, amount) {
        return _this2.onAfterCreateRow(index, amount);
      });
      this.addHook('beforeRemoveRow', function (index, amount) {
        return _this2.onBeforeRemoveRow(index, amount);
      });
      this.addHook('afterRemoveRow', function () {
        return _this2.onAfterRemoveRow();
      });
      this.addHook('afterLoadData', function (firstRun) {
        return _this2.onAfterLoadData(firstRun);
      });
      (0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "enablePlugin", this).call(this);
    }
    /**
     * Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
     */

  }, {
    key: "updatePlugin",
    value: function updatePlugin() {
      var settings = this.hot.getSettings().trimRows;

      if (Array.isArray(settings)) {
        this.disablePlugin();
        this.enablePlugin();
      }

      (0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "updatePlugin", this).call(this);
    }
    /**
     * Disables the plugin functionality for this Handsontable instance.
     */

  }, {
    key: "disablePlugin",
    value: function disablePlugin() {
      this.trimmedRows = [];
      this.removedRows.length = 0;
      this.rowsMapper.clearMap();
      (0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "disablePlugin", this).call(this);
    }
    /**
     * Trims the rows provided in the array.
     *
     * @param {Number[]} rows Array of physical row indexes.
     * @fires Hooks#skipLengthCache
     * @fires Hooks#beforeTrimRow
     * @fires Hooks#afterTrimRow
     */

  }, {
    key: "trimRows",
    value: function trimRows(rows) {
      var currentTrimConfig = this.trimmedRows;
      var isValidConfig = this.isValidConfig(rows);
      var destinationTrimConfig = currentTrimConfig;

      if (isValidConfig) {
        destinationTrimConfig = Array.from(new Set(currentTrimConfig.concat(rows)));
      }

      var allowTrimRow = this.hot.runHooks('beforeTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig);

      if (allowTrimRow === false) {
        return;
      }

      if (isValidConfig) {
        this.trimmedRows = destinationTrimConfig;
        this.hot.runHooks('skipLengthCache', 100);
        this.rowsMapper.createMap(this.hot.countSourceRows());
      }

      this.hot.runHooks('afterTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig, isValidConfig && destinationTrimConfig.length > currentTrimConfig.length);
    }
    /**
     * Trims the row provided as physical row index (counting from 0).
     *
     * @param {...Number} row Physical row index.
     */

  }, {
    key: "trimRow",
    value: function trimRow() {
      for (var _len = arguments.length, row = new Array(_len), _key = 0; _key < _len; _key++) {
        row[_key] = arguments[_key];
      }

      this.trimRows(row);
    }
    /**
     * Untrims the rows provided in the array.
     *
     * @param {Number[]} rows Array of physical row indexes.
     * @fires Hooks#skipLengthCache
     * @fires Hooks#beforeUntrimRow
     * @fires Hooks#afterUntrimRow
     */

  }, {
    key: "untrimRows",
    value: function untrimRows(rows) {
      var currentTrimConfig = this.trimmedRows;
      var isValidConfig = this.isValidConfig(rows);
      var destinationTrimConfig = currentTrimConfig;

      if (isValidConfig) {
        destinationTrimConfig = this.trimmedRows.filter(function (trimmedRow) {
          return rows.includes(trimmedRow) === false;
        });
      }

      var allowUntrimRow = this.hot.runHooks('beforeUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig);

      if (allowUntrimRow === false) {
        return;
      }

      if (isValidConfig) {
        this.trimmedRows = destinationTrimConfig;
        this.hot.runHooks('skipLengthCache', 100);
        this.rowsMapper.createMap(this.hot.countSourceRows());
      }

      this.hot.runHooks('afterUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig, isValidConfig && destinationTrimConfig.length < currentTrimConfig.length);
    }
    /**
     * Untrims the row provided as row index (counting from 0).
     *
     * @param {...Number} row Physical row index.
     */

  }, {
    key: "untrimRow",
    value: function untrimRow() {
      for (var _len2 = arguments.length, row = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        row[_key2] = arguments[_key2];
      }

      this.untrimRows(row);
    }
    /**
     * Checks if given physical row is hidden.
     *
     * @returns {Boolean}
     */

  }, {
    key: "isTrimmed",
    value: function isTrimmed(row) {
      return this.trimmedRows.includes(row);
    }
    /**
     * Untrims all trimmed rows.
     */

  }, {
    key: "untrimAll",
    value: function untrimAll() {
      this.untrimRows([].concat(this.trimmedRows));
    }
    /**
     * Get if trim config is valid.
     *
     * @param {Array} trimmedRows List of physical row indexes.
     * @returns {Boolean}
     */

  }, {
    key: "isValidConfig",
    value: function isValidConfig(trimmedRows) {
      var _this3 = this;

      return trimmedRows.every(function (trimmedRow) {
        return Number.isInteger(trimmedRow) && trimmedRow >= 0 && trimmedRow < _this3.hot.countSourceRows();
      });
    }
    /**
     * On modify row listener.
     *
     * @private
     * @param {Number} row Visual row index.
     * @param {String} source Source name.
     * @returns {Number|null}
     */

  }, {
    key: "onModifyRow",
    value: function onModifyRow(row, source) {
      var physicalRow = row;

      if (source !== this.pluginName) {
        physicalRow = this.rowsMapper.getValueByIndex(physicalRow);
      }

      return physicalRow;
    }
    /**
     * On unmodifyRow listener.
     *
     * @private
     * @param {Number} row Physical row index.
     * @param {String} source Source name.
     * @returns {Number|null}
     */

  }, {
    key: "onUnmodifyRow",
    value: function onUnmodifyRow(row, source) {
      var visualRow = row;

      if (source !== this.pluginName) {
        visualRow = this.rowsMapper.getIndexByValue(visualRow);
      }

      return visualRow;
    }
    /**
     * `beforeCreateRow` hook callback.
     *
     * @private
     * @param {Number} index Index of the newly created row.
     * @param {Number} amount Amount of created rows.
     * @param {String} source Source of the change.
     */

  }, {
    key: "onBeforeCreateRow",
    value: function onBeforeCreateRow(index, amount, source) {
      if (this.isEnabled() && this.trimmedRows.length > 0 && source === 'auto') {
        return false;
      }
    }
    /**
     * On after create row listener.
     *
     * @private
     * @param {Number} index Visual row index.
     * @param {Number} amount Defines how many rows removed.
     */

  }, {
    key: "onAfterCreateRow",
    value: function onAfterCreateRow(index, amount) {
      var _this4 = this;

      this.rowsMapper.shiftItems(index, amount);
      this.trimmedRows = (0, _array.arrayMap)(this.trimmedRows, function (trimmedRow) {
        if (trimmedRow >= _this4.rowsMapper.getValueByIndex(index)) {
          return trimmedRow + amount;
        }

        return trimmedRow;
      });
    }
    /**
     * On before remove row listener.
     *
     * @private
     * @param {Number} index Visual row index.
     * @param {Number} amount Defines how many rows removed.
     *
     * @fires Hooks#modifyRow
     */

  }, {
    key: "onBeforeRemoveRow",
    value: function onBeforeRemoveRow(index, amount) {
      var _this5 = this;

      this.removedRows.length = 0;

      if (index !== false) {
        // Collect physical row index.
        (0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
          _this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName));
        });
      }
    }
    /**
     * On after remove row listener.
     *
     * @private
     */

  }, {
    key: "onAfterRemoveRow",
    value: function onAfterRemoveRow() {
      var _this6 = this;

      this.rowsMapper.unshiftItems(this.removedRows); // TODO: Maybe it can be optimized? N x M checks, where N is number of already trimmed rows and M is number of removed rows.
      // Decreasing physical indexes (some of them should be updated, because few indexes are missing in new list of indexes after removal).

      this.trimmedRows = (0, _array.arrayMap)(this.trimmedRows, function (trimmedRow) {
        return trimmedRow - _this6.removedRows.filter(function (removedRow) {
          return removedRow < trimmedRow;
        }).length;
      });
    }
    /**
     * On after load data listener.
     *
     * @private
     * @param {Boolean} firstRun Indicates if hook was fired while Handsontable initialization.
     */

  }, {
    key: "onAfterLoadData",
    value: function onAfterLoadData(firstRun) {
      if (!firstRun) {
        this.rowsMapper.createMap(this.hot.countSourceRows());
      }
    }
    /**
     * Destroys the plugin instance.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this.rowsMapper.destroy();
      (0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "destroy", this).call(this);
    }
  }]);
  return TrimRows;
}(_base.default);

(0, _plugins.registerPlugin)('trimRows', TrimRows);
var _default = TrimRows;
exports.default = _default;

/***/ }),
/* 772 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _interopRequireDefault = __webpack_require__(0);

exports.__esModule = true;
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));

var _createClass2 = _interopRequireDefault(__webpack_require__(2));

var _arrayMapper = _interopRequireDefault(__webpack_require__(91));

var _object = __webpack_require__(4);

var _number = __webpack_require__(15);

/**
 * @class RowsMapper
 * @plugin TrimRows
 */
var RowsMapper =
/*#__PURE__*/
function () {
  function RowsMapper(trimRows) {
    (0, _classCallCheck2.default)(this, RowsMapper);

    /**
     * Instance of TrimRows plugin.
     *
     * @type {TrimRows}
     */
    this.trimRows = trimRows;
  }
  /**
   * Reset current map array and create new one.
   *
   * @param {Number} [length] Custom generated map length.
   */


  (0, _createClass2.default)(RowsMapper, [{
    key: "createMap",
    value: function createMap(length) {
      var _this = this;

      var rowOffset = 0;
      var originLength = length === void 0 ? this._arrayMap.length : length;
      this._arrayMap.length = 0;
      (0, _number.rangeEach)(originLength - 1, function (itemIndex) {
        if (_this.trimRows.isTrimmed(itemIndex)) {
          rowOffset += 1;
        } else {
          _this._arrayMap[itemIndex - rowOffset] = itemIndex;
        }
      });
    }
    /**
     * Destroy class.
     */

  }, {
    key: "destroy",
    value: function destroy() {
      this._arrayMap = null;
    }
  }]);
  return RowsMapper;
}();

(0, _object.mixin)(RowsMapper, _arrayMapper.default);
var _default = RowsMapper;
exports.default = _default;

/***/ })
/******/ ])["default"];
});
